blob: 0440d8800f8a99a04e17fa2e5dc171f6f4027a01 [file] [log] [blame]
Rene Bolldorf4ff40d52011-11-17 14:25:09 +00001/*
Gabor Juhose9b62e82012-03-14 10:36:14 +01002 * Atheros AR724X PCI host controller driver
Rene Bolldorf4ff40d52011-11-17 14:25:09 +00003 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
Gabor Juhose9b62e82012-03-14 10:36:14 +01005 * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
Rene Bolldorf4ff40d52011-11-17 14:25:09 +00006 *
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.
10 */
11
Gabor Juhos908339e2013-02-03 09:58:38 +000012#include <linux/spinlock.h>
Gabor Juhos4c07c7d2012-03-14 10:36:07 +010013#include <linux/irq.h>
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000014#include <linux/pci.h>
Gabor Juhos58d2e9b2013-02-02 11:40:42 +000015#include <linux/module.h>
16#include <linux/platform_device.h>
Gabor Juhos6015a852012-03-14 10:36:05 +010017#include <asm/mach-ath79/ath79.h>
Gabor Juhos4c07c7d2012-03-14 10:36:07 +010018#include <asm/mach-ath79/ar71xx_regs.h>
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000019
Gabor Juhosa1dca312012-08-23 15:35:26 +020020#define AR724X_PCI_REG_RESET 0x18
Gabor Juhos4c07c7d2012-03-14 10:36:07 +010021#define AR724X_PCI_REG_INT_STATUS 0x4c
22#define AR724X_PCI_REG_INT_MASK 0x50
23
Gabor Juhosa1dca312012-08-23 15:35:26 +020024#define AR724X_PCI_RESET_LINK_UP BIT(0)
25
Gabor Juhos4c07c7d2012-03-14 10:36:07 +010026#define AR724X_PCI_INT_DEV0 BIT(14)
27
28#define AR724X_PCI_IRQ_COUNT 1
29
Gabor Juhos6015a852012-03-14 10:36:05 +010030#define AR7240_BAR0_WAR_VALUE 0xffff
31
Gabor Juhos908339e2013-02-03 09:58:38 +000032struct ar724x_pci_controller {
33 void __iomem *devcfg_base;
34 void __iomem *ctrl_base;
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000035
Gabor Juhos908339e2013-02-03 09:58:38 +000036 int irq;
Gabor Juhos8b66d462013-02-03 10:00:16 +000037 int irq_base;
Gabor Juhosa1dca312012-08-23 15:35:26 +020038
Gabor Juhos908339e2013-02-03 09:58:38 +000039 bool link_up;
40 bool bar0_is_cached;
41 u32 bar0_value;
42
43 spinlock_t lock;
44
45 struct pci_controller pci_controller;
Gabor Juhos34b134a2013-02-03 09:59:45 +000046 struct resource io_res;
47 struct resource mem_res;
Gabor Juhos908339e2013-02-03 09:58:38 +000048};
49
50static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
Gabor Juhosa1dca312012-08-23 15:35:26 +020051{
52 u32 reset;
53
Gabor Juhos908339e2013-02-03 09:58:38 +000054 reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
Gabor Juhosa1dca312012-08-23 15:35:26 +020055 return reset & AR724X_PCI_RESET_LINK_UP;
56}
Gabor Juhos6015a852012-03-14 10:36:05 +010057
Gabor Juhos908339e2013-02-03 09:58:38 +000058static inline struct ar724x_pci_controller *
59pci_bus_to_ar724x_controller(struct pci_bus *bus)
60{
61 struct pci_controller *hose;
62
63 hose = (struct pci_controller *) bus->sysdata;
64 return container_of(hose, struct ar724x_pci_controller, pci_controller);
65}
66
Gabor Juhosd624bd32012-03-14 10:29:26 +010067static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000068 int size, uint32_t *value)
69{
Gabor Juhos908339e2013-02-03 09:58:38 +000070 struct ar724x_pci_controller *apc;
Gabor Juhos64adb6b2012-03-14 10:36:04 +010071 unsigned long flags;
Gabor Juhosc1984412012-03-14 10:29:27 +010072 void __iomem *base;
Gabor Juhos64adb6b2012-03-14 10:36:04 +010073 u32 data;
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000074
Gabor Juhos908339e2013-02-03 09:58:38 +000075 apc = pci_bus_to_ar724x_controller(bus);
76 if (!apc->link_up)
Gabor Juhosa1dca312012-08-23 15:35:26 +020077 return PCIBIOS_DEVICE_NOT_FOUND;
78
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000079 if (devfn)
80 return PCIBIOS_DEVICE_NOT_FOUND;
81
Gabor Juhos908339e2013-02-03 09:58:38 +000082 base = apc->devcfg_base;
Gabor Juhosc1984412012-03-14 10:29:27 +010083
Gabor Juhos908339e2013-02-03 09:58:38 +000084 spin_lock_irqsave(&apc->lock, flags);
Gabor Juhos64adb6b2012-03-14 10:36:04 +010085 data = __raw_readl(base + (where & ~3));
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000086
87 switch (size) {
88 case 1:
Gabor Juhos64adb6b2012-03-14 10:36:04 +010089 if (where & 1)
90 data >>= 8;
91 if (where & 2)
92 data >>= 16;
93 data &= 0xff;
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000094 break;
95 case 2:
Gabor Juhos64adb6b2012-03-14 10:36:04 +010096 if (where & 2)
97 data >>= 16;
98 data &= 0xffff;
Rene Bolldorf4ff40d52011-11-17 14:25:09 +000099 break;
100 case 4:
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000101 break;
102 default:
Gabor Juhos908339e2013-02-03 09:58:38 +0000103 spin_unlock_irqrestore(&apc->lock, flags);
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000104
105 return PCIBIOS_BAD_REGISTER_NUMBER;
106 }
107
Gabor Juhos908339e2013-02-03 09:58:38 +0000108 spin_unlock_irqrestore(&apc->lock, flags);
Gabor Juhos6015a852012-03-14 10:36:05 +0100109
110 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
Gabor Juhos908339e2013-02-03 09:58:38 +0000111 apc->bar0_is_cached) {
Gabor Juhos6015a852012-03-14 10:36:05 +0100112 /* use the cached value */
Gabor Juhos908339e2013-02-03 09:58:38 +0000113 *value = apc->bar0_value;
Gabor Juhos6015a852012-03-14 10:36:05 +0100114 } else {
115 *value = data;
116 }
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000117
118 return PCIBIOS_SUCCESSFUL;
119}
120
Gabor Juhosd624bd32012-03-14 10:29:26 +0100121static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000122 int size, uint32_t value)
123{
Gabor Juhos908339e2013-02-03 09:58:38 +0000124 struct ar724x_pci_controller *apc;
Gabor Juhos64adb6b2012-03-14 10:36:04 +0100125 unsigned long flags;
Gabor Juhosc1984412012-03-14 10:29:27 +0100126 void __iomem *base;
Gabor Juhos64adb6b2012-03-14 10:36:04 +0100127 u32 data;
128 int s;
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000129
Gabor Juhos908339e2013-02-03 09:58:38 +0000130 apc = pci_bus_to_ar724x_controller(bus);
131 if (!apc->link_up)
Gabor Juhosa1dca312012-08-23 15:35:26 +0200132 return PCIBIOS_DEVICE_NOT_FOUND;
133
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000134 if (devfn)
135 return PCIBIOS_DEVICE_NOT_FOUND;
136
Gabor Juhos6015a852012-03-14 10:36:05 +0100137 if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) {
138 if (value != 0xffffffff) {
139 /*
140 * WAR for a hw issue. If the BAR0 register of the
141 * device is set to the proper base address, the
142 * memory space of the device is not accessible.
143 *
144 * Cache the intended value so it can be read back,
145 * and write a SoC specific constant value to the
146 * BAR0 register in order to make the device memory
147 * accessible.
148 */
Gabor Juhos908339e2013-02-03 09:58:38 +0000149 apc->bar0_is_cached = true;
150 apc->bar0_value = value;
Gabor Juhos6015a852012-03-14 10:36:05 +0100151
152 value = AR7240_BAR0_WAR_VALUE;
153 } else {
Gabor Juhos908339e2013-02-03 09:58:38 +0000154 apc->bar0_is_cached = false;
Gabor Juhos6015a852012-03-14 10:36:05 +0100155 }
156 }
157
Gabor Juhos908339e2013-02-03 09:58:38 +0000158 base = apc->devcfg_base;
Gabor Juhosc1984412012-03-14 10:29:27 +0100159
Gabor Juhos908339e2013-02-03 09:58:38 +0000160 spin_lock_irqsave(&apc->lock, flags);
Gabor Juhos64adb6b2012-03-14 10:36:04 +0100161 data = __raw_readl(base + (where & ~3));
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000162
163 switch (size) {
164 case 1:
Gabor Juhos64adb6b2012-03-14 10:36:04 +0100165 s = ((where & 3) * 8);
166 data &= ~(0xff << s);
167 data |= ((value & 0xff) << s);
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000168 break;
169 case 2:
Gabor Juhos64adb6b2012-03-14 10:36:04 +0100170 s = ((where & 2) * 8);
171 data &= ~(0xffff << s);
172 data |= ((value & 0xffff) << s);
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000173 break;
174 case 4:
Gabor Juhos64adb6b2012-03-14 10:36:04 +0100175 data = value;
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000176 break;
177 default:
Gabor Juhos908339e2013-02-03 09:58:38 +0000178 spin_unlock_irqrestore(&apc->lock, flags);
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000179
180 return PCIBIOS_BAD_REGISTER_NUMBER;
181 }
182
Gabor Juhos64adb6b2012-03-14 10:36:04 +0100183 __raw_writel(data, base + (where & ~3));
184 /* flush write */
185 __raw_readl(base + (where & ~3));
Gabor Juhos908339e2013-02-03 09:58:38 +0000186 spin_unlock_irqrestore(&apc->lock, flags);
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000187
188 return PCIBIOS_SUCCESSFUL;
189}
190
Gabor Juhosd624bd32012-03-14 10:29:26 +0100191static struct pci_ops ar724x_pci_ops = {
192 .read = ar724x_pci_read,
193 .write = ar724x_pci_write,
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000194};
195
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100196static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
Rene Bolldorf4ff40d52011-11-17 14:25:09 +0000197{
Gabor Juhos908339e2013-02-03 09:58:38 +0000198 struct ar724x_pci_controller *apc;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100199 void __iomem *base;
200 u32 pending;
201
Gabor Juhos908339e2013-02-03 09:58:38 +0000202 apc = irq_get_handler_data(irq);
203 base = apc->ctrl_base;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100204
205 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
206 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
207
208 if (pending & AR724X_PCI_INT_DEV0)
Gabor Juhos8b66d462013-02-03 10:00:16 +0000209 generic_handle_irq(apc->irq_base + 0);
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100210
211 else
212 spurious_interrupt();
213}
214
215static void ar724x_pci_irq_unmask(struct irq_data *d)
216{
Gabor Juhos908339e2013-02-03 09:58:38 +0000217 struct ar724x_pci_controller *apc;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100218 void __iomem *base;
Gabor Juhos8b66d462013-02-03 10:00:16 +0000219 int offset;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100220 u32 t;
221
Gabor Juhos908339e2013-02-03 09:58:38 +0000222 apc = irq_data_get_irq_chip_data(d);
223 base = apc->ctrl_base;
Gabor Juhos8b66d462013-02-03 10:00:16 +0000224 offset = apc->irq_base - d->irq;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100225
Gabor Juhos8b66d462013-02-03 10:00:16 +0000226 switch (offset) {
227 case 0:
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100228 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
229 __raw_writel(t | AR724X_PCI_INT_DEV0,
230 base + AR724X_PCI_REG_INT_MASK);
231 /* flush write */
232 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
233 }
234}
235
236static void ar724x_pci_irq_mask(struct irq_data *d)
237{
Gabor Juhos908339e2013-02-03 09:58:38 +0000238 struct ar724x_pci_controller *apc;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100239 void __iomem *base;
Gabor Juhos8b66d462013-02-03 10:00:16 +0000240 int offset;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100241 u32 t;
242
Gabor Juhos908339e2013-02-03 09:58:38 +0000243 apc = irq_data_get_irq_chip_data(d);
244 base = apc->ctrl_base;
Gabor Juhos8b66d462013-02-03 10:00:16 +0000245 offset = apc->irq_base - d->irq;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100246
Gabor Juhos8b66d462013-02-03 10:00:16 +0000247 switch (offset) {
248 case 0:
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100249 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
250 __raw_writel(t & ~AR724X_PCI_INT_DEV0,
251 base + AR724X_PCI_REG_INT_MASK);
252
253 /* flush write */
254 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
255
256 t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
257 __raw_writel(t | AR724X_PCI_INT_DEV0,
258 base + AR724X_PCI_REG_INT_STATUS);
259
260 /* flush write */
261 __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
262 }
263}
264
265static struct irq_chip ar724x_pci_irq_chip = {
266 .name = "AR724X PCI ",
267 .irq_mask = ar724x_pci_irq_mask,
268 .irq_unmask = ar724x_pci_irq_unmask,
269 .irq_mask_ack = ar724x_pci_irq_mask,
270};
271
Gabor Juhos8b66d462013-02-03 10:00:16 +0000272static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc,
273 int id)
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100274{
275 void __iomem *base;
276 int i;
277
Gabor Juhos908339e2013-02-03 09:58:38 +0000278 base = apc->ctrl_base;
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100279
280 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
281 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
282
Gabor Juhos8b66d462013-02-03 10:00:16 +0000283 apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT);
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100284
Gabor Juhos8b66d462013-02-03 10:00:16 +0000285 for (i = apc->irq_base;
286 i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) {
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100287 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
288 handle_level_irq);
Gabor Juhos908339e2013-02-03 09:58:38 +0000289 irq_set_chip_data(i, apc);
290 }
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100291
Gabor Juhos908339e2013-02-03 09:58:38 +0000292 irq_set_handler_data(apc->irq, apc);
293 irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
Gabor Juhos4c07c7d2012-03-14 10:36:07 +0100294}
295
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000296static int ar724x_pci_probe(struct platform_device *pdev)
297{
Gabor Juhos908339e2013-02-03 09:58:38 +0000298 struct ar724x_pci_controller *apc;
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000299 struct resource *res;
Gabor Juhos8b66d462013-02-03 10:00:16 +0000300 int id;
301
302 id = pdev->id;
303 if (id == -1)
304 id = 0;
Gabor Juhos908339e2013-02-03 09:58:38 +0000305
306 apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
307 GFP_KERNEL);
308 if (!apc)
309 return -ENOMEM;
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000310
311 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
312 if (!res)
313 return -EINVAL;
314
Gabor Juhos908339e2013-02-03 09:58:38 +0000315 apc->ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
316 if (apc->ctrl_base == NULL)
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000317 return -EBUSY;
318
319 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
320 if (!res)
321 return -EINVAL;
322
Gabor Juhos908339e2013-02-03 09:58:38 +0000323 apc->devcfg_base = devm_request_and_ioremap(&pdev->dev, res);
324 if (!apc->devcfg_base)
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000325 return -EBUSY;
326
Gabor Juhos908339e2013-02-03 09:58:38 +0000327 apc->irq = platform_get_irq(pdev, 0);
328 if (apc->irq < 0)
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000329 return -EINVAL;
330
Gabor Juhos908339e2013-02-03 09:58:38 +0000331 spin_lock_init(&apc->lock);
332
Gabor Juhos34b134a2013-02-03 09:59:45 +0000333 res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
334 if (!res)
335 return -EINVAL;
336
337 apc->io_res.parent = res;
338 apc->io_res.name = "PCI IO space";
339 apc->io_res.start = res->start;
340 apc->io_res.end = res->end;
341 apc->io_res.flags = IORESOURCE_IO;
342
343 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
344 if (!res)
345 return -EINVAL;
346
347 apc->mem_res.parent = res;
348 apc->mem_res.name = "PCI memory space";
349 apc->mem_res.start = res->start;
350 apc->mem_res.end = res->end;
351 apc->mem_res.flags = IORESOURCE_MEM;
352
Gabor Juhos908339e2013-02-03 09:58:38 +0000353 apc->pci_controller.pci_ops = &ar724x_pci_ops;
Gabor Juhos34b134a2013-02-03 09:59:45 +0000354 apc->pci_controller.io_resource = &apc->io_res;
355 apc->pci_controller.mem_resource = &apc->mem_res;
Gabor Juhos908339e2013-02-03 09:58:38 +0000356
357 apc->link_up = ar724x_pci_check_link(apc);
358 if (!apc->link_up)
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000359 dev_warn(&pdev->dev, "PCIe link is down\n");
360
Gabor Juhos8b66d462013-02-03 10:00:16 +0000361 ar724x_pci_irq_init(apc, id);
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000362
Gabor Juhos908339e2013-02-03 09:58:38 +0000363 register_pci_controller(&apc->pci_controller);
Gabor Juhos58d2e9b2013-02-02 11:40:42 +0000364
365 return 0;
366}
367
368static struct platform_driver ar724x_pci_driver = {
369 .probe = ar724x_pci_probe,
370 .driver = {
371 .name = "ar724x-pci",
372 .owner = THIS_MODULE,
373 },
374};
375
376static int __init ar724x_pci_init(void)
377{
378 return platform_driver_register(&ar724x_pci_driver);
379}
380
381postcore_initcall(ar724x_pci_init);