Version:  2.0.40 2.2.26 2.4.37 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1

Linux/arch/mips/pci/pci-ar724x.c

  1 /*
  2  *  Atheros AR724X PCI host controller driver
  3  *
  4  *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
  5  *  Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
  6  *
  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 
 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 
 19 #define AR724X_PCI_REG_RESET            0x18
 20 #define AR724X_PCI_REG_INT_STATUS       0x4c
 21 #define AR724X_PCI_REG_INT_MASK         0x50
 22 
 23 #define AR724X_PCI_RESET_LINK_UP        BIT(0)
 24 
 25 #define AR724X_PCI_INT_DEV0             BIT(14)
 26 
 27 #define AR724X_PCI_IRQ_COUNT            1
 28 
 29 #define AR7240_BAR0_WAR_VALUE   0xffff
 30 
 31 #define AR724X_PCI_CMD_INIT     (PCI_COMMAND_MEMORY |           \
 32                                  PCI_COMMAND_MASTER |           \
 33                                  PCI_COMMAND_INVALIDATE |       \
 34                                  PCI_COMMAND_PARITY |           \
 35                                  PCI_COMMAND_SERR |             \
 36                                  PCI_COMMAND_FAST_BACK)
 37 
 38 struct ar724x_pci_controller {
 39         void __iomem *devcfg_base;
 40         void __iomem *ctrl_base;
 41         void __iomem *crp_base;
 42 
 43         int irq;
 44         int irq_base;
 45 
 46         bool link_up;
 47         bool bar0_is_cached;
 48         u32  bar0_value;
 49 
 50         struct pci_controller pci_controller;
 51         struct resource io_res;
 52         struct resource mem_res;
 53 };
 54 
 55 static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
 56 {
 57         u32 reset;
 58 
 59         reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
 60         return reset & AR724X_PCI_RESET_LINK_UP;
 61 }
 62 
 63 static inline struct ar724x_pci_controller *
 64 pci_bus_to_ar724x_controller(struct pci_bus *bus)
 65 {
 66         struct pci_controller *hose;
 67 
 68         hose = (struct pci_controller *) bus->sysdata;
 69         return container_of(hose, struct ar724x_pci_controller, pci_controller);
 70 }
 71 
 72 static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
 73                                   int where, int size, u32 value)
 74 {
 75         void __iomem *base;
 76         u32 data;
 77         int s;
 78 
 79         WARN_ON(where & (size - 1));
 80 
 81         if (!apc->link_up)
 82                 return PCIBIOS_DEVICE_NOT_FOUND;
 83 
 84         base = apc->crp_base;
 85         data = __raw_readl(base + (where & ~3));
 86 
 87         switch (size) {
 88         case 1:
 89                 s = ((where & 3) * 8);
 90                 data &= ~(0xff << s);
 91                 data |= ((value & 0xff) << s);
 92                 break;
 93         case 2:
 94                 s = ((where & 2) * 8);
 95                 data &= ~(0xffff << s);
 96                 data |= ((value & 0xffff) << s);
 97                 break;
 98         case 4:
 99                 data = value;
100                 break;
101         default:
102                 return PCIBIOS_BAD_REGISTER_NUMBER;
103         }
104 
105         __raw_writel(data, base + (where & ~3));
106         /* flush write */
107         __raw_readl(base + (where & ~3));
108 
109         return PCIBIOS_SUCCESSFUL;
110 }
111 
112 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
113                             int size, uint32_t *value)
114 {
115         struct ar724x_pci_controller *apc;
116         void __iomem *base;
117         u32 data;
118 
119         apc = pci_bus_to_ar724x_controller(bus);
120         if (!apc->link_up)
121                 return PCIBIOS_DEVICE_NOT_FOUND;
122 
123         if (devfn)
124                 return PCIBIOS_DEVICE_NOT_FOUND;
125 
126         base = apc->devcfg_base;
127         data = __raw_readl(base + (where & ~3));
128 
129         switch (size) {
130         case 1:
131                 if (where & 1)
132                         data >>= 8;
133                 if (where & 2)
134                         data >>= 16;
135                 data &= 0xff;
136                 break;
137         case 2:
138                 if (where & 2)
139                         data >>= 16;
140                 data &= 0xffff;
141                 break;
142         case 4:
143                 break;
144         default:
145                 return PCIBIOS_BAD_REGISTER_NUMBER;
146         }
147 
148         if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
149             apc->bar0_is_cached) {
150                 /* use the cached value */
151                 *value = apc->bar0_value;
152         } else {
153                 *value = data;
154         }
155 
156         return PCIBIOS_SUCCESSFUL;
157 }
158 
159 static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
160                              int size, uint32_t value)
161 {
162         struct ar724x_pci_controller *apc;
163         void __iomem *base;
164         u32 data;
165         int s;
166 
167         apc = pci_bus_to_ar724x_controller(bus);
168         if (!apc->link_up)
169                 return PCIBIOS_DEVICE_NOT_FOUND;
170 
171         if (devfn)
172                 return PCIBIOS_DEVICE_NOT_FOUND;
173 
174         if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) {
175                 if (value != 0xffffffff) {
176                         /*
177                          * WAR for a hw issue. If the BAR0 register of the
178                          * device is set to the proper base address, the
179                          * memory space of the device is not accessible.
180                          *
181                          * Cache the intended value so it can be read back,
182                          * and write a SoC specific constant value to the
183                          * BAR0 register in order to make the device memory
184                          * accessible.
185                          */
186                         apc->bar0_is_cached = true;
187                         apc->bar0_value = value;
188 
189                         value = AR7240_BAR0_WAR_VALUE;
190                 } else {
191                         apc->bar0_is_cached = false;
192                 }
193         }
194 
195         base = apc->devcfg_base;
196         data = __raw_readl(base + (where & ~3));
197 
198         switch (size) {
199         case 1:
200                 s = ((where & 3) * 8);
201                 data &= ~(0xff << s);
202                 data |= ((value & 0xff) << s);
203                 break;
204         case 2:
205                 s = ((where & 2) * 8);
206                 data &= ~(0xffff << s);
207                 data |= ((value & 0xffff) << s);
208                 break;
209         case 4:
210                 data = value;
211                 break;
212         default:
213                 return PCIBIOS_BAD_REGISTER_NUMBER;
214         }
215 
216         __raw_writel(data, base + (where & ~3));
217         /* flush write */
218         __raw_readl(base + (where & ~3));
219 
220         return PCIBIOS_SUCCESSFUL;
221 }
222 
223 static struct pci_ops ar724x_pci_ops = {
224         .read   = ar724x_pci_read,
225         .write  = ar724x_pci_write,
226 };
227 
228 static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
229 {
230         struct ar724x_pci_controller *apc;
231         void __iomem *base;
232         u32 pending;
233 
234         apc = irq_get_handler_data(irq);
235         base = apc->ctrl_base;
236 
237         pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
238                   __raw_readl(base + AR724X_PCI_REG_INT_MASK);
239 
240         if (pending & AR724X_PCI_INT_DEV0)
241                 generic_handle_irq(apc->irq_base + 0);
242 
243         else
244                 spurious_interrupt();
245 }
246 
247 static void ar724x_pci_irq_unmask(struct irq_data *d)
248 {
249         struct ar724x_pci_controller *apc;
250         void __iomem *base;
251         int offset;
252         u32 t;
253 
254         apc = irq_data_get_irq_chip_data(d);
255         base = apc->ctrl_base;
256         offset = apc->irq_base - d->irq;
257 
258         switch (offset) {
259         case 0:
260                 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
261                 __raw_writel(t | AR724X_PCI_INT_DEV0,
262                              base + AR724X_PCI_REG_INT_MASK);
263                 /* flush write */
264                 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
265         }
266 }
267 
268 static void ar724x_pci_irq_mask(struct irq_data *d)
269 {
270         struct ar724x_pci_controller *apc;
271         void __iomem *base;
272         int offset;
273         u32 t;
274 
275         apc = irq_data_get_irq_chip_data(d);
276         base = apc->ctrl_base;
277         offset = apc->irq_base - d->irq;
278 
279         switch (offset) {
280         case 0:
281                 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
282                 __raw_writel(t & ~AR724X_PCI_INT_DEV0,
283                              base + AR724X_PCI_REG_INT_MASK);
284 
285                 /* flush write */
286                 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
287 
288                 t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
289                 __raw_writel(t | AR724X_PCI_INT_DEV0,
290                              base + AR724X_PCI_REG_INT_STATUS);
291 
292                 /* flush write */
293                 __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
294         }
295 }
296 
297 static struct irq_chip ar724x_pci_irq_chip = {
298         .name           = "AR724X PCI ",
299         .irq_mask       = ar724x_pci_irq_mask,
300         .irq_unmask     = ar724x_pci_irq_unmask,
301         .irq_mask_ack   = ar724x_pci_irq_mask,
302 };
303 
304 static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc,
305                                 int id)
306 {
307         void __iomem *base;
308         int i;
309 
310         base = apc->ctrl_base;
311 
312         __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
313         __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
314 
315         apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT);
316 
317         for (i = apc->irq_base;
318              i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) {
319                 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
320                                          handle_level_irq);
321                 irq_set_chip_data(i, apc);
322         }
323 
324         irq_set_handler_data(apc->irq, apc);
325         irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
326 }
327 
328 static int ar724x_pci_probe(struct platform_device *pdev)
329 {
330         struct ar724x_pci_controller *apc;
331         struct resource *res;
332         int id;
333 
334         id = pdev->id;
335         if (id == -1)
336                 id = 0;
337 
338         apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
339                             GFP_KERNEL);
340         if (!apc)
341                 return -ENOMEM;
342 
343         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
344         apc->ctrl_base = devm_ioremap_resource(&pdev->dev, res);
345         if (IS_ERR(apc->ctrl_base))
346                 return PTR_ERR(apc->ctrl_base);
347 
348         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
349         apc->devcfg_base = devm_ioremap_resource(&pdev->dev, res);
350         if (IS_ERR(apc->devcfg_base))
351                 return PTR_ERR(apc->devcfg_base);
352 
353         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base");
354         apc->crp_base = devm_ioremap_resource(&pdev->dev, res);
355         if (IS_ERR(apc->crp_base))
356                 return PTR_ERR(apc->crp_base);
357 
358         apc->irq = platform_get_irq(pdev, 0);
359         if (apc->irq < 0)
360                 return -EINVAL;
361 
362         res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
363         if (!res)
364                 return -EINVAL;
365 
366         apc->io_res.parent = res;
367         apc->io_res.name = "PCI IO space";
368         apc->io_res.start = res->start;
369         apc->io_res.end = res->end;
370         apc->io_res.flags = IORESOURCE_IO;
371 
372         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
373         if (!res)
374                 return -EINVAL;
375 
376         apc->mem_res.parent = res;
377         apc->mem_res.name = "PCI memory space";
378         apc->mem_res.start = res->start;
379         apc->mem_res.end = res->end;
380         apc->mem_res.flags = IORESOURCE_MEM;
381 
382         apc->pci_controller.pci_ops = &ar724x_pci_ops;
383         apc->pci_controller.io_resource = &apc->io_res;
384         apc->pci_controller.mem_resource = &apc->mem_res;
385 
386         apc->link_up = ar724x_pci_check_link(apc);
387         if (!apc->link_up)
388                 dev_warn(&pdev->dev, "PCIe link is down\n");
389 
390         ar724x_pci_irq_init(apc, id);
391 
392         ar724x_pci_local_write(apc, PCI_COMMAND, 4, AR724X_PCI_CMD_INIT);
393 
394         register_pci_controller(&apc->pci_controller);
395 
396         return 0;
397 }
398 
399 static struct platform_driver ar724x_pci_driver = {
400         .probe = ar724x_pci_probe,
401         .driver = {
402                 .name = "ar724x-pci",
403         },
404 };
405 
406 static int __init ar724x_pci_init(void)
407 {
408         return platform_driver_register(&ar724x_pci_driver);
409 }
410 
411 postcore_initcall(ar724x_pci_init);
412 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us