1*a47a12beSStefan Roese /* 2*a47a12beSStefan Roese * Copyright 2004,2007-2009 Freescale Semiconductor, Inc. 3*a47a12beSStefan Roese * (C) Copyright 2002, 2003 Motorola Inc. 4*a47a12beSStefan Roese * Xianghua Xiao (X.Xiao@motorola.com) 5*a47a12beSStefan Roese * 6*a47a12beSStefan Roese * (C) Copyright 2000 7*a47a12beSStefan Roese * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 8*a47a12beSStefan Roese * 9*a47a12beSStefan Roese * See file CREDITS for list of people who contributed to this 10*a47a12beSStefan Roese * project. 11*a47a12beSStefan Roese * 12*a47a12beSStefan Roese * This program is free software; you can redistribute it and/or 13*a47a12beSStefan Roese * modify it under the terms of the GNU General Public License as 14*a47a12beSStefan Roese * published by the Free Software Foundation; either version 2 of 15*a47a12beSStefan Roese * the License, or (at your option) any later version. 16*a47a12beSStefan Roese * 17*a47a12beSStefan Roese * This program is distributed in the hope that it will be useful, 18*a47a12beSStefan Roese * but WITHOUT ANY WARRANTY; without even the implied warranty of 19*a47a12beSStefan Roese * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20*a47a12beSStefan Roese * GNU General Public License for more details. 21*a47a12beSStefan Roese * 22*a47a12beSStefan Roese * You should have received a copy of the GNU General Public License 23*a47a12beSStefan Roese * along with this program; if not, write to the Free Software 24*a47a12beSStefan Roese * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 25*a47a12beSStefan Roese * MA 02111-1307 USA 26*a47a12beSStefan Roese */ 27*a47a12beSStefan Roese 28*a47a12beSStefan Roese #include <config.h> 29*a47a12beSStefan Roese #include <common.h> 30*a47a12beSStefan Roese #include <watchdog.h> 31*a47a12beSStefan Roese #include <command.h> 32*a47a12beSStefan Roese #include <fsl_esdhc.h> 33*a47a12beSStefan Roese #include <asm/cache.h> 34*a47a12beSStefan Roese #include <asm/io.h> 35*a47a12beSStefan Roese 36*a47a12beSStefan Roese DECLARE_GLOBAL_DATA_PTR; 37*a47a12beSStefan Roese 38*a47a12beSStefan Roese int checkcpu (void) 39*a47a12beSStefan Roese { 40*a47a12beSStefan Roese sys_info_t sysinfo; 41*a47a12beSStefan Roese uint pvr, svr; 42*a47a12beSStefan Roese uint fam; 43*a47a12beSStefan Roese uint ver; 44*a47a12beSStefan Roese uint major, minor; 45*a47a12beSStefan Roese struct cpu_type *cpu; 46*a47a12beSStefan Roese char buf1[32], buf2[32]; 47*a47a12beSStefan Roese #ifdef CONFIG_DDR_CLK_FREQ 48*a47a12beSStefan Roese volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 49*a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET 50*a47a12beSStefan Roese u32 ddr_sync = ((gur->rcwsr[5]) & FSL_CORENET_RCWSR5_DDR_SYNC) 51*a47a12beSStefan Roese >> FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT; 52*a47a12beSStefan Roese #else 53*a47a12beSStefan Roese u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO) 54*a47a12beSStefan Roese >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; 55*a47a12beSStefan Roese #endif 56*a47a12beSStefan Roese #else 57*a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET 58*a47a12beSStefan Roese u32 ddr_sync = 0; 59*a47a12beSStefan Roese #else 60*a47a12beSStefan Roese u32 ddr_ratio = 0; 61*a47a12beSStefan Roese #endif 62*a47a12beSStefan Roese #endif /* CONFIG_DDR_CLK_FREQ */ 63*a47a12beSStefan Roese int i; 64*a47a12beSStefan Roese 65*a47a12beSStefan Roese svr = get_svr(); 66*a47a12beSStefan Roese major = SVR_MAJ(svr); 67*a47a12beSStefan Roese #ifdef CONFIG_MPC8536 68*a47a12beSStefan Roese major &= 0x7; /* the msb of this nibble is a mfg code */ 69*a47a12beSStefan Roese #endif 70*a47a12beSStefan Roese minor = SVR_MIN(svr); 71*a47a12beSStefan Roese 72*a47a12beSStefan Roese if (cpu_numcores() > 1) { 73*a47a12beSStefan Roese #ifndef CONFIG_MP 74*a47a12beSStefan Roese puts("Unicore software on multiprocessor system!!\n" 75*a47a12beSStefan Roese "To enable mutlticore build define CONFIG_MP\n"); 76*a47a12beSStefan Roese #endif 77*a47a12beSStefan Roese volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC85xx_PIC_ADDR); 78*a47a12beSStefan Roese printf("CPU%d: ", pic->whoami); 79*a47a12beSStefan Roese } else { 80*a47a12beSStefan Roese puts("CPU: "); 81*a47a12beSStefan Roese } 82*a47a12beSStefan Roese 83*a47a12beSStefan Roese cpu = gd->cpu; 84*a47a12beSStefan Roese 85*a47a12beSStefan Roese puts(cpu->name); 86*a47a12beSStefan Roese if (IS_E_PROCESSOR(svr)) 87*a47a12beSStefan Roese puts("E"); 88*a47a12beSStefan Roese 89*a47a12beSStefan Roese printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr); 90*a47a12beSStefan Roese 91*a47a12beSStefan Roese pvr = get_pvr(); 92*a47a12beSStefan Roese fam = PVR_FAM(pvr); 93*a47a12beSStefan Roese ver = PVR_VER(pvr); 94*a47a12beSStefan Roese major = PVR_MAJ(pvr); 95*a47a12beSStefan Roese minor = PVR_MIN(pvr); 96*a47a12beSStefan Roese 97*a47a12beSStefan Roese printf("Core: "); 98*a47a12beSStefan Roese switch (fam) { 99*a47a12beSStefan Roese case PVR_FAM(PVR_85xx): 100*a47a12beSStefan Roese puts("E500"); 101*a47a12beSStefan Roese break; 102*a47a12beSStefan Roese default: 103*a47a12beSStefan Roese puts("Unknown"); 104*a47a12beSStefan Roese break; 105*a47a12beSStefan Roese } 106*a47a12beSStefan Roese 107*a47a12beSStefan Roese if (PVR_MEM(pvr) == 0x03) 108*a47a12beSStefan Roese puts("MC"); 109*a47a12beSStefan Roese 110*a47a12beSStefan Roese printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr); 111*a47a12beSStefan Roese 112*a47a12beSStefan Roese get_sys_info(&sysinfo); 113*a47a12beSStefan Roese 114*a47a12beSStefan Roese puts("Clock Configuration:"); 115*a47a12beSStefan Roese for (i = 0; i < cpu_numcores(); i++) { 116*a47a12beSStefan Roese if (!(i & 3)) 117*a47a12beSStefan Roese printf ("\n "); 118*a47a12beSStefan Roese printf("CPU%d:%-4s MHz, ", 119*a47a12beSStefan Roese i,strmhz(buf1, sysinfo.freqProcessor[i])); 120*a47a12beSStefan Roese } 121*a47a12beSStefan Roese printf("\n CCB:%-4s MHz,\n", strmhz(buf1, sysinfo.freqSystemBus)); 122*a47a12beSStefan Roese 123*a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET 124*a47a12beSStefan Roese if (ddr_sync == 1) { 125*a47a12beSStefan Roese printf(" DDR:%-4s MHz (%s MT/s data rate) " 126*a47a12beSStefan Roese "(Synchronous), ", 127*a47a12beSStefan Roese strmhz(buf1, sysinfo.freqDDRBus/2), 128*a47a12beSStefan Roese strmhz(buf2, sysinfo.freqDDRBus)); 129*a47a12beSStefan Roese } else { 130*a47a12beSStefan Roese printf(" DDR:%-4s MHz (%s MT/s data rate) " 131*a47a12beSStefan Roese "(Asynchronous), ", 132*a47a12beSStefan Roese strmhz(buf1, sysinfo.freqDDRBus/2), 133*a47a12beSStefan Roese strmhz(buf2, sysinfo.freqDDRBus)); 134*a47a12beSStefan Roese } 135*a47a12beSStefan Roese #else 136*a47a12beSStefan Roese switch (ddr_ratio) { 137*a47a12beSStefan Roese case 0x0: 138*a47a12beSStefan Roese printf(" DDR:%-4s MHz (%s MT/s data rate), ", 139*a47a12beSStefan Roese strmhz(buf1, sysinfo.freqDDRBus/2), 140*a47a12beSStefan Roese strmhz(buf2, sysinfo.freqDDRBus)); 141*a47a12beSStefan Roese break; 142*a47a12beSStefan Roese case 0x7: 143*a47a12beSStefan Roese printf(" DDR:%-4s MHz (%s MT/s data rate) " 144*a47a12beSStefan Roese "(Synchronous), ", 145*a47a12beSStefan Roese strmhz(buf1, sysinfo.freqDDRBus/2), 146*a47a12beSStefan Roese strmhz(buf2, sysinfo.freqDDRBus)); 147*a47a12beSStefan Roese break; 148*a47a12beSStefan Roese default: 149*a47a12beSStefan Roese printf(" DDR:%-4s MHz (%s MT/s data rate) " 150*a47a12beSStefan Roese "(Asynchronous), ", 151*a47a12beSStefan Roese strmhz(buf1, sysinfo.freqDDRBus/2), 152*a47a12beSStefan Roese strmhz(buf2, sysinfo.freqDDRBus)); 153*a47a12beSStefan Roese break; 154*a47a12beSStefan Roese } 155*a47a12beSStefan Roese #endif 156*a47a12beSStefan Roese 157*a47a12beSStefan Roese if (sysinfo.freqLocalBus > LCRR_CLKDIV) { 158*a47a12beSStefan Roese printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freqLocalBus)); 159*a47a12beSStefan Roese } else { 160*a47a12beSStefan Roese printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n", 161*a47a12beSStefan Roese sysinfo.freqLocalBus); 162*a47a12beSStefan Roese } 163*a47a12beSStefan Roese 164*a47a12beSStefan Roese #ifdef CONFIG_CPM2 165*a47a12beSStefan Roese printf("CPM: %s MHz\n", strmhz(buf1, sysinfo.freqSystemBus)); 166*a47a12beSStefan Roese #endif 167*a47a12beSStefan Roese 168*a47a12beSStefan Roese #ifdef CONFIG_QE 169*a47a12beSStefan Roese printf(" QE:%-4s MHz\n", strmhz(buf1, sysinfo.freqQE)); 170*a47a12beSStefan Roese #endif 171*a47a12beSStefan Roese 172*a47a12beSStefan Roese #ifdef CONFIG_SYS_DPAA_FMAN 173*a47a12beSStefan Roese for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) { 174*a47a12beSStefan Roese printf(" FMAN%d: %s MHz\n", i, 175*a47a12beSStefan Roese strmhz(buf1, sysinfo.freqFMan[i])); 176*a47a12beSStefan Roese } 177*a47a12beSStefan Roese #endif 178*a47a12beSStefan Roese 179*a47a12beSStefan Roese #ifdef CONFIG_SYS_DPAA_PME 180*a47a12beSStefan Roese printf(" PME: %s MHz\n", strmhz(buf1, sysinfo.freqPME)); 181*a47a12beSStefan Roese #endif 182*a47a12beSStefan Roese 183*a47a12beSStefan Roese puts("L1: D-cache 32 kB enabled\n I-cache 32 kB enabled\n"); 184*a47a12beSStefan Roese 185*a47a12beSStefan Roese return 0; 186*a47a12beSStefan Roese } 187*a47a12beSStefan Roese 188*a47a12beSStefan Roese 189*a47a12beSStefan Roese /* ------------------------------------------------------------------------- */ 190*a47a12beSStefan Roese 191*a47a12beSStefan Roese int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) 192*a47a12beSStefan Roese { 193*a47a12beSStefan Roese /* Everything after the first generation of PQ3 parts has RSTCR */ 194*a47a12beSStefan Roese #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ 195*a47a12beSStefan Roese defined(CONFIG_MPC8555) || defined(CONFIG_MPC8560) 196*a47a12beSStefan Roese unsigned long val, msr; 197*a47a12beSStefan Roese 198*a47a12beSStefan Roese /* 199*a47a12beSStefan Roese * Initiate hard reset in debug control register DBCR0 200*a47a12beSStefan Roese * Make sure MSR[DE] = 1. This only resets the core. 201*a47a12beSStefan Roese */ 202*a47a12beSStefan Roese msr = mfmsr (); 203*a47a12beSStefan Roese msr |= MSR_DE; 204*a47a12beSStefan Roese mtmsr (msr); 205*a47a12beSStefan Roese 206*a47a12beSStefan Roese val = mfspr(DBCR0); 207*a47a12beSStefan Roese val |= 0x70000000; 208*a47a12beSStefan Roese mtspr(DBCR0,val); 209*a47a12beSStefan Roese #else 210*a47a12beSStefan Roese volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 211*a47a12beSStefan Roese out_be32(&gur->rstcr, 0x2); /* HRESET_REQ */ 212*a47a12beSStefan Roese udelay(100); 213*a47a12beSStefan Roese #endif 214*a47a12beSStefan Roese 215*a47a12beSStefan Roese return 1; 216*a47a12beSStefan Roese } 217*a47a12beSStefan Roese 218*a47a12beSStefan Roese 219*a47a12beSStefan Roese /* 220*a47a12beSStefan Roese * Get timebase clock frequency 221*a47a12beSStefan Roese */ 222*a47a12beSStefan Roese unsigned long get_tbclk (void) 223*a47a12beSStefan Roese { 224*a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET 225*a47a12beSStefan Roese return (gd->bus_clk + 8) / 16; 226*a47a12beSStefan Roese #else 227*a47a12beSStefan Roese return (gd->bus_clk + 4UL)/8UL; 228*a47a12beSStefan Roese #endif 229*a47a12beSStefan Roese } 230*a47a12beSStefan Roese 231*a47a12beSStefan Roese 232*a47a12beSStefan Roese #if defined(CONFIG_WATCHDOG) 233*a47a12beSStefan Roese void 234*a47a12beSStefan Roese watchdog_reset(void) 235*a47a12beSStefan Roese { 236*a47a12beSStefan Roese int re_enable = disable_interrupts(); 237*a47a12beSStefan Roese reset_85xx_watchdog(); 238*a47a12beSStefan Roese if (re_enable) enable_interrupts(); 239*a47a12beSStefan Roese } 240*a47a12beSStefan Roese 241*a47a12beSStefan Roese void 242*a47a12beSStefan Roese reset_85xx_watchdog(void) 243*a47a12beSStefan Roese { 244*a47a12beSStefan Roese /* 245*a47a12beSStefan Roese * Clear TSR(WIS) bit by writing 1 246*a47a12beSStefan Roese */ 247*a47a12beSStefan Roese unsigned long val; 248*a47a12beSStefan Roese val = mfspr(SPRN_TSR); 249*a47a12beSStefan Roese val |= TSR_WIS; 250*a47a12beSStefan Roese mtspr(SPRN_TSR, val); 251*a47a12beSStefan Roese } 252*a47a12beSStefan Roese #endif /* CONFIG_WATCHDOG */ 253*a47a12beSStefan Roese 254*a47a12beSStefan Roese /* 255*a47a12beSStefan Roese * Configures a UPM. The function requires the respective MxMR to be set 256*a47a12beSStefan Roese * before calling this function. "size" is the number or entries, not a sizeof. 257*a47a12beSStefan Roese */ 258*a47a12beSStefan Roese void upmconfig (uint upm, uint * table, uint size) 259*a47a12beSStefan Roese { 260*a47a12beSStefan Roese int i, mdr, mad, old_mad = 0; 261*a47a12beSStefan Roese volatile u32 *mxmr; 262*a47a12beSStefan Roese volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); 263*a47a12beSStefan Roese volatile u32 *brp,*orp; 264*a47a12beSStefan Roese volatile u8* dummy = NULL; 265*a47a12beSStefan Roese int upmmask; 266*a47a12beSStefan Roese 267*a47a12beSStefan Roese switch (upm) { 268*a47a12beSStefan Roese case UPMA: 269*a47a12beSStefan Roese mxmr = &lbc->mamr; 270*a47a12beSStefan Roese upmmask = BR_MS_UPMA; 271*a47a12beSStefan Roese break; 272*a47a12beSStefan Roese case UPMB: 273*a47a12beSStefan Roese mxmr = &lbc->mbmr; 274*a47a12beSStefan Roese upmmask = BR_MS_UPMB; 275*a47a12beSStefan Roese break; 276*a47a12beSStefan Roese case UPMC: 277*a47a12beSStefan Roese mxmr = &lbc->mcmr; 278*a47a12beSStefan Roese upmmask = BR_MS_UPMC; 279*a47a12beSStefan Roese break; 280*a47a12beSStefan Roese default: 281*a47a12beSStefan Roese printf("%s: Bad UPM index %d to configure\n", __FUNCTION__, upm); 282*a47a12beSStefan Roese hang(); 283*a47a12beSStefan Roese } 284*a47a12beSStefan Roese 285*a47a12beSStefan Roese /* Find the address for the dummy write transaction */ 286*a47a12beSStefan Roese for (brp = &lbc->br0, orp = &lbc->or0, i = 0; i < 8; 287*a47a12beSStefan Roese i++, brp += 2, orp += 2) { 288*a47a12beSStefan Roese 289*a47a12beSStefan Roese /* Look for a valid BR with selected UPM */ 290*a47a12beSStefan Roese if ((in_be32(brp) & (BR_V | BR_MSEL)) == (BR_V | upmmask)) { 291*a47a12beSStefan Roese dummy = (volatile u8*)(in_be32(brp) & BR_BA); 292*a47a12beSStefan Roese break; 293*a47a12beSStefan Roese } 294*a47a12beSStefan Roese } 295*a47a12beSStefan Roese 296*a47a12beSStefan Roese if (i == 8) { 297*a47a12beSStefan Roese printf("Error: %s() could not find matching BR\n", __FUNCTION__); 298*a47a12beSStefan Roese hang(); 299*a47a12beSStefan Roese } 300*a47a12beSStefan Roese 301*a47a12beSStefan Roese for (i = 0; i < size; i++) { 302*a47a12beSStefan Roese /* 1 */ 303*a47a12beSStefan Roese out_be32(mxmr, (in_be32(mxmr) & 0x4fffffc0) | MxMR_OP_WARR | i); 304*a47a12beSStefan Roese /* 2 */ 305*a47a12beSStefan Roese out_be32(&lbc->mdr, table[i]); 306*a47a12beSStefan Roese /* 3 */ 307*a47a12beSStefan Roese mdr = in_be32(&lbc->mdr); 308*a47a12beSStefan Roese /* 4 */ 309*a47a12beSStefan Roese *(volatile u8 *)dummy = 0; 310*a47a12beSStefan Roese /* 5 */ 311*a47a12beSStefan Roese do { 312*a47a12beSStefan Roese mad = in_be32(mxmr) & MxMR_MAD_MSK; 313*a47a12beSStefan Roese } while (mad <= old_mad && !(!mad && i == (size-1))); 314*a47a12beSStefan Roese old_mad = mad; 315*a47a12beSStefan Roese } 316*a47a12beSStefan Roese out_be32(mxmr, (in_be32(mxmr) & 0x4fffffc0) | MxMR_OP_NORM); 317*a47a12beSStefan Roese } 318*a47a12beSStefan Roese 319*a47a12beSStefan Roese /* 320*a47a12beSStefan Roese * Initializes on-chip MMC controllers. 321*a47a12beSStefan Roese * to override, implement board_mmc_init() 322*a47a12beSStefan Roese */ 323*a47a12beSStefan Roese int cpu_mmc_init(bd_t *bis) 324*a47a12beSStefan Roese { 325*a47a12beSStefan Roese #ifdef CONFIG_FSL_ESDHC 326*a47a12beSStefan Roese return fsl_esdhc_mmc_init(bis); 327*a47a12beSStefan Roese #else 328*a47a12beSStefan Roese return 0; 329*a47a12beSStefan Roese #endif 330*a47a12beSStefan Roese } 331