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/rtc.h> 22#include <linux/init.h> 23#include <linux/vt_kern.h> 24#ifdef CONFIG_ZORRO 25#include <linux/zorro.h> 26#endif 27 28#include <asm/bootinfo.h> 29#include <asm/setup.h> 30#include <asm/system.h> 31#include <asm/pgtable.h> 32#include <asm/amigahw.h> 33#include <asm/amigaints.h> 34#include <asm/irq.h> 35#include <asm/rtc.h> 36#include <asm/keyboard.h> 37#include <asm/machdep.h> 38#include <asm/io.h> 39 40unsigned long amiga_model; 41unsigned long amiga_eclock; 42unsigned long amiga_masterclock; 43unsigned long amiga_colorclock; 44unsigned long amiga_chipset; 45unsigned char amiga_vblank; 46unsigned char amiga_psfreq; 47struct amiga_hw_present amiga_hw_present; 48 49static char s_a500[] __initdata = "A500"; 50static char s_a500p[] __initdata = "A500+"; 51static char s_a600[] __initdata = "A600"; 52static char s_a1000[] __initdata = "A1000"; 53static char s_a1200[] __initdata = "A1200"; 54static char s_a2000[] __initdata = "A2000"; 55static char s_a2500[] __initdata = "A2500"; 56static char s_a3000[] __initdata = "A3000"; 57static char s_a3000t[] __initdata = "A3000T"; 58static char s_a3000p[] __initdata = "A3000+"; 59static char s_a4000[] __initdata = "A4000"; 60static char s_a4000t[] __initdata = "A4000T"; 61static char s_cdtv[] __initdata = "CDTV"; 62static char s_cd32[] __initdata = "CD32"; 63static char s_draco[] __initdata = "Draco"; 64static char *amiga_models[] __initdata = { 65 s_a500, s_a500p, s_a600, s_a1000, s_a1200, s_a2000, s_a2500, s_a3000, 66 s_a3000t, s_a3000p, s_a4000, s_a4000t, s_cdtv, s_cd32, s_draco, 67}; 68 69static char amiga_model_name[13] = "Amiga "; 70 71extern char m68k_debug_device[]; 72 73static void amiga_sched_init(void (*handler)(int, void *, struct pt_regs *)); 74/* amiga specific keyboard functions */ 75extern int amiga_keyb_init(void); 76extern int amiga_kbdrate (struct kbd_repeat *); 77extern int amiga_kbd_translate(unsigned char keycode, unsigned char *keycodep, 78 char raw_mode); 79/* amiga specific irq functions */ 80extern void amiga_init_IRQ (void); 81extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *); 82extern int amiga_request_irq (unsigned int irq, 83 void (*handler)(int, void *, struct pt_regs *), 84 unsigned long flags, const char *devname, 85 void *dev_id); 86extern void amiga_free_irq (unsigned int irq, void *dev_id); 87extern void amiga_enable_irq (unsigned int); 88extern void amiga_disable_irq (unsigned int); 89static void amiga_get_model(char *model); 90static int amiga_get_hardware_list(char *buffer); 91extern int amiga_get_irq_list (char *); 92/* amiga specific timer functions */ 93static unsigned long amiga_gettimeoffset (void); 94static void a3000_gettod (int *, int *, int *, int *, int *, int *); 95static void a2000_gettod (int *, int *, int *, int *, int *, int *); 96static int amiga_hwclk (int, struct rtc_time *); 97static int amiga_set_clock_mmss (unsigned long); 98extern void amiga_mksound( unsigned int count, unsigned int ticks ); 99#ifdef CONFIG_AMIGA_FLOPPY 100extern void amiga_floppy_setup(char *, int *); 101#endif 102static void amiga_reset (void); 103extern void amiga_init_sound(void); 104static void amiga_savekmsg_init(void); 105static void amiga_mem_console_write(struct console *co, const char *b, 106 unsigned int count); 107void amiga_serial_console_write(struct console *co, const char *s, 108 unsigned int count); 109static void amiga_debug_init(void); 110#ifdef CONFIG_HEARTBEAT 111static void amiga_heartbeat(int on); 112#endif 113 114static struct console amiga_console_driver = { 115 name: "debug", 116 flags: CON_PRINTBUFFER, 117 index: -1, 118}; 119 120#ifdef CONFIG_MAGIC_SYSRQ 121static 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 133 /* 134 * Motherboard Resources present in all Amiga models 135 */ 136 137static struct { 138 struct resource _ciab, _ciaa, _custom, _kickstart; 139} mb_resources = { 140 _ciab: { "CIA B", 0x00bfd000, 0x00bfdfff }, 141 _ciaa: { "CIA A", 0x00bfe000, 0x00bfefff }, 142 _custom: { "Custom I/O", 0x00dff000, 0x00dfffff }, 143 _kickstart: { "Kickstart ROM", 0x00f80000, 0x00ffffff } 144}; 145 146static struct resource rtc_resource = { 147 NULL, 0x00dc0000, 0x00dcffff 148}; 149 150static struct resource ram_resource[NUM_MEMINFO]; 151 152 153 /* 154 * Parse an Amiga-specific record in the bootinfo 155 */ 156 157int amiga_parse_bootinfo(const struct bi_record *record) 158{ 159 int unknown = 0; 160 const unsigned long *data = record->data; 161 162 switch (record->tag) { 163 case BI_AMIGA_MODEL: 164 amiga_model = *data; 165 break; 166 167 case BI_AMIGA_ECLOCK: 168 amiga_eclock = *data; 169 break; 170 171 case BI_AMIGA_CHIPSET: 172 amiga_chipset = *data; 173 break; 174 175 case BI_AMIGA_CHIP_SIZE: 176 amiga_chip_size = *(const int *)data; 177 break; 178 179 case BI_AMIGA_VBLANK: 180 amiga_vblank = *(const unsigned char *)data; 181 break; 182 183 case BI_AMIGA_PSFREQ: 184 amiga_psfreq = *(const unsigned char *)data; 185 break; 186 187 case BI_AMIGA_AUTOCON: 188#ifdef CONFIG_ZORRO 189 if (zorro_num_autocon < ZORRO_NUM_AUTO) { 190 const struct ConfigDev *cd = (struct ConfigDev *)data; 191 struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; 192 dev->rom = cd->cd_Rom; 193 dev->slotaddr = cd->cd_SlotAddr; 194 dev->slotsize = cd->cd_SlotSize; 195 dev->resource.start = (unsigned long)cd->cd_BoardAddr; 196 dev->resource.end = dev->resource.start+cd->cd_BoardSize-1; 197 } else 198 printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); 199#endif /* CONFIG_ZORRO */ 200 break; 201 202 case BI_AMIGA_SERPER: 203 /* serial port period: ignored here */ 204 break; 205 206 default: 207 unknown = 1; 208 } 209 return(unknown); 210} 211 212 /* 213 * Identify builtin hardware 214 */ 215 216static void __init amiga_identify(void) 217{ 218 /* Fill in some default values, if necessary */ 219 if (amiga_eclock == 0) 220 amiga_eclock = 709379; 221 222 memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); 223 224 printk("Amiga hardware found: "); 225 if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { 226 printk("[%s] ", amiga_models[amiga_model-AMI_500]); 227 strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); 228 } 229 230 switch(amiga_model) { 231 case AMI_UNKNOWN: 232 goto Generic; 233 234 case AMI_600: 235 case AMI_1200: 236 AMIGAHW_SET(A1200_IDE); 237 AMIGAHW_SET(PCMCIA); 238 case AMI_500: 239 case AMI_500PLUS: 240 case AMI_1000: 241 case AMI_2000: 242 case AMI_2500: 243 AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ 244 goto Generic; 245 246 case AMI_3000: 247 case AMI_3000T: 248 AMIGAHW_SET(AMBER_FF); 249 AMIGAHW_SET(MAGIC_REKICK); 250 /* fall through */ 251 case AMI_3000PLUS: 252 AMIGAHW_SET(A3000_SCSI); 253 AMIGAHW_SET(A3000_CLK); 254 AMIGAHW_SET(ZORRO3); 255 goto Generic; 256 257 case AMI_4000T: 258 AMIGAHW_SET(A4000_SCSI); 259 /* fall through */ 260 case AMI_4000: 261 AMIGAHW_SET(A4000_IDE); 262 AMIGAHW_SET(A3000_CLK); 263 AMIGAHW_SET(ZORRO3); 264 goto Generic; 265 266 case AMI_CDTV: 267 case AMI_CD32: 268 AMIGAHW_SET(CD_ROM); 269 AMIGAHW_SET(A2000_CLK); /* Is this correct? */ 270 goto Generic; 271 272 Generic: 273 AMIGAHW_SET(AMI_VIDEO); 274 AMIGAHW_SET(AMI_BLITTER); 275 AMIGAHW_SET(AMI_AUDIO); 276 AMIGAHW_SET(AMI_FLOPPY); 277 AMIGAHW_SET(AMI_KEYBOARD); 278 AMIGAHW_SET(AMI_MOUSE); 279 AMIGAHW_SET(AMI_SERIAL); 280 AMIGAHW_SET(AMI_PARALLEL); 281 AMIGAHW_SET(CHIP_RAM); 282 AMIGAHW_SET(PAULA); 283 284 switch(amiga_chipset) { 285 case CS_OCS: 286 case CS_ECS: 287 case CS_AGA: 288 switch (custom.deniseid & 0xf) { 289 case 0x0c: 290 AMIGAHW_SET(DENISE_HR); 291 break; 292 case 0x08: 293 AMIGAHW_SET(LISA); 294 break; 295 } 296 break; 297 default: 298 AMIGAHW_SET(DENISE); 299 break; 300 } 301 switch ((custom.vposr>>8) & 0x7f) { 302 case 0x00: 303 AMIGAHW_SET(AGNUS_PAL); 304 break; 305 case 0x10: 306 AMIGAHW_SET(AGNUS_NTSC); 307 break; 308 case 0x20: 309 case 0x21: 310 AMIGAHW_SET(AGNUS_HR_PAL); 311 break; 312 case 0x30: 313 case 0x31: 314 AMIGAHW_SET(AGNUS_HR_NTSC); 315 break; 316 case 0x22: 317 case 0x23: 318 AMIGAHW_SET(ALICE_PAL); 319 break; 320 case 0x32: 321 case 0x33: 322 AMIGAHW_SET(ALICE_NTSC); 323 break; 324 } 325 AMIGAHW_SET(ZORRO); 326 break; 327 328 case AMI_DRACO: 329 panic("No support for Draco yet"); 330 331 default: 332 panic("Unknown Amiga Model"); 333 } 334 335#define AMIGAHW_ANNOUNCE(name, str) \ 336 if (AMIGAHW_PRESENT(name)) \ 337 printk(str) 338 339 AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); 340 AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); 341 AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF "); 342 AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO "); 343 AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY "); 344 AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI "); 345 AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI "); 346 AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE "); 347 AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE "); 348 AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM "); 349 AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD "); 350 AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE "); 351 AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL "); 352 AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL "); 353 AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK "); 354 AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK "); 355 AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM "); 356 AMIGAHW_ANNOUNCE(PAULA, "PAULA "); 357 AMIGAHW_ANNOUNCE(DENISE, "DENISE "); 358 AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR "); 359 AMIGAHW_ANNOUNCE(LISA, "LISA "); 360 AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL "); 361 AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC "); 362 AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL "); 363 AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC "); 364 AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL "); 365 AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC "); 366 AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); 367 AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); 368 if (AMIGAHW_PRESENT(ZORRO)) 369 printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); 370 printk("\n"); 371 372#undef AMIGAHW_ANNOUNCE 373} 374 375 /* 376 * Setup the Amiga configuration info 377 */ 378 379void __init config_amiga(void) 380{ 381 int i; 382 383 amiga_debug_init(); 384 amiga_identify(); 385 386 /* Yuk, we don't have PCI memory */ 387 iomem_resource.name = "Memory"; 388 for (i = 0; i < 4; i++) 389 request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); 390 391 mach_sched_init = amiga_sched_init; 392#ifdef CONFIG_VT 393 mach_keyb_init = amiga_keyb_init; 394 mach_kbdrate = amiga_kbdrate; 395 mach_kbd_translate = amiga_kbd_translate; 396 kd_mksound = amiga_mksound; 397#endif 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#ifdef CONFIG_MAGIC_SYSRQ 439 SYSRQ_KEY = 0xff; 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 517static unsigned short jiffy_ticks; 518 519static 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. */ 546static 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 574static 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 591static 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 618static int amiga_hwclk(int op, struct rtc_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->tm_sec = tod->second1 * 10 + tod->second2; 627 t->tm_min = tod->minute1 * 10 + tod->minute2; 628 t->tm_hour = tod->hour1 * 10 + tod->hour2; 629 t->tm_mday = tod->day1 * 10 + tod->day2; 630 t->tm_wday = tod->weekday; 631 t->tm_mon = tod->month1 * 10 + tod->month2 - 1; 632 t->tm_year = tod->year1 * 10 + tod->year2; 633 if (t->tm_year <= 69) 634 t->tm_year += 100; 635 } else { 636 tod->second1 = t->tm_sec / 10; 637 tod->second2 = t->tm_sec % 10; 638 tod->minute1 = t->tm_min / 10; 639 tod->minute2 = t->tm_min % 10; 640 tod->hour1 = t->tm_hour / 10; 641 tod->hour2 = t->tm_hour % 10; 642 tod->day1 = t->tm_mday / 10; 643 tod->day2 = t->tm_mday % 10; 644 if (t->tm_wday != -1) 645 tod->weekday = t->tm_wday; 646 tod->month1 = (t->tm_mon + 1) / 10; 647 tod->month2 = (t->tm_mon + 1) % 10; 648 if (t->tm_year >= 100) 649 t->tm_year -= 100; 650 tod->year1 = t->tm_year / 10; 651 tod->year2 = t->tm_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->tm_sec = tod->second1 * 10 + tod->second2; 665 t->tm_min = tod->minute1 * 10 + tod->minute2; 666 t->tm_hour = (tod->hour1 & 3) * 10 + tod->hour2; 667 t->tm_mday = tod->day1 * 10 + tod->day2; 668 t->tm_wday = tod->weekday; 669 t->tm_mon = tod->month1 * 10 + tod->month2 - 1; 670 t->tm_year = tod->year1 * 10 + tod->year2; 671 if (t->tm_year <= 69) 672 t->tm_year += 100; 673 674 if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){ 675 if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12) 676 t->tm_hour = 0; 677 else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12) 678 t->tm_hour += 12; 679 } 680 } else { 681 tod->second1 = t->tm_sec / 10; 682 tod->second2 = t->tm_sec % 10; 683 tod->minute1 = t->tm_min / 10; 684 tod->minute2 = t->tm_min % 10; 685 if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE) 686 tod->hour1 = t->tm_hour / 10; 687 else if (t->tm_hour >= 12) 688 tod->hour1 = TOD2000_HOUR1_PM + 689 (t->tm_hour - 12) / 10; 690 else 691 tod->hour1 = t->tm_hour / 10; 692 tod->hour2 = t->tm_hour % 10; 693 tod->day1 = t->tm_mday / 10; 694 tod->day2 = t->tm_mday % 10; 695 if (t->tm_wday != -1) 696 tod->weekday = t->tm_wday; 697 tod->month1 = (t->tm_mon + 1) / 10; 698 tod->month2 = (t->tm_mon + 1) % 10; 699 if (t->tm_year >= 100) 700 t->tm_year -= 100; 701 tod->year1 = t->tm_year / 10; 702 tod->year2 = t->tm_year % 10; 703 } 704 705 tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD; 706 } 707 708 return 0; 709} 710 711static 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 745static NORET_TYPE void amiga_reset( void ) 746 ATTRIB_NORET; 747 748static void amiga_reset (void) 749{ 750 unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); 751 unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label); 752 753 cli(); 754 if (CPU_IS_040_OR_060) 755 /* Setup transparent translation registers for mapping 756 * of 16 MB kernel segment before disabling translation 757 */ 758 __asm__ __volatile__ 759 ("movel %0,%/d0\n\t" 760 "andl #0xff000000,%/d0\n\t" 761 "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */ 762 ".chip 68040\n\t" 763 "movec %%d0,%%itt0\n\t" 764 "movec %%d0,%%dtt0\n\t" 765 ".chip 68k\n\t" 766 "jmp %0@\n\t" 767 : /* no outputs */ 768 : "a" (jmp_addr040)); 769 else 770 /* for 680[23]0, just disable translation and jump to the physical 771 * address of the label 772 */ 773 __asm__ __volatile__ 774 ("pmove %/tc,%@\n\t" 775 "bclr #7,%@\n\t" 776 "pmove %@,%/tc\n\t" 777 "jmp %0@\n\t" 778 : /* no outputs */ 779 : "a" (jmp_addr)); 780 jmp_addr_label040: 781 /* disable translation on '040 now */ 782 __asm__ __volatile__ 783 ("moveq #0,%/d0\n\t" 784 ".chip 68040\n\t" 785 "movec %%d0,%%tc\n\t" /* disable MMU */ 786 ".chip 68k\n\t" 787 : /* no outputs */ 788 : /* no inputs */ 789 : "d0"); 790 791 jmp_addr_label: 792 /* pickup reset address from AmigaOS ROM, reset devices and jump 793 * to reset address 794 */ 795 __asm__ __volatile__ 796 ("movew #0x2700,%/sr\n\t" 797 "leal 0x01000000,%/a0\n\t" 798 "subl %/a0@(-0x14),%/a0\n\t" 799 "movel %/a0@(4),%/a0\n\t" 800 "subql #2,%/a0\n\t" 801 "bra 1f\n\t" 802 /* align on a longword boundary */ 803 __ALIGN_STR "\n" 804 "1:\n\t" 805 "reset\n\t" 806 "jmp %/a0@" : /* Just that gcc scans it for % escapes */ ); 807 808 for (;;); 809 810} 811 812 813 /* 814 * Debugging 815 */ 816 817#define SAVEKMSG_MAXMEM 128*1024 818 819#define SAVEKMSG_MAGIC1 0x53415645 /* 'SAVE' */ 820#define SAVEKMSG_MAGIC2 0x4B4D5347 /* 'KMSG' */ 821 822struct savekmsg { 823 unsigned long magic1; /* SAVEKMSG_MAGIC1 */ 824 unsigned long magic2; /* SAVEKMSG_MAGIC2 */ 825 unsigned long magicptr; /* address of magic1 */ 826 unsigned long size; 827 char data[0]; 828}; 829 830static struct savekmsg *savekmsg = NULL; 831 832static void amiga_mem_console_write(struct console *co, const char *s, 833 unsigned int count) 834{ 835 if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { 836 memcpy(savekmsg->data+savekmsg->size, s, count); 837 savekmsg->size += count; 838 } 839} 840 841static void amiga_savekmsg_init(void) 842{ 843 static struct resource debug_res = { "Debug" }; 844 845 savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); 846 savekmsg->magic1 = SAVEKMSG_MAGIC1; 847 savekmsg->magic2 = SAVEKMSG_MAGIC2; 848 savekmsg->magicptr = virt_to_phys(savekmsg); 849 savekmsg->size = 0; 850} 851 852static void amiga_serial_putc(char c) 853{ 854 custom.serdat = (unsigned char)c | 0x100; 855 while (!(custom.serdatr & 0x2000)) 856 ; 857} 858 859void amiga_serial_console_write(struct console *co, const char *s, 860 unsigned int count) 861{ 862 while (count--) { 863 if (*s == '\n') 864 amiga_serial_putc('\r'); 865 amiga_serial_putc(*s++); 866 } 867} 868 869#ifdef CONFIG_SERIAL_CONSOLE 870void amiga_serial_puts(const char *s) 871{ 872 amiga_serial_console_write(NULL, s, strlen(s)); 873} 874 875int amiga_serial_console_wait_key(struct console *co) 876{ 877 int ch; 878 879 while (!(custom.intreqr & IF_RBF)) 880 barrier(); 881 ch = custom.serdatr & 0xff; 882 /* clear the interrupt, so that another character can be read */ 883 custom.intreq = IF_RBF; 884 return ch; 885} 886 887void amiga_serial_gets(struct console *co, char *s, int len) 888{ 889 int ch, cnt = 0; 890 891 while (1) { 892 ch = amiga_serial_console_wait_key(co); 893 894 /* Check for backspace. */ 895 if (ch == 8 || ch == 127) { 896 if (cnt == 0) { 897 amiga_serial_putc('\007'); 898 continue; 899 } 900 cnt--; 901 amiga_serial_puts("\010 \010"); 902 continue; 903 } 904 905 /* Check for enter. */ 906 if (ch == 10 || ch == 13) 907 break; 908 909 /* See if line is too long. */ 910 if (cnt >= len + 1) { 911 amiga_serial_putc(7); 912 cnt--; 913 continue; 914 } 915 916 /* Store and echo character. */ 917 s[cnt++] = ch; 918 amiga_serial_putc(ch); 919 } 920 /* Print enter. */ 921 amiga_serial_puts("\r\n"); 922 s[cnt] = 0; 923} 924#endif 925 926static void __init amiga_debug_init(void) 927{ 928 if (!strcmp( m68k_debug_device, "ser" )) { 929 /* no initialization required (?) */ 930 amiga_console_driver.write = amiga_serial_console_write; 931 register_console(&amiga_console_driver); 932 } 933} 934 935#ifdef CONFIG_HEARTBEAT 936static void amiga_heartbeat(int on) 937{ 938 if (on) 939 ciaa.pra &= ~2; 940 else 941 ciaa.pra |= 2; 942} 943#endif 944 945 /* 946 * Amiga specific parts of /proc 947 */ 948 949static void amiga_get_model(char *model) 950{ 951 strcpy(model, amiga_model_name); 952} 953 954 955static int amiga_get_hardware_list(char *buffer) 956{ 957 int len = 0; 958 959 if (AMIGAHW_PRESENT(CHIP_RAM)) 960 len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10); 961 len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n", 962 amiga_psfreq, amiga_eclock); 963 if (AMIGAHW_PRESENT(AMI_VIDEO)) { 964 char *type; 965 switch(amiga_chipset) { 966 case CS_OCS: 967 type = "OCS"; 968 break; 969 case CS_ECS: 970 type = "ECS"; 971 break; 972 case CS_AGA: 973 type = "AGA"; 974 break; 975 default: 976 type = "Old or Unknown"; 977 break; 978 } 979 len += sprintf(buffer+len, "Graphics:\t%s\n", type); 980 } 981 982#define AMIGAHW_ANNOUNCE(name, str) \ 983 if (AMIGAHW_PRESENT(name)) \ 984 len += sprintf (buffer+len, "\t%s\n", str) 985 986 len += sprintf (buffer + len, "Detected hardware:\n"); 987 988 AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video"); 989 AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter"); 990 AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer"); 991 AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio"); 992 AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller"); 993 AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)"); 994 AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)"); 995 AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)"); 996 AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)"); 997 AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive"); 998 AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard"); 999 AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port"); 1000 AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port"); 1001 AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port"); 1002 AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)"); 1003 AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)"); 1004 AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM"); 1005 AMIGAHW_ANNOUNCE(PAULA, "Paula 8364"); 1006 AMIGAHW_ANNOUNCE(DENISE, "Denise 8362"); 1007 AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373"); 1008 AMIGAHW_ANNOUNCE(LISA, "Lisa 8375"); 1009 AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371"); 1010 AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370"); 1011 AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372"); 1012 AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372"); 1013 AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374"); 1014 AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); 1015 AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); 1016 AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); 1017#ifdef CONFIG_ZORRO 1018 if (AMIGAHW_PRESENT(ZORRO)) 1019 len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " 1020 "Device%s\n", 1021 AMIGAHW_PRESENT(ZORRO3) ? "I" : "", 1022 zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); 1023#endif /* CONFIG_ZORRO */ 1024 1025#undef AMIGAHW_ANNOUNCE 1026 1027 return(len); 1028} 1029