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 
set_io_cycles(void)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 */
set_config_cycles(int alow)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 
mkaddr(unsigned char bus,unsigned char devfn,unsigned char where)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 
v320usc_pcibios_read_config_byte(struct pci_dev * dev,int where,u8 * val)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 
v320usc_pcibios_read_config_word(struct pci_dev * dev,int where,u16 * val)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 
v320usc_pcibios_read_config_dword(struct pci_dev * dev,int where,u32 * val)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 
v320usc_pcibios_write_config_byte(struct pci_dev * dev,int where,u8 val)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 
v320usc_pcibios_write_config_word(struct pci_dev * dev,int where,u16 val)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 
v320usc_pcibios_write_config_dword(struct pci_dev * dev,int where,u32 val)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 
no_swizzle(struct pci_dev * dev,u8 * pin)351 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
352 {
353 	return PCI_SLOT(dev->devfn);
354 }
355 
356 
map_keywest_irq(struct pci_dev * dev,u8 slot,u8 pin)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 *
pcibios_setup(char * str)366 pcibios_setup(char *str)
367 {
368 	return(str);
369 }
370 
371 
372 void __init
pcibios_fixup_pbus_ranges(struct pci_bus * bus,struct pbus_set_ranges_data * ranges)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 
pcibios_init(void)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 
pcibios_fixup_bus(struct pci_bus * bus)487 void __init pcibios_fixup_bus(struct pci_bus *bus)
488 {
489 	printk("%s,%d: %s()\n", __FILE__, __LINE__, __FUNCTION__);
490 }
491 
pci_fixup_ide_bases(struct pci_dev * d)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 */
519