diff options
author | John Crispin <blogic@openwrt.org> | 2014-09-12 06:52:55 +0000 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2014-09-12 06:52:55 +0000 |
commit | 77a4c61c8a5c9e67f6354f78e12b59f5b4d424c5 (patch) | |
tree | 0e45fe78374940922d1a7876cd7af0926e6201ab | |
parent | 0390584332769399f3008aa0a8dbcf209df477ec (diff) | |
download | master-187ad058-77a4c61c8a5c9e67f6354f78e12b59f5b4d424c5.tar.gz master-187ad058-77a4c61c8a5c9e67f6354f78e12b59f5b4d424c5.tar.bz2 master-187ad058-77a4c61c8a5c9e67f6354f78e12b59f5b4d424c5.zip |
atheros: ar2315-pci: rework host controller initialization
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 <ryazanov.s.a@gmail.com>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@42500 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r-- | target/linux/atheros/patches-3.14/105-ar2315_pci.patch | 74 |
1 files 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 5487cdc794..45f9cdffc0 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); |