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 <asm/irq.h>
34#include <asm/signal.h>
35#include <asm/system.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_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 unsigned long 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 if (offset > 255)
195 BUG();
196 if (busnr > 255)
197 BUG();
198 if (devfn > 255)
199 BUG();
200
201 if (busnr == 0) {
202 int slot = PCI_SLOT(devfn);
203
204
205
206
207
208
209
210
211
212
213
214 address = PCI_FUNC(devfn) << 8;
215 mapaddress = V3_LB_MAP_TYPE_CONFIG;
216
217 if (slot > 12)
218
219
220
221 mapaddress |= 1 << (slot - 5);
222 else
223
224
225
226 address |= 1 << (slot + 11);
227 } else {
228
229
230
231
232
233
234
235
236
237
238
239
240 mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN;
241 address = (busnr << 16) | (devfn << 8);
242 }
243
244
245
246
247
248
249 v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
250 V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE);
251
252
253
254
255 v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) |
256 V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE);
257 v3_writew(V3_LB_MAP1, mapaddress);
258
259 return PCI_CONFIG_VADDR + address + offset;
260}
261
262static void v3_close_config_window(void)
263{
264
265
266
267 v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
268 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
269 V3_LB_BASE_ENABLE);
270 v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
271 V3_LB_MAP_TYPE_MEM_MULTIPLE);
272
273
274
275
276 v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
277 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
278}
279
280static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where,
281 int size, u32 *val)
282{
283 unsigned long addr;
284 unsigned long flags;
285 u32 v;
286
287 spin_lock_irqsave(&v3_lock, flags);
288 addr = v3_open_config_window(bus, devfn, where);
289
290 switch (size) {
291 case 1:
292 v = __raw_readb(addr);
293 break;
294
295 case 2:
296 v = __raw_readw(addr);
297 break;
298
299 default:
300 v = __raw_readl(addr);
301 break;
302 }
303
304 v3_close_config_window();
305 spin_unlock_irqrestore(&v3_lock, flags);
306
307 *val = v;
308 return PCIBIOS_SUCCESSFUL;
309}
310
311static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
312 int size, u32 val)
313{
314 unsigned long addr;
315 unsigned long flags;
316
317 spin_lock_irqsave(&v3_lock, flags);
318 addr = v3_open_config_window(bus, devfn, where);
319
320 switch (size) {
321 case 1:
322 __raw_writeb((u8)val, addr);
323 __raw_readb(addr);
324 break;
325
326 case 2:
327 __raw_writew((u16)val, addr);
328 __raw_readw(addr);
329 break;
330
331 case 4:
332 __raw_writel(val, addr);
333 __raw_readl(addr);
334 break;
335 }
336
337 v3_close_config_window();
338 spin_unlock_irqrestore(&v3_lock, flags);
339
340 return PCIBIOS_SUCCESSFUL;
341}
342
343static struct pci_ops pci_v3_ops = {
344 .read = v3_read_config,
345 .write = v3_write_config,
346};
347
348static struct resource non_mem = {
349 .name = "PCI non-prefetchable",
350 .start = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START,
351 .end = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
352 .flags = IORESOURCE_MEM,
353};
354
355static struct resource pre_mem = {
356 .name = "PCI prefetchable",
357 .start = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START,
358 .end = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
359 .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
360};
361
362static int __init pci_v3_setup_resources(struct resource **resource)
363{
364 if (request_resource(&iomem_resource, &non_mem)) {
365 printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
366 "memory region\n");
367 return -EBUSY;
368 }
369 if (request_resource(&iomem_resource, &pre_mem)) {
370 release_resource(&non_mem);
371 printk(KERN_ERR "PCI: unable to allocate prefetchable "
372 "memory region\n");
373 return -EBUSY;
374 }
375
376
377
378
379
380
381 resource[0] = &ioport_resource;
382 resource[1] = &non_mem;
383 resource[2] = &pre_mem;
384
385 return 1;
386}
387
388
389
390
391
392
393#define SC_PCI IO_ADDRESS(INTEGRATOR_SC_PCIENABLE)
394#define SC_LBFADDR IO_ADDRESS(INTEGRATOR_SC_BASE + 0x20)
395#define SC_LBFCODE IO_ADDRESS(INTEGRATOR_SC_BASE + 0x24)
396
397static int
398v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
399{
400 unsigned long pc = instruction_pointer(regs);
401 unsigned long instr = *(unsigned long *)pc;
402#if 0
403 char buf[128];
404
405 sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
406 addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
407 v3_readb(V3_LB_ISTAT));
408 printk(KERN_DEBUG "%s", buf);
409#endif
410
411 v3_writeb(V3_LB_ISTAT, 0);
412 __raw_writel(3, SC_PCI);
413
414
415
416
417
418 if ((instr & 0x0c100000) == 0x04100000) {
419 int reg = (instr >> 12) & 15;
420 unsigned long val;
421
422 if (instr & 0x00400000)
423 val = 255;
424 else
425 val = -1;
426
427 regs->uregs[reg] = val;
428 regs->ARM_pc += 4;
429 return 0;
430 }
431
432 if ((instr & 0x0e100090) == 0x00100090) {
433 int reg = (instr >> 12) & 15;
434
435 regs->uregs[reg] = -1;
436 regs->ARM_pc += 4;
437 return 0;
438 }
439
440 return 1;
441}
442
443static irqreturn_t v3_irq(int dummy, void *devid)
444{
445#ifdef CONFIG_DEBUG_LL
446 struct pt_regs *regs = get_irq_regs();
447 unsigned long pc = instruction_pointer(regs);
448 unsigned long instr = *(unsigned long *)pc;
449 char buf[128];
450 extern void printascii(const char *);
451
452 sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
453 "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
454 __raw_readl(SC_LBFADDR),
455 __raw_readl(SC_LBFCODE) & 255,
456 v3_readb(V3_LB_ISTAT));
457 printascii(buf);
458#endif
459
460 v3_writew(V3_PCI_STAT, 0xf000);
461 v3_writeb(V3_LB_ISTAT, 0);
462 __raw_writel(3, SC_PCI);
463
464#ifdef CONFIG_DEBUG_LL
465
466
467
468
469 if ((instr & 0x0c100000) == 0x04100000) {
470 int reg = (instr >> 16) & 15;
471 sprintf(buf, " reg%d = %08lx\n", reg, regs->uregs[reg]);
472 printascii(buf);
473 }
474#endif
475 return IRQ_HANDLED;
476}
477
478int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
479{
480 int ret = 0;
481
482 if (nr == 0) {
483 sys->mem_offset = PHYS_PCI_MEM_BASE;
484 ret = pci_v3_setup_resources(sys->resource);
485 }
486
487 return ret;
488}
489
490struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
491{
492 return pci_scan_bus(sys->busnr, &pci_v3_ops, sys);
493}
494
495
496
497
498
499void __init pci_v3_preinit(void)
500{
501 unsigned long flags;
502 unsigned int temp;
503 int ret;
504
505
506
507
508 hook_fault_code(4, v3_pci_fault, SIGBUS, 0, "external abort on linefetch");
509 hook_fault_code(6, v3_pci_fault, SIGBUS, 0, "external abort on linefetch");
510 hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
511 hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
512
513 spin_lock_irqsave(&v3_lock, flags);
514
515
516
517
518 if (v3_readw(V3_SYSTEM) & V3_SYSTEM_M_LOCK)
519 v3_writew(V3_SYSTEM, 0xa05f);
520
521
522
523
524
525 v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
526 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
527 v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(PCI_BUS_NONMEM_START) |
528 V3_LB_MAP_TYPE_MEM);
529
530
531
532
533
534 v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
535 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
536 V3_LB_BASE_ENABLE);
537 v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
538 V3_LB_MAP_TYPE_MEM_MULTIPLE);
539
540
541
542
543 v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(PHYS_PCI_IO_BASE) |
544 V3_LB_BASE_ENABLE);
545 v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
546
547
548
549
550 temp = v3_readw(V3_PCI_CFG) & ~V3_PCI_CFG_M_I2O_EN;
551 temp |= V3_PCI_CFG_M_IO_REG_DIS | V3_PCI_CFG_M_IO_DIS;
552 v3_writew(V3_PCI_CFG, temp);
553
554 printk(KERN_DEBUG "FIFO_CFG: %04x FIFO_PRIO: %04x\n",
555 v3_readw(V3_FIFO_CFG), v3_readw(V3_FIFO_PRIORITY));
556
557
558
559
560
561
562 v3_writew(V3_FIFO_PRIORITY, 0x0a0a);
563
564
565
566
567 temp = v3_readw(V3_SYSTEM) | V3_SYSTEM_M_LOCK;
568 v3_writew(V3_SYSTEM, temp);
569
570
571
572
573 v3_writeb(V3_LB_ISTAT, 0);
574 v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
575 v3_writeb(V3_LB_IMASK, 0x28);
576 __raw_writel(3, SC_PCI);
577
578
579
580
581 ret = request_irq(IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
582 if (ret)
583 printk(KERN_ERR "PCI: unable to grab PCI error "
584 "interrupt: %d\n", ret);
585
586 spin_unlock_irqrestore(&v3_lock, flags);
587}
588
589void __init pci_v3_postinit(void)
590{
591 unsigned int pci_cmd;
592
593 pci_cmd = PCI_COMMAND_MEMORY |
594 PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
595
596 v3_writew(V3_PCI_CMD, pci_cmd);
597
598 v3_writeb(V3_LB_ISTAT, ~0x40);
599 v3_writeb(V3_LB_IMASK, 0x68);
600
601#if 0
602 ret = request_irq(IRQ_AP_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
603 if (ret)
604 printk(KERN_ERR "PCI: unable to grab local bus timeout "
605 "interrupt: %d\n", ret);
606#endif
607
608 register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
609}
610