1 /* 2 * (C) Copyright 2011 3 * Graeme Russ, <graeme.russ@gmail.com> 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 #include <common.h> 24 #include <fdtdec.h> 25 #include <spi.h> 26 #include <asm/sections.h> 27 28 DECLARE_GLOBAL_DATA_PTR; 29 30 /* Get the top of usable RAM */ 31 __weak ulong board_get_usable_ram_top(ulong total_size) 32 { 33 return gd->ram_size; 34 } 35 36 int calculate_relocation_address(void) 37 { 38 const ulong uboot_size = (uintptr_t)&__bss_end - 39 (uintptr_t)&__text_start; 40 ulong total_size; 41 ulong dest_addr; 42 ulong fdt_size = 0; 43 44 #if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) 45 if (gd->fdt_blob) 46 fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); 47 #endif 48 total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN + 49 CONFIG_SYS_STACK_SIZE + fdt_size; 50 51 dest_addr = board_get_usable_ram_top(total_size); 52 /* 53 * NOTE: All destination address are rounded down to 16-byte 54 * boundary to satisfy various worst-case alignment 55 * requirements 56 */ 57 dest_addr &= ~15; 58 59 #if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) 60 /* 61 * If the device tree is sitting immediate above our image then we 62 * must relocate it. If it is embedded in the data section, then it 63 * will be relocated with other data. 64 */ 65 if (gd->fdt_blob) { 66 dest_addr -= fdt_size; 67 gd->new_fdt = (void *)dest_addr; 68 dest_addr &= ~15; 69 } 70 #endif 71 /* U-Boot is below the FDT */ 72 dest_addr -= uboot_size; 73 dest_addr &= ~((1 << 12) - 1); 74 gd->relocaddr = dest_addr; 75 gd->reloc_off = dest_addr - (uintptr_t)&__text_start; 76 77 /* Stack is at the bottom, so it can grow down */ 78 gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN; 79 80 return 0; 81 } 82 83 int init_cache_f_r(void) 84 { 85 /* Initialise the CPU cache(s) */ 86 return init_cache(); 87 } 88 89 bd_t bd_data; 90 91 int init_bd_struct_r(void) 92 { 93 gd->bd = &bd_data; 94 memset(gd->bd, 0, sizeof(bd_t)); 95 96 return 0; 97 } 98 99 int init_func_spi(void) 100 { 101 puts("SPI: "); 102 spi_init(); 103 puts("ready\n"); 104 return 0; 105 } 106 107 int find_fdt(void) 108 { 109 #ifdef CONFIG_OF_EMBED 110 /* Get a pointer to the FDT */ 111 gd->fdt_blob = _binary_dt_dtb_start; 112 #elif defined CONFIG_OF_SEPARATE 113 /* FDT is at end of image */ 114 gd->fdt_blob = (ulong *)&_end; 115 #endif 116 /* Allow the early environment to override the fdt address */ 117 gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, 118 (uintptr_t)gd->fdt_blob); 119 120 return 0; 121 } 122 123 int prepare_fdt(void) 124 { 125 /* For now, put this check after the console is ready */ 126 if (fdtdec_prepare_fdt()) { 127 panic("** CONFIG_OF_CONTROL defined but no FDT - please see " 128 "doc/README.fdt-control"); 129 } 130 131 return 0; 132 } 133