diff options
Diffstat (limited to 'arch/sparc/kernel/leon_pci_grpci1.c')
-rw-r--r-- | arch/sparc/kernel/leon_pci_grpci1.c | 724 |
1 files changed, 724 insertions, 0 deletions
diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c new file mode 100644 index 000000000000..7739a54315e2 --- /dev/null +++ b/arch/sparc/kernel/leon_pci_grpci1.c | |||
@@ -0,0 +1,724 @@ | |||
1 | /* | ||
2 | * leon_pci_grpci1.c: GRPCI1 Host PCI driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Aeroflex Gaisler AB | ||
5 | * | ||
6 | * This GRPCI1 driver does not support PCI interrupts taken from | ||
7 | * GPIO pins. Interrupt generation at PCI parity and system error | ||
8 | * detection is by default turned off since some GRPCI1 cores does | ||
9 | * not support detection. It can be turned on from the bootloader | ||
10 | * using the all_pci_errors property. | ||
11 | * | ||
12 | * Contributors: Daniel Hellstrom <daniel@gaisler.com> | ||
13 | */ | ||
14 | |||
15 | #include <linux/of_device.h> | ||
16 | #include <linux/export.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/of_irq.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/pci.h> | ||
21 | |||
22 | #include <asm/leon_pci.h> | ||
23 | #include <asm/sections.h> | ||
24 | #include <asm/vaddrs.h> | ||
25 | #include <asm/leon.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include "irq.h" | ||
29 | |||
30 | /* Enable/Disable Debugging Configuration Space Access */ | ||
31 | #undef GRPCI1_DEBUG_CFGACCESS | ||
32 | |||
33 | /* | ||
34 | * GRPCI1 APB Register MAP | ||
35 | */ | ||
36 | struct grpci1_regs { | ||
37 | unsigned int cfg_stat; /* 0x00 Configuration / Status */ | ||
38 | unsigned int bar0; /* 0x04 BAR0 (RO) */ | ||
39 | unsigned int page0; /* 0x08 PAGE0 (RO) */ | ||
40 | unsigned int bar1; /* 0x0C BAR1 (RO) */ | ||
41 | unsigned int page1; /* 0x10 PAGE1 */ | ||
42 | unsigned int iomap; /* 0x14 IO Map */ | ||
43 | unsigned int stat_cmd; /* 0x18 PCI Status & Command (RO) */ | ||
44 | unsigned int irq; /* 0x1C Interrupt register */ | ||
45 | }; | ||
46 | |||
47 | #define REGLOAD(a) (be32_to_cpu(__raw_readl(&(a)))) | ||
48 | #define REGSTORE(a, v) (__raw_writel(cpu_to_be32(v), &(a))) | ||
49 | |||
50 | #define PAGE0_BTEN_BIT 0 | ||
51 | #define PAGE0_BTEN (1 << PAGE0_BTEN_BIT) | ||
52 | |||
53 | #define CFGSTAT_HOST_BIT 13 | ||
54 | #define CFGSTAT_CTO_BIT 8 | ||
55 | #define CFGSTAT_HOST (1 << CFGSTAT_HOST_BIT) | ||
56 | #define CFGSTAT_CTO (1 << CFGSTAT_CTO_BIT) | ||
57 | |||
58 | #define IRQ_DPE (1 << 9) | ||
59 | #define IRQ_SSE (1 << 8) | ||
60 | #define IRQ_RMA (1 << 7) | ||
61 | #define IRQ_RTA (1 << 6) | ||
62 | #define IRQ_STA (1 << 5) | ||
63 | #define IRQ_DPED (1 << 4) | ||
64 | #define IRQ_INTD (1 << 3) | ||
65 | #define IRQ_INTC (1 << 2) | ||
66 | #define IRQ_INTB (1 << 1) | ||
67 | #define IRQ_INTA (1 << 0) | ||
68 | #define IRQ_DEF_ERRORS (IRQ_RMA | IRQ_RTA | IRQ_STA) | ||
69 | #define IRQ_ALL_ERRORS (IRQ_DPED | IRQ_DEF_ERRORS | IRQ_SSE | IRQ_DPE) | ||
70 | #define IRQ_INTX (IRQ_INTA | IRQ_INTB | IRQ_INTC | IRQ_INTD) | ||
71 | #define IRQ_MASK_BIT 16 | ||
72 | |||
73 | #define DEF_PCI_ERRORS (PCI_STATUS_SIG_TARGET_ABORT | \ | ||
74 | PCI_STATUS_REC_TARGET_ABORT | \ | ||
75 | PCI_STATUS_REC_MASTER_ABORT) | ||
76 | #define ALL_PCI_ERRORS (PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY | \ | ||
77 | PCI_STATUS_SIG_SYSTEM_ERROR | DEF_PCI_ERRORS) | ||
78 | |||
79 | #define TGT 256 | ||
80 | |||
81 | struct grpci1_priv { | ||
82 | struct leon_pci_info info; /* must be on top of this structure */ | ||
83 | struct grpci1_regs *regs; /* GRPCI register map */ | ||
84 | struct device *dev; | ||
85 | int pci_err_mask; /* STATUS register error mask */ | ||
86 | int irq; /* LEON irqctrl GRPCI IRQ */ | ||
87 | unsigned char irq_map[4]; /* GRPCI nexus PCI INTX# IRQs */ | ||
88 | unsigned int irq_err; /* GRPCI nexus Virt Error IRQ */ | ||
89 | |||
90 | /* AHB PCI Windows */ | ||
91 | unsigned long pci_area; /* MEMORY */ | ||
92 | unsigned long pci_area_end; | ||
93 | unsigned long pci_io; /* I/O */ | ||
94 | unsigned long pci_conf; /* CONFIGURATION */ | ||
95 | unsigned long pci_conf_end; | ||
96 | unsigned long pci_io_va; | ||
97 | }; | ||
98 | |||
99 | static struct grpci1_priv *grpci1priv; | ||
100 | |||
101 | static int grpci1_cfg_w32(struct grpci1_priv *priv, unsigned int bus, | ||
102 | unsigned int devfn, int where, u32 val); | ||
103 | |||
104 | int grpci1_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
105 | { | ||
106 | struct grpci1_priv *priv = dev->bus->sysdata; | ||
107 | int irq_group; | ||
108 | |||
109 | /* Use default IRQ decoding on PCI BUS0 according slot numbering */ | ||
110 | irq_group = slot & 0x3; | ||
111 | pin = ((pin - 1) + irq_group) & 0x3; | ||
112 | |||
113 | return priv->irq_map[pin]; | ||
114 | } | ||
115 | |||
116 | static int grpci1_cfg_r32(struct grpci1_priv *priv, unsigned int bus, | ||
117 | unsigned int devfn, int where, u32 *val) | ||
118 | { | ||
119 | u32 *pci_conf, tmp, cfg; | ||
120 | |||
121 | if (where & 0x3) | ||
122 | return -EINVAL; | ||
123 | |||
124 | if (bus == 0) { | ||
125 | devfn += (0x8 * 6); /* start at AD16=Device0 */ | ||
126 | } else if (bus == TGT) { | ||
127 | bus = 0; | ||
128 | devfn = 0; /* special case: bridge controller itself */ | ||
129 | } | ||
130 | |||
131 | /* Select bus */ | ||
132 | cfg = REGLOAD(priv->regs->cfg_stat); | ||
133 | REGSTORE(priv->regs->cfg_stat, (cfg & ~(0xf << 23)) | (bus << 23)); | ||
134 | |||
135 | /* do read access */ | ||
136 | pci_conf = (u32 *) (priv->pci_conf | (devfn << 8) | (where & 0xfc)); | ||
137 | tmp = LEON3_BYPASS_LOAD_PA(pci_conf); | ||
138 | |||
139 | /* check if master abort was received */ | ||
140 | if (REGLOAD(priv->regs->cfg_stat) & CFGSTAT_CTO) { | ||
141 | *val = 0xffffffff; | ||
142 | /* Clear Master abort bit in PCI cfg space (is set) */ | ||
143 | tmp = REGLOAD(priv->regs->stat_cmd); | ||
144 | grpci1_cfg_w32(priv, TGT, 0, PCI_COMMAND, tmp); | ||
145 | } else { | ||
146 | /* Bus always little endian (unaffected by byte-swapping) */ | ||
147 | *val = flip_dword(tmp); | ||
148 | } | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int grpci1_cfg_r16(struct grpci1_priv *priv, unsigned int bus, | ||
154 | unsigned int devfn, int where, u32 *val) | ||
155 | { | ||
156 | u32 v; | ||
157 | int ret; | ||
158 | |||
159 | if (where & 0x1) | ||
160 | return -EINVAL; | ||
161 | ret = grpci1_cfg_r32(priv, bus, devfn, where & ~0x3, &v); | ||
162 | *val = 0xffff & (v >> (8 * (where & 0x3))); | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static int grpci1_cfg_r8(struct grpci1_priv *priv, unsigned int bus, | ||
167 | unsigned int devfn, int where, u32 *val) | ||
168 | { | ||
169 | u32 v; | ||
170 | int ret; | ||
171 | |||
172 | ret = grpci1_cfg_r32(priv, bus, devfn, where & ~0x3, &v); | ||
173 | *val = 0xff & (v >> (8 * (where & 3))); | ||
174 | |||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | static int grpci1_cfg_w32(struct grpci1_priv *priv, unsigned int bus, | ||
179 | unsigned int devfn, int where, u32 val) | ||
180 | { | ||
181 | unsigned int *pci_conf; | ||
182 | u32 cfg; | ||
183 | |||
184 | if (where & 0x3) | ||
185 | return -EINVAL; | ||
186 | |||
187 | if (bus == 0) { | ||
188 | devfn += (0x8 * 6); /* start at AD16=Device0 */ | ||
189 | } else if (bus == TGT) { | ||
190 | bus = 0; | ||
191 | devfn = 0; /* special case: bridge controller itself */ | ||
192 | } | ||
193 | |||
194 | /* Select bus */ | ||
195 | cfg = REGLOAD(priv->regs->cfg_stat); | ||
196 | REGSTORE(priv->regs->cfg_stat, (cfg & ~(0xf << 23)) | (bus << 23)); | ||
197 | |||
198 | pci_conf = (unsigned int *) (priv->pci_conf | | ||
199 | (devfn << 8) | (where & 0xfc)); | ||
200 | LEON3_BYPASS_STORE_PA(pci_conf, flip_dword(val)); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int grpci1_cfg_w16(struct grpci1_priv *priv, unsigned int bus, | ||
206 | unsigned int devfn, int where, u32 val) | ||
207 | { | ||
208 | int ret; | ||
209 | u32 v; | ||
210 | |||
211 | if (where & 0x1) | ||
212 | return -EINVAL; | ||
213 | ret = grpci1_cfg_r32(priv, bus, devfn, where&~3, &v); | ||
214 | if (ret) | ||
215 | return ret; | ||
216 | v = (v & ~(0xffff << (8 * (where & 0x3)))) | | ||
217 | ((0xffff & val) << (8 * (where & 0x3))); | ||
218 | return grpci1_cfg_w32(priv, bus, devfn, where & ~0x3, v); | ||
219 | } | ||
220 | |||
221 | static int grpci1_cfg_w8(struct grpci1_priv *priv, unsigned int bus, | ||
222 | unsigned int devfn, int where, u32 val) | ||
223 | { | ||
224 | int ret; | ||
225 | u32 v; | ||
226 | |||
227 | ret = grpci1_cfg_r32(priv, bus, devfn, where & ~0x3, &v); | ||
228 | if (ret != 0) | ||
229 | return ret; | ||
230 | v = (v & ~(0xff << (8 * (where & 0x3)))) | | ||
231 | ((0xff & val) << (8 * (where & 0x3))); | ||
232 | return grpci1_cfg_w32(priv, bus, devfn, where & ~0x3, v); | ||
233 | } | ||
234 | |||
235 | /* Read from Configuration Space. When entering here the PCI layer has taken | ||
236 | * the pci_lock spinlock and IRQ is off. | ||
237 | */ | ||
238 | static int grpci1_read_config(struct pci_bus *bus, unsigned int devfn, | ||
239 | int where, int size, u32 *val) | ||
240 | { | ||
241 | struct grpci1_priv *priv = grpci1priv; | ||
242 | unsigned int busno = bus->number; | ||
243 | int ret; | ||
244 | |||
245 | if (PCI_SLOT(devfn) > 15 || busno > 15) { | ||
246 | *val = ~0; | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | switch (size) { | ||
251 | case 1: | ||
252 | ret = grpci1_cfg_r8(priv, busno, devfn, where, val); | ||
253 | break; | ||
254 | case 2: | ||
255 | ret = grpci1_cfg_r16(priv, busno, devfn, where, val); | ||
256 | break; | ||
257 | case 4: | ||
258 | ret = grpci1_cfg_r32(priv, busno, devfn, where, val); | ||
259 | break; | ||
260 | default: | ||
261 | ret = -EINVAL; | ||
262 | break; | ||
263 | } | ||
264 | |||
265 | #ifdef GRPCI1_DEBUG_CFGACCESS | ||
266 | printk(KERN_INFO | ||
267 | "grpci1_read_config: [%02x:%02x:%x] ofs=%d val=%x size=%d\n", | ||
268 | busno, PCI_SLOT(devfn), PCI_FUNC(devfn), where, *val, size); | ||
269 | #endif | ||
270 | |||
271 | return ret; | ||
272 | } | ||
273 | |||
274 | /* Write to Configuration Space. When entering here the PCI layer has taken | ||
275 | * the pci_lock spinlock and IRQ is off. | ||
276 | */ | ||
277 | static int grpci1_write_config(struct pci_bus *bus, unsigned int devfn, | ||
278 | int where, int size, u32 val) | ||
279 | { | ||
280 | struct grpci1_priv *priv = grpci1priv; | ||
281 | unsigned int busno = bus->number; | ||
282 | |||
283 | if (PCI_SLOT(devfn) > 15 || busno > 15) | ||
284 | return 0; | ||
285 | |||
286 | #ifdef GRPCI1_DEBUG_CFGACCESS | ||
287 | printk(KERN_INFO | ||
288 | "grpci1_write_config: [%02x:%02x:%x] ofs=%d size=%d val=%x\n", | ||
289 | busno, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); | ||
290 | #endif | ||
291 | |||
292 | switch (size) { | ||
293 | default: | ||
294 | return -EINVAL; | ||
295 | case 1: | ||
296 | return grpci1_cfg_w8(priv, busno, devfn, where, val); | ||
297 | case 2: | ||
298 | return grpci1_cfg_w16(priv, busno, devfn, where, val); | ||
299 | case 4: | ||
300 | return grpci1_cfg_w32(priv, busno, devfn, where, val); | ||
301 | } | ||
302 | } | ||
303 | |||
304 | static struct pci_ops grpci1_ops = { | ||
305 | .read = grpci1_read_config, | ||
306 | .write = grpci1_write_config, | ||
307 | }; | ||
308 | |||
309 | /* GENIRQ IRQ chip implementation for grpci1 irqmode=0..2. In configuration | ||
310 | * 3 where all PCI Interrupts has a separate IRQ on the system IRQ controller | ||
311 | * this is not needed and the standard IRQ controller can be used. | ||
312 | */ | ||
313 | |||
314 | static void grpci1_mask_irq(struct irq_data *data) | ||
315 | { | ||
316 | u32 irqidx; | ||
317 | struct grpci1_priv *priv = grpci1priv; | ||
318 | |||
319 | irqidx = (u32)data->chip_data - 1; | ||
320 | if (irqidx > 3) /* only mask PCI interrupts here */ | ||
321 | return; | ||
322 | irqidx += IRQ_MASK_BIT; | ||
323 | |||
324 | REGSTORE(priv->regs->irq, REGLOAD(priv->regs->irq) & ~(1 << irqidx)); | ||
325 | } | ||
326 | |||
327 | static void grpci1_unmask_irq(struct irq_data *data) | ||
328 | { | ||
329 | u32 irqidx; | ||
330 | struct grpci1_priv *priv = grpci1priv; | ||
331 | |||
332 | irqidx = (u32)data->chip_data - 1; | ||
333 | if (irqidx > 3) /* only unmask PCI interrupts here */ | ||
334 | return; | ||
335 | irqidx += IRQ_MASK_BIT; | ||
336 | |||
337 | REGSTORE(priv->regs->irq, REGLOAD(priv->regs->irq) | (1 << irqidx)); | ||
338 | } | ||
339 | |||
340 | static unsigned int grpci1_startup_irq(struct irq_data *data) | ||
341 | { | ||
342 | grpci1_unmask_irq(data); | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static void grpci1_shutdown_irq(struct irq_data *data) | ||
347 | { | ||
348 | grpci1_mask_irq(data); | ||
349 | } | ||
350 | |||
351 | static struct irq_chip grpci1_irq = { | ||
352 | .name = "grpci1", | ||
353 | .irq_startup = grpci1_startup_irq, | ||
354 | .irq_shutdown = grpci1_shutdown_irq, | ||
355 | .irq_mask = grpci1_mask_irq, | ||
356 | .irq_unmask = grpci1_unmask_irq, | ||
357 | }; | ||
358 | |||
359 | /* Handle one or multiple IRQs from the PCI core */ | ||
360 | static void grpci1_pci_flow_irq(unsigned int irq, struct irq_desc *desc) | ||
361 | { | ||
362 | struct grpci1_priv *priv = grpci1priv; | ||
363 | int i, ack = 0; | ||
364 | unsigned int irqreg; | ||
365 | |||
366 | irqreg = REGLOAD(priv->regs->irq); | ||
367 | irqreg = (irqreg >> IRQ_MASK_BIT) & irqreg; | ||
368 | |||
369 | /* Error Interrupt? */ | ||
370 | if (irqreg & IRQ_ALL_ERRORS) { | ||
371 | generic_handle_irq(priv->irq_err); | ||
372 | ack = 1; | ||
373 | } | ||
374 | |||
375 | /* PCI Interrupt? */ | ||
376 | if (irqreg & IRQ_INTX) { | ||
377 | /* Call respective PCI Interrupt handler */ | ||
378 | for (i = 0; i < 4; i++) { | ||
379 | if (irqreg & (1 << i)) | ||
380 | generic_handle_irq(priv->irq_map[i]); | ||
381 | } | ||
382 | ack = 1; | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * Call "first level" IRQ chip end-of-irq handler. It will ACK LEON IRQ | ||
387 | * Controller, this must be done after IRQ sources have been handled to | ||
388 | * avoid double IRQ generation | ||
389 | */ | ||
390 | if (ack) | ||
391 | desc->irq_data.chip->irq_eoi(&desc->irq_data); | ||
392 | } | ||
393 | |||
394 | /* Create a virtual IRQ */ | ||
395 | static unsigned int grpci1_build_device_irq(unsigned int irq) | ||
396 | { | ||
397 | unsigned int virq = 0, pil; | ||
398 | |||
399 | pil = 1 << 8; | ||
400 | virq = irq_alloc(irq, pil); | ||
401 | if (virq == 0) | ||
402 | goto out; | ||
403 | |||
404 | irq_set_chip_and_handler_name(virq, &grpci1_irq, handle_simple_irq, | ||
405 | "pcilvl"); | ||
406 | irq_set_chip_data(virq, (void *)irq); | ||
407 | |||
408 | out: | ||
409 | return virq; | ||
410 | } | ||
411 | |||
412 | /* | ||
413 | * Initialize mappings AMBA<->PCI, clear IRQ state, setup PCI interface | ||
414 | * | ||
415 | * Target BARs: | ||
416 | * BAR0: unused in this implementation | ||
417 | * BAR1: peripheral DMA to host's memory (size at least 256MByte) | ||
418 | * BAR2..BAR5: not implemented in hardware | ||
419 | */ | ||
420 | void grpci1_hw_init(struct grpci1_priv *priv) | ||
421 | { | ||
422 | u32 ahbadr, bar_sz, data, pciadr; | ||
423 | struct grpci1_regs *regs = priv->regs; | ||
424 | |||
425 | /* set 1:1 mapping between AHB -> PCI memory space */ | ||
426 | REGSTORE(regs->cfg_stat, priv->pci_area & 0xf0000000); | ||
427 | |||
428 | /* map PCI accesses to target BAR1 to Linux kernel memory 1:1 */ | ||
429 | ahbadr = 0xf0000000 & (u32)__pa(PAGE_ALIGN((unsigned long) &_end)); | ||
430 | REGSTORE(regs->page1, ahbadr); | ||
431 | |||
432 | /* translate I/O accesses to 0, I/O Space always @ PCI low 64Kbytes */ | ||
433 | REGSTORE(regs->iomap, REGLOAD(regs->iomap) & 0x0000ffff); | ||
434 | |||
435 | /* disable and clear pending interrupts */ | ||
436 | REGSTORE(regs->irq, 0); | ||
437 | |||
438 | /* Setup BAR0 outside access range so that it does not conflict with | ||
439 | * peripheral DMA. There is no need to set up the PAGE0 register. | ||
440 | */ | ||
441 | grpci1_cfg_w32(priv, TGT, 0, PCI_BASE_ADDRESS_0, 0xffffffff); | ||
442 | grpci1_cfg_r32(priv, TGT, 0, PCI_BASE_ADDRESS_0, &bar_sz); | ||
443 | bar_sz = ~bar_sz + 1; | ||
444 | pciadr = priv->pci_area - bar_sz; | ||
445 | grpci1_cfg_w32(priv, TGT, 0, PCI_BASE_ADDRESS_0, pciadr); | ||
446 | |||
447 | /* | ||
448 | * Setup the Host's PCI Target BAR1 for other peripherals to access, | ||
449 | * and do DMA to the host's memory. | ||
450 | */ | ||
451 | grpci1_cfg_w32(priv, TGT, 0, PCI_BASE_ADDRESS_1, ahbadr); | ||
452 | |||
453 | /* | ||
454 | * Setup Latency Timer and cache line size. Default cache line | ||
455 | * size will result in poor performance (256 word fetches), 0xff | ||
456 | * will set it according to the max size of the PCI FIFO. | ||
457 | */ | ||
458 | grpci1_cfg_w8(priv, TGT, 0, PCI_CACHE_LINE_SIZE, 0xff); | ||
459 | grpci1_cfg_w8(priv, TGT, 0, PCI_LATENCY_TIMER, 0x40); | ||
460 | |||
461 | /* set as bus master, enable pci memory responses, clear status bits */ | ||
462 | grpci1_cfg_r32(priv, TGT, 0, PCI_COMMAND, &data); | ||
463 | data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); | ||
464 | grpci1_cfg_w32(priv, TGT, 0, PCI_COMMAND, data); | ||
465 | } | ||
466 | |||
467 | static irqreturn_t grpci1_jump_interrupt(int irq, void *arg) | ||
468 | { | ||
469 | struct grpci1_priv *priv = arg; | ||
470 | dev_err(priv->dev, "Jump IRQ happened\n"); | ||
471 | return IRQ_NONE; | ||
472 | } | ||
473 | |||
474 | /* Handle GRPCI1 Error Interrupt */ | ||
475 | static irqreturn_t grpci1_err_interrupt(int irq, void *arg) | ||
476 | { | ||
477 | struct grpci1_priv *priv = arg; | ||
478 | u32 status; | ||
479 | |||
480 | grpci1_cfg_r16(priv, TGT, 0, PCI_STATUS, &status); | ||
481 | status &= priv->pci_err_mask; | ||
482 | |||
483 | if (status == 0) | ||
484 | return IRQ_NONE; | ||
485 | |||
486 | if (status & PCI_STATUS_PARITY) | ||
487 | dev_err(priv->dev, "Data Parity Error\n"); | ||
488 | |||
489 | if (status & PCI_STATUS_SIG_TARGET_ABORT) | ||
490 | dev_err(priv->dev, "Signalled Target Abort\n"); | ||
491 | |||
492 | if (status & PCI_STATUS_REC_TARGET_ABORT) | ||
493 | dev_err(priv->dev, "Received Target Abort\n"); | ||
494 | |||
495 | if (status & PCI_STATUS_REC_MASTER_ABORT) | ||
496 | dev_err(priv->dev, "Received Master Abort\n"); | ||
497 | |||
498 | if (status & PCI_STATUS_SIG_SYSTEM_ERROR) | ||
499 | dev_err(priv->dev, "Signalled System Error\n"); | ||
500 | |||
501 | if (status & PCI_STATUS_DETECTED_PARITY) | ||
502 | dev_err(priv->dev, "Parity Error\n"); | ||
503 | |||
504 | /* Clear handled INT TYPE IRQs */ | ||
505 | grpci1_cfg_w16(priv, TGT, 0, PCI_STATUS, status); | ||
506 | |||
507 | return IRQ_HANDLED; | ||
508 | } | ||
509 | |||
510 | static int grpci1_of_probe(struct platform_device *ofdev) | ||
511 | { | ||
512 | struct grpci1_regs *regs; | ||
513 | struct grpci1_priv *priv; | ||
514 | int err, len; | ||
515 | const int *tmp; | ||
516 | u32 cfg, size, err_mask; | ||
517 | struct resource *res; | ||
518 | |||
519 | if (grpci1priv) { | ||
520 | dev_err(&ofdev->dev, "only one GRPCI1 supported\n"); | ||
521 | return -ENODEV; | ||
522 | } | ||
523 | |||
524 | if (ofdev->num_resources < 3) { | ||
525 | dev_err(&ofdev->dev, "not enough APB/AHB resources\n"); | ||
526 | return -EIO; | ||
527 | } | ||
528 | |||
529 | priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL); | ||
530 | if (!priv) { | ||
531 | dev_err(&ofdev->dev, "memory allocation failed\n"); | ||
532 | return -ENOMEM; | ||
533 | } | ||
534 | platform_set_drvdata(ofdev, priv); | ||
535 | priv->dev = &ofdev->dev; | ||
536 | |||
537 | /* find device register base address */ | ||
538 | res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); | ||
539 | regs = devm_request_and_ioremap(&ofdev->dev, res); | ||
540 | if (!regs) { | ||
541 | dev_err(&ofdev->dev, "io-regs mapping failed\n"); | ||
542 | return -EADDRNOTAVAIL; | ||
543 | } | ||
544 | |||
545 | /* | ||
546 | * check that we're in Host Slot and that we can act as a Host Bridge | ||
547 | * and not only as target/peripheral. | ||
548 | */ | ||
549 | cfg = REGLOAD(regs->cfg_stat); | ||
550 | if ((cfg & CFGSTAT_HOST) == 0) { | ||
551 | dev_err(&ofdev->dev, "not in host system slot\n"); | ||
552 | return -EIO; | ||
553 | } | ||
554 | |||
555 | /* check that BAR1 support 256 MByte so that we can map kernel space */ | ||
556 | REGSTORE(regs->page1, 0xffffffff); | ||
557 | size = ~REGLOAD(regs->page1) + 1; | ||
558 | if (size < 0x10000000) { | ||
559 | dev_err(&ofdev->dev, "BAR1 must be at least 256MByte\n"); | ||
560 | return -EIO; | ||
561 | } | ||
562 | |||
563 | /* hardware must support little-endian PCI (byte-twisting) */ | ||
564 | if ((REGLOAD(regs->page0) & PAGE0_BTEN) == 0) { | ||
565 | dev_err(&ofdev->dev, "byte-twisting is required\n"); | ||
566 | return -EIO; | ||
567 | } | ||
568 | |||
569 | priv->regs = regs; | ||
570 | priv->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); | ||
571 | dev_info(&ofdev->dev, "host found at 0x%p, irq%d\n", regs, priv->irq); | ||
572 | |||
573 | /* Find PCI Memory, I/O and Configuration Space Windows */ | ||
574 | priv->pci_area = ofdev->resource[1].start; | ||
575 | priv->pci_area_end = ofdev->resource[1].end+1; | ||
576 | priv->pci_io = ofdev->resource[2].start; | ||
577 | priv->pci_conf = ofdev->resource[2].start + 0x10000; | ||
578 | priv->pci_conf_end = priv->pci_conf + 0x10000; | ||
579 | priv->pci_io_va = (unsigned long)ioremap(priv->pci_io, 0x10000); | ||
580 | if (!priv->pci_io_va) { | ||
581 | dev_err(&ofdev->dev, "unable to map PCI I/O area\n"); | ||
582 | return -EIO; | ||
583 | } | ||
584 | |||
585 | printk(KERN_INFO | ||
586 | "GRPCI1: MEMORY SPACE [0x%08lx - 0x%08lx]\n" | ||
587 | " I/O SPACE [0x%08lx - 0x%08lx]\n" | ||
588 | " CONFIG SPACE [0x%08lx - 0x%08lx]\n", | ||
589 | priv->pci_area, priv->pci_area_end-1, | ||
590 | priv->pci_io, priv->pci_conf-1, | ||
591 | priv->pci_conf, priv->pci_conf_end-1); | ||
592 | |||
593 | /* | ||
594 | * I/O Space resources in I/O Window mapped into Virtual Adr Space | ||
595 | * We never use low 4KB because some devices seem have problems using | ||
596 | * address 0. | ||
597 | */ | ||
598 | priv->info.io_space.name = "GRPCI1 PCI I/O Space"; | ||
599 | priv->info.io_space.start = priv->pci_io_va + 0x1000; | ||
600 | priv->info.io_space.end = priv->pci_io_va + 0x10000 - 1; | ||
601 | priv->info.io_space.flags = IORESOURCE_IO; | ||
602 | |||
603 | /* | ||
604 | * grpci1 has no prefetchable memory, map everything as | ||
605 | * non-prefetchable memory | ||
606 | */ | ||
607 | priv->info.mem_space.name = "GRPCI1 PCI MEM Space"; | ||
608 | priv->info.mem_space.start = priv->pci_area; | ||
609 | priv->info.mem_space.end = priv->pci_area_end - 1; | ||
610 | priv->info.mem_space.flags = IORESOURCE_MEM; | ||
611 | |||
612 | if (request_resource(&iomem_resource, &priv->info.mem_space) < 0) { | ||
613 | dev_err(&ofdev->dev, "unable to request PCI memory area\n"); | ||
614 | err = -ENOMEM; | ||
615 | goto err1; | ||
616 | } | ||
617 | |||
618 | if (request_resource(&ioport_resource, &priv->info.io_space) < 0) { | ||
619 | dev_err(&ofdev->dev, "unable to request PCI I/O area\n"); | ||
620 | err = -ENOMEM; | ||
621 | goto err2; | ||
622 | } | ||
623 | |||
624 | /* setup maximum supported PCI buses */ | ||
625 | priv->info.busn.name = "GRPCI1 busn"; | ||
626 | priv->info.busn.start = 0; | ||
627 | priv->info.busn.end = 15; | ||
628 | |||
629 | grpci1priv = priv; | ||
630 | |||
631 | /* Initialize hardware */ | ||
632 | grpci1_hw_init(priv); | ||
633 | |||
634 | /* | ||
635 | * Get PCI Interrupt to System IRQ mapping and setup IRQ handling | ||
636 | * Error IRQ. All PCI and PCI-Error interrupts are shared using the | ||
637 | * same system IRQ. | ||
638 | */ | ||
639 | leon_update_virq_handling(priv->irq, grpci1_pci_flow_irq, "pcilvl", 0); | ||
640 | |||
641 | priv->irq_map[0] = grpci1_build_device_irq(1); | ||
642 | priv->irq_map[1] = grpci1_build_device_irq(2); | ||
643 | priv->irq_map[2] = grpci1_build_device_irq(3); | ||
644 | priv->irq_map[3] = grpci1_build_device_irq(4); | ||
645 | priv->irq_err = grpci1_build_device_irq(5); | ||
646 | |||
647 | printk(KERN_INFO " PCI INTA..D#: IRQ%d, IRQ%d, IRQ%d, IRQ%d\n", | ||
648 | priv->irq_map[0], priv->irq_map[1], priv->irq_map[2], | ||
649 | priv->irq_map[3]); | ||
650 | |||
651 | /* Enable IRQs on LEON IRQ controller */ | ||
652 | err = devm_request_irq(&ofdev->dev, priv->irq, grpci1_jump_interrupt, 0, | ||
653 | "GRPCI1_JUMP", priv); | ||
654 | if (err) { | ||
655 | dev_err(&ofdev->dev, "ERR IRQ request failed: %d\n", err); | ||
656 | goto err3; | ||
657 | } | ||
658 | |||
659 | /* Setup IRQ handler for access errors */ | ||
660 | err = devm_request_irq(&ofdev->dev, priv->irq_err, | ||
661 | grpci1_err_interrupt, IRQF_SHARED, "GRPCI1_ERR", | ||
662 | priv); | ||
663 | if (err) { | ||
664 | dev_err(&ofdev->dev, "ERR VIRQ request failed: %d\n", err); | ||
665 | goto err3; | ||
666 | } | ||
667 | |||
668 | tmp = of_get_property(ofdev->dev.of_node, "all_pci_errors", &len); | ||
669 | if (tmp && (len == 4)) { | ||
670 | priv->pci_err_mask = ALL_PCI_ERRORS; | ||
671 | err_mask = IRQ_ALL_ERRORS << IRQ_MASK_BIT; | ||
672 | } else { | ||
673 | priv->pci_err_mask = DEF_PCI_ERRORS; | ||
674 | err_mask = IRQ_DEF_ERRORS << IRQ_MASK_BIT; | ||
675 | } | ||
676 | |||
677 | /* | ||
678 | * Enable Error Interrupts. PCI interrupts are unmasked once request_irq | ||
679 | * is called by the PCI Device drivers | ||
680 | */ | ||
681 | REGSTORE(regs->irq, err_mask); | ||
682 | |||
683 | /* Init common layer and scan buses */ | ||
684 | priv->info.ops = &grpci1_ops; | ||
685 | priv->info.map_irq = grpci1_map_irq; | ||
686 | leon_pci_init(ofdev, &priv->info); | ||
687 | |||
688 | return 0; | ||
689 | |||
690 | err3: | ||
691 | release_resource(&priv->info.io_space); | ||
692 | err2: | ||
693 | release_resource(&priv->info.mem_space); | ||
694 | err1: | ||
695 | iounmap((void *)priv->pci_io_va); | ||
696 | grpci1priv = NULL; | ||
697 | return err; | ||
698 | } | ||
699 | |||
700 | static struct of_device_id grpci1_of_match[] = { | ||
701 | { | ||
702 | .name = "GAISLER_PCIFBRG", | ||
703 | }, | ||
704 | { | ||
705 | .name = "01_014", | ||
706 | }, | ||
707 | {}, | ||
708 | }; | ||
709 | |||
710 | static struct platform_driver grpci1_of_driver = { | ||
711 | .driver = { | ||
712 | .name = "grpci1", | ||
713 | .owner = THIS_MODULE, | ||
714 | .of_match_table = grpci1_of_match, | ||
715 | }, | ||
716 | .probe = grpci1_of_probe, | ||
717 | }; | ||
718 | |||
719 | static int __init grpci1_init(void) | ||
720 | { | ||
721 | return platform_driver_register(&grpci1_of_driver); | ||
722 | } | ||
723 | |||
724 | subsys_initcall(grpci1_init); | ||