2 * Atheros AR724X PCI host controller driver
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation.
12 #include <linux/irq.h>
13 #include <linux/pci.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <asm/mach-ath79/ath79.h>
17 #include <asm/mach-ath79/ar71xx_regs.h>
18 #include <asm/mach-ath79/pci.h>
20 #define AR724X_PCI_CFG_BASE 0x14000000
21 #define AR724X_PCI_CFG_SIZE 0x1000
22 #define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000)
23 #define AR724X_PCI_CTRL_SIZE 0x100
25 #define AR724X_PCI_MEM_BASE 0x10000000
26 #define AR724X_PCI_MEM_SIZE 0x04000000
28 #define AR724X_PCI_REG_RESET 0x18
29 #define AR724X_PCI_REG_INT_STATUS 0x4c
30 #define AR724X_PCI_REG_INT_MASK 0x50
32 #define AR724X_PCI_RESET_LINK_UP BIT(0)
34 #define AR724X_PCI_INT_DEV0 BIT(14)
36 #define AR724X_PCI_IRQ_COUNT 1
38 #define AR7240_BAR0_WAR_VALUE 0xffff
40 static DEFINE_SPINLOCK(ar724x_pci_lock);
41 static void __iomem *ar724x_pci_devcfg_base;
42 static void __iomem *ar724x_pci_ctrl_base;
44 static u32 ar724x_pci_bar0_value;
45 static bool ar724x_pci_bar0_is_cached;
46 static bool ar724x_pci_link_up;
48 static inline bool ar724x_pci_check_link(void)
52 reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET);
53 return reset & AR724X_PCI_RESET_LINK_UP;
56 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
57 int size, uint32_t *value)
63 if (!ar724x_pci_link_up)
64 return PCIBIOS_DEVICE_NOT_FOUND;
67 return PCIBIOS_DEVICE_NOT_FOUND;
69 base = ar724x_pci_devcfg_base;
71 spin_lock_irqsave(&ar724x_pci_lock, flags);
72 data = __raw_readl(base + (where & ~3));
90 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
92 return PCIBIOS_BAD_REGISTER_NUMBER;
95 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
97 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
98 ar724x_pci_bar0_is_cached) {
99 /* use the cached value */
100 *value = ar724x_pci_bar0_value;
105 return PCIBIOS_SUCCESSFUL;
108 static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
109 int size, uint32_t value)
116 if (!ar724x_pci_link_up)
117 return PCIBIOS_DEVICE_NOT_FOUND;
120 return PCIBIOS_DEVICE_NOT_FOUND;
122 if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) {
123 if (value != 0xffffffff) {
125 * WAR for a hw issue. If the BAR0 register of the
126 * device is set to the proper base address, the
127 * memory space of the device is not accessible.
129 * Cache the intended value so it can be read back,
130 * and write a SoC specific constant value to the
131 * BAR0 register in order to make the device memory
134 ar724x_pci_bar0_is_cached = true;
135 ar724x_pci_bar0_value = value;
137 value = AR7240_BAR0_WAR_VALUE;
139 ar724x_pci_bar0_is_cached = false;
143 base = ar724x_pci_devcfg_base;
145 spin_lock_irqsave(&ar724x_pci_lock, flags);
146 data = __raw_readl(base + (where & ~3));
150 s = ((where & 3) * 8);
151 data &= ~(0xff << s);
152 data |= ((value & 0xff) << s);
155 s = ((where & 2) * 8);
156 data &= ~(0xffff << s);
157 data |= ((value & 0xffff) << s);
163 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
165 return PCIBIOS_BAD_REGISTER_NUMBER;
168 __raw_writel(data, base + (where & ~3));
170 __raw_readl(base + (where & ~3));
171 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
173 return PCIBIOS_SUCCESSFUL;
176 static struct pci_ops ar724x_pci_ops = {
177 .read = ar724x_pci_read,
178 .write = ar724x_pci_write,
181 static struct resource ar724x_io_resource = {
182 .name = "PCI IO space",
185 .flags = IORESOURCE_IO,
188 static struct resource ar724x_mem_resource = {
189 .name = "PCI memory space",
190 .start = AR724X_PCI_MEM_BASE,
191 .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1,
192 .flags = IORESOURCE_MEM,
195 static struct pci_controller ar724x_pci_controller = {
196 .pci_ops = &ar724x_pci_ops,
197 .io_resource = &ar724x_io_resource,
198 .mem_resource = &ar724x_mem_resource,
201 static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
206 base = ar724x_pci_ctrl_base;
208 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
209 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
211 if (pending & AR724X_PCI_INT_DEV0)
212 generic_handle_irq(ATH79_PCI_IRQ(0));
215 spurious_interrupt();
218 static void ar724x_pci_irq_unmask(struct irq_data *d)
223 base = ar724x_pci_ctrl_base;
226 case ATH79_PCI_IRQ(0):
227 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
228 __raw_writel(t | AR724X_PCI_INT_DEV0,
229 base + AR724X_PCI_REG_INT_MASK);
231 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
235 static void ar724x_pci_irq_mask(struct irq_data *d)
240 base = ar724x_pci_ctrl_base;
243 case ATH79_PCI_IRQ(0):
244 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
245 __raw_writel(t & ~AR724X_PCI_INT_DEV0,
246 base + AR724X_PCI_REG_INT_MASK);
249 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
251 t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
252 __raw_writel(t | AR724X_PCI_INT_DEV0,
253 base + AR724X_PCI_REG_INT_STATUS);
256 __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
260 static struct irq_chip ar724x_pci_irq_chip = {
261 .name = "AR724X PCI ",
262 .irq_mask = ar724x_pci_irq_mask,
263 .irq_unmask = ar724x_pci_irq_unmask,
264 .irq_mask_ack = ar724x_pci_irq_mask,
267 static void ar724x_pci_irq_init(int irq)
272 base = ar724x_pci_ctrl_base;
274 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
275 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
277 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
279 for (i = ATH79_PCI_IRQ_BASE;
280 i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++)
281 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
284 irq_set_chained_handler(irq, ar724x_pci_irq_handler);
287 int ar724x_pcibios_init(int irq)
293 ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE,
294 AR724X_PCI_CFG_SIZE);
295 if (ar724x_pci_devcfg_base == NULL)
298 ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE,
299 AR724X_PCI_CTRL_SIZE);
300 if (ar724x_pci_ctrl_base == NULL)
301 goto err_unmap_devcfg;
303 ar724x_pci_link_up = ar724x_pci_check_link();
304 if (!ar724x_pci_link_up)
305 pr_warn("ar724x: PCIe link is down\n");
307 ar724x_pci_irq_init(irq);
308 register_pci_controller(&ar724x_pci_controller);
310 return PCIBIOS_SUCCESSFUL;
313 iounmap(ar724x_pci_devcfg_base);
318 static int ar724x_pci_probe(struct platform_device *pdev)
320 struct resource *res;
323 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
327 ar724x_pci_ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
328 if (ar724x_pci_ctrl_base == NULL)
331 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
335 ar724x_pci_devcfg_base = devm_request_and_ioremap(&pdev->dev, res);
336 if (!ar724x_pci_devcfg_base)
339 irq = platform_get_irq(pdev, 0);
343 ar724x_pci_link_up = ar724x_pci_check_link();
344 if (!ar724x_pci_link_up)
345 dev_warn(&pdev->dev, "PCIe link is down\n");
347 ar724x_pci_irq_init(irq);
349 register_pci_controller(&ar724x_pci_controller);
354 static struct platform_driver ar724x_pci_driver = {
355 .probe = ar724x_pci_probe,
357 .name = "ar724x-pci",
358 .owner = THIS_MODULE,
362 static int __init ar724x_pci_init(void)
364 return platform_driver_register(&ar724x_pci_driver);
367 postcore_initcall(ar724x_pci_init);