Merge branches 'at91', 'dyntick', 'ep93xx', 'iop', 'ixp', 'misc', 'orion', 'omap...
[deliverable/linux.git] / arch / powerpc / platforms / cell / celleb_scc_pciex.c
1 /*
2 * Support for Celleb PCI-Express.
3 *
4 * (C) Copyright 2007-2008 TOSHIBA CORPORATION
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #undef DEBUG
22
23 #include <linux/kernel.h>
24 #include <linux/pci.h>
25 #include <linux/string.h>
26 #include <linux/init.h>
27 #include <linux/bootmem.h>
28 #include <linux/delay.h>
29 #include <linux/interrupt.h>
30
31 #include <asm/io.h>
32 #include <asm/irq.h>
33 #include <asm/iommu.h>
34 #include <asm/byteorder.h>
35
36 #include "celleb_scc.h"
37 #include "celleb_pci.h"
38
39 #define PEX_IN(base, off) in_be32((void __iomem *)(base) + (off))
40 #define PEX_OUT(base, off, data) out_be32((void __iomem *)(base) + (off), (data))
41
42 static void scc_pciex_io_flush(struct iowa_bus *bus)
43 {
44 (void)PEX_IN(bus->phb->cfg_addr, PEXDMRDEN0);
45 }
46
47 /*
48 * Memory space access to device on PCIEX
49 */
50 #define PCIEX_MMIO_READ(name, ret) \
51 static ret scc_pciex_##name(const PCI_IO_ADDR addr) \
52 { \
53 ret val = __do_##name(addr); \
54 scc_pciex_io_flush(iowa_mem_find_bus(addr)); \
55 return val; \
56 }
57
58 #define PCIEX_MMIO_READ_STR(name) \
59 static void scc_pciex_##name(const PCI_IO_ADDR addr, void *buf, \
60 unsigned long count) \
61 { \
62 __do_##name(addr, buf, count); \
63 scc_pciex_io_flush(iowa_mem_find_bus(addr)); \
64 }
65
66 PCIEX_MMIO_READ(readb, u8)
67 PCIEX_MMIO_READ(readw, u16)
68 PCIEX_MMIO_READ(readl, u32)
69 PCIEX_MMIO_READ(readq, u64)
70 PCIEX_MMIO_READ(readw_be, u16)
71 PCIEX_MMIO_READ(readl_be, u32)
72 PCIEX_MMIO_READ(readq_be, u64)
73 PCIEX_MMIO_READ_STR(readsb)
74 PCIEX_MMIO_READ_STR(readsw)
75 PCIEX_MMIO_READ_STR(readsl)
76
77 static void scc_pciex_memcpy_fromio(void *dest, const PCI_IO_ADDR src,
78 unsigned long n)
79 {
80 __do_memcpy_fromio(dest, src, n);
81 scc_pciex_io_flush(iowa_mem_find_bus(src));
82 }
83
84 /*
85 * I/O port access to devices on PCIEX.
86 */
87
88 static inline unsigned long get_bus_address(struct pci_controller *phb,
89 unsigned long port)
90 {
91 return port - ((unsigned long)(phb->io_base_virt) - _IO_BASE);
92 }
93
94 static u32 scc_pciex_read_port(struct pci_controller *phb,
95 unsigned long port, int size)
96 {
97 unsigned int byte_enable;
98 unsigned int cmd, shift;
99 unsigned long addr;
100 u32 data, ret;
101
102 BUG_ON(((port & 0x3ul) + size) > 4);
103
104 addr = get_bus_address(phb, port);
105 shift = addr & 0x3ul;
106 byte_enable = ((1 << size) - 1) << shift;
107 cmd = PEXDCMND_IO_READ | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
108 PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
109 PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
110 data = PEX_IN(phb->cfg_addr, PEXDRDATA);
111 ret = (data >> (shift * 8)) & (0xFFFFFFFF >> ((4 - size) * 8));
112
113 pr_debug("PCIEX:PIO READ:port=0x%lx, addr=0x%lx, size=%d, be=%x,"
114 " cmd=%x, data=%x, ret=%x\n", port, addr, size, byte_enable,
115 cmd, data, ret);
116
117 return ret;
118 }
119
120 static void scc_pciex_write_port(struct pci_controller *phb,
121 unsigned long port, int size, u32 val)
122 {
123 unsigned int byte_enable;
124 unsigned int cmd, shift;
125 unsigned long addr;
126 u32 data;
127
128 BUG_ON(((port & 0x3ul) + size) > 4);
129
130 addr = get_bus_address(phb, port);
131 shift = addr & 0x3ul;
132 byte_enable = ((1 << size) - 1) << shift;
133 cmd = PEXDCMND_IO_WRITE | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
134 data = (val & (0xFFFFFFFF >> (4 - size) * 8)) << (shift * 8);
135 PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
136 PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
137 PEX_OUT(phb->cfg_addr, PEXDWDATA, data);
138
139 pr_debug("PCIEX:PIO WRITE:port=0x%lx, addr=%lx, size=%d, val=%x,"
140 " be=%x, cmd=%x, data=%x\n", port, addr, size, val,
141 byte_enable, cmd, data);
142 }
143
144 static u8 __scc_pciex_inb(struct pci_controller *phb, unsigned long port)
145 {
146 return (u8)scc_pciex_read_port(phb, port, 1);
147 }
148
149 static u16 __scc_pciex_inw(struct pci_controller *phb, unsigned long port)
150 {
151 u32 data;
152 if ((port & 0x3ul) < 3)
153 data = scc_pciex_read_port(phb, port, 2);
154 else {
155 u32 d1 = scc_pciex_read_port(phb, port, 1);
156 u32 d2 = scc_pciex_read_port(phb, port + 1, 1);
157 data = d1 | (d2 << 8);
158 }
159 return (u16)data;
160 }
161
162 static u32 __scc_pciex_inl(struct pci_controller *phb, unsigned long port)
163 {
164 unsigned int mod = port & 0x3ul;
165 u32 data;
166 if (mod == 0)
167 data = scc_pciex_read_port(phb, port, 4);
168 else {
169 u32 d1 = scc_pciex_read_port(phb, port, 4 - mod);
170 u32 d2 = scc_pciex_read_port(phb, port + 1, mod);
171 data = d1 | (d2 << (mod * 8));
172 }
173 return data;
174 }
175
176 static void __scc_pciex_outb(struct pci_controller *phb,
177 u8 val, unsigned long port)
178 {
179 scc_pciex_write_port(phb, port, 1, (u32)val);
180 }
181
182 static void __scc_pciex_outw(struct pci_controller *phb,
183 u16 val, unsigned long port)
184 {
185 if ((port & 0x3ul) < 3)
186 scc_pciex_write_port(phb, port, 2, (u32)val);
187 else {
188 u32 d1 = val & 0x000000FF;
189 u32 d2 = (val & 0x0000FF00) >> 8;
190 scc_pciex_write_port(phb, port, 1, d1);
191 scc_pciex_write_port(phb, port + 1, 1, d2);
192 }
193 }
194
195 static void __scc_pciex_outl(struct pci_controller *phb,
196 u32 val, unsigned long port)
197 {
198 unsigned int mod = port & 0x3ul;
199 if (mod == 0)
200 scc_pciex_write_port(phb, port, 4, val);
201 else {
202 u32 d1 = val & (0xFFFFFFFFul >> (mod * 8));
203 u32 d2 = val >> ((4 - mod) * 8);
204 scc_pciex_write_port(phb, port, 4 - mod, d1);
205 scc_pciex_write_port(phb, port + 1, mod, d2);
206 }
207 }
208
209 #define PCIEX_PIO_FUNC(size, name) \
210 static u##size scc_pciex_in##name(unsigned long port) \
211 { \
212 struct iowa_bus *bus = iowa_pio_find_bus(port); \
213 u##size data = __scc_pciex_in##name(bus->phb, port); \
214 scc_pciex_io_flush(bus); \
215 return data; \
216 } \
217 static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \
218 { \
219 struct iowa_bus *bus = iowa_pio_find_bus(p); \
220 __le##size *dst = b; \
221 for (; c != 0; c--, dst++) \
222 *dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \
223 scc_pciex_io_flush(bus); \
224 } \
225 static void scc_pciex_out##name(u##size val, unsigned long port) \
226 { \
227 struct iowa_bus *bus = iowa_pio_find_bus(port); \
228 __scc_pciex_out##name(bus->phb, val, port); \
229 } \
230 static void scc_pciex_outs##name(unsigned long p, const void *b, \
231 unsigned long c) \
232 { \
233 struct iowa_bus *bus = iowa_pio_find_bus(p); \
234 const __le##size *src = b; \
235 for (; c != 0; c--, src++) \
236 __scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \
237 }
238 #define __le8 u8
239 #define cpu_to_le8(x) (x)
240 #define le8_to_cpu(x) (x)
241 PCIEX_PIO_FUNC(8, b)
242 PCIEX_PIO_FUNC(16, w)
243 PCIEX_PIO_FUNC(32, l)
244
245 static struct ppc_pci_io scc_pciex_ops = {
246 .readb = scc_pciex_readb,
247 .readw = scc_pciex_readw,
248 .readl = scc_pciex_readl,
249 .readq = scc_pciex_readq,
250 .readw_be = scc_pciex_readw_be,
251 .readl_be = scc_pciex_readl_be,
252 .readq_be = scc_pciex_readq_be,
253 .readsb = scc_pciex_readsb,
254 .readsw = scc_pciex_readsw,
255 .readsl = scc_pciex_readsl,
256 .memcpy_fromio = scc_pciex_memcpy_fromio,
257 .inb = scc_pciex_inb,
258 .inw = scc_pciex_inw,
259 .inl = scc_pciex_inl,
260 .outb = scc_pciex_outb,
261 .outw = scc_pciex_outw,
262 .outl = scc_pciex_outl,
263 .insb = scc_pciex_insb,
264 .insw = scc_pciex_insw,
265 .insl = scc_pciex_insl,
266 .outsb = scc_pciex_outsb,
267 .outsw = scc_pciex_outsw,
268 .outsl = scc_pciex_outsl,
269 };
270
271 static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data)
272 {
273 dma_addr_t dummy_page_da;
274 void *dummy_page_va;
275
276 dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
277 if (!dummy_page_va) {
278 pr_err("PCIEX:Alloc dummy_page_va failed\n");
279 return -1;
280 }
281
282 dummy_page_da = dma_map_single(bus->phb->parent, dummy_page_va,
283 PAGE_SIZE, DMA_FROM_DEVICE);
284 if (dma_mapping_error(dummy_page_da)) {
285 pr_err("PCIEX:Map dummy page failed.\n");
286 kfree(dummy_page_va);
287 return -1;
288 }
289
290 PEX_OUT(bus->phb->cfg_addr, PEXDMRDADR0, dummy_page_da);
291
292 return 0;
293 }
294
295 /*
296 * config space access
297 */
298 #define MK_PEXDADRS(bus_no, dev_no, func_no, addr) \
299 ((uint32_t)(((addr) & ~0x3UL) | \
300 ((bus_no) << PEXDADRS_BUSNO_SHIFT) | \
301 ((dev_no) << PEXDADRS_DEVNO_SHIFT) | \
302 ((func_no) << PEXDADRS_FUNCNO_SHIFT)))
303
304 #define MK_PEXDCMND_BYTE_EN(addr, size) \
305 ((((0x1 << (size))-1) << ((addr) & 0x3)) << PEXDCMND_BYTE_EN_SHIFT)
306 #define MK_PEXDCMND(cmd, addr, size) ((cmd) | MK_PEXDCMND_BYTE_EN(addr, size))
307
308 static uint32_t config_read_pciex_dev(unsigned int __iomem *base,
309 uint64_t bus_no, uint64_t dev_no, uint64_t func_no,
310 uint64_t off, uint64_t size)
311 {
312 uint32_t ret;
313 uint32_t addr, cmd;
314
315 addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
316 cmd = MK_PEXDCMND(PEXDCMND_CONFIG_READ, off, size);
317 PEX_OUT(base, PEXDADRS, addr);
318 PEX_OUT(base, PEXDCMND, cmd);
319 ret = (PEX_IN(base, PEXDRDATA)
320 >> ((off & (4-size)) * 8)) & ((0x1 << (size * 8)) - 1);
321 return ret;
322 }
323
324 static void config_write_pciex_dev(unsigned int __iomem *base, uint64_t bus_no,
325 uint64_t dev_no, uint64_t func_no, uint64_t off, uint64_t size,
326 uint32_t data)
327 {
328 uint32_t addr, cmd;
329
330 addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
331 cmd = MK_PEXDCMND(PEXDCMND_CONFIG_WRITE, off, size);
332 PEX_OUT(base, PEXDADRS, addr);
333 PEX_OUT(base, PEXDCMND, cmd);
334 PEX_OUT(base, PEXDWDATA,
335 (data & ((0x1 << (size * 8)) - 1)) << ((off & (4-size)) * 8));
336 }
337
338 #define MK_PEXCADRS_BYTE_EN(off, len) \
339 ((((0x1 << (len)) - 1) << ((off) & 0x3)) << PEXCADRS_BYTE_EN_SHIFT)
340 #define MK_PEXCADRS(cmd, addr, size) \
341 ((cmd) | MK_PEXCADRS_BYTE_EN(addr, size) | ((addr) & ~0x3))
342 static uint32_t config_read_pciex_rc(unsigned int __iomem *base,
343 uint32_t where, uint32_t size)
344 {
345 PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_READ, where, size));
346 return (PEX_IN(base, PEXCRDATA)
347 >> ((where & (4 - size)) * 8)) & ((0x1 << (size * 8)) - 1);
348 }
349
350 static void config_write_pciex_rc(unsigned int __iomem *base, uint32_t where,
351 uint32_t size, uint32_t val)
352 {
353 uint32_t data;
354
355 data = (val & ((0x1 << (size * 8)) - 1)) << ((where & (4 - size)) * 8);
356 PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_WRITE, where, size));
357 PEX_OUT(base, PEXCWDATA, data);
358 }
359
360 /* Interfaces */
361 /* Note: Work-around
362 * On SCC PCIEXC, one device is seen on all 32 dev_no.
363 * As SCC PCIEXC can have only one device on the bus, we look only one dev_no.
364 * (dev_no = 1)
365 */
366 static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
367 int where, int size, unsigned int *val)
368 {
369 struct device_node *dn;
370 struct pci_controller *phb;
371
372 dn = bus->sysdata;
373 phb = pci_find_hose_for_OF_device(dn);
374
375 if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1) {
376 *val = ~0;
377 return PCIBIOS_DEVICE_NOT_FOUND;
378 }
379
380 if (bus->number == 0 && PCI_SLOT(devfn) == 0)
381 *val = config_read_pciex_rc(phb->cfg_addr, where, size);
382 else
383 *val = config_read_pciex_dev(phb->cfg_addr, bus->number,
384 PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
385
386 return PCIBIOS_SUCCESSFUL;
387 }
388
389 static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
390 int where, int size, unsigned int val)
391 {
392 struct device_node *dn;
393 struct pci_controller *phb;
394
395 dn = bus->sysdata;
396 phb = pci_find_hose_for_OF_device(dn);
397
398 if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1)
399 return PCIBIOS_DEVICE_NOT_FOUND;
400
401 if (bus->number == 0 && PCI_SLOT(devfn) == 0)
402 config_write_pciex_rc(phb->cfg_addr, where, size, val);
403 else
404 config_write_pciex_dev(phb->cfg_addr, bus->number,
405 PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
406 return PCIBIOS_SUCCESSFUL;
407 }
408
409 static struct pci_ops scc_pciex_pci_ops = {
410 scc_pciex_read_config,
411 scc_pciex_write_config,
412 };
413
414 static void pciex_clear_intr_all(unsigned int __iomem *base)
415 {
416 PEX_OUT(base, PEXAERRSTS, 0xffffffff);
417 PEX_OUT(base, PEXPRERRSTS, 0xffffffff);
418 PEX_OUT(base, PEXINTSTS, 0xffffffff);
419 }
420
421 #if 0
422 static void pciex_disable_intr_all(unsigned int *base)
423 {
424 PEX_OUT(base, PEXINTMASK, 0x0);
425 PEX_OUT(base, PEXAERRMASK, 0x0);
426 PEX_OUT(base, PEXPRERRMASK, 0x0);
427 PEX_OUT(base, PEXVDMASK, 0x0);
428 }
429 #endif
430
431 static void pciex_enable_intr_all(unsigned int __iomem *base)
432 {
433 PEX_OUT(base, PEXINTMASK, 0x0000e7f1);
434 PEX_OUT(base, PEXAERRMASK, 0x03ff01ff);
435 PEX_OUT(base, PEXPRERRMASK, 0x0001010f);
436 PEX_OUT(base, PEXVDMASK, 0x00000001);
437 }
438
439 static void pciex_check_status(unsigned int __iomem *base)
440 {
441 uint32_t err = 0;
442 uint32_t intsts, aerr, prerr, rcvcp, lenerr;
443 uint32_t maea, maec;
444
445 intsts = PEX_IN(base, PEXINTSTS);
446 aerr = PEX_IN(base, PEXAERRSTS);
447 prerr = PEX_IN(base, PEXPRERRSTS);
448 rcvcp = PEX_IN(base, PEXRCVCPLIDA);
449 lenerr = PEX_IN(base, PEXLENERRIDA);
450
451 if (intsts || aerr || prerr || rcvcp || lenerr)
452 err = 1;
453
454 pr_info("PCEXC interrupt!!\n");
455 pr_info("PEXINTSTS :0x%08x\n", intsts);
456 pr_info("PEXAERRSTS :0x%08x\n", aerr);
457 pr_info("PEXPRERRSTS :0x%08x\n", prerr);
458 pr_info("PEXRCVCPLIDA :0x%08x\n", rcvcp);
459 pr_info("PEXLENERRIDA :0x%08x\n", lenerr);
460
461 /* print detail of Protection Error */
462 if (intsts & 0x00004000) {
463 uint32_t i, n;
464 for (i = 0; i < 4; i++) {
465 n = 1 << i;
466 if (prerr & n) {
467 maea = PEX_IN(base, PEXMAEA(i));
468 maec = PEX_IN(base, PEXMAEC(i));
469 pr_info("PEXMAEC%d :0x%08x\n", i, maec);
470 pr_info("PEXMAEA%d :0x%08x\n", i, maea);
471 }
472 }
473 }
474
475 if (err)
476 pciex_clear_intr_all(base);
477 }
478
479 static irqreturn_t pciex_handle_internal_irq(int irq, void *dev_id)
480 {
481 struct pci_controller *phb = dev_id;
482
483 pr_debug("PCIEX:pciex_handle_internal_irq(irq=%d)\n", irq);
484
485 BUG_ON(phb->cfg_addr == NULL);
486
487 pciex_check_status(phb->cfg_addr);
488
489 return IRQ_HANDLED;
490 }
491
492 static __init int celleb_setup_pciex(struct device_node *node,
493 struct pci_controller *phb)
494 {
495 struct resource r;
496 struct of_irq oirq;
497 int virq;
498
499 /* SMMIO registers; used inside this file */
500 if (of_address_to_resource(node, 0, &r)) {
501 pr_err("PCIEXC:Failed to get config resource.\n");
502 return 1;
503 }
504 phb->cfg_addr = ioremap(r.start, r.end - r.start + 1);
505 if (!phb->cfg_addr) {
506 pr_err("PCIEXC:Failed to remap SMMIO region.\n");
507 return 1;
508 }
509
510 /* Not use cfg_data, cmd and data regs are near address reg */
511 phb->cfg_data = NULL;
512
513 /* set pci_ops */
514 phb->ops = &scc_pciex_pci_ops;
515
516 /* internal interrupt handler */
517 if (of_irq_map_one(node, 1, &oirq)) {
518 pr_err("PCIEXC:Failed to map irq\n");
519 goto error;
520 }
521 virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
522 oirq.size);
523 if (request_irq(virq, pciex_handle_internal_irq,
524 IRQF_DISABLED, "pciex", (void *)phb)) {
525 pr_err("PCIEXC:Failed to request irq\n");
526 goto error;
527 }
528
529 /* enable all interrupts */
530 pciex_clear_intr_all(phb->cfg_addr);
531 pciex_enable_intr_all(phb->cfg_addr);
532 /* MSI: TBD */
533
534 return 0;
535
536 error:
537 phb->cfg_data = NULL;
538 if (phb->cfg_addr)
539 iounmap(phb->cfg_addr);
540 phb->cfg_addr = NULL;
541 return 1;
542 }
543
544 struct celleb_phb_spec celleb_pciex_spec __initdata = {
545 .setup = celleb_setup_pciex,
546 .ops = &scc_pciex_ops,
547 .iowa_init = &scc_pciex_iowa_init,
548 };
This page took 0.070149 seconds and 6 git commands to generate.