1d47ab0ecSGraeme Russ /* 2d47ab0ecSGraeme Russ * (C) Copyright 2011 3d47ab0ecSGraeme Russ * Graeme Russ, <graeme.russ@gmail.com> 4d47ab0ecSGraeme Russ * 5*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 6d47ab0ecSGraeme Russ */ 7d47ab0ecSGraeme Russ #include <common.h> 8f697d528SSimon Glass #include <fdtdec.h> 98313315bSGabe Black #include <spi.h> 1086cfb6bdSSimon Glass #include <asm/sections.h> 11d47ab0ecSGraeme Russ 12d47ab0ecSGraeme Russ DECLARE_GLOBAL_DATA_PTR; 13d47ab0ecSGraeme Russ 145e98947fSSimon Glass /* Get the top of usable RAM */ 155e98947fSSimon Glass __weak ulong board_get_usable_ram_top(ulong total_size) 16a1d57b7aSGraeme Russ { 175e98947fSSimon Glass return gd->ram_size; 185e98947fSSimon Glass } 195e98947fSSimon Glass 205e98947fSSimon Glass int calculate_relocation_address(void) 215e98947fSSimon Glass { 225e98947fSSimon Glass const ulong uboot_size = (uintptr_t)&__bss_end - 235e98947fSSimon Glass (uintptr_t)&__text_start; 245e98947fSSimon Glass ulong total_size; 25a1d57b7aSGraeme Russ ulong dest_addr; 26f697d528SSimon Glass ulong fdt_size = 0; 27a1d57b7aSGraeme Russ 28f697d528SSimon Glass #if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) 29f697d528SSimon Glass if (gd->fdt_blob) 30f697d528SSimon Glass fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); 31f697d528SSimon Glass #endif 325e98947fSSimon Glass total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN + 33f697d528SSimon Glass CONFIG_SYS_STACK_SIZE + fdt_size; 345e98947fSSimon Glass 35f697d528SSimon Glass dest_addr = board_get_usable_ram_top(total_size); 36a1d57b7aSGraeme Russ /* 37a1d57b7aSGraeme Russ * NOTE: All destination address are rounded down to 16-byte 38a1d57b7aSGraeme Russ * boundary to satisfy various worst-case alignment 39a1d57b7aSGraeme Russ * requirements 40a1d57b7aSGraeme Russ */ 41f697d528SSimon Glass dest_addr &= ~15; 42a1d57b7aSGraeme Russ 43f697d528SSimon Glass #if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) 44f697d528SSimon Glass /* 45f697d528SSimon Glass * If the device tree is sitting immediate above our image then we 46f697d528SSimon Glass * must relocate it. If it is embedded in the data section, then it 47f697d528SSimon Glass * will be relocated with other data. 48f697d528SSimon Glass */ 49f697d528SSimon Glass if (gd->fdt_blob) { 50f697d528SSimon Glass dest_addr -= fdt_size; 511938f4a5SSimon Glass gd->new_fdt = (void *)dest_addr; 52f697d528SSimon Glass dest_addr &= ~15; 53f697d528SSimon Glass } 54f697d528SSimon Glass #endif 555e98947fSSimon Glass /* U-Boot is below the FDT */ 565e98947fSSimon Glass dest_addr -= uboot_size; 575e98947fSSimon Glass dest_addr &= ~((1 << 12) - 1); 58a1d57b7aSGraeme Russ gd->relocaddr = dest_addr; 595e98947fSSimon Glass gd->reloc_off = dest_addr - (uintptr_t)&__text_start; 60a1d57b7aSGraeme Russ 6132f98735SGabe Black /* Stack is at the bottom, so it can grow down */ 6232f98735SGabe Black gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN; 6332f98735SGabe Black 64a1d57b7aSGraeme Russ return 0; 65a1d57b7aSGraeme Russ } 66a1d57b7aSGraeme Russ 67a1d57b7aSGraeme Russ int init_cache_f_r(void) 68a1d57b7aSGraeme Russ { 69a1d57b7aSGraeme Russ /* Initialise the CPU cache(s) */ 70a1d57b7aSGraeme Russ return init_cache(); 71a1d57b7aSGraeme Russ } 72a1d57b7aSGraeme Russ 73d47ab0ecSGraeme Russ bd_t bd_data; 74d47ab0ecSGraeme Russ 75d47ab0ecSGraeme Russ int init_bd_struct_r(void) 76d47ab0ecSGraeme Russ { 77d47ab0ecSGraeme Russ gd->bd = &bd_data; 78d47ab0ecSGraeme Russ memset(gd->bd, 0, sizeof(bd_t)); 79d47ab0ecSGraeme Russ 80d47ab0ecSGraeme Russ return 0; 81d47ab0ecSGraeme Russ } 82d47ab0ecSGraeme Russ 838313315bSGabe Black int init_func_spi(void) 848313315bSGabe Black { 858313315bSGabe Black puts("SPI: "); 868313315bSGabe Black spi_init(); 878313315bSGabe Black puts("ready\n"); 888313315bSGabe Black return 0; 898313315bSGabe Black } 90b208c7f1SGabe Black 91b208c7f1SGabe Black int find_fdt(void) 92b208c7f1SGabe Black { 93b208c7f1SGabe Black #ifdef CONFIG_OF_EMBED 94b208c7f1SGabe Black /* Get a pointer to the FDT */ 95b208c7f1SGabe Black gd->fdt_blob = _binary_dt_dtb_start; 96b208c7f1SGabe Black #elif defined CONFIG_OF_SEPARATE 97b208c7f1SGabe Black /* FDT is at end of image */ 984b491b8dSSimon Glass gd->fdt_blob = (ulong *)&_end; 99b208c7f1SGabe Black #endif 100b208c7f1SGabe Black /* Allow the early environment to override the fdt address */ 101b208c7f1SGabe Black gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, 102b208c7f1SGabe Black (uintptr_t)gd->fdt_blob); 103b208c7f1SGabe Black 104b208c7f1SGabe Black return 0; 105b208c7f1SGabe Black } 106b208c7f1SGabe Black 107b208c7f1SGabe Black int prepare_fdt(void) 108b208c7f1SGabe Black { 109b208c7f1SGabe Black /* For now, put this check after the console is ready */ 110b208c7f1SGabe Black if (fdtdec_prepare_fdt()) { 111b208c7f1SGabe Black panic("** CONFIG_OF_CONTROL defined but no FDT - please see " 112b208c7f1SGabe Black "doc/README.fdt-control"); 113b208c7f1SGabe Black } 114b208c7f1SGabe Black 115b208c7f1SGabe Black return 0; 116b208c7f1SGabe Black } 117