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> 25*f697d528SSimon Glass #include <fdtdec.h> 26d47ab0ecSGraeme Russ #include <stdio_dev.h> 27d47ab0ecSGraeme Russ #include <version.h> 28d47ab0ecSGraeme Russ #include <malloc.h> 29d47ab0ecSGraeme Russ #include <net.h> 30d47ab0ecSGraeme Russ #include <ide.h> 31d47ab0ecSGraeme Russ #include <serial.h> 328313315bSGabe Black #include <spi.h> 33d47ab0ecSGraeme Russ #include <status_led.h> 34a1d57b7aSGraeme Russ #include <asm/processor.h> 35d47ab0ecSGraeme Russ #include <asm/u-boot-x86.h> 36d65297b6SGabe Black #include <linux/compiler.h> 37d47ab0ecSGraeme Russ 38d47ab0ecSGraeme Russ #include <asm/init_helpers.h> 39d47ab0ecSGraeme Russ 40d47ab0ecSGraeme Russ DECLARE_GLOBAL_DATA_PTR; 41d47ab0ecSGraeme Russ 42d47ab0ecSGraeme Russ /************************************************************************ 43d47ab0ecSGraeme Russ * Init Utilities * 44d47ab0ecSGraeme Russ ************************************************************************ 45d47ab0ecSGraeme Russ * Some of this code should be moved into the core functions, 46d47ab0ecSGraeme Russ * or dropped completely, 47d47ab0ecSGraeme Russ * but let's get it working (again) first... 48d47ab0ecSGraeme Russ */ 49d47ab0ecSGraeme Russ 50d47ab0ecSGraeme Russ int display_banner(void) 51d47ab0ecSGraeme Russ { 52d47ab0ecSGraeme Russ printf("\n\n%s\n\n", version_string); 53d47ab0ecSGraeme Russ 54d47ab0ecSGraeme Russ return 0; 55d47ab0ecSGraeme Russ } 56d47ab0ecSGraeme Russ 57d47ab0ecSGraeme Russ int display_dram_config(void) 58d47ab0ecSGraeme Russ { 59d47ab0ecSGraeme Russ int i; 60d47ab0ecSGraeme Russ 61d47ab0ecSGraeme Russ puts("DRAM Configuration:\n"); 62d47ab0ecSGraeme Russ 63d47ab0ecSGraeme Russ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 64d47ab0ecSGraeme Russ printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); 65d47ab0ecSGraeme Russ print_size(gd->bd->bi_dram[i].size, "\n"); 66d47ab0ecSGraeme Russ } 67d47ab0ecSGraeme Russ 68d47ab0ecSGraeme Russ return 0; 69d47ab0ecSGraeme Russ } 70d47ab0ecSGraeme Russ 71d47ab0ecSGraeme Russ int init_baudrate_f(void) 72d47ab0ecSGraeme Russ { 73d47ab0ecSGraeme Russ gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); 74d47ab0ecSGraeme Russ return 0; 75d47ab0ecSGraeme Russ } 76d47ab0ecSGraeme Russ 775e98947fSSimon Glass /* Get the top of usable RAM */ 785e98947fSSimon Glass __weak ulong board_get_usable_ram_top(ulong total_size) 79a1d57b7aSGraeme Russ { 805e98947fSSimon Glass return gd->ram_size; 815e98947fSSimon Glass } 825e98947fSSimon Glass 835e98947fSSimon Glass int calculate_relocation_address(void) 845e98947fSSimon Glass { 855e98947fSSimon Glass const ulong uboot_size = (uintptr_t)&__bss_end - 865e98947fSSimon Glass (uintptr_t)&__text_start; 875e98947fSSimon Glass ulong total_size; 88a1d57b7aSGraeme Russ ulong dest_addr; 89*f697d528SSimon Glass ulong fdt_size = 0; 90a1d57b7aSGraeme Russ 91*f697d528SSimon Glass #if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) 92*f697d528SSimon Glass if (gd->fdt_blob) 93*f697d528SSimon Glass fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); 94*f697d528SSimon Glass #endif 955e98947fSSimon Glass total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN + 96*f697d528SSimon Glass CONFIG_SYS_STACK_SIZE + fdt_size; 975e98947fSSimon Glass 98*f697d528SSimon Glass dest_addr = board_get_usable_ram_top(total_size); 99a1d57b7aSGraeme Russ /* 100a1d57b7aSGraeme Russ * NOTE: All destination address are rounded down to 16-byte 101a1d57b7aSGraeme Russ * boundary to satisfy various worst-case alignment 102a1d57b7aSGraeme Russ * requirements 103a1d57b7aSGraeme Russ */ 104*f697d528SSimon Glass dest_addr &= ~15; 105a1d57b7aSGraeme Russ 106*f697d528SSimon Glass #if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) 107*f697d528SSimon Glass /* 108*f697d528SSimon Glass * If the device tree is sitting immediate above our image then we 109*f697d528SSimon Glass * must relocate it. If it is embedded in the data section, then it 110*f697d528SSimon Glass * will be relocated with other data. 111*f697d528SSimon Glass */ 112*f697d528SSimon Glass if (gd->fdt_blob) { 113*f697d528SSimon Glass dest_addr -= fdt_size; 114*f697d528SSimon Glass gd->arch.new_fdt = (void *)dest_addr; 115*f697d528SSimon Glass dest_addr &= ~15; 116*f697d528SSimon Glass } 117*f697d528SSimon Glass #endif 1185e98947fSSimon Glass /* U-Boot is below the FDT */ 1195e98947fSSimon Glass dest_addr -= uboot_size; 1205e98947fSSimon Glass dest_addr &= ~((1 << 12) - 1); 121a1d57b7aSGraeme Russ gd->relocaddr = dest_addr; 1225e98947fSSimon Glass gd->reloc_off = dest_addr - (uintptr_t)&__text_start; 123a1d57b7aSGraeme Russ 12432f98735SGabe Black /* Stack is at the bottom, so it can grow down */ 12532f98735SGabe Black gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN; 12632f98735SGabe Black 127a1d57b7aSGraeme Russ return 0; 128a1d57b7aSGraeme Russ } 129a1d57b7aSGraeme Russ 130a1d57b7aSGraeme Russ int init_cache_f_r(void) 131a1d57b7aSGraeme Russ { 132a1d57b7aSGraeme Russ /* Initialise the CPU cache(s) */ 133a1d57b7aSGraeme Russ return init_cache(); 134a1d57b7aSGraeme Russ } 135a1d57b7aSGraeme Russ 136a1d57b7aSGraeme Russ int set_reloc_flag_r(void) 137a1d57b7aSGraeme Russ { 138a1d57b7aSGraeme Russ gd->flags = GD_FLG_RELOC; 139a1d57b7aSGraeme Russ 140a1d57b7aSGraeme Russ return 0; 141a1d57b7aSGraeme Russ } 142a1d57b7aSGraeme Russ 143d47ab0ecSGraeme Russ int mem_malloc_init_r(void) 144d47ab0ecSGraeme Russ { 145d47ab0ecSGraeme Russ mem_malloc_init(((gd->relocaddr - CONFIG_SYS_MALLOC_LEN)+3)&~3, 146d47ab0ecSGraeme Russ CONFIG_SYS_MALLOC_LEN); 147d47ab0ecSGraeme Russ 148d47ab0ecSGraeme Russ return 0; 149d47ab0ecSGraeme Russ } 150d47ab0ecSGraeme Russ 151d47ab0ecSGraeme Russ bd_t bd_data; 152d47ab0ecSGraeme Russ 153d47ab0ecSGraeme Russ int init_bd_struct_r(void) 154d47ab0ecSGraeme Russ { 155d47ab0ecSGraeme Russ gd->bd = &bd_data; 156d47ab0ecSGraeme Russ memset(gd->bd, 0, sizeof(bd_t)); 157d47ab0ecSGraeme Russ 158d47ab0ecSGraeme Russ return 0; 159d47ab0ecSGraeme Russ } 160d47ab0ecSGraeme Russ 161d47ab0ecSGraeme Russ #ifndef CONFIG_SYS_NO_FLASH 162d47ab0ecSGraeme Russ int flash_init_r(void) 163d47ab0ecSGraeme Russ { 164d47ab0ecSGraeme Russ ulong size; 165d47ab0ecSGraeme Russ 166d47ab0ecSGraeme Russ puts("Flash: "); 167d47ab0ecSGraeme Russ 168d47ab0ecSGraeme Russ /* configure available FLASH banks */ 169d47ab0ecSGraeme Russ size = flash_init(); 170d47ab0ecSGraeme Russ 171d47ab0ecSGraeme Russ print_size(size, "\n"); 172d47ab0ecSGraeme Russ 173d47ab0ecSGraeme Russ return 0; 174d47ab0ecSGraeme Russ } 175d47ab0ecSGraeme Russ #endif 176d47ab0ecSGraeme Russ 177d47ab0ecSGraeme Russ #ifdef CONFIG_STATUS_LED 178d47ab0ecSGraeme Russ int status_led_set_r(void) 179d47ab0ecSGraeme Russ { 180d47ab0ecSGraeme Russ status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); 181d47ab0ecSGraeme Russ 182d47ab0ecSGraeme Russ return 0; 183d47ab0ecSGraeme Russ } 184d47ab0ecSGraeme Russ #endif 185d47ab0ecSGraeme Russ 186d47ab0ecSGraeme Russ int set_load_addr_r(void) 187d47ab0ecSGraeme Russ { 188d47ab0ecSGraeme Russ /* Initialize from environment */ 189d47ab0ecSGraeme Russ load_addr = getenv_ulong("loadaddr", 16, load_addr); 190d47ab0ecSGraeme Russ 191d47ab0ecSGraeme Russ return 0; 192d47ab0ecSGraeme Russ } 1938313315bSGabe Black 1948313315bSGabe Black int init_func_spi(void) 1958313315bSGabe Black { 1968313315bSGabe Black puts("SPI: "); 1978313315bSGabe Black spi_init(); 1988313315bSGabe Black puts("ready\n"); 1998313315bSGabe Black return 0; 2008313315bSGabe Black } 201b208c7f1SGabe Black 202b208c7f1SGabe Black #ifdef CONFIG_OF_CONTROL 203b208c7f1SGabe Black int find_fdt(void) 204b208c7f1SGabe Black { 205b208c7f1SGabe Black #ifdef CONFIG_OF_EMBED 206b208c7f1SGabe Black /* Get a pointer to the FDT */ 207b208c7f1SGabe Black gd->fdt_blob = _binary_dt_dtb_start; 208b208c7f1SGabe Black #elif defined CONFIG_OF_SEPARATE 209b208c7f1SGabe Black /* FDT is at end of image */ 2104b491b8dSSimon Glass gd->fdt_blob = (ulong *)&_end; 211b208c7f1SGabe Black #endif 212b208c7f1SGabe Black /* Allow the early environment to override the fdt address */ 213b208c7f1SGabe Black gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, 214b208c7f1SGabe Black (uintptr_t)gd->fdt_blob); 215b208c7f1SGabe Black 216b208c7f1SGabe Black return 0; 217b208c7f1SGabe Black } 218b208c7f1SGabe Black 219b208c7f1SGabe Black int prepare_fdt(void) 220b208c7f1SGabe Black { 221b208c7f1SGabe Black /* For now, put this check after the console is ready */ 222b208c7f1SGabe Black if (fdtdec_prepare_fdt()) { 223b208c7f1SGabe Black panic("** CONFIG_OF_CONTROL defined but no FDT - please see " 224b208c7f1SGabe Black "doc/README.fdt-control"); 225b208c7f1SGabe Black } 226b208c7f1SGabe Black 227b208c7f1SGabe Black return 0; 228b208c7f1SGabe Black } 229b208c7f1SGabe Black #endif 230