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 print_size(checkicache(), " I-Cache "); 140 print_size(checkdcache(), " D-Cache"); 141 142 /* do we have a FEC (860T/P or 852/859/866/885)? */ 143 144 immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; 145 if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { 146 printf (" FEC present"); 147 } 148 149 if (!m) { 150 puts (cpu_warning); 151 } 152 153 putc ('\n'); 154 155 #ifdef DEBUG 156 if(clock != measure_gclk()) { 157 printf ("clock %ldHz != %dHz\n", clock, measure_gclk()); 158 } 159 #endif 160 161 return 0; 162 } 163 164 #elif defined(CONFIG_MPC862) 165 166 static int check_CPU (long clock, uint pvr, uint immr) 167 { 168 volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000); 169 uint k, m; 170 char buf[32]; 171 char pre = 'X'; 172 __maybe_unused char *mid = "xx"; 173 char *suf; 174 175 /* the highest 16 bits should be 0x0050 for a 8xx */ 176 177 if ((pvr >> 16) != 0x0050) 178 return -1; 179 180 k = (immr << 16) | 181 immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)]; 182 m = 0; 183 184 switch (k) { 185 186 /* this value is not documented anywhere */ 187 case 0x06000000: mid = "P"; suf = "0"; break; 188 case 0x06010001: mid = "P"; suf = "A"; m = 1; break; 189 case 0x07000003: mid = "P"; suf = "B"; m = 1; break; 190 default: suf = NULL; break; 191 } 192 193 #ifndef CONFIG_MPC857 194 if (suf) 195 printf ("%cPC862%sZPnn%s", pre, mid, suf); 196 else 197 printf ("unknown MPC862 (0x%08x)", k); 198 #else 199 if (suf) 200 printf ("%cPC857TZPnn%s", pre, suf); /* only 857T tested right now! */ 201 else 202 printf ("unknown MPC857 (0x%08x)", k); 203 #endif 204 205 printf(" at %s MHz: ", strmhz(buf, clock)); 206 207 print_size(checkicache(), " I-Cache "); 208 print_size(checkdcache(), " D-Cache"); 209 210 /* lets check and see if we're running on a 862T (or P?) */ 211 212 immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; 213 if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { 214 printf (" FEC present"); 215 } 216 217 if (!m) { 218 puts (cpu_warning); 219 } 220 221 putc ('\n'); 222 223 return 0; 224 } 225 226 #elif defined(CONFIG_MPC823) 227 228 static int check_CPU (long clock, uint pvr, uint immr) 229 { 230 volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000); 231 uint k, m; 232 char buf[32]; 233 char *suf; 234 235 /* the highest 16 bits should be 0x0050 for a 8xx */ 236 237 if ((pvr >> 16) != 0x0050) 238 return -1; 239 240 k = (immr << 16) | 241 in_be16(&immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)]); 242 m = 0; 243 244 switch (k) { 245 /* MPC823 */ 246 case 0x20000000: suf = "0"; break; 247 case 0x20010000: suf = "0.1"; break; 248 case 0x20020000: suf = "Z2/3"; break; 249 case 0x20020001: suf = "Z3"; break; 250 case 0x21000000: suf = "A"; break; 251 case 0x21010000: suf = "B"; m = 1; break; 252 case 0x21010001: suf = "B2"; m = 1; break; 253 /* MPC823E */ 254 case 0x24010000: suf = NULL; 255 puts ("PPC823EZTnnB2"); 256 m = 1; 257 break; 258 default: 259 suf = NULL; 260 printf ("unknown MPC823 (0x%08x)", k); 261 break; 262 } 263 if (suf) 264 printf ("PPC823ZTnn%s", suf); 265 266 printf(" at %s MHz: ", strmhz(buf, clock)); 267 268 print_size(checkicache(), " I-Cache "); 269 print_size(checkdcache(), " D-Cache"); 270 271 /* lets check and see if we're running on a 860T (or P?) */ 272 273 immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; 274 if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { 275 puts (" FEC present"); 276 } 277 278 if (!m) { 279 puts (cpu_warning); 280 } 281 282 putc ('\n'); 283 284 return 0; 285 } 286 287 #elif defined(CONFIG_MPC850) 288 289 static int check_CPU (long clock, uint pvr, uint immr) 290 { 291 volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000); 292 uint k, m; 293 char buf[32]; 294 295 /* the highest 16 bits should be 0x0050 for a 8xx */ 296 297 if ((pvr >> 16) != 0x0050) 298 return -1; 299 300 k = (immr << 16) | 301 immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)]; 302 m = 0; 303 304 switch (k) { 305 case 0x20020001: 306 printf ("XPC850xxZT"); 307 break; 308 case 0x21000065: 309 printf ("XPC850xxZTA"); 310 break; 311 case 0x21010067: 312 printf ("XPC850xxZTB"); 313 m = 1; 314 break; 315 case 0x21020068: 316 printf ("XPC850xxZTC"); 317 m = 1; 318 break; 319 default: 320 printf ("unknown MPC850 (0x%08x)", k); 321 } 322 printf(" at %s MHz: ", strmhz(buf, clock)); 323 324 print_size(checkicache(), " I-Cache "); 325 print_size(checkdcache(), " D-Cache"); 326 327 /* lets check and see if we're running on a 850T (or P?) */ 328 329 immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; 330 if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { 331 printf (" FEC present"); 332 } 333 334 if (!m) { 335 puts (cpu_warning); 336 } 337 338 putc ('\n'); 339 340 return 0; 341 } 342 #else 343 #error CPU undefined 344 #endif 345 /* ------------------------------------------------------------------------- */ 346 347 int checkcpu (void) 348 { 349 ulong clock = gd->cpu_clk; 350 uint immr = get_immr (0); /* Return full IMMR contents */ 351 uint pvr = get_pvr (); 352 353 puts ("CPU: "); 354 355 /* 850 has PARTNUM 20 */ 356 /* 801 has PARTNUM 10 */ 357 return check_CPU (clock, pvr, immr); 358 } 359 360 /* ------------------------------------------------------------------------- */ 361 /* L1 i-cache */ 362 /* the standard 860 has 128 sets of 16 bytes in 2 ways (= 4 kB) */ 363 /* the 860 P (plus) has 256 sets of 16 bytes in 4 ways (= 16 kB) */ 364 365 int checkicache (void) 366 { 367 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 368 volatile memctl8xx_t *memctl = &immap->im_memctl; 369 u32 cacheon = rd_ic_cst () & IDC_ENABLED; 370 371 #ifdef CONFIG_IP86x 372 u32 k = memctl->memc_br1 & ~0x00007fff; /* probe in flash memoryarea */ 373 #else 374 u32 k = memctl->memc_br0 & ~0x00007fff; /* probe in flash memoryarea */ 375 #endif 376 u32 m; 377 u32 lines = -1; 378 379 wr_ic_cst (IDC_UNALL); 380 wr_ic_cst (IDC_INVALL); 381 wr_ic_cst (IDC_DISABLE); 382 __asm__ volatile ("isync"); 383 384 while (!((m = rd_ic_cst ()) & IDC_CERR2)) { 385 wr_ic_adr (k); 386 wr_ic_cst (IDC_LDLCK); 387 __asm__ volatile ("isync"); 388 389 lines++; 390 k += 0x10; /* the number of bytes in a cacheline */ 391 } 392 393 wr_ic_cst (IDC_UNALL); 394 wr_ic_cst (IDC_INVALL); 395 396 if (cacheon) 397 wr_ic_cst (IDC_ENABLE); 398 else 399 wr_ic_cst (IDC_DISABLE); 400 401 __asm__ volatile ("isync"); 402 403 return lines << 4; 404 }; 405 406 /* ------------------------------------------------------------------------- */ 407 /* L1 d-cache */ 408 /* the standard 860 has 128 sets of 16 bytes in 2 ways (= 4 kB) */ 409 /* the 860 P (plus) has 256 sets of 16 bytes in 2 ways (= 8 kB) */ 410 /* call with cache disabled */ 411 412 int checkdcache (void) 413 { 414 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 415 volatile memctl8xx_t *memctl = &immap->im_memctl; 416 u32 cacheon = rd_dc_cst () & IDC_ENABLED; 417 418 #ifdef CONFIG_IP86x 419 u32 k = memctl->memc_br1 & ~0x00007fff; /* probe in flash memoryarea */ 420 #else 421 u32 k = memctl->memc_br0 & ~0x00007fff; /* probe in flash memoryarea */ 422 #endif 423 u32 m; 424 u32 lines = -1; 425 426 wr_dc_cst (IDC_UNALL); 427 wr_dc_cst (IDC_INVALL); 428 wr_dc_cst (IDC_DISABLE); 429 430 while (!((m = rd_dc_cst ()) & IDC_CERR2)) { 431 wr_dc_adr (k); 432 wr_dc_cst (IDC_LDLCK); 433 lines++; 434 k += 0x10; /* the number of bytes in a cacheline */ 435 } 436 437 wr_dc_cst (IDC_UNALL); 438 wr_dc_cst (IDC_INVALL); 439 440 if (cacheon) 441 wr_dc_cst (IDC_ENABLE); 442 else 443 wr_dc_cst (IDC_DISABLE); 444 445 return lines << 4; 446 }; 447 448 /* ------------------------------------------------------------------------- */ 449 450 void upmconfig (uint upm, uint * table, uint size) 451 { 452 uint i; 453 uint addr = 0; 454 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 455 volatile memctl8xx_t *memctl = &immap->im_memctl; 456 457 for (i = 0; i < size; i++) { 458 memctl->memc_mdr = table[i]; /* (16-15) */ 459 memctl->memc_mcr = addr | upm; /* (16-16) */ 460 addr++; 461 } 462 } 463 464 /* ------------------------------------------------------------------------- */ 465 466 #ifndef CONFIG_LWMON 467 468 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 469 { 470 ulong msr, addr; 471 472 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 473 474 immap->im_clkrst.car_plprcr |= PLPRCR_CSR; /* Checkstop Reset enable */ 475 476 /* Interrupts and MMU off */ 477 __asm__ volatile ("mtspr 81, 0"); 478 __asm__ volatile ("mfmsr %0":"=r" (msr)); 479 480 msr &= ~0x1030; 481 __asm__ volatile ("mtmsr %0"::"r" (msr)); 482 483 /* 484 * Trying to execute the next instruction at a non-existing address 485 * should cause a machine check, resulting in reset 486 */ 487 #ifdef CONFIG_SYS_RESET_ADDRESS 488 addr = CONFIG_SYS_RESET_ADDRESS; 489 #else 490 /* 491 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address, CONFIG_SYS_MONITOR_BASE 492 * - sizeof (ulong) is usually a valid address. Better pick an address 493 * known to be invalid on your system and assign it to CONFIG_SYS_RESET_ADDRESS. 494 * "(ulong)-1" used to be a good choice for many systems... 495 */ 496 addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong); 497 #endif 498 ((void (*)(void)) addr) (); 499 return 1; 500 } 501 502 #else /* CONFIG_LWMON */ 503 504 /* 505 * On the LWMON board, the MCLR reset input of the PIC's on the board 506 * uses a 47K/1n RC combination which has a 47us time constant. The 507 * low signal on the HRESET pin of the CPU is only 512 clocks = 8 us 508 * and thus too short to reset the external hardware. So we use the 509 * watchdog to reset the board. 510 */ 511 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 512 { 513 /* prevent triggering the watchdog */ 514 disable_interrupts (); 515 516 /* make sure the watchdog is running */ 517 reset_8xx_watchdog ((immap_t *) CONFIG_SYS_IMMR); 518 519 /* wait for watchdog reset */ 520 while (1) {}; 521 522 /* NOTREACHED */ 523 return 1; 524 } 525 526 #endif /* CONFIG_LWMON */ 527 528 /* ------------------------------------------------------------------------- */ 529 530 /* 531 * Get timebase clock frequency (like cpu_clk in Hz) 532 * 533 * See sections 14.2 and 14.6 of the User's Manual 534 */ 535 unsigned long get_tbclk (void) 536 { 537 uint immr = get_immr (0); /* Return full IMMR contents */ 538 volatile immap_t *immap = (volatile immap_t *)(immr & 0xFFFF0000); 539 ulong oscclk, factor, pll; 540 541 if (immap->im_clkrst.car_sccr & SCCR_TBS) { 542 return (gd->cpu_clk / 16); 543 } 544 545 pll = immap->im_clkrst.car_plprcr; 546 547 #define PLPRCR_val(a) ((pll & PLPRCR_ ## a ## _MSK) >> PLPRCR_ ## a ## _SHIFT) 548 549 /* 550 * For newer PQ1 chips (MPC866/87x/88x families), PLL multiplication 551 * factor is calculated as follows: 552 * 553 * MFN 554 * MFI + ------- 555 * MFD + 1 556 * factor = ----------------- 557 * (PDF + 1) * 2^S 558 * 559 * For older chips, it's just MF field of PLPRCR plus one. 560 */ 561 if ((immr & 0x0FFF) >= MPC8xx_NEW_CLK) { /* MPC866/87x/88x series */ 562 factor = (PLPRCR_val(MFI) + PLPRCR_val(MFN)/(PLPRCR_val(MFD)+1))/ 563 (PLPRCR_val(PDF)+1) / (1<<PLPRCR_val(S)); 564 } else { 565 factor = PLPRCR_val(MF)+1; 566 } 567 568 oscclk = gd->cpu_clk / factor; 569 570 if ((immap->im_clkrst.car_sccr & SCCR_RTSEL) == 0 || factor > 2) { 571 return (oscclk / 4); 572 } 573 return (oscclk / 16); 574 } 575 576 /* ------------------------------------------------------------------------- */ 577 578 #if defined(CONFIG_WATCHDOG) 579 void watchdog_reset (void) 580 { 581 int re_enable = disable_interrupts (); 582 583 reset_8xx_watchdog ((immap_t *) CONFIG_SYS_IMMR); 584 if (re_enable) 585 enable_interrupts (); 586 } 587 #endif /* CONFIG_WATCHDOG */ 588 589 #if defined(CONFIG_WATCHDOG) || defined(CONFIG_LWMON) 590 591 void reset_8xx_watchdog (volatile immap_t * immr) 592 { 593 # if defined(CONFIG_LWMON) 594 /* 595 * The LWMON board uses a MAX6301 Watchdog 596 * with the trigger pin connected to port PA.7 597 * 598 * (The old board version used a MAX706TESA Watchdog, which 599 * had to be handled exactly the same.) 600 */ 601 # define WATCHDOG_BIT 0x0100 602 immr->im_ioport.iop_papar &= ~(WATCHDOG_BIT); /* GPIO */ 603 immr->im_ioport.iop_padir |= WATCHDOG_BIT; /* Output */ 604 immr->im_ioport.iop_paodr &= ~(WATCHDOG_BIT); /* active output */ 605 606 immr->im_ioport.iop_padat ^= WATCHDOG_BIT; /* Toggle WDI */ 607 # elif defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X) 608 /* 609 * The KUP4 boards uses a TPS3705 Watchdog 610 * with the trigger pin connected to port PA.5 611 */ 612 # define WATCHDOG_BIT 0x0400 613 immr->im_ioport.iop_papar &= ~(WATCHDOG_BIT); /* GPIO */ 614 immr->im_ioport.iop_padir |= WATCHDOG_BIT; /* Output */ 615 immr->im_ioport.iop_paodr &= ~(WATCHDOG_BIT); /* active output */ 616 617 immr->im_ioport.iop_padat ^= WATCHDOG_BIT; /* Toggle WDI */ 618 # else 619 /* 620 * All other boards use the MPC8xx Internal Watchdog 621 */ 622 immr->im_siu_conf.sc_swsr = 0x556c; /* write magic1 */ 623 immr->im_siu_conf.sc_swsr = 0xaa39; /* write magic2 */ 624 # endif /* CONFIG_LWMON */ 625 } 626 #endif /* CONFIG_WATCHDOG */ 627 628 /* 629 * Initializes on-chip ethernet controllers. 630 * to override, implement board_eth_init() 631 */ 632 int cpu_eth_init(bd_t *bis) 633 { 634 #if defined(SCC_ENET) && defined(CONFIG_CMD_NET) 635 scc_initialize(bis); 636 #endif 637 #if defined(FEC_ENET) 638 fec_initialize(bis); 639 #endif 640 return 0; 641 } 642