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