1 /****************************************************************************/
3 * pci.c: V3 Hurricane specific PCI support.
5 * Copyright (C) 1999,2000 Dan Aizenstros (dan@vcubed.com)
6 * Copyright (C) 2001, Lineo Inc., <davidm@moreton.com.au>
9 /****************************************************************************/
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/pci.h>
14 #include <linux/types.h>
15 #include <linux/init.h>
16 #include <linux/autoconf.h>
17 #include <asm/byteorder.h>
19 #include <asm/system.h>
21 #include <asm/byteorder.h>
24 #include "pci-v320usc.h"
26 /****************************************************************************/
28 /****************************************************************************/
31 #define V320USC_MEM_SPACE 0xB8000000 /* V320 sees this as AC000000 ! */
32 #define V320USC_IO_SPACE 0xB4000000
33 #define V320USC_CONF_SPACE 0xB4000000
35 #define V320USC_MEM_SPACE 0xab000000
36 #define V320USC_IO_SPACE 0xaa000000
37 #define V320USC_CONF_SPACE 0xaa000000
39 #define V320USC_BASE 0xb1fd0000
41 #ifdef __LITTLE_ENDIAN
42 #define reg08(x) (V320USC_BASE + (V320USC_##x))
43 #define reg16(x) (V320USC_BASE + (V320USC_##x))
45 #define reg08(x) (V320USC_BASE + ((V320USC_##x)^3))
46 #define reg16(x) (V320USC_BASE + ((V320USC_##x)^2))
49 #define reg32(x) (V320USC_BASE + (V320USC_##x))
51 #define v320usc_inb(addr) readb(reg08(addr)
52 #define v320usc_outb(value, addr) writeb(value, reg08(addr))
53 #define v320usc_inw(addr) readw(reg16(addr))
54 #define v320usc_outw(value, addr) writew(value, reg16(addr))
55 #define v320usc_inl(addr) readl(reg32(addr))
56 #define v320usc_outl(value, addr) writel(value, reg32(addr))
58 /****************************************************************************/
60 /* Set the LB_PCI_BASE0 register to allow PCI Memory cycles to be used */
62 static void set_io_cycles(void)
67 (v320usc_inl(LB_PCI_BASE0) &
68 ~(LB_PCI_BASEX_PCI_CMD_MASK | LB_PCI_BASEX_ALOW_MASK))
69 | LB_PCI_BASEX_IO, LB_PCI_BASE0);
71 /* do a read of the register to flush the posting buffer */
72 tempscratch = v320usc_inl(LB_PCI_BASE0);
76 /* Set the LB_PCI_BASE0 register to allow PCI Config cycles to be used */
77 static void set_config_cycles(int alow)
81 tempscratch = v320usc_inl(LB_PCI_BASE0);
83 v320usc_outl((tempscratch &
84 ~(LB_PCI_BASEX_PCI_CMD_MASK | LB_PCI_BASEX_ALOW_MASK))
85 | LB_PCI_BASEX_CONFIG | alow, LB_PCI_BASE0);
87 /* do a read of the register to flush the posting buffer */
88 tempscratch = v320usc_inl(LB_PCI_BASE0);
92 static int mkaddr (unsigned char bus,
99 addr = ((bus & 0xff) << 0x10) |
100 ((devfn & 0xff) << 0x08) |
103 /* set alow for type 1 configuration cycle */
106 int device, function;
108 if (devfn >= PCI_DEVFN(12, 0))
111 device = PCI_SLOT(devfn);
112 function = PCI_FUNC(devfn);
114 /* This next line assumes that the PCI backplane connects */
115 /* the IDSEL line for each slot to a Address line with a */
116 /* small value resistor. Note: The PCI spec. suggests */
117 /* several options here. This code assumes the following */
118 /* IDSEL to Address line mapping. */
120 /* Slot Address Line */
127 /* 0x800 is AD11 set, shift left by the slot number (device) */
128 addr = (0x800 << device) | (function << 8) | where;
130 /* set alow for type 0 configuration cycle */
134 set_config_cycles(alow);
140 static int v320usc_pcibios_read_config_byte (
145 int retVal = PCIBIOS_SUCCESSFUL;
151 /* Clear status bits */
152 v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
154 if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
157 // *val = readb(V320USC_CONF_SPACE + addr);
158 *val = * (unsigned char *) (V320USC_CONF_SPACE + addr);
160 /* Check for master abort */
161 if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {
162 v320usc_outw(0xffff, PCI_STAT_W);
163 // printk("Master abort byte\n");
169 restore_flags(flags);
174 static int v320usc_pcibios_read_config_word (
179 int retVal = PCIBIOS_SUCCESSFUL;
184 return PCIBIOS_BAD_REGISTER_NUMBER;
188 /* Clear status bits */
189 v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
191 if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
194 *val = readw(V320USC_CONF_SPACE + addr);
196 /* Check for master abort */
197 if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {
198 v320usc_outw(0xffff, PCI_STAT_W);
199 // printk("Master abort word\n");
206 restore_flags(flags);
212 static int v320usc_pcibios_read_config_dword (
217 int retVal = PCIBIOS_SUCCESSFUL;
222 return PCIBIOS_BAD_REGISTER_NUMBER;
226 /* Clear status bits */
227 v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
229 if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
232 *val = readl(V320USC_CONF_SPACE + addr);
234 /* Check for master abort */
235 if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {
236 v320usc_outw(0xffff, PCI_STAT_W);
237 // printk("Master abort long\n");
244 restore_flags(flags);
250 static int v320usc_pcibios_write_config_byte (
255 int retVal = PCIBIOS_SUCCESSFUL;
261 if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
264 writeb(val, V320USC_CONF_SPACE + addr);
266 /* wait for write FIFO to empty */
267 v320usc_inw(PCI_STAT_W);
271 restore_flags(flags);
277 static int v320usc_pcibios_write_config_word (
282 int retVal = PCIBIOS_SUCCESSFUL;
287 return PCIBIOS_BAD_REGISTER_NUMBER;
291 if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
294 writew(val, V320USC_CONF_SPACE + addr);
296 /* wait for write FIFO to empty */
297 v320usc_inw(PCI_STAT_W);
301 restore_flags(flags);
307 static int v320usc_pcibios_write_config_dword (
312 int retVal = PCIBIOS_SUCCESSFUL;
317 return PCIBIOS_BAD_REGISTER_NUMBER;
321 if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
324 writel(val, V320USC_CONF_SPACE + addr);
326 /* wait for write FIFO to empty */
327 v320usc_inw(PCI_STAT_W);
331 restore_flags(flags);
337 struct pci_ops pci_config_ops = {
338 v320usc_pcibios_read_config_byte,
339 v320usc_pcibios_read_config_word,
340 v320usc_pcibios_read_config_dword,
341 v320usc_pcibios_write_config_byte,
342 v320usc_pcibios_write_config_word,
343 v320usc_pcibios_write_config_dword
346 /****************************************************************************/
348 /* Everything hangs off this */
349 static struct pci_bus *pci_root_bus;
351 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
353 return PCI_SLOT(dev->devfn);
357 static int __init map_keywest_irq(struct pci_dev *dev, u8 slot, u8 pin)
359 if (pin >= 1 && pin <= 4)
360 return(PINT_IRQ_BASE + 2 + pin - 1);
366 pcibios_setup(char *str)
373 pcibios_fixup_pbus_ranges(struct pci_bus *bus,
374 struct pbus_set_ranges_data *ranges)
376 ranges->io_start -= bus->resource[0]->start;
377 ranges->io_end -= bus->resource[0]->start;
378 ranges->mem_start -= bus->resource[1]->start;
379 ranges->mem_end -= bus->resource[1]->start;
383 void __init pcibios_init(void)
387 if (sh_mv.mv_init_pci != NULL)
390 if (v320usc_inw(PCI_VENDOR) != V3USC_PCI_VENDOR) {
391 printk("V320USC: PCI bridge chip not found\n");
395 switch (v320usc_inw(PCI_DEVICE)) {
396 case V3USC_PCI_DEVICE_MIPS_9: mode = "MIPS 9-bit"; break;
397 case V3USC_PCI_DEVICE_MIPS_5: mode = "MIPS 5-bit"; break;
398 case V3USC_PCI_DEVICE_SH3: mode = "SH-3"; break;
399 case V3USC_PCI_DEVICE_SH4: mode = "SH-4"; break;
400 default: mode = "unknown !"; break;
402 printk("V3 Semiconductor V320USC bridge in %s mode\n", mode);
405 * RST_OUT de asserted
407 v320usc_outb(0x80, SYSTEM);
410 * 16x8 latency time, GRANT, Normal arbitration, RAM Disable,
411 * CLK_OUT Disable, SYNC_RDY, BREQ_NEG
413 v320usc_outl(0x10120001, LB_BUS_CFG);
416 * System error enable, PCI bus master, Memory & IO Access enable
418 v320usc_outw(0x0047, PCI_CMD_W);
419 v320usc_outw(0xf100, PCI_STAT_W); /* clear any errors */
422 * 32x8 clocks as Latency Timer
424 v320usc_outl(0x00008800, PCI_HDR_CFG);
426 v320usc_outl(0x00005761, DRAM_BLK0);
427 v320usc_outl(0x02005761, DRAM_BLK1);
428 v320usc_outl(0x00000000, DRAM_BLK2);
429 v320usc_outl(0x00000000, DRAM_BLK3);
430 v320usc_outl(0x00000942, DRAM_CFG);
431 v320usc_outl(0x80030066, PCI_BUS_CFG);
433 v320usc_outl(v320usc_inl(INT_STAT), INT_STAT); /* clear any ints */
435 v320usc_outl(0x00000000, INT_CFG0);
436 v320usc_outl(0x00000000, INT_CFG1);
437 v320usc_outl(0x00000000, INT_CFG2);
438 v320usc_outl(0x00000000, INT_CFG3);
441 v320usc_outl(0x0c000000, PCI_I2O_BASE);
442 v320usc_outl(0x0c010053, PCI_I2O_MAP);
444 v320usc_outl(0x0c000001, PCI_MEM_BASE);
445 v320usc_outl(0x00010063, PCI_MEM_MAP);
447 v320usc_outl(0x00000000, LB_PCU_BASE); /* Disable PCU on SuperH */
449 v320usc_outl(0x00000081, PCI_PCU_BASE);
452 #ifndef CONFIG_PCMCIA
453 v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */
454 v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */
456 v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */
457 v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */
463 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
464 pci_assign_unassigned_resources();
465 pci_fixup_irqs(no_swizzle, map_keywest_irq);
467 #ifndef CONFIG_PCMCIA
468 v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */
469 v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */
471 v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */
472 v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */
476 * Lock the system registers
478 v320usc_outb(0x60, SYSTEM);
481 * Map all the PCI IO space
483 mach_port_map(PCIBIOS_MIN_IO, (64*1024) - PCIBIOS_MIN_IO,
484 V320USC_IO_SPACE+PCIBIOS_MIN_IO, 0);
487 void __init pcibios_fixup_bus(struct pci_bus *bus)
489 printk("%s,%d: %s()\n", __FILE__, __LINE__, __FUNCTION__);
492 static void __init pci_fixup_ide_bases(struct pci_dev *d)
497 * PCI IDE controllers use non-standard I/O port decoding, respect it.
499 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
501 printk("PCI: IDE base address fixup for %s\n", d->slot_name);
503 struct resource *r = &d->resource[i];
504 if ((r->start & ~0x80) == 0x374) {
511 /* Add future fixups here... */
512 struct pci_fixup pcibios_fixups[] = {
513 { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
517 /****************************************************************************/
518 #endif /* CONFIG_PCI */