/* Global PCIe core initializations for 440SPe core */ static int __init ppc440spe_pciex_core_init(struct device_node *np) { int time_out = 20; /* Set PLL clock receiver to LVPECL */ dcri_clrset(SDR0, PESDR0_PLLLCT1, 0, 1 << 28); /* Shouldn't we do all the calibration stuff etc... here ? */ if (ppc440spe_pciex_check_reset(np)) return -ENXIO; if (!(mfdcri(SDR0, PESDR0_PLLLCT2) & 0x10000)) { printk(KERN_INFO "PCIE: PESDR_PLLCT2 resistance calibration " "failed (0x%08x)\n", mfdcri(SDR0, PESDR0_PLLLCT2)); return -1; } /* De-assert reset of PCIe PLL, wait for lock */ dcri_clrset(SDR0, PESDR0_PLLLCT1, 1 << 24, 0); udelay(3); while (time_out) { if (!(mfdcri(SDR0, PESDR0_PLLLCT3) & 0x10000000)) { time_out--; udelay(1); } else break; } if (!time_out) { printk(KERN_INFO "PCIE: VCO output not locked\n"); return -1; } pr_debug("PCIE initialization OK\n"); return 3; }
static int __init kilauea_probe(void) { unsigned long root = of_get_flat_dt_root(); if (!of_flat_dt_is_compatible(root, "amcc,kilauea")) return 0; ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; /* * 405EX(r) has SDR0_MFR[E0CS/E1CS] set after reset. This selects * the internal loopback mode. Clear these bits so that both EMACs * don't use loopback mode as deafult. */ dcri_clrset(SDR0, SDR0_MFR, 0x0c000000, 0); return 1; }
static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) { u32 val = 1 << 24; if (port->endpoint) val = PTYPE_LEGACY_ENDPOINT << 20; else val = PTYPE_ROOT_PORT << 20; if (port->index == 0) val |= LNKW_X8 << 12; else val |= LNKW_X4 << 12; mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x20222222); if (ppc440spe_revA()) mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x11000000); mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL0SET1, 0x35000000); mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL1SET1, 0x35000000); mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL2SET1, 0x35000000); mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL3SET1, 0x35000000); if (port->index == 0) { mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL4SET1, 0x35000000); mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL5SET1, 0x35000000); mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL6SET1, 0x35000000); mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL7SET1, 0x35000000); } dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, (1 << 24) | (1 << 16), 1 << 12); return 0; }
static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) { int rc = 0; /* Init HW */ if (ppc4xx_pciex_hwops->port_init_hw) rc = ppc4xx_pciex_hwops->port_init_hw(port); if (rc != 0) return rc; printk(KERN_INFO "PCIE%d: Checking link...\n", port->index); /* Wait for reset to complete */ if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) { printk(KERN_WARNING "PCIE%d: PGRST failed\n", port->index); return -1; } /* Check for card presence detect if supported, if not, just wait for * link unconditionally. * * note that we don't fail if there is no link, we just filter out * config space accesses. That way, it will be easier to implement * hotplug later on. */ if (!port->has_ibpre || !ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP, 1 << 28, 1 << 28, 100)) { printk(KERN_INFO "PCIE%d: Device detected, waiting for link...\n", port->index); if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP, 0x1000, 0x1000, 2000)) printk(KERN_WARNING "PCIE%d: Link up failed\n", port->index); else { printk(KERN_INFO "PCIE%d: link is up !\n", port->index); port->link = 1; } } else printk(KERN_INFO "PCIE%d: No device detected.\n", port->index); /* * Initialize mapping: disable all regions and configure * CFG and REG regions based on resources in the device tree */ ppc4xx_pciex_port_init_mapping(port); /* * Map UTL */ port->utl_base = ioremap(port->utl_regs.start, 0x100); BUG_ON(port->utl_base == NULL); /* * Setup UTL registers --BenH. */ if (ppc4xx_pciex_hwops->setup_utl) ppc4xx_pciex_hwops->setup_utl(port); /* * Check for VC0 active and assert RDY. */ if (port->link && ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 16, 1 << 16, 5000)) { printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index); port->link = 0; } dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 0, 1 << 20); msleep(100); return 0; }