1 /* 2 * (C) Copyright 2000-2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* 9 * m8xx.c 10 * 11 * CPU specific code 12 * 13 * written or collected and sometimes rewritten by 14 * Magnus Damm <damm@bitsmart.com> 15 * 16 * minor modifications by 17 * Wolfgang Denk <wd@denx.de> 18 */ 19 20 #include <common.h> 21 #include <watchdog.h> 22 #include <command.h> 23 #include <mpc8xx.h> 24 #include <commproc.h> 25 #include <netdev.h> 26 #include <asm/cache.h> 27 #include <linux/compiler.h> 28 #include <asm/io.h> 29 30 #if defined(CONFIG_OF_LIBFDT) 31 #include <libfdt.h> 32 #include <fdt_support.h> 33 #endif 34 35 DECLARE_GLOBAL_DATA_PTR; 36 37 static char *cpu_warning = "\n " \ 38 "*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***"; 39 40 #if ((defined(CONFIG_MPC86x) || defined(CONFIG_MPC855)) && \ 41 !defined(CONFIG_MPC862)) 42 43 static int check_CPU (long clock, uint pvr, uint immr) 44 { 45 char *id_str = 46 # if defined(CONFIG_MPC855) 47 "PC855"; 48 # elif defined(CONFIG_MPC860P) 49 "PC860P"; 50 # else 51 NULL; 52 # endif 53 volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000); 54 uint k, m; 55 char buf[32]; 56 char pre = 'X'; 57 char *mid = "xx"; 58 char *suf; 59 60 /* the highest 16 bits should be 0x0050 for a 860 */ 61 62 if ((pvr >> 16) != 0x0050) 63 return -1; 64 65 k = (immr << 16) | 66 immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)]; 67 m = 0; 68 suf = ""; 69 70 /* 71 * Some boards use sockets so different CPUs can be used. 72 * We have to check chip version in run time. 73 */ 74 switch (k) { 75 case 0x00020001: pre = 'P'; break; 76 case 0x00030001: break; 77 case 0x00120003: suf = "A"; break; 78 case 0x00130003: suf = "A3"; break; 79 80 case 0x00200004: suf = "B"; break; 81 82 case 0x00300004: suf = "C"; break; 83 case 0x00310004: suf = "C1"; m = 1; break; 84 85 case 0x00200064: mid = "SR"; suf = "B"; break; 86 case 0x00300065: mid = "SR"; suf = "C"; break; 87 case 0x00310065: mid = "SR"; suf = "C1"; m = 1; break; 88 case 0x05010000: suf = "D3"; m = 1; break; 89 case 0x05020000: suf = "D4"; m = 1; break; 90 /* this value is not documented anywhere */ 91 case 0x40000000: pre = 'P'; suf = "D"; m = 1; break; 92 /* MPC866P/MPC866T/MPC859T/MPC859DSL/MPC852T */ 93 case 0x08010004: /* Rev. A.0 */ 94 suf = "A"; 95 /* fall through */ 96 case 0x08000003: /* Rev. 0.3 */ 97 pre = 'M'; m = 1; 98 if (id_str == NULL) 99 id_str = 100 # if defined(CONFIG_MPC852T) 101 "PC852T"; 102 # elif defined(CONFIG_MPC859T) 103 "PC859T"; 104 # elif defined(CONFIG_MPC859DSL) 105 "PC859DSL"; 106 # elif defined(CONFIG_MPC866T) 107 "PC866T"; 108 # else 109 "PC866x"; /* Unknown chip from MPC866 family */ 110 # endif 111 break; 112 case 0x09000000: pre = 'M'; mid = suf = ""; m = 1; 113 if (id_str == NULL) 114 id_str = "PC885"; /* 870/875/880/885 */ 115 break; 116 117 default: suf = NULL; break; 118 } 119 120 if (id_str == NULL) 121 id_str = "PC86x"; /* Unknown 86x chip */ 122 if (suf) 123 printf ("%c%s%sZPnn%s", pre, id_str, mid, suf); 124 else 125 printf ("unknown M%s (0x%08x)", id_str, k); 126 127 128 #if defined(CONFIG_SYS_8xx_CPUCLK_MIN) && defined(CONFIG_SYS_8xx_CPUCLK_MAX) 129 printf (" at %s MHz [%d.%d...%d.%d MHz]\n ", 130 strmhz (buf, clock), 131 CONFIG_SYS_8xx_CPUCLK_MIN / 1000000, 132 ((CONFIG_SYS_8xx_CPUCLK_MIN % 1000000) + 50000) / 100000, 133 CONFIG_SYS_8xx_CPUCLK_MAX / 1000000, 134 ((CONFIG_SYS_8xx_CPUCLK_MAX % 1000000) + 50000) / 100000 135 ); 136 #else 137 printf (" at %s MHz: ", strmhz (buf, clock)); 138 #endif 139 printf ("%u kB I-Cache %u kB D-Cache", 140 checkicache () >> 10, 141 checkdcache () >> 10 142 ); 143 144 /* do we have a FEC (860T/P or 852/859/866/885)? */ 145 146 immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; 147 if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { 148 printf (" FEC present"); 149 } 150 151 if (!m) { 152 puts (cpu_warning); 153 } 154 155 putc ('\n'); 156 157 #ifdef DEBUG 158 if(clock != measure_gclk()) { 159 printf ("clock %ldHz != %dHz\n", clock, measure_gclk()); 160 } 161 #endif 162 163 return 0; 164 } 165 166 #elif defined(CONFIG_MPC862) 167 168 static int check_CPU (long clock, uint pvr, uint immr) 169 { 170 volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000); 171 uint k, m; 172 char buf[32]; 173 char pre = 'X'; 174 __maybe_unused char *mid = "xx"; 175 char *suf; 176 177 /* the highest 16 bits should be 0x0050 for a 8xx */ 178 179 if ((pvr >> 16) != 0x0050) 180 return -1; 181 182 k = (immr << 16) | 183 immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)]; 184 m = 0; 185 186 switch (k) { 187 188 /* this value is not documented anywhere */ 189 case 0x06000000: mid = "P"; suf = "0"; break; 190 case 0x06010001: mid = "P"; suf = "A"; m = 1; break; 191 case 0x07000003: mid = "P"; suf = "B"; m = 1; break; 192 default: suf = NULL; break; 193 } 194 195 #ifndef CONFIG_MPC857 196 if (suf) 197 printf ("%cPC862%sZPnn%s", pre, mid, suf); 198 else 199 printf ("unknown MPC862 (0x%08x)", k); 200 #else 201 if (suf) 202 printf ("%cPC857TZPnn%s", pre, suf); /* only 857T tested right now! */ 203 else 204 printf ("unknown MPC857 (0x%08x)", k); 205 #endif 206 207 printf (" at %s MHz:", strmhz (buf, clock)); 208 209 printf (" %u kB I-Cache", checkicache () >> 10); 210 printf (" %u kB D-Cache", checkdcache () >> 10); 211 212 /* lets check and see if we're running on a 862T (or P?) */ 213 214 immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; 215 if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { 216 printf (" FEC present"); 217 } 218 219 if (!m) { 220 puts (cpu_warning); 221 } 222 223 putc ('\n'); 224 225 return 0; 226 } 227 228 #elif defined(CONFIG_MPC823) 229 230 static int check_CPU (long clock, uint pvr, uint immr) 231 { 232 volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000); 233 uint k, m; 234 char buf[32]; 235 char *suf; 236 237 /* the highest 16 bits should be 0x0050 for a 8xx */ 238 239 if ((pvr >> 16) != 0x0050) 240 return -1; 241 242 k = (immr << 16) | 243 in_be16(&immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)]); 244 m = 0; 245 246 switch (k) { 247 /* MPC823 */ 248 case 0x20000000: suf = "0"; break; 249 case 0x20010000: suf = "0.1"; break; 250 case 0x20020000: suf = "Z2/3"; break; 251 case 0x20020001: suf = "Z3"; break; 252 case 0x21000000: suf = "A"; break; 253 case 0x21010000: suf = "B"; m = 1; break; 254 case 0x21010001: suf = "B2"; m = 1; break; 255 /* MPC823E */ 256 case 0x24010000: suf = NULL; 257 puts ("PPC823EZTnnB2"); 258 m = 1; 259 break; 260 default: 261 suf = NULL; 262 printf ("unknown MPC823 (0x%08x)", k); 263 break; 264 } 265 if (suf) 266 printf ("PPC823ZTnn%s", suf); 267 268 printf (" at %s MHz:", strmhz (buf, clock)); 269 270 printf (" %u kB I-Cache", checkicache () >> 10); 271 printf (" %u kB D-Cache", checkdcache () >> 10); 272 273 /* lets check and see if we're running on a 860T (or P?) */ 274 275 immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; 276 if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { 277 puts (" FEC present"); 278 } 279 280 if (!m) { 281 puts (cpu_warning); 282 } 283 284 putc ('\n'); 285 286 return 0; 287 } 288 289 #elif defined(CONFIG_MPC850) 290 291 static int check_CPU (long clock, uint pvr, uint immr) 292 { 293 volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000); 294 uint k, m; 295 char buf[32]; 296 297 /* the highest 16 bits should be 0x0050 for a 8xx */ 298 299 if ((pvr >> 16) != 0x0050) 300 return -1; 301 302 k = (immr << 16) | 303 immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)]; 304 m = 0; 305 306 switch (k) { 307 case 0x20020001: 308 printf ("XPC850xxZT"); 309 break; 310 case 0x21000065: 311 printf ("XPC850xxZTA"); 312 break; 313 case 0x21010067: 314 printf ("XPC850xxZTB"); 315 m = 1; 316 break; 317 case 0x21020068: 318 printf ("XPC850xxZTC"); 319 m = 1; 320 break; 321 default: 322 printf ("unknown MPC850 (0x%08x)", k); 323 } 324 printf (" at %s MHz:", strmhz (buf, clock)); 325 326 printf (" %u kB I-Cache", checkicache () >> 10); 327 printf (" %u kB D-Cache", checkdcache () >> 10); 328 329 /* lets check and see if we're running on a 850T (or P?) */ 330 331 immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; 332 if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { 333 printf (" FEC present"); 334 } 335 336 if (!m) { 337 puts (cpu_warning); 338 } 339 340 putc ('\n'); 341 342 return 0; 343 } 344 #else 345 #error CPU undefined 346 #endif 347 /* ------------------------------------------------------------------------- */ 348 349 int checkcpu (void) 350 { 351 ulong clock = gd->cpu_clk; 352 uint immr = get_immr (0); /* Return full IMMR contents */ 353 uint pvr = get_pvr (); 354 355 puts ("CPU: "); 356 357 /* 850 has PARTNUM 20 */ 358 /* 801 has PARTNUM 10 */ 359 return check_CPU (clock, pvr, immr); 360 } 361 362 /* ------------------------------------------------------------------------- */ 363 /* L1 i-cache */ 364 /* the standard 860 has 128 sets of 16 bytes in 2 ways (= 4 kB) */ 365 /* the 860 P (plus) has 256 sets of 16 bytes in 4 ways (= 16 kB) */ 366 367 int checkicache (void) 368 { 369 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 370 volatile memctl8xx_t *memctl = &immap->im_memctl; 371 u32 cacheon = rd_ic_cst () & IDC_ENABLED; 372 373 #ifdef CONFIG_IP86x 374 u32 k = memctl->memc_br1 & ~0x00007fff; /* probe in flash memoryarea */ 375 #else 376 u32 k = memctl->memc_br0 & ~0x00007fff; /* probe in flash memoryarea */ 377 #endif 378 u32 m; 379 u32 lines = -1; 380 381 wr_ic_cst (IDC_UNALL); 382 wr_ic_cst (IDC_INVALL); 383 wr_ic_cst (IDC_DISABLE); 384 __asm__ volatile ("isync"); 385 386 while (!((m = rd_ic_cst ()) & IDC_CERR2)) { 387 wr_ic_adr (k); 388 wr_ic_cst (IDC_LDLCK); 389 __asm__ volatile ("isync"); 390 391 lines++; 392 k += 0x10; /* the number of bytes in a cacheline */ 393 } 394 395 wr_ic_cst (IDC_UNALL); 396 wr_ic_cst (IDC_INVALL); 397 398 if (cacheon) 399 wr_ic_cst (IDC_ENABLE); 400 else 401 wr_ic_cst (IDC_DISABLE); 402 403 __asm__ volatile ("isync"); 404 405 return lines << 4; 406 }; 407 408 /* ------------------------------------------------------------------------- */ 409 /* L1 d-cache */ 410 /* the standard 860 has 128 sets of 16 bytes in 2 ways (= 4 kB) */ 411 /* the 860 P (plus) has 256 sets of 16 bytes in 2 ways (= 8 kB) */ 412 /* call with cache disabled */ 413 414 int checkdcache (void) 415 { 416 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 417 volatile memctl8xx_t *memctl = &immap->im_memctl; 418 u32 cacheon = rd_dc_cst () & IDC_ENABLED; 419 420 #ifdef CONFIG_IP86x 421 u32 k = memctl->memc_br1 & ~0x00007fff; /* probe in flash memoryarea */ 422 #else 423 u32 k = memctl->memc_br0 & ~0x00007fff; /* probe in flash memoryarea */ 424 #endif 425 u32 m; 426 u32 lines = -1; 427 428 wr_dc_cst (IDC_UNALL); 429 wr_dc_cst (IDC_INVALL); 430 wr_dc_cst (IDC_DISABLE); 431 432 while (!((m = rd_dc_cst ()) & IDC_CERR2)) { 433 wr_dc_adr (k); 434 wr_dc_cst (IDC_LDLCK); 435 lines++; 436 k += 0x10; /* the number of bytes in a cacheline */ 437 } 438 439 wr_dc_cst (IDC_UNALL); 440 wr_dc_cst (IDC_INVALL); 441 442 if (cacheon) 443 wr_dc_cst (IDC_ENABLE); 444 else 445 wr_dc_cst (IDC_DISABLE); 446 447 return lines << 4; 448 }; 449 450 /* ------------------------------------------------------------------------- */ 451 452 void upmconfig (uint upm, uint * table, uint size) 453 { 454 uint i; 455 uint addr = 0; 456 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 457 volatile memctl8xx_t *memctl = &immap->im_memctl; 458 459 for (i = 0; i < size; i++) { 460 memctl->memc_mdr = table[i]; /* (16-15) */ 461 memctl->memc_mcr = addr | upm; /* (16-16) */ 462 addr++; 463 } 464 } 465 466 /* ------------------------------------------------------------------------- */ 467 468 #ifndef CONFIG_LWMON 469 470 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 471 { 472 ulong msr, addr; 473 474 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 475 476 immap->im_clkrst.car_plprcr |= PLPRCR_CSR; /* Checkstop Reset enable */ 477 478 /* Interrupts and MMU off */ 479 __asm__ volatile ("mtspr 81, 0"); 480 __asm__ volatile ("mfmsr %0":"=r" (msr)); 481 482 msr &= ~0x1030; 483 __asm__ volatile ("mtmsr %0"::"r" (msr)); 484 485 /* 486 * Trying to execute the next instruction at a non-existing address 487 * should cause a machine check, resulting in reset 488 */ 489 #ifdef CONFIG_SYS_RESET_ADDRESS 490 addr = CONFIG_SYS_RESET_ADDRESS; 491 #else 492 /* 493 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address, CONFIG_SYS_MONITOR_BASE 494 * - sizeof (ulong) is usually a valid address. Better pick an address 495 * known to be invalid on your system and assign it to CONFIG_SYS_RESET_ADDRESS. 496 * "(ulong)-1" used to be a good choice for many systems... 497 */ 498 addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong); 499 #endif 500 ((void (*)(void)) addr) (); 501 return 1; 502 } 503 504 #else /* CONFIG_LWMON */ 505 506 /* 507 * On the LWMON board, the MCLR reset input of the PIC's on the board 508 * uses a 47K/1n RC combination which has a 47us time constant. The 509 * low signal on the HRESET pin of the CPU is only 512 clocks = 8 us 510 * and thus too short to reset the external hardware. So we use the 511 * watchdog to reset the board. 512 */ 513 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 514 { 515 /* prevent triggering the watchdog */ 516 disable_interrupts (); 517 518 /* make sure the watchdog is running */ 519 reset_8xx_watchdog ((immap_t *) CONFIG_SYS_IMMR); 520 521 /* wait for watchdog reset */ 522 while (1) {}; 523 524 /* NOTREACHED */ 525 return 1; 526 } 527 528 #endif /* CONFIG_LWMON */ 529 530 /* ------------------------------------------------------------------------- */ 531 532 /* 533 * Get timebase clock frequency (like cpu_clk in Hz) 534 * 535 * See sections 14.2 and 14.6 of the User's Manual 536 */ 537 unsigned long get_tbclk (void) 538 { 539 uint immr = get_immr (0); /* Return full IMMR contents */ 540 volatile immap_t *immap = (volatile immap_t *)(immr & 0xFFFF0000); 541 ulong oscclk, factor, pll; 542 543 if (immap->im_clkrst.car_sccr & SCCR_TBS) { 544 return (gd->cpu_clk / 16); 545 } 546 547 pll = immap->im_clkrst.car_plprcr; 548 549 #define PLPRCR_val(a) ((pll & PLPRCR_ ## a ## _MSK) >> PLPRCR_ ## a ## _SHIFT) 550 551 /* 552 * For newer PQ1 chips (MPC866/87x/88x families), PLL multiplication 553 * factor is calculated as follows: 554 * 555 * MFN 556 * MFI + ------- 557 * MFD + 1 558 * factor = ----------------- 559 * (PDF + 1) * 2^S 560 * 561 * For older chips, it's just MF field of PLPRCR plus one. 562 */ 563 if ((immr & 0x0FFF) >= MPC8xx_NEW_CLK) { /* MPC866/87x/88x series */ 564 factor = (PLPRCR_val(MFI) + PLPRCR_val(MFN)/(PLPRCR_val(MFD)+1))/ 565 (PLPRCR_val(PDF)+1) / (1<<PLPRCR_val(S)); 566 } else { 567 factor = PLPRCR_val(MF)+1; 568 } 569 570 oscclk = gd->cpu_clk / factor; 571 572 if ((immap->im_clkrst.car_sccr & SCCR_RTSEL) == 0 || factor > 2) { 573 return (oscclk / 4); 574 } 575 return (oscclk / 16); 576 } 577 578 /* ------------------------------------------------------------------------- */ 579 580 #if defined(CONFIG_WATCHDOG) 581 void watchdog_reset (void) 582 { 583 int re_enable = disable_interrupts (); 584 585 reset_8xx_watchdog ((immap_t *) CONFIG_SYS_IMMR); 586 if (re_enable) 587 enable_interrupts (); 588 } 589 #endif /* CONFIG_WATCHDOG */ 590 591 #if defined(CONFIG_WATCHDOG) || defined(CONFIG_LWMON) 592 593 void reset_8xx_watchdog (volatile immap_t * immr) 594 { 595 # if defined(CONFIG_LWMON) 596 /* 597 * The LWMON board uses a MAX6301 Watchdog 598 * with the trigger pin connected to port PA.7 599 * 600 * (The old board version used a MAX706TESA Watchdog, which 601 * had to be handled exactly the same.) 602 */ 603 # define WATCHDOG_BIT 0x0100 604 immr->im_ioport.iop_papar &= ~(WATCHDOG_BIT); /* GPIO */ 605 immr->im_ioport.iop_padir |= WATCHDOG_BIT; /* Output */ 606 immr->im_ioport.iop_paodr &= ~(WATCHDOG_BIT); /* active output */ 607 608 immr->im_ioport.iop_padat ^= WATCHDOG_BIT; /* Toggle WDI */ 609 # elif defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X) 610 /* 611 * The KUP4 boards uses a TPS3705 Watchdog 612 * with the trigger pin connected to port PA.5 613 */ 614 # define WATCHDOG_BIT 0x0400 615 immr->im_ioport.iop_papar &= ~(WATCHDOG_BIT); /* GPIO */ 616 immr->im_ioport.iop_padir |= WATCHDOG_BIT; /* Output */ 617 immr->im_ioport.iop_paodr &= ~(WATCHDOG_BIT); /* active output */ 618 619 immr->im_ioport.iop_padat ^= WATCHDOG_BIT; /* Toggle WDI */ 620 # else 621 /* 622 * All other boards use the MPC8xx Internal Watchdog 623 */ 624 immr->im_siu_conf.sc_swsr = 0x556c; /* write magic1 */ 625 immr->im_siu_conf.sc_swsr = 0xaa39; /* write magic2 */ 626 # endif /* CONFIG_LWMON */ 627 } 628 #endif /* CONFIG_WATCHDOG */ 629 630 /* 631 * Initializes on-chip ethernet controllers. 632 * to override, implement board_eth_init() 633 */ 634 int cpu_eth_init(bd_t *bis) 635 { 636 #if defined(SCC_ENET) && defined(CONFIG_CMD_NET) 637 scc_initialize(bis); 638 #endif 639 #if defined(FEC_ENET) 640 fec_initialize(bis); 641 #endif 642 return 0; 643 } 644