]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/board_r.c
Introduce generic post-relocation board_r.c
[karo-tx-uboot.git] / common / board_r.c
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 }