blob: 9dae689b6a9b0da641a9283c3a7ad749dc9a28d3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 * Copyright (C) 2003, 2004 Paul Mundt
4 * Copyright (C) 2004 Richard Curnow
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Support functions for the SH5 PCI hardware.
10 */
11
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/kernel.h>
13#include <linux/rwsem.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/interrupt.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/pci.h>
20#include <linux/delay.h>
21#include <linux/types.h>
22#include <asm/pci.h>
23#include <linux/irq.h>
24
25#include <asm/io.h>
26#include <asm/hardware.h>
27#include "pci_sh5.h"
28
29static unsigned long pcicr_virt;
30unsigned long pciio_virt;
31
32static void __init pci_fixup_ide_bases(struct pci_dev *d)
33{
34 int i;
35
36 /*
37 * PCI IDE controllers use non-standard I/O port decoding, respect it.
38 */
39 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
40 return;
41 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
42 for(i=0; i<4; i++) {
43 struct resource *r = &d->resource[i];
44 if ((r->start & ~0x80) == 0x374) {
45 r->start |= 2;
46 r->end = r->start;
47 }
48 }
49}
50DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
51
52char * __init pcibios_setup(char *str)
53{
54 return str;
55}
56
57/* Rounds a number UP to the nearest power of two. Used for
58 * sizing the PCI window.
59 */
60static u32 __init r2p2(u32 num)
61{
62 int i = 31;
63 u32 tmp = num;
64
65 if (num == 0)
66 return 0;
67
68 do {
69 if (tmp & (1 << 31))
70 break;
71 i--;
72 tmp <<= 1;
73 } while (i >= 0);
74
75 tmp = 1 << i;
76 /* If the original number isn't a power of 2, round it up */
77 if (tmp != num)
78 tmp <<= 1;
79
80 return tmp;
81}
82
83extern unsigned long long memory_start, memory_end;
84
85int __init sh5pci_init(unsigned memStart, unsigned memSize)
86{
87 u32 lsr0;
88 u32 uval;
89
90 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
91 if (!pcicr_virt) {
92 panic("Unable to remap PCICR\n");
93 }
94
95 pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
96 if (!pciio_virt) {
97 panic("Unable to remap PCIIO\n");
98 }
99
100 pr_debug("Register base addres is 0x%08lx\n", pcicr_virt);
101
102 /* Clear snoop registers */
103 SH5PCI_WRITE(CSCR0, 0);
104 SH5PCI_WRITE(CSCR1, 0);
105
106 pr_debug("Wrote to reg\n");
107
108 /* Switch off interrupts */
109 SH5PCI_WRITE(INTM, 0);
110 SH5PCI_WRITE(AINTM, 0);
111 SH5PCI_WRITE(PINTM, 0);
112
113 /* Set bus active, take it out of reset */
114 uval = SH5PCI_READ(CR);
115
116 /* Set command Register */
117 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM);
118
119 uval=SH5PCI_READ(CR);
120 pr_debug("CR is actually 0x%08x\n",uval);
121
122 /* Allow it to be a master */
123 /* NB - WE DISABLE I/O ACCESS to stop overlap */
124 /* set WAIT bit to enable stepping, an attempt to improve stability */
125 SH5PCI_WRITE_SHORT(CSR_CMD,
126 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
127
128 /*
129 ** Set translation mapping memory in order to convert the address
130 ** used for the main bus, to the PCI internal address.
131 */
132 SH5PCI_WRITE(MBR,0x40000000);
133
134 /* Always set the max size 512M */
135 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
136
137 /*
138 ** I/O addresses are mapped at internal PCI specific address
139 ** as is described into the configuration bridge table.
140 ** These are changed to 0, to allow cards that have legacy
141 ** io such as vga to function correctly. We set the SH5 IOBAR to
142 ** 256K, which is a bit big as we can only have 64K of address space
143 */
144
145 SH5PCI_WRITE(IOBR,0x0);
146
147 pr_debug("PCI:Writing 0x%08x to IOBR\n",0);
148
149 /* Set up a 256K window. Totally pointless waste of address space */
150 SH5PCI_WRITE(IOBMR,0);
151 pr_debug("PCI:Writing 0x%08x to IOBMR\n",0);
152
153 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally,
154 * we would want to map the I/O region somewhere, but it is so big this is not
155 * that easy!
156 */
157 SH5PCI_WRITE(CSR_IBAR0,~0);
158 /* Set memory size value */
159 memSize = memory_end - memory_start;
160
161 /* Now we set up the mbars so the PCI bus can see the memory of the machine */
162 if (memSize < (1024 * 1024)) {
163 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
164 return -EINVAL;
165 }
166
167 /* Set LSR 0 */
168 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
169 SH5PCI_WRITE(LSR0, lsr0);
170
171 pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0);
172
173 /* Set MBAR 0 */
174 SH5PCI_WRITE(CSR_MBAR0, memory_start);
175 SH5PCI_WRITE(LAR0, memory_start);
176
177 SH5PCI_WRITE(CSR_MBAR1,0);
178 SH5PCI_WRITE(LAR1,0);
179 SH5PCI_WRITE(LSR1,0);
180
181 pr_debug("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);
182 pr_debug("PCI:Writing 0x%08llx to LAR0\n",memory_start);
183
184 /* Enable the PCI interrupts on the device */
185 SH5PCI_WRITE(INTM, ~0);
186 SH5PCI_WRITE(AINTM, ~0);
187 SH5PCI_WRITE(PINTM, ~0);
188
189 pr_debug("Switching on all error interrupts\n");
190
191 return(0);
192}
193
194static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
195 int size, u32 *val)
196{
197 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
198
199 switch (size) {
200 case 1:
201 *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
202 break;
203 case 2:
204 *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
205 break;
206 case 4:
207 *val = SH5PCI_READ(PDR);
208 break;
209 }
210
211 return PCIBIOS_SUCCESSFUL;
212}
213
214static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
215 int size, u32 val)
216{
217 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
218
219 switch (size) {
220 case 1:
221 SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
222 break;
223 case 2:
224 SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
225 break;
226 case 4:
227 SH5PCI_WRITE(PDR, val);
228 break;
229 }
230
231 return PCIBIOS_SUCCESSFUL;
232}
233
234static struct pci_ops pci_config_ops = {
235 .read = sh5pci_read,
236 .write = sh5pci_write,
237};
238
239/* Everything hangs off this */
240static struct pci_bus *pci_root_bus;
241
242
243static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
244{
245 pr_debug("swizzle for dev %d on bus %d slot %d pin is %d\n",
246 dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
247 return PCI_SLOT(dev->devfn);
248}
249
250static inline u8 bridge_swizzle(u8 pin, u8 slot)
251{
252 return (((pin-1) + slot) % 4) + 1;
253}
254
255u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
256{
257 if (dev->bus->number != 0) {
258 u8 pin = *pinp;
259 do {
260 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
261 /* Move up the chain of bridges. */
262 dev = dev->bus->self;
263 } while (dev->bus->self);
264 *pinp = pin;
265
266 /* The slot is the slot of the last bridge. */
267 }
268
269 return PCI_SLOT(dev->devfn);
270}
271
272/* This needs to be shunted out of here into the board specific bit */
273
274static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
275{
276 int result = -1;
277
278 /* The complication here is that the PCI IRQ lines from the Cayman's 2
279 5V slots get into the CPU via a different path from the IRQ lines
280 from the 3 3.3V slots. Thus, we have to detect whether the card's
281 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
282 at the point where we cross from 5V to 3.3V is not the normal case.
283
284 The added complication is that we don't know that the 5V slots are
285 always bus 2, because a card containing a PCI-PCI bridge may be
286 plugged into a 3.3V slot, and this changes the bus numbering.
287
288 Also, the Cayman has an intermediate PCI bus that goes a custom
289 expansion board header (and to the secondary bridge). This bus has
290 never been used in practice.
291
292 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
293 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of the 1ary bridge.
294 */
295
296 struct slot_pin {
297 int slot;
298 int pin;
299 } path[4];
300 int i=0;
301
302 while (dev->bus->number > 0) {
303
304 slot = path[i].slot = PCI_SLOT(dev->devfn);
305 pin = path[i].pin = bridge_swizzle(pin, slot);
306 dev = dev->bus->self;
307 i++;
308 if (i > 3) panic("PCI path to root bus too long!\n");
309 }
310
311 slot = PCI_SLOT(dev->devfn);
312 /* This is the slot on bus 0 through which the device is eventually
313 reachable. */
314
315 /* Now work back up. */
316 if ((slot < 3) || (i == 0)) {
317 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
318 swizzle now. */
319 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
320 } else {
321 i--;
322 slot = path[i].slot;
323 pin = path[i].pin;
324 if (slot > 0) {
325 panic("PCI expansion bus device found - not handled!\n");
326 } else {
327 if (i > 0) {
328 /* 5V slots */
329 i--;
330 slot = path[i].slot;
331 pin = path[i].pin;
332 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
333 result = IRQ_P2INTA + (pin - 1);
334 } else {
335 /* IRQ for 2ary PCI-PCI bridge : unused */
336 result = -1;
337 }
338 }
339 }
340
341 return result;
342}
343
344irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
345{
346 unsigned pci_int, pci_air, pci_cir, pci_aint;
347
348 pci_int = SH5PCI_READ(INT);
349 pci_cir = SH5PCI_READ(CIR);
350 pci_air = SH5PCI_READ(AIR);
351
352 if (pci_int) {
353 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
354 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
355 printk("PCI AIR -> 0x%x\n", pci_air);
356 printk("PCI CIR -> 0x%x\n", pci_cir);
357 SH5PCI_WRITE(INT, ~0);
358 }
359
360 pci_aint = SH5PCI_READ(AINT);
361 if (pci_aint) {
362 printk("PCI ARB INTERRUPT!\n");
363 printk("PCI AINT -> 0x%x\n", pci_aint);
364 printk("PCI AIR -> 0x%x\n", pci_air);
365 printk("PCI CIR -> 0x%x\n", pci_cir);
366 SH5PCI_WRITE(AINT, ~0);
367 }
368
369 return IRQ_HANDLED;
370}
371
372irqreturn_t pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
373{
374 printk("SERR IRQ\n");
375
376 return IRQ_NONE;
377}
378
379#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
380
381static void __init
382pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
383 struct resource *memr)
384{
385 struct resource io_res, mem_res;
386 struct pci_dev *dev;
387 struct pci_dev *bridge = bus->self;
388 struct list_head *ln;
389
390 if (!bridge)
391 return; /* host bridge, nothing to do */
392
393 /* set reasonable default locations for pcibios_align_resource */
394 io_res.start = PCIBIOS_MIN_IO;
395 mem_res.start = PCIBIOS_MIN_MEM;
396
397 io_res.end = io_res.start;
398 mem_res.end = mem_res.start;
399
400 /* Collect information about how our direct children are layed out. */
401 for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
402 int i;
403 dev = pci_dev_b(ln);
404
405 /* Skip bridges for now */
406 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
407 continue;
408
409 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
410 struct resource res;
411 unsigned long size;
412
413 memcpy(&res, &dev->resource[i], sizeof(res));
414 size = res.end - res.start + 1;
415
416 if (res.flags & IORESOURCE_IO) {
417 res.start = io_res.end;
418 pcibios_align_resource(dev, &res, size, 0);
419 io_res.end = res.start + size;
420 } else if (res.flags & IORESOURCE_MEM) {
421 res.start = mem_res.end;
422 pcibios_align_resource(dev, &res, size, 0);
423 mem_res.end = res.start + size;
424 }
425 }
426 }
427
428 /* And for all of the subordinate busses. */
429 for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
430 pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res);
431
432 /* turn the ending locations into sizes (subtract start) */
433 io_res.end -= io_res.start;
434 mem_res.end -= mem_res.start;
435
436 /* Align the sizes up by bridge rules */
437 io_res.end = ROUND_UP(io_res.end, 4*1024) - 1;
438 mem_res.end = ROUND_UP(mem_res.end, 1*1024*1024) - 1;
439
440 /* Adjust the bridge's allocation requirements */
441 bridge->resource[0].end = bridge->resource[0].start + io_res.end;
442 bridge->resource[1].end = bridge->resource[1].start + mem_res.end;
443
444 bridge->resource[PCI_BRIDGE_RESOURCES].end =
445 bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end;
446 bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
447 bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end;
448
449 /* adjust parent's resource requirements */
450 if (ior) {
451 ior->end = ROUND_UP(ior->end, 4*1024);
452 ior->end += io_res.end;
453 }
454
455 if (memr) {
456 memr->end = ROUND_UP(memr->end, 1*1024*1024);
457 memr->end += mem_res.end;
458 }
459}
460
461#undef ROUND_UP
462
463static void __init pcibios_size_bridges(void)
464{
465 struct resource io_res, mem_res;
466
467 memset(&io_res, 0, sizeof(io_res));
468 memset(&mem_res, 0, sizeof(mem_res));
469
470 pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
471}
472
473static int __init pcibios_init(void)
474{
475 if (request_irq(IRQ_ERR, pcish5_err_irq,
Thomas Gleixner5fb55ae2006-07-01 19:29:24 -0700476 IRQF_DISABLED, "PCI Error",NULL) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
478 return -EINVAL;
479 }
480
481 if (request_irq(IRQ_SERR, pcish5_serr_irq,
Thomas Gleixner5fb55ae2006-07-01 19:29:24 -0700482 IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
484 return -EINVAL;
485 }
486
487 /* The pci subsytem needs to know where memory is and how much
488 * of it there is. I've simply made these globals. A better mechanism
489 * is probably needed.
490 */
491 sh5pci_init(__pa(memory_start),
492 __pa(memory_end) - __pa(memory_start));
493
494 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
495 pcibios_size_bridges();
496 pci_assign_unassigned_resources();
497 pci_fixup_irqs(no_swizzle, map_cayman_irq);
498
499 return 0;
500}
501
502subsys_initcall(pcibios_init);
503
504void __init pcibios_fixup_bus(struct pci_bus *bus)
505{
506 struct pci_dev *dev = bus->self;
507 int i;
508
509#if 1
510 if(dev) {
511 for(i=0; i<3; i++) {
512 bus->resource[i] =
513 &dev->resource[PCI_BRIDGE_RESOURCES+i];
514 bus->resource[i]->name = bus->name;
515 }
516 bus->resource[0]->flags |= IORESOURCE_IO;
517 bus->resource[1]->flags |= IORESOURCE_MEM;
518
519 /* For now, propagate host limits to the bus;
520 * we'll adjust them later. */
521
522#if 1
523 bus->resource[0]->end = 64*1024 - 1 ;
524 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
525 bus->resource[0]->start = PCIBIOS_MIN_IO;
526 bus->resource[1]->start = PCIBIOS_MIN_MEM;
527#else
528 bus->resource[0]->end = 0
529 bus->resource[1]->end = 0
530 bus->resource[0]->start =0
531 bus->resource[1]->start = 0;
532#endif
533 /* Turn off downstream PF memory address range by default */
534 bus->resource[2]->start = 1024*1024;
535 bus->resource[2]->end = bus->resource[2]->start - 1;
536 }
537#endif
538
539}
540