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