This source file includes following definitions.
- cuda_pram_read_byte
- cuda_pram_write_byte
- pmu_pram_read_byte
- pmu_pram_write_byte
- via_rtc_recv
- via_rtc_send
- via_rtc_command
- via_pram_read_byte
- via_pram_write_byte
- via_read_time
- via_set_rtc_time
- via_shutdown
- oss_shutdown
- cuda_restart
- cuda_shutdown
- mac_pram_read_byte
- mac_pram_write_byte
- mac_pram_get_size
- mac_poweroff
- mac_reset
- unmktime
- mac_hwclk
   1 
   2 
   3 
   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 
  30 
  31 
  32 
  33 
  34 
  35 #define RTC_OFFSET 2082844800
  36 
  37 static void (*rom_reset)(void);
  38 
  39 #if IS_ENABLED(CONFIG_NVRAM)
  40 #ifdef CONFIG_ADB_CUDA
  41 static unsigned char cuda_pram_read_byte(int offset)
  42 {
  43         struct adb_request req;
  44 
  45         if (cuda_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
  46                          (offset >> 8) & 0xFF, offset & 0xFF) < 0)
  47                 return 0;
  48         while (!req.complete)
  49                 cuda_poll();
  50         return req.reply[3];
  51 }
  52 
  53 static void cuda_pram_write_byte(unsigned char data, int offset)
  54 {
  55         struct adb_request req;
  56 
  57         if (cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
  58                          (offset >> 8) & 0xFF, offset & 0xFF, data) < 0)
  59                 return;
  60         while (!req.complete)
  61                 cuda_poll();
  62 }
  63 #endif 
  64 
  65 #ifdef CONFIG_ADB_PMU
  66 static unsigned char pmu_pram_read_byte(int offset)
  67 {
  68         struct adb_request req;
  69 
  70         if (pmu_request(&req, NULL, 3, PMU_READ_XPRAM,
  71                         offset & 0xFF, 1) < 0)
  72                 return 0;
  73         pmu_wait_complete(&req);
  74 
  75         return req.reply[0];
  76 }
  77 
  78 static void pmu_pram_write_byte(unsigned char data, int offset)
  79 {
  80         struct adb_request req;
  81 
  82         if (pmu_request(&req, NULL, 4, PMU_WRITE_XPRAM,
  83                         offset & 0xFF, 1, data) < 0)
  84                 return;
  85         pmu_wait_complete(&req);
  86 }
  87 #endif 
  88 #endif 
  89 
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 static __u8 via_rtc_recv(void)
  98 {
  99         int i, reg;
 100         __u8 data;
 101 
 102         reg = via1[vBufB] & ~VIA1B_vRTCClk;
 103 
 104         
 105 
 106         via1[vDirB] &= ~VIA1B_vRTCData;
 107 
 108         
 109 
 110         data = 0;
 111         for (i = 0 ; i < 8 ; i++) {
 112                 via1[vBufB] = reg;
 113                 via1[vBufB] = reg | VIA1B_vRTCClk;
 114                 data = (data << 1) | (via1[vBufB] & VIA1B_vRTCData);
 115         }
 116 
 117         
 118 
 119         via1[vDirB] |= VIA1B_vRTCData;
 120 
 121         return data;
 122 }
 123 
 124 static void via_rtc_send(__u8 data)
 125 {
 126         int i, reg, bit;
 127 
 128         reg = via1[vBufB] & ~(VIA1B_vRTCClk | VIA1B_vRTCData);
 129 
 130         
 131 
 132         for (i = 0 ; i < 8 ; i++) {
 133                 bit = data & 0x80? 1 : 0;
 134                 data <<= 1;
 135                 via1[vBufB] = reg | bit;
 136                 via1[vBufB] = reg | bit | VIA1B_vRTCClk;
 137         }
 138 }
 139 
 140 
 141 
 142 
 143 
 144 
 145 #define RTC_FLG_READ            BIT(7)
 146 #define RTC_FLG_WRITE_PROTECT   BIT(7)
 147 #define RTC_CMD_READ(r)         (RTC_FLG_READ | (r << 2))
 148 #define RTC_CMD_WRITE(r)        (r << 2)
 149 #define RTC_REG_SECONDS_0       0
 150 #define RTC_REG_SECONDS_1       1
 151 #define RTC_REG_SECONDS_2       2
 152 #define RTC_REG_SECONDS_3       3
 153 #define RTC_REG_WRITE_PROTECT   13
 154 
 155 
 156 
 157 
 158 
 159 
 160 #define RTC_REG_XPRAM           14
 161 #define RTC_CMD_XPRAM_READ      (RTC_CMD_READ(RTC_REG_XPRAM) << 8)
 162 #define RTC_CMD_XPRAM_WRITE     (RTC_CMD_WRITE(RTC_REG_XPRAM) << 8)
 163 #define RTC_CMD_XPRAM_ARG(a)    (((a & 0xE0) << 3) | ((a & 0x1F) << 2))
 164 
 165 
 166 
 167 
 168 
 169 
 170 
 171 
 172 
 173 
 174 static void via_rtc_command(int command, __u8 *data)
 175 {
 176         unsigned long flags;
 177         int is_read;
 178 
 179         local_irq_save(flags);
 180 
 181         
 182 
 183         command = (command & ~3) | 1;
 184 
 185         
 186 
 187         via1[vBufB] = (via1[vBufB] | VIA1B_vRTCClk) & ~VIA1B_vRTCEnb;
 188 
 189         if (command & 0xFF00) {         
 190                 via_rtc_send((command & 0xFF00) >> 8);
 191                 via_rtc_send(command & 0xFF);
 192                 is_read = command & (RTC_FLG_READ << 8);
 193         } else {                        
 194                 via_rtc_send(command);
 195                 is_read = command & RTC_FLG_READ;
 196         }
 197         if (is_read) {
 198                 *data = via_rtc_recv();
 199         } else {
 200                 via_rtc_send(*data);
 201         }
 202 
 203         
 204 
 205         via1[vBufB] |= VIA1B_vRTCEnb;
 206 
 207         local_irq_restore(flags);
 208 }
 209 
 210 #if IS_ENABLED(CONFIG_NVRAM)
 211 static unsigned char via_pram_read_byte(int offset)
 212 {
 213         unsigned char temp;
 214 
 215         via_rtc_command(RTC_CMD_XPRAM_READ | RTC_CMD_XPRAM_ARG(offset), &temp);
 216 
 217         return temp;
 218 }
 219 
 220 static void via_pram_write_byte(unsigned char data, int offset)
 221 {
 222         unsigned char temp;
 223 
 224         temp = 0x55;
 225         via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
 226 
 227         temp = data;
 228         via_rtc_command(RTC_CMD_XPRAM_WRITE | RTC_CMD_XPRAM_ARG(offset), &temp);
 229 
 230         temp = 0x55 | RTC_FLG_WRITE_PROTECT;
 231         via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
 232 }
 233 #endif 
 234 
 235 
 236 
 237 
 238 
 239 
 240 
 241 
 242 static time64_t via_read_time(void)
 243 {
 244         union {
 245                 __u8 cdata[4];
 246                 __u32 idata;
 247         } result, last_result;
 248         int count = 1;
 249 
 250         via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_0), &last_result.cdata[3]);
 251         via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_1), &last_result.cdata[2]);
 252         via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_2), &last_result.cdata[1]);
 253         via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_3), &last_result.cdata[0]);
 254 
 255         
 256 
 257 
 258 
 259 
 260         while (1) {
 261                 via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_0),
 262                                 &result.cdata[3]);
 263                 via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_1),
 264                                 &result.cdata[2]);
 265                 via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_2),
 266                                 &result.cdata[1]);
 267                 via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_3),
 268                                 &result.cdata[0]);
 269 
 270                 if (result.idata == last_result.idata)
 271                         return (time64_t)result.idata - RTC_OFFSET;
 272 
 273                 if (++count > 10)
 274                         break;
 275 
 276                 last_result.idata = result.idata;
 277         }
 278 
 279         pr_err("%s: failed to read a stable value; got 0x%08x then 0x%08x\n",
 280                __func__, last_result.idata, result.idata);
 281 
 282         return 0;
 283 }
 284 
 285 
 286 
 287 
 288 
 289 
 290 
 291 
 292 static void via_set_rtc_time(struct rtc_time *tm)
 293 {
 294         union {
 295                 __u8 cdata[4];
 296                 __u32 idata;
 297         } data;
 298         __u8 temp;
 299         time64_t time;
 300 
 301         time = mktime64(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
 302                         tm->tm_hour, tm->tm_min, tm->tm_sec);
 303 
 304         
 305 
 306         temp = 0x55;
 307         via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
 308 
 309         data.idata = lower_32_bits(time + RTC_OFFSET);
 310         via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_0), &data.cdata[3]);
 311         via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_1), &data.cdata[2]);
 312         via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_2), &data.cdata[1]);
 313         via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_3), &data.cdata[0]);
 314 
 315         
 316 
 317         temp = 0x55 | RTC_FLG_WRITE_PROTECT;
 318         via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
 319 }
 320 
 321 static void via_shutdown(void)
 322 {
 323         if (rbv_present) {
 324                 via2[rBufB] &= ~0x04;
 325         } else {
 326                 
 327                 via2[vDirB] |= 0x04;
 328                 
 329                 via2[vBufB] &= ~0x04;
 330                 mdelay(1000);
 331         }
 332 }
 333 
 334 static void oss_shutdown(void)
 335 {
 336         oss->rom_ctrl = OSS_POWEROFF;
 337 }
 338 
 339 #ifdef CONFIG_ADB_CUDA
 340 static void cuda_restart(void)
 341 {
 342         struct adb_request req;
 343 
 344         if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM) < 0)
 345                 return;
 346         while (!req.complete)
 347                 cuda_poll();
 348 }
 349 
 350 static void cuda_shutdown(void)
 351 {
 352         struct adb_request req;
 353 
 354         if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN) < 0)
 355                 return;
 356 
 357         
 358         switch (macintosh_config->ident) {
 359         case MAC_MODEL_C660:
 360         case MAC_MODEL_Q605:
 361         case MAC_MODEL_Q605_ACC:
 362         case MAC_MODEL_P475:
 363         case MAC_MODEL_P475F:
 364                 return;
 365         }
 366 
 367         while (!req.complete)
 368                 cuda_poll();
 369 }
 370 #endif 
 371 
 372 
 373 
 374 
 375 
 376 
 377 
 378 
 379 #if IS_ENABLED(CONFIG_NVRAM)
 380 unsigned char mac_pram_read_byte(int addr)
 381 {
 382         switch (macintosh_config->adb_type) {
 383         case MAC_ADB_IOP:
 384         case MAC_ADB_II:
 385         case MAC_ADB_PB1:
 386                 return via_pram_read_byte(addr);
 387 #ifdef CONFIG_ADB_CUDA
 388         case MAC_ADB_EGRET:
 389         case MAC_ADB_CUDA:
 390                 return cuda_pram_read_byte(addr);
 391 #endif
 392 #ifdef CONFIG_ADB_PMU
 393         case MAC_ADB_PB2:
 394                 return pmu_pram_read_byte(addr);
 395 #endif
 396         default:
 397                 return 0xFF;
 398         }
 399 }
 400 
 401 void mac_pram_write_byte(unsigned char val, int addr)
 402 {
 403         switch (macintosh_config->adb_type) {
 404         case MAC_ADB_IOP:
 405         case MAC_ADB_II:
 406         case MAC_ADB_PB1:
 407                 via_pram_write_byte(val, addr);
 408                 break;
 409 #ifdef CONFIG_ADB_CUDA
 410         case MAC_ADB_EGRET:
 411         case MAC_ADB_CUDA:
 412                 cuda_pram_write_byte(val, addr);
 413                 break;
 414 #endif
 415 #ifdef CONFIG_ADB_PMU
 416         case MAC_ADB_PB2:
 417                 pmu_pram_write_byte(val, addr);
 418                 break;
 419 #endif
 420         default:
 421                 break;
 422         }
 423 }
 424 
 425 ssize_t mac_pram_get_size(void)
 426 {
 427         return 256;
 428 }
 429 #endif 
 430 
 431 void mac_poweroff(void)
 432 {
 433         if (oss_present) {
 434                 oss_shutdown();
 435         } else if (macintosh_config->adb_type == MAC_ADB_II) {
 436                 via_shutdown();
 437 #ifdef CONFIG_ADB_CUDA
 438         } else if (macintosh_config->adb_type == MAC_ADB_EGRET ||
 439                    macintosh_config->adb_type == MAC_ADB_CUDA) {
 440                 cuda_shutdown();
 441 #endif
 442 #ifdef CONFIG_ADB_PMU
 443         } else if (macintosh_config->adb_type == MAC_ADB_PB2) {
 444                 pmu_shutdown();
 445 #endif
 446         }
 447 
 448         pr_crit("It is now safe to turn off your Macintosh.\n");
 449         local_irq_disable();
 450         while(1);
 451 }
 452 
 453 void mac_reset(void)
 454 {
 455         if (macintosh_config->adb_type == MAC_ADB_II &&
 456             macintosh_config->ident != MAC_MODEL_SE30) {
 457                 
 458                 
 459 
 460                 if (mac_bi_data.rombase == 0)
 461                         mac_bi_data.rombase = 0x40800000;
 462 
 463                 
 464                 rom_reset = (void *) (mac_bi_data.rombase + 0xa);
 465 
 466                 local_irq_disable();
 467                 rom_reset();
 468 #ifdef CONFIG_ADB_CUDA
 469         } else if (macintosh_config->adb_type == MAC_ADB_EGRET ||
 470                    macintosh_config->adb_type == MAC_ADB_CUDA) {
 471                 cuda_restart();
 472 #endif
 473 #ifdef CONFIG_ADB_PMU
 474         } else if (macintosh_config->adb_type == MAC_ADB_PB2) {
 475                 pmu_restart();
 476 #endif
 477         } else if (CPU_IS_030) {
 478 
 479                 
 480 
 481 
 482 
 483 
 484 
 485                 unsigned long rombase = 0x40000000;
 486 
 487                 
 488                 unsigned long virt = (unsigned long) mac_reset;
 489                 unsigned long phys = virt_to_phys(mac_reset);
 490                 unsigned long addr = (phys&0xFF000000)|0x8777;
 491                 unsigned long offset = phys-virt;
 492 
 493                 local_irq_disable(); 
 494                 __asm__ __volatile__(".chip 68030\n\t"
 495                                      "pmove %0,%/tt0\n\t"
 496                                      ".chip 68k"
 497                                      : : "m" (addr));
 498                 
 499                 __asm__ __volatile__(
 500                     ".chip 68030\n\t"
 501                     "lea %/pc@(1f),%/a0\n\t"
 502                     "addl %0,%/a0\n\t"
 503                     "addl %0,%/sp\n\t"
 504                     "pflusha\n\t"
 505                     "jmp %/a0@\n\t" 
 506                     "0:.long 0\n\t" 
 507                     
 508                     "1:\n\t"
 509                     "lea %/pc@(0b),%/a0\n\t"
 510                     "pmove %/a0@, %/tc\n\t" 
 511                     "pmove %/a0@, %/tt0\n\t" 
 512                     "pmove %/a0@, %/tt1\n\t" 
 513                     "movel #0, %/a0\n\t"
 514                     "movec %/a0, %/vbr\n\t" 
 515                     "movec %/a0, %/cacr\n\t" 
 516                     "movel #0x0808,%/a0\n\t"
 517                     "movec %/a0, %/cacr\n\t" 
 518                     "movew #0x2700,%/sr\n\t" 
 519                     "movel %1@(0x0),%/a0\n\t"
 520                     "movec %/a0, %/isp\n\t"
 521                     "movel %1@(0x4),%/a0\n\t" 
 522                     "reset\n\t" 
 523                     "jmp %/a0@\n\t" 
 524                     ".chip 68k"
 525                     : : "r" (offset), "a" (rombase) : "a0");
 526         }
 527 
 528         
 529         pr_crit("Restart failed. Please restart manually.\n");
 530         local_irq_disable();
 531         while(1);
 532 }
 533 
 534 
 535 
 536 
 537 
 538 
 539 
 540 
 541 
 542 #define SECS_PER_MINUTE (60)
 543 #define SECS_PER_HOUR  (SECS_PER_MINUTE * 60)
 544 #define SECS_PER_DAY   (SECS_PER_HOUR * 24)
 545 
 546 static void unmktime(time64_t time, long offset,
 547                      int *yearp, int *monp, int *dayp,
 548                      int *hourp, int *minp, int *secp)
 549 {
 550         
 551         static const unsigned short int __mon_yday[2][13] =
 552         {
 553                 
 554                 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
 555                 
 556                 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
 557         };
 558         int days, rem, y, wday, yday;
 559         const unsigned short int *ip;
 560 
 561         days = div_u64_rem(time, SECS_PER_DAY, &rem);
 562         rem += offset;
 563         while (rem < 0) {
 564                 rem += SECS_PER_DAY;
 565                 --days;
 566         }
 567         while (rem >= SECS_PER_DAY) {
 568                 rem -= SECS_PER_DAY;
 569                 ++days;
 570         }
 571         *hourp = rem / SECS_PER_HOUR;
 572         rem %= SECS_PER_HOUR;
 573         *minp = rem / SECS_PER_MINUTE;
 574         *secp = rem % SECS_PER_MINUTE;
 575         
 576         wday = (4 + days) % 7; 
 577         if (wday < 0) wday += 7;
 578         y = 1970;
 579 
 580 #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
 581 #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
 582 #define __isleap(year)  \
 583   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
 584 
 585         while (days < 0 || days >= (__isleap (y) ? 366 : 365))
 586         {
 587                 
 588                 long int yg = y + days / 365 - (days % 365 < 0);
 589 
 590                 
 591                 days -= (yg - y) * 365 +
 592                         LEAPS_THRU_END_OF(yg - 1) - LEAPS_THRU_END_OF(y - 1);
 593                 y = yg;
 594         }
 595         *yearp = y - 1900;
 596         yday = days; 
 597         ip = __mon_yday[__isleap(y)];
 598         for (y = 11; days < (long int) ip[y]; --y)
 599                 continue;
 600         days -= ip[y];
 601         *monp = y;
 602         *dayp = days + 1; 
 603         return;
 604 }
 605 
 606 
 607 
 608 
 609 
 610 int mac_hwclk(int op, struct rtc_time *t)
 611 {
 612         time64_t now;
 613 
 614         if (!op) { 
 615                 switch (macintosh_config->adb_type) {
 616                 case MAC_ADB_IOP:
 617                 case MAC_ADB_II:
 618                 case MAC_ADB_PB1:
 619                         now = via_read_time();
 620                         break;
 621 #ifdef CONFIG_ADB_CUDA
 622                 case MAC_ADB_EGRET:
 623                 case MAC_ADB_CUDA:
 624                         now = cuda_get_time();
 625                         break;
 626 #endif
 627 #ifdef CONFIG_ADB_PMU
 628                 case MAC_ADB_PB2:
 629                         now = pmu_get_time();
 630                         break;
 631 #endif
 632                 default:
 633                         now = 0;
 634                 }
 635 
 636                 t->tm_wday = 0;
 637                 unmktime(now, 0,
 638                          &t->tm_year, &t->tm_mon, &t->tm_mday,
 639                          &t->tm_hour, &t->tm_min, &t->tm_sec);
 640                 pr_debug("%s: read %ptR\n", __func__, t);
 641         } else { 
 642                 pr_debug("%s: tried to write %ptR\n", __func__, t);
 643 
 644                 switch (macintosh_config->adb_type) {
 645                 case MAC_ADB_IOP:
 646                 case MAC_ADB_II:
 647                 case MAC_ADB_PB1:
 648                         via_set_rtc_time(t);
 649                         break;
 650 #ifdef CONFIG_ADB_CUDA
 651                 case MAC_ADB_EGRET:
 652                 case MAC_ADB_CUDA:
 653                         cuda_set_rtc_time(t);
 654                         break;
 655 #endif
 656 #ifdef CONFIG_ADB_PMU
 657                 case MAC_ADB_PB2:
 658                         pmu_set_rtc_time(t);
 659                         break;
 660 #endif
 661                 default:
 662                         return -ENODEV;
 663                 }
 664         }
 665         return 0;
 666 }