From 6ba3363290b49021ec3b8bf8fa0466343f9170df Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 13 Mar 2015 03:00:43 +0000 Subject: atheros: v3.18: remap PCI controller MMR memory Honestly remap PCI controller MMR and use accessor functions to interact with registers. Signed-off-by: Sergey Ryazanov SVN-Revision: 44720 --- target/linux/atheros/patches-3.18/100-board.patch | 3 +- .../atheros/patches-3.18/105-ar2315_pci.patch | 135 +++++++++++++-------- 2 files changed, 88 insertions(+), 50 deletions(-) diff --git a/target/linux/atheros/patches-3.18/100-board.patch b/target/linux/atheros/patches-3.18/100-board.patch index e90cd633b6..b6b37d1bbd 100644 --- a/target/linux/atheros/patches-3.18/100-board.patch +++ b/target/linux/atheros/patches-3.18/100-board.patch @@ -629,7 +629,7 @@ +#endif /* __ASM_MACH_ATH25_WAR_H */ --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/ar2315_regs.h -@@ -0,0 +1,510 @@ +@@ -0,0 +1,511 @@ +/* + * Register definitions for AR2315+ + * @@ -675,6 +675,7 @@ +#define AR2315_SPI_READ 0x08000000 /* SPI FLASH */ +#define AR2315_WLAN0 0x10000000 /* Wireless MMR */ +#define AR2315_PCI 0x10100000 /* PCI MMR */ ++#define AR2315_PCI_SIZE 0x00001000 +#define AR2315_SDRAMCTL 0x10300000 /* SDRAM MMR */ +#define AR2315_LOCAL 0x10400000 /* LOCAL BUS MMR */ +#define AR2315_ENET0 0x10500000 /* ETHERNET MMR */ diff --git a/target/linux/atheros/patches-3.18/105-ar2315_pci.patch b/target/linux/atheros/patches-3.18/105-ar2315_pci.patch index 02074ddf76..904e60fe54 100644 --- a/target/linux/atheros/patches-3.18/105-ar2315_pci.patch +++ b/target/linux/atheros/patches-3.18/105-ar2315_pci.patch @@ -10,7 +10,7 @@ obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o --- /dev/null +++ b/arch/mips/pci/pci-ar2315.c -@@ -0,0 +1,445 @@ +@@ -0,0 +1,482 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License @@ -67,11 +67,11 @@ +/* + * PCI Bus Interface Registers + */ -+#define AR2315_PCI_1MS_REG (AR2315_PCI + 0x0008) ++#define AR2315_PCI_1MS_REG 0x0008 + +#define AR2315_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ + -+#define AR2315_PCI_MISC_CONFIG (AR2315_PCI + 0x000c) ++#define AR2315_PCI_MISC_CONFIG 0x000c + +#define AR2315_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */ +#define AR2315_PCIMISC_CFG_SEL 0x00000002 /* Mem or Config cycles */ @@ -87,38 +87,38 @@ +#define AR2315_PCICACHE_DIS 0x00001000 /* PCI external access cache + * disable */ + -+#define AR2315_PCI_OUT_TSTAMP (AR2315_PCI + 0x0010) ++#define AR2315_PCI_OUT_TSTAMP 0x0010 + -+#define AR2315_PCI_UNCACHE_CFG (AR2315_PCI + 0x0014) ++#define AR2315_PCI_UNCACHE_CFG 0x0014 + -+#define AR2315_PCI_IN_EN (AR2315_PCI + 0x0100) ++#define AR2315_PCI_IN_EN 0x0100 + +#define AR2315_PCI_IN_EN0 0x01 /* Enable chain 0 */ +#define AR2315_PCI_IN_EN1 0x02 /* Enable chain 1 */ +#define AR2315_PCI_IN_EN2 0x04 /* Enable chain 2 */ +#define AR2315_PCI_IN_EN3 0x08 /* Enable chain 3 */ + -+#define AR2315_PCI_IN_DIS (AR2315_PCI + 0x0104) ++#define AR2315_PCI_IN_DIS 0x0104 + +#define AR2315_PCI_IN_DIS0 0x01 /* Disable chain 0 */ +#define AR2315_PCI_IN_DIS1 0x02 /* Disable chain 1 */ +#define AR2315_PCI_IN_DIS2 0x04 /* Disable chain 2 */ +#define AR2315_PCI_IN_DIS3 0x08 /* Disable chain 3 */ + -+#define AR2315_PCI_IN_PTR (AR2315_PCI + 0x0200) ++#define AR2315_PCI_IN_PTR 0x0200 + -+#define AR2315_PCI_OUT_EN (AR2315_PCI + 0x0400) ++#define AR2315_PCI_OUT_EN 0x0400 + +#define AR2315_PCI_OUT_EN0 0x01 /* Enable chain 0 */ + -+#define AR2315_PCI_OUT_DIS (AR2315_PCI + 0x0404) ++#define AR2315_PCI_OUT_DIS 0x0404 + +#define AR2315_PCI_OUT_DIS0 0x01 /* Disable chain 0 */ + -+#define AR2315_PCI_OUT_PTR (AR2315_PCI + 0x0408) ++#define AR2315_PCI_OUT_PTR 0x0408 + +/* PCI interrupt status (write one to clear) */ -+#define AR2315_PCI_ISR (AR2315_PCI + 0x0500) ++#define AR2315_PCI_ISR 0x0500 + +#define AR2315_PCI_INT_TX 0x00000001 /* Desc In Completed */ +#define AR2315_PCI_INT_TXOK 0x00000002 /* Desc In OK */ @@ -134,20 +134,20 @@ +#define AR2315_PCI_INT_ABORT 0x04000000 /* PCI bus abort event */ + +/* PCI interrupt mask */ -+#define AR2315_PCI_IMR (AR2315_PCI + 0x0504) ++#define AR2315_PCI_IMR 0x0504 + +/* Global PCI interrupt enable */ -+#define AR2315_PCI_IER (AR2315_PCI + 0x0508) ++#define AR2315_PCI_IER 0x0508 + +#define AR2315_PCI_IER_DISABLE 0x00 /* disable pci interrupts */ +#define AR2315_PCI_IER_ENABLE 0x01 /* enable pci interrupts */ + -+#define AR2315_PCI_HOST_IN_EN (AR2315_PCI + 0x0800) -+#define AR2315_PCI_HOST_IN_DIS (AR2315_PCI + 0x0804) -+#define AR2315_PCI_HOST_IN_PTR (AR2315_PCI + 0x0810) -+#define AR2315_PCI_HOST_OUT_EN (AR2315_PCI + 0x0900) -+#define AR2315_PCI_HOST_OUT_DIS (AR2315_PCI + 0x0904) -+#define AR2315_PCI_HOST_OUT_PTR (AR2315_PCI + 0x0908) ++#define AR2315_PCI_HOST_IN_EN 0x0800 ++#define AR2315_PCI_HOST_IN_DIS 0x0804 ++#define AR2315_PCI_HOST_IN_PTR 0x0810 ++#define AR2315_PCI_HOST_OUT_EN 0x0900 ++#define AR2315_PCI_HOST_OUT_DIS 0x0904 ++#define AR2315_PCI_HOST_OUT_PTR 0x0908 + +/* + * PCI interrupts, which share IP5 @@ -174,6 +174,7 @@ + +struct ar2315_pci_ctrl { + void __iomem *cfg_mem; ++ void __iomem *mmr_mem; + struct pci_controller pci_ctrl; + struct resource mem_res; + struct resource io_res; @@ -186,6 +187,27 @@ + return container_of(hose, struct ar2315_pci_ctrl, pci_ctrl); +} + ++static inline u32 ar2315_pci_reg_read(struct ar2315_pci_ctrl *apc, u32 reg) ++{ ++ return __raw_readl(apc->mmr_mem + reg); ++} ++ ++static inline void ar2315_pci_reg_write(struct ar2315_pci_ctrl *apc, u32 reg, ++ u32 val) ++{ ++ __raw_writel(val, apc->mmr_mem + reg); ++} ++ ++static inline void ar2315_pci_reg_mask(struct ar2315_pci_ctrl *apc, u32 reg, ++ u32 mask, u32 val) ++{ ++ u32 ret = ar2315_pci_reg_read(apc, reg); ++ ++ ret &= ~mask; ++ ret |= val; ++ ar2315_pci_reg_write(apc, reg, ret); ++} ++ +static int ar2315_pci_cfg_access(struct ar2315_pci_ctrl *apc, unsigned devfn, + int where, int size, u32 *ptr, bool write) +{ @@ -201,22 +223,24 @@ + return PCIBIOS_DEVICE_NOT_FOUND; + + /* Clear pending errors */ -+ ar231x_write_reg(AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); ++ ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); + /* Select Configuration access */ -+ ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, 0, AR2315_PCIMISC_CFG_SEL); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, 0, ++ AR2315_PCIMISC_CFG_SEL); + + mb(); /* PCI must see space change before we begin */ + + value = __raw_readl(apc->cfg_mem + addr); + -+ isr = ar231x_read_reg(AR2315_PCI_ISR); ++ isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR); ++ + if (isr & AR2315_PCI_INT_ABORT) + goto exit_err; + + if (write) { + value = (value & ~(mask << sh)) | *ptr << sh; + __raw_writel(value, apc->cfg_mem + addr); -+ isr = ar231x_read_reg(AR2315_PCI_ISR); ++ isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR); + if (isr & AR2315_PCI_INT_ABORT) + goto exit_err; + } else { @@ -226,13 +250,14 @@ + goto exit; + +exit_err: -+ ar231x_write_reg(AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); ++ ar2315_pci_reg_write(apc, 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); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, ++ 0); + + return isr & AR2315_PCI_INT_ABORT ? PCIBIOS_DEVICE_NOT_FOUND : + PCIBIOS_SUCCESSFUL; @@ -308,8 +333,9 @@ + +static void ar2315_pci_irq_handler(unsigned irq, struct irq_desc *desc) +{ -+ u32 pending = ar231x_read_reg(AR2315_PCI_ISR) & -+ ar231x_read_reg(AR2315_PCI_IMR); ++ struct ar2315_pci_ctrl *apc = irq_get_handler_data(irq); ++ u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) & ++ ar2315_pci_reg_read(apc, AR2315_PCI_IMR); + + if (pending & AR2315_PCI_INT_EXT) + generic_handle_irq(AR2315_PCI_IRQ_EXT); @@ -321,24 +347,27 @@ + +static void ar2315_pci_irq_mask(struct irq_data *d) +{ ++ struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); + u32 m = 1 << (d->irq - AR2315_PCI_IRQ_BASE + AR2315_PCI_IRQ_SHIFT); + -+ ar231x_mask_reg(AR2315_PCI_IMR, m, 0); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, m, 0); +} + +static void ar2315_pci_irq_mask_ack(struct irq_data *d) +{ ++ struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); + u32 m = 1 << (d->irq - AR2315_PCI_IRQ_BASE + AR2315_PCI_IRQ_SHIFT); + -+ ar231x_mask_reg(AR2315_PCI_IMR, m, 0); -+ ar231x_write_reg(AR2315_PCI_ISR, m); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, m, 0); ++ ar2315_pci_reg_write(apc, AR2315_PCI_ISR, m); +} + +static void ar2315_pci_irq_unmask(struct irq_data *d) +{ ++ struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); + u32 m = 1 << (d->irq - AR2315_PCI_IRQ_BASE + AR2315_PCI_IRQ_SHIFT); + -+ ar231x_mask_reg(AR2315_PCI_IMR, 0, m); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, 0, m); +} + +static struct irq_chip ar2315_pci_irq_chip = { @@ -348,28 +377,30 @@ + .irq_unmask = ar2315_pci_irq_unmask, +}; + -+static void ar2315_pci_irq_init(void) ++static void ar2315_pci_irq_init(struct ar2315_pci_ctrl *apc) +{ + int i; + -+ ar231x_mask_reg(AR2315_PCI_IER, AR2315_PCI_IER_ENABLE, 0); -+ ar231x_mask_reg(AR2315_PCI_IMR, (AR2315_PCI_INT_ABORT | -+ AR2315_PCI_INT_EXT), 0); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_IER, AR2315_PCI_IER_ENABLE, 0); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, (AR2315_PCI_INT_ABORT | ++ AR2315_PCI_INT_EXT), 0); + + for (i = 0; i < AR2315_PCI_IRQ_COUNT; ++i) { + int irq = AR2315_PCI_IRQ_BASE + i; + + irq_set_chip_and_handler(irq, &ar2315_pci_irq_chip, + handle_level_irq); ++ irq_set_chip_data(irq, apc); + } + + irq_set_chained_handler(AR2315_IRQ_LCBUS_PCI, ar2315_pci_irq_handler); ++ irq_set_handler_data(AR2315_IRQ_LCBUS_PCI, apc); + + /* Clear any pending Abort or external Interrupts + * and enable interrupt processing */ -+ ar231x_write_reg(AR2315_PCI_ISR, (AR2315_PCI_INT_ABORT | -+ AR2315_PCI_INT_EXT)); -+ ar231x_mask_reg(AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE); ++ ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT | ++ AR2315_PCI_INT_EXT); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE); +} + +static int ar2315_pci_probe(struct platform_device *pdev) @@ -382,6 +413,10 @@ + if (!apc) + return -ENOMEM; + ++ apc->mmr_mem = devm_ioremap_nocache(dev, AR2315_PCI, AR2315_PCI_SIZE); ++ if (!apc->mmr_mem) ++ return -ENOMEM; ++ + apc->mem_res.name = "AR2315 PCI mem space"; + apc->mem_res.start = AR2315_PCIEXT; + apc->mem_res.end = AR2315_PCIEXT + AR2315_PCIEXT_SZ - 1; @@ -396,19 +431,21 @@ + } + + /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */ -+ ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_RST_MODE, -+ AR2315_PCIRST_LOW); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, ++ AR2315_PCIMISC_RST_MODE, ++ AR2315_PCIRST_LOW); + msleep(100); + + /* Bring the PCI out of reset */ -+ ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_RST_MODE, -+ AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8); ++ ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, ++ AR2315_PCIMISC_RST_MODE, ++ AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8); + -+ ar231x_write_reg(AR2315_PCI_UNCACHE_CFG, -+ 0x1E | /* 1GB uncached */ -+ (1 << 5) | /* Enable uncached */ -+ (0x2 << 30) /* Base: 0x80000000 */); -+ ar231x_read_reg(AR2315_PCI_UNCACHE_CFG); ++ ar2315_pci_reg_write(apc, AR2315_PCI_UNCACHE_CFG, ++ 0x1E | /* 1GB uncached */ ++ (1 << 5) | /* Enable uncached */ ++ (0x2 << 30) /* Base: 0x80000000 */); ++ ar2315_pci_reg_read(apc, AR2315_PCI_UNCACHE_CFG); + + msleep(500); + @@ -416,7 +453,7 @@ + if (err) + return err; + -+ ar2315_pci_irq_init(); ++ ar2315_pci_irq_init(apc); + + /* PCI controller does not support I/O ports */ + apc->io_res.name = "AR2315 IO space"; -- cgit v1.2.3