]>
Commit | Line | Data |
---|---|---|
6cb142fa WD |
1 | /* |
2 | * U-boot - board.c First C file to be called contains init routines | |
3 | * | |
155fd766 | 4 | * Copyright (c) 2005-2007 Analog Devices Inc. |
6cb142fa WD |
5 | * |
6 | * (C) Copyright 2000-2004 | |
7 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
8 | * | |
9 | * See file CREDITS for list of people who contributed to this | |
10 | * project. | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or | |
13 | * modify it under the terms of the GNU General Public License as | |
14 | * published by the Free Software Foundation; either version 2 of | |
15 | * the License, or (at your option) any later version. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, | |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU General Public License for more details. | |
21 | * | |
22 | * You should have received a copy of the GNU General Public License | |
23 | * along with this program; if not, write to the Free Software | |
155fd766 AL |
24 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
25 | * MA 02110-1301 USA | |
6cb142fa WD |
26 | */ |
27 | ||
28 | #include <common.h> | |
29 | #include <command.h> | |
30 | #include <malloc.h> | |
31 | #include <devices.h> | |
32 | #include <version.h> | |
33 | #include <net.h> | |
34 | #include <environment.h> | |
3f0606ad | 35 | #include <i2c.h> |
6cb142fa | 36 | #include "blackfin_board.h" |
3f0606ad | 37 | #include <asm/cplb.h> |
2439e4bf | 38 | #include "../drivers/net/smc91111.h" |
6cb142fa | 39 | |
9171fc81 | 40 | #if defined(CONFIG_POST) |
3f0606ad AL |
41 | #include <post.h> |
42 | int post_flag; | |
43 | #endif | |
d87080b7 | 44 | |
1218abf1 WD |
45 | DECLARE_GLOBAL_DATA_PTR; |
46 | ||
3f0606ad | 47 | #ifndef CFG_NO_FLASH |
6cb142fa | 48 | extern flash_info_t flash_info[]; |
3f0606ad | 49 | #endif |
6cb142fa | 50 | |
3f0606ad AL |
51 | static inline u_long get_vco(void) |
52 | { | |
53 | u_long msel; | |
54 | u_long vco; | |
55 | ||
56 | msel = (*pPLL_CTL >> 9) & 0x3F; | |
57 | if (0 == msel) | |
58 | msel = 64; | |
59 | ||
60 | vco = CONFIG_CLKIN_HZ; | |
61 | vco >>= (1 & *pPLL_CTL); /* DF bit */ | |
62 | vco = msel * vco; | |
63 | return vco; | |
64 | } | |
65 | ||
66 | /*Get the Core clock*/ | |
67 | u_long get_cclk(void) | |
68 | { | |
69 | u_long csel, ssel; | |
70 | if (*pPLL_STAT & 0x1) | |
71 | return CONFIG_CLKIN_HZ; | |
72 | ||
73 | ssel = *pPLL_DIV; | |
74 | csel = ((ssel >> 4) & 0x03); | |
75 | ssel &= 0xf; | |
76 | if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ | |
77 | return get_vco() / ssel; | |
78 | return get_vco() >> csel; | |
79 | } | |
80 | ||
81 | /* Get the System clock */ | |
82 | u_long get_sclk(void) | |
83 | { | |
84 | u_long ssel; | |
85 | ||
86 | if (*pPLL_STAT & 0x1) | |
87 | return CONFIG_CLKIN_HZ; | |
88 | ||
89 | ssel = (*pPLL_DIV & 0xf); | |
90 | ||
91 | return get_vco() / ssel; | |
92 | } | |
6cb142fa WD |
93 | |
94 | static void mem_malloc_init(void) | |
95 | { | |
96 | mem_malloc_start = CFG_MALLOC_BASE; | |
97 | mem_malloc_end = (CFG_MALLOC_BASE + CFG_MALLOC_LEN); | |
98 | mem_malloc_brk = mem_malloc_start; | |
3f0606ad | 99 | memset((void *)mem_malloc_start, 0, mem_malloc_end - mem_malloc_start); |
6cb142fa WD |
100 | } |
101 | ||
102 | void *sbrk(ptrdiff_t increment) | |
103 | { | |
104 | ulong old = mem_malloc_brk; | |
105 | ulong new = old + increment; | |
106 | ||
107 | if ((new < mem_malloc_start) || (new > mem_malloc_end)) { | |
108 | return (NULL); | |
109 | } | |
110 | mem_malloc_brk = new; | |
111 | ||
3f0606ad | 112 | return ((void *)old); |
6cb142fa WD |
113 | } |
114 | ||
115 | static int display_banner(void) | |
116 | { | |
117 | sprintf(version_string, VERSION_STRING_FORMAT, VERSION_STRING); | |
118 | printf("%s\n", version_string); | |
f7ce12cb | 119 | printf("CPU: ADSP " MK_STR(CONFIG_BFIN_CPU) " (Detected Rev: 0.%d)\n", bfin_revid()); |
6cb142fa WD |
120 | return (0); |
121 | } | |
122 | ||
123 | static void display_flash_config(ulong size) | |
124 | { | |
125 | puts("FLASH: "); | |
126 | print_size(size, "\n"); | |
127 | return; | |
128 | } | |
129 | ||
130 | static int init_baudrate(void) | |
131 | { | |
3f0606ad | 132 | char tmp[64]; |
6cb142fa WD |
133 | int i = getenv_r("baudrate", tmp, sizeof(tmp)); |
134 | gd->bd->bi_baudrate = gd->baudrate = (i > 0) | |
3f0606ad AL |
135 | ? (int)simple_strtoul(tmp, NULL, 10) |
136 | : CONFIG_BAUDRATE; | |
6cb142fa WD |
137 | return (0); |
138 | } | |
139 | ||
140 | #ifdef DEBUG | |
141 | static void display_global_data(void) | |
142 | { | |
6cb142fa WD |
143 | bd_t *bd; |
144 | bd = gd->bd; | |
145 | printf("--flags:%x\n", gd->flags); | |
146 | printf("--board_type:%x\n", gd->board_type); | |
147 | printf("--baudrate:%x\n", gd->baudrate); | |
148 | printf("--have_console:%x\n", gd->have_console); | |
149 | printf("--ram_size:%x\n", gd->ram_size); | |
150 | printf("--reloc_off:%x\n", gd->reloc_off); | |
151 | printf("--env_addr:%x\n", gd->env_addr); | |
152 | printf("--env_valid:%x\n", gd->env_valid); | |
153 | printf("--bd:%x %x\n", gd->bd, bd); | |
154 | printf("---bi_baudrate:%x\n", bd->bi_baudrate); | |
155 | printf("---bi_ip_addr:%x\n", bd->bi_ip_addr); | |
156 | printf("---bi_enetaddr:%x %x %x %x %x %x\n", | |
3f0606ad AL |
157 | bd->bi_enetaddr[0], |
158 | bd->bi_enetaddr[1], | |
159 | bd->bi_enetaddr[2], | |
160 | bd->bi_enetaddr[3], bd->bi_enetaddr[4], bd->bi_enetaddr[5]); | |
6cb142fa WD |
161 | printf("---bi_arch_number:%x\n", bd->bi_arch_number); |
162 | printf("---bi_boot_params:%x\n", bd->bi_boot_params); | |
163 | printf("---bi_memstart:%x\n", bd->bi_memstart); | |
164 | printf("---bi_memsize:%x\n", bd->bi_memsize); | |
165 | printf("---bi_flashstart:%x\n", bd->bi_flashstart); | |
166 | printf("---bi_flashsize:%x\n", bd->bi_flashsize); | |
167 | printf("---bi_flashoffset:%x\n", bd->bi_flashoffset); | |
168 | printf("--jt:%x *:%x\n", gd->jt, *(gd->jt)); | |
169 | } | |
170 | #endif | |
171 | ||
3f0606ad AL |
172 | /* we cover everything with 4 meg pages, and need an extra for L1 */ |
173 | unsigned int icplb_table[page_descriptor_table_size][2]; | |
174 | unsigned int dcplb_table[page_descriptor_table_size][2]; | |
175 | ||
176 | void init_cplbtables(void) | |
177 | { | |
178 | int i, j; | |
179 | ||
180 | j = 0; | |
181 | icplb_table[j][0] = 0xFFA00000; | |
182 | icplb_table[j][1] = L1_IMEMORY; | |
183 | j++; | |
184 | ||
7b7e30aa | 185 | for (i = 0; i < CONFIG_MEM_SIZE / 4; i++) { |
3f0606ad AL |
186 | icplb_table[j][0] = (i * 4 * 1024 * 1024); |
187 | if (i * 4 * 1024 * 1024 <= CFG_MONITOR_BASE | |
188 | && (i + 1) * 4 * 1024 * 1024 >= CFG_MONITOR_BASE) { | |
189 | icplb_table[j][1] = SDRAM_IKERNEL; | |
190 | } else { | |
191 | icplb_table[j][1] = SDRAM_IGENERIC; | |
192 | } | |
193 | j++; | |
194 | } | |
3f0606ad | 195 | icplb_table[j][0] = 0x20000000; |
7b7e30aa | 196 | icplb_table[j][1] = SDRAM_INON_CHBL; |
3f0606ad AL |
197 | j = 0; |
198 | dcplb_table[j][0] = 0xFF800000; | |
199 | dcplb_table[j][1] = L1_DMEMORY; | |
200 | j++; | |
201 | ||
202 | for (i = 0; i < CONFIG_MEM_SIZE / 4; i++) { | |
203 | dcplb_table[j][0] = (i * 4 * 1024 * 1024); | |
204 | if (i * 4 * 1024 * 1024 <= CFG_MONITOR_BASE | |
205 | && (i + 1) * 4 * 1024 * 1024 >= CFG_MONITOR_BASE) { | |
206 | dcplb_table[j][1] = SDRAM_DKERNEL; | |
207 | } else { | |
208 | dcplb_table[j][1] = SDRAM_DGENERIC; | |
209 | } | |
210 | j++; | |
211 | } | |
212 | ||
3f0606ad AL |
213 | dcplb_table[j][0] = 0x20000000; |
214 | dcplb_table[j][1] = SDRAM_EBIU; | |
3f0606ad AL |
215 | } |
216 | ||
6cb142fa WD |
217 | /* |
218 | * All attempts to come up with a "common" initialization sequence | |
219 | * that works for all boards and architectures failed: some of the | |
220 | * requirements are just _too_ different. To get rid of the resulting | |
221 | * mess of board dependend #ifdef'ed code we now make the whole | |
222 | * initialization sequence configurable to the user. | |
223 | * | |
224 | * The requirements for any new initalization function is simple: it | |
225 | * receives a pointer to the "global data" structure as it's only | |
226 | * argument, and returns an integer return code, where 0 means | |
227 | * "continue" and != 0 means "fatal error, hang the system". | |
228 | */ | |
229 | ||
230 | void board_init_f(ulong bootflag) | |
231 | { | |
6cb142fa WD |
232 | ulong addr; |
233 | bd_t *bd; | |
3f0606ad AL |
234 | int i; |
235 | ||
236 | init_cplbtables(); | |
6cb142fa WD |
237 | |
238 | gd = (gd_t *) (CFG_GBL_DATA_ADDR); | |
3f0606ad | 239 | memset((void *)gd, 0, sizeof(gd_t)); |
6cb142fa WD |
240 | |
241 | /* Board data initialization */ | |
242 | addr = (CFG_GBL_DATA_ADDR + sizeof(gd_t)); | |
243 | ||
244 | /* Align to 4 byte boundary */ | |
8e7b703a | 245 | addr &= ~(4 - 1); |
3f0606ad | 246 | bd = (bd_t *) addr; |
6cb142fa | 247 | gd->bd = bd; |
3f0606ad | 248 | memset((void *)bd, 0, sizeof(bd_t)); |
6cb142fa WD |
249 | |
250 | /* Initialize */ | |
9171fc81 | 251 | irq_init(); |
6cb142fa WD |
252 | env_init(); /* initialize environment */ |
253 | init_baudrate(); /* initialze baudrate settings */ | |
254 | serial_init(); /* serial communications setup */ | |
255 | console_init_f(); | |
3f0606ad AL |
256 | #ifdef CONFIG_ICACHE_ON |
257 | icache_enable(); | |
258 | #endif | |
259 | #ifdef CONFIG_DCACHE_ON | |
260 | dcache_enable(); | |
261 | #endif | |
6cb142fa | 262 | display_banner(); /* say that we are here */ |
3f0606ad AL |
263 | |
264 | for (i = 0; i < page_descriptor_table_size; i++) { | |
8440bb14 | 265 | debug |
3f0606ad AL |
266 | ("data (%02i)= 0x%08x : 0x%08x intr = 0x%08x : 0x%08x\n", |
267 | i, dcplb_table[i][0], dcplb_table[i][1], icplb_table[i][0], | |
268 | icplb_table[i][1]); | |
269 | } | |
270 | ||
6cb142fa | 271 | checkboard(); |
67350568 | 272 | #if defined(CONFIG_RTC_BF533) && defined(CONFIG_CMD_DATE) |
6cb142fa WD |
273 | rtc_init(); |
274 | #endif | |
275 | timer_init(); | |
3f0606ad AL |
276 | printf("Clock: VCO: %lu MHz, Core: %lu MHz, System: %lu MHz\n", |
277 | get_vco() / 1000000, get_cclk() / 1000000, get_sclk() / 1000000); | |
6cb142fa WD |
278 | printf("SDRAM: "); |
279 | print_size(initdram(0), "\n"); | |
9171fc81 | 280 | #if defined(CONFIG_POST) |
3f0606ad AL |
281 | post_init_f(); |
282 | post_bootmode_init(); | |
283 | post_run(NULL, POST_ROM | post_bootmode_get(0)); | |
284 | #endif | |
6cb142fa WD |
285 | board_init_r((gd_t *) gd, 0x20000010); |
286 | } | |
287 | ||
3f0606ad AL |
288 | #if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C) |
289 | static int init_func_i2c(void) | |
290 | { | |
291 | puts("I2C: "); | |
292 | i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); | |
293 | puts("ready\n"); | |
294 | return (0); | |
295 | } | |
296 | #endif | |
297 | ||
6cb142fa WD |
298 | void board_init_r(gd_t * id, ulong dest_addr) |
299 | { | |
6cb142fa WD |
300 | ulong size; |
301 | extern void malloc_bin_reloc(void); | |
302 | char *s, *e; | |
303 | bd_t *bd; | |
304 | int i; | |
305 | gd = id; | |
306 | gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ | |
307 | bd = gd->bd; | |
308 | ||
9171fc81 | 309 | #if defined(CONFIG_POST) |
3f0606ad AL |
310 | post_output_backlog(); |
311 | post_reloc(); | |
312 | #endif | |
313 | ||
9171fc81 | 314 | #if !defined(CFG_NO_FLASH) |
6cb142fa WD |
315 | /* There are some other pointer constants we must deal with */ |
316 | /* configure available FLASH banks */ | |
317 | size = flash_init(); | |
318 | display_flash_config(size); | |
3f0606ad AL |
319 | flash_protect(FLAG_PROTECT_SET, CFG_FLASH_BASE, |
320 | CFG_FLASH_BASE + 0x1ffff, &flash_info[0]); | |
6cb142fa WD |
321 | bd->bi_flashstart = CFG_FLASH_BASE; |
322 | bd->bi_flashsize = size; | |
323 | bd->bi_flashoffset = 0; | |
324 | #else | |
325 | bd->bi_flashstart = 0; | |
326 | bd->bi_flashsize = 0; | |
327 | bd->bi_flashoffset = 0; | |
328 | #endif | |
329 | /* initialize malloc() area */ | |
330 | mem_malloc_init(); | |
331 | malloc_bin_reloc(); | |
332 | ||
3f0606ad AL |
333 | #ifdef CONFIG_SPI |
334 | # if ! defined(CFG_ENV_IS_IN_EEPROM) | |
335 | spi_init_f(); | |
336 | # endif | |
337 | spi_init_r(); | |
338 | #endif | |
339 | ||
6cb142fa WD |
340 | /* relocate environment function pointers etc. */ |
341 | env_relocate(); | |
342 | ||
343 | /* board MAC address */ | |
344 | s = getenv("ethaddr"); | |
345 | for (i = 0; i < 6; ++i) { | |
346 | bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0; | |
347 | if (s) | |
348 | s = (*e) ? e + 1 : e; | |
349 | } | |
350 | ||
351 | /* IP Address */ | |
352 | bd->bi_ip_addr = getenv_IPaddr("ipaddr"); | |
353 | ||
354 | /* Initialize devices */ | |
355 | devices_init(); | |
356 | jumptable_init(); | |
357 | ||
358 | /* Initialize the console (after the relocation and devices init) */ | |
359 | console_init_r(); | |
360 | ||
361 | /* Initialize from environment */ | |
362 | if ((s = getenv("loadaddr")) != NULL) { | |
363 | load_addr = simple_strtoul(s, NULL, 16); | |
364 | } | |
67350568 | 365 | #if defined(CONFIG_CMD_NET) |
6cb142fa WD |
366 | if ((s = getenv("bootfile")) != NULL) { |
367 | copy_filename(BootFile, s, sizeof(BootFile)); | |
368 | } | |
369 | #endif | |
3f0606ad | 370 | |
67350568 | 371 | #if defined(CONFIG_CMD_NAND) |
3f0606ad AL |
372 | puts("NAND: "); |
373 | nand_init(); /* go init the NAND */ | |
374 | #endif | |
375 | ||
6cb142fa WD |
376 | #if defined(CONFIG_MISC_INIT_R) |
377 | /* miscellaneous platform dependent initialisations */ | |
378 | misc_init_r(); | |
379 | #endif | |
380 | ||
f7ce12cb | 381 | #ifdef CONFIG_CMD_NET |
3f0606ad AL |
382 | printf("Net: "); |
383 | eth_initialize(bd); | |
384 | #endif | |
385 | ||
6cb142fa WD |
386 | #ifdef CONFIG_DRIVER_SMC91111 |
387 | #ifdef SHARED_RESOURCES | |
388 | /* Switch to Ethernet */ | |
389 | swap_to(ETHERNET); | |
390 | #endif | |
3f0606ad AL |
391 | if ((SMC_inw(BANK_SELECT) & UPPER_BYTE_MASK) != SMC_IDENT) { |
392 | printf("ERROR: Can't find SMC91111 at address %x\n", | |
393 | SMC_BASE_ADDRESS); | |
6cb142fa WD |
394 | } else { |
395 | printf("Net: SMC91111 at 0x%08X\n", SMC_BASE_ADDRESS); | |
396 | } | |
397 | ||
398 | #ifdef SHARED_RESOURCES | |
399 | swap_to(FLASH); | |
400 | #endif | |
401 | #endif | |
3f0606ad | 402 | #if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C) |
6cb142fa WD |
403 | init_func_i2c(); |
404 | #endif | |
405 | ||
406 | #ifdef DEBUG | |
3f0606ad AL |
407 | display_global_data(); |
408 | #endif | |
409 | ||
9171fc81 | 410 | #if defined(CONFIG_POST) |
3f0606ad AL |
411 | if (post_flag) |
412 | post_run(NULL, POST_RAM | post_bootmode_get(0)); | |
6cb142fa WD |
413 | #endif |
414 | ||
415 | /* main_loop() can return to retry autoboot, if so just run it again. */ | |
416 | for (;;) { | |
417 | main_loop(); | |
418 | } | |
419 | } | |
420 | ||
6cb142fa WD |
421 | void hang(void) |
422 | { | |
423 | puts("### ERROR ### Please RESET the board ###\n"); | |
3f0606ad | 424 | for (;;) ; |
6cb142fa | 425 | } |