1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/kernel.h>
24#include <linux/pci.h>
25#include <linux/ioport.h>
26#include <linux/interrupt.h>
27#include <linux/spinlock.h>
28#include <linux/init.h>
29#include <linux/io.h>
30
31#include <mach/hardware.h>
32#include <mach/platform.h>
33#include <mach/irqs.h>
34
35#include <asm/signal.h>
36#include <asm/mach/pci.h>
37#include <asm/irq_regs.h>
38
39#include <asm/hardware/pci_v3.h>
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105#define v3_writeb(o,v) __raw_writeb(v, PCI_V3_VADDR + (unsigned int)(o))
106#define v3_readb(o) (__raw_readb(PCI_V3_VADDR + (unsigned int)(o)))
107
108#define v3_writew(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o))
109#define v3_readw(o) (__raw_readw(PCI_V3_VADDR + (unsigned int)(o)))
110
111#define v3_writel(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o))
112#define v3_readl(o) (__raw_readl(PCI_V3_VADDR + (unsigned int)(o)))
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166static DEFINE_RAW_SPINLOCK(v3_lock);
167
168#define PCI_BUS_NONMEM_START 0x00000000
169#define PCI_BUS_NONMEM_SIZE SZ_256M
170
171#define PCI_BUS_PREMEM_START PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
172#define PCI_BUS_PREMEM_SIZE SZ_256M
173
174#if PCI_BUS_NONMEM_START & 0x000fffff
175#error PCI_BUS_NONMEM_START must be megabyte aligned
176#endif
177#if PCI_BUS_PREMEM_START & 0x000fffff
178#error PCI_BUS_PREMEM_START must be megabyte aligned
179#endif
180
181#undef V3_LB_BASE_PREFETCH
182#define V3_LB_BASE_PREFETCH 0
183
184static void __iomem *v3_open_config_window(struct pci_bus *bus,
185 unsigned int devfn, int offset)
186{
187 unsigned int address, mapaddress, busnr;
188
189 busnr = bus->number;
190
191
192
193
194 BUG_ON(offset > 255);
195 BUG_ON(busnr > 255);
196 BUG_ON(devfn > 255);
197
198 if (busnr == 0) {
199 int slot = PCI_SLOT(devfn);
200
201
202
203
204
205
206
207
208
209
210
211 address = PCI_FUNC(devfn) << 8;
212 mapaddress = V3_LB_MAP_TYPE_CONFIG;
213
214 if (slot > 12)
215
216
217
218 mapaddress |= 1 << (slot - 5);
219 else
220
221
222
223 address |= 1 << (slot + 11);
224 } else {
225
226
227
228
229
230
231
232
233
234
235
236
237 mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN;
238 address = (busnr << 16) | (devfn << 8);
239 }
240
241
242
243
244
245
246 v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
247 V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE);
248
249
250
251
252 v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) |
253 V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE);
254 v3_writew(V3_LB_MAP1, mapaddress);
255
256 return PCI_CONFIG_VADDR + address + offset;
257}
258
259static void v3_close_config_window(void)
260{
261
262
263
264 v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
265 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
266 V3_LB_BASE_ENABLE);
267 v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
268 V3_LB_MAP_TYPE_MEM_MULTIPLE);
269
270
271
272
273 v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
274 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
275}
276
277static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where,
278 int size, u32 *val)
279{
280 void __iomem *addr;
281 unsigned long flags;
282 u32 v;
283
284 raw_spin_lock_irqsave(&v3_lock, flags);
285 addr = v3_open_config_window(bus, devfn, where);
286
287 switch (size) {
288 case 1:
289 v = __raw_readb(addr);
290 break;
291
292 case 2:
293 v = __raw_readw(addr);
294 break;
295
296 default:
297 v = __raw_readl(addr);
298 break;
299 }
300
301 v3_close_config_window();
302 raw_spin_unlock_irqrestore(&v3_lock, flags);
303
304 *val = v;
305 return PCIBIOS_SUCCESSFUL;
306}
307
308static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
309 int size, u32 val)
310{
311 void __iomem *addr;
312 unsigned long flags;
313
314 raw_spin_lock_irqsave(&v3_lock, flags);
315 addr = v3_open_config_window(bus, devfn, where);
316
317 switch (size) {
318 case 1:
319 __raw_writeb((u8)val, addr);
320 __raw_readb(addr);
321 break;
322
323 case 2:
324 __raw_writew((u16)val, addr);
325 __raw_readw(addr);
326 break;
327
328 case 4:
329 __raw_writel(val, addr);
330 __raw_readl(addr);
331 break;
332 }
333
334 v3_close_config_window();
335 raw_spin_unlock_irqrestore(&v3_lock, flags);
336
337 return PCIBIOS_SUCCESSFUL;
338}
339
340struct pci_ops pci_v3_ops = {
341 .read = v3_read_config,
342 .write = v3_write_config,
343};
344
345static struct resource non_mem = {
346 .name = "PCI non-prefetchable",
347 .start = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START,
348 .end = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
349 .flags = IORESOURCE_MEM,
350};
351
352static struct resource pre_mem = {
353 .name = "PCI prefetchable",
354 .start = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START,
355 .end = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
356 .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
357};
358
359static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
360{
361 if (request_resource(&iomem_resource, &non_mem)) {
362 printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
363 "memory region\n");
364 return -EBUSY;
365 }
366 if (request_resource(&iomem_resource, &pre_mem)) {
367 release_resource(&non_mem);
368 printk(KERN_ERR "PCI: unable to allocate prefetchable "
369 "memory region\n");
370 return -EBUSY;
371 }
372
373
374
375
376
377 pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
378 pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
379
380 return 1;
381}
382
383
384
385
386
387
388static void __iomem *ap_syscon_base;
389#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
390#define INTEGRATOR_SC_LBFADDR_OFFSET 0x20
391#define INTEGRATOR_SC_LBFCODE_OFFSET 0x24
392
393static int
394v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
395{
396 unsigned long pc = instruction_pointer(regs);
397 unsigned long instr = *(unsigned long *)pc;
398#if 0
399 char buf[128];
400
401 sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
402 addr, fsr, pc, instr, __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
403 v3_readb(V3_LB_ISTAT));
404 printk(KERN_DEBUG "%s", buf);
405#endif
406
407 v3_writeb(V3_LB_ISTAT, 0);
408 __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
409
410
411
412
413
414 if ((instr & 0x0c100000) == 0x04100000) {
415 int reg = (instr >> 12) & 15;
416 unsigned long val;
417
418 if (instr & 0x00400000)
419 val = 255;
420 else
421 val = -1;
422
423 regs->uregs[reg] = val;
424 regs->ARM_pc += 4;
425 return 0;
426 }
427
428 if ((instr & 0x0e100090) == 0x00100090) {
429 int reg = (instr >> 12) & 15;
430
431 regs->uregs[reg] = -1;
432 regs->ARM_pc += 4;
433 return 0;
434 }
435
436 return 1;
437}
438
439static irqreturn_t v3_irq(int dummy, void *devid)
440{
441#ifdef CONFIG_DEBUG_LL
442 struct pt_regs *regs = get_irq_regs();
443 unsigned long pc = instruction_pointer(regs);
444 unsigned long instr = *(unsigned long *)pc;
445 char buf[128];
446 extern void printascii(const char *);
447
448 sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
449 "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
450 __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET),
451 __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
452 v3_readb(V3_LB_ISTAT));
453 printascii(buf);
454#endif
455
456 v3_writew(V3_PCI_STAT, 0xf000);
457 v3_writeb(V3_LB_ISTAT, 0);
458 __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
459
460#ifdef CONFIG_DEBUG_LL
461
462
463
464
465 if ((instr & 0x0c100000) == 0x04100000) {
466 int reg = (instr >> 16) & 15;
467 sprintf(buf, " reg%d = %08lx\n", reg, regs->uregs[reg]);
468 printascii(buf);
469 }
470#endif
471 return IRQ_HANDLED;
472}
473
474int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
475{
476 int ret = 0;
477
478 if (!ap_syscon_base)
479 return -EINVAL;
480
481 if (nr == 0) {
482 sys->mem_offset = PHYS_PCI_MEM_BASE;
483 ret = pci_v3_setup_resources(sys);
484 }
485
486 return ret;
487}
488
489
490
491
492
493void __init pci_v3_preinit(void)
494{
495 unsigned long flags;
496 unsigned int temp;
497 int ret;
498
499
500 ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
501 if (!ap_syscon_base) {
502 pr_err("unable to remap the AP syscon for PCIv3\n");
503 return;
504 }
505
506 pcibios_min_mem = 0x00100000;
507
508
509
510
511 hook_fault_code(4, v3_pci_fault, SIGBUS, 0, "external abort on linefetch");
512 hook_fault_code(6, v3_pci_fault, SIGBUS, 0, "external abort on linefetch");
513 hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
514 hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
515
516 raw_spin_lock_irqsave(&v3_lock, flags);
517
518
519
520
521 if (v3_readw(V3_SYSTEM) & V3_SYSTEM_M_LOCK)
522 v3_writew(V3_SYSTEM, 0xa05f);
523
524
525
526
527
528 v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
529 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
530 v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(PCI_BUS_NONMEM_START) |
531 V3_LB_MAP_TYPE_MEM);
532
533
534
535
536
537 v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
538 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
539 V3_LB_BASE_ENABLE);
540 v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
541 V3_LB_MAP_TYPE_MEM_MULTIPLE);
542
543
544
545
546 v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(PHYS_PCI_IO_BASE) |
547 V3_LB_BASE_ENABLE);
548 v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
549
550
551
552
553 temp = v3_readw(V3_PCI_CFG) & ~V3_PCI_CFG_M_I2O_EN;
554 temp |= V3_PCI_CFG_M_IO_REG_DIS | V3_PCI_CFG_M_IO_DIS;
555 v3_writew(V3_PCI_CFG, temp);
556
557 printk(KERN_DEBUG "FIFO_CFG: %04x FIFO_PRIO: %04x\n",
558 v3_readw(V3_FIFO_CFG), v3_readw(V3_FIFO_PRIORITY));
559
560
561
562
563
564
565 v3_writew(V3_FIFO_PRIORITY, 0x0a0a);
566
567
568
569
570 temp = v3_readw(V3_SYSTEM) | V3_SYSTEM_M_LOCK;
571 v3_writew(V3_SYSTEM, temp);
572
573
574
575
576 v3_writeb(V3_LB_ISTAT, 0);
577 v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
578 v3_writeb(V3_LB_IMASK, 0x28);
579 __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
580
581
582
583
584 ret = request_irq(IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
585 if (ret)
586 printk(KERN_ERR "PCI: unable to grab PCI error "
587 "interrupt: %d\n", ret);
588
589 raw_spin_unlock_irqrestore(&v3_lock, flags);
590}
591
592void __init pci_v3_postinit(void)
593{
594 unsigned int pci_cmd;
595
596 pci_cmd = PCI_COMMAND_MEMORY |
597 PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
598
599 v3_writew(V3_PCI_CMD, pci_cmd);
600
601 v3_writeb(V3_LB_ISTAT, ~0x40);
602 v3_writeb(V3_LB_IMASK, 0x68);
603
604#if 0
605 ret = request_irq(IRQ_AP_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
606 if (ret)
607 printk(KERN_ERR "PCI: unable to grab local bus timeout "
608 "interrupt: %d\n", ret);
609#endif
610
611 register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
612}
613