X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=target%2Flinux%2Fatheros%2Fpatches-3.14%2F105-ar2315_pci.patch;h=7630e94d25487be0c003cbc513e3ccb07887dca3;hp=8009da0684dce683ed5e26d175443321c6558404;hb=a8799105d77032d2e448bd0d05486a3dc3cee24a;hpb=dbdd8906ac776e9b8d51284d4dc0ce24920a2231 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 8009da0684..7630e94d25 100644 --- a/target/linux/atheros/patches-3.14/105-ar2315_pci.patch +++ b/target/linux/atheros/patches-3.14/105-ar2315_pci.patch @@ -1,13 +1,16 @@ ---- a/arch/mips/ar231x/Makefile -+++ b/arch/mips/ar231x/Makefile -@@ -14,3 +14,4 @@ obj-$(CONFIG_EARLY_PRINTK) += early_prin +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o + obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ + ops-bcm63xx.o + obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o ++obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o + obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o + obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o - obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o - obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o -+obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o --- /dev/null -+++ b/arch/mips/ar231x/pci.c -@@ -0,0 +1,336 @@ ++++ b/arch/mips/pci/pci-ar2315.c +@@ -0,0 +1,345 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License @@ -49,6 +52,7 @@ + +#include +#include ++#include +#include +#include +#include @@ -59,61 +63,65 @@ +#include +#include +#include -+#include "devices.h" + -+#define AR2315_MEM_BASE 0x80800000UL -+#define AR2315_MEM_SIZE 0x00ffffffUL -+#define AR2315_IO_SIZE 0x00007fffUL ++/* Arbitrary size of memory region to access the configuration space */ ++#define AR2315_PCI_CFG_SIZE 0x00100000 + +#define AR2315_PCI_HOST_SLOT 3 +#define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS) + -+static unsigned long configspace; ++static void __iomem *ar2315_pci_cfg_mem; + +static int ar2315_pci_cfg_access(int devfn, int where, int size, u32 *ptr, + bool write) +{ + int func = PCI_FUNC(devfn); + int dev = PCI_SLOT(devfn); -+ u32 value = 0; -+ int err = 0; -+ u32 addr; ++ u32 addr = (1 << (13 + dev)) | (func << 8) | (where & ~3); ++ u32 mask = 0xffffffff >> 8 * (4 - size); ++ u32 sh = (where & 3) * 8; ++ u32 value, isr; + ++ /* Prevent access past the remapped area */ ++ if (addr >= AR2315_PCI_CFG_SIZE || dev > 18) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ /* Clear pending errors */ ++ ar231x_write_reg(AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); + /* Select Configuration access */ + ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, 0, AR2315_PCIMISC_CFG_SEL); -+ mb(); + -+ addr = (u32)configspace + (1 << (13 + dev)) + (func << 8) + where; -+ if (size == 1) -+ addr ^= 0x3; -+ else if (size == 2) -+ addr ^= 0x2; ++ mb(); /* PCI must see space change before we begin */ ++ ++ value = __raw_readl(ar2315_pci_cfg_mem + addr); ++ ++ isr = ar231x_read_reg(AR2315_PCI_ISR); ++ if (isr & AR2315_PCI_INT_ABORT) ++ goto exit_err; + + if (write) { -+ value = *ptr; -+ if (size == 1) -+ err = put_dbe(value, (u8 *)addr); -+ else if (size == 2) -+ err = put_dbe(value, (u16 *)addr); -+ else if (size == 4) -+ err = put_dbe(value, (u32 *)addr); ++ value = (value & ~(mask << sh)) | *ptr << sh; ++ __raw_writel(value, ar2315_pci_cfg_mem + addr); ++ isr = ar231x_read_reg(AR2315_PCI_ISR); ++ if (isr & AR2315_PCI_INT_ABORT) ++ goto exit_err; + } else { -+ if (size == 1) -+ err = get_dbe(value, (u8 *)addr); -+ else if (size == 2) -+ err = get_dbe(value, (u16 *)addr); -+ else if (size == 4) -+ err = get_dbe(value, (u32 *)addr); -+ if (err) -+ *ptr = 0xffffffff; -+ else -+ *ptr = value; ++ *ptr = (value >> sh) & mask; + } + ++ goto exit; ++ ++exit_err: ++ ar231x_write_reg(AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); ++ if (!write) ++ *ptr = 0xffffffff; ++ ++exit: + /* Select Memory access */ + ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, 0); + -+ return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++ return isr & AR2315_PCI_INT_ABORT ? PCIBIOS_DEVICE_NOT_FOUND : ++ PCIBIOS_SUCCESSFUL; +} + +static inline int ar2315_pci_local_cfg_rd(unsigned devfn, int where, u32 *val) @@ -129,7 +137,7 @@ +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)) ++ if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) + return PCIBIOS_DEVICE_NOT_FOUND; + + return ar2315_pci_cfg_access(devfn, where, size, value, 0); @@ -138,7 +146,7 @@ +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)) ++ if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) + return PCIBIOS_DEVICE_NOT_FOUND; + + return ar2315_pci_cfg_access(devfn, where, size, &value, 1); @@ -151,16 +159,16 @@ + +static struct resource ar2315_mem_resource = { + .name = "ar2315-pci-mem", -+ .start = AR2315_MEM_BASE, -+ .end = AR2315_MEM_BASE + AR2315_MEM_SIZE - AR2315_IO_SIZE - 1 + -+ 0x4000000, ++ .start = AR2315_PCIEXT, ++ .end = AR2315_PCIEXT + AR2315_PCIEXT_SZ - 1, + .flags = IORESOURCE_MEM, +}; + ++/* PCI controller does not support I/O ports */ +static struct resource ar2315_io_resource = { + .name = "ar2315-pci-io", -+ .start = AR2315_MEM_BASE + AR2315_MEM_SIZE - AR2315_IO_SIZE, -+ .end = AR2315_MEM_BASE + AR2315_MEM_SIZE - 1, ++ .start = 0, ++ .end = 0, + .flags = IORESOURCE_IO, +}; + @@ -172,16 +180,6 @@ + .io_offset = 0x00000000UL, +}; + -+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ return AR2315_PCI_IRQ_EXT; -+} -+ -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ return 0; -+} -+ +static int ar2315_pci_host_setup(void) +{ + unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0); @@ -193,9 +191,12 @@ + 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); ++ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_0, ++ AR2315_PCI_HOST_MBAR0); ++ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_1, ++ AR2315_PCI_HOST_MBAR1); ++ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_2, ++ AR2315_PCI_HOST_MBAR2); + + /* Run */ + ar2315_pci_local_cfg_wr(devfn, PCI_COMMAND, PCI_COMMAND_MEMORY | @@ -272,22 +273,19 @@ + ar231x_mask_reg(AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE); +} + -+static int __init -+ar2315_pci_init(void) ++static int ar2315_pci_probe(struct platform_device *pdev) +{ ++ struct device *dev = &pdev->dev; + u32 reg; + int res; + -+ if (ar231x_devtype != DEV_TYPE_AR2315) -+ return -ENODEV; -+ + /* Remap PCI config space */ -+ configspace = (unsigned long)ioremap_nocache(AR2315_PCIEXT, -+ 1 * 1024 * 1024); -+ ar2315_pci_controller.io_map_base = -+ (unsigned long)ioremap_nocache(AR2315_MEM_BASE + -+ AR2315_MEM_SIZE, AR2315_IO_SIZE); -+ set_io_port_base(ar2315_pci_controller.io_map_base); /* PCI I/O space*/ ++ ar2315_pci_cfg_mem = devm_ioremap_nocache(dev, AR2315_PCIEXT, ++ AR2315_PCI_CFG_SIZE); ++ if (!ar2315_pci_cfg_mem) { ++ dev_err(dev, "failed to remap PCI config space\n"); ++ return -ENOMEM; ++ } + + /* Reset PCI DMA logic */ + reg = ar231x_mask_reg(AR2315_RESET, 0, AR2315_RESET_PCIDMA); @@ -324,36 +322,50 @@ + + msleep(500); + -+ /* dirty hack - anyone with a datasheet that knows the memory map ? */ -+ ioport_resource.start = 0x10000000; -+ ioport_resource.end = 0xffffffff; -+ + res = ar2315_pci_host_setup(); + if (res) -+ goto error; ++ return res; + + ar2315_pci_irq_init(); + + register_pci_controller(&ar2315_pci_controller); + + return 0; -+ -+error: -+ iounmap((void __iomem *)configspace); -+ return res; +} + ++static struct platform_driver ar2315_pci_driver = { ++ .probe = ar2315_pci_probe, ++ .driver = { ++ .name = "ar2315-pci", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init ar2315_pci_init(void) ++{ ++ return platform_driver_register(&ar2315_pci_driver); ++} +arch_initcall(ar2315_pci_init); ++ ++int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ return AR2315_PCI_IRQ_EXT; ++} ++ ++int pcibios_plat_dev_init(struct pci_dev *dev) ++{ ++ return 0; ++} --- a/arch/mips/ar231x/Kconfig +++ b/arch/mips/ar231x/Kconfig -@@ -7,3 +7,10 @@ config ATHEROS_AR2315 +@@ -8,3 +8,10 @@ config SOC_AR2315 bool "Atheros 2315+ support" depends on ATHEROS_AR231X default y + -+config ATHEROS_AR2315_PCI -+ bool "PCI support" -+ depends on ATHEROS_AR2315 ++config PCI_AR2315 ++ bool "AR2315 PCI controller support" ++ depends on SOC_AR2315 + select HW_HAS_PCI + select PCI + default y @@ -363,10 +375,29 @@ do_IRQ(AR2315_IRQ_WLAN0_INTRS); else if (pending & CAUSEF_IP4) do_IRQ(AR2315_IRQ_ENET0_INTRS); -+#ifdef CONFIG_ATHEROS_AR2315_PCI ++#ifdef CONFIG_PCI_AR2315 + else if (pending & CAUSEF_IP5) + do_IRQ(AR2315_IRQ_LCBUS_PCI); +#endif else if (pending & CAUSEF_IP2) do_IRQ(AR2315_IRQ_MISC_INTRS); else if (pending & CAUSEF_IP7) +@@ -568,3 +572,18 @@ ar2315_plat_setup(void) + ar231x_serial_setup(AR2315_UART0, AR2315_MISC_IRQ_UART0, + ar2315_apb_frequency()); + } ++ ++#ifdef CONFIG_PCI_AR2315 ++static int __init ar2315_pci_init(void) ++{ ++ struct platform_device *pdev; ++ ++ if (!is_2315() || ar231x_devtype != DEV_TYPE_AR2315) ++ return -ENODEV; ++ ++ pdev = platform_device_register_simple("ar2315-pci", -1, NULL, 0); ++ ++ return pdev ? 0 : -ENODEV; ++} ++arch_initcall(ar2315_pci_init); ++#endif