File: /usr/src/linux/arch/ppc/kernel/gemini_setup.c

1     /*
2      * BK Id: SCCS/s.gemini_setup.c 1.11 08/20/01 14:34:41 paulus
3      */
4     /*
5      *  linux/arch/ppc/kernel/setup.c
6      *
7      *  Copyright (C) 1995 Linus Torvalds
8      *  Adapted from 'alpha' version by Gary Thomas
9      *  Modified by Cort Dougan (cort@cs.nmt.edu)
10      *  Synergy Microsystems board support by Dan Cox (dan@synergymicro.com)
11      *
12      */
13     
14     #include <linux/config.h>
15     #include <linux/stddef.h>
16     #include <linux/kernel.h>
17     #include <linux/init.h>
18     #include <linux/errno.h> 
19     #include <linux/reboot.h>
20     #include <linux/pci.h>
21     #include <linux/time.h>
22     #include <linux/kdev_t.h>
23     #include <linux/types.h>
24     #include <linux/major.h>
25     #include <linux/blk.h>
26     #include <linux/console.h>
27     
28     #include <asm/system.h>
29     #include <asm/pgtable.h>
30     #include <asm/page.h>
31     #include <asm/dma.h>
32     #include <asm/io.h>
33     #include <asm/m48t35.h>
34     #include <asm/gemini.h>
35     #include <asm/time.h>
36     
37     #include "local_irq.h"
38     #include "open_pic.h"
39     
40     void gemini_find_bridges(void);
41     static int gemini_get_clock_speed(void);
42     extern void gemini_pcibios_fixup(void);
43     
44     static char *gemini_board_families[] = {
45       "VGM", "VSS", "KGM", "VGR", "VCM", "VCS", "KCM", "VCR"
46     };
47     static int gemini_board_count = sizeof(gemini_board_families) /
48                                      sizeof(gemini_board_families[0]);
49     
50     static unsigned int cpu_7xx[16] = {
51     	0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
52     };
53     static unsigned int cpu_6xx[16] = {
54     	0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0
55     };
56     
57     /*
58      * prom_init is the Gemini version of prom.c:prom_init.  We only need
59      * the BSS clearing code, so I copied that out of prom.c.  This is a
60      * lot simpler than hacking prom.c so it will build with Gemini. -VAL
61      */
62     
63     #define PTRRELOC(x)	((typeof(x))((unsigned long)(x) + offset))
64     
65     unsigned long
66     prom_init(void)
67     {
68     	unsigned long offset = reloc_offset();
69     	unsigned long phys;
70     	extern char __bss_start, _end;
71     
72     	/* First zero the BSS -- use memset, some arches don't have
73     	 * caches on yet */
74     	memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
75     
76      	/* Default */
77      	phys = offset + KERNELBASE;
78     
79     	gemini_prom_init();
80     
81     	return phys;
82     }
83     
84     int
85     gemini_get_cpuinfo(char *buffer)
86     {
87     	int len;
88     	unsigned char reg, rev;
89     	char *family;
90     	unsigned int type;
91     
92     	reg = readb(GEMINI_FEAT);
93     	family = gemini_board_families[((reg>>4) & 0xf)];
94     	if (((reg>>4) & 0xf) > gemini_board_count)
95     		printk(KERN_ERR "cpuinfo(): unable to determine board family\n");
96     
97     	reg = readb(GEMINI_BREV);
98     	type = (reg>>4) & 0xf;
99     	rev = reg & 0xf;
100     
101     	reg = readb(GEMINI_BECO);
102     
103     	len = sprintf( buffer, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", 
104     		       family, type, (rev + 'A'), (reg & 0xf));
105     
106     	len = sprintf(buffer, "board\t\t: Gemini %s", family);
107     	if (type > 9)
108     		len += sprintf(buffer+len, "%c", (type - 10) + 'A');
109     	else
110     		len += sprintf(buffer+len, "%d", type);
111     
112     	len += sprintf(buffer+len, ", rev %c, eco %d\n",
113     		       (rev + 'A'), (reg & 0xf));
114     
115     	len += sprintf(buffer+len, "clock\t\t: %dMhz\n", 
116     		       gemini_get_clock_speed());
117     
118     	return len;
119     }
120     
121     static u_char gemini_openpic_initsenses[] = {
122     	1,
123     	1,
124     	1,
125     	1,
126     	0,
127     	0,
128     	1, /* remainder are level-triggered */
129     };
130     
131     #define GEMINI_MPIC_ADDR (0xfcfc0000)
132     #define GEMINI_MPIC_PCI_CFG (0x80005800)
133     
134     void __init gemini_openpic_init(void)
135     {
136     
137     	OpenPIC_Addr = (volatile struct OpenPIC *)
138     		grackle_read(GEMINI_MPIC_PCI_CFG + 0x10);
139     	OpenPIC_InitSenses = gemini_openpic_initsenses;
140     	OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses );
141     
142     	ioremap( GEMINI_MPIC_ADDR, OPENPIC_SIZE);
143     }
144     
145     
146     extern unsigned long loops_per_jiffy;
147     extern int root_mountflags;
148     extern char cmd_line[];
149     
150     void
151     gemini_heartbeat(void)
152     {
153     	static unsigned long led = GEMINI_LEDBASE+(4*8);
154     	static char direction = 8;
155     	*(char *)led = 0;
156     	if ( (led + direction) > (GEMINI_LEDBASE+(7*8)) ||
157     	     (led + direction) < (GEMINI_LEDBASE+(4*8)) )
158     		direction *= -1;
159     	led += direction;
160     	*(char *)led = 0xff;
161     	ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
162     }
163     
164     void __init gemini_setup_arch(void)
165     {
166     	extern char cmd_line[];
167     
168     
169     	loops_per_jiffy = 50000000/HZ;
170     
171     #ifdef CONFIG_BLK_DEV_INITRD
172     	/* bootable off CDROM */
173     	if (initrd_start)
174     		ROOT_DEV = MKDEV(SCSI_CDROM_MAJOR, 0);
175     	else
176     #endif
177     		ROOT_DEV = to_kdev_t(0x0801);
178     
179     	/* nothing but serial consoles... */
180     	sprintf(cmd_line, "%s console=ttyS0", cmd_line);
181     
182     	printk("Boot arguments: %s\n", cmd_line);
183     
184     	ppc_md.heartbeat = gemini_heartbeat;
185     	ppc_md.heartbeat_reset = HZ/8;
186     	ppc_md.heartbeat_count = 1;
187     	
188     	/* Lookup PCI hosts */
189     	gemini_find_bridges();
190     	/* take special pains to map the MPIC, since it isn't mapped yet */
191     	gemini_openpic_init();
192     	/* start the L2 */
193     	gemini_init_l2();
194     }
195     
196     
197     int
198     gemini_get_clock_speed(void)
199     {
200     	unsigned long hid1, pvr;
201     	int clock;
202     
203     	pvr = mfspr(PVR);
204     	hid1 = (mfspr(HID1) >> 28) & 0xf;
205     	if (PVR_VER(pvr) == 8 ||
206     	    PVR_VER(pvr) == 12)
207     		hid1 = cpu_7xx[hid1];
208     	else
209     		hid1 = cpu_6xx[hid1];
210     
211     	switch((readb(GEMINI_BSTAT) & 0xc) >> 2) {
212     
213     	case 0:
214     	default:
215     		clock = (hid1*100)/3;
216     		break;
217       
218     	case 1:
219     		clock = (hid1*125)/3;
220     		break;
221       
222     	case 2:
223     		clock = (hid1*50);
224     		break;
225     	}
226     
227     	return clock;
228     }
229     
230     void __init gemini_init_l2(void)
231     {
232             unsigned char reg, brev, fam, creg;
233             unsigned long cache;
234             unsigned long pvr;
235     
236             reg = readb(GEMINI_L2CFG);
237             brev = readb(GEMINI_BREV);
238             fam = readb(GEMINI_FEAT);
239             pvr = mfspr(PVR);
240     
241             switch(PVR_VER(pvr)) {
242     
243             case 8:
244                     if (reg & 0xc0)
245                             cache = (((reg >> 6) & 0x3) << 28);
246                     else
247                             cache = 0x3 << 28;
248     
249     #ifdef CONFIG_SMP
250                     /* Pre-3.0 processor revs had snooping errata.  Leave
251                        their L2's disabled with SMP. -- Dan */
252                     if (PVR_CFG(pvr) < 3) {
253                             printk("Pre-3.0 750; L2 left disabled!\n");
254                             return;
255                     }
256     #endif /* CONFIG_SMP */
257     
258                     /* Special case: VGM5-B's came before L2 ratios were set on
259                        the board.  Processor speed shouldn't be too high, so
260                        set L2 ratio to 1:1.5.  */
261                     if ((brev == 0x51) && ((fam & 0xa0) >> 4) == 0)
262                             reg |= 1;
263     
264                     /* determine best cache ratio based upon what the board
265                        tells us (which sometimes _may_ not be true) and
266                        the processor speed. */
267                     else {
268                             if (gemini_get_clock_speed() > 250)
269                                     reg = 2;
270                     }
271                     break;
272             case 12:
273     	{
274     		static unsigned long l2_size_val = 0;
275     		
276     		if (!l2_size_val)
277     			l2_size_val = _get_L2CR();
278     		cache = l2_size_val;
279                     break;
280     	}
281             case 4:
282             case 9:
283                     creg = readb(GEMINI_CPUSTAT);
284                     if (((creg & 0xc) >> 2) != 1)
285                             printk("Dual-604 boards don't support the use of L2\n");
286                     else
287                             writeb(1, GEMINI_L2CFG);
288                     return;
289             default:
290                     printk("Unknown processor; L2 left disabled\n");
291                     return;
292             }
293     
294             cache |= ((1<<reg) << 25);
295             cache |= (L2CR_L2RAM_MASK|L2CR_L2CTL|L2CR_L2DO);
296             _set_L2CR(0);
297             _set_L2CR(cache | L2CR_L2E);
298     
299     }
300     
301     void
302     gemini_restart(char *cmd)
303     {
304     	__cli();
305     	/* make a clean restart, not via the MPIC */
306     	_gemini_reboot();
307     	for(;;);
308     }
309     
310     void
311     gemini_power_off(void)
312     {
313     	for(;;);
314     }
315     
316     void
317     gemini_halt(void)
318     {
319     	gemini_restart(NULL);
320     }
321     
322     void __init gemini_init_IRQ(void)
323     {
324     	/* gemini has no 8259 */
325     	openpic_init(1, 0, 0, -1);
326     }
327     
328     #define gemini_rtc_read(x)       (readb(GEMINI_RTC+(x)))
329     #define gemini_rtc_write(val,x)  (writeb((val),(GEMINI_RTC+(x))))
330     
331     /* ensure that the RTC is up and running */
332     long __init gemini_time_init(void)
333     {
334     	unsigned char reg;
335     
336     	reg = gemini_rtc_read(M48T35_RTC_CONTROL);
337     
338     	if ( reg & M48T35_RTC_STOPPED ) {
339     		printk(KERN_INFO "M48T35 real-time-clock was stopped. Now starting...\n");
340     		gemini_rtc_write((reg & ~(M48T35_RTC_STOPPED)), M48T35_RTC_CONTROL);
341     		gemini_rtc_write((reg | M48T35_RTC_SET), M48T35_RTC_CONTROL);
342     	}
343     	return 0;
344     }
345     
346     #undef DEBUG_RTC
347     
348     unsigned long
349     gemini_get_rtc_time(void)
350     {
351     	unsigned int year, mon, day, hour, min, sec;
352     	unsigned char reg;
353     
354     	reg = gemini_rtc_read(M48T35_RTC_CONTROL);
355     	gemini_rtc_write((reg|M48T35_RTC_READ), M48T35_RTC_CONTROL);
356     #ifdef DEBUG_RTC
357     	printk("get rtc: reg = %x\n", reg);
358     #endif
359       
360     	do {
361     		sec = gemini_rtc_read(M48T35_RTC_SECONDS);
362     		min = gemini_rtc_read(M48T35_RTC_MINUTES);
363     		hour = gemini_rtc_read(M48T35_RTC_HOURS);
364     		day = gemini_rtc_read(M48T35_RTC_DOM);
365     		mon = gemini_rtc_read(M48T35_RTC_MONTH);
366     		year = gemini_rtc_read(M48T35_RTC_YEAR);
367     	} while( sec != gemini_rtc_read(M48T35_RTC_SECONDS));
368     #ifdef DEBUG_RTC
369     	printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", 
370     	       sec, min, hour, day, mon, year);
371     #endif
372     
373     	gemini_rtc_write(reg, M48T35_RTC_CONTROL);
374     
375     	BCD_TO_BIN(sec);
376     	BCD_TO_BIN(min);
377     	BCD_TO_BIN(hour);
378     	BCD_TO_BIN(day);
379     	BCD_TO_BIN(mon);
380     	BCD_TO_BIN(year);
381     
382     	if ((year += 1900) < 1970)
383     		year += 100;
384     #ifdef DEBUG_RTC
385     	printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", 
386     	       sec, min, hour, day, mon, year);
387     #endif
388     
389     	return mktime( year, mon, day, hour, min, sec );
390     }
391     
392     
393     int
394     gemini_set_rtc_time( unsigned long now )
395     {
396     	unsigned char reg;
397     	struct rtc_time tm;
398     
399     	to_tm( now, &tm );
400     
401     	reg = gemini_rtc_read(M48T35_RTC_CONTROL);
402     #if DEBUG_RTC
403     	printk("set rtc: reg = %x\n", reg);
404     #endif
405       
406     	gemini_rtc_write((reg|M48T35_RTC_SET), M48T35_RTC_CONTROL);
407     #if DEBUG_RTC
408     	printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n",
409     	       tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year);
410     #endif
411       
412     	tm.tm_year -= 1900;
413     	BIN_TO_BCD(tm.tm_sec);
414     	BIN_TO_BCD(tm.tm_min);
415     	BIN_TO_BCD(tm.tm_hour);
416     	BIN_TO_BCD(tm.tm_mon);
417     	BIN_TO_BCD(tm.tm_mday);
418     	BIN_TO_BCD(tm.tm_year);
419     #ifdef DEBUG_RTC
420     	printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n",
421     	       tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year);
422     #endif
423     
424     	gemini_rtc_write(tm.tm_sec, M48T35_RTC_SECONDS);
425     	gemini_rtc_write(tm.tm_min, M48T35_RTC_MINUTES);
426     	gemini_rtc_write(tm.tm_hour, M48T35_RTC_HOURS);
427     	gemini_rtc_write(tm.tm_mday, M48T35_RTC_DOM);
428     	gemini_rtc_write(tm.tm_mon, M48T35_RTC_MONTH);
429     	gemini_rtc_write(tm.tm_year, M48T35_RTC_YEAR);
430     
431     	/* done writing */
432     	gemini_rtc_write(reg, M48T35_RTC_CONTROL);
433     
434     	if ((time_state == TIME_ERROR) || (time_state == TIME_BAD))
435     		time_state = TIME_OK;
436       
437     	return 0;
438     }
439     
440     /*  use the RTC to determine the decrementer count */
441     void __init gemini_calibrate_decr(void)
442     {
443     	int freq, divisor;
444     	unsigned char reg;
445     
446     	/* determine processor bus speed */
447     	reg = readb(GEMINI_BSTAT);
448     
449     	switch(((reg & 0x0c)>>2)&0x3) {
450     	case 0:
451     	default:
452     		freq = 66667;
453     		break;
454     	case 1:
455     		freq = 83000;
456     		break;
457     	case 2:
458     		freq = 100000;
459     		break;
460     	}
461     
462     	freq *= 1000;
463     	divisor = 4;
464     	tb_ticks_per_jiffy = freq / HZ / divisor;
465     	tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
466     }
467     
468     unsigned long __init gemini_find_end_of_memory(void)
469     {
470     	unsigned long total;
471     	unsigned char reg;
472     
473     	reg = readb(GEMINI_MEMCFG);
474     	total = ((1<<((reg & 0x7) - 1)) *
475     		 (8<<((reg >> 3) & 0x7)));
476     	total *= (1024*1024);
477     	return total;
478     }
479     
480     static void __init
481     gemini_map_io(void)
482     {
483     	io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO);
484     	io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
485     }
486     
487     #ifdef CONFIG_SMP
488     static int
489     smp_gemini_probe(void)
490     {
491     	int i, nr;
492     
493             nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK) >> 2;
494     	if (nr == 0)
495     		nr = 4;
496     
497     	if (nr > 1) {
498     		openpic_request_IPIs();
499     		for (i = 1; i < nr; ++i)
500     			smp_hw_index[i] = i;
501     	}
502     
503     	return nr;
504     }
505     
506     static void
507     smp_gemini_kick_cpu(int nr)
508     {
509     	openpic_init_processor( 1<<nr );
510     	openpic_init_processor( 0 );
511     }
512     
513     static void
514     smp_gemini_setup_cpu(int cpu_nr)
515     {
516     	if (OpenPIC_Addr)
517     		do_openpic_setup_cpu();
518     	if (cpu_nr > 0)
519     		gemini_init_l2();
520     }
521     
522     static struct smp_ops_t gemini_smp_ops = {
523     	smp_openpic_message_pass,
524     	smp_gemini_probe,
525     	smp_gemini_kick_cpu,
526     	smp_gemini_setup_cpu,
527     };
528     #endif /* CONFIG_SMP */
529     
530     void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
531     			  unsigned long r6, unsigned long r7)
532     {
533     	int i;
534     
535     	for(i = 0; i < GEMINI_LEDS; i++)
536     		gemini_led_off(i);
537      
538     	ISA_DMA_THRESHOLD = 0;
539     	DMA_MODE_READ = 0;
540     	DMA_MODE_WRITE = 0;
541     
542     #ifdef CONFIG_BLK_DEV_INITRD
543     	if ( r4 )
544     	{
545     		initrd_start = r4 + KERNELBASE;
546     		initrd_end = r5 + KERNELBASE;
547     	}
548     #endif
549     
550     	ppc_md.setup_arch = gemini_setup_arch;
551     	ppc_md.setup_residual = NULL;
552     	ppc_md.get_cpuinfo = gemini_get_cpuinfo;
553     	ppc_md.irq_cannonicalize = NULL;
554     	ppc_md.init_IRQ = gemini_init_IRQ;
555     	ppc_md.get_irq = openpic_get_irq;
556     	ppc_md.init = NULL;
557     
558     	ppc_md.restart = gemini_restart;
559     	ppc_md.power_off = gemini_power_off;
560     	ppc_md.halt = gemini_halt;
561     
562     	ppc_md.time_init = gemini_time_init;
563     	ppc_md.set_rtc_time = gemini_set_rtc_time;
564     	ppc_md.get_rtc_time = gemini_get_rtc_time;
565     	ppc_md.calibrate_decr = gemini_calibrate_decr;
566     
567     	ppc_md.find_end_of_memory = gemini_find_end_of_memory;
568     	ppc_md.setup_io_mappings = gemini_map_io;
569     
570     	/* no keyboard/mouse/video stuff yet.. */
571     	ppc_md.kbd_setkeycode = NULL;
572     	ppc_md.kbd_getkeycode = NULL;
573     	ppc_md.kbd_translate = NULL;
574     	ppc_md.kbd_unexpected_up = NULL;
575     	ppc_md.kbd_leds = NULL;
576     	ppc_md.kbd_init_hw = NULL;
577     #ifdef CONFIG_MAGIC_SYSRQ
578     	ppc_md.ppc_kbd_sysrq_xlate = NULL;
579     #endif
580     	ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup;
581     
582     #ifdef CONFIG_SMP
583     	ppc_md.smp_ops = &gemini_smp_ops;
584     #endif /* CONFIG_SMP */
585     }
586