[OpenWrt-Devel] [PATCH 19/32] atheros: ar2315-pci: rework host controller initialization

Sergey Ryazanov ryazanov.s.a at gmail.com
Thu Sep 11 22:00:36 EDT 2014


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 at gmail.com>
---

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
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list