]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/mips/lib/board.c
Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / arch / mips / lib / board.c
1 /*
2  * (C) Copyright 2003
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <command.h>
10 #include <malloc.h>
11 #include <serial.h>
12 #include <stdio_dev.h>
13 #include <version.h>
14 #include <net.h>
15 #include <environment.h>
16 #include <nand.h>
17 #include <onenand_uboot.h>
18 #include <spi.h>
19
20 #ifdef CONFIG_BITBANGMII
21 #include <miiphy.h>
22 #endif
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 ulong monitor_flash_len;
27
28 static char *failed = "*** failed ***\n";
29
30 int __board_early_init_f(void)
31 {
32         /*
33          * Nothing to do in this dummy implementation
34          */
35         return 0;
36 }
37 int board_early_init_f(void)
38         __attribute__((weak, alias("__board_early_init_f")));
39
40 static int init_func_ram(void)
41 {
42 #ifdef  CONFIG_BOARD_TYPES
43         int board_type = gd->board_type;
44 #else
45         int board_type = 0;     /* use dummy arg */
46 #endif
47         puts("DRAM:  ");
48
49         gd->ram_size = initdram(board_type);
50         if (gd->ram_size > 0) {
51                 print_size(gd->ram_size, "\n");
52                 return 0;
53         }
54         puts(failed);
55         return 1;
56 }
57
58 static int display_banner(void)
59 {
60
61         printf("\n\n%s\n\n", version_string);
62         return 0;
63 }
64
65 #ifndef CONFIG_SYS_NO_FLASH
66 static void display_flash_config(ulong size)
67 {
68         puts("Flash: ");
69         print_size(size, "\n");
70 }
71 #endif
72
73 static int init_baudrate(void)
74 {
75         gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
76         return 0;
77 }
78
79
80 /*
81  * Breath some life into the board...
82  *
83  * The first part of initialization is running from Flash memory;
84  * its main purpose is to initialize the RAM so that we
85  * can relocate the monitor code to RAM.
86  */
87
88 /*
89  * All attempts to come up with a "common" initialization sequence
90  * that works for all boards and architectures failed: some of the
91  * requirements are just _too_ different. To get rid of the resulting
92  * mess of board dependend #ifdef'ed code we now make the whole
93  * initialization sequence configurable to the user.
94  *
95  * The requirements for any new initalization function is simple: it
96  * receives a pointer to the "global data" structure as it's only
97  * argument, and returns an integer return code, where 0 means
98  * "continue" and != 0 means "fatal error, hang the system".
99  */
100 typedef int (init_fnc_t)(void);
101
102 init_fnc_t *init_sequence[] = {
103         board_early_init_f,
104         timer_init,
105         env_init,               /* initialize environment */
106         init_baudrate,          /* initialize baudrate settings */
107         serial_init,            /* serial communications setup */
108         console_init_f,
109         display_banner,         /* say that we are here */
110         checkboard,
111         init_func_ram,
112         NULL,
113 };
114
115
116 void board_init_f(ulong bootflag)
117 {
118         gd_t gd_data, *id;
119         bd_t *bd;
120         init_fnc_t **init_fnc_ptr;
121         ulong addr, addr_sp, len;
122         ulong *s;
123
124         /* Pointer is writable since we allocated a register for it.
125          */
126         gd = &gd_data;
127         /* compiler optimization barrier needed for GCC >= 3.4 */
128         __asm__ __volatile__("" : : : "memory");
129
130         memset((void *)gd, 0, sizeof(gd_t));
131
132         for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
133                 if ((*init_fnc_ptr)() != 0)
134                         hang();
135         }
136
137         /*
138          * Now that we have DRAM mapped and working, we can
139          * relocate the code and continue running from DRAM.
140          */
141         addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
142
143         /* We can reserve some RAM "on top" here.
144          */
145
146         /* round down to next 4 kB limit.
147          */
148         addr &= ~(4096 - 1);
149         debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
150
151         /* Reserve memory for U-Boot code, data & bss
152          * round down to next 16 kB limit
153          */
154         len = bss_end() - CONFIG_SYS_MONITOR_BASE;
155         addr -= len;
156         addr &= ~(16 * 1024 - 1);
157
158         debug("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
159
160          /* Reserve memory for malloc() arena.
161          */
162         addr_sp = addr - TOTAL_MALLOC_LEN;
163         debug("Reserving %dk for malloc() at: %08lx\n",
164                         TOTAL_MALLOC_LEN >> 10, addr_sp);
165
166         /*
167          * (permanently) allocate a Board Info struct
168          * and a permanent copy of the "global" data
169          */
170         addr_sp -= sizeof(bd_t);
171         bd = (bd_t *)addr_sp;
172         gd->bd = bd;
173         debug("Reserving %zu Bytes for Board Info at: %08lx\n",
174                         sizeof(bd_t), addr_sp);
175
176         addr_sp -= sizeof(gd_t);
177         id = (gd_t *)addr_sp;
178         debug("Reserving %zu Bytes for Global Data at: %08lx\n",
179                         sizeof(gd_t), addr_sp);
180
181         /* Reserve memory for boot params.
182          */
183         addr_sp -= CONFIG_SYS_BOOTPARAMS_LEN;
184         bd->bi_boot_params = addr_sp;
185         debug("Reserving %dk for boot params() at: %08lx\n",
186                         CONFIG_SYS_BOOTPARAMS_LEN >> 10, addr_sp);
187
188         /*
189          * Finally, we set up a new (bigger) stack.
190          *
191          * Leave some safety gap for SP, force alignment on 16 byte boundary
192          * Clear initial stack frame
193          */
194         addr_sp -= 16;
195         addr_sp &= ~0xF;
196         s = (ulong *)addr_sp;
197         *s-- = 0;
198         *s-- = 0;
199         addr_sp = (ulong)s;
200         debug("Stack Pointer at: %08lx\n", addr_sp);
201
202         /*
203          * Save local variables to board info struct
204          */
205         bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;        /* start of DRAM */
206         bd->bi_memsize  = gd->ram_size;         /* size of DRAM in bytes */
207
208         memcpy(id, (void *)gd, sizeof(gd_t));
209
210         relocate_code(addr_sp, id, addr);
211
212         /* NOTREACHED - relocate_code() does not return */
213 }
214
215 /*
216  * This is the next part if the initialization sequence: we are now
217  * running from RAM and have a "normal" C environment, i. e. global
218  * data can be written, BSS has been cleared, the stack size in not
219  * that critical any more, etc.
220  */
221
222 void board_init_r(gd_t *id, ulong dest_addr)
223 {
224 #ifndef CONFIG_SYS_NO_FLASH
225         ulong size;
226 #endif
227         bd_t *bd;
228
229         gd = id;
230         gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
231
232         debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
233
234         gd->reloc_off = dest_addr - CONFIG_SYS_MONITOR_BASE;
235
236         monitor_flash_len = image_copy_end() - dest_addr;
237
238         serial_initialize();
239
240         bd = gd->bd;
241
242         /* The Malloc area is immediately below the monitor copy in DRAM */
243         mem_malloc_init(CONFIG_SYS_MONITOR_BASE + gd->reloc_off -
244                         TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN);
245
246 #ifndef CONFIG_SYS_NO_FLASH
247         /* configure available FLASH banks */
248         size = flash_init();
249         display_flash_config(size);
250         bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
251         bd->bi_flashsize = size;
252
253 #if CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE
254         bd->bi_flashoffset = monitor_flash_len; /* reserved area for U-Boot */
255 #else
256         bd->bi_flashoffset = 0;
257 #endif
258 #else
259         bd->bi_flashstart = 0;
260         bd->bi_flashsize = 0;
261         bd->bi_flashoffset = 0;
262 #endif
263
264 #ifdef CONFIG_CMD_NAND
265         puts("NAND:  ");
266         nand_init();            /* go init the NAND */
267 #endif
268
269 #if defined(CONFIG_CMD_ONENAND)
270         onenand_init();
271 #endif
272
273         /* relocate environment function pointers etc. */
274         env_relocate();
275
276 #if defined(CONFIG_PCI)
277         /*
278          * Do pci configuration
279          */
280         pci_init();
281 #endif
282
283 /** leave this here (after malloc(), environment and PCI are working) **/
284         /* Initialize stdio devices */
285         stdio_init();
286
287         jumptable_init();
288
289         /* Initialize the console (after the relocation and devices init) */
290         console_init_r();
291 /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
292
293         /* Initialize from environment */
294         load_addr = getenv_ulong("loadaddr", 16, load_addr);
295
296 #ifdef CONFIG_CMD_SPI
297         puts("SPI:   ");
298         spi_init();             /* go init the SPI */
299         puts("ready\n");
300 #endif
301
302 #if defined(CONFIG_MISC_INIT_R)
303         /* miscellaneous platform dependent initialisations */
304         misc_init_r();
305 #endif
306
307 #ifdef CONFIG_BITBANGMII
308         bb_miiphy_init();
309 #endif
310 #if defined(CONFIG_CMD_NET)
311         puts("Net:   ");
312         eth_initialize(gd->bd);
313 #endif
314
315         /* main_loop() can return to retry autoboot, if so just run it again. */
316         for (;;)
317                 main_loop();
318
319         /* NOTREACHED - no way out of command loop except booting */
320 }