File: /usr/src/linux/arch/m68k/amiga/config.c

1     /*
2      *  linux/arch/m68k/amiga/config.c
3      *
4      *  Copyright (C) 1993 Hamish Macdonald
5      *
6      * This file is subject to the terms and conditions of the GNU General Public
7      * License.  See the file COPYING in the main directory of this archive
8      * for more details.
9      */
10     
11     /*
12      * Miscellaneous Amiga stuff
13      */
14     
15     #include <linux/config.h>
16     #include <linux/types.h>
17     #include <linux/kernel.h>
18     #include <linux/mm.h>
19     #include <linux/tty.h>
20     #include <linux/console.h>
21     #include <linux/init.h>
22     #ifdef CONFIG_ZORRO
23     #include <linux/zorro.h>
24     #endif
25     
26     #include <asm/bootinfo.h>
27     #include <asm/setup.h>
28     #include <asm/system.h>
29     #include <asm/pgtable.h>
30     #include <asm/amigahw.h>
31     #include <asm/amigaints.h>
32     #include <asm/irq.h>
33     #include <asm/rtc.h>
34     #include <asm/keyboard.h>
35     #include <asm/machdep.h>
36     #include <asm/io.h>
37     
38     unsigned long amiga_model;
39     unsigned long amiga_eclock;
40     unsigned long amiga_masterclock;
41     unsigned long amiga_colorclock;
42     unsigned long amiga_chipset;
43     unsigned char amiga_vblank;
44     unsigned char amiga_psfreq;
45     struct amiga_hw_present amiga_hw_present;
46     
47     static char s_a500[] __initdata = "A500";
48     static char s_a500p[] __initdata = "A500+";
49     static char s_a600[] __initdata = "A600";
50     static char s_a1000[] __initdata = "A1000";
51     static char s_a1200[] __initdata = "A1200";
52     static char s_a2000[] __initdata = "A2000";
53     static char s_a2500[] __initdata = "A2500";
54     static char s_a3000[] __initdata = "A3000";
55     static char s_a3000t[] __initdata = "A3000T";
56     static char s_a3000p[] __initdata = "A3000+";
57     static char s_a4000[] __initdata = "A4000";
58     static char s_a4000t[] __initdata = "A4000T";
59     static char s_cdtv[] __initdata = "CDTV";
60     static char s_cd32[] __initdata = "CD32";
61     static char s_draco[] __initdata = "Draco";
62     static char *amiga_models[] __initdata = {
63         s_a500, s_a500p, s_a600, s_a1000, s_a1200, s_a2000, s_a2500, s_a3000,
64         s_a3000t, s_a3000p, s_a4000, s_a4000t, s_cdtv, s_cd32, s_draco,
65     };
66     
67     static char amiga_model_name[13] = "Amiga ";
68     
69     extern char m68k_debug_device[];
70     
71     static void amiga_sched_init(void (*handler)(int, void *, struct pt_regs *));
72     /* amiga specific keyboard functions */
73     extern int amiga_keyb_init(void);
74     extern int amiga_kbdrate (struct kbd_repeat *);
75     extern int amiga_kbd_translate(unsigned char keycode, unsigned char *keycodep,
76     			       char raw_mode);
77     /* amiga specific irq functions */
78     extern void amiga_init_IRQ (void);
79     extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
80     extern int amiga_request_irq (unsigned int irq,
81     			      void (*handler)(int, void *, struct pt_regs *),
82                                   unsigned long flags, const char *devname,
83     			      void *dev_id);
84     extern void amiga_free_irq (unsigned int irq, void *dev_id);
85     extern void amiga_enable_irq (unsigned int);
86     extern void amiga_disable_irq (unsigned int);
87     static void amiga_get_model(char *model);
88     static int amiga_get_hardware_list(char *buffer);
89     extern int amiga_get_irq_list (char *);
90     /* amiga specific timer functions */
91     static unsigned long amiga_gettimeoffset (void);
92     static void a3000_gettod (int *, int *, int *, int *, int *, int *);
93     static void a2000_gettod (int *, int *, int *, int *, int *, int *);
94     static int amiga_hwclk (int, struct hwclk_time *);
95     static int amiga_set_clock_mmss (unsigned long);
96     extern void amiga_mksound( unsigned int count, unsigned int ticks );
97     #ifdef CONFIG_AMIGA_FLOPPY
98     extern void amiga_floppy_setup(char *, int *);
99     #endif
100     static void amiga_reset (void);
101     static int amiga_wait_key (struct console *co);
102     extern void amiga_init_sound(void);
103     static void amiga_savekmsg_init(void);
104     static void amiga_mem_console_write(struct console *co, const char *b,
105     				    unsigned int count);
106     void amiga_serial_console_write(struct console *co, const char *s,
107     				unsigned int count);
108     static void amiga_debug_init(void);
109     #ifdef CONFIG_HEARTBEAT
110     static void amiga_heartbeat(int on);
111     #endif
112     
113     static struct console amiga_console_driver = {
114     	name:		"debug",
115     	wait_key:	amiga_wait_key,
116     	flags:		CON_PRINTBUFFER,
117     	index:		-1,
118     };
119     
120     #ifdef CONFIG_MAGIC_SYSRQ
121     static char amiga_sysrq_xlate[128] =
122     	"\0001234567890-=\\\000\000"					/* 0x00 - 0x0f */
123     	"qwertyuiop[]\000123"							/* 0x10 - 0x1f */
124     	"asdfghjkl;'\000\000456"						/* 0x20 - 0x2f */
125     	"\000zxcvbnm,./\000+789"						/* 0x30 - 0x3f */
126     	" \177\t\r\r\000\177\000\000\000-\000\000\000\000\000"	/* 0x40 - 0x4f */
127     	"\000\201\202\203\204\205\206\207\210\211()/*+\000"	/* 0x50 - 0x5f */
128     	"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"	/* 0x60 - 0x6f */
129     	"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";	/* 0x70 - 0x7f */
130     #endif
131     
132     extern void (*kd_mksound)(unsigned int, unsigned int);
133     
134     
135         /*
136          *  Motherboard Resources present in all Amiga models
137          */
138     
139     static struct {
140         struct resource _ciab, _ciaa, _custom, _kickstart;
141     } mb_resources = {
142         _ciab:	{ "CIA B", 0x00bfd000, 0x00bfdfff },
143         _ciaa:	{ "CIA A", 0x00bfe000, 0x00bfefff },
144         _custom:	{ "Custom I/O", 0x00dff000, 0x00dfffff },
145         _kickstart:	{ "Kickstart ROM", 0x00f80000, 0x00ffffff }
146     };
147     
148     static struct resource rtc_resource = {
149         NULL, 0x00dc0000, 0x00dcffff
150     };
151     
152     static struct resource ram_resource[NUM_MEMINFO];
153     
154     
155         /*
156          *  Parse an Amiga-specific record in the bootinfo
157          */
158     
159     int amiga_parse_bootinfo(const struct bi_record *record)
160     {
161         int unknown = 0;
162         const unsigned long *data = record->data;
163     
164         switch (record->tag) {
165     	case BI_AMIGA_MODEL:
166     	    amiga_model = *data;
167     	    break;
168     
169     	case BI_AMIGA_ECLOCK:
170     	    amiga_eclock = *data;
171     	    break;
172     
173     	case BI_AMIGA_CHIPSET:
174     	    amiga_chipset = *data;
175     	    break;
176     
177     	case BI_AMIGA_CHIP_SIZE:
178     	    amiga_chip_size = *(const int *)data;
179     	    break;
180     
181     	case BI_AMIGA_VBLANK:
182     	    amiga_vblank = *(const unsigned char *)data;
183     	    break;
184     
185     	case BI_AMIGA_PSFREQ:
186     	    amiga_psfreq = *(const unsigned char *)data;
187     	    break;
188     
189     	case BI_AMIGA_AUTOCON:
190     #ifdef CONFIG_ZORRO
191     	    if (zorro_num_autocon < ZORRO_NUM_AUTO) {
192     		const struct ConfigDev *cd = (struct ConfigDev *)data;
193     		struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++];
194     		dev->rom = cd->cd_Rom;
195     		dev->slotaddr = cd->cd_SlotAddr;
196     		dev->slotsize = cd->cd_SlotSize;
197     		dev->resource.start = (unsigned long)cd->cd_BoardAddr;
198     		dev->resource.end = dev->resource.start+cd->cd_BoardSize-1;
199     	    } else
200     		printk("amiga_parse_bootinfo: too many AutoConfig devices\n");
201     #endif /* CONFIG_ZORRO */
202     	    break;
203     
204     	case BI_AMIGA_SERPER:
205     	    /* serial port period: ignored here */
206     	    break;
207     
208     	default:
209     	    unknown = 1;
210         }
211         return(unknown);
212     }
213     
214         /*
215          *  Identify builtin hardware
216          */
217     
218     static void __init amiga_identify(void)
219     {
220       /* Fill in some default values, if necessary */
221       if (amiga_eclock == 0)
222         amiga_eclock = 709379;
223     
224       memset(&amiga_hw_present, 0, sizeof(amiga_hw_present));
225     
226       printk("Amiga hardware found: ");
227       if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) {
228         printk("[%s] ", amiga_models[amiga_model-AMI_500]);
229         strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]);
230       }
231     
232       switch(amiga_model) {
233       case AMI_UNKNOWN:
234         goto Generic;
235     
236       case AMI_600:
237       case AMI_1200:
238         AMIGAHW_SET(A1200_IDE);
239         AMIGAHW_SET(PCMCIA);
240       case AMI_500:
241       case AMI_500PLUS:
242       case AMI_1000:
243       case AMI_2000:
244       case AMI_2500:
245         AMIGAHW_SET(A2000_CLK);	/* Is this correct for all models? */
246         goto Generic;
247     
248       case AMI_3000:
249       case AMI_3000T:
250         AMIGAHW_SET(AMBER_FF);
251         AMIGAHW_SET(MAGIC_REKICK);
252         /* fall through */
253       case AMI_3000PLUS:
254         AMIGAHW_SET(A3000_SCSI);
255         AMIGAHW_SET(A3000_CLK);
256         AMIGAHW_SET(ZORRO3);
257         goto Generic;
258     
259       case AMI_4000T:
260         AMIGAHW_SET(A4000_SCSI);
261         /* fall through */
262       case AMI_4000:
263         AMIGAHW_SET(A4000_IDE);
264         AMIGAHW_SET(A3000_CLK);
265         AMIGAHW_SET(ZORRO3);
266         goto Generic;
267     
268       case AMI_CDTV:
269       case AMI_CD32:
270         AMIGAHW_SET(CD_ROM);
271         AMIGAHW_SET(A2000_CLK);             /* Is this correct? */
272         goto Generic;
273     
274       Generic:
275         AMIGAHW_SET(AMI_VIDEO);
276         AMIGAHW_SET(AMI_BLITTER);
277         AMIGAHW_SET(AMI_AUDIO);
278         AMIGAHW_SET(AMI_FLOPPY);
279         AMIGAHW_SET(AMI_KEYBOARD);
280         AMIGAHW_SET(AMI_MOUSE);
281         AMIGAHW_SET(AMI_SERIAL);
282         AMIGAHW_SET(AMI_PARALLEL);
283         AMIGAHW_SET(CHIP_RAM);
284         AMIGAHW_SET(PAULA);
285     
286         switch(amiga_chipset) {
287         case CS_OCS:
288         case CS_ECS:
289         case CS_AGA:
290           switch (custom.deniseid & 0xf) {
291           case 0x0c:
292     	AMIGAHW_SET(DENISE_HR);
293     	break;
294           case 0x08:
295     	AMIGAHW_SET(LISA);
296     	break;
297           }
298           break;
299         default:
300           AMIGAHW_SET(DENISE);
301           break;
302         }
303         switch ((custom.vposr>>8) & 0x7f) {
304         case 0x00:
305           AMIGAHW_SET(AGNUS_PAL);
306           break;
307         case 0x10:
308           AMIGAHW_SET(AGNUS_NTSC);
309           break;
310         case 0x20:
311         case 0x21:
312           AMIGAHW_SET(AGNUS_HR_PAL);
313           break;
314         case 0x30:
315         case 0x31:
316           AMIGAHW_SET(AGNUS_HR_NTSC);
317           break;
318         case 0x22:
319         case 0x23:
320           AMIGAHW_SET(ALICE_PAL);
321           break;
322         case 0x32:
323         case 0x33:
324           AMIGAHW_SET(ALICE_NTSC);
325           break;
326         }
327         AMIGAHW_SET(ZORRO);
328         break;
329     
330       case AMI_DRACO:
331         panic("No support for Draco yet");
332      
333       default:
334         panic("Unknown Amiga Model");
335       }
336     
337     #define AMIGAHW_ANNOUNCE(name, str)			\
338       if (AMIGAHW_PRESENT(name))				\
339         printk(str)
340     
341       AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO ");
342       AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER ");
343       AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF ");
344       AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO ");
345       AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY ");
346       AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI ");
347       AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI ");
348       AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE ");
349       AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE ");
350       AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM ");
351       AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD ");
352       AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE ");
353       AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL ");
354       AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL ");
355       AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK ");
356       AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK ");
357       AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM ");
358       AMIGAHW_ANNOUNCE(PAULA, "PAULA ");
359       AMIGAHW_ANNOUNCE(DENISE, "DENISE ");
360       AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR ");
361       AMIGAHW_ANNOUNCE(LISA, "LISA ");
362       AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL ");
363       AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC ");
364       AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL ");
365       AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC ");
366       AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL ");
367       AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC ");
368       AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK ");
369       AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA ");
370       if (AMIGAHW_PRESENT(ZORRO))
371         printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : "");
372       printk("\n");
373     
374     #undef AMIGAHW_ANNOUNCE
375     }
376     
377         /*
378          *  Setup the Amiga configuration info
379          */
380     
381     void __init config_amiga(void)
382     {
383       int i;
384     
385       amiga_debug_init();
386       amiga_identify();
387     
388       /* Yuk, we don't have PCI memory */
389       iomem_resource.name = "Memory";
390       for (i = 0; i < 4; i++)
391         request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
392     
393       mach_sched_init      = amiga_sched_init;
394       mach_keyb_init       = amiga_keyb_init;
395       mach_kbdrate         = amiga_kbdrate;
396       mach_kbd_translate   = amiga_kbd_translate;
397       SYSRQ_KEY            = 0xff;
398       mach_init_IRQ        = amiga_init_IRQ;
399       mach_default_handler = &amiga_default_handler;
400       mach_request_irq     = amiga_request_irq;
401       mach_free_irq        = amiga_free_irq;
402       enable_irq           = amiga_enable_irq;
403       disable_irq          = amiga_disable_irq;
404       mach_get_model       = amiga_get_model;
405       mach_get_hardware_list = amiga_get_hardware_list;
406       mach_get_irq_list    = amiga_get_irq_list;
407       mach_gettimeoffset   = amiga_gettimeoffset;
408       if (AMIGAHW_PRESENT(A3000_CLK)){
409         mach_gettod  = a3000_gettod;
410         rtc_resource.name = "A3000 RTC";
411         request_resource(&iomem_resource, &rtc_resource);
412       }
413       else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
414         mach_gettod  = a2000_gettod;
415         rtc_resource.name = "A2000 RTC";
416         request_resource(&iomem_resource, &rtc_resource);
417       }
418     
419       mach_max_dma_address = 0xffffffff; /*
420     				      * default MAX_DMA=0xffffffff
421     				      * on all machines. If we don't
422     				      * do so, the SCSI code will not
423     				      * be able to allocate any mem
424     				      * for transfers, unless we are
425     				      * dealing with a Z2 mem only
426     				      * system.                  /Jes
427     				      */
428     
429       mach_hwclk           = amiga_hwclk;
430       mach_set_clock_mmss  = amiga_set_clock_mmss;
431     #ifdef CONFIG_AMIGA_FLOPPY
432       mach_floppy_setup    = amiga_floppy_setup;
433     #endif
434       mach_reset           = amiga_reset;
435     #ifdef CONFIG_DUMMY_CONSOLE
436       conswitchp           = &dummy_con;
437     #endif
438       kd_mksound           = amiga_mksound;
439     #ifdef CONFIG_MAGIC_SYSRQ
440       mach_sysrq_key = 0x5f;	     /* HELP */
441       mach_sysrq_shift_state = 0x03; /* SHIFT+ALTGR */
442       mach_sysrq_shift_mask = 0xff;  /* all modifiers except CapsLock */
443       mach_sysrq_xlate = amiga_sysrq_xlate;
444     #endif
445     #ifdef CONFIG_HEARTBEAT
446       mach_heartbeat = amiga_heartbeat;
447     #endif
448     
449       /* Fill in the clock values (based on the 700 kHz E-Clock) */
450       amiga_masterclock = 40*amiga_eclock;	/* 28 MHz */
451       amiga_colorclock = 5*amiga_eclock;	/* 3.5 MHz */
452     
453       /* clear all DMA bits */
454       custom.dmacon = DMAF_ALL;
455       /* ensure that the DMA master bit is set */
456       custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
457     
458       /* don't use Z2 RAM as system memory on Z3 capable machines */
459       if (AMIGAHW_PRESENT(ZORRO3)) {
460         int i, j;
461         u32 disabled_z2mem = 0;
462         for (i = 0; i < m68k_num_memory; i++)
463           if (m68k_memory[i].addr < 16*1024*1024) {
464     	if (i == 0) {
465     	  /* don't cut off the branch we're sitting on */
466     	  printk("Warning: kernel runs in Zorro II memory\n");
467     	  continue;
468     	}
469     	disabled_z2mem += m68k_memory[i].size;
470     	m68k_num_memory--;
471     	for (j = i; j < m68k_num_memory; j++)
472     	  m68k_memory[j] = m68k_memory[j+1];
473     	i--;
474           }
475         if (disabled_z2mem)
476           printk("%dK of Zorro II memory will not be used as system memory\n",
477     	     disabled_z2mem>>10);
478       }
479     
480       /* request all RAM */
481       for (i = 0; i < m68k_num_memory; i++) {
482         ram_resource[i].name =
483           (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" :
484           (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" :
485           "16-bit Slow RAM";
486         ram_resource[i].start = m68k_memory[i].addr;
487         ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1;
488         request_resource(&iomem_resource, &ram_resource[i]);
489       }
490     
491       /* initialize chipram allocator */
492       amiga_chip_init ();
493     
494       /* debugging using chipram */
495       if (!strcmp( m68k_debug_device, "mem" )){
496     	  if (!AMIGAHW_PRESENT(CHIP_RAM))
497     		  printk("Warning: no chipram present for debugging\n");
498     	  else {
499     		  amiga_savekmsg_init();
500     		  amiga_console_driver.write = amiga_mem_console_write;
501     		  register_console(&amiga_console_driver);
502     	  }
503       }
504     
505       /* our beloved beeper */
506       if (AMIGAHW_PRESENT(AMI_AUDIO))
507     	  amiga_init_sound();
508     
509       /*
510        * if it is an A3000, set the magic bit that forces
511        * a hard rekick
512        */
513       if (AMIGAHW_PRESENT(MAGIC_REKICK))
514     	  *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80;
515     }
516     
517     static unsigned short jiffy_ticks;
518     
519     static void __init amiga_sched_init(void (*timer_routine)(int, void *,
520     							  struct pt_regs *))
521     {
522     	static struct resource sched_res = {
523     	    "timer", 0x00bfd400, 0x00bfd5ff,
524     	};
525     	jiffy_ticks = (amiga_eclock+HZ/2)/HZ;
526     
527     	if (request_resource(&mb_resources._ciab, &sched_res))
528     	    printk("Cannot allocate ciab.ta{lo,hi}\n");
529     	ciab.cra &= 0xC0;   /* turn off timer A, continuous mode, from Eclk */
530     	ciab.talo = jiffy_ticks % 256;
531     	ciab.tahi = jiffy_ticks / 256;
532     
533     	/* install interrupt service routine for CIAB Timer A
534     	 *
535     	 * Please don't change this to use ciaa, as it interferes with the
536     	 * SCSI code. We'll have to take a look at this later
537     	 */
538     	request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL);
539     	/* start timer */
540     	ciab.cra |= 0x11;
541     }
542     
543     #define TICK_SIZE 10000
544     
545     /* This is always executed with interrupts disabled.  */
546     static unsigned long amiga_gettimeoffset (void)
547     {
548     	unsigned short hi, lo, hi2;
549     	unsigned long ticks, offset = 0;
550     
551     	/* read CIA B timer A current value */
552     	hi  = ciab.tahi;
553     	lo  = ciab.talo;
554     	hi2 = ciab.tahi;
555     
556     	if (hi != hi2) {
557     		lo = ciab.talo;
558     		hi = hi2;
559     	}
560     
561     	ticks = hi << 8 | lo;
562     
563     	if (ticks > jiffy_ticks / 2)
564     		/* check for pending interrupt */
565     		if (cia_set_irq(&ciab_base, 0) & CIA_ICR_TA)
566     			offset = 10000;
567     
568     	ticks = jiffy_ticks - ticks;
569     	ticks = (10000 * ticks) / jiffy_ticks;
570     
571     	return ticks + offset;
572     }
573     
574     static void a3000_gettod (int *yearp, int *monp, int *dayp,
575     			  int *hourp, int *minp, int *secp)
576     {
577     	volatile struct tod3000 *tod = TOD_3000;
578     
579     	tod->cntrl1 = TOD3000_CNTRL1_HOLD;
580     
581     	*secp  = tod->second1 * 10 + tod->second2;
582     	*minp  = tod->minute1 * 10 + tod->minute2;
583     	*hourp = tod->hour1   * 10 + tod->hour2;
584     	*dayp  = tod->day1    * 10 + tod->day2;
585     	*monp  = tod->month1  * 10 + tod->month2;
586     	*yearp = tod->year1   * 10 + tod->year2;
587     
588     	tod->cntrl1 = TOD3000_CNTRL1_FREE;
589     }
590     
591     static void a2000_gettod (int *yearp, int *monp, int *dayp,
592     			  int *hourp, int *minp, int *secp)
593     {
594     	volatile struct tod2000 *tod = TOD_2000;
595     
596     	tod->cntrl1 = TOD2000_CNTRL1_HOLD;
597     
598     	while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
599     		;
600     
601     	*secp  = tod->second1     * 10 + tod->second2;
602     	*minp  = tod->minute1     * 10 + tod->minute2;
603     	*hourp = (tod->hour1 & 3) * 10 + tod->hour2;
604     	*dayp  = tod->day1        * 10 + tod->day2;
605     	*monp  = tod->month1      * 10 + tod->month2;
606     	*yearp = tod->year1       * 10 + tod->year2;
607     
608     	if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){
609     		if (!(tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
610     			*hourp = 0;
611     		else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12)
612     			*hourp += 12;
613     	}
614     
615     	tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
616     }
617     
618     static int amiga_hwclk(int op, struct hwclk_time *t)
619     {
620     	if (AMIGAHW_PRESENT(A3000_CLK)) {
621     		volatile struct tod3000 *tod = TOD_3000;
622     
623     		tod->cntrl1 = TOD3000_CNTRL1_HOLD;
624     
625     		if (!op) { /* read */
626     			t->sec  = tod->second1 * 10 + tod->second2;
627     			t->min  = tod->minute1 * 10 + tod->minute2;
628     			t->hour = tod->hour1   * 10 + tod->hour2;
629     			t->day  = tod->day1    * 10 + tod->day2;
630     			t->wday = tod->weekday;
631     			t->mon  = tod->month1  * 10 + tod->month2 - 1;
632     			t->year = tod->year1   * 10 + tod->year2;
633     			if (t->year <= 69)
634     				t->year += 100;
635     		} else {
636     			tod->second1 = t->sec / 10;
637     			tod->second2 = t->sec % 10;
638     			tod->minute1 = t->min / 10;
639     			tod->minute2 = t->min % 10;
640     			tod->hour1   = t->hour / 10;
641     			tod->hour2   = t->hour % 10;
642     			tod->day1    = t->day / 10;
643     			tod->day2    = t->day % 10;
644     			if (t->wday != -1)
645     				tod->weekday = t->wday;
646     			tod->month1  = (t->mon + 1) / 10;
647     			tod->month2  = (t->mon + 1) % 10;
648     			if (t->year >= 100)
649     				t->year -= 100;
650     			tod->year1   = t->year / 10;
651     			tod->year2   = t->year % 10;
652     		}
653     
654     		tod->cntrl1 = TOD3000_CNTRL1_FREE;
655     	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
656     		volatile struct tod2000 *tod = TOD_2000;
657     
658     		tod->cntrl1 = TOD2000_CNTRL1_HOLD;
659     	    
660     		while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
661     			;
662     
663     		if (!op) { /* read */
664     			t->sec  = tod->second1     * 10 + tod->second2;
665     			t->min  = tod->minute1     * 10 + tod->minute2;
666     			t->hour = (tod->hour1 & 3) * 10 + tod->hour2;
667     			t->day  = tod->day1        * 10 + tod->day2;
668     			t->wday = tod->weekday;
669     			t->mon  = tod->month1      * 10 + tod->month2 - 1;
670     			t->year = tod->year1       * 10 + tod->year2;
671     			if (t->year <= 69)
672     				t->year += 100;
673     
674     			if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){
675     				if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
676     					t->hour = 0;
677     				else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
678     					t->hour += 12;
679     			}
680     		} else {
681     			tod->second1 = t->sec / 10;
682     			tod->second2 = t->sec % 10;
683     			tod->minute1 = t->min / 10;
684     			tod->minute2 = t->min % 10;
685     			if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE)
686     				tod->hour1 = t->hour / 10;
687     			else if (t->hour >= 12)
688     				tod->hour1 = TOD2000_HOUR1_PM +
689     					(t->hour - 12) / 10;
690     			else
691     				tod->hour1 = t->hour / 10;
692     			tod->hour2   = t->hour % 10;
693     			tod->day1    = t->day / 10;
694     			tod->day2    = t->day % 10;
695     			if (t->wday != -1)
696     				tod->weekday = t->wday;
697     			tod->month1  = (t->mon + 1) / 10;
698     			tod->month2  = (t->mon + 1) % 10;
699     			if (t->year >= 100)
700     				t->year -= 100;
701     			tod->year1   = t->year / 10;
702     			tod->year2   = t->year % 10;
703     		}
704     
705     		tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
706     	}
707     
708     	return 0;
709     }
710     
711     static int amiga_set_clock_mmss (unsigned long nowtime)
712     {
713     	short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
714     
715     	if (AMIGAHW_PRESENT(A3000_CLK)) {
716     		volatile struct tod3000 *tod = TOD_3000;
717     
718     		tod->cntrl1 = TOD3000_CNTRL1_HOLD;
719     
720     		tod->second1 = real_seconds / 10;
721     		tod->second2 = real_seconds % 10;
722     		tod->minute1 = real_minutes / 10;
723     		tod->minute2 = real_minutes % 10;
724     		
725     		tod->cntrl1 = TOD3000_CNTRL1_FREE;
726     	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
727     		volatile struct tod2000 *tod = TOD_2000;
728     
729     		tod->cntrl1 = TOD2000_CNTRL1_HOLD;
730     	    
731     		while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
732     			;
733     
734     		tod->second1 = real_seconds / 10;
735     		tod->second2 = real_seconds % 10;
736     		tod->minute1 = real_minutes / 10;
737     		tod->minute2 = real_minutes % 10;
738     
739     		tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
740     	}
741     
742     	return 0;
743     }
744     
745     static int amiga_wait_key (struct console *co)
746     {
747         int i;
748     
749         while (1) {
750     	while (ciaa.pra & 0x40);
751     
752     	/* debounce */
753     	for (i = 0; i < 1000; i++);
754     
755     	if (!(ciaa.pra & 0x40))
756     	    break;
757         }
758     
759         /* wait for button up */
760         while (1) {
761     	while (!(ciaa.pra & 0x40));
762     
763     	/* debounce */
764     	for (i = 0; i < 1000; i++);
765     
766     	if (ciaa.pra & 0x40)
767     	    break;
768         }
769         return 0;
770     }
771     
772     static NORET_TYPE void amiga_reset( void )
773         ATTRIB_NORET;
774     
775     static void amiga_reset (void)
776     {
777       unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);
778       unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label);
779     
780       cli();
781       if (CPU_IS_040_OR_060)
782         /* Setup transparent translation registers for mapping
783          * of 16 MB kernel segment before disabling translation
784          */
785         __asm__ __volatile__
786           ("movel    %0,%/d0\n\t"
787            "andl     #0xff000000,%/d0\n\t"
788            "orw      #0xe020,%/d0\n\t"   /* map 16 MB, enable, cacheable */
789            ".chip    68040\n\t"
790            "movec    %%d0,%%itt0\n\t"
791            "movec    %%d0,%%dtt0\n\t"
792            ".chip    68k\n\t"
793            "jmp      %0@\n\t"
794            : /* no outputs */
795            : "a" (jmp_addr040));
796       else
797         /* for 680[23]0, just disable translation and jump to the physical
798          * address of the label
799          */
800         __asm__ __volatile__
801           ("pmove  %/tc,%@\n\t"
802            "bclr   #7,%@\n\t"
803            "pmove  %@,%/tc\n\t"
804            "jmp    %0@\n\t"
805            : /* no outputs */
806            : "a" (jmp_addr));
807      jmp_addr_label040:
808       /* disable translation on '040 now */
809       __asm__ __volatile__    
810         ("moveq #0,%/d0\n\t"
811          ".chip 68040\n\t"
812          "movec %%d0,%%tc\n\t"	/* disable MMU */
813          ".chip 68k\n\t"
814          : /* no outputs */
815          : /* no inputs */
816          : "d0");
817     
818      jmp_addr_label:
819       /* pickup reset address from AmigaOS ROM, reset devices and jump
820        * to reset address
821        */
822       __asm__ __volatile__
823         ("movew #0x2700,%/sr\n\t"
824          "leal  0x01000000,%/a0\n\t"
825          "subl  %/a0@(-0x14),%/a0\n\t"
826          "movel %/a0@(4),%/a0\n\t"
827          "subql #2,%/a0\n\t"
828          "bra   1f\n\t"
829          /* align on a longword boundary */
830          __ALIGN_STR "\n"
831          "1:\n\t"
832          "reset\n\t"
833          "jmp   %/a0@" : /* Just that gcc scans it for % escapes */ );
834       
835       for (;;);
836     
837     }
838     
839     
840         /*
841          *  Debugging
842          */
843     
844     #define SAVEKMSG_MAXMEM		128*1024
845     
846     #define SAVEKMSG_MAGIC1		0x53415645	/* 'SAVE' */
847     #define SAVEKMSG_MAGIC2		0x4B4D5347	/* 'KMSG' */
848     
849     struct savekmsg {
850         unsigned long magic1;		/* SAVEKMSG_MAGIC1 */
851         unsigned long magic2;		/* SAVEKMSG_MAGIC2 */
852         unsigned long magicptr;		/* address of magic1 */
853         unsigned long size;
854         char data[0];
855     };
856     
857     static struct savekmsg *savekmsg = NULL;
858     
859     static void amiga_mem_console_write(struct console *co, const char *s,
860     				    unsigned int count)
861     {
862         if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) {
863             memcpy(savekmsg->data+savekmsg->size, s, count);
864             savekmsg->size += count;
865         }
866     }
867     
868     static void amiga_savekmsg_init(void)
869     {
870         static struct resource debug_res = { "Debug" };
871     
872         savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res);
873         savekmsg->magic1 = SAVEKMSG_MAGIC1;
874         savekmsg->magic2 = SAVEKMSG_MAGIC2;
875         savekmsg->magicptr = virt_to_phys(savekmsg);
876         savekmsg->size = 0;
877     }
878     
879     static void amiga_serial_putc(char c)
880     {
881         custom.serdat = (unsigned char)c | 0x100;
882         while (!(custom.serdatr & 0x2000))
883     	;
884     }
885     
886     void amiga_serial_console_write(struct console *co, const char *s,
887     				       unsigned int count)
888     {
889         while (count--) {
890     	if (*s == '\n')
891     	    amiga_serial_putc('\r');
892     	amiga_serial_putc(*s++);
893         }
894     }
895     
896     #ifdef CONFIG_SERIAL_CONSOLE
897     void amiga_serial_puts(const char *s)
898     {
899         amiga_serial_console_write(NULL, s, strlen(s));
900     }
901     
902     int amiga_serial_console_wait_key(struct console *co)
903     {
904         int ch;
905     
906         while (!(custom.intreqr & IF_RBF))
907     	barrier();
908         ch = custom.serdatr & 0xff;
909         /* clear the interrupt, so that another character can be read */
910         custom.intreq = IF_RBF;
911         return ch;
912     }
913     
914     void amiga_serial_gets(struct console *co, char *s, int len)
915     {
916         int ch, cnt = 0;
917     
918         while (1) {
919     	ch = amiga_serial_console_wait_key(co);
920     
921     	/* Check for backspace. */
922     	if (ch == 8 || ch == 127) {
923     	    if (cnt == 0) {
924     		amiga_serial_putc('\007');
925     		continue;
926     	    }
927     	    cnt--;
928     	    amiga_serial_puts("\010 \010");
929     	    continue;
930     	}
931     
932     	/* Check for enter. */
933     	if (ch == 10 || ch == 13)
934     	    break;
935     
936     	/* See if line is too long. */
937     	if (cnt >= len + 1) {
938     	    amiga_serial_putc(7);
939     	    cnt--;
940     	    continue;
941     	}
942     
943     	/* Store and echo character. */
944     	s[cnt++] = ch;
945     	amiga_serial_putc(ch);
946         }
947         /* Print enter. */
948         amiga_serial_puts("\r\n");
949         s[cnt] = 0;
950     }
951     #endif
952     
953     static void __init amiga_debug_init(void)
954     {
955     	if (!strcmp( m68k_debug_device, "ser" )) {
956     		/* no initialization required (?) */
957     		amiga_console_driver.write = amiga_serial_console_write;
958     		register_console(&amiga_console_driver);
959     	}
960     }
961     
962     #ifdef CONFIG_HEARTBEAT
963     static void amiga_heartbeat(int on)
964     {
965         if (on)
966     	ciaa.pra &= ~2;
967         else
968     	ciaa.pra |= 2;
969     }
970     #endif
971     
972         /*
973          *  Amiga specific parts of /proc
974          */
975     
976     static void amiga_get_model(char *model)
977     {
978         strcpy(model, amiga_model_name);
979     }
980     
981     
982     static int amiga_get_hardware_list(char *buffer)
983     {
984         int len = 0;
985     
986         if (AMIGAHW_PRESENT(CHIP_RAM))
987     	len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10);
988         len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",
989     		   amiga_psfreq, amiga_eclock);
990         if (AMIGAHW_PRESENT(AMI_VIDEO)) {
991     	char *type;
992     	switch(amiga_chipset) {
993     	    case CS_OCS:
994     		type = "OCS";
995     		break;
996     	    case CS_ECS:
997     		type = "ECS";
998     		break;
999     	    case CS_AGA:
1000     		type = "AGA";
1001     		break;
1002     	    default:
1003     		type = "Old or Unknown";
1004     		break;
1005     	}
1006     	len += sprintf(buffer+len, "Graphics:\t%s\n", type);
1007         }
1008     
1009     #define AMIGAHW_ANNOUNCE(name, str)			\
1010         if (AMIGAHW_PRESENT(name))				\
1011     	len += sprintf (buffer+len, "\t%s\n", str)
1012     
1013         len += sprintf (buffer + len, "Detected hardware:\n");
1014     
1015         AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video");
1016         AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter");
1017         AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer");
1018         AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio");
1019         AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller");
1020         AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)");
1021         AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)");
1022         AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)");
1023         AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)");
1024         AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive");
1025         AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard");
1026         AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port");
1027         AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port");
1028         AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port");
1029         AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)");
1030         AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)");
1031         AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM");
1032         AMIGAHW_ANNOUNCE(PAULA, "Paula 8364");
1033         AMIGAHW_ANNOUNCE(DENISE, "Denise 8362");
1034         AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373");
1035         AMIGAHW_ANNOUNCE(LISA, "Lisa 8375");
1036         AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371");
1037         AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370");
1038         AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372");
1039         AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372");
1040         AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374");
1041         AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374");
1042         AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
1043         AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");
1044     #ifdef CONFIG_ZORRO
1045         if (AMIGAHW_PRESENT(ZORRO))
1046     	len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion "
1047     				   "Device%s\n",
1048     		       AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
1049     		       zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
1050     #endif /* CONFIG_ZORRO */
1051     
1052     #undef AMIGAHW_ANNOUNCE
1053     
1054         return(len);
1055     }
1056