]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/mips/lib/board.c
MIPS: move mips_io_port_base out of board.c
[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 #ifdef CONFIG_INCA_IP
107         incaip_set_cpuclk,      /* set cpu clock according to env. variable */
108 #endif
109         init_baudrate,          /* initialize baudrate settings */
110         serial_init,            /* serial communications setup */
111         console_init_f,
112         display_banner,         /* say that we are here */
113         checkboard,
114         init_func_ram,
115         NULL,
116 };
117
118
119 void board_init_f(ulong bootflag)
120 {
121         gd_t gd_data, *id;
122         bd_t *bd;
123         init_fnc_t **init_fnc_ptr;
124         ulong addr, addr_sp, len;
125         ulong *s;
126
127         /* Pointer is writable since we allocated a register for it.
128          */
129         gd = &gd_data;
130         /* compiler optimization barrier needed for GCC >= 3.4 */
131         __asm__ __volatile__("" : : : "memory");
132
133         memset((void *)gd, 0, sizeof(gd_t));
134
135         for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
136                 if ((*init_fnc_ptr)() != 0)
137                         hang();
138         }
139
140         /*
141          * Now that we have DRAM mapped and working, we can
142          * relocate the code and continue running from DRAM.
143          */
144         addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
145
146         /* We can reserve some RAM "on top" here.
147          */
148
149         /* round down to next 4 kB limit.
150          */
151         addr &= ~(4096 - 1);
152         debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
153
154         /* Reserve memory for U-Boot code, data & bss
155          * round down to next 16 kB limit
156          */
157         len = bss_end() - CONFIG_SYS_MONITOR_BASE;
158         addr -= len;
159         addr &= ~(16 * 1024 - 1);
160
161         debug("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
162
163          /* Reserve memory for malloc() arena.
164          */
165         addr_sp = addr - TOTAL_MALLOC_LEN;
166         debug("Reserving %dk for malloc() at: %08lx\n",
167                         TOTAL_MALLOC_LEN >> 10, addr_sp);
168
169         /*
170          * (permanently) allocate a Board Info struct
171          * and a permanent copy of the "global" data
172          */
173         addr_sp -= sizeof(bd_t);
174         bd = (bd_t *)addr_sp;
175         gd->bd = bd;
176         debug("Reserving %zu Bytes for Board Info at: %08lx\n",
177                         sizeof(bd_t), addr_sp);
178
179         addr_sp -= sizeof(gd_t);
180         id = (gd_t *)addr_sp;
181         debug("Reserving %zu Bytes for Global Data at: %08lx\n",
182                         sizeof(gd_t), addr_sp);
183
184         /* Reserve memory for boot params.
185          */
186         addr_sp -= CONFIG_SYS_BOOTPARAMS_LEN;
187         bd->bi_boot_params = addr_sp;
188         debug("Reserving %dk for boot params() at: %08lx\n",
189                         CONFIG_SYS_BOOTPARAMS_LEN >> 10, addr_sp);
190
191         /*
192          * Finally, we set up a new (bigger) stack.
193          *
194          * Leave some safety gap for SP, force alignment on 16 byte boundary
195          * Clear initial stack frame
196          */
197         addr_sp -= 16;
198         addr_sp &= ~0xF;
199         s = (ulong *)addr_sp;
200         *s-- = 0;
201         *s-- = 0;
202         addr_sp = (ulong)s;
203         debug("Stack Pointer at: %08lx\n", addr_sp);
204
205         /*
206          * Save local variables to board info struct
207          */
208         bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;        /* start of DRAM */
209         bd->bi_memsize  = gd->ram_size;         /* size of DRAM in bytes */
210         bd->bi_baudrate = gd->baudrate;         /* Console Baudrate */
211
212         memcpy(id, (void *)gd, sizeof(gd_t));
213
214         relocate_code(addr_sp, id, addr);
215
216         /* NOTREACHED - relocate_code() does not return */
217 }
218
219 /*
220  * This is the next part if the initialization sequence: we are now
221  * running from RAM and have a "normal" C environment, i. e. global
222  * data can be written, BSS has been cleared, the stack size in not
223  * that critical any more, etc.
224  */
225
226 void board_init_r(gd_t *id, ulong dest_addr)
227 {
228 #ifndef CONFIG_SYS_NO_FLASH
229         ulong size;
230 #endif
231         bd_t *bd;
232
233         gd = id;
234         gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
235
236         debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
237
238         gd->reloc_off = dest_addr - CONFIG_SYS_MONITOR_BASE;
239
240         monitor_flash_len = image_copy_end() - dest_addr;
241
242         serial_initialize();
243
244         bd = gd->bd;
245
246         /* The Malloc area is immediately below the monitor copy in DRAM */
247         mem_malloc_init(CONFIG_SYS_MONITOR_BASE + gd->reloc_off -
248                         TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN);
249
250 #ifndef CONFIG_SYS_NO_FLASH
251         /* configure available FLASH banks */
252         size = flash_init();
253         display_flash_config(size);
254         bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
255         bd->bi_flashsize = size;
256
257 #if CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE
258         bd->bi_flashoffset = monitor_flash_len; /* reserved area for U-Boot */
259 #else
260         bd->bi_flashoffset = 0;
261 #endif
262 #else
263         bd->bi_flashstart = 0;
264         bd->bi_flashsize = 0;
265         bd->bi_flashoffset = 0;
266 #endif
267
268 #ifdef CONFIG_CMD_NAND
269         puts("NAND:  ");
270         nand_init();            /* go init the NAND */
271 #endif
272
273 #if defined(CONFIG_CMD_ONENAND)
274         onenand_init();
275 #endif
276
277         /* relocate environment function pointers etc. */
278         env_relocate();
279
280 #if defined(CONFIG_PCI)
281         /*
282          * Do pci configuration
283          */
284         pci_init();
285 #endif
286
287 /** leave this here (after malloc(), environment and PCI are working) **/
288         /* Initialize stdio devices */
289         stdio_init();
290
291         jumptable_init();
292
293         /* Initialize the console (after the relocation and devices init) */
294         console_init_r();
295 /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
296
297         /* Initialize from environment */
298         load_addr = getenv_ulong("loadaddr", 16, load_addr);
299
300 #ifdef CONFIG_CMD_SPI
301         puts("SPI:   ");
302         spi_init();             /* go init the SPI */
303         puts("ready\n");
304 #endif
305
306 #if defined(CONFIG_MISC_INIT_R)
307         /* miscellaneous platform dependent initialisations */
308         misc_init_r();
309 #endif
310
311 #ifdef CONFIG_BITBANGMII
312         bb_miiphy_init();
313 #endif
314 #if defined(CONFIG_CMD_NET)
315         puts("Net:   ");
316         eth_initialize(gd->bd);
317 #endif
318
319         /* main_loop() can return to retry autoboot, if so just run it again. */
320         for (;;)
321                 main_loop();
322
323         /* NOTREACHED - no way out of command loop except booting */
324 }