mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2024-12-26 16:42:47 +00:00
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 <ryazanov.s.a@gmail.com> SVN-Revision: 44720
This commit is contained in:
parent
862a89b8f7
commit
6ba3363290
@ -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 */
|
||||
|
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user