]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/m68k/lib/board.c
Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / arch / m68k / lib / board.c
1 /*
2  * (C) Copyright 2003
3  * Josef Baumgartner <josef.baumgartner@telex.de>
4  *
5  * (C) Copyright 2000-2002
6  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <watchdog.h>
13 #include <command.h>
14 #include <malloc.h>
15 #include <stdio_dev.h>
16 #include <linux/compiler.h>
17
18 #include <asm/immap.h>
19
20 #if defined(CONFIG_CMD_IDE)
21 #include <ide.h>
22 #endif
23 #if defined(CONFIG_CMD_SCSI)
24 #include <scsi.h>
25 #endif
26 #if defined(CONFIG_CMD_KGDB)
27 #include <kgdb.h>
28 #endif
29 #ifdef CONFIG_STATUS_LED
30 #include <status_led.h>
31 #endif
32 #include <net.h>
33 #include <serial.h>
34 #if defined(CONFIG_CMD_BEDBUG)
35 #include <cmd_bedbug.h>
36 #endif
37 #ifdef CONFIG_SYS_ALLOC_DPRAM
38 #include <commproc.h>
39 #endif
40 #include <version.h>
41
42 #if defined(CONFIG_HARD_I2C) || \
43         defined(CONFIG_SYS_I2C)
44 #include <i2c.h>
45 #endif
46
47 #ifdef CONFIG_CMD_SPI
48 #include <spi.h>
49 #endif
50
51 #ifdef CONFIG_BITBANGMII
52 #include <miiphy.h>
53 #endif
54
55 #include <nand.h>
56
57 DECLARE_GLOBAL_DATA_PTR;
58
59 static char *failed = "*** failed ***\n";
60
61 #include <environment.h>
62
63 extern ulong __init_end;
64 extern ulong __bss_end;
65
66 #if defined(CONFIG_WATCHDOG)
67 # undef INIT_FUNC_WATCHDOG_INIT
68 # define INIT_FUNC_WATCHDOG_INIT        watchdog_init,
69 # define WATCHDOG_DISABLE               watchdog_disable
70
71 extern int watchdog_init(void);
72 extern int watchdog_disable(void);
73 #else
74 # define INIT_FUNC_WATCHDOG_INIT        /* undef */
75 # define WATCHDOG_DISABLE               /* undef */
76 #endif /* CONFIG_WATCHDOG */
77
78 ulong monitor_flash_len;
79
80 /************************************************************************
81  * Utilities                                                            *
82  ************************************************************************
83  */
84
85 /*
86  * All attempts to come up with a "common" initialization sequence
87  * that works for all boards and architectures failed: some of the
88  * requirements are just _too_ different. To get rid of the resulting
89  * mess of board dependend #ifdef'ed code we now make the whole
90  * initialization sequence configurable to the user.
91  *
92  * The requirements for any new initalization function is simple: it
93  * receives a pointer to the "global data" structure as it's only
94  * argument, and returns an integer return code, where 0 means
95  * "continue" and != 0 means "fatal error, hang the system".
96  */
97 typedef int (init_fnc_t) (void);
98
99 /************************************************************************
100  * Init Utilities
101  ************************************************************************
102  * Some of this code should be moved into the core functions,
103  * but let's get it working (again) first...
104  */
105
106 static int init_baudrate (void)
107 {
108         gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
109         return 0;
110 }
111
112 /***********************************************************************/
113
114 static int init_func_ram (void)
115 {
116         int board_type = 0;     /* use dummy arg */
117         puts ("DRAM:  ");
118
119         if ((gd->ram_size = initdram (board_type)) > 0) {
120                 print_size (gd->ram_size, "\n");
121                 return (0);
122         }
123         puts (failed);
124         return (1);
125 }
126
127 /***********************************************************************/
128
129 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
130 static int init_func_i2c (void)
131 {
132         puts ("I2C:   ");
133 #ifdef CONFIG_SYS_I2C
134         i2c_init_all();
135 #else
136         i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
137 #endif
138         puts ("ready\n");
139         return (0);
140 }
141 #endif
142
143 #if defined(CONFIG_HARD_SPI)
144 static int init_func_spi (void)
145 {
146         puts ("SPI:   ");
147         spi_init ();
148         puts ("ready\n");
149         return (0);
150 }
151 #endif
152
153 /***********************************************************************/
154
155 /************************************************************************
156  * Initialization sequence                                              *
157  ************************************************************************
158  */
159
160 init_fnc_t *init_sequence[] = {
161         get_clocks,
162         env_init,
163         init_baudrate,
164         serial_init,
165         console_init_f,
166         display_options,
167         checkcpu,
168         checkboard,
169 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
170         init_func_i2c,
171 #endif
172 #if defined(CONFIG_HARD_SPI)
173         init_func_spi,
174 #endif
175         init_func_ram,
176 #if defined(CONFIG_SYS_DRAM_TEST)
177         testdram,
178 #endif /* CONFIG_SYS_DRAM_TEST */
179         INIT_FUNC_WATCHDOG_INIT
180         NULL,                   /* Terminate this list */
181 };
182
183
184 /************************************************************************
185  *
186  * This is the first part of the initialization sequence that is
187  * implemented in C, but still running from ROM.
188  *
189  * The main purpose is to provide a (serial) console interface as
190  * soon as possible (so we can see any error messages), and to
191  * initialize the RAM so that we can relocate the monitor code to
192  * RAM.
193  *
194  * Be aware of the restrictions: global data is read-only, BSS is not
195  * initialized, and stack space is limited to a few kB.
196  *
197  ************************************************************************
198  */
199
200 void
201 board_init_f (ulong bootflag)
202 {
203         bd_t *bd;
204         ulong len, addr, addr_sp;
205         ulong *paddr;
206         gd_t *id;
207         init_fnc_t **init_fnc_ptr;
208 #ifdef CONFIG_PRAM
209         ulong reg;
210 #endif
211
212         /* Pointer is writable since we allocated a register for it */
213         gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
214         /* compiler optimization barrier needed for GCC >= 3.4 */
215         __asm__ __volatile__("": : :"memory");
216
217         /* Clear initial global data */
218         memset ((void *) gd, 0, sizeof (gd_t));
219
220         for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
221                 if ((*init_fnc_ptr)() != 0) {
222                         hang ();
223                 }
224         }
225
226         /*
227          * Now that we have DRAM mapped and working, we can
228          * relocate the code and continue running from DRAM.
229          *
230          * Reserve memory at end of RAM for (top down in that order):
231          *      - protected RAM
232          *      - LCD framebuffer
233          *      - monitor code
234          *      - board info struct
235          */
236         len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
237
238         addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
239
240 #ifdef CONFIG_LOGBUFFER
241         /* reserve kernel log buffer */
242         addr -= (LOGBUFF_RESERVE);
243         debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr);
244 #endif
245
246 #ifdef CONFIG_PRAM
247         /*
248          * reserve protected RAM
249          */
250         reg = getenv_ulong("pram", 10, CONFIG_PRAM);
251         addr -= (reg << 10);            /* size is in kB */
252         debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr);
253 #endif /* CONFIG_PRAM */
254
255         /* round down to next 4 kB limit */
256         addr &= ~(4096 - 1);
257         debug ("Top of RAM usable for U-Boot at: %08lx\n", addr);
258
259 #ifdef CONFIG_LCD
260 #ifdef CONFIG_FB_ADDR
261         gd->fb_base = CONFIG_FB_ADDR;
262 #else
263         /* reserve memory for LCD display (always full pages) */
264         addr = lcd_setmem (addr);
265         gd->fb_base = addr;
266 #endif /* CONFIG_FB_ADDR */
267 #endif /* CONFIG_LCD */
268
269         /*
270          * reserve memory for U-Boot code, data & bss
271          * round down to next 4 kB limit
272          */
273         addr -= len;
274         addr &= ~(4096 - 1);
275
276         debug ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
277
278         /*
279          * reserve memory for malloc() arena
280          */
281         addr_sp = addr - TOTAL_MALLOC_LEN;
282         debug ("Reserving %dk for malloc() at: %08lx\n",
283                         TOTAL_MALLOC_LEN >> 10, addr_sp);
284
285         /*
286          * (permanently) allocate a Board Info struct
287          * and a permanent copy of the "global" data
288          */
289         addr_sp -= sizeof (bd_t);
290         bd = (bd_t *) addr_sp;
291         gd->bd = bd;
292         debug ("Reserving %zu Bytes for Board Info at: %08lx\n",
293                         sizeof (bd_t), addr_sp);
294         addr_sp -= sizeof (gd_t);
295         id = (gd_t *) addr_sp;
296         debug ("Reserving %zu Bytes for Global Data at: %08lx\n",
297                         sizeof (gd_t), addr_sp);
298
299         /* Reserve memory for boot params. */
300         addr_sp -= CONFIG_SYS_BOOTPARAMS_LEN;
301         bd->bi_boot_params = addr_sp;
302         debug ("Reserving %dk for boot parameters at: %08lx\n",
303                         CONFIG_SYS_BOOTPARAMS_LEN >> 10, addr_sp);
304
305         /*
306          * Finally, we set up a new (bigger) stack.
307          *
308          * Leave some safety gap for SP, force alignment on 16 byte boundary
309          * Clear initial stack frame
310          */
311         addr_sp -= 16;
312         addr_sp &= ~0xF;
313
314         paddr = (ulong *)addr_sp;
315         *paddr-- = 0;
316         *paddr-- = 0;
317         addr_sp = (ulong)paddr;
318
319         debug ("Stack Pointer at: %08lx\n", addr_sp);
320
321         /*
322          * Save local variables to board info struct
323          */
324         bd->bi_memstart  = CONFIG_SYS_SDRAM_BASE;       /* start of  DRAM memory      */
325         bd->bi_memsize   = gd->ram_size;        /* size  of  DRAM memory in bytes */
326 #ifdef CONFIG_SYS_INIT_RAM_ADDR
327         bd->bi_sramstart = CONFIG_SYS_INIT_RAM_ADDR;    /* start of  SRAM memory        */
328         bd->bi_sramsize  = CONFIG_SYS_INIT_RAM_SIZE;    /* size  of  SRAM memory        */
329 #endif
330         bd->bi_mbar_base = CONFIG_SYS_MBAR;             /* base of internal registers */
331
332         bd->bi_bootflags = bootflag;            /* boot / reboot flag (for LynxOS)    */
333
334         WATCHDOG_RESET ();
335         bd->bi_intfreq = gd->cpu_clk;   /* Internal Freq, in Hz */
336         bd->bi_busfreq = gd->bus_clk;   /* Bus Freq,      in Hz */
337 #ifdef CONFIG_PCI
338         bd->bi_pcifreq = gd->pci_clk;           /* PCI Freq in Hz */
339 #endif
340 #ifdef CONFIG_EXTRA_CLOCK
341         bd->bi_inpfreq = gd->arch.inp_clk;              /* input Freq in Hz */
342         bd->bi_vcofreq = gd->arch.vco_clk;              /* vco Freq in Hz */
343         bd->bi_flbfreq = gd->arch.flb_clk;              /* flexbus Freq in Hz */
344 #endif
345
346 #ifdef CONFIG_SYS_EXTBDINFO
347         strncpy (bd->bi_s_version, "1.2", sizeof (bd->bi_s_version));
348         strncpy (bd->bi_r_version, U_BOOT_VERSION, sizeof (bd->bi_r_version));
349 #endif
350
351         WATCHDOG_RESET ();
352
353 #ifdef CONFIG_POST
354         post_bootmode_init();
355         post_run (NULL, POST_ROM | post_bootmode_get(0));
356 #endif
357
358         WATCHDOG_RESET();
359
360         memcpy (id, (void *)gd, sizeof (gd_t));
361
362         debug ("Start relocate of code from %08x to %08lx\n", CONFIG_SYS_MONITOR_BASE, addr);
363         relocate_code (addr_sp, id, addr);
364
365         /* NOTREACHED - jump_to_ram() does not return */
366 }
367
368 /************************************************************************
369  *
370  * This is the next part if the initialization sequence: we are now
371  * running from RAM and have a "normal" C environment, i. e. global
372  * data can be written, BSS has been cleared, the stack size in not
373  * that critical any more, etc.
374  *
375  ************************************************************************
376  */
377 void board_init_r (gd_t *id, ulong dest_addr)
378 {
379         char *s __maybe_unused;
380         bd_t *bd;
381
382 #ifndef CONFIG_ENV_IS_NOWHERE
383         extern char * env_name_spec;
384 #endif
385 #ifndef CONFIG_SYS_NO_FLASH
386         ulong flash_size;
387 #endif
388         gd = id;                /* initialize RAM version of global data */
389         bd = gd->bd;
390
391         gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
392
393         WATCHDOG_RESET ();
394
395         gd->reloc_off =  dest_addr - CONFIG_SYS_MONITOR_BASE;
396
397         serial_initialize();
398
399         debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
400
401         monitor_flash_len = (ulong)&__init_end - dest_addr;
402
403 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
404         /*
405          * We have to relocate the command table manually
406          */
407         fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd),
408                         ll_entry_count(cmd_tbl_t, cmd));
409 #endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */
410
411         /* there are some other pointer constants we must deal with */
412 #ifndef CONFIG_ENV_IS_NOWHERE
413         env_name_spec += gd->reloc_off;
414 #endif
415
416         WATCHDOG_RESET ();
417
418 #ifdef CONFIG_LOGBUFFER
419         logbuff_init_ptrs ();
420 #endif
421 #ifdef CONFIG_POST
422         post_output_backlog ();
423         post_reloc ();
424 #endif
425         WATCHDOG_RESET();
426
427 #if 0
428         /* instruction cache enabled in cpu_init_f() for faster relocation */
429         icache_enable ();       /* it's time to enable the instruction cache */
430 #endif
431
432         /*
433          * Setup trap handlers
434          */
435         trap_init (CONFIG_SYS_SDRAM_BASE);
436
437         /* The Malloc area is immediately below the monitor copy in DRAM */
438         mem_malloc_init (CONFIG_SYS_MONITOR_BASE + gd->reloc_off -
439                         TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN);
440
441 #if !defined(CONFIG_SYS_NO_FLASH)
442         puts ("Flash: ");
443
444         if ((flash_size = flash_init ()) > 0) {
445 # ifdef CONFIG_SYS_FLASH_CHECKSUM
446                 print_size (flash_size, "");
447                 /*
448                  * Compute and print flash CRC if flashchecksum is set to 'y'
449                  *
450                  * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
451                  */
452                 if (getenv_yesno("flashchecksum") == 1) {
453                         printf ("  CRC: %08X",
454                                         crc32 (0,
455                                                    (const unsigned char *) CONFIG_SYS_FLASH_BASE,
456                                                    flash_size)
457                                         );
458                 }
459                 putc ('\n');
460 # else  /* !CONFIG_SYS_FLASH_CHECKSUM */
461                 print_size (flash_size, "\n");
462 # endif /* CONFIG_SYS_FLASH_CHECKSUM */
463         } else {
464                 puts (failed);
465                 hang ();
466         }
467
468         bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;      /* update start of FLASH memory    */
469         bd->bi_flashsize = flash_size;  /* size of FLASH memory (final value) */
470         bd->bi_flashoffset = 0;
471 #else   /* CONFIG_SYS_NO_FLASH */
472         bd->bi_flashsize = 0;
473         bd->bi_flashstart = 0;
474         bd->bi_flashoffset = 0;
475 #endif /* !CONFIG_SYS_NO_FLASH */
476
477         WATCHDOG_RESET ();
478
479         /* initialize higher level parts of CPU like time base and timers */
480         cpu_init_r ();
481
482         WATCHDOG_RESET ();
483
484 #ifdef CONFIG_SPI
485 # if !defined(CONFIG_ENV_IS_IN_EEPROM)
486         spi_init_f ();
487 # endif
488         spi_init_r ();
489 #endif
490
491 #if defined(CONFIG_SYS_I2C)
492         /* Adjust I2C subsystem pointers after relocation */
493         i2c_reloc_fixup();
494 #endif
495
496         /* relocate environment function pointers etc. */
497         env_relocate ();
498
499         WATCHDOG_RESET ();
500
501 #if defined(CONFIG_PCI)
502         /*
503          * Do pci configuration
504          */
505         pci_init ();
506 #endif
507
508         /** leave this here (after malloc(), environment and PCI are working) **/
509         /* Initialize stdio devices */
510         stdio_init ();
511
512         /* Initialize the jump table for applications */
513         jumptable_init ();
514
515         /* Initialize the console (after the relocation and devices init) */
516         console_init_r ();
517
518 #if defined(CONFIG_MISC_INIT_R)
519         /* miscellaneous platform dependent initialisations */
520         misc_init_r ();
521 #endif
522
523 #if defined(CONFIG_CMD_KGDB)
524         WATCHDOG_RESET ();
525         puts ("KGDB:  ");
526         kgdb_init ();
527 #endif
528
529         debug ("U-Boot relocated to %08lx\n", dest_addr);
530
531         /*
532          * Enable Interrupts
533          */
534         interrupt_init ();
535
536         /* Must happen after interrupts are initialized since
537          * an irq handler gets installed
538          */
539         timer_init();
540
541 #ifdef CONFIG_STATUS_LED
542         status_led_set (STATUS_LED_BOOT, STATUS_LED_BLINKING);
543 #endif
544
545         udelay (20);
546
547         /* Insert function pointers now that we have relocated the code */
548
549         /* Initialize from environment */
550         load_addr = getenv_ulong("loadaddr", 16, load_addr);
551
552         WATCHDOG_RESET ();
553
554 #if defined(CONFIG_CMD_DOC)
555         WATCHDOG_RESET ();
556         puts ("DOC:   ");
557         doc_init ();
558 #endif
559
560 #if defined(CONFIG_CMD_NAND)
561         WATCHDOG_RESET ();
562         puts ("NAND:  ");
563         nand_init();            /* go init the NAND */
564 #endif
565
566 #ifdef CONFIG_BITBANGMII
567         bb_miiphy_init();
568 #endif
569 #if defined(CONFIG_CMD_NET)
570         WATCHDOG_RESET();
571 #if defined(FEC_ENET)
572         eth_init(bd);
573 #endif
574         puts ("Net:   ");
575         eth_initialize (bd);
576 #endif
577
578 #ifdef CONFIG_POST
579         post_run (NULL, POST_RAM | post_bootmode_get(0));
580 #endif
581
582 #if defined(CONFIG_CMD_PCMCIA) \
583     && !defined(CONFIG_CMD_IDE)
584         WATCHDOG_RESET ();
585         puts ("PCMCIA:");
586         pcmcia_init ();
587 #endif
588
589 #if defined(CONFIG_CMD_IDE)
590         WATCHDOG_RESET ();
591         puts ("IDE:   ");
592         ide_init ();
593 #endif
594
595 #ifdef CONFIG_LAST_STAGE_INIT
596         WATCHDOG_RESET ();
597         /*
598          * Some parts can be only initialized if all others (like
599          * Interrupts) are up and running (i.e. the PC-style ISA
600          * keyboard).
601          */
602         last_stage_init ();
603 #endif
604
605 #if defined(CONFIG_CMD_BEDBUG)
606         WATCHDOG_RESET ();
607         bedbug_init ();
608 #endif
609
610 #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
611         /*
612          * Export available size of memory for Linux,
613          * taking into account the protected RAM at top of memory
614          */
615         {
616                 ulong pram = 0;
617                 char memsz[32];
618
619 #ifdef CONFIG_PRAM
620                 pram = getenv_ulong("pram", 10, CONFIG_PRAM);
621 #endif
622 #ifdef CONFIG_LOGBUFFER
623                 /* Also take the logbuffer into account (pram is in kB) */
624                 pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024;
625 #endif
626                 sprintf (memsz, "%ldk", (bd->bi_memsize / 1024) - pram);
627                 setenv ("mem", memsz);
628         }
629 #endif
630
631 #ifdef CONFIG_MODEM_SUPPORT
632  {
633          extern int do_mdm_init;
634          do_mdm_init = gd->do_mdm_init;
635  }
636 #endif
637
638 #ifdef CONFIG_WATCHDOG
639         /* disable watchdog if environment is set */
640         if ((s = getenv ("watchdog")) != NULL) {
641                 if (strncmp (s, "off", 3) == 0) {
642                         WATCHDOG_DISABLE ();
643                 }
644         }
645 #endif /* CONFIG_WATCHDOG*/
646
647
648         /* Initialization complete - start the monitor */
649
650         /* main_loop() can return to retry autoboot, if so just run it again. */
651         for (;;) {
652                 WATCHDOG_RESET ();
653                 main_loop ();
654         }
655
656         /* NOTREACHED - no way out of command loop except booting */
657 }