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        bd_t *bd;
 211        char buf[32];
 212
 213#ifdef CONFIG_BOARD_EARLY_INIT_F
 214        serial_early_puts("Board early init flash\n");
 215        board_early_init_f();
 216#endif
 217
 218        serial_early_puts("Init CPLB tables\n");
 219        init_cplbtables();
 220
 221        serial_early_puts("Exceptions setup\n");
 222        exception_init();
 223
 224#ifndef CONFIG_ICACHE_OFF
 225        serial_early_puts("Turn on ICACHE\n");
 226        icache_enable();
 227#endif
 228#ifndef CONFIG_DCACHE_OFF
 229        serial_early_puts("Turn on DCACHE\n");
 230        dcache_enable();
 231#endif
 232
 233#ifdef CONFIG_WATCHDOG
 234        serial_early_puts("Setting up external watchdog\n");
 235        watchdog_init();
 236#endif
 237
 238#ifdef DEBUG
 239        if (GENERATED_GBL_DATA_SIZE < sizeof(*gd))
 240                hang();
 241#endif
 242        serial_early_puts("Init global data\n");
 243        gd = (gd_t *) (CONFIG_SYS_GBL_DATA_ADDR);
 244        memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 245
 246        bd = (bd_t *) (CONFIG_SYS_BD_INFO_ADDR);
 247        gd->bd = bd;
 248        memset((void *)bd, 0, GENERATED_BD_INFO_SIZE);
 249
 250        bd->bi_r_version = version_string;
 251        bd->bi_cpu = MK_STR(CONFIG_BFIN_CPU);
 252        bd->bi_board_name = BFIN_BOARD_NAME;
 253        bd->bi_vco = get_vco();
 254        bd->bi_cclk = get_cclk();
 255        bd->bi_sclk = get_sclk();
 256        bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 257        bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
 258
 259        /* Initialize */
 260        serial_early_puts("IRQ init\n");
 261        irq_init();
 262        serial_early_puts("Environment init\n");
 263        env_init();
 264        serial_early_puts("Baudrate init\n");
 265        init_baudrate();
 266        serial_early_puts("Serial init\n");
 267        serial_init();
 268        serial_early_puts("Console init flash\n");
 269        console_init_f();
 270        serial_early_puts("End of early debugging\n");
 271        display_banner();
 272
 273        checkboard();
 274        timer_init();
 275
 276        printf("Clock: VCO: %s MHz, ", strmhz(buf, get_vco()));
 277        printf("Core: %s MHz, ", strmhz(buf, get_cclk()));
 278        printf("System: %s MHz\n", strmhz(buf, get_sclk()));
 279
 280        if (CONFIG_MEM_SIZE) {
 281                printf("RAM:   ");
 282                print_size(bd->bi_memsize, "\n");
 283        }
 284
 285#if defined(CONFIG_POST)
 286        post_init_f();
 287        post_bootmode_init();
 288        post_run(NULL, POST_ROM | post_bootmode_get(0));
 289#endif
 290
 291        board_init_r((gd_t *) gd, 0x20000010);
 292}
 293
 294static void board_net_init_r(bd_t *bd)
 295{
 296#ifdef CONFIG_BITBANGMII
 297        bb_miiphy_init();
 298#endif
 299#ifdef CONFIG_CMD_NET
 300        char *s;
 301
 302        if ((s = getenv("bootfile")) != NULL)
 303                copy_filename(BootFile, s, sizeof(BootFile));
 304
 305        bd->bi_ip_addr = getenv_IPaddr("ipaddr");
 306
 307        printf("Net:   ");
 308        eth_initialize(gd->bd);
 309#endif
 310}
 311
 312void board_init_r(gd_t * id, ulong dest_addr)
 313{
 314        char *s;
 315        bd_t *bd;
 316        gd = id;
 317        gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
 318        bd = gd->bd;
 319
 320#if defined(CONFIG_POST)
 321        post_output_backlog();
 322#endif
 323
 324        /* initialize malloc() area */
 325        mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
 326
 327#if     !defined(CONFIG_SYS_NO_FLASH)
 328        /* Initialize the flash and protect u-boot by default */
 329        extern flash_info_t flash_info[];
 330        puts("Flash: ");
 331        ulong size = flash_init();
 332        print_size(size, "\n");
 333        flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH_BASE,
 334                CONFIG_SYS_FLASH_BASE + CONFIG_SYS_MONITOR_LEN - 1,
 335                &flash_info[0]);
 336        bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 337        bd->bi_flashsize = size;
 338        bd->bi_flashoffset = 0;
 339#else
 340        bd->bi_flashstart = 0;
 341        bd->bi_flashsize = 0;
 342        bd->bi_flashoffset = 0;
 343#endif
 344
 345#ifdef CONFIG_CMD_NAND
 346        puts("NAND:  ");
 347        nand_init();            /* go init the NAND */
 348#endif
 349
 350#ifdef CONFIG_GENERIC_MMC
 351        puts("MMC:   ");
 352        mmc_initialize(bd);
 353#endif
 354
 355        /* relocate environment function pointers etc. */
 356        env_relocate();
 357
 358        /* Initialize stdio devices */
 359        stdio_init();
 360        jumptable_init();
 361
 362        /* Initialize the console (after the relocation and devices init) */
 363        console_init_r();
 364
 365#ifdef CONFIG_CMD_KGDB
 366        puts("KGDB:  ");
 367        kgdb_init();
 368#endif
 369
 370#ifdef CONFIG_STATUS_LED
 371        status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
 372        status_led_set(STATUS_LED_CRASH, STATUS_LED_OFF);
 373#endif
 374
 375        /* Initialize from environment */
 376        if ((s = getenv("loadaddr")) != NULL)
 377                load_addr = simple_strtoul(s, NULL, 16);
 378
 379#if defined(CONFIG_MISC_INIT_R)
 380        /* miscellaneous platform dependent initialisations */
 381        misc_init_r();
 382#endif
 383
 384        board_net_init_r(bd);
 385
 386        display_global_data();
 387
 388#if defined(CONFIG_POST)
 389        if (post_flag)
 390                post_run(NULL, POST_RAM | post_bootmode_get(0));
 391#endif
 392
 393        if (CONFIG_MEM_SIZE && bfin_os_log_check()) {
 394                puts("\nLog buffer from operating system:\n");
 395                bfin_os_log_dump();
 396                puts("\n");
 397        }
 398
 399        /* main_loop() can return to retry autoboot, if so just run it again. */
 400        for (;;)
 401                main_loop();
 402}
 403
 404void hang(void)
 405{
 406#ifdef CONFIG_STATUS_LED
 407        status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
 408        status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING);
 409#endif
 410        puts("### ERROR ### Please RESET the board ###\n");
 411        while (1)
 412                /* If a JTAG emulator is hooked up, we'll automatically trigger
 413                 * a breakpoint in it.  If one isn't, this is just a NOP.
 414                 */
 415                asm("emuexcpt;");
 416}
 417