1d47ab0ecSGraeme Russ /* 2d47ab0ecSGraeme Russ * (C) Copyright 2011 3d47ab0ecSGraeme Russ * Graeme Russ, <graeme.russ@gmail.com> 4d47ab0ecSGraeme Russ * 5d47ab0ecSGraeme Russ * See file CREDITS for list of people who contributed to this 6d47ab0ecSGraeme Russ * project. 7d47ab0ecSGraeme Russ * 8d47ab0ecSGraeme Russ * This program is free software; you can redistribute it and/or 9d47ab0ecSGraeme Russ * modify it under the terms of the GNU General Public License as 10d47ab0ecSGraeme Russ * published by the Free Software Foundation; either version 2 of 11d47ab0ecSGraeme Russ * the License, or (at your option) any later version. 12d47ab0ecSGraeme Russ * 13d47ab0ecSGraeme Russ * This program is distributed in the hope that it will be useful, 14d47ab0ecSGraeme Russ * but WITHOUT ANY WARRANTY; without even the implied warranty of 15d47ab0ecSGraeme Russ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16d47ab0ecSGraeme Russ * GNU General Public License for more details. 17d47ab0ecSGraeme Russ * 18d47ab0ecSGraeme Russ * You should have received a copy of the GNU General Public License 19d47ab0ecSGraeme Russ * along with this program; if not, write to the Free Software 20d47ab0ecSGraeme Russ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21d47ab0ecSGraeme Russ * MA 02111-1307 USA 22d47ab0ecSGraeme Russ */ 23d47ab0ecSGraeme Russ #include <common.h> 24d47ab0ecSGraeme Russ #include <command.h> 25d47ab0ecSGraeme Russ #include <stdio_dev.h> 26d47ab0ecSGraeme Russ #include <version.h> 27d47ab0ecSGraeme Russ #include <malloc.h> 28d47ab0ecSGraeme Russ #include <net.h> 29d47ab0ecSGraeme Russ #include <ide.h> 30d47ab0ecSGraeme Russ #include <serial.h> 318313315bSGabe Black #include <spi.h> 32d47ab0ecSGraeme Russ #include <status_led.h> 33a1d57b7aSGraeme Russ #include <asm/processor.h> 34d47ab0ecSGraeme Russ #include <asm/u-boot-x86.h> 35d65297b6SGabe Black #include <linux/compiler.h> 36d47ab0ecSGraeme Russ 37d47ab0ecSGraeme Russ #include <asm/init_helpers.h> 38d47ab0ecSGraeme Russ 39d47ab0ecSGraeme Russ DECLARE_GLOBAL_DATA_PTR; 40d47ab0ecSGraeme Russ 41d47ab0ecSGraeme Russ /************************************************************************ 42d47ab0ecSGraeme Russ * Init Utilities * 43d47ab0ecSGraeme Russ ************************************************************************ 44d47ab0ecSGraeme Russ * Some of this code should be moved into the core functions, 45d47ab0ecSGraeme Russ * or dropped completely, 46d47ab0ecSGraeme Russ * but let's get it working (again) first... 47d47ab0ecSGraeme Russ */ 48d47ab0ecSGraeme Russ 49d47ab0ecSGraeme Russ int display_banner(void) 50d47ab0ecSGraeme Russ { 51d47ab0ecSGraeme Russ printf("\n\n%s\n\n", version_string); 52d47ab0ecSGraeme Russ 53d47ab0ecSGraeme Russ return 0; 54d47ab0ecSGraeme Russ } 55d47ab0ecSGraeme Russ 56d47ab0ecSGraeme Russ int display_dram_config(void) 57d47ab0ecSGraeme Russ { 58d47ab0ecSGraeme Russ int i; 59d47ab0ecSGraeme Russ 60d47ab0ecSGraeme Russ puts("DRAM Configuration:\n"); 61d47ab0ecSGraeme Russ 62d47ab0ecSGraeme Russ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 63d47ab0ecSGraeme Russ printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); 64d47ab0ecSGraeme Russ print_size(gd->bd->bi_dram[i].size, "\n"); 65d47ab0ecSGraeme Russ } 66d47ab0ecSGraeme Russ 67d47ab0ecSGraeme Russ return 0; 68d47ab0ecSGraeme Russ } 69d47ab0ecSGraeme Russ 70d47ab0ecSGraeme Russ int init_baudrate_f(void) 71d47ab0ecSGraeme Russ { 72d47ab0ecSGraeme Russ gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); 73d47ab0ecSGraeme Russ return 0; 74d47ab0ecSGraeme Russ } 75d47ab0ecSGraeme Russ 76*5e98947fSSimon Glass /* Get the top of usable RAM */ 77*5e98947fSSimon Glass __weak ulong board_get_usable_ram_top(ulong total_size) 78a1d57b7aSGraeme Russ { 79*5e98947fSSimon Glass return gd->ram_size; 80*5e98947fSSimon Glass } 81*5e98947fSSimon Glass 82*5e98947fSSimon Glass int calculate_relocation_address(void) 83*5e98947fSSimon Glass { 84*5e98947fSSimon Glass const ulong uboot_size = (uintptr_t)&__bss_end - 85*5e98947fSSimon Glass (uintptr_t)&__text_start; 86*5e98947fSSimon Glass ulong total_size; 87a1d57b7aSGraeme Russ ulong dest_addr; 88a1d57b7aSGraeme Russ 89*5e98947fSSimon Glass total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN + 90*5e98947fSSimon Glass CONFIG_SYS_STACK_SIZE; 91*5e98947fSSimon Glass 92a1d57b7aSGraeme Russ /* 93a1d57b7aSGraeme Russ * NOTE: All destination address are rounded down to 16-byte 94a1d57b7aSGraeme Russ * boundary to satisfy various worst-case alignment 95a1d57b7aSGraeme Russ * requirements 96a1d57b7aSGraeme Russ */ 97*5e98947fSSimon Glass dest_addr = board_get_usable_ram_top(total_size); 98a1d57b7aSGraeme Russ 99*5e98947fSSimon Glass /* U-Boot is below the FDT */ 100*5e98947fSSimon Glass dest_addr -= uboot_size; 101*5e98947fSSimon Glass dest_addr &= ~((1 << 12) - 1); 102a1d57b7aSGraeme Russ gd->relocaddr = dest_addr; 103*5e98947fSSimon Glass gd->reloc_off = dest_addr - (uintptr_t)&__text_start; 104a1d57b7aSGraeme Russ 10532f98735SGabe Black /* Stack is at the bottom, so it can grow down */ 10632f98735SGabe Black gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN; 10732f98735SGabe Black 108a1d57b7aSGraeme Russ return 0; 109a1d57b7aSGraeme Russ } 110a1d57b7aSGraeme Russ 111a1d57b7aSGraeme Russ int init_cache_f_r(void) 112a1d57b7aSGraeme Russ { 113a1d57b7aSGraeme Russ /* Initialise the CPU cache(s) */ 114a1d57b7aSGraeme Russ return init_cache(); 115a1d57b7aSGraeme Russ } 116a1d57b7aSGraeme Russ 117a1d57b7aSGraeme Russ int set_reloc_flag_r(void) 118a1d57b7aSGraeme Russ { 119a1d57b7aSGraeme Russ gd->flags = GD_FLG_RELOC; 120a1d57b7aSGraeme Russ 121a1d57b7aSGraeme Russ return 0; 122a1d57b7aSGraeme Russ } 123a1d57b7aSGraeme Russ 124d47ab0ecSGraeme Russ int mem_malloc_init_r(void) 125d47ab0ecSGraeme Russ { 126d47ab0ecSGraeme Russ mem_malloc_init(((gd->relocaddr - CONFIG_SYS_MALLOC_LEN)+3)&~3, 127d47ab0ecSGraeme Russ CONFIG_SYS_MALLOC_LEN); 128d47ab0ecSGraeme Russ 129d47ab0ecSGraeme Russ return 0; 130d47ab0ecSGraeme Russ } 131d47ab0ecSGraeme Russ 132d47ab0ecSGraeme Russ bd_t bd_data; 133d47ab0ecSGraeme Russ 134d47ab0ecSGraeme Russ int init_bd_struct_r(void) 135d47ab0ecSGraeme Russ { 136d47ab0ecSGraeme Russ gd->bd = &bd_data; 137d47ab0ecSGraeme Russ memset(gd->bd, 0, sizeof(bd_t)); 138d47ab0ecSGraeme Russ 139d47ab0ecSGraeme Russ return 0; 140d47ab0ecSGraeme Russ } 141d47ab0ecSGraeme Russ 142d47ab0ecSGraeme Russ #ifndef CONFIG_SYS_NO_FLASH 143d47ab0ecSGraeme Russ int flash_init_r(void) 144d47ab0ecSGraeme Russ { 145d47ab0ecSGraeme Russ ulong size; 146d47ab0ecSGraeme Russ 147d47ab0ecSGraeme Russ puts("Flash: "); 148d47ab0ecSGraeme Russ 149d47ab0ecSGraeme Russ /* configure available FLASH banks */ 150d47ab0ecSGraeme Russ size = flash_init(); 151d47ab0ecSGraeme Russ 152d47ab0ecSGraeme Russ print_size(size, "\n"); 153d47ab0ecSGraeme Russ 154d47ab0ecSGraeme Russ return 0; 155d47ab0ecSGraeme Russ } 156d47ab0ecSGraeme Russ #endif 157d47ab0ecSGraeme Russ 158d47ab0ecSGraeme Russ #ifdef CONFIG_STATUS_LED 159d47ab0ecSGraeme Russ int status_led_set_r(void) 160d47ab0ecSGraeme Russ { 161d47ab0ecSGraeme Russ status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); 162d47ab0ecSGraeme Russ 163d47ab0ecSGraeme Russ return 0; 164d47ab0ecSGraeme Russ } 165d47ab0ecSGraeme Russ #endif 166d47ab0ecSGraeme Russ 167d47ab0ecSGraeme Russ int set_load_addr_r(void) 168d47ab0ecSGraeme Russ { 169d47ab0ecSGraeme Russ /* Initialize from environment */ 170d47ab0ecSGraeme Russ load_addr = getenv_ulong("loadaddr", 16, load_addr); 171d47ab0ecSGraeme Russ 172d47ab0ecSGraeme Russ return 0; 173d47ab0ecSGraeme Russ } 1748313315bSGabe Black 1758313315bSGabe Black int init_func_spi(void) 1768313315bSGabe Black { 1778313315bSGabe Black puts("SPI: "); 1788313315bSGabe Black spi_init(); 1798313315bSGabe Black puts("ready\n"); 1808313315bSGabe Black return 0; 1818313315bSGabe Black } 182b208c7f1SGabe Black 183b208c7f1SGabe Black #ifdef CONFIG_OF_CONTROL 184b208c7f1SGabe Black int find_fdt(void) 185b208c7f1SGabe Black { 186b208c7f1SGabe Black #ifdef CONFIG_OF_EMBED 187b208c7f1SGabe Black /* Get a pointer to the FDT */ 188b208c7f1SGabe Black gd->fdt_blob = _binary_dt_dtb_start; 189b208c7f1SGabe Black #elif defined CONFIG_OF_SEPARATE 190b208c7f1SGabe Black /* FDT is at end of image */ 191b208c7f1SGabe Black gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE); 192b208c7f1SGabe Black #endif 193b208c7f1SGabe Black /* Allow the early environment to override the fdt address */ 194b208c7f1SGabe Black gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, 195b208c7f1SGabe Black (uintptr_t)gd->fdt_blob); 196b208c7f1SGabe Black 197b208c7f1SGabe Black return 0; 198b208c7f1SGabe Black } 199b208c7f1SGabe Black 200b208c7f1SGabe Black int prepare_fdt(void) 201b208c7f1SGabe Black { 202b208c7f1SGabe Black /* For now, put this check after the console is ready */ 203b208c7f1SGabe Black if (fdtdec_prepare_fdt()) { 204b208c7f1SGabe Black panic("** CONFIG_OF_CONTROL defined but no FDT - please see " 205b208c7f1SGabe Black "doc/README.fdt-control"); 206b208c7f1SGabe Black } 207b208c7f1SGabe Black 208b208c7f1SGabe Black return 0; 209b208c7f1SGabe Black } 210b208c7f1SGabe Black #endif 211