xref: /rk3399_rockchip-uboot/common/board_r.c (revision ea8c37da8eefbb5253b6c2990269f23abac3e97d)
1 /*
2  * Copyright (c) 2011 The Chromium OS Authors.
3  * (C) Copyright 2002-2006
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  *
6  * (C) Copyright 2002
7  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
8  * Marius Groeger <mgroeger@sysgo.de>
9  *
10  * See file CREDITS for list of people who contributed to this
11  * project.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License as
15  * published by the Free Software Foundation; either version 2 of
16  * the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26  * MA 02111-1307 USA
27  */
28 
29 #include <common.h>
30 #ifdef CONFIG_HAS_DATAFLASH
31 #include <dataflash.h>
32 #endif
33 #include <environment.h>
34 #include <fdtdec.h>
35 #include <initcall.h>
36 #include <logbuff.h>
37 #include <malloc.h>
38 #include <mmc.h>
39 #include <nand.h>
40 #include <onenand_uboot.h>
41 #include <serial.h>
42 #include <stdio_dev.h>
43 #include <asm/sections.h>
44 
45 DECLARE_GLOBAL_DATA_PTR;
46 
47 ulong monitor_flash_len;
48 
49 
50 static int initr_reloc(void)
51 {
52 	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
53 	bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
54 
55 	return 0;
56 }
57 
58 #ifdef CONFIG_ARM
59 /*
60  * Some of these functions are needed purely because the functions they
61  * call return void. If we change them to return 0, these stubs can go away.
62  */
63 static int initr_caches(void)
64 {
65 	/* Enable caches */
66 	enable_caches();
67 	return 0;
68 }
69 #endif
70 
71 static int initr_reloc_global_data(void)
72 {
73 #ifdef CONFIG_SYS_SYM_OFFSETS
74 	monitor_flash_len = _end_ofs;
75 #else
76 	monitor_flash_len = (ulong)&__init_end - gd->dest_addr;
77 #endif
78 }
79 
80 static int initr_serial(void)
81 {
82 	serial_initialize();
83 	return 0;
84 }
85 
86 #ifdef CONFIG_LOGBUFFER
87 unsigned long logbuffer_base(void)
88 {
89 	return gd->ram_top - LOGBUFF_LEN;
90 }
91 
92 static int initr_logbuffer(void)
93 {
94 	logbuff_init_ptrs();
95 	return 0;
96 }
97 #endif
98 
99 #ifdef CONFIG_POST
100 static int initr_post_backlog(void)
101 {
102 	post_output_backlog();
103 	return 0;
104 }
105 #endif
106 
107 static int initr_malloc(void)
108 {
109 	ulong malloc_start;
110 
111 	/* The malloc area is immediately below the monitor copy in DRAM */
112 	malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN;
113 	mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN);
114 	return 0;
115 }
116 
117 __weak int power_init_board(void)
118 {
119 	return 0;
120 }
121 
122 static int initr_announce(void)
123 {
124 	debug("Now running in RAM - U-Boot at: %08lx\n", gd->dest_addr);
125 	return 0;
126 }
127 
128 #if !defined(CONFIG_SYS_NO_FLASH)
129 static int initr_flash(void)
130 {
131 	ulong flash_size;
132 
133 	puts("Flash: ");
134 
135 	flash_size = flash_init();
136 	if (flash_size <= 0) {
137 		puts("*** failed ***\n");
138 		return -1;
139 	}
140 	print_size(flash_size, "");
141 #ifdef CONFIG_SYS_FLASH_CHECKSUM
142 	/*
143 	* Compute and print flash CRC if flashchecksum is set to 'y'
144 	*
145 	* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
146 	*/
147 	if (getenv_yesno("flashchecksum") == 1) {
148 		printf("  CRC: %08X", crc32(0,
149 			(const unsigned char *) CONFIG_SYS_FLASH_BASE,
150 			flash_size));
151 	}
152 #endif /* CONFIG_SYS_FLASH_CHECKSUM */
153 	putc('\n');
154 
155 	return 0;
156 }
157 #endif
158 
159 #ifdef CONFIG_CMD_NAND
160 /* go init the NAND */
161 int initr_nand(void)
162 {
163 	puts("NAND:  ");
164 	nand_init();
165 	return 0;
166 }
167 #endif
168 
169 #if defined(CONFIG_CMD_ONENAND)
170 /* go init the NAND */
171 int initr_onenand(void)
172 {
173 	puts("NAND:  ");
174 	onenand_init();
175 	return 0;
176 }
177 #endif
178 
179 #ifdef CONFIG_GENERIC_MMC
180 int initr_mmc(void)
181 {
182 	puts("MMC:   ");
183 	mmc_initialize(gd->bd);
184 	return 0;
185 }
186 #endif
187 
188 #ifdef CONFIG_HAS_DATAFLASH
189 int initr_dataflash(void)
190 {
191 	AT91F_DataflashInit();
192 	dataflash_print_info();
193 	return 0;
194 }
195 #endif
196 
197 /*
198  * Tell if it's OK to load the environment early in boot.
199  *
200  * If CONFIG_OF_CONFIG is defined, we'll check with the FDT to see
201  * if this is OK (defaulting to saying it's OK).
202  *
203  * NOTE: Loading the environment early can be a bad idea if security is
204  *       important, since no verification is done on the environment.
205  *
206  * @return 0 if environment should not be loaded, !=0 if it is ok to load
207  */
208 static int should_load_env(void)
209 {
210 #ifdef CONFIG_OF_CONTROL
211 	return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 1);
212 #elif defined CONFIG_DELAY_ENVIRONMENT
213 	return 0;
214 #else
215 	return 1;
216 #endif
217 }
218 
219 static int initr_env(void)
220 {
221 	/* initialize environment */
222 	if (should_load_env())
223 		env_relocate();
224 	else
225 		set_default_env(NULL);
226 
227 	/* Initialize from environment */
228 	load_addr = getenv_ulong("loadaddr", 16, load_addr);
229 	return 0;
230 }
231 
232 static int initr_jumptable(void)
233 {
234 	jumptable_init();
235 	return 0;
236 }
237 
238 #if defined(CONFIG_API)
239 static int initr_api(void)
240 {
241 	/* Initialize API */
242 	api_init();
243 	return 0;
244 }
245 #endif
246 
247 #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
248 static int show_model_r(void)
249 {
250 	/* Put this here so it appears on the LCD, now it is ready */
251 # ifdef CONFIG_OF_CONTROL
252 	const char *model;
253 
254 	model = (char *)fdt_getprop(gd->fdt_blob, 0, "model", NULL);
255 	printf("Model: %s\n", model ? model : "<unknown>");
256 # else
257 	checkboard();
258 # endif
259 }
260 #endif
261 
262 /* enable exceptions */
263 static int initr_enable_interrupts(void)
264 {
265 	enable_interrupts();
266 	return 0;
267 }
268 
269 #ifdef CONFIG_CMD_NET
270 static int initr_ethaddr(void)
271 {
272 
273 	return 0;
274 }
275 #endif /* CONFIG_CMD_NET */
276 
277 #ifdef CONFIG_BITBANGMII
278 static int initr_bbmii(void)
279 {
280 	bb_miiphy_init();
281 	return 0;
282 }
283 #endif
284 
285 #ifdef CONFIG_CMD_NET
286 static int initr_net(void)
287 {
288 	puts("Net:   ");
289 	eth_initialize(gd->bd);
290 #if defined(CONFIG_RESET_PHY_R)
291 	debug("Reset Ethernet PHY\n");
292 	reset_phy();
293 #endif
294 	return 0;
295 }
296 #endif
297 
298 #ifdef CONFIG_POST
299 static int initr_post(void)
300 {
301 	post_run(NULL, POST_RAM | post_bootmode_get(0));
302 	return 0;
303 }
304 #endif
305 
306 #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
307 /*
308  * Export available size of memory for Linux, taking into account the
309  * protected RAM at top of memory
310  */
311 int initr_mem(void)
312 {
313 	ulong pram = 0;
314 	char memsz[32];
315 
316 # ifdef CONFIG_PRAM
317 	pram = getenv_ulong("pram", 10, CONFIG_PRAM);
318 # endif
319 # if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
320 	/* Also take the logbuffer into account (pram is in kB) */
321 	pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
322 # endif
323 	sprintf(memsz, "%ldk", (gd->ram_size / 1024) - pram);
324 	setenv("mem", memsz);
325 }
326 #endif
327 
328 static int run_main_loop(void)
329 {
330 	/* main_loop() can return to retry autoboot, if so just run it again */
331 	for (;;)
332 		main_loop();
333 	return 0;
334 }
335 
336 /*
337  * Over time we hope to remove these functions with code fragments and
338  * stub funtcions, and instead call the relevant function directly.
339  *
340  * We also hope to remove most of the driver-related init and do it if/when
341  * the driver is later used.
342  */
343 init_fnc_t init_sequence_r[] = {
344 	initr_reloc,
345 #ifdef CONFIG_ARM
346 	initr_caches,
347 	board_init,	/* Setup chipselects */
348 #endif
349 	initr_reloc_global_data,
350 	initr_serial,
351 	initr_announce,
352 #ifdef CONFIG_LOGBUFFER
353 	initr_logbuffer,
354 #endif
355 #ifdef CONFIG_POST
356 	initr_post_backlog,
357 #endif
358 	initr_malloc,
359 #ifdef CONFIG_ARCH_EARLY_INIT_R
360 	arch_early_init_r,
361 #endif
362 	power_init_board,
363 #ifndef CONFIG_SYS_NO_FLASH
364 	initr_flash,
365 #endif
366 #ifdef CONFIG_CMD_NAND
367 	initr_nand,
368 #endif
369 #ifdef CONFIG_CMD_ONENAND
370 	initr_onenand,
371 #endif
372 #ifdef CONFIG_GENERIC_MMC
373 	initr_mmc,
374 #endif
375 #ifdef CONFIG_HAS_DATAFLASH
376 	initr_dataflash,
377 #endif
378 	initr_env,
379 	stdio_init,
380 	initr_jumptable,
381 #ifdef CONFIG_API
382 	initr_api,
383 #endif
384 	console_init_r,		/* fully init console as a device */
385 #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
386 	show_model_r,
387 #endif
388 #ifdef CONFIG_ARCH_MISC_INIT
389 	arch_misc_init,		/* miscellaneous arch-dependent init */
390 #endif
391 #ifdef CONFIG_MISC_INIT_R
392 	misc_init_r,		/* miscellaneous platform-dependent init */
393 #endif
394 	interrupt_init,
395 	initr_enable_interrupts,
396 #ifdef CONFIG_CMD_NET
397 	initr_ethaddr,
398 #endif
399 #ifdef CONFIG_BOARD_LATE_INIT
400 	board_late_init,
401 #endif
402 #ifdef CONFIG_BITBANGMII
403 	initr_bbmii,
404 #endif
405 #ifdef CONFIG_CMD_NET
406 	initr_net,
407 #endif
408 #ifdef CONFIG_POST
409 	initr_post,
410 #endif
411 	run_main_loop,
412 };
413 
414 void board_init_r(gd_t *new_gd, ulong dest_addr)
415 {
416 	gd = new_gd;
417 	if (initcall_run_list(init_sequence_r))
418 		hang();
419 
420 	/* NOTREACHED - run_main_loop() does not return */
421 	hang();
422 }
423