Explicitly configure PCI host controller, and do not expose it to PCI subsystem. The PCI host controller acts as a usual PCI device connected to the bus, but its configuration as a usual PCI device is senseless, since the host controller provide access to _internal_ memory space for _external_ device.
Signed-off-by: Sergey Ryazanov <[email protected]> --- Fixup trick works only by a fluke. PCI subsystem calls fixups before the memory regions allocation, and BAR1 (which is used for RAM access) has not been reprogrammed just because PCI subsystem could not find suitable address block: "pci 0000:00:03.0: BAR 1: can't assign mem (size 0x4000000)" --- .../atheros/patches-3.14/105-ar2315_pci.patch | 74 +++++++++++++++------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/target/linux/atheros/patches-3.14/105-ar2315_pci.patch b/target/linux/atheros/patches-3.14/105-ar2315_pci.patch index 5487cdc..45f9cdf 100644 --- a/target/linux/atheros/patches-3.14/105-ar2315_pci.patch +++ b/target/linux/atheros/patches-3.14/105-ar2315_pci.patch @@ -7,7 +7,7 @@ +obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o --- /dev/null +++ b/arch/mips/ar231x/pci.c -@@ -0,0 +1,254 @@ +@@ -0,0 +1,280 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License @@ -65,6 +65,9 @@ +#define AR2315_MEM_SIZE 0x00ffffffUL +#define AR2315_IO_SIZE 0x00007fffUL + ++#define AR2315_PCI_HOST_SLOT 3 ++#define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS) ++ +static unsigned long configspace; + +static int ar2315_pci_cfg_access(int devfn, int where, int size, u32 *ptr, @@ -76,9 +79,6 @@ + int err = 0; + u32 addr; + -+ if (((dev != 0) && (dev != 3)) || (func > 2)) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ + /* Select Configuration access */ + ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, 0, AR2315_PCIMISC_CFG_SEL); + mb(); @@ -116,15 +116,31 @@ + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + ++static inline int ar2315_pci_local_cfg_rd(unsigned devfn, int where, u32 *val) ++{ ++ return ar2315_pci_cfg_access(devfn, where, sizeof(u32), val, false); ++} ++ ++static inline int ar2315_pci_local_cfg_wr(unsigned devfn, int where, u32 val) ++{ ++ return ar2315_pci_cfg_access(devfn, where, sizeof(u32), &val, true); ++} ++ +static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *value) +{ ++ if ((PCI_SLOT(devfn) != 0) || (PCI_FUNC(devfn) > 2)) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ + return ar2315_pci_cfg_access(devfn, where, size, value, 0); +} + +static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 value) +{ ++ if ((PCI_SLOT(devfn) != 0) || (PCI_FUNC(devfn) > 2)) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ + return ar2315_pci_cfg_access(devfn, where, size, &value, 1); +} + @@ -178,33 +194,35 @@ + return 0; +} + -+static void -+ar2315_pci_fixup(struct pci_dev *dev) ++static int ar2315_pci_host_setup(void) +{ -+ unsigned int devfn = dev->devfn; -+ -+ if (dev->bus->number != 0) -+ return; -+ -+ /* Only fix up the PCI host settings */ -+ if ((PCI_SLOT(devfn) != 3) || (PCI_FUNC(devfn) != 0)) -+ return; -+ -+ /* Fix up MBARs */ -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, HOST_PCI_MBAR0); -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, HOST_PCI_MBAR1); -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, HOST_PCI_MBAR2); -+ pci_write_config_dword(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | -+ PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL | -+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | -+ PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK); ++ unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0); ++ int res; ++ u32 id; ++ ++ res = ar2315_pci_local_cfg_rd(devfn, PCI_VENDOR_ID, &id); ++ if (res != PCIBIOS_SUCCESSFUL || id != AR2315_PCI_HOST_DEVID) ++ return -ENODEV; ++ ++ /* Program MBARs */ ++ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_0, HOST_PCI_MBAR0); ++ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_1, HOST_PCI_MBAR1); ++ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_2, HOST_PCI_MBAR2); ++ ++ /* Run */ ++ ar2315_pci_local_cfg_wr(devfn, PCI_COMMAND, PCI_COMMAND_MEMORY | ++ PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL | ++ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | ++ PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK); ++ ++ return 0; +} -+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, ar2315_pci_fixup); + +static int __init +ar2315_pci_init(void) +{ + u32 reg; ++ int res; + + if (ar231x_devtype != DEV_TYPE_AR2315) + return -ENODEV; @@ -256,9 +274,17 @@ + ioport_resource.start = 0x10000000; + ioport_resource.end = 0xffffffff; + ++ res = ar2315_pci_host_setup(); ++ if (res) ++ goto error; ++ + register_pci_controller(&ar2315_pci_controller); + + return 0; ++ ++error: ++ iounmap((void __iomem *)configspace); ++ return res; +} + +arch_initcall(ar2315_pci_init); -- 1.8.1.5 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
