uboot/arch/avr32/lib/board.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2004-2006 Atmel Corporation
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22#include <common.h>
  23#include <command.h>
  24#include <malloc.h>
  25#include <stdio_dev.h>
  26#include <version.h>
  27#include <net.h>
  28#include <atmel_mci.h>
  29
  30#ifdef CONFIG_BITBANGMII
  31#include <miiphy.h>
  32#endif
  33
  34#include <asm/sections.h>
  35#include <asm/arch/mmu.h>
  36#include <asm/arch/hardware.h>
  37
  38#ifndef CONFIG_IDENT_STRING
  39#define CONFIG_IDENT_STRING ""
  40#endif
  41
  42#ifdef CONFIG_GENERIC_ATMEL_MCI
  43#include <mmc.h>
  44#endif
  45DECLARE_GLOBAL_DATA_PTR;
  46
  47unsigned long monitor_flash_len;
  48
  49/* Weak aliases for optional board functions */
  50static int __do_nothing(void)
  51{
  52        return 0;
  53}
  54int board_postclk_init(void) __attribute__((weak, alias("__do_nothing")));
  55int board_early_init_r(void) __attribute__((weak, alias("__do_nothing")));
  56
  57/* provide cpu_mmc_init, to overwrite provide board_mmc_init */
  58int cpu_mmc_init(bd_t *bd)
  59{
  60        /* This calls the atmel_mci_init in gen_atmel_mci.c */
  61        return atmel_mci_init((void *)ATMEL_BASE_MMCI);
  62}
  63
  64#ifdef CONFIG_SYS_DMA_ALLOC_LEN
  65#include <asm/arch/cacheflush.h>
  66#include <asm/io.h>
  67
  68static unsigned long dma_alloc_start;
  69static unsigned long dma_alloc_end;
  70static unsigned long dma_alloc_brk;
  71
  72static void dma_alloc_init(void)
  73{
  74        unsigned long monitor_addr;
  75
  76        monitor_addr = CONFIG_SYS_MONITOR_BASE + gd->reloc_off;
  77        dma_alloc_end = monitor_addr - CONFIG_SYS_MALLOC_LEN;
  78        dma_alloc_start = dma_alloc_end - CONFIG_SYS_DMA_ALLOC_LEN;
  79        dma_alloc_brk = dma_alloc_start;
  80
  81        printf("DMA: Using memory from 0x%08lx to 0x%08lx\n",
  82               dma_alloc_start, dma_alloc_end);
  83
  84        dcache_invalidate_range(cached(dma_alloc_start),
  85                                dma_alloc_end - dma_alloc_start);
  86}
  87
  88void *dma_alloc_coherent(size_t len, unsigned long *handle)
  89{
  90        unsigned long paddr = dma_alloc_brk;
  91
  92        if (dma_alloc_brk + len > dma_alloc_end)
  93                return NULL;
  94
  95        dma_alloc_brk = ((paddr + len + CONFIG_SYS_DCACHE_LINESZ - 1)
  96                         & ~(CONFIG_SYS_DCACHE_LINESZ - 1));
  97
  98        *handle = paddr;
  99        return uncached(paddr);
 100}
 101#else
 102static inline void dma_alloc_init(void)
 103{
 104
 105}
 106#endif
 107
 108static int init_baudrate(void)
 109{
 110        gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
 111        return 0;
 112}
 113
 114static int display_banner (void)
 115{
 116        printf ("\n\n%s\n\n", version_string);
 117        printf ("U-Boot code: %08lx -> %08lx  data: %08lx -> %08lx\n",
 118                (unsigned long)_text, (unsigned long)_etext,
 119                (unsigned long)_data, (unsigned long)__bss_end);
 120        return 0;
 121}
 122
 123void hang(void)
 124{
 125        for (;;) ;
 126}
 127
 128static int display_dram_config (void)
 129{
 130        int i;
 131
 132        puts ("DRAM Configuration:\n");
 133
 134        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 135                printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
 136                print_size (gd->bd->bi_dram[i].size, "\n");
 137        }
 138
 139        return 0;
 140}
 141
 142static void display_flash_config (void)
 143{
 144        puts ("Flash: ");
 145        print_size(gd->bd->bi_flashsize, " ");
 146        printf("at address 0x%08lx\n", gd->bd->bi_flashstart);
 147}
 148
 149void board_init_f(ulong board_type)
 150{
 151        gd_t gd_data;
 152        gd_t *new_gd;
 153        bd_t *bd;
 154        unsigned long *new_sp;
 155        unsigned long monitor_len;
 156        unsigned long monitor_addr;
 157        unsigned long addr;
 158        long sdram_size;
 159
 160        /* Initialize the global data pointer */
 161        memset(&gd_data, 0, sizeof(gd_data));
 162        gd = &gd_data;
 163
 164        /* Perform initialization sequence */
 165        board_early_init_f();
 166        cpu_init();
 167        board_postclk_init();
 168        env_init();
 169        init_baudrate();
 170        serial_init();
 171        console_init_f();
 172        display_banner();
 173        sdram_size = initdram(board_type);
 174
 175        /* If we have no SDRAM, we can't go on */
 176        if (sdram_size <= 0)
 177                panic("No working SDRAM available\n");
 178
 179        /*
 180         * Now that we have DRAM mapped and working, we can
 181         * relocate the code and continue running from DRAM.
 182         *
 183         * Reserve memory at end of RAM for (top down in that order):
 184         *  - u-boot image
 185         *  - heap for malloc()
 186         *  - board info struct
 187         *  - global data struct
 188         *  - stack
 189         */
 190        addr = CONFIG_SYS_SDRAM_BASE + sdram_size;
 191        monitor_len = (char *)__bss_end - _text;
 192
 193        /*
 194         * Reserve memory for u-boot code, data and bss.
 195         * Round down to next 4 kB limit.
 196         */
 197        addr -= monitor_len;
 198        addr &= ~(4096UL - 1);
 199        monitor_addr = addr;
 200
 201        /* Reserve memory for malloc() */
 202        addr -= CONFIG_SYS_MALLOC_LEN;
 203
 204#ifdef CONFIG_SYS_DMA_ALLOC_LEN
 205        /* Reserve DMA memory (must be cache aligned) */
 206        addr &= ~(CONFIG_SYS_DCACHE_LINESZ - 1);
 207        addr -= CONFIG_SYS_DMA_ALLOC_LEN;
 208#endif
 209
 210#ifdef CONFIG_LCD
 211#ifdef CONFIG_FB_ADDR
 212        printf("LCD: Frame buffer allocated at preset 0x%08x\n",
 213               CONFIG_FB_ADDR);
 214        gd->fb_base = CONFIG_FB_ADDR;
 215#else
 216        addr = lcd_setmem(addr);
 217        printf("LCD: Frame buffer allocated at 0x%08lx\n", addr);
 218        gd->fb_base = addr;
 219#endif /* CONFIG_FB_ADDR */
 220#endif /* CONFIG_LCD */
 221
 222        /* Allocate a Board Info struct on a word boundary */
 223        addr -= sizeof(bd_t);
 224        addr &= ~3UL;
 225        gd->bd = bd = (bd_t *)addr;
 226
 227        /* Allocate a new global data copy on a 8-byte boundary. */
 228        addr -= sizeof(gd_t);
 229        addr &= ~7UL;
 230        new_gd = (gd_t *)addr;
 231
 232        /* And finally, a new, bigger stack. */
 233        new_sp = (unsigned long *)addr;
 234        gd->arch.stack_end = addr;
 235        *(--new_sp) = 0;
 236        *(--new_sp) = 0;
 237
 238        /*
 239         * Initialize the board information struct with the
 240         * information we have.
 241         */
 242        bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
 243        bd->bi_dram[0].size = sdram_size;
 244        bd->bi_baudrate = gd->baudrate;
 245
 246        memcpy(new_gd, gd, sizeof(gd_t));
 247
 248        relocate_code((unsigned long)new_sp, new_gd, monitor_addr);
 249}
 250
 251void board_init_r(gd_t *new_gd, ulong dest_addr)
 252{
 253#ifndef CONFIG_ENV_IS_NOWHERE
 254        extern char * env_name_spec;
 255#endif
 256        bd_t *bd;
 257
 258        gd = new_gd;
 259        bd = gd->bd;
 260
 261        gd->flags |= GD_FLG_RELOC;
 262        gd->reloc_off = dest_addr - CONFIG_SYS_MONITOR_BASE;
 263
 264        /* Enable the MMU so that we can keep u-boot simple */
 265        mmu_init_r(dest_addr);
 266
 267        board_early_init_r();
 268
 269        monitor_flash_len = _edata - _text;
 270
 271#if defined(CONFIG_NEEDS_MANUAL_RELOC)
 272        /*
 273         * We have to relocate the command table manually
 274         */
 275        fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd),
 276                        ll_entry_count(cmd_tbl_t, cmd));
 277#endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */
 278
 279        /* there are some other pointer constants we must deal with */
 280#ifndef CONFIG_ENV_IS_NOWHERE
 281        env_name_spec += gd->reloc_off;
 282#endif
 283
 284        timer_init();
 285
 286        /* The malloc area is right below the monitor image in RAM */
 287        mem_malloc_init(CONFIG_SYS_MONITOR_BASE + gd->reloc_off -
 288                        CONFIG_SYS_MALLOC_LEN, CONFIG_SYS_MALLOC_LEN);
 289        dma_alloc_init();
 290
 291        enable_interrupts();
 292
 293        bd->bi_flashstart = 0;
 294        bd->bi_flashsize = 0;
 295        bd->bi_flashoffset = 0;
 296
 297#ifndef CONFIG_SYS_NO_FLASH
 298        bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 299        bd->bi_flashsize = flash_init();
 300        bd->bi_flashoffset = (unsigned long)_edata - (unsigned long)_text;
 301
 302        if (bd->bi_flashsize)
 303                display_flash_config();
 304#endif
 305
 306        if (bd->bi_dram[0].size)
 307                display_dram_config();
 308
 309        gd->bd->bi_boot_params = malloc(CONFIG_SYS_BOOTPARAMS_LEN);
 310        if (!gd->bd->bi_boot_params)
 311                puts("WARNING: Cannot allocate space for boot parameters\n");
 312
 313        /* initialize environment */
 314        env_relocate();
 315
 316        stdio_init();
 317        jumptable_init();
 318        console_init_r();
 319
 320        /* Initialize from environment */
 321        load_addr = getenv_ulong("loadaddr", 16, load_addr);
 322
 323#ifdef CONFIG_BITBANGMII
 324        bb_miiphy_init();
 325#endif
 326#if defined(CONFIG_CMD_NET)
 327        puts("Net:   ");
 328        eth_initialize(gd->bd);
 329#endif
 330
 331#ifdef CONFIG_GENERIC_ATMEL_MCI
 332        mmc_initialize(gd->bd);
 333#endif
 334        for (;;) {
 335                main_loop();
 336        }
 337}
 338