uboot/arch/blackfin/lib/board.c
<<
>>
Prefs
   1/*
   2 * U-boot - board.c First C file to be called contains init routines
   3 *
   4 * Copyright (c) 2005-2008 Analog Devices Inc.
   5 *
   6 * (C) Copyright 2000-2004
   7 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   8 *
   9 * Licensed under the GPL-2 or later.
  10 */
  11
  12#include <common.h>
  13#include <command.h>
  14#include <stdio_dev.h>
  15#include <environment.h>
  16#include <malloc.h>
  17#include <mmc.h>
  18#include <net.h>
  19#include <timestamp.h>
  20#include <status_led.h>
  21#include <version.h>
  22
  23#include <asm/cplb.h>
  24#include <asm/mach-common/bits/mpu.h>
  25#include <kgdb.h>
  26
  27#ifdef CONFIG_CMD_NAND
  28#include <nand.h>       /* cannot even include nand.h if it isnt configured */
  29#endif
  30
  31#ifdef CONFIG_BITBANGMII
  32#include <miiphy.h>
  33#endif
  34
  35#if defined(CONFIG_POST)
  36#include <post.h>
  37int post_flag;
  38#endif
  39
  40DECLARE_GLOBAL_DATA_PTR;
  41
  42const char version_string[] = U_BOOT_VERSION " ("U_BOOT_DATE" - "U_BOOT_TIME")";
  43
  44__attribute__((always_inline))
  45static inline void serial_early_puts(const char *s)
  46{
  47#ifdef CONFIG_DEBUG_EARLY_SERIAL
  48        serial_puts("Early: ");
  49        serial_puts(s);
  50#endif
  51}
  52
  53static int display_banner(void)
  54{
  55        printf("\n\n%s\n\n", version_string);
  56        printf("CPU:   ADSP %s "
  57                "(Detected Rev: 0.%d) "
  58                "(%s boot)\n",
  59                gd->bd->bi_cpu,
  60                bfin_revid(),
  61                get_bfin_boot_mode(CONFIG_BFIN_BOOT_MODE));
  62        return 0;
  63}
  64
  65static int init_baudrate(void)
  66{
  67        char baudrate[15];
  68        int i = getenv_f("baudrate", baudrate, sizeof(baudrate));
  69        gd->bd->bi_baudrate = gd->baudrate = (i > 0)
  70            ? simple_strtoul(baudrate, NULL, 10)
  71            : CONFIG_BAUDRATE;
  72        return 0;
  73}
  74
  75static void display_global_data(void)
  76{
  77        bd_t *bd;
  78
  79#ifndef CONFIG_DEBUG_EARLY_SERIAL
  80        return;
  81#endif
  82
  83        bd = gd->bd;
  84        printf(" gd: %p\n", gd);
  85        printf(" |-flags: %lx\n", gd->flags);
  86        printf(" |-board_type: %lx\n", gd->board_type);
  87        printf(" |-baudrate: %lu\n", gd->baudrate);
  88        printf(" |-have_console: %lx\n", gd->have_console);
  89        printf(" |-ram_size: %lx\n", gd->ram_size);
  90        printf(" |-env_addr: %lx\n", gd->env_addr);
  91        printf(" |-env_valid: %lx\n", gd->env_valid);
  92        printf(" |-jt(%p): %p\n", gd->jt, *(gd->jt));
  93        printf(" \\-bd: %p\n", gd->bd);
  94        printf("   |-bi_baudrate: %x\n", bd->bi_baudrate);
  95        printf("   |-bi_ip_addr: %lx\n", bd->bi_ip_addr);
  96        printf("   |-bi_boot_params: %lx\n", bd->bi_boot_params);
  97        printf("   |-bi_memstart: %lx\n", bd->bi_memstart);
  98        printf("   |-bi_memsize: %lx\n", bd->bi_memsize);
  99        printf("   |-bi_flashstart: %lx\n", bd->bi_flashstart);
 100        printf("   |-bi_flashsize: %lx\n", bd->bi_flashsize);
 101        printf("   \\-bi_flashoffset: %lx\n", bd->bi_flashoffset);
 102}
 103
 104#define CPLB_PAGE_SIZE (4 * 1024 * 1024)
 105#define CPLB_PAGE_MASK (~(CPLB_PAGE_SIZE - 1))
 106void init_cplbtables(void)
 107{
 108        volatile uint32_t *ICPLB_ADDR, *ICPLB_DATA;
 109        volatile uint32_t *DCPLB_ADDR, *DCPLB_DATA;
 110        uint32_t extern_memory;
 111        size_t i;
 112
 113        void icplb_add(uint32_t addr, uint32_t data)
 114        {
 115                *(ICPLB_ADDR + i) = addr;
 116                *(ICPLB_DATA + i) = data;
 117        }
 118        void dcplb_add(uint32_t addr, uint32_t data)
 119        {
 120                *(DCPLB_ADDR + i) = addr;
 121                *(DCPLB_DATA + i) = data;
 122        }
 123
 124        /* populate a few common entries ... we'll let
 125         * the memory map and cplb exception handler do
 126         * the rest of the work.
 127         */
 128        i = 0;
 129        ICPLB_ADDR = (uint32_t *)ICPLB_ADDR0;
 130        ICPLB_DATA = (uint32_t *)ICPLB_DATA0;
 131        DCPLB_ADDR = (uint32_t *)DCPLB_ADDR0;
 132        DCPLB_DATA = (uint32_t *)DCPLB_DATA0;
 133
 134        icplb_add(0xFFA00000, L1_IMEMORY);
 135        dcplb_add(0xFF800000, L1_DMEMORY);
 136        ++i;
 137
 138        if (CONFIG_MEM_SIZE) {
 139                uint32_t mbase = CONFIG_SYS_MONITOR_BASE;
 140                uint32_t mend  = mbase + CONFIG_SYS_MONITOR_LEN;
 141                mbase &= CPLB_PAGE_MASK;
 142                mend &= CPLB_PAGE_MASK;
 143
 144                icplb_add(mbase, SDRAM_IKERNEL);
 145                dcplb_add(mbase, SDRAM_DKERNEL);
 146                ++i;
 147
 148                /*
 149                 * If the monitor crosses a 4 meg boundary, we'll need
 150                 * to lock two entries for it.  We assume it doesn't
 151                 * cross two 4 meg boundaries ...
 152                 */
 153                if (mbase != mend) {
 154                        icplb_add(mend, SDRAM_IKERNEL);
 155                        dcplb_add(mend, SDRAM_DKERNEL);
 156                        ++i;
 157                }
 158        }
 159
 160        icplb_add(0x20000000, SDRAM_INON_CHBL);
 161        dcplb_add(0x20000000, SDRAM_EBIU);
 162        ++i;
 163
 164        /* Add entries for the rest of external RAM up to the bootrom */
 165        extern_memory = 0;
 166
 167#ifdef CONFIG_DEBUG_NULL_PTR
 168        icplb_add(extern_memory, (SDRAM_IKERNEL & ~PAGE_SIZE_MASK) | PAGE_SIZE_1KB);
 169        dcplb_add(extern_memory, (SDRAM_DKERNEL & ~PAGE_SIZE_MASK) | PAGE_SIZE_1KB);
 170        ++i;
 171        icplb_add(extern_memory, SDRAM_IKERNEL);
 172        dcplb_add(extern_memory, SDRAM_DKERNEL);
 173        extern_memory += CPLB_PAGE_SIZE;
 174        ++i;
 175#endif
 176
 177        while (i < 16 && extern_memory < (CONFIG_SYS_MONITOR_BASE & CPLB_PAGE_MASK)) {
 178                icplb_add(extern_memory, SDRAM_IGENERIC);
 179                dcplb_add(extern_memory, SDRAM_DGENERIC);
 180                extern_memory += CPLB_PAGE_SIZE;
 181                ++i;
 182        }
 183        while (i < 16) {
 184                icplb_add(0, 0);
 185                dcplb_add(0, 0);
 186                ++i;
 187        }
 188}
 189
 190/*
 191 * All attempts to come up with a "common" initialization sequence
 192 * that works for all boards and architectures failed: some of the
 193 * requirements are just _too_ different. To get rid of the resulting
 194 * mess of board dependend #ifdef'ed code we now make the whole
 195 * initialization sequence configurable to the user.
 196 *
 197 * The requirements for any new initalization function is simple: it
 198 * receives a pointer to the "global data" structure as it's only
 199 * argument, and returns an integer return code, where 0 means
 200 * "continue" and != 0 means "fatal error, hang the system".
 201 */
 202
 203extern int watchdog_init(void);
 204extern int exception_init(void);
 205extern int irq_init(void);
 206extern int timer_init(void);
 207
 208void board_init_f(ulong bootflag)
 209{
 210        ulong addr;
 211        bd_t *bd;
 212        char buf[32];
 213
 214#ifdef CONFIG_BOARD_EARLY_INIT_F
 215        serial_early_puts("Board early init flash\n");
 216        board_early_init_f();
 217#endif
 218
 219        serial_early_puts("Init CPLB tables\n");
 220        init_cplbtables();
 221
 222        serial_early_puts("Exceptions setup\n");
 223        exception_init();
 224
 225#ifndef CONFIG_ICACHE_OFF
 226        serial_early_puts("Turn on ICACHE\n");
 227        icache_enable();
 228#endif
 229#ifndef CONFIG_DCACHE_OFF
 230        serial_early_puts("Turn on DCACHE\n");
 231        dcache_enable();
 232#endif
 233
 234#ifdef CONFIG_WATCHDOG
 235        serial_early_puts("Setting up external watchdog\n");
 236        watchdog_init();
 237#endif
 238
 239#ifdef DEBUG
 240        if (GENERATED_GBL_DATA_SIZE < sizeof(*gd))
 241                hang();
 242#endif
 243        serial_early_puts("Init global data\n");
 244        gd = (gd_t *) (CONFIG_SYS_GBL_DATA_ADDR);
 245        memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 246
 247        /* Board data initialization */
 248        addr = (CONFIG_SYS_GBL_DATA_ADDR + sizeof(gd_t));
 249
 250        /* Align to 4 byte boundary */
 251        addr &= ~(4 - 1);
 252        bd = (bd_t *) addr;
 253        gd->bd = bd;
 254        memset((void *)bd, 0, sizeof(bd_t));
 255
 256        bd->bi_r_version = version_string;
 257        bd->bi_cpu = BFIN_CPU;
 258        bd->bi_board_name = BFIN_BOARD_NAME;
 259        bd->bi_vco = get_vco();
 260        bd->bi_cclk = get_cclk();
 261        bd->bi_sclk = get_sclk();
 262        bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 263        bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
 264
 265        /* Initialize */
 266        serial_early_puts("IRQ init\n");
 267        irq_init();
 268        serial_early_puts("Environment init\n");
 269        env_init();
 270        serial_early_puts("Baudrate init\n");
 271        init_baudrate();
 272        serial_early_puts("Serial init\n");
 273        serial_init();
 274        serial_early_puts("Console init flash\n");
 275        console_init_f();
 276        serial_early_puts("End of early debugging\n");
 277        display_banner();
 278
 279        checkboard();
 280        timer_init();
 281
 282        printf("Clock: VCO: %s MHz, ", strmhz(buf, get_vco()));
 283        printf("Core: %s MHz, ", strmhz(buf, get_cclk()));
 284        printf("System: %s MHz\n", strmhz(buf, get_sclk()));
 285
 286        printf("RAM:   ");
 287        print_size(bd->bi_memsize, "\n");
 288#if defined(CONFIG_POST)
 289        post_init_f();
 290        post_bootmode_init();
 291        post_run(NULL, POST_ROM | post_bootmode_get(0));
 292#endif
 293
 294        board_init_r((gd_t *) gd, 0x20000010);
 295}
 296
 297static void board_net_init_r(bd_t *bd)
 298{
 299#ifdef CONFIG_BITBANGMII
 300        bb_miiphy_init();
 301#endif
 302#ifdef CONFIG_CMD_NET
 303        char *s;
 304
 305        if ((s = getenv("bootfile")) != NULL)
 306                copy_filename(BootFile, s, sizeof(BootFile));
 307
 308        bd->bi_ip_addr = getenv_IPaddr("ipaddr");
 309
 310        printf("Net:   ");
 311        eth_initialize(gd->bd);
 312#endif
 313}
 314
 315void board_init_r(gd_t * id, ulong dest_addr)
 316{
 317        char *s;
 318        bd_t *bd;
 319        gd = id;
 320        gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
 321        bd = gd->bd;
 322
 323#if defined(CONFIG_POST)
 324        post_output_backlog();
 325#endif
 326
 327        /* initialize malloc() area */
 328        mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
 329
 330#if     !defined(CONFIG_SYS_NO_FLASH)
 331        /* Initialize the flash and protect u-boot by default */
 332        extern flash_info_t flash_info[];
 333        puts("Flash: ");
 334        ulong size = flash_init();
 335        print_size(size, "\n");
 336        flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH_BASE,
 337                CONFIG_SYS_FLASH_BASE + CONFIG_SYS_MONITOR_LEN - 1,
 338                &flash_info[0]);
 339        bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 340        bd->bi_flashsize = size;
 341        bd->bi_flashoffset = 0;
 342#else
 343        bd->bi_flashstart = 0;
 344        bd->bi_flashsize = 0;
 345        bd->bi_flashoffset = 0;
 346#endif
 347
 348#ifdef CONFIG_CMD_NAND
 349        puts("NAND:  ");
 350        nand_init();            /* go init the NAND */
 351#endif
 352
 353#ifdef CONFIG_GENERIC_MMC
 354        puts("MMC:   ");
 355        mmc_initialize(bd);
 356#endif
 357
 358        /* relocate environment function pointers etc. */
 359        env_relocate();
 360
 361        /* Initialize stdio devices */
 362        stdio_init();
 363        jumptable_init();
 364
 365        /* Initialize the console (after the relocation and devices init) */
 366        console_init_r();
 367
 368#ifdef CONFIG_CMD_KGDB
 369        puts("KGDB:  ");
 370        kgdb_init();
 371#endif
 372
 373#ifdef CONFIG_STATUS_LED
 374        status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
 375        status_led_set(STATUS_LED_CRASH, STATUS_LED_OFF);
 376#endif
 377
 378        /* Initialize from environment */
 379        if ((s = getenv("loadaddr")) != NULL)
 380                load_addr = simple_strtoul(s, NULL, 16);
 381
 382#if defined(CONFIG_MISC_INIT_R)
 383        /* miscellaneous platform dependent initialisations */
 384        misc_init_r();
 385#endif
 386
 387        board_net_init_r(bd);
 388
 389        display_global_data();
 390
 391#if defined(CONFIG_POST)
 392        if (post_flag)
 393                post_run(NULL, POST_RAM | post_bootmode_get(0));
 394#endif
 395
 396        if (bfin_os_log_check()) {
 397                puts("\nLog buffer from operating system:\n");
 398                bfin_os_log_dump();
 399                puts("\n");
 400        }
 401
 402        /* main_loop() can return to retry autoboot, if so just run it again. */
 403        for (;;)
 404                main_loop();
 405}
 406
 407void hang(void)
 408{
 409#ifdef CONFIG_STATUS_LED
 410        status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
 411        status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING);
 412#endif
 413        puts("### ERROR ### Please RESET the board ###\n");
 414        while (1)
 415                /* If a JTAG emulator is hooked up, we'll automatically trigger
 416                 * a breakpoint in it.  If one isn't, this is just a NOP.
 417                 */
 418                asm("emuexcpt;");
 419}
 420