]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/m68k/lib/board.c
Merge branch 'master' of git://git.denx.de/u-boot-i2c
[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         bd->bi_baudrate = gd->baudrate; /* Console Baudrate     */
346
347 #ifdef CONFIG_SYS_EXTBDINFO
348         strncpy (bd->bi_s_version, "1.2", sizeof (bd->bi_s_version));
349         strncpy (bd->bi_r_version, U_BOOT_VERSION, sizeof (bd->bi_r_version));
350 #endif
351
352         WATCHDOG_RESET ();
353
354 #ifdef CONFIG_POST
355         post_bootmode_init();
356         post_run (NULL, POST_ROM | post_bootmode_get(0));
357 #endif
358
359         WATCHDOG_RESET();
360
361         memcpy (id, (void *)gd, sizeof (gd_t));
362
363         debug ("Start relocate of code from %08x to %08lx\n", CONFIG_SYS_MONITOR_BASE, addr);
364         relocate_code (addr_sp, id, addr);
365
366         /* NOTREACHED - jump_to_ram() does not return */
367 }
368
369 /************************************************************************
370  *
371  * This is the next part if the initialization sequence: we are now
372  * running from RAM and have a "normal" C environment, i. e. global
373  * data can be written, BSS has been cleared, the stack size in not
374  * that critical any more, etc.
375  *
376  ************************************************************************
377  */
378 void board_init_r (gd_t *id, ulong dest_addr)
379 {
380         char *s __maybe_unused;
381         bd_t *bd;
382
383 #ifndef CONFIG_ENV_IS_NOWHERE
384         extern char * env_name_spec;
385 #endif
386 #ifndef CONFIG_SYS_NO_FLASH
387         ulong flash_size;
388 #endif
389         gd = id;                /* initialize RAM version of global data */
390         bd = gd->bd;
391
392         gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
393
394         WATCHDOG_RESET ();
395
396         gd->reloc_off =  dest_addr - CONFIG_SYS_MONITOR_BASE;
397
398         serial_initialize();
399
400         debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
401
402         monitor_flash_len = (ulong)&__init_end - dest_addr;
403
404 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
405         /*
406          * We have to relocate the command table manually
407          */
408         fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd),
409                         ll_entry_count(cmd_tbl_t, cmd));
410 #endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */
411
412         /* there are some other pointer constants we must deal with */
413 #ifndef CONFIG_ENV_IS_NOWHERE
414         env_name_spec += gd->reloc_off;
415 #endif
416
417         WATCHDOG_RESET ();
418
419 #ifdef CONFIG_LOGBUFFER
420         logbuff_init_ptrs ();
421 #endif
422 #ifdef CONFIG_POST
423         post_output_backlog ();
424         post_reloc ();
425 #endif
426         WATCHDOG_RESET();
427
428 #if 0
429         /* instruction cache enabled in cpu_init_f() for faster relocation */
430         icache_enable ();       /* it's time to enable the instruction cache */
431 #endif
432
433         /*
434          * Setup trap handlers
435          */
436         trap_init (CONFIG_SYS_SDRAM_BASE);
437
438         /* The Malloc area is immediately below the monitor copy in DRAM */
439         mem_malloc_init (CONFIG_SYS_MONITOR_BASE + gd->reloc_off -
440                         TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN);
441
442 #if !defined(CONFIG_SYS_NO_FLASH)
443         puts ("Flash: ");
444
445         if ((flash_size = flash_init ()) > 0) {
446 # ifdef CONFIG_SYS_FLASH_CHECKSUM
447                 print_size (flash_size, "");
448                 /*
449                  * Compute and print flash CRC if flashchecksum is set to 'y'
450                  *
451                  * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
452                  */
453                 if (getenv_yesno("flashchecksum") == 1) {
454                         printf ("  CRC: %08X",
455                                         crc32 (0,
456                                                    (const unsigned char *) CONFIG_SYS_FLASH_BASE,
457                                                    flash_size)
458                                         );
459                 }
460                 putc ('\n');
461 # else  /* !CONFIG_SYS_FLASH_CHECKSUM */
462                 print_size (flash_size, "\n");
463 # endif /* CONFIG_SYS_FLASH_CHECKSUM */
464         } else {
465                 puts (failed);
466                 hang ();
467         }
468
469         bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;      /* update start of FLASH memory    */
470         bd->bi_flashsize = flash_size;  /* size of FLASH memory (final value) */
471         bd->bi_flashoffset = 0;
472 #else   /* CONFIG_SYS_NO_FLASH */
473         bd->bi_flashsize = 0;
474         bd->bi_flashstart = 0;
475         bd->bi_flashoffset = 0;
476 #endif /* !CONFIG_SYS_NO_FLASH */
477
478         WATCHDOG_RESET ();
479
480         /* initialize higher level parts of CPU like time base and timers */
481         cpu_init_r ();
482
483         WATCHDOG_RESET ();
484
485 #ifdef CONFIG_SPI
486 # if !defined(CONFIG_ENV_IS_IN_EEPROM)
487         spi_init_f ();
488 # endif
489         spi_init_r ();
490 #endif
491
492 #if defined(CONFIG_SYS_I2C)
493         /* Adjust I2C subsystem pointers after relocation */
494         i2c_reloc_fixup();
495 #endif
496
497         /* relocate environment function pointers etc. */
498         env_relocate ();
499
500         WATCHDOG_RESET ();
501
502 #if defined(CONFIG_PCI)
503         /*
504          * Do pci configuration
505          */
506         pci_init ();
507 #endif
508
509         /** leave this here (after malloc(), environment and PCI are working) **/
510         /* Initialize stdio devices */
511         stdio_init ();
512
513         /* Initialize the jump table for applications */
514         jumptable_init ();
515
516         /* Initialize the console (after the relocation and devices init) */
517         console_init_r ();
518
519 #if defined(CONFIG_MISC_INIT_R)
520         /* miscellaneous platform dependent initialisations */
521         misc_init_r ();
522 #endif
523
524 #if defined(CONFIG_CMD_KGDB)
525         WATCHDOG_RESET ();
526         puts ("KGDB:  ");
527         kgdb_init ();
528 #endif
529
530         debug ("U-Boot relocated to %08lx\n", dest_addr);
531
532         /*
533          * Enable Interrupts
534          */
535         interrupt_init ();
536
537         /* Must happen after interrupts are initialized since
538          * an irq handler gets installed
539          */
540         timer_init();
541
542 #ifdef CONFIG_STATUS_LED
543         status_led_set (STATUS_LED_BOOT, STATUS_LED_BLINKING);
544 #endif
545
546         udelay (20);
547
548         /* Insert function pointers now that we have relocated the code */
549
550         /* Initialize from environment */
551         load_addr = getenv_ulong("loadaddr", 16, load_addr);
552
553         WATCHDOG_RESET ();
554
555 #if defined(CONFIG_CMD_DOC)
556         WATCHDOG_RESET ();
557         puts ("DOC:   ");
558         doc_init ();
559 #endif
560
561 #if defined(CONFIG_CMD_NAND)
562         WATCHDOG_RESET ();
563         puts ("NAND:  ");
564         nand_init();            /* go init the NAND */
565 #endif
566
567 #ifdef CONFIG_BITBANGMII
568         bb_miiphy_init();
569 #endif
570 #if defined(CONFIG_CMD_NET)
571         WATCHDOG_RESET();
572 #if defined(FEC_ENET)
573         eth_init(bd);
574 #endif
575         puts ("Net:   ");
576         eth_initialize (bd);
577 #endif
578
579 #ifdef CONFIG_POST
580         post_run (NULL, POST_RAM | post_bootmode_get(0));
581 #endif
582
583 #if defined(CONFIG_CMD_PCMCIA) \
584     && !defined(CONFIG_CMD_IDE)
585         WATCHDOG_RESET ();
586         puts ("PCMCIA:");
587         pcmcia_init ();
588 #endif
589
590 #if defined(CONFIG_CMD_IDE)
591         WATCHDOG_RESET ();
592         puts ("IDE:   ");
593         ide_init ();
594 #endif
595
596 #ifdef CONFIG_LAST_STAGE_INIT
597         WATCHDOG_RESET ();
598         /*
599          * Some parts can be only initialized if all others (like
600          * Interrupts) are up and running (i.e. the PC-style ISA
601          * keyboard).
602          */
603         last_stage_init ();
604 #endif
605
606 #if defined(CONFIG_CMD_BEDBUG)
607         WATCHDOG_RESET ();
608         bedbug_init ();
609 #endif
610
611 #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
612         /*
613          * Export available size of memory for Linux,
614          * taking into account the protected RAM at top of memory
615          */
616         {
617                 ulong pram = 0;
618                 char memsz[32];
619
620 #ifdef CONFIG_PRAM
621                 pram = getenv_ulong("pram", 10, CONFIG_PRAM);
622 #endif
623 #ifdef CONFIG_LOGBUFFER
624                 /* Also take the logbuffer into account (pram is in kB) */
625                 pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024;
626 #endif
627                 sprintf (memsz, "%ldk", (bd->bi_memsize / 1024) - pram);
628                 setenv ("mem", memsz);
629         }
630 #endif
631
632 #ifdef CONFIG_MODEM_SUPPORT
633  {
634          extern int do_mdm_init;
635          do_mdm_init = gd->do_mdm_init;
636  }
637 #endif
638
639 #ifdef CONFIG_WATCHDOG
640         /* disable watchdog if environment is set */
641         if ((s = getenv ("watchdog")) != NULL) {
642                 if (strncmp (s, "off", 3) == 0) {
643                         WATCHDOG_DISABLE ();
644                 }
645         }
646 #endif /* CONFIG_WATCHDOG*/
647
648
649         /* Initialization complete - start the monitor */
650
651         /* main_loop() can return to retry autoboot, if so just run it again. */
652         for (;;) {
653                 WATCHDOG_RESET ();
654                 main_loop ();
655         }
656
657         /* NOTREACHED - no way out of command loop except booting */
658 }