blob: 4c06a4866b1e28307bbc30b26edf6b299bae4339 [file] [log] [blame]
Macpaul Lin0d1f4742011-10-11 22:33:19 +00001/*
2 * (C) Copyright 2002-2006
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * Copyright (C) 2011 Andes Technology Corporation
6 * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
7 * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
8 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02009 * SPDX-License-Identifier: GPL-2.0+
Macpaul Lin0d1f4742011-10-11 22:33:19 +000010 */
11
12#include <common.h>
13#include <command.h>
14#include <malloc.h>
15#include <stdio_dev.h>
16#include <timestamp.h>
17#include <version.h>
18#include <net.h>
19#include <serial.h>
20#include <nand.h>
21#include <onenand_uboot.h>
22#include <mmc.h>
Kuan-Yu Kuob73752a2013-04-23 07:47:47 +000023#include <asm/sections.h>
Macpaul Lin0d1f4742011-10-11 22:33:19 +000024
25DECLARE_GLOBAL_DATA_PTR;
26
Heiko Schochere0e55bc2012-01-16 21:12:24 +000027#if defined(CONFIG_SYS_I2C)
28#include <i2c.h>
29#endif
30
Macpaul Lin0d1f4742011-10-11 22:33:19 +000031ulong monitor_flash_len;
32
33/*
34 * Init Utilities
35 */
36
37#if !defined(CONFIG_BAUDRATE)
38#define CONFIG_BAUDRATE 38400
39#endif
40static int init_baudrate(void)
41{
Macpaul Lin48260952011-10-24 16:43:17 +080042 gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
Macpaul Lin0d1f4742011-10-11 22:33:19 +000043 return 0;
44}
45
46/*
47 * WARNING: this code looks "cleaner" than the PowerPC version, but
48 * has the disadvantage that you either get nothing, or everything.
49 * On PowerPC, you might see "DRAM: " before the system hangs - which
50 * gives a simple yet clear indication which part of the
51 * initialization if failing.
52 */
53static int display_dram_config(void)
54{
55 int i;
56
57#ifdef DEBUG
58 puts("RAM Configuration:\n");
59
60 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
61 printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
62 print_size(gd->bd->bi_dram[i].size, "\n");
63 }
64#else
65 ulong size = 0;
66
67 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
68 size += gd->bd->bi_dram[i].size;
69
70 puts("DRAM: ");
71 print_size(size, "\n");
72#endif
73
74 return 0;
75}
76
77#ifndef CONFIG_SYS_NO_FLASH
78static void display_flash_config(ulong size)
79{
80 puts("Flash: ");
81 print_size(size, "\n");
82}
83#endif /* CONFIG_SYS_NO_FLASH */
84
85#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
86#include <pci.h>
87static int nds32_pci_init(void)
88{
89 pci_init();
90 return 0;
91}
92#endif /* CONFIG_CMD_PCI || CONFIG_PCI */
93
94#if defined(CONFIG_PMU) || defined(CONFIG_PCU)
Mike Frysinger1ab1e612012-08-06 13:46:37 +000095#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Macpaul Lin0d1f4742011-10-11 22:33:19 +000096static int pmu_init(void)
97{
98#if defined(CONFIG_FTPMU010_POWER)
99#ifdef __NDS32_N1213_43U1H__ /* AG101: internal definition in toolchain */
100 ftpmu010_sdram_clk_disable(CONFIG_SYS_FTPMU010_PDLLCR0_HCLKOUTDIS);
101 ftpmu010_mfpsr_select_dev(FTPMU010_MFPSR_AC97CLKSEL);
102 ftpmu010_sdramhtc_set(CONFIG_SYS_FTPMU010_SDRAMHTC);
103#endif /* __NDS32_N1213_43U1H__ */
104#endif
105 return 0;
106}
107#endif
Mike Frysinger1ab1e612012-08-06 13:46:37 +0000108#endif
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000109
110/*
111 * Breathe some life into the board...
112 *
113 * Initialize a serial port as console, and carry out some hardware
114 * tests.
115 *
116 * The first part of initialization is running from Flash memory;
117 * its main purpose is to initialize the RAM so that we
118 * can relocate the monitor code to RAM.
119 */
120
121/*
122 * All attempts to come up with a "common" initialization sequence
123 * that works for all boards and architectures failed: some of the
124 * requirements are just _too_ different. To get rid of the resulting
125 * mess of board dependent #ifdef'ed code we now make the whole
126 * initialization sequence configurable to the user.
127 *
128 * The requirements for any new initalization function is simple: it
129 * receives a pointer to the "global data" structure as it's only
130 * argument, and returns an integer return code, where 0 means
131 * "continue" and != 0 means "fatal error, hang the system".
132 */
133typedef int (init_fnc_t)(void);
134
135void __dram_init_banksize(void)
136{
137 gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
138 gd->bd->bi_dram[0].size = gd->ram_size;
139}
140void dram_init_banksize(void)
141 __attribute__((weak, alias("__dram_init_banksize")));
142
143init_fnc_t *init_sequence[] = {
144#if defined(CONFIG_ARCH_CPU_INIT)
145 arch_cpu_init, /* basic arch cpu dependent setup */
146#endif
147#if defined(CONFIG_PMU) || defined(CONFIG_PCU)
148#ifndef CONFIG_SKIP_LOWLEVEL_INIT
149 pmu_init,
150#endif
151#endif
152 board_init, /* basic board dependent setup */
153#if defined(CONFIG_USE_IRQ)
154 interrupt_init, /* set up exceptions */
155#endif
156 timer_init, /* initialize timer */
157 env_init, /* initialize environment */
158 init_baudrate, /* initialze baudrate settings */
159 serial_init, /* serial communications setup */
160 console_init_f, /* stage 1 init of console */
161#if defined(CONFIG_DISPLAY_BOARDINFO)
162 checkboard, /* display board info */
163#endif
Heiko Schochere0e55bc2012-01-16 21:12:24 +0000164#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000165 init_func_i2c,
166#endif
167 dram_init, /* configure available RAM banks */
168 display_dram_config,
169 NULL,
170};
171
172void board_init_f(ulong bootflag)
173{
174 bd_t *bd;
175 init_fnc_t **init_fnc_ptr;
176 gd_t *id;
177 ulong addr, addr_sp;
178
179 /* Pointer is writable since we allocated a register for it */
180 gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
181
182 memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
183
Simon Glassed70c8f2013-03-14 06:54:53 +0000184 gd->mon_len = (unsigned int)(&__bss_end) - (unsigned int)(&_start);
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000185
186 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
187 if ((*init_fnc_ptr)() != 0)
188 hang();
189 }
190
191 debug("monitor len: %08lX\n", gd->mon_len);
192 /*
193 * Ram is setup, size stored in gd !!
194 */
195 debug("ramsize: %08lX\n", gd->ram_size);
196
197 addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
198
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000199 /* round down to next 4 kB limit */
200 addr &= ~(4096 - 1);
201 debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
202
203#ifdef CONFIG_LCD
204#ifdef CONFIG_FB_ADDR
205 gd->fb_base = CONFIG_FB_ADDR;
206#else
207 /* reserve memory for LCD display (always full pages) */
208 addr = lcd_setmem(addr);
209 gd->fb_base = addr;
210#endif /* CONFIG_FB_ADDR */
211#endif /* CONFIG_LCD */
212
213 /*
214 * reserve memory for U-Boot code, data & bss
215 * round down to next 4 kB limit
216 */
217 addr -= gd->mon_len;
218 addr &= ~(4096 - 1);
219
220 debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
221
222 /*
223 * reserve memory for malloc() arena
224 */
225 addr_sp = addr - TOTAL_MALLOC_LEN;
226 debug("Reserving %dk for malloc() at: %08lx\n",
227 TOTAL_MALLOC_LEN >> 10, addr_sp);
228 /*
229 * (permanently) allocate a Board Info struct
230 * and a permanent copy of the "global" data
231 */
232 addr_sp -= GENERATED_BD_INFO_SIZE;
233 bd = (bd_t *) addr_sp;
234 gd->bd = bd;
235 memset((void *)bd, 0, GENERATED_BD_INFO_SIZE);
236 debug("Reserving %zu Bytes for Board Info at: %08lx\n",
237 GENERATED_BD_INFO_SIZE, addr_sp);
238
239 addr_sp -= GENERATED_GBL_DATA_SIZE;
240 id = (gd_t *) addr_sp;
241 debug("Reserving %zu Bytes for Global Data at: %08lx\n",
242 GENERATED_GBL_DATA_SIZE, addr_sp);
243
244 /* setup stackpointer for exeptions */
245 gd->irq_sp = addr_sp;
246#ifdef CONFIG_USE_IRQ
247 addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
248 debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
249 CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp);
250#endif
251 /* leave 3 words for abort-stack */
252 addr_sp -= 12;
253
254 /* 8-byte alignment for ABI compliance */
255 addr_sp &= ~0x07;
256 debug("New Stack Pointer is: %08lx\n", addr_sp);
257
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000258 /* Ram isn't board specific, so move it to board code ... */
259 dram_init_banksize();
260 display_dram_config(); /* and display it */
261
262 gd->relocaddr = addr;
263 gd->start_addr_sp = addr_sp;
264
265 gd->reloc_off = addr - _TEXT_BASE;
266
267 debug("relocation Offset is: %08lx\n", gd->reloc_off);
268 memcpy(id, (void *)gd, GENERATED_GBL_DATA_SIZE);
269
270 relocate_code(addr_sp, id, addr);
271
272 /* NOTREACHED - relocate_code() does not return */
273}
274
275/*
276 * This is the next part if the initialization sequence: we are now
277 * running from RAM and have a "normal" C environment, i. e. global
278 * data can be written, BSS has been cleared, the stack size in not
279 * that critical any more, etc.
280 */
281void board_init_r(gd_t *id, ulong dest_addr)
282{
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000283 bd_t *bd;
284 ulong malloc_start;
285
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000286 gd = id;
287 bd = gd->bd;
288
289 gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
290
Kuan-Yu Kuob73752a2013-04-23 07:47:47 +0000291 monitor_flash_len = (ulong)&_end - (ulong)&_start;
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000292 debug("monitor flash len: %08lX\n", monitor_flash_len);
293
294 board_init(); /* Setup chipselects */
295
296#if defined(CONFIG_NEEDS_MANUAL_RELOC)
297 /*
298 * We have to relocate the command table manually
299 */
Marek Vasut69c5e342012-10-12 10:27:04 +0000300 fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd),
301 ll_entry_count(cmd_tbl_t, cmd));
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000302#endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */
303
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000304 serial_initialize();
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000305
306 debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
307
308 /* The Malloc area is immediately below the monitor copy in DRAM */
309 malloc_start = dest_addr - TOTAL_MALLOC_LEN;
310 mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN);
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000311
312#ifndef CONFIG_SYS_NO_FLASH
313 /* configure available FLASH banks */
314 gd->bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
315 gd->bd->bi_flashsize = flash_init();
316 gd->bd->bi_flashoffset = CONFIG_SYS_FLASH_BASE + gd->bd->bi_flashsize;
317
318 if (gd->bd->bi_flashsize)
319 display_flash_config(gd->bd->bi_flashsize);
320#endif /* CONFIG_SYS_NO_FLASH */
321
322#if defined(CONFIG_CMD_NAND)
323 puts("NAND: ");
324 nand_init(); /* go init the NAND */
325#endif
326
Macpaul Linb381d912011-11-18 17:01:31 +0800327#if defined(CONFIG_CMD_IDE)
328 puts("IDE: ");
329 ide_init();
330#endif
331
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000332#ifdef CONFIG_GENERIC_MMC
333 puts("MMC: ");
334 mmc_initialize(gd->bd);
335#endif
336
Heiko Schochere0e55bc2012-01-16 21:12:24 +0000337#if defined(CONFIG_SYS_I2C_ADAPTERS)
338 i2c_reloc_fixup();
339#endif
340
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000341 /* initialize environment */
342 env_relocate();
343
344#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
Macpaul Line474e772011-11-25 17:14:51 +0800345 puts("PCI: ");
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000346 nds32_pci_init();
347#endif
348
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000349 stdio_init(); /* get the devices list going. */
350
351 jumptable_init();
352
353#if defined(CONFIG_API)
354 /* Initialize API */
355 api_init();
356#endif
357
358 console_init_r(); /* fully init console as a device */
359
360#if defined(CONFIG_ARCH_MISC_INIT)
361 /* miscellaneous arch dependent initialisations */
362 arch_misc_init();
363#endif
364#if defined(CONFIG_MISC_INIT_R)
365 /* miscellaneous platform dependent initialisations */
366 misc_init_r();
367#endif
368
369#if defined(CONFIG_USE_IRQ)
370 /* set up exceptions */
371 interrupt_init();
372 /* enable exceptions */
373 enable_interrupts();
374#endif
375
376 /* Initialize from environment */
Macpaul Lin48260952011-10-24 16:43:17 +0800377 load_addr = getenv_ulong("loadaddr", 16, load_addr);
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000378
Nobuhiro Iwamatsu4298c932012-04-17 16:41:14 +0000379#ifdef CONFIG_BOARD_LATE_INIT
Macpaul Lin0d1f4742011-10-11 22:33:19 +0000380 board_late_init();
381#endif
382
383#if defined(CONFIG_CMD_NET)
384 puts("Net: ");
385
386 eth_initialize(gd->bd);
387#if defined(CONFIG_RESET_PHY_R)
388 debug("Reset Ethernet PHY\n");
389 reset_phy();
390#endif
391#endif
392
393 /* main_loop() can return to retry autoboot, if so just run it again. */
394 for (;;)
395 main_loop();
396
397 /* NOTREACHED - no way out of command loop except booting */
398}