uboot/arch/nds32/lib/board.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002-2006
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * Copyright (C) 2011 Andes Technology Corporation
   6 * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
   7 * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
   8 *
   9 * See file CREDITS for list of people who contributed to this
  10 * project.
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation; either version 2 of
  15 * the License, or (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25 * MA 02111-1307 USA
  26 */
  27
  28#include <common.h>
  29#include <command.h>
  30#include <malloc.h>
  31#include <stdio_dev.h>
  32#include <timestamp.h>
  33#include <version.h>
  34#include <net.h>
  35#include <serial.h>
  36#include <nand.h>
  37#include <onenand_uboot.h>
  38#include <mmc.h>
  39
  40DECLARE_GLOBAL_DATA_PTR;
  41
  42ulong monitor_flash_len;
  43
  44/*
  45 * Init Utilities
  46 */
  47
  48#if !defined(CONFIG_BAUDRATE)
  49#define CONFIG_BAUDRATE 38400
  50#endif
  51static int init_baudrate(void)
  52{
  53        gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
  54        return 0;
  55}
  56
  57/*
  58 * WARNING: this code looks "cleaner" than the PowerPC version, but
  59 * has the disadvantage that you either get nothing, or everything.
  60 * On PowerPC, you might see "DRAM: " before the system hangs - which
  61 * gives a simple yet clear indication which part of the
  62 * initialization if failing.
  63 */
  64static int display_dram_config(void)
  65{
  66        int i;
  67
  68#ifdef DEBUG
  69        puts("RAM Configuration:\n");
  70
  71        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
  72                printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
  73                print_size(gd->bd->bi_dram[i].size, "\n");
  74        }
  75#else
  76        ulong size = 0;
  77
  78        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
  79                size += gd->bd->bi_dram[i].size;
  80
  81        puts("DRAM:  ");
  82        print_size(size, "\n");
  83#endif
  84
  85        return 0;
  86}
  87
  88#ifndef CONFIG_SYS_NO_FLASH
  89static void display_flash_config(ulong size)
  90{
  91        puts("Flash: ");
  92        print_size(size, "\n");
  93}
  94#endif /* CONFIG_SYS_NO_FLASH */
  95
  96#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
  97#include <pci.h>
  98static int nds32_pci_init(void)
  99{
 100        pci_init();
 101        return 0;
 102}
 103#endif /* CONFIG_CMD_PCI || CONFIG_PCI */
 104
 105#if defined(CONFIG_PMU) || defined(CONFIG_PCU)
 106#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 107static int pmu_init(void)
 108{
 109#if defined(CONFIG_FTPMU010_POWER)
 110#ifdef __NDS32_N1213_43U1H__    /* AG101: internal definition in toolchain */
 111        ftpmu010_sdram_clk_disable(CONFIG_SYS_FTPMU010_PDLLCR0_HCLKOUTDIS);
 112        ftpmu010_mfpsr_select_dev(FTPMU010_MFPSR_AC97CLKSEL);
 113        ftpmu010_sdramhtc_set(CONFIG_SYS_FTPMU010_SDRAMHTC);
 114#endif  /* __NDS32_N1213_43U1H__ */
 115#endif
 116        return 0;
 117}
 118#endif
 119#endif
 120
 121/*
 122 * Breathe some life into the board...
 123 *
 124 * Initialize a serial port as console, and carry out some hardware
 125 * tests.
 126 *
 127 * The first part of initialization is running from Flash memory;
 128 * its main purpose is to initialize the RAM so that we
 129 * can relocate the monitor code to RAM.
 130 */
 131
 132/*
 133 * All attempts to come up with a "common" initialization sequence
 134 * that works for all boards and architectures failed: some of the
 135 * requirements are just _too_ different. To get rid of the resulting
 136 * mess of board dependent #ifdef'ed code we now make the whole
 137 * initialization sequence configurable to the user.
 138 *
 139 * The requirements for any new initalization function is simple: it
 140 * receives a pointer to the "global data" structure as it's only
 141 * argument, and returns an integer return code, where 0 means
 142 * "continue" and != 0 means "fatal error, hang the system".
 143 */
 144typedef int (init_fnc_t)(void);
 145
 146void __dram_init_banksize(void)
 147{
 148        gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
 149        gd->bd->bi_dram[0].size =  gd->ram_size;
 150}
 151void dram_init_banksize(void)
 152        __attribute__((weak, alias("__dram_init_banksize")));
 153
 154init_fnc_t *init_sequence[] = {
 155#if defined(CONFIG_ARCH_CPU_INIT)
 156        arch_cpu_init,          /* basic arch cpu dependent setup */
 157#endif
 158#if defined(CONFIG_PMU) || defined(CONFIG_PCU)
 159#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 160        pmu_init,
 161#endif
 162#endif
 163        board_init,             /* basic board dependent setup */
 164#if defined(CONFIG_USE_IRQ)
 165        interrupt_init,         /* set up exceptions */
 166#endif
 167        timer_init,             /* initialize timer */
 168        env_init,               /* initialize environment */
 169        init_baudrate,          /* initialze baudrate settings */
 170        serial_init,            /* serial communications setup */
 171        console_init_f,         /* stage 1 init of console */
 172#if defined(CONFIG_DISPLAY_BOARDINFO)
 173        checkboard,             /* display board info */
 174#endif
 175#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 176        init_func_i2c,
 177#endif
 178        dram_init,              /* configure available RAM banks */
 179        display_dram_config,
 180        NULL,
 181};
 182
 183void board_init_f(ulong bootflag)
 184{
 185        bd_t *bd;
 186        init_fnc_t **init_fnc_ptr;
 187        gd_t *id;
 188        ulong addr, addr_sp;
 189
 190        /* Pointer is writable since we allocated a register for it */
 191        gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
 192
 193        memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 194
 195        gd->mon_len = (unsigned int)(&__bss_end__) - (unsigned int)(&_start);
 196
 197        for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 198                if ((*init_fnc_ptr)() != 0)
 199                        hang();
 200        }
 201
 202        debug("monitor len: %08lX\n", gd->mon_len);
 203        /*
 204         * Ram is setup, size stored in gd !!
 205         */
 206        debug("ramsize: %08lX\n", gd->ram_size);
 207
 208        addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
 209
 210#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 211        /* reserve TLB table */
 212        addr -= (4096 * 4);
 213
 214        /* round down to next 64 kB limit */
 215        addr &= ~(0x10000 - 1);
 216
 217        gd->tlb_addr = addr;
 218        debug("TLB table at: %08lx\n", addr);
 219#endif
 220
 221        /* round down to next 4 kB limit */
 222        addr &= ~(4096 - 1);
 223        debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
 224
 225#ifdef CONFIG_LCD
 226#ifdef CONFIG_FB_ADDR
 227        gd->fb_base = CONFIG_FB_ADDR;
 228#else
 229        /* reserve memory for LCD display (always full pages) */
 230        addr = lcd_setmem(addr);
 231        gd->fb_base = addr;
 232#endif /* CONFIG_FB_ADDR */
 233#endif /* CONFIG_LCD */
 234
 235        /*
 236         * reserve memory for U-Boot code, data & bss
 237         * round down to next 4 kB limit
 238         */
 239        addr -= gd->mon_len;
 240        addr &= ~(4096 - 1);
 241
 242        debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
 243
 244        /*
 245         * reserve memory for malloc() arena
 246         */
 247        addr_sp = addr - TOTAL_MALLOC_LEN;
 248        debug("Reserving %dk for malloc() at: %08lx\n",
 249                        TOTAL_MALLOC_LEN >> 10, addr_sp);
 250        /*
 251         * (permanently) allocate a Board Info struct
 252         * and a permanent copy of the "global" data
 253         */
 254        addr_sp -= GENERATED_BD_INFO_SIZE;
 255        bd = (bd_t *) addr_sp;
 256        gd->bd = bd;
 257        memset((void *)bd, 0, GENERATED_BD_INFO_SIZE);
 258        debug("Reserving %zu Bytes for Board Info at: %08lx\n",
 259                        GENERATED_BD_INFO_SIZE, addr_sp);
 260
 261        addr_sp -= GENERATED_GBL_DATA_SIZE;
 262        id = (gd_t *) addr_sp;
 263        debug("Reserving %zu Bytes for Global Data at: %08lx\n",
 264                        GENERATED_GBL_DATA_SIZE, addr_sp);
 265
 266        /* setup stackpointer for exeptions */
 267        gd->irq_sp = addr_sp;
 268#ifdef CONFIG_USE_IRQ
 269        addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
 270        debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
 271                CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp);
 272#endif
 273        /* leave 3 words for abort-stack    */
 274        addr_sp -= 12;
 275
 276        /* 8-byte alignment for ABI compliance */
 277        addr_sp &= ~0x07;
 278        debug("New Stack Pointer is: %08lx\n", addr_sp);
 279
 280        gd->bd->bi_baudrate = gd->baudrate;
 281        /* Ram isn't board specific, so move it to board code ... */
 282        dram_init_banksize();
 283        display_dram_config();  /* and display it */
 284
 285        gd->relocaddr = addr;
 286        gd->start_addr_sp = addr_sp;
 287
 288        gd->reloc_off = addr - _TEXT_BASE;
 289
 290        debug("relocation Offset is: %08lx\n", gd->reloc_off);
 291        memcpy(id, (void *)gd, GENERATED_GBL_DATA_SIZE);
 292
 293        relocate_code(addr_sp, id, addr);
 294
 295        /* NOTREACHED - relocate_code() does not return */
 296}
 297
 298/*
 299 * This is the next part if the initialization sequence: we are now
 300 * running from RAM and have a "normal" C environment, i. e. global
 301 * data can be written, BSS has been cleared, the stack size in not
 302 * that critical any more, etc.
 303 */
 304void board_init_r(gd_t *id, ulong dest_addr)
 305{
 306        bd_t *bd;
 307        ulong malloc_start;
 308
 309        gd = id;
 310        bd = gd->bd;
 311
 312        gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
 313
 314        monitor_flash_len = &_end - &_start;
 315        debug("monitor flash len: %08lX\n", monitor_flash_len);
 316
 317        board_init();   /* Setup chipselects */
 318
 319#if defined(CONFIG_NEEDS_MANUAL_RELOC)
 320        /*
 321         * We have to relocate the command table manually
 322         */
 323        fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd),
 324                        ll_entry_count(cmd_tbl_t, cmd));
 325#endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */
 326
 327        serial_initialize();
 328
 329        debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
 330
 331        /* The Malloc area is immediately below the monitor copy in DRAM */
 332        malloc_start = dest_addr - TOTAL_MALLOC_LEN;
 333        mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN);
 334        malloc_bin_reloc();
 335
 336#ifndef CONFIG_SYS_NO_FLASH
 337        /* configure available FLASH banks */
 338        gd->bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 339        gd->bd->bi_flashsize = flash_init();
 340        gd->bd->bi_flashoffset = CONFIG_SYS_FLASH_BASE + gd->bd->bi_flashsize;
 341
 342        if (gd->bd->bi_flashsize)
 343                        display_flash_config(gd->bd->bi_flashsize);
 344#endif /* CONFIG_SYS_NO_FLASH */
 345
 346#if defined(CONFIG_CMD_NAND)
 347        puts("NAND:  ");
 348        nand_init();            /* go init the NAND */
 349#endif
 350
 351#if defined(CONFIG_CMD_IDE)
 352        puts("IDE:   ");
 353        ide_init();
 354#endif
 355
 356#ifdef CONFIG_GENERIC_MMC
 357        puts("MMC:   ");
 358        mmc_initialize(gd->bd);
 359#endif
 360
 361        /* initialize environment */
 362        env_relocate();
 363
 364#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
 365        puts("PCI:   ");
 366        nds32_pci_init();
 367#endif
 368
 369        stdio_init();   /* get the devices list going. */
 370
 371        jumptable_init();
 372
 373#if defined(CONFIG_API)
 374        /* Initialize API */
 375        api_init();
 376#endif
 377
 378        console_init_r();       /* fully init console as a device */
 379
 380#if defined(CONFIG_ARCH_MISC_INIT)
 381        /* miscellaneous arch dependent initialisations */
 382        arch_misc_init();
 383#endif
 384#if defined(CONFIG_MISC_INIT_R)
 385        /* miscellaneous platform dependent initialisations */
 386        misc_init_r();
 387#endif
 388
 389#if defined(CONFIG_USE_IRQ)
 390        /* set up exceptions */
 391        interrupt_init();
 392        /* enable exceptions */
 393        enable_interrupts();
 394#endif
 395
 396        /* Initialize from environment */
 397        load_addr = getenv_ulong("loadaddr", 16, load_addr);
 398
 399#ifdef CONFIG_BOARD_LATE_INIT
 400        board_late_init();
 401#endif
 402
 403#if defined(CONFIG_CMD_NET)
 404        puts("Net:   ");
 405
 406        eth_initialize(gd->bd);
 407#if defined(CONFIG_RESET_PHY_R)
 408        debug("Reset Ethernet PHY\n");
 409        reset_phy();
 410#endif
 411#endif
 412
 413        /* main_loop() can return to retry autoboot, if so just run it again. */
 414        for (;;)
 415                main_loop();
 416
 417        /* NOTREACHED - no way out of command loop except booting */
 418}
 419
 420void hang(void)
 421{
 422        puts("### ERROR ### Please RESET the board ###\n");
 423        for (;;)
 424                ;
 425}
 426