misc.c (16318B)
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 36static void (*rom_reset)(void); 37 38#if IS_ENABLED(CONFIG_NVRAM) 39#ifdef CONFIG_ADB_CUDA 40static 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 52static 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 65static 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 77static 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 96static __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 123static 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 in 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 173static 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) 210static 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 219static 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 241static 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 291static 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 320static 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 333static void oss_shutdown(void) 334{ 335 oss->rom_ctrl = OSS_POWEROFF; 336} 337 338#ifdef CONFIG_ADB_CUDA 339static 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 349static 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) 379unsigned 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 400void 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 424ssize_t mac_pram_get_size(void) 425{ 426 return 256; 427} 428#endif /* CONFIG_NVRAM */ 429 430void 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 452void mac_reset(void) 453{ 454 if (macintosh_config->adb_type == MAC_ADB_II && 455 macintosh_config->ident != MAC_MODEL_SE30) { 456 /* need ROMBASE in booter */ 457 /* indeed, plus need to MAP THE ROM !! */ 458 459 if (mac_bi_data.rombase == 0) 460 mac_bi_data.rombase = 0x40800000; 461 462 /* works on some */ 463 rom_reset = (void *) (mac_bi_data.rombase + 0xa); 464 465 local_irq_disable(); 466 rom_reset(); 467#ifdef CONFIG_ADB_CUDA 468 } else if (macintosh_config->adb_type == MAC_ADB_EGRET || 469 macintosh_config->adb_type == MAC_ADB_CUDA) { 470 cuda_restart(); 471#endif 472#ifdef CONFIG_ADB_PMU 473 } else if (macintosh_config->adb_type == MAC_ADB_PB2) { 474 pmu_restart(); 475#endif 476 } else if (CPU_IS_030) { 477 478 /* 030-specific reset routine. The idea is general, but the 479 * specific registers to reset are '030-specific. Until I 480 * have a non-030 machine, I can't test anything else. 481 * -- C. Scott Ananian <cananian@alumni.princeton.edu> 482 */ 483 484 unsigned long rombase = 0x40000000; 485 486 /* make a 1-to-1 mapping, using the transparent tran. reg. */ 487 unsigned long virt = (unsigned long) mac_reset; 488 unsigned long phys = virt_to_phys(mac_reset); 489 unsigned long addr = (phys&0xFF000000)|0x8777; 490 unsigned long offset = phys-virt; 491 492 local_irq_disable(); /* lets not screw this up, ok? */ 493 __asm__ __volatile__(".chip 68030\n\t" 494 "pmove %0,%/tt0\n\t" 495 ".chip 68k" 496 : : "m" (addr)); 497 /* Now jump to physical address so we can disable MMU */ 498 __asm__ __volatile__( 499 ".chip 68030\n\t" 500 "lea %/pc@(1f),%/a0\n\t" 501 "addl %0,%/a0\n\t"/* fixup target address and stack ptr */ 502 "addl %0,%/sp\n\t" 503 "pflusha\n\t" 504 "jmp %/a0@\n\t" /* jump into physical memory */ 505 "0:.long 0\n\t" /* a constant zero. */ 506 /* OK. Now reset everything and jump to reset vector. */ 507 "1:\n\t" 508 "lea %/pc@(0b),%/a0\n\t" 509 "pmove %/a0@, %/tc\n\t" /* disable mmu */ 510 "pmove %/a0@, %/tt0\n\t" /* disable tt0 */ 511 "pmove %/a0@, %/tt1\n\t" /* disable tt1 */ 512 "movel #0, %/a0\n\t" 513 "movec %/a0, %/vbr\n\t" /* clear vector base register */ 514 "movec %/a0, %/cacr\n\t" /* disable caches */ 515 "movel #0x0808,%/a0\n\t" 516 "movec %/a0, %/cacr\n\t" /* flush i&d caches */ 517 "movew #0x2700,%/sr\n\t" /* set up status register */ 518 "movel %1@(0x0),%/a0\n\t"/* load interrupt stack pointer */ 519 "movec %/a0, %/isp\n\t" 520 "movel %1@(0x4),%/a0\n\t" /* load reset vector */ 521 "reset\n\t" /* reset external devices */ 522 "jmp %/a0@\n\t" /* jump to the reset vector */ 523 ".chip 68k" 524 : : "r" (offset), "a" (rombase) : "a0"); 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 545static 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 609int 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}