xref: /OK3568_Linux_fs/u-boot/arch/powerpc/cpu/mpc86xx/cpu.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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