1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Miscellaneous Mac68K-specific stuff 4 */ 5 6 #include <linux/types.h> 7 #include <linux/errno.h> 8 #include <linux/kernel.h> 9 #include <linux/delay.h> 10 #include <linux/sched.h> 11 #include <linux/time.h> 12 #include <linux/rtc.h> 13 #include <linux/mm.h> 14 15 #include <linux/adb.h> 16 #include <linux/cuda.h> 17 #include <linux/pmu.h> 18 19 #include <linux/uaccess.h> 20 #include <asm/io.h> 21 #include <asm/segment.h> 22 #include <asm/setup.h> 23 #include <asm/macintosh.h> 24 #include <asm/mac_via.h> 25 #include <asm/mac_oss.h> 26 27 #include <asm/machdep.h> 28 29 /* Offset between Unix time (1970-based) and Mac time (1904-based) */ 30 31 #define RTC_OFFSET 2082844800 32 33 static void (*rom_reset)(void); 34 35 #ifdef CONFIG_ADB_CUDA 36 static long cuda_read_time(void) 37 { 38 struct adb_request req; 39 long time; 40 41 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) 42 return 0; 43 while (!req.complete) 44 cuda_poll(); 45 46 time = (req.reply[3] << 24) | (req.reply[4] << 16) | 47 (req.reply[5] << 8) | req.reply[6]; 48 return time - RTC_OFFSET; 49 } 50 51 static void cuda_write_time(long data) 52 { 53 struct adb_request req; 54 55 data += RTC_OFFSET; 56 if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, 57 (data >> 24) & 0xFF, (data >> 16) & 0xFF, 58 (data >> 8) & 0xFF, data & 0xFF) < 0) 59 return; 60 while (!req.complete) 61 cuda_poll(); 62 } 63 64 static __u8 cuda_read_pram(int offset) 65 { 66 struct adb_request req; 67 68 if (cuda_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM, 69 (offset >> 8) & 0xFF, offset & 0xFF) < 0) 70 return 0; 71 while (!req.complete) 72 cuda_poll(); 73 return req.reply[3]; 74 } 75 76 static void cuda_write_pram(int offset, __u8 data) 77 { 78 struct adb_request req; 79 80 if (cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM, 81 (offset >> 8) & 0xFF, offset & 0xFF, data) < 0) 82 return; 83 while (!req.complete) 84 cuda_poll(); 85 } 86 #endif /* CONFIG_ADB_CUDA */ 87 88 #ifdef CONFIG_ADB_PMU 89 static long pmu_read_time(void) 90 { 91 struct adb_request req; 92 long time; 93 94 if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) 95 return 0; 96 while (!req.complete) 97 pmu_poll(); 98 99 time = (req.reply[1] << 24) | (req.reply[2] << 16) | 100 (req.reply[3] << 8) | req.reply[4]; 101 return time - RTC_OFFSET; 102 } 103 104 static void pmu_write_time(long data) 105 { 106 struct adb_request req; 107 108 data += RTC_OFFSET; 109 if (pmu_request(&req, NULL, 5, PMU_SET_RTC, 110 (data >> 24) & 0xFF, (data >> 16) & 0xFF, 111 (data >> 8) & 0xFF, data & 0xFF) < 0) 112 return; 113 while (!req.complete) 114 pmu_poll(); 115 } 116 117 static __u8 pmu_read_pram(int offset) 118 { 119 struct adb_request req; 120 121 if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM, 122 (offset >> 8) & 0xFF, offset & 0xFF) < 0) 123 return 0; 124 while (!req.complete) 125 pmu_poll(); 126 return req.reply[3]; 127 } 128 129 static void pmu_write_pram(int offset, __u8 data) 130 { 131 struct adb_request req; 132 133 if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM, 134 (offset >> 8) & 0xFF, offset & 0xFF, data) < 0) 135 return; 136 while (!req.complete) 137 pmu_poll(); 138 } 139 #endif /* CONFIG_ADB_PMU */ 140 141 /* 142 * VIA PRAM/RTC access routines 143 * 144 * Must be called with interrupts disabled and 145 * the RTC should be enabled. 146 */ 147 148 static __u8 via_pram_readbyte(void) 149 { 150 int i, reg; 151 __u8 data; 152 153 reg = via1[vBufB] & ~VIA1B_vRTCClk; 154 155 /* Set the RTC data line to be an input. */ 156 157 via1[vDirB] &= ~VIA1B_vRTCData; 158 159 /* The bits of the byte come out in MSB order */ 160 161 data = 0; 162 for (i = 0 ; i < 8 ; i++) { 163 via1[vBufB] = reg; 164 via1[vBufB] = reg | VIA1B_vRTCClk; 165 data = (data << 1) | (via1[vBufB] & VIA1B_vRTCData); 166 } 167 168 /* Return RTC data line to output state */ 169 170 via1[vDirB] |= VIA1B_vRTCData; 171 172 return data; 173 } 174 175 static void via_pram_writebyte(__u8 data) 176 { 177 int i, reg, bit; 178 179 reg = via1[vBufB] & ~(VIA1B_vRTCClk | VIA1B_vRTCData); 180 181 /* The bits of the byte go in in MSB order */ 182 183 for (i = 0 ; i < 8 ; i++) { 184 bit = data & 0x80? 1 : 0; 185 data <<= 1; 186 via1[vBufB] = reg | bit; 187 via1[vBufB] = reg | bit | VIA1B_vRTCClk; 188 } 189 } 190 191 /* 192 * Execute a VIA PRAM/RTC command. For read commands 193 * data should point to a one-byte buffer for the 194 * resulting data. For write commands it should point 195 * to the data byte to for the command. 196 * 197 * This function disables all interrupts while running. 198 */ 199 200 static void via_pram_command(int command, __u8 *data) 201 { 202 unsigned long flags; 203 int is_read; 204 205 local_irq_save(flags); 206 207 /* Enable the RTC and make sure the strobe line is high */ 208 209 via1[vBufB] = (via1[vBufB] | VIA1B_vRTCClk) & ~VIA1B_vRTCEnb; 210 211 if (command & 0xFF00) { /* extended (two-byte) command */ 212 via_pram_writebyte((command & 0xFF00) >> 8); 213 via_pram_writebyte(command & 0xFF); 214 is_read = command & 0x8000; 215 } else { /* one-byte command */ 216 via_pram_writebyte(command); 217 is_read = command & 0x80; 218 } 219 if (is_read) { 220 *data = via_pram_readbyte(); 221 } else { 222 via_pram_writebyte(*data); 223 } 224 225 /* All done, disable the RTC */ 226 227 via1[vBufB] |= VIA1B_vRTCEnb; 228 229 local_irq_restore(flags); 230 } 231 232 static __u8 via_read_pram(int offset) 233 { 234 return 0; 235 } 236 237 static void via_write_pram(int offset, __u8 data) 238 { 239 } 240 241 /* 242 * Return the current time in seconds since January 1, 1904. 243 * 244 * This only works on machines with the VIA-based PRAM/RTC, which 245 * is basically any machine with Mac II-style ADB. 246 */ 247 248 static long via_read_time(void) 249 { 250 union { 251 __u8 cdata[4]; 252 long idata; 253 } result, last_result; 254 int count = 1; 255 256 via_pram_command(0x81, &last_result.cdata[3]); 257 via_pram_command(0x85, &last_result.cdata[2]); 258 via_pram_command(0x89, &last_result.cdata[1]); 259 via_pram_command(0x8D, &last_result.cdata[0]); 260 261 /* 262 * The NetBSD guys say to loop until you get the same reading 263 * twice in a row. 264 */ 265 266 while (1) { 267 via_pram_command(0x81, &result.cdata[3]); 268 via_pram_command(0x85, &result.cdata[2]); 269 via_pram_command(0x89, &result.cdata[1]); 270 via_pram_command(0x8D, &result.cdata[0]); 271 272 if (result.idata == last_result.idata) 273 return result.idata - RTC_OFFSET; 274 275 if (++count > 10) 276 break; 277 278 last_result.idata = result.idata; 279 } 280 281 pr_err("via_read_time: failed to read a stable value; got 0x%08lx then 0x%08lx\n", 282 last_result.idata, result.idata); 283 284 return 0; 285 } 286 287 /* 288 * Set the current time to a number of seconds since January 1, 1904. 289 * 290 * This only works on machines with the VIA-based PRAM/RTC, which 291 * is basically any machine with Mac II-style ADB. 292 */ 293 294 static void via_write_time(long time) 295 { 296 union { 297 __u8 cdata[4]; 298 long idata; 299 } data; 300 __u8 temp; 301 302 /* Clear the write protect bit */ 303 304 temp = 0x55; 305 via_pram_command(0x35, &temp); 306 307 data.idata = time + RTC_OFFSET; 308 via_pram_command(0x01, &data.cdata[3]); 309 via_pram_command(0x05, &data.cdata[2]); 310 via_pram_command(0x09, &data.cdata[1]); 311 via_pram_command(0x0D, &data.cdata[0]); 312 313 /* Set the write protect bit */ 314 315 temp = 0xD5; 316 via_pram_command(0x35, &temp); 317 } 318 319 static void via_shutdown(void) 320 { 321 if (rbv_present) { 322 via2[rBufB] &= ~0x04; 323 } else { 324 /* Direction of vDirB is output */ 325 via2[vDirB] |= 0x04; 326 /* Send a value of 0 on that line */ 327 via2[vBufB] &= ~0x04; 328 mdelay(1000); 329 } 330 } 331 332 static void oss_shutdown(void) 333 { 334 oss->rom_ctrl = OSS_POWEROFF; 335 } 336 337 #ifdef CONFIG_ADB_CUDA 338 static void cuda_restart(void) 339 { 340 struct adb_request req; 341 342 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM) < 0) 343 return; 344 while (!req.complete) 345 cuda_poll(); 346 } 347 348 static void cuda_shutdown(void) 349 { 350 struct adb_request req; 351 352 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN) < 0) 353 return; 354 355 /* Avoid infinite polling loop when PSU is not under Cuda control */ 356 switch (macintosh_config->ident) { 357 case MAC_MODEL_C660: 358 case MAC_MODEL_Q605: 359 case MAC_MODEL_Q605_ACC: 360 case MAC_MODEL_P475: 361 case MAC_MODEL_P475F: 362 return; 363 } 364 365 while (!req.complete) 366 cuda_poll(); 367 } 368 #endif /* CONFIG_ADB_CUDA */ 369 370 /* 371 *------------------------------------------------------------------- 372 * Below this point are the generic routines; they'll dispatch to the 373 * correct routine for the hardware on which we're running. 374 *------------------------------------------------------------------- 375 */ 376 377 void mac_pram_read(int offset, __u8 *buffer, int len) 378 { 379 __u8 (*func)(int); 380 int i; 381 382 switch (macintosh_config->adb_type) { 383 case MAC_ADB_IOP: 384 case MAC_ADB_II: 385 case MAC_ADB_PB1: 386 func = via_read_pram; 387 break; 388 #ifdef CONFIG_ADB_CUDA 389 case MAC_ADB_EGRET: 390 case MAC_ADB_CUDA: 391 func = cuda_read_pram; 392 break; 393 #endif 394 #ifdef CONFIG_ADB_PMU 395 case MAC_ADB_PB2: 396 func = pmu_read_pram; 397 break; 398 #endif 399 default: 400 return; 401 } 402 for (i = 0 ; i < len ; i++) { 403 buffer[i] = (*func)(offset++); 404 } 405 } 406 407 void mac_pram_write(int offset, __u8 *buffer, int len) 408 { 409 void (*func)(int, __u8); 410 int i; 411 412 switch (macintosh_config->adb_type) { 413 case MAC_ADB_IOP: 414 case MAC_ADB_II: 415 case MAC_ADB_PB1: 416 func = via_write_pram; 417 break; 418 #ifdef CONFIG_ADB_CUDA 419 case MAC_ADB_EGRET: 420 case MAC_ADB_CUDA: 421 func = cuda_write_pram; 422 break; 423 #endif 424 #ifdef CONFIG_ADB_PMU 425 case MAC_ADB_PB2: 426 func = pmu_write_pram; 427 break; 428 #endif 429 default: 430 return; 431 } 432 for (i = 0 ; i < len ; i++) { 433 (*func)(offset++, buffer[i]); 434 } 435 } 436 437 void mac_poweroff(void) 438 { 439 if (oss_present) { 440 oss_shutdown(); 441 } else if (macintosh_config->adb_type == MAC_ADB_II) { 442 via_shutdown(); 443 #ifdef CONFIG_ADB_CUDA 444 } else if (macintosh_config->adb_type == MAC_ADB_EGRET || 445 macintosh_config->adb_type == MAC_ADB_CUDA) { 446 cuda_shutdown(); 447 #endif 448 #ifdef CONFIG_ADB_PMU 449 } else if (macintosh_config->adb_type == MAC_ADB_PB2) { 450 pmu_shutdown(); 451 #endif 452 } 453 454 pr_crit("It is now safe to turn off your Macintosh.\n"); 455 local_irq_disable(); 456 while(1); 457 } 458 459 void mac_reset(void) 460 { 461 if (macintosh_config->adb_type == MAC_ADB_II) { 462 unsigned long flags; 463 464 /* need ROMBASE in booter */ 465 /* indeed, plus need to MAP THE ROM !! */ 466 467 if (mac_bi_data.rombase == 0) 468 mac_bi_data.rombase = 0x40800000; 469 470 /* works on some */ 471 rom_reset = (void *) (mac_bi_data.rombase + 0xa); 472 473 if (macintosh_config->ident == MAC_MODEL_SE30) { 474 /* 475 * MSch: Machines known to crash on ROM reset ... 476 */ 477 } else { 478 local_irq_save(flags); 479 480 rom_reset(); 481 482 local_irq_restore(flags); 483 } 484 #ifdef CONFIG_ADB_CUDA 485 } else if (macintosh_config->adb_type == MAC_ADB_EGRET || 486 macintosh_config->adb_type == MAC_ADB_CUDA) { 487 cuda_restart(); 488 #endif 489 #ifdef CONFIG_ADB_PMU 490 } else if (macintosh_config->adb_type == MAC_ADB_PB2) { 491 pmu_restart(); 492 #endif 493 } else if (CPU_IS_030) { 494 495 /* 030-specific reset routine. The idea is general, but the 496 * specific registers to reset are '030-specific. Until I 497 * have a non-030 machine, I can't test anything else. 498 * -- C. Scott Ananian <cananian@alumni.princeton.edu> 499 */ 500 501 unsigned long rombase = 0x40000000; 502 503 /* make a 1-to-1 mapping, using the transparent tran. reg. */ 504 unsigned long virt = (unsigned long) mac_reset; 505 unsigned long phys = virt_to_phys(mac_reset); 506 unsigned long addr = (phys&0xFF000000)|0x8777; 507 unsigned long offset = phys-virt; 508 509 local_irq_disable(); /* lets not screw this up, ok? */ 510 __asm__ __volatile__(".chip 68030\n\t" 511 "pmove %0,%/tt0\n\t" 512 ".chip 68k" 513 : : "m" (addr)); 514 /* Now jump to physical address so we can disable MMU */ 515 __asm__ __volatile__( 516 ".chip 68030\n\t" 517 "lea %/pc@(1f),%/a0\n\t" 518 "addl %0,%/a0\n\t"/* fixup target address and stack ptr */ 519 "addl %0,%/sp\n\t" 520 "pflusha\n\t" 521 "jmp %/a0@\n\t" /* jump into physical memory */ 522 "0:.long 0\n\t" /* a constant zero. */ 523 /* OK. Now reset everything and jump to reset vector. */ 524 "1:\n\t" 525 "lea %/pc@(0b),%/a0\n\t" 526 "pmove %/a0@, %/tc\n\t" /* disable mmu */ 527 "pmove %/a0@, %/tt0\n\t" /* disable tt0 */ 528 "pmove %/a0@, %/tt1\n\t" /* disable tt1 */ 529 "movel #0, %/a0\n\t" 530 "movec %/a0, %/vbr\n\t" /* clear vector base register */ 531 "movec %/a0, %/cacr\n\t" /* disable caches */ 532 "movel #0x0808,%/a0\n\t" 533 "movec %/a0, %/cacr\n\t" /* flush i&d caches */ 534 "movew #0x2700,%/sr\n\t" /* set up status register */ 535 "movel %1@(0x0),%/a0\n\t"/* load interrupt stack pointer */ 536 "movec %/a0, %/isp\n\t" 537 "movel %1@(0x4),%/a0\n\t" /* load reset vector */ 538 "reset\n\t" /* reset external devices */ 539 "jmp %/a0@\n\t" /* jump to the reset vector */ 540 ".chip 68k" 541 : : "r" (offset), "a" (rombase) : "a0"); 542 } 543 544 /* should never get here */ 545 pr_crit("Restart failed. Please restart manually.\n"); 546 local_irq_disable(); 547 while(1); 548 } 549 550 /* 551 * This function translates seconds since 1970 into a proper date. 552 * 553 * Algorithm cribbed from glibc2.1, __offtime(). 554 */ 555 #define SECS_PER_MINUTE (60) 556 #define SECS_PER_HOUR (SECS_PER_MINUTE * 60) 557 #define SECS_PER_DAY (SECS_PER_HOUR * 24) 558 559 static void unmktime(unsigned long time, long offset, 560 int *yearp, int *monp, int *dayp, 561 int *hourp, int *minp, int *secp) 562 { 563 /* How many days come before each month (0-12). */ 564 static const unsigned short int __mon_yday[2][13] = 565 { 566 /* Normal years. */ 567 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 568 /* Leap years. */ 569 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 570 }; 571 long int days, rem, y, wday, yday; 572 const unsigned short int *ip; 573 574 days = time / SECS_PER_DAY; 575 rem = time % SECS_PER_DAY; 576 rem += offset; 577 while (rem < 0) { 578 rem += SECS_PER_DAY; 579 --days; 580 } 581 while (rem >= SECS_PER_DAY) { 582 rem -= SECS_PER_DAY; 583 ++days; 584 } 585 *hourp = rem / SECS_PER_HOUR; 586 rem %= SECS_PER_HOUR; 587 *minp = rem / SECS_PER_MINUTE; 588 *secp = rem % SECS_PER_MINUTE; 589 /* January 1, 1970 was a Thursday. */ 590 wday = (4 + days) % 7; /* Day in the week. Not currently used */ 591 if (wday < 0) wday += 7; 592 y = 1970; 593 594 #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) 595 #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) 596 #define __isleap(year) \ 597 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) 598 599 while (days < 0 || days >= (__isleap (y) ? 366 : 365)) 600 { 601 /* Guess a corrected year, assuming 365 days per year. */ 602 long int yg = y + days / 365 - (days % 365 < 0); 603 604 /* Adjust DAYS and Y to match the guessed year. */ 605 days -= (yg - y) * 365 + 606 LEAPS_THRU_END_OF(yg - 1) - LEAPS_THRU_END_OF(y - 1); 607 y = yg; 608 } 609 *yearp = y - 1900; 610 yday = days; /* day in the year. Not currently used. */ 611 ip = __mon_yday[__isleap(y)]; 612 for (y = 11; days < (long int) ip[y]; --y) 613 continue; 614 days -= ip[y]; 615 *monp = y; 616 *dayp = days + 1; /* day in the month */ 617 return; 618 } 619 620 /* 621 * Read/write the hardware clock. 622 */ 623 624 int mac_hwclk(int op, struct rtc_time *t) 625 { 626 unsigned long now; 627 628 if (!op) { /* read */ 629 switch (macintosh_config->adb_type) { 630 case MAC_ADB_IOP: 631 case MAC_ADB_II: 632 case MAC_ADB_PB1: 633 now = via_read_time(); 634 break; 635 #ifdef CONFIG_ADB_CUDA 636 case MAC_ADB_EGRET: 637 case MAC_ADB_CUDA: 638 now = cuda_read_time(); 639 break; 640 #endif 641 #ifdef CONFIG_ADB_PMU 642 case MAC_ADB_PB2: 643 now = pmu_read_time(); 644 break; 645 #endif 646 default: 647 now = 0; 648 } 649 650 t->tm_wday = 0; 651 unmktime(now, 0, 652 &t->tm_year, &t->tm_mon, &t->tm_mday, 653 &t->tm_hour, &t->tm_min, &t->tm_sec); 654 pr_debug("%s: read %04d-%02d-%-2d %02d:%02d:%02d\n", 655 __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, 656 t->tm_hour, t->tm_min, t->tm_sec); 657 } else { /* write */ 658 pr_debug("%s: tried to write %04d-%02d-%-2d %02d:%02d:%02d\n", 659 __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, 660 t->tm_hour, t->tm_min, t->tm_sec); 661 662 now = mktime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, 663 t->tm_hour, t->tm_min, t->tm_sec); 664 665 switch (macintosh_config->adb_type) { 666 case MAC_ADB_IOP: 667 case MAC_ADB_II: 668 case MAC_ADB_PB1: 669 via_write_time(now); 670 break; 671 #ifdef CONFIG_ADB_CUDA 672 case MAC_ADB_EGRET: 673 case MAC_ADB_CUDA: 674 cuda_write_time(now); 675 break; 676 #endif 677 #ifdef CONFIG_ADB_PMU 678 case MAC_ADB_PB2: 679 pmu_write_time(now); 680 break; 681 #endif 682 default: 683 return -ENODEV; 684 } 685 } 686 return 0; 687 } 688 689 /* 690 * Set minutes/seconds in the hardware clock 691 */ 692 693 int mac_set_clock_mmss (unsigned long nowtime) 694 { 695 struct rtc_time now; 696 697 mac_hwclk(0, &now); 698 now.tm_sec = nowtime % 60; 699 now.tm_min = (nowtime / 60) % 60; 700 mac_hwclk(1, &now); 701 702 return 0; 703 } 704