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/spinlock.h>
13 #include <linux/irq.h>
14 #include <linux/pci.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <asm/mach-ath79/ath79.h>
18 #include <asm/mach-ath79/ar71xx_regs.h>
20 #define AR724X_PCI_REG_RESET 0x18
21 #define AR724X_PCI_REG_INT_STATUS 0x4c
22 #define AR724X_PCI_REG_INT_MASK 0x50
24 #define AR724X_PCI_RESET_LINK_UP BIT(0)
26 #define AR724X_PCI_INT_DEV0 BIT(14)
28 #define AR724X_PCI_IRQ_COUNT 1
30 #define AR7240_BAR0_WAR_VALUE 0xffff
32 struct ar724x_pci_controller {
33 void __iomem *devcfg_base;
34 void __iomem *ctrl_base;
44 struct pci_controller pci_controller;
47 static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
51 reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
52 return reset & AR724X_PCI_RESET_LINK_UP;
55 static inline struct ar724x_pci_controller *
56 pci_bus_to_ar724x_controller(struct pci_bus *bus)
58 struct pci_controller *hose;
60 hose = (struct pci_controller *) bus->sysdata;
61 return container_of(hose, struct ar724x_pci_controller, pci_controller);
64 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
65 int size, uint32_t *value)
67 struct ar724x_pci_controller *apc;
72 apc = pci_bus_to_ar724x_controller(bus);
74 return PCIBIOS_DEVICE_NOT_FOUND;
77 return PCIBIOS_DEVICE_NOT_FOUND;
79 base = apc->devcfg_base;
81 spin_lock_irqsave(&apc->lock, flags);
82 data = __raw_readl(base + (where & ~3));
100 spin_unlock_irqrestore(&apc->lock, flags);
102 return PCIBIOS_BAD_REGISTER_NUMBER;
105 spin_unlock_irqrestore(&apc->lock, flags);
107 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
108 apc->bar0_is_cached) {
109 /* use the cached value */
110 *value = apc->bar0_value;
115 return PCIBIOS_SUCCESSFUL;
118 static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
119 int size, uint32_t value)
121 struct ar724x_pci_controller *apc;
127 apc = pci_bus_to_ar724x_controller(bus);
129 return PCIBIOS_DEVICE_NOT_FOUND;
132 return PCIBIOS_DEVICE_NOT_FOUND;
134 if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) {
135 if (value != 0xffffffff) {
137 * WAR for a hw issue. If the BAR0 register of the
138 * device is set to the proper base address, the
139 * memory space of the device is not accessible.
141 * Cache the intended value so it can be read back,
142 * and write a SoC specific constant value to the
143 * BAR0 register in order to make the device memory
146 apc->bar0_is_cached = true;
147 apc->bar0_value = value;
149 value = AR7240_BAR0_WAR_VALUE;
151 apc->bar0_is_cached = false;
155 base = apc->devcfg_base;
157 spin_lock_irqsave(&apc->lock, flags);
158 data = __raw_readl(base + (where & ~3));
162 s = ((where & 3) * 8);
163 data &= ~(0xff << s);
164 data |= ((value & 0xff) << s);
167 s = ((where & 2) * 8);
168 data &= ~(0xffff << s);
169 data |= ((value & 0xffff) << s);
175 spin_unlock_irqrestore(&apc->lock, flags);
177 return PCIBIOS_BAD_REGISTER_NUMBER;
180 __raw_writel(data, base + (where & ~3));
182 __raw_readl(base + (where & ~3));
183 spin_unlock_irqrestore(&apc->lock, flags);
185 return PCIBIOS_SUCCESSFUL;
188 static struct pci_ops ar724x_pci_ops = {
189 .read = ar724x_pci_read,
190 .write = ar724x_pci_write,
193 static struct resource ar724x_io_resource = {
194 .name = "PCI IO space",
197 .flags = IORESOURCE_IO,
200 static struct resource ar724x_mem_resource = {
201 .name = "PCI memory space",
202 .start = AR724X_PCI_MEM_BASE,
203 .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1,
204 .flags = IORESOURCE_MEM,
207 static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
209 struct ar724x_pci_controller *apc;
213 apc = irq_get_handler_data(irq);
214 base = apc->ctrl_base;
216 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
217 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
219 if (pending & AR724X_PCI_INT_DEV0)
220 generic_handle_irq(ATH79_PCI_IRQ(0));
223 spurious_interrupt();
226 static void ar724x_pci_irq_unmask(struct irq_data *d)
228 struct ar724x_pci_controller *apc;
232 apc = irq_data_get_irq_chip_data(d);
233 base = apc->ctrl_base;
236 case ATH79_PCI_IRQ(0):
237 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
238 __raw_writel(t | AR724X_PCI_INT_DEV0,
239 base + AR724X_PCI_REG_INT_MASK);
241 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
245 static void ar724x_pci_irq_mask(struct irq_data *d)
247 struct ar724x_pci_controller *apc;
251 apc = irq_data_get_irq_chip_data(d);
252 base = apc->ctrl_base;
255 case ATH79_PCI_IRQ(0):
256 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
257 __raw_writel(t & ~AR724X_PCI_INT_DEV0,
258 base + AR724X_PCI_REG_INT_MASK);
261 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
263 t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
264 __raw_writel(t | AR724X_PCI_INT_DEV0,
265 base + AR724X_PCI_REG_INT_STATUS);
268 __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
272 static struct irq_chip ar724x_pci_irq_chip = {
273 .name = "AR724X PCI ",
274 .irq_mask = ar724x_pci_irq_mask,
275 .irq_unmask = ar724x_pci_irq_unmask,
276 .irq_mask_ack = ar724x_pci_irq_mask,
279 static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc)
284 base = apc->ctrl_base;
286 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
287 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
289 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
291 for (i = ATH79_PCI_IRQ_BASE;
292 i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) {
293 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
295 irq_set_chip_data(i, apc);
298 irq_set_handler_data(apc->irq, apc);
299 irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
302 static int ar724x_pci_probe(struct platform_device *pdev)
304 struct ar724x_pci_controller *apc;
305 struct resource *res;
307 apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
312 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
316 apc->ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
317 if (apc->ctrl_base == NULL)
320 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
324 apc->devcfg_base = devm_request_and_ioremap(&pdev->dev, res);
325 if (!apc->devcfg_base)
328 apc->irq = platform_get_irq(pdev, 0);
332 spin_lock_init(&apc->lock);
334 apc->pci_controller.pci_ops = &ar724x_pci_ops;
335 apc->pci_controller.io_resource = &ar724x_io_resource;
336 apc->pci_controller.mem_resource = &ar724x_mem_resource;
338 apc->link_up = ar724x_pci_check_link(apc);
340 dev_warn(&pdev->dev, "PCIe link is down\n");
342 ar724x_pci_irq_init(apc);
344 register_pci_controller(&apc->pci_controller);
349 static struct platform_driver ar724x_pci_driver = {
350 .probe = ar724x_pci_probe,
352 .name = "ar724x-pci",
353 .owner = THIS_MODULE,
357 static int __init ar724x_pci_init(void)
359 return platform_driver_register(&ar724x_pci_driver);
362 postcore_initcall(ar724x_pci_init);