void __init orion_pcie_reset(void __iomem *base) { u32 reg; int i; /* * MV-S104860-U0, Rev. C: * PCI Express Unit Soft Reset * When set, generates an internal reset in the PCI Express unit. * This bit should be cleared after the link is re-established. */ reg = readl(base + PCIE_DEBUG_CTRL); reg |= PCIE_DEBUG_SOFT_RESET; writel(reg, base + PCIE_DEBUG_CTRL); for (i = 0; i < 20; i++) { mdelay(10); if (orion_pcie_link_up(base)) break; } reg &= ~(PCIE_DEBUG_SOFT_RESET); writel(reg, base + PCIE_DEBUG_CTRL); }
static void __init add_pcie_port(int index, unsigned long base) { printk(KERN_INFO "Kirkwood PCIe port %d: ", index); if (orion_pcie_link_up((void __iomem *)base)) { printk(KERN_INFO "link up\n"); pcie_port_map[num_pcie_ports++] = index; } else printk(KERN_INFO "link down, ignoring\n"); }
static int pcie_valid_config(int bus, int dev) { if (bus == 0 && dev == 0) return 1; if (!orion_pcie_link_up(PCIE_BASE)) return 0; if (bus == 0 && dev != 1) return 0; return 1; }
static void __init add_pcie_port(int index, unsigned long base) { printk(KERN_INFO "Dove PCIe port %d: ", index); if (orion_pcie_link_up((void __iomem *)base)) { struct pcie_port *pp = &pcie_port[num_pcie_ports++]; printk(KERN_INFO "link up\n"); pp->index = index; pp->root_bus_nr = -1; pp->base = (void __iomem *)base; spin_lock_init(&pp->conf_lock); memset(pp->res, 0, sizeof(pp->res)); } else { printk(KERN_INFO "link down, ignoring\n"); } }
static int pcie_valid_config(int bus, int dev) { /* * Don't go out when trying to access -- * 1. nonexisting device on local bus * 2. where there's no device connected (no link) */ if (bus == 0 && dev == 0) return 1; if (!orion_pcie_link_up(PCIE_BASE)) return 0; if (bus == 0 && dev != 1) return 0; return 1; }
static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) { /* * Don't go out when trying to access -- * 1. nonexisting device on local bus * 2. where there's no device connected (no link) */ if (bus == pp->root_bus_nr && dev == 0) return 1; if (!orion_pcie_link_up(pp->base)) return 0; if (bus == pp->root_bus_nr && dev != 1) return 0; return 1; }
static void __init add_pcie_port(int maj, int min, unsigned long base) { printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min); if (orion_pcie_link_up((void __iomem *)base)) { struct pcie_port *pp = &pcie_port[num_pcie_ports++]; printk("link up\n"); pp->maj = maj; pp->min = min; pp->root_bus_nr = -1; pp->base = (void __iomem *)base; spin_lock_init(&pp->conf_lock); memset(pp->res, 0, sizeof(pp->res)); } else { printk("link down, ignoring\n"); } }
static void __init add_pcie_port(int index, void __iomem *base) { printk(KERN_INFO "Dove PCIe port %d: ", index); if (orion_pcie_link_up(base)) { struct pcie_port *pp = &pcie_port[num_pcie_ports++]; struct clk *clk = clk_get_sys("pcie", (index ? "1" : "0")); if (!IS_ERR(clk)) clk_prepare_enable(clk); printk(KERN_INFO "link up\n"); pp->index = index; pp->root_bus_nr = -1; pp->base = base; spin_lock_init(&pp->conf_lock); memset(&pp->res, 0, sizeof(pp->res)); } else { printk(KERN_INFO "link down, ignoring\n"); } }
void dove_restore_pcie_regs(void) { u32 i; u32 timeout = 50; u32 reg; /* Configure PCIE ports */ for (i = 0; i<num_pcie_ports; i++) { orion_pcie_set_local_bus_nr(pcie_port[i].base, pcie_port[i].root_bus_nr); orion_pcie_setup(pcie_port[i].base); dove_pcie_clk_out_config(i); dove_pcie_tune_phy(pcie_port[i].base); } /* Enable Link on both ports */ reg = readl(CPU_CONTROL); reg &= ~(CPU_CTRL_PCIE0_LINK | CPU_CTRL_PCIE1_LINK); writel(reg, CPU_CONTROL); /* * Loop waiting for link up on the phy of the ports. */ do { int i; int links_ready = 1; for (i = 0; i < num_pcie_ports; i++) if (!orion_pcie_link_up(pcie_port[i].base)) links_ready = 0; if (links_ready) break; mdelay(1); } while (timeout--); }