109f455dcSMasahiro Yamada /* 2*7aaa5a60STom Warren * (C) Copyright 2010-2015 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 21659a0755STom Warren void save_boot_params_ret(void); 22659a0755STom Warren 2309f455dcSMasahiro Yamada DECLARE_GLOBAL_DATA_PTR; 2409f455dcSMasahiro Yamada 2509f455dcSMasahiro Yamada enum { 2609f455dcSMasahiro Yamada /* UARTs which we can enable */ 2709f455dcSMasahiro Yamada UARTA = 1 << 0, 2809f455dcSMasahiro Yamada UARTB = 1 << 1, 2909f455dcSMasahiro Yamada UARTC = 1 << 2, 3009f455dcSMasahiro Yamada UARTD = 1 << 3, 3109f455dcSMasahiro Yamada UARTE = 1 << 4, 3209f455dcSMasahiro Yamada UART_COUNT = 5, 3309f455dcSMasahiro Yamada }; 3409f455dcSMasahiro Yamada 35537e9673SSimon Glass static bool from_spl __attribute__ ((section(".data"))); 36537e9673SSimon Glass 37537e9673SSimon Glass #ifndef CONFIG_SPL_BUILD 38537e9673SSimon Glass void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) 39537e9673SSimon Glass { 40537e9673SSimon Glass from_spl = r0 != UBOOT_NOT_LOADED_FROM_SPL; 41537e9673SSimon Glass save_boot_params_ret(); 42537e9673SSimon Glass } 43537e9673SSimon Glass #endif 44537e9673SSimon Glass 45537e9673SSimon Glass bool spl_was_boot_source(void) 46537e9673SSimon Glass { 47537e9673SSimon Glass return from_spl; 48537e9673SSimon Glass } 49537e9673SSimon Glass 5073c38934SStephen Warren #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE) 5173c38934SStephen Warren #if !defined(CONFIG_TEGRA124) 5273c38934SStephen Warren #error tegra_cpu_is_non_secure has only been validated on Tegra124 5373c38934SStephen Warren #endif 5473c38934SStephen Warren bool tegra_cpu_is_non_secure(void) 5573c38934SStephen Warren { 5673c38934SStephen Warren /* 5773c38934SStephen Warren * This register reads 0xffffffff in non-secure mode. This register 5873c38934SStephen Warren * only implements bits 31:20, so the lower bits will always read 0 in 5973c38934SStephen Warren * secure mode. Thus, the lower bits are an indicator for secure vs. 6073c38934SStephen Warren * non-secure mode. 6173c38934SStephen Warren */ 6273c38934SStephen Warren struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE; 6373c38934SStephen Warren uint32_t mc_s_cfg0 = readl(&mc->mc_security_cfg0); 6473c38934SStephen Warren return (mc_s_cfg0 & 1) == 1; 6573c38934SStephen Warren } 6673c38934SStephen Warren #endif 6773c38934SStephen Warren 6809f455dcSMasahiro Yamada /* Read the RAM size directly from the memory controller */ 6909f455dcSMasahiro Yamada unsigned int query_sdram_size(void) 7009f455dcSMasahiro Yamada { 7109f455dcSMasahiro Yamada struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE; 723a2cab51SStephen Warren u32 emem_cfg, size_bytes; 7309f455dcSMasahiro Yamada 743a2cab51SStephen Warren emem_cfg = readl(&mc->mc_emem_cfg); 7509f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA20) 763a2cab51SStephen Warren debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", emem_cfg); 773a2cab51SStephen Warren size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024); 7809f455dcSMasahiro Yamada #else 793a2cab51SStephen Warren debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", emem_cfg); 8056519c4fSStephen Warren /* 8156519c4fSStephen Warren * If >=4GB RAM is present, the byte RAM size won't fit into 32-bits 8256519c4fSStephen Warren * and will wrap. Clip the reported size to the maximum that a 32-bit 8356519c4fSStephen Warren * variable can represent (rounded to a page). 8456519c4fSStephen Warren */ 8556519c4fSStephen Warren if (emem_cfg >= 4096) { 8656519c4fSStephen Warren size_bytes = U32_MAX & ~(0x1000 - 1); 8756519c4fSStephen Warren } else { 8856519c4fSStephen Warren /* RAM size EMC is programmed to. */ 8956519c4fSStephen Warren size_bytes = emem_cfg * 1024 * 1024; 9056519c4fSStephen Warren /* 9156519c4fSStephen Warren * If all RAM fits within 32-bits, it can be accessed without 9256519c4fSStephen Warren * LPAE, so go test the RAM size. Otherwise, we can't access 9356519c4fSStephen Warren * all the RAM, and get_ram_size() would get confused, so 9456519c4fSStephen Warren * avoid using it. There's no reason we should need this 9556519c4fSStephen Warren * validation step anyway. 9656519c4fSStephen Warren */ 9756519c4fSStephen Warren if (emem_cfg <= (0 - PHYS_SDRAM_1) / (1024 * 1024)) 9856519c4fSStephen Warren size_bytes = get_ram_size((void *)PHYS_SDRAM_1, 9956519c4fSStephen Warren size_bytes); 10056519c4fSStephen Warren } 10109f455dcSMasahiro Yamada #endif 10209f455dcSMasahiro Yamada 10309f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) 10409f455dcSMasahiro Yamada /* External memory limited to 2047 MB due to IROM/HI-VEC */ 1053a2cab51SStephen Warren if (size_bytes == SZ_2G) 1063a2cab51SStephen Warren size_bytes -= SZ_1M; 10709f455dcSMasahiro Yamada #endif 10809f455dcSMasahiro Yamada 1093a2cab51SStephen Warren return size_bytes; 11009f455dcSMasahiro Yamada } 11109f455dcSMasahiro Yamada 11209f455dcSMasahiro Yamada int dram_init(void) 11309f455dcSMasahiro Yamada { 11409f455dcSMasahiro Yamada /* We do not initialise DRAM here. We just query the size */ 11509f455dcSMasahiro Yamada gd->ram_size = query_sdram_size(); 11609f455dcSMasahiro Yamada return 0; 11709f455dcSMasahiro Yamada } 11809f455dcSMasahiro Yamada 11909f455dcSMasahiro Yamada static int uart_configs[] = { 12009f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA20) 12109f455dcSMasahiro Yamada #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) 12209f455dcSMasahiro Yamada FUNCMUX_UART1_UAA_UAB, 12309f455dcSMasahiro Yamada #elif defined(CONFIG_TEGRA_UARTA_GPU) 12409f455dcSMasahiro Yamada FUNCMUX_UART1_GPU, 12509f455dcSMasahiro Yamada #elif defined(CONFIG_TEGRA_UARTA_SDIO1) 12609f455dcSMasahiro Yamada FUNCMUX_UART1_SDIO1, 12709f455dcSMasahiro Yamada #else 12809f455dcSMasahiro Yamada FUNCMUX_UART1_IRRX_IRTX, 12909f455dcSMasahiro Yamada #endif 13009f455dcSMasahiro Yamada FUNCMUX_UART2_UAD, 13109f455dcSMasahiro Yamada -1, 13209f455dcSMasahiro Yamada FUNCMUX_UART4_GMC, 13309f455dcSMasahiro Yamada -1, 13409f455dcSMasahiro Yamada #elif defined(CONFIG_TEGRA30) 13509f455dcSMasahiro Yamada FUNCMUX_UART1_ULPI, /* UARTA */ 13609f455dcSMasahiro Yamada -1, 13709f455dcSMasahiro Yamada -1, 13809f455dcSMasahiro Yamada -1, 13909f455dcSMasahiro Yamada -1, 14009f455dcSMasahiro Yamada #elif defined(CONFIG_TEGRA114) 14109f455dcSMasahiro Yamada -1, 14209f455dcSMasahiro Yamada -1, 14309f455dcSMasahiro Yamada -1, 14409f455dcSMasahiro Yamada FUNCMUX_UART4_GMI, /* UARTD */ 14509f455dcSMasahiro Yamada -1, 146*7aaa5a60STom Warren #elif defined(CONFIG_TEGRA124) 14709f455dcSMasahiro Yamada FUNCMUX_UART1_KBC, /* UARTA */ 14809f455dcSMasahiro Yamada -1, 14909f455dcSMasahiro Yamada -1, 15009f455dcSMasahiro Yamada FUNCMUX_UART4_GPIO, /* UARTD */ 15109f455dcSMasahiro Yamada -1, 152*7aaa5a60STom Warren #else /* Tegra210 */ 153*7aaa5a60STom Warren FUNCMUX_UART1_UART1, /* UARTA */ 154*7aaa5a60STom Warren -1, 155*7aaa5a60STom Warren -1, 156*7aaa5a60STom Warren FUNCMUX_UART4_UART4, /* UARTD */ 157*7aaa5a60STom Warren -1, 15809f455dcSMasahiro Yamada #endif 15909f455dcSMasahiro Yamada }; 16009f455dcSMasahiro Yamada 16109f455dcSMasahiro Yamada /** 16209f455dcSMasahiro Yamada * Set up the specified uarts 16309f455dcSMasahiro Yamada * 16409f455dcSMasahiro Yamada * @param uarts_ids Mask containing UARTs to init (UARTx) 16509f455dcSMasahiro Yamada */ 16609f455dcSMasahiro Yamada static void setup_uarts(int uart_ids) 16709f455dcSMasahiro Yamada { 16809f455dcSMasahiro Yamada static enum periph_id id_for_uart[] = { 16909f455dcSMasahiro Yamada PERIPH_ID_UART1, 17009f455dcSMasahiro Yamada PERIPH_ID_UART2, 17109f455dcSMasahiro Yamada PERIPH_ID_UART3, 17209f455dcSMasahiro Yamada PERIPH_ID_UART4, 17309f455dcSMasahiro Yamada PERIPH_ID_UART5, 17409f455dcSMasahiro Yamada }; 17509f455dcSMasahiro Yamada size_t i; 17609f455dcSMasahiro Yamada 17709f455dcSMasahiro Yamada for (i = 0; i < UART_COUNT; i++) { 17809f455dcSMasahiro Yamada if (uart_ids & (1 << i)) { 17909f455dcSMasahiro Yamada enum periph_id id = id_for_uart[i]; 18009f455dcSMasahiro Yamada 18109f455dcSMasahiro Yamada funcmux_select(id, uart_configs[i]); 18209f455dcSMasahiro Yamada clock_ll_start_uart(id); 18309f455dcSMasahiro Yamada } 18409f455dcSMasahiro Yamada } 18509f455dcSMasahiro Yamada } 18609f455dcSMasahiro Yamada 18709f455dcSMasahiro Yamada void board_init_uart_f(void) 18809f455dcSMasahiro Yamada { 18909f455dcSMasahiro Yamada int uart_ids = 0; /* bit mask of which UART ids to enable */ 19009f455dcSMasahiro Yamada 19109f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTA 19209f455dcSMasahiro Yamada uart_ids |= UARTA; 19309f455dcSMasahiro Yamada #endif 19409f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTB 19509f455dcSMasahiro Yamada uart_ids |= UARTB; 19609f455dcSMasahiro Yamada #endif 19709f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTC 19809f455dcSMasahiro Yamada uart_ids |= UARTC; 19909f455dcSMasahiro Yamada #endif 20009f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTD 20109f455dcSMasahiro Yamada uart_ids |= UARTD; 20209f455dcSMasahiro Yamada #endif 20309f455dcSMasahiro Yamada #ifdef CONFIG_TEGRA_ENABLE_UARTE 20409f455dcSMasahiro Yamada uart_ids |= UARTE; 20509f455dcSMasahiro Yamada #endif 20609f455dcSMasahiro Yamada setup_uarts(uart_ids); 20709f455dcSMasahiro Yamada } 20809f455dcSMasahiro Yamada 20932b3234fSThierry Reding #if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) 21009f455dcSMasahiro Yamada void enable_caches(void) 21109f455dcSMasahiro Yamada { 21209f455dcSMasahiro Yamada /* Enable D-cache. I-cache is already enabled in start.S */ 21309f455dcSMasahiro Yamada dcache_enable(); 21409f455dcSMasahiro Yamada } 21509f455dcSMasahiro Yamada #endif 216