1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2006,2009-2010 Freescale Semiconductor, Inc.
3*4882a593Smuzhiyun * Jeff Brown
4*4882a593Smuzhiyun * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <common.h>
10*4882a593Smuzhiyun #include <watchdog.h>
11*4882a593Smuzhiyun #include <command.h>
12*4882a593Smuzhiyun #include <asm/cache.h>
13*4882a593Smuzhiyun #include <asm/mmu.h>
14*4882a593Smuzhiyun #include <mpc86xx.h>
15*4882a593Smuzhiyun #include <asm/fsl_law.h>
16*4882a593Smuzhiyun #include <asm/ppc.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /*
21*4882a593Smuzhiyun * Default board reset function
22*4882a593Smuzhiyun */
23*4882a593Smuzhiyun static void
__board_reset(void)24*4882a593Smuzhiyun __board_reset(void)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun /* Do nothing */
27*4882a593Smuzhiyun }
28*4882a593Smuzhiyun void board_reset(void) __attribute__((weak, alias("__board_reset")));
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun int
checkcpu(void)32*4882a593Smuzhiyun checkcpu(void)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun sys_info_t sysinfo;
35*4882a593Smuzhiyun uint pvr, svr;
36*4882a593Smuzhiyun uint major, minor;
37*4882a593Smuzhiyun char buf1[32], buf2[32];
38*4882a593Smuzhiyun volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
39*4882a593Smuzhiyun volatile ccsr_gur_t *gur = &immap->im_gur;
40*4882a593Smuzhiyun struct cpu_type *cpu;
41*4882a593Smuzhiyun uint msscr0 = mfspr(MSSCR0);
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun svr = get_svr();
44*4882a593Smuzhiyun major = SVR_MAJ(svr);
45*4882a593Smuzhiyun minor = SVR_MIN(svr);
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun if (cpu_numcores() > 1) {
48*4882a593Smuzhiyun #ifndef CONFIG_MP
49*4882a593Smuzhiyun puts("Unicore software on multiprocessor system!!\n"
50*4882a593Smuzhiyun "To enable mutlticore build define CONFIG_MP\n");
51*4882a593Smuzhiyun #endif
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun puts("CPU: ");
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun cpu = gd->arch.cpu;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun puts(cpu->name);
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
60*4882a593Smuzhiyun puts("Core: ");
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun pvr = get_pvr();
63*4882a593Smuzhiyun major = PVR_E600_MAJ(pvr);
64*4882a593Smuzhiyun minor = PVR_E600_MIN(pvr);
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun printf("e600 Core %d", (msscr0 & 0x20) ? 1 : 0);
67*4882a593Smuzhiyun if (gur->pordevsr & MPC86xx_PORDEVSR_CORE1TE)
68*4882a593Smuzhiyun puts("\n Core1Translation Enabled");
69*4882a593Smuzhiyun debug(" (MSSCR0=%x, PORDEVSR=%x)", msscr0, gur->pordevsr);
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun get_sys_info(&sysinfo);
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun puts("Clock Configuration:\n");
76*4882a593Smuzhiyun printf(" CPU:%-4s MHz, ", strmhz(buf1, sysinfo.freq_processor));
77*4882a593Smuzhiyun printf("MPX:%-4s MHz\n", strmhz(buf1, sysinfo.freq_systembus));
78*4882a593Smuzhiyun printf(" DDR:%-4s MHz (%s MT/s data rate), ",
79*4882a593Smuzhiyun strmhz(buf1, sysinfo.freq_systembus / 2),
80*4882a593Smuzhiyun strmhz(buf2, sysinfo.freq_systembus));
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun if (sysinfo.freq_localbus > LCRR_CLKDIV) {
83*4882a593Smuzhiyun printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freq_localbus));
84*4882a593Smuzhiyun } else {
85*4882a593Smuzhiyun printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n",
86*4882a593Smuzhiyun sysinfo.freq_localbus);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun puts("L1: D-cache 32 KiB enabled\n");
90*4882a593Smuzhiyun puts(" I-cache 32 KiB enabled\n");
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun puts("L2: ");
93*4882a593Smuzhiyun if (get_l2cr() & 0x80000000) {
94*4882a593Smuzhiyun #if defined(CONFIG_ARCH_MPC8610)
95*4882a593Smuzhiyun puts("256");
96*4882a593Smuzhiyun #elif defined(CONFIG_ARCH_MPC8641)
97*4882a593Smuzhiyun puts("512");
98*4882a593Smuzhiyun #endif
99*4882a593Smuzhiyun puts(" KiB enabled\n");
100*4882a593Smuzhiyun } else {
101*4882a593Smuzhiyun puts("Disabled\n");
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun return 0;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun
do_reset(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])108*4882a593Smuzhiyun int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
111*4882a593Smuzhiyun volatile ccsr_gur_t *gur = &immap->im_gur;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /* Attempt board-specific reset */
114*4882a593Smuzhiyun board_reset();
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /* Next try asserting HRESET_REQ */
117*4882a593Smuzhiyun out_be32(&gur->rstcr, MPC86xx_RSTCR_HRST_REQ);
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun while (1)
120*4882a593Smuzhiyun ;
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun return 1;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun /*
127*4882a593Smuzhiyun * Get timebase clock frequency
128*4882a593Smuzhiyun */
129*4882a593Smuzhiyun unsigned long
get_tbclk(void)130*4882a593Smuzhiyun get_tbclk(void)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun sys_info_t sys_info;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun get_sys_info(&sys_info);
135*4882a593Smuzhiyun return (sys_info.freq_systembus + 3L) / 4L;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun #if defined(CONFIG_WATCHDOG)
140*4882a593Smuzhiyun void
watchdog_reset(void)141*4882a593Smuzhiyun watchdog_reset(void)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun #if defined(CONFIG_ARCH_MPC8610)
144*4882a593Smuzhiyun /*
145*4882a593Smuzhiyun * This actually feed the hard enabled watchdog.
146*4882a593Smuzhiyun */
147*4882a593Smuzhiyun volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
148*4882a593Smuzhiyun volatile ccsr_wdt_t *wdt = &immap->im_wdt;
149*4882a593Smuzhiyun volatile ccsr_gur_t *gur = &immap->im_gur;
150*4882a593Smuzhiyun u32 tmp = gur->pordevsr;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun if (tmp & 0x4000) {
153*4882a593Smuzhiyun wdt->swsrr = 0x556c;
154*4882a593Smuzhiyun wdt->swsrr = 0xaa39;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun #endif
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun #endif /* CONFIG_WATCHDOG */
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun /*
161*4882a593Smuzhiyun * Print out the state of various machine registers.
162*4882a593Smuzhiyun * Currently prints out LAWs, BR0/OR0, and BATs
163*4882a593Smuzhiyun */
print_reginfo(void)164*4882a593Smuzhiyun void print_reginfo(void)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun print_bats();
167*4882a593Smuzhiyun print_laws();
168*4882a593Smuzhiyun print_lbc_regs();
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun /*
172*4882a593Smuzhiyun * Set the DDR BATs to reflect the actual size of DDR.
173*4882a593Smuzhiyun *
174*4882a593Smuzhiyun * dram_size is the actual size of DDR, in bytes
175*4882a593Smuzhiyun *
176*4882a593Smuzhiyun * Note: we assume that CONFIG_MAX_MEM_MAPPED is 2G or smaller as we only
177*4882a593Smuzhiyun * are using a single BAT to cover DDR.
178*4882a593Smuzhiyun *
179*4882a593Smuzhiyun * If this is not true, (e.g. CONFIG_MAX_MEM_MAPPED is 2GB but HID0_XBSEN
180*4882a593Smuzhiyun * is not defined) then we might have a situation where U-Boot will attempt
181*4882a593Smuzhiyun * to relocated itself outside of the region mapped by DBAT0.
182*4882a593Smuzhiyun * This will cause a machine check.
183*4882a593Smuzhiyun *
184*4882a593Smuzhiyun * Currently we are limited to power of two sized DDR since we only use a
185*4882a593Smuzhiyun * single bat. If a non-power of two size is used that is less than
186*4882a593Smuzhiyun * CONFIG_MAX_MEM_MAPPED u-boot will crash.
187*4882a593Smuzhiyun *
188*4882a593Smuzhiyun */
setup_ddr_bat(phys_addr_t dram_size)189*4882a593Smuzhiyun void setup_ddr_bat(phys_addr_t dram_size)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun unsigned long batu, bl;
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun bl = TO_BATU_BL(min(dram_size, CONFIG_MAX_MEM_MAPPED));
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun if (BATU_SIZE(bl) != dram_size) {
196*4882a593Smuzhiyun u64 sz = (u64)dram_size - BATU_SIZE(bl);
197*4882a593Smuzhiyun print_size(sz, " left unmapped\n");
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun batu = bl | BATU_VS | BATU_VP;
201*4882a593Smuzhiyun write_bat(DBAT0, batu, CONFIG_SYS_DBAT0L);
202*4882a593Smuzhiyun write_bat(IBAT0, batu, CONFIG_SYS_IBAT0L);
203*4882a593Smuzhiyun }
204