static void plx_pcie_switch_init(struct pci_bus *bus, unsigned int devfn) { struct soc_pcie_port *port = soc_pcie_bus2port(bus); u32 dRead = 0; u16 bm = 0; int bus_inc = 0; soc_pci_read_config(bus, devfn, 0x100, 4, &dRead); printk("PCIE: Doing PLX switch Init...Test Read = %08x\n", (unsigned int)dRead); /* Debug control register. */ soc_pci_read_config(bus, devfn, 0x1dc, 4, &dRead); dRead &= ~(1<<22); soc_pci_write_config(bus, devfn, 0x1dc, 4, dRead); /* Set GPIO enables. */ soc_pci_read_config(bus, devfn, 0x62c, 4, &dRead); printk("PCIE: Doing PLX switch Init...GPIO Read = %08x\n", (unsigned int)dRead); dRead &= ~((1 << 0) | (1 << 1) | (1 << 3)); dRead |= ((1 << 4) | (1 << 5) | (1 << 7)); soc_pci_write_config(bus, devfn, 0x62c, 4, dRead); mdelay(50); dRead |= ((1<<0)|(1<<1)); soc_pci_write_config(bus, devfn, 0x62c, 4, dRead); soc_pci_read_config(bus, devfn, 0x4, 2, &bm); #if NS_PCI_DEBUG printk("bus master: %08x\n", bm); #endif bm |= 0x06; soc_pci_write_config(bus, devfn, 0x4, 2, bm); bm = 0; #if NS_PCI_DEBUG soc_pci_read_config(bus, devfn, 0x4, 2, &bm); printk("bus master after: %08x\n", bm); bm = 0; #endif /* Bus 1 if the upstream port of the switch. * Bus 2 has the two downstream ports, one on each device number. */ if (bus->number == (bus_inc + 1)) { soc_pci_write_config(bus, devfn, 0x18, 4, PLX_PRIM_SEC_BUS_NUM); /* TODO: We need to scan all outgoing windows, * to look for a base limit pair for this register. */ /* MEM_BASE, MEM_LIM require 1MB alignment */ BUG_ON((port->owin_res->start >> 16) & 0xf); soc_pci_write_config(bus, devfn, PCI_MEMORY_BASE, 2, port->owin_res->start >> 16); BUG_ON(((port->owin_res->start + SZ_32M) >> 16) & 0xf); soc_pci_write_config(bus, devfn, PCI_MEMORY_LIMIT, 2, (port->owin_res->start + SZ_32M) >> 16); } else if (bus->number == (bus_inc + 2)) {
void pcieSwitchInit( struct pci_bus *bus, unsigned int devfn) { struct soc_pcie_port *port = soc_pcie_bus2port(bus); u32 dRead = 0; u32 bm = 0; soc_pci_read_config(bus, devfn, 0x100, 4, &dRead); printk("PCIE: Doing PLX switch Init...Test Read = %08x\n",(unsigned int)dRead); //Debug control register. soc_pci_read_config(bus, devfn, 0x1dc, 4, &dRead); dRead &= ~(1<<22); soc_pci_write_config(bus, devfn, 0x1dc, 4, dRead); //Set GPIO enables. soc_pci_read_config(bus, devfn, 0x62c, 4, &dRead); printk("PCIE: Doing PLX switch Init...GPIO Read = %08x\n",(unsigned int)dRead); dRead &= ~((1<<0)|(1<<1)|(1<<3)); dRead |= ((1<<4)|(1<<5)|(1<<7)); soc_pci_write_config(bus, devfn, 0x62c, 4, dRead); mdelay(50); dRead |= ((1<<0)|(1<<1)); soc_pci_write_config(bus, devfn, 0x62c, 4, dRead); soc_pci_read_config(bus, devfn, 0x4, 2, &bm); #if NS_PCI_DEBUG printk("bus master: %08x\n", bm); #endif bm |= 0x06; soc_pci_write_config(bus, devfn, 0x4,2, bm); bm = 0; soc_pci_read_config(bus, devfn, 0x4, 2, &bm); printk("bus master after: %08x\n", bm); bm =0; //Bus 1 if the upstream port of the switch. Bus 2 has the two downstream ports, one on each device number. if(bus->number == 1) { soc_pci_write_config(bus, devfn, 0x18, 4, pcieSwitchPrimSecBusNum); //TODO: We need to scan all outgoing windows, to look for a base limit pair for this register. //npciConfigOutLong(instance, busNo, deviceNo, 0, 0x20,0xcff0c000); /* MEM_BASE, MEM_LIM require 1MB alignment */ BUG_ON( (port->owin_res->start >> 16) & 0xf ); soc_pci_write_config(bus, devfn, PCI_MEMORY_BASE, 2, port->owin_res->start >> 16 ); BUG_ON(((port->owin_res->start + SZ_32M) >> 16 ) & 0xf ); soc_pci_write_config(bus, devfn, PCI_MEMORY_LIMIT, 2, (port->owin_res->start + SZ_32M) >> 16 ); }
static void __iomem * soc_pci_cfg_base(struct pci_bus *bus, unsigned int devfn, int where) { struct soc_pcie_port *port = soc_pcie_bus2port(bus); int busno = bus->number; int slot = PCI_SLOT(devfn); int fn = PCI_FUNC(devfn); void __iomem *base; int offset; int type; u32 addr_reg ; base = port->reg_base ; /* If there is no link, just show the PCI bridge. */ if (!port->link && (busno > 0 || slot > 0)) return NULL; /* */ if (busno == 0) { if (slot >= 1) return NULL; type = slot; __raw_writel( where & 0xffc, base + SOC_PCIE_EXT_CFG_ADDR ); offset = SOC_PCIE_EXT_CFG_DATA; } else { type = 1; if (fn > 1) return NULL; addr_reg = (busno & 0xff) << 20 | (slot << 15) | (fn << 12) | (where & 0xffc) | (type & 0x3); __raw_writel( addr_reg, base + SOC_PCIE_CFG_ADDR ); offset = SOC_PCIE_CFG_DATA ; } return base + offset; }