109f455dcSMasahiro Yamada /* 209f455dcSMasahiro Yamada * (C) Copyright 2010-2014 309f455dcSMasahiro Yamada * NVIDIA Corporation <www.nvidia.com> 409f455dcSMasahiro Yamada * 509f455dcSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 609f455dcSMasahiro Yamada */ 709f455dcSMasahiro Yamada 809f455dcSMasahiro Yamada #include <common.h> 9537e9673SSimon Glass #include <spl.h> 1009f455dcSMasahiro Yamada #include <asm/io.h> 1109f455dcSMasahiro Yamada #include <asm/arch/clock.h> 1209f455dcSMasahiro Yamada #include <asm/arch/funcmux.h> 1309f455dcSMasahiro Yamada #include <asm/arch/mc.h> 1409f455dcSMasahiro Yamada #include <asm/arch/tegra.h> 1573c38934SStephen Warren #include <asm/arch-tegra/ap.h> 1609f455dcSMasahiro Yamada #include <asm/arch-tegra/board.h> 1709f455dcSMasahiro Yamada #include <asm/arch-tegra/pmc.h> 1809f455dcSMasahiro Yamada #include <asm/arch-tegra/sys_proto.h> 1909f455dcSMasahiro Yamada #include <asm/arch-tegra/warmboot.h> 2009f455dcSMasahiro Yamada 2109f455dcSMasahiro Yamada DECLARE_GLOBAL_DATA_PTR; 2209f455dcSMasahiro Yamada 2309f455dcSMasahiro Yamada enum { 2409f455dcSMasahiro Yamada /* UARTs which we can enable */ 2509f455dcSMasahiro Yamada UARTA = 1 << 0, 2609f455dcSMasahiro Yamada UARTB = 1 << 1, 2709f455dcSMasahiro Yamada UARTC = 1 << 2, 2809f455dcSMasahiro Yamada UARTD = 1 << 3, 2909f455dcSMasahiro Yamada UARTE = 1 << 4, 3009f455dcSMasahiro Yamada UART_COUNT = 5, 3109f455dcSMasahiro Yamada }; 3209f455dcSMasahiro Yamada 33537e9673SSimon Glass static bool from_spl __attribute__ ((section(".data"))); 34537e9673SSimon Glass 35537e9673SSimon Glass #ifndef CONFIG_SPL_BUILD 36537e9673SSimon Glass void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) 37537e9673SSimon Glass { 38537e9673SSimon Glass from_spl = r0 != UBOOT_NOT_LOADED_FROM_SPL; 39537e9673SSimon Glass save_boot_params_ret(); 40537e9673SSimon Glass } 41537e9673SSimon Glass #endif 42537e9673SSimon Glass 43537e9673SSimon Glass bool spl_was_boot_source(void) 44537e9673SSimon Glass { 45537e9673SSimon Glass return from_spl; 46537e9673SSimon Glass } 47537e9673SSimon Glass 4873c38934SStephen Warren #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE) 4973c38934SStephen Warren #if !defined(CONFIG_TEGRA124) 5073c38934SStephen Warren #error tegra_cpu_is_non_secure has only been validated on Tegra124 5173c38934SStephen Warren #endif 5273c38934SStephen Warren bool tegra_cpu_is_non_secure(void) 5373c38934SStephen Warren { 5473c38934SStephen Warren /* 5573c38934SStephen Warren * This register reads 0xffffffff in non-secure mode. This register 5673c38934SStephen Warren * only implements bits 31:20, so the lower bits will always read 0 in 5773c38934SStephen Warren * secure mode. Thus, the lower bits are an indicator for secure vs. 5873c38934SStephen Warren * non-secure mode. 5973c38934SStephen Warren */ 6073c38934SStephen Warren struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE; 6173c38934SStephen Warren uint32_t mc_s_cfg0 = readl(&mc->mc_security_cfg0); 6273c38934SStephen Warren return (mc_s_cfg0 & 1) == 1; 6373c38934SStephen Warren } 6473c38934SStephen Warren #endif 6573c38934SStephen Warren 6609f455dcSMasahiro Yamada /* Read the RAM size directly from the memory controller */ 6709f455dcSMasahiro Yamada unsigned int query_sdram_size(void) 6809f455dcSMasahiro Yamada { 6909f455dcSMasahiro Yamada struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE; 703a2cab51SStephen Warren u32 emem_cfg, size_bytes; 7109f455dcSMasahiro Yamada 723a2cab51SStephen Warren emem_cfg = readl(&mc->mc_emem_cfg); 7309f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA20) 743a2cab51SStephen Warren debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", emem_cfg); 753a2cab51SStephen Warren size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024); 7609f455dcSMasahiro Yamada #else 773a2cab51SStephen Warren debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", emem_cfg); 7856519c4fSStephen Warren /* 7956519c4fSStephen Warren * If >=4GB RAM is present, the byte RAM size won't fit into 32-bits 8056519c4fSStephen Warren * and will wrap. Clip the reported size to the maximum that a 32-bit 8156519c4fSStephen Warren * variable can represent (rounded to a page). 8256519c4fSStephen Warren */ 8356519c4fSStephen Warren if (emem_cfg >= 4096) { 8456519c4fSStephen Warren size_bytes = U32_MAX & ~(0x1000 - 1); 8556519c4fSStephen Warren } else { 8656519c4fSStephen Warren /* RAM size EMC is programmed to. */ 8756519c4fSStephen Warren size_bytes = emem_cfg * 1024 * 1024; 8856519c4fSStephen Warren /* 8956519c4fSStephen Warren * If all RAM fits within 32-bits, it can be accessed without 9056519c4fSStephen Warren * LPAE, so go test the RAM size. Otherwise, we can't access 9156519c4fSStephen Warren * all the RAM, and get_ram_size() would get confused, so 9256519c4fSStephen Warren * avoid using it. There's no reason we should need this 9356519c4fSStephen Warren * validation step anyway. 9456519c4fSStephen Warren */ 9556519c4fSStephen Warren if (emem_cfg <= (0 - PHYS_SDRAM_1) / (1024 * 1024)) 9656519c4fSStephen Warren size_bytes = get_ram_size((void *)PHYS_SDRAM_1, 9756519c4fSStephen Warren size_bytes); 9856519c4fSStephen Warren } 9909f455dcSMasahiro Yamada #endif 10009f455dcSMasahiro Yamada 10109f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) 10209f455dcSMasahiro Yamada /* External memory limited to 2047 MB due to IROM/HI-VEC */ 1033a2cab51SStephen Warren if (size_bytes == SZ_2G) 1043a2cab51SStephen Warren size_bytes -= SZ_1M; 10509f455dcSMasahiro Yamada #endif 10609f455dcSMasahiro Yamada 1073a2cab51SStephen Warren return size_bytes; 10809f455dcSMasahiro Yamada } 10909f455dcSMasahiro Yamada 11009f455dcSMasahiro Yamada int dram_init(void) 11109f455dcSMasahiro Yamada { 11209f455dcSMasahiro Yamada /* We do not initialise DRAM here. We just query the size */ 11309f455dcSMasahiro Yamada gd->ram_size = query_sdram_size(); 11409f455dcSMasahiro Yamada return 0; 11509f455dcSMasahiro Yamada } 11609f455dcSMasahiro Yamada 11709f455dcSMasahiro Yamada static int uart_configs[] = { 11809f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA20) 11909f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) 12009f455dcSMasahiro Yamada FUNCMUX_UART1_UAA_UAB, 12109f455dcSMasahiro Yamada #elif defined(CONFIG_TEGRA_UARTA_GPU) 12209f455dcSMasahiro Yamada FUNCMUX_UART1_GPU, 12309f455dcSMasahiro Yamada #elif defined(CONFIG_TEGRA_UARTA_SDIO1) 12409f455dcSMasahiro Yamada FUNCMUX_UART1_SDIO1, 12509f455dcSMasahiro Yamada #else 12609f455dcSMasahiro Yamada FUNCMUX_UART1_IRRX_IRTX, 12709f455dcSMasahiro Yamada #endif 12809f455dcSMasahiro Yamada FUNCMUX_UART2_UAD, 12909f455dcSMasahiro Yamada -1, 13009f455dcSMasahiro Yamada FUNCMUX_UART4_GMC, 13109f455dcSMasahiro Yamada -1, 13209f455dcSMasahiro Yamada #elif defined(CONFIG_TEGRA30) 13309f455dcSMasahiro Yamada FUNCMUX_UART1_ULPI, /* UARTA */ 13409f455dcSMasahiro Yamada -1, 13509f455dcSMasahiro Yamada -1, 13609f455dcSMasahiro Yamada -1, 13709f455dcSMasahiro Yamada -1, 13809f455dcSMasahiro Yamada #elif defined(CONFIG_TEGRA114) 13909f455dcSMasahiro Yamada -1, 14009f455dcSMasahiro Yamada -1, 14109f455dcSMasahiro Yamada -1, 14209f455dcSMasahiro Yamada FUNCMUX_UART4_GMI, /* UARTD */ 14309f455dcSMasahiro Yamada -1, 14409f455dcSMasahiro Yamada #else /* Tegra124 */ 14509f455dcSMasahiro Yamada FUNCMUX_UART1_KBC, /* UARTA */ 14609f455dcSMasahiro Yamada -1, 14709f455dcSMasahiro Yamada -1, 14809f455dcSMasahiro Yamada FUNCMUX_UART4_GPIO, /* UARTD */ 14909f455dcSMasahiro Yamada -1, 15009f455dcSMasahiro Yamada #endif 15109f455dcSMasahiro Yamada }; 15209f455dcSMasahiro Yamada 15309f455dcSMasahiro Yamada /** 15409f455dcSMasahiro Yamada * Set up the specified uarts 15509f455dcSMasahiro Yamada * 15609f455dcSMasahiro Yamada * @param uarts_ids Mask containing UARTs to init (UARTx) 15709f455dcSMasahiro Yamada */ 15809f455dcSMasahiro Yamada static void setup_uarts(int uart_ids) 15909f455dcSMasahiro Yamada { 16009f455dcSMasahiro Yamada static enum periph_id id_for_uart[] = { 16109f455dcSMasahiro Yamada PERIPH_ID_UART1, 16209f455dcSMasahiro Yamada PERIPH_ID_UART2, 16309f455dcSMasahiro Yamada PERIPH_ID_UART3, 16409f455dcSMasahiro Yamada PERIPH_ID_UART4, 16509f455dcSMasahiro Yamada PERIPH_ID_UART5, 16609f455dcSMasahiro Yamada }; 16709f455dcSMasahiro Yamada size_t i; 16809f455dcSMasahiro Yamada 16909f455dcSMasahiro Yamada for (i = 0; i < UART_COUNT; i++) { 17009f455dcSMasahiro Yamada if (uart_ids & (1 << i)) { 17109f455dcSMasahiro Yamada enum periph_id id = id_for_uart[i]; 17209f455dcSMasahiro Yamada 17309f455dcSMasahiro Yamada funcmux_select(id, uart_configs[i]); 17409f455dcSMasahiro Yamada clock_ll_start_uart(id); 17509f455dcSMasahiro Yamada } 17609f455dcSMasahiro Yamada } 17709f455dcSMasahiro Yamada } 17809f455dcSMasahiro Yamada 17909f455dcSMasahiro Yamada void board_init_uart_f(void) 18009f455dcSMasahiro Yamada { 18109f455dcSMasahiro Yamada int uart_ids = 0; /* bit mask of which UART ids to enable */ 18209f455dcSMasahiro Yamada 18309f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTA 18409f455dcSMasahiro Yamada uart_ids |= UARTA; 18509f455dcSMasahiro Yamada #endif 18609f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTB 18709f455dcSMasahiro Yamada uart_ids |= UARTB; 18809f455dcSMasahiro Yamada #endif 18909f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTC 19009f455dcSMasahiro Yamada uart_ids |= UARTC; 19109f455dcSMasahiro Yamada #endif 19209f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTD 19309f455dcSMasahiro Yamada uart_ids |= UARTD; 19409f455dcSMasahiro Yamada #endif 19509f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTE 19609f455dcSMasahiro Yamada uart_ids |= UARTE; 19709f455dcSMasahiro Yamada #endif 19809f455dcSMasahiro Yamada setup_uarts(uart_ids); 19909f455dcSMasahiro Yamada } 20009f455dcSMasahiro Yamada 201*32b3234fSThierry Reding #if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) 20209f455dcSMasahiro Yamada void enable_caches(void) 20309f455dcSMasahiro Yamada { 20409f455dcSMasahiro Yamada /* Enable D-cache. I-cache is already enabled in start.S */ 20509f455dcSMasahiro Yamada dcache_enable(); 20609f455dcSMasahiro Yamada } 20709f455dcSMasahiro Yamada #endif 208