import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / sh / kernel / pci-v320usc.c
1 /****************************************************************************/
2 /*
3  * pci.c: V3 Hurricane specific PCI support.
4  *
5  * Copyright (C) 1999,2000 Dan Aizenstros (dan@vcubed.com)
6  * Copyright (C) 2001, Lineo Inc., <davidm@moreton.com.au>
7  *               SH3 port.
8  */
9 /****************************************************************************/
10
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>
18 #include <asm/pci.h>
19 #include <asm/system.h>
20 #include <asm/irq.h>
21 #include <asm/byteorder.h>
22 #include <asm/io.h>
23
24 #include "pci-v320usc.h"
25
26 /****************************************************************************/
27 #ifdef CONFIG_PCI
28 /****************************************************************************/
29
30 #ifndef CONFIG_PCMCIA
31 #define V320USC_MEM_SPACE       0xB8000000 /* V320 sees this as AC000000 ! */
32 #define V320USC_IO_SPACE        0xB4000000
33 #define V320USC_CONF_SPACE      0xB4000000
34 #else
35 #define V320USC_MEM_SPACE       0xab000000
36 #define V320USC_IO_SPACE        0xaa000000
37 #define V320USC_CONF_SPACE      0xaa000000
38 #endif
39 #define V320USC_BASE            0xb1fd0000
40
41 #ifdef __LITTLE_ENDIAN
42 #define reg08(x)        (V320USC_BASE + (V320USC_##x))
43 #define reg16(x)        (V320USC_BASE + (V320USC_##x))
44 #else
45 #define reg08(x)        (V320USC_BASE + ((V320USC_##x)^3))
46 #define reg16(x)        (V320USC_BASE + ((V320USC_##x)^2))
47 #endif
48
49 #define reg32(x)        (V320USC_BASE + (V320USC_##x))
50
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))
57
58 /****************************************************************************/
59
60 /* Set the LB_PCI_BASE0 register to allow PCI Memory cycles to be used */
61
62 static void set_io_cycles(void)
63 {
64         u32 tempscratch;
65
66         v320usc_outl(
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);
70
71         /* do a read of the register to flush the posting buffer */
72         tempscratch = v320usc_inl(LB_PCI_BASE0);
73 }
74
75
76 /* Set the LB_PCI_BASE0 register to allow PCI Config cycles to be used */
77 static void set_config_cycles(int alow)
78 {
79         u32 tempscratch;
80
81         tempscratch = v320usc_inl(LB_PCI_BASE0);
82
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);
86
87         /* do a read of the register to flush the posting buffer */
88         tempscratch = v320usc_inl(LB_PCI_BASE0);
89 }
90
91
92 static int mkaddr (unsigned char bus,
93                 unsigned char devfn,
94                 unsigned char where)
95 {
96         int addr, alow;
97
98         if (bus) {
99                 addr =  ((bus    & 0xff) << 0x10) | 
100                         ((devfn & 0xff) << 0x08) |
101                          (where  & 0xff);
102
103                 /* set alow for type 1 configuration cycle */
104                 alow = 1;
105         } else {
106                 int device, function;
107
108                 if (devfn >= PCI_DEVFN(12, 0))
109                         return -1;
110
111                 device = PCI_SLOT(devfn);
112                 function = PCI_FUNC(devfn);
113
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.                          */
119
120                 /* Slot  Address Line */
121                 /*  0  - AD11 */
122                 /*  1  - AD12 */
123                 /*  2  - AD13 */
124                 /*  3  - AD14 */
125                 /*  4  - AD15 */
126
127                 /* 0x800 is AD11 set, shift left by the slot number (device) */
128                 addr = (0x800 << device) | (function << 8) | where;
129                 
130                 /* set alow for type 0 configuration cycle */
131                 alow = 0;
132         }
133
134         set_config_cycles(alow);
135
136         return addr;
137 }
138
139
140 static int v320usc_pcibios_read_config_byte (
141                                                 struct pci_dev *dev,
142                                                 int where,
143                                                 u8 *val)
144 {
145         int retVal = PCIBIOS_SUCCESSFUL;
146         unsigned long flags;
147         int addr;
148
149         save_and_cli(flags);
150
151         /* Clear status bits */
152         v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
153
154         if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
155                 retVal = -1;
156         else {
157                 // *val = readb(V320USC_CONF_SPACE + addr);
158                 *val = * (unsigned char *) (V320USC_CONF_SPACE + addr);
159
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");
164                         *val = 0xff;
165                 }
166         }
167
168         set_io_cycles();
169         restore_flags(flags);
170         return retVal;
171 }
172
173
174 static int v320usc_pcibios_read_config_word (
175                                                 struct pci_dev *dev,
176                                                 int where,
177                                                 u16 *val)
178 {
179         int retVal = PCIBIOS_SUCCESSFUL;
180         unsigned long flags;
181         int addr;
182
183         if (where & 1)
184                 return PCIBIOS_BAD_REGISTER_NUMBER;
185
186         save_and_cli(flags);
187
188         /* Clear status bits */
189         v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
190
191         if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
192                 retVal = -1;
193         else {
194                 *val = readw(V320USC_CONF_SPACE + addr);
195
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");
200                         *val = 0xffff;
201                 }
202         }
203
204         set_io_cycles();
205
206         restore_flags(flags);
207
208         return retVal;
209 }
210
211
212 static int v320usc_pcibios_read_config_dword (
213                                                 struct pci_dev *dev,
214                                                 int where,
215                                                 u32 *val)
216 {
217         int retVal = PCIBIOS_SUCCESSFUL;
218         unsigned long flags;
219         int addr;
220
221         if (where & 3)
222                 return PCIBIOS_BAD_REGISTER_NUMBER;
223
224         save_and_cli(flags);
225
226         /* Clear status bits */
227         v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
228
229         if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
230                 retVal = -1;
231         else {
232                 *val = readl(V320USC_CONF_SPACE + addr);
233
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");
238                         *val = 0xffffffff;
239                 }
240         }
241
242         set_io_cycles();
243
244         restore_flags(flags);
245
246         return retVal;
247 }
248
249
250 static int v320usc_pcibios_write_config_byte (
251                                                 struct pci_dev *dev,
252                                                 int where,
253                                                 u8 val)
254 {
255         int retVal = PCIBIOS_SUCCESSFUL;
256         unsigned long flags;
257         int addr;
258
259         save_and_cli(flags);
260
261         if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
262                 retVal = -1;
263         else
264                 writeb(val, V320USC_CONF_SPACE + addr);
265
266         /* wait for write FIFO to empty */
267         v320usc_inw(PCI_STAT_W);
268
269         set_io_cycles();
270
271         restore_flags(flags);
272
273         return retVal;
274 }
275
276
277 static int v320usc_pcibios_write_config_word (
278                                                 struct pci_dev *dev,
279                                                 int where,
280                                                 u16 val)
281 {
282         int retVal = PCIBIOS_SUCCESSFUL;
283         unsigned long flags;
284         int addr;
285
286         if (where & 1)
287                 return PCIBIOS_BAD_REGISTER_NUMBER;
288
289         save_and_cli(flags);
290
291         if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
292                 retVal = -1;
293         else
294                 writew(val, V320USC_CONF_SPACE + addr);
295
296         /* wait for write FIFO to empty */
297         v320usc_inw(PCI_STAT_W);
298
299         set_io_cycles();
300
301         restore_flags(flags);
302
303         return retVal;
304 }
305
306
307 static int v320usc_pcibios_write_config_dword (
308                                                 struct pci_dev *dev,
309                                                 int where,
310                                                 u32 val)
311 {
312         int retVal = PCIBIOS_SUCCESSFUL;
313         unsigned long flags;
314         int addr;
315
316         if (where & 3)
317                 return PCIBIOS_BAD_REGISTER_NUMBER;
318
319         save_and_cli(flags);
320
321         if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
322                 retVal = -1;
323         else
324                 writel(val, V320USC_CONF_SPACE + addr);
325
326         /* wait for write FIFO to empty */
327         v320usc_inw(PCI_STAT_W);
328
329         set_io_cycles();
330
331         restore_flags(flags);
332
333         return retVal;
334 }
335
336
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
344 };
345
346 /****************************************************************************/
347
348 /* Everything hangs off this */
349 static struct pci_bus *pci_root_bus;
350
351 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
352 {
353         return PCI_SLOT(dev->devfn);
354 }
355
356
357 static int __init map_keywest_irq(struct pci_dev *dev, u8 slot, u8 pin)
358 {
359         if (pin >= 1 && pin <= 4)
360                 return(PINT_IRQ_BASE + 2 + pin - 1);
361         return(-1);
362 }
363
364
365 char *
366 pcibios_setup(char *str)
367 {
368         return(str);
369 }
370
371
372 void __init
373 pcibios_fixup_pbus_ranges(struct pci_bus *bus,
374                           struct pbus_set_ranges_data *ranges)
375 {
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;
380 }
381
382
383 void __init pcibios_init(void)
384 {
385         char *mode;
386
387         if (sh_mv.mv_init_pci != NULL)
388                 sh_mv.mv_init_pci();
389
390         if (v320usc_inw(PCI_VENDOR) != V3USC_PCI_VENDOR) {
391                 printk("V320USC: PCI bridge chip not found\n");
392                 return;
393         }
394
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;
401         }
402         printk("V3 Semiconductor V320USC bridge in %s mode\n", mode);
403
404         /*
405          * RST_OUT de asserted
406          */
407         v320usc_outb(0x80, SYSTEM);
408
409         /*
410          * 16x8 latency time, GRANT, Normal arbitration, RAM Disable,
411          * CLK_OUT Disable, SYNC_RDY, BREQ_NEG
412          */
413         v320usc_outl(0x10120001, LB_BUS_CFG);
414
415         /*
416          * System error enable, PCI bus master, Memory & IO Access enable
417          */
418         v320usc_outw(0x0047, PCI_CMD_W);
419         v320usc_outw(0xf100, PCI_STAT_W); /* clear any errors */
420
421         /*
422          * 32x8 clocks as Latency Timer
423          */
424         v320usc_outl(0x00008800, PCI_HDR_CFG);
425
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);
432
433         v320usc_outl(v320usc_inl(INT_STAT), INT_STAT); /* clear any ints */
434
435         v320usc_outl(0x00000000, INT_CFG0);
436         v320usc_outl(0x00000000, INT_CFG1);
437         v320usc_outl(0x00000000, INT_CFG2);
438         v320usc_outl(0x00000000, INT_CFG3);
439
440 #if 0
441         v320usc_outl(0x0c000000, PCI_I2O_BASE);
442         v320usc_outl(0x0c010053, PCI_I2O_MAP);
443 #endif
444         v320usc_outl(0x0c000001, PCI_MEM_BASE);
445         v320usc_outl(0x00010063, PCI_MEM_MAP);
446
447         v320usc_outl(0x00000000, LB_PCU_BASE); /* Disable PCU on SuperH */
448 #if 0
449         v320usc_outl(0x00000081, PCI_PCU_BASE);
450 #endif
451
452 #ifndef CONFIG_PCMCIA
453         v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */
454         v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */
455 #else
456         v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */
457         v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */
458 #endif
459
460         /*
461          * do the scan
462          */
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);
466
467 #ifndef CONFIG_PCMCIA
468         v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */
469         v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */
470 #else
471         v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */
472         v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */
473 #endif
474
475         /*
476          * Lock the system registers
477          */
478         v320usc_outb(0x60, SYSTEM);
479
480         /*
481          * Map all the PCI IO space
482          */
483         mach_port_map(PCIBIOS_MIN_IO, (64*1024) - PCIBIOS_MIN_IO,
484                         V320USC_IO_SPACE+PCIBIOS_MIN_IO, 0);
485 }
486
487 void __init pcibios_fixup_bus(struct pci_bus *bus)
488 {
489         printk("%s,%d: %s()\n", __FILE__, __LINE__, __FUNCTION__);
490 }
491
492 static void __init pci_fixup_ide_bases(struct pci_dev *d)
493 {
494         int i;
495
496         /*
497          * PCI IDE controllers use non-standard I/O port decoding, respect it.
498          */
499         if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
500                 return;
501         printk("PCI: IDE base address fixup for %s\n", d->slot_name);
502         for(i=0; i<4; i++) {
503                 struct resource *r = &d->resource[i];
504                 if ((r->start & ~0x80) == 0x374) {
505                         r->start |= 2;
506                         r->end = r->start;
507                 }
508         }
509 }
510
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 },
514         { 0 }
515 };
516
517 /****************************************************************************/
518 #endif /* CONFIG_PCI */