uboot/drivers/pci/fsl_pci_init.c
<<
>>
Prefs
   1/*
   2 * Copyright 2007-2011 Freescale Semiconductor, Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms of the GNU General Public License as published by the Free
   6 * Software Foundation; either version 2 of the License, or (at your option)
   7 * any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17 * MA 02111-1307 USA
  18 */
  19
  20#include <common.h>
  21#include <malloc.h>
  22#include <asm/fsl_serdes.h>
  23
  24DECLARE_GLOBAL_DATA_PTR;
  25
  26/*
  27 * PCI/PCIE Controller initialization for mpc85xx/mpc86xx soc's
  28 *
  29 * Initialize controller and call the common driver/pci pci_hose_scan to
  30 * scan for bridges and devices.
  31 *
  32 * Hose fields which need to be pre-initialized by board specific code:
  33 *   regions[]
  34 *   first_busno
  35 *
  36 * Fields updated:
  37 *   last_busno
  38 */
  39
  40#include <pci.h>
  41#include <asm/io.h>
  42#include <asm/fsl_pci.h>
  43
  44/* Freescale-specific PCI config registers */
  45#define FSL_PCI_PBFR            0x44
  46#define FSL_PCIE_CAP_ID         0x4c
  47#define FSL_PCIE_CFG_RDY        0x4b0
  48#define FSL_PROG_IF_AGENT       0x1
  49
  50void pciauto_prescan_setup_bridge(struct pci_controller *hose,
  51                                pci_dev_t dev, int sub_bus);
  52void pciauto_postscan_setup_bridge(struct pci_controller *hose,
  53                                pci_dev_t dev, int sub_bus);
  54void pciauto_config_init(struct pci_controller *hose);
  55
  56#ifndef CONFIG_SYS_PCI_MEMORY_BUS
  57#define CONFIG_SYS_PCI_MEMORY_BUS 0
  58#endif
  59
  60#ifndef CONFIG_SYS_PCI_MEMORY_PHYS
  61#define CONFIG_SYS_PCI_MEMORY_PHYS 0
  62#endif
  63
  64#if defined(CONFIG_SYS_PCI_64BIT) && !defined(CONFIG_SYS_PCI64_MEMORY_BUS)
  65#define CONFIG_SYS_PCI64_MEMORY_BUS (64ull*1024*1024*1024)
  66#endif
  67
  68/* Setup one inbound ATMU window.
  69 *
  70 * We let the caller decide what the window size should be
  71 */
  72static void set_inbound_window(volatile pit_t *pi,
  73                                struct pci_region *r,
  74                                u64 size)
  75{
  76        u32 sz = (__ilog2_u64(size) - 1);
  77        u32 flag = PIWAR_EN | PIWAR_LOCAL |
  78                        PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
  79
  80        out_be32(&pi->pitar, r->phys_start >> 12);
  81        out_be32(&pi->piwbar, r->bus_start >> 12);
  82#ifdef CONFIG_SYS_PCI_64BIT
  83        out_be32(&pi->piwbear, r->bus_start >> 44);
  84#else
  85        out_be32(&pi->piwbear, 0);
  86#endif
  87        if (r->flags & PCI_REGION_PREFETCH)
  88                flag |= PIWAR_PF;
  89        out_be32(&pi->piwar, flag | sz);
  90}
  91
  92int fsl_setup_hose(struct pci_controller *hose, unsigned long addr)
  93{
  94        volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) addr;
  95
  96        /* Reset hose to make sure its in a clean state */
  97        memset(hose, 0, sizeof(struct pci_controller));
  98
  99        pci_setup_indirect(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
 100
 101        return fsl_is_pci_agent(hose);
 102}
 103
 104static int fsl_pci_setup_inbound_windows(struct pci_controller *hose,
 105                                         u64 out_lo, u8 pcie_cap,
 106                                         volatile pit_t *pi)
 107{
 108        struct pci_region *r = hose->regions + hose->region_count;
 109        u64 sz = min((u64)gd->ram_size, (1ull << 32));
 110
 111        phys_addr_t phys_start = CONFIG_SYS_PCI_MEMORY_PHYS;
 112        pci_addr_t bus_start = CONFIG_SYS_PCI_MEMORY_BUS;
 113        pci_size_t pci_sz;
 114
 115        /* we have no space available for inbound memory mapping */
 116        if (bus_start > out_lo) {
 117                printf ("no space for inbound mapping of memory\n");
 118                return 0;
 119        }
 120
 121        /* limit size */
 122        if ((bus_start + sz) > out_lo) {
 123                sz = out_lo - bus_start;
 124                debug ("limiting size to %llx\n", sz);
 125        }
 126
 127        pci_sz = 1ull << __ilog2_u64(sz);
 128        /*
 129         * we can overlap inbound/outbound windows on PCI-E since RX & TX
 130         * links a separate
 131         */
 132        if ((pcie_cap == PCI_CAP_ID_EXP) && (pci_sz < sz)) {
 133                debug ("R0 bus_start: %llx phys_start: %llx size: %llx\n",
 134                        (u64)bus_start, (u64)phys_start, (u64)sz);
 135                pci_set_region(r, bus_start, phys_start, sz,
 136                                PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
 137                                PCI_REGION_PREFETCH);
 138
 139                /* if we aren't an exact power of two match, pci_sz is smaller
 140                 * round it up to the next power of two.  We report the actual
 141                 * size to pci region tracking.
 142                 */
 143                if (pci_sz != sz)
 144                        sz = 2ull << __ilog2_u64(sz);
 145
 146                set_inbound_window(pi--, r++, sz);
 147                sz = 0; /* make sure we dont set the R2 window */
 148        } else {
 149                debug ("R0 bus_start: %llx phys_start: %llx size: %llx\n",
 150                        (u64)bus_start, (u64)phys_start, (u64)pci_sz);
 151                pci_set_region(r, bus_start, phys_start, pci_sz,
 152                                PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
 153                                PCI_REGION_PREFETCH);
 154                set_inbound_window(pi--, r++, pci_sz);
 155
 156                sz -= pci_sz;
 157                bus_start += pci_sz;
 158                phys_start += pci_sz;
 159
 160                pci_sz = 1ull << __ilog2_u64(sz);
 161                if (sz) {
 162                        debug ("R1 bus_start: %llx phys_start: %llx size: %llx\n",
 163                                (u64)bus_start, (u64)phys_start, (u64)pci_sz);
 164                        pci_set_region(r, bus_start, phys_start, pci_sz,
 165                                        PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
 166                                        PCI_REGION_PREFETCH);
 167                        set_inbound_window(pi--, r++, pci_sz);
 168                        sz -= pci_sz;
 169                        bus_start += pci_sz;
 170                        phys_start += pci_sz;
 171                }
 172        }
 173
 174#if defined(CONFIG_PHYS_64BIT) && defined(CONFIG_SYS_PCI_64BIT)
 175        /*
 176         * On 64-bit capable systems, set up a mapping for all of DRAM
 177         * in high pci address space.
 178         */
 179        pci_sz = 1ull << __ilog2_u64(gd->ram_size);
 180        /* round up to the next largest power of two */
 181        if (gd->ram_size > pci_sz)
 182                pci_sz = 1ull << (__ilog2_u64(gd->ram_size) + 1);
 183        debug ("R64 bus_start: %llx phys_start: %llx size: %llx\n",
 184                (u64)CONFIG_SYS_PCI64_MEMORY_BUS,
 185                (u64)CONFIG_SYS_PCI_MEMORY_PHYS,
 186                (u64)pci_sz);
 187        pci_set_region(r,
 188                        CONFIG_SYS_PCI64_MEMORY_BUS,
 189                        CONFIG_SYS_PCI_MEMORY_PHYS,
 190                        pci_sz,
 191                        PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
 192                        PCI_REGION_PREFETCH);
 193        set_inbound_window(pi--, r++, pci_sz);
 194#else
 195        pci_sz = 1ull << __ilog2_u64(sz);
 196        if (sz) {
 197                debug ("R2 bus_start: %llx phys_start: %llx size: %llx\n",
 198                        (u64)bus_start, (u64)phys_start, (u64)pci_sz);
 199                pci_set_region(r, bus_start, phys_start, pci_sz,
 200                                PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
 201                                PCI_REGION_PREFETCH);
 202                sz -= pci_sz;
 203                bus_start += pci_sz;
 204                phys_start += pci_sz;
 205                set_inbound_window(pi--, r++, pci_sz);
 206        }
 207#endif
 208
 209#ifdef CONFIG_PHYS_64BIT
 210        if (sz && (((u64)gd->ram_size) < (1ull << 32)))
 211                printf("Was not able to map all of memory via "
 212                        "inbound windows -- %lld remaining\n", sz);
 213#endif
 214
 215        hose->region_count = r - hose->regions;
 216
 217        return 1;
 218}
 219
 220void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info)
 221{
 222        u32 cfg_addr = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_addr;
 223        u32 cfg_data = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_data;
 224        u16 temp16;
 225        u32 temp32;
 226        u32 block_rev;
 227        int enabled, r, inbound = 0;
 228        u16 ltssm;
 229        u8 temp8, pcie_cap;
 230        volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *)cfg_addr;
 231        struct pci_region *reg = hose->regions + hose->region_count;
 232        pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
 233
 234        /* Initialize ATMU registers based on hose regions and flags */
 235        volatile pot_t *po = &pci->pot[1];      /* skip 0 */
 236        volatile pit_t *pi;
 237
 238        u64 out_hi = 0, out_lo = -1ULL;
 239        u32 pcicsrbar, pcicsrbar_sz;
 240
 241        pci_setup_indirect(hose, cfg_addr, cfg_data);
 242
 243        block_rev = in_be32(&pci->block_rev1);
 244        if (PEX_IP_BLK_REV_2_2 <= block_rev) {
 245                pi = &pci->pit[2];      /* 0xDC0 */
 246        } else {
 247                pi = &pci->pit[3];      /* 0xDE0 */
 248        }
 249
 250        /* Handle setup of outbound windows first */
 251        for (r = 0; r < hose->region_count; r++) {
 252                unsigned long flags = hose->regions[r].flags;
 253                u32 sz = (__ilog2_u64((u64)hose->regions[r].size) - 1);
 254
 255                flags &= PCI_REGION_SYS_MEMORY|PCI_REGION_TYPE;
 256                if (flags != PCI_REGION_SYS_MEMORY) {
 257                        u64 start = hose->regions[r].bus_start;
 258                        u64 end = start + hose->regions[r].size;
 259
 260                        out_be32(&po->powbar, hose->regions[r].phys_start >> 12);
 261                        out_be32(&po->potar, start >> 12);
 262#ifdef CONFIG_SYS_PCI_64BIT
 263                        out_be32(&po->potear, start >> 44);
 264#else
 265                        out_be32(&po->potear, 0);
 266#endif
 267                        if (hose->regions[r].flags & PCI_REGION_IO) {
 268                                out_be32(&po->powar, POWAR_EN | sz |
 269                                        POWAR_IO_READ | POWAR_IO_WRITE);
 270                        } else {
 271                                out_be32(&po->powar, POWAR_EN | sz |
 272                                        POWAR_MEM_READ | POWAR_MEM_WRITE);
 273                                out_lo = min(start, out_lo);
 274                                out_hi = max(end, out_hi);
 275                        }
 276                        po++;
 277                }
 278        }
 279        debug("Outbound memory range: %llx:%llx\n", out_lo, out_hi);
 280
 281        /* setup PCSRBAR/PEXCSRBAR */
 282        pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0xffffffff);
 283        pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0, &pcicsrbar_sz);
 284        pcicsrbar_sz = ~pcicsrbar_sz + 1;
 285
 286        if (out_hi < (0x100000000ull - pcicsrbar_sz) ||
 287                (out_lo > 0x100000000ull))
 288                pcicsrbar = 0x100000000ull - pcicsrbar_sz;
 289        else
 290                pcicsrbar = (out_lo - pcicsrbar_sz) & -pcicsrbar_sz;
 291        pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, pcicsrbar);
 292
 293        out_lo = min(out_lo, (u64)pcicsrbar);
 294
 295        debug("PCICSRBAR @ 0x%x\n", pcicsrbar);
 296
 297        pci_set_region(reg++, pcicsrbar, CONFIG_SYS_CCSRBAR_PHYS,
 298                        pcicsrbar_sz, PCI_REGION_SYS_MEMORY);
 299        hose->region_count++;
 300
 301        /* see if we are a PCIe or PCI controller */
 302        pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
 303
 304        /* inbound */
 305        inbound = fsl_pci_setup_inbound_windows(hose, out_lo, pcie_cap, pi);
 306
 307        for (r = 0; r < hose->region_count; r++)
 308                debug("PCI reg:%d %016llx:%016llx %016llx %08x\n", r,
 309                        (u64)hose->regions[r].phys_start,
 310                        hose->regions[r].bus_start,
 311                        hose->regions[r].size,
 312                        hose->regions[r].flags);
 313
 314        pci_register_hose(hose);
 315        pciauto_config_init(hose);      /* grab pci_{mem,prefetch,io} */
 316        hose->current_busno = hose->first_busno;
 317
 318        out_be32(&pci->pedr, 0xffffffff);       /* Clear any errors */
 319        out_be32(&pci->peer, ~0x20140); /* Enable All Error Interupts except
 320                                         * - Master abort (pci)
 321                                         * - Master PERR (pci)
 322                                         * - ICCA (PCIe)
 323                                         */
 324        pci_hose_read_config_dword(hose, dev, PCI_DCR, &temp32);
 325        temp32 |= 0xf000e;              /* set URR, FER, NFER (but not CER) */
 326        pci_hose_write_config_dword(hose, dev, PCI_DCR, temp32);
 327
 328#if defined(CONFIG_FSL_PCIE_DISABLE_ASPM)
 329        temp32 = 0;
 330        pci_hose_read_config_dword(hose, dev, PCI_LCR, &temp32);
 331        temp32 &= ~0x03;                /* Disable ASPM  */
 332        pci_hose_write_config_dword(hose, dev, PCI_LCR, temp32);
 333        udelay(1);
 334#endif
 335        if (pcie_cap == PCI_CAP_ID_EXP) {
 336                pci_hose_read_config_word(hose, dev, PCI_LTSSM, &ltssm);
 337                enabled = ltssm >= PCI_LTSSM_L0;
 338
 339#ifdef CONFIG_FSL_PCIE_RESET
 340                if (ltssm == 1) {
 341                        int i;
 342                        debug("....PCIe link error. " "LTSSM=0x%02x.", ltssm);
 343                        /* assert PCIe reset */
 344                        setbits_be32(&pci->pdb_stat, 0x08000000);
 345                        (void) in_be32(&pci->pdb_stat);
 346                        udelay(100);
 347                        debug("  Asserting PCIe reset @%x = %x\n",
 348                              &pci->pdb_stat, in_be32(&pci->pdb_stat));
 349                        /* clear PCIe reset */
 350                        clrbits_be32(&pci->pdb_stat, 0x08000000);
 351                        asm("sync;isync");
 352                        for (i=0; i<100 && ltssm < PCI_LTSSM_L0; i++) {
 353                                pci_hose_read_config_word(hose, dev, PCI_LTSSM,
 354                                                        &ltssm);
 355                                udelay(1000);
 356                                debug("....PCIe link error. "
 357                                      "LTSSM=0x%02x.\n", ltssm);
 358                        }
 359                        enabled = ltssm >= PCI_LTSSM_L0;
 360
 361                        /* we need to re-write the bar0 since a reset will
 362                         * clear it
 363                         */
 364                        pci_hose_write_config_dword(hose, dev,
 365                                        PCI_BASE_ADDRESS_0, pcicsrbar);
 366                }
 367#endif
 368
 369                if (!enabled) {
 370                        /* Let the user know there's no PCIe link */
 371                        printf("no link, regs @ 0x%lx\n", pci_info->regs);
 372                        hose->last_busno = hose->first_busno;
 373                        return;
 374                }
 375
 376                out_be32(&pci->pme_msg_det, 0xffffffff);
 377                out_be32(&pci->pme_msg_int_en, 0xffffffff);
 378
 379                /* Print the negotiated PCIe link width */
 380                pci_hose_read_config_word(hose, dev, PCI_LSR, &temp16);
 381                printf("x%d, regs @ 0x%lx\n", (temp16 & 0x3f0 ) >> 4,
 382                        pci_info->regs);
 383
 384                hose->current_busno++; /* Start scan with secondary */
 385                pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
 386        }
 387
 388        /* Use generic setup_device to initialize standard pci regs,
 389         * but do not allocate any windows since any BAR found (such
 390         * as PCSRBAR) is not in this cpu's memory space.
 391         */
 392        pciauto_setup_device(hose, dev, 0, hose->pci_mem,
 393                             hose->pci_prefetch, hose->pci_io);
 394
 395        if (inbound) {
 396                pci_hose_read_config_word(hose, dev, PCI_COMMAND, &temp16);
 397                pci_hose_write_config_word(hose, dev, PCI_COMMAND,
 398                                           temp16 | PCI_COMMAND_MEMORY);
 399        }
 400
 401#ifndef CONFIG_PCI_NOSCAN
 402        pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &temp8);
 403
 404        /* Programming Interface (PCI_CLASS_PROG)
 405         * 0 == pci host or pcie root-complex,
 406         * 1 == pci agent or pcie end-point
 407         */
 408        if (!temp8) {
 409                debug("           Scanning PCI bus %02x\n",
 410                        hose->current_busno);
 411                hose->last_busno = pci_hose_scan_bus(hose, hose->current_busno);
 412        } else {
 413                debug("           Not scanning PCI bus %02x. PI=%x\n",
 414                        hose->current_busno, temp8);
 415                hose->last_busno = hose->current_busno;
 416        }
 417
 418        /* if we are PCIe - update limit regs and subordinate busno
 419         * for the virtual P2P bridge
 420         */
 421        if (pcie_cap == PCI_CAP_ID_EXP) {
 422                pciauto_postscan_setup_bridge(hose, dev, hose->last_busno);
 423        }
 424#else
 425        hose->last_busno = hose->current_busno;
 426#endif
 427
 428        /* Clear all error indications */
 429        if (pcie_cap == PCI_CAP_ID_EXP)
 430                out_be32(&pci->pme_msg_det, 0xffffffff);
 431        out_be32(&pci->pedr, 0xffffffff);
 432
 433        pci_hose_read_config_word (hose, dev, PCI_DSR, &temp16);
 434        if (temp16) {
 435                pci_hose_write_config_word(hose, dev, PCI_DSR, 0xffff);
 436        }
 437
 438        pci_hose_read_config_word (hose, dev, PCI_SEC_STATUS, &temp16);
 439        if (temp16) {
 440                pci_hose_write_config_word(hose, dev, PCI_SEC_STATUS, 0xffff);
 441        }
 442}
 443
 444int fsl_is_pci_agent(struct pci_controller *hose)
 445{
 446        u8 prog_if;
 447        pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
 448
 449        pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prog_if);
 450
 451        return (prog_if == FSL_PROG_IF_AGENT);
 452}
 453
 454int fsl_pci_init_port(struct fsl_pci_info *pci_info,
 455                        struct pci_controller *hose, int busno)
 456{
 457        volatile ccsr_fsl_pci_t *pci;
 458        struct pci_region *r;
 459        pci_dev_t dev = PCI_BDF(busno,0,0);
 460        u8 pcie_cap;
 461
 462        pci = (ccsr_fsl_pci_t *) pci_info->regs;
 463
 464        /* on non-PCIe controllers we don't have pme_msg_det so this code
 465         * should do nothing since the read will return 0
 466         */
 467        if (in_be32(&pci->pme_msg_det)) {
 468                out_be32(&pci->pme_msg_det, 0xffffffff);
 469                debug (" with errors.  Clearing.  Now 0x%08x",
 470                        pci->pme_msg_det);
 471        }
 472
 473        r = hose->regions + hose->region_count;
 474
 475        /* outbound memory */
 476        pci_set_region(r++,
 477                        pci_info->mem_bus,
 478                        pci_info->mem_phys,
 479                        pci_info->mem_size,
 480                        PCI_REGION_MEM);
 481
 482        /* outbound io */
 483        pci_set_region(r++,
 484                        pci_info->io_bus,
 485                        pci_info->io_phys,
 486                        pci_info->io_size,
 487                        PCI_REGION_IO);
 488
 489        hose->region_count = r - hose->regions;
 490        hose->first_busno = busno;
 491
 492        fsl_pci_init(hose, pci_info);
 493
 494        if (fsl_is_pci_agent(hose)) {
 495                fsl_pci_config_unlock(hose);
 496                hose->last_busno = hose->first_busno;
 497        }
 498
 499        pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
 500        printf("PCI%s%x: Bus %02x - %02x\n", pcie_cap == PCI_CAP_ID_EXP ?
 501                "e" : "", pci_info->pci_num,
 502                hose->first_busno, hose->last_busno);
 503
 504        return(hose->last_busno + 1);
 505}
 506
 507/* Enable inbound PCI config cycles for agent/endpoint interface */
 508void fsl_pci_config_unlock(struct pci_controller *hose)
 509{
 510        pci_dev_t dev = PCI_BDF(hose->first_busno,0,0);
 511        u8 agent;
 512        u8 pcie_cap;
 513        u16 pbfr;
 514
 515        pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &agent);
 516        if (!agent)
 517                return;
 518
 519        pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
 520        if (pcie_cap != 0x0) {
 521                /* PCIe - set CFG_READY bit of Configuration Ready Register */
 522                pci_hose_write_config_byte(hose, dev, FSL_PCIE_CFG_RDY, 0x1);
 523        } else {
 524                /* PCI - clear ACL bit of PBFR */
 525                pci_hose_read_config_word(hose, dev, FSL_PCI_PBFR, &pbfr);
 526                pbfr &= ~0x20;
 527                pci_hose_write_config_word(hose, dev, FSL_PCI_PBFR, pbfr);
 528        }
 529}
 530
 531#if defined(CONFIG_PCIE1) || defined(CONFIG_PCIE2) || \
 532    defined(CONFIG_PCIE3) || defined(CONFIG_PCIE4)
 533int fsl_configure_pcie(struct fsl_pci_info *info,
 534                        struct pci_controller *hose,
 535                        const char *connected, int busno)
 536{
 537        int is_endpoint;
 538
 539        set_next_law(info->mem_phys, law_size_bits(info->mem_size), info->law);
 540        set_next_law(info->io_phys, law_size_bits(info->io_size), info->law);
 541
 542        is_endpoint = fsl_setup_hose(hose, info->regs);
 543        printf("PCIe%u: %s", info->pci_num,
 544                is_endpoint ? "Endpoint" : "Root Complex");
 545        if (connected)
 546                printf(" of %s", connected);
 547        puts(", ");
 548
 549        return fsl_pci_init_port(info, hose, busno);
 550}
 551
 552#if defined(CONFIG_FSL_CORENET)
 553        #define _DEVDISR_PCIE1 FSL_CORENET_DEVDISR_PCIE1
 554        #define _DEVDISR_PCIE2 FSL_CORENET_DEVDISR_PCIE2
 555        #define _DEVDISR_PCIE3 FSL_CORENET_DEVDISR_PCIE3
 556        #define _DEVDISR_PCIE4 FSL_CORENET_DEVDISR_PCIE4
 557        #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
 558#elif defined(CONFIG_MPC85xx)
 559        #define _DEVDISR_PCIE1 MPC85xx_DEVDISR_PCIE
 560        #define _DEVDISR_PCIE2 MPC85xx_DEVDISR_PCIE2
 561        #define _DEVDISR_PCIE3 MPC85xx_DEVDISR_PCIE3
 562        #define _DEVDISR_PCIE4 0
 563        #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
 564#elif defined(CONFIG_MPC86xx)
 565        #define _DEVDISR_PCIE1 MPC86xx_DEVDISR_PCIE1
 566        #define _DEVDISR_PCIE2 MPC86xx_DEVDISR_PCIE2
 567        #define _DEVDISR_PCIE3 0
 568        #define _DEVDISR_PCIE4 0
 569        #define CONFIG_SYS_MPC8xxx_GUTS_ADDR \
 570                (&((immap_t *)CONFIG_SYS_IMMR)->im_gur)
 571#else
 572#error "No defines for DEVDISR_PCIE"
 573#endif
 574
 575/* Implement a dummy function for those platforms w/o SERDES */
 576static const char *__board_serdes_name(enum srds_prtcl device)
 577{
 578        switch (device) {
 579#ifdef CONFIG_SYS_PCIE1_NAME
 580        case PCIE1:
 581                return CONFIG_SYS_PCIE1_NAME;
 582#endif
 583#ifdef CONFIG_SYS_PCIE2_NAME
 584        case PCIE2:
 585                return CONFIG_SYS_PCIE2_NAME;
 586#endif
 587#ifdef CONFIG_SYS_PCIE3_NAME
 588        case PCIE3:
 589                return CONFIG_SYS_PCIE3_NAME;
 590#endif
 591#ifdef CONFIG_SYS_PCIE4_NAME
 592        case PCIE4:
 593                return CONFIG_SYS_PCIE4_NAME;
 594#endif
 595        default:
 596                return NULL;
 597        }
 598
 599        return NULL;
 600}
 601
 602__attribute__((weak, alias("__board_serdes_name"))) const char *
 603board_serdes_name(enum srds_prtcl device);
 604
 605static u32 devdisr_mask[] = {
 606        _DEVDISR_PCIE1,
 607        _DEVDISR_PCIE2,
 608        _DEVDISR_PCIE3,
 609        _DEVDISR_PCIE4,
 610};
 611
 612int fsl_pcie_init_ctrl(int busno, u32 devdisr, enum srds_prtcl dev,
 613                        struct fsl_pci_info *pci_info)
 614{
 615        struct pci_controller *hose;
 616        int num = dev - PCIE1;
 617
 618        hose = calloc(1, sizeof(struct pci_controller));
 619        if (!hose)
 620                return busno;
 621
 622        if (is_serdes_configured(dev) && !(devdisr & devdisr_mask[num])) {
 623                busno = fsl_configure_pcie(pci_info, hose,
 624                                board_serdes_name(dev), busno);
 625        } else {
 626                printf("PCIe%d: disabled\n", num + 1);
 627        }
 628
 629        return busno;
 630}
 631
 632int fsl_pcie_init_board(int busno)
 633{
 634        struct fsl_pci_info pci_info;
 635        ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC8xxx_GUTS_ADDR;
 636        u32 devdisr = in_be32(&gur->devdisr);
 637
 638#ifdef CONFIG_PCIE1
 639        SET_STD_PCIE_INFO(pci_info, 1);
 640        busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE1, &pci_info);
 641#else
 642        setbits_be32(&gur->devdisr, _DEVDISR_PCIE1); /* disable */
 643#endif
 644
 645#ifdef CONFIG_PCIE2
 646        SET_STD_PCIE_INFO(pci_info, 2);
 647        busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE2, &pci_info);
 648#else
 649        setbits_be32(&gur->devdisr, _DEVDISR_PCIE2); /* disable */
 650#endif
 651
 652#ifdef CONFIG_PCIE3
 653        SET_STD_PCIE_INFO(pci_info, 3);
 654        busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE3, &pci_info);
 655#else
 656        setbits_be32(&gur->devdisr, _DEVDISR_PCIE3); /* disable */
 657#endif
 658
 659#ifdef CONFIG_PCIE4
 660        SET_STD_PCIE_INFO(pci_info, 4);
 661        busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE4, &pci_info);
 662#else
 663        setbits_be32(&gur->devdisr, _DEVDISR_PCIE4); /* disable */
 664#endif
 665
 666        return busno;
 667}
 668#else
 669int fsl_pcie_init_ctrl(int busno, u32 devdisr, enum srds_prtcl dev,
 670                        struct fsl_pci_info *pci_info)
 671{
 672        return busno;
 673}
 674
 675int fsl_pcie_init_board(int busno)
 676{
 677        return busno;
 678}
 679#endif
 680
 681#ifdef CONFIG_OF_BOARD_SETUP
 682#include <libfdt.h>
 683#include <fdt_support.h>
 684
 685void ft_fsl_pci_setup(void *blob, const char *pci_compat,
 686                        unsigned long ctrl_addr)
 687{
 688        int off;
 689        u32 bus_range[2];
 690        phys_addr_t p_ctrl_addr = (phys_addr_t)ctrl_addr;
 691        struct pci_controller *hose;
 692
 693        hose = find_hose_by_cfg_addr((void *)(ctrl_addr));
 694
 695        /* convert ctrl_addr to true physical address */
 696        p_ctrl_addr = (phys_addr_t)ctrl_addr - CONFIG_SYS_CCSRBAR;
 697        p_ctrl_addr += CONFIG_SYS_CCSRBAR_PHYS;
 698
 699        off = fdt_node_offset_by_compat_reg(blob, pci_compat, p_ctrl_addr);
 700
 701        if (off < 0)
 702                return;
 703
 704        /* We assume a cfg_addr not being set means we didn't setup the controller */
 705        if ((hose == NULL) || (hose->cfg_addr == NULL)) {
 706                fdt_del_node(blob, off);
 707        } else {
 708                bus_range[0] = 0;
 709                bus_range[1] = hose->last_busno - hose->first_busno;
 710                fdt_setprop(blob, off, "bus-range", &bus_range[0], 2*4);
 711                fdt_pci_dma_ranges(blob, off, hose);
 712        }
 713}
 714#endif
 715