blob: a9e26bd1a3629b451e8effef27b710d6adde437c [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Tom Warren41b68382011-01-27 10:58:05 +00002/*
Tom Warrenab0cc6b2015-03-04 16:36:00 -07003 * (C) Copyright 2010-2015
Tom Warren41b68382011-01-27 10:58:05 +00004 * NVIDIA Corporation <www.nvidia.com>
Tom Warren41b68382011-01-27 10:58:05 +00005 */
6
7#include <common.h>
Thomas Choue3b90262015-11-19 21:48:11 +08008#include <dm.h>
9#include <ns16550.h>
Simon Glasseec13c42015-05-13 07:02:29 -060010#include <spl.h>
Tom Warren41b68382011-01-27 10:58:05 +000011#include <asm/io.h>
Thierry Reding45ad0b02019-04-15 11:32:18 +020012#if IS_ENABLED(CONFIG_TEGRA_CLKRST)
Simon Glass96b7c432011-11-28 15:04:39 +000013#include <asm/arch/clock.h>
Thierry Reding45ad0b02019-04-15 11:32:18 +020014#endif
Simon Glass96b7c432011-11-28 15:04:39 +000015#include <asm/arch/funcmux.h>
Thierry Reding17987bb2019-04-15 11:32:20 +020016#if IS_ENABLED(CONFIG_TEGRA_MC)
Marcel Ziswilerc5ecf272014-10-10 23:32:32 +020017#include <asm/arch/mc.h>
Thierry Reding17987bb2019-04-15 11:32:20 +020018#endif
Tom Warrenab371962012-09-19 15:50:56 -070019#include <asm/arch/tegra.h>
Stephen Warren8d1fb312015-01-19 16:25:52 -070020#include <asm/arch-tegra/ap.h>
Lucas Stache80f7ca2012-09-29 10:02:08 +000021#include <asm/arch-tegra/board.h>
Tom Warrenab371962012-09-19 15:50:56 -070022#include <asm/arch-tegra/pmc.h>
23#include <asm/arch-tegra/sys_proto.h>
24#include <asm/arch-tegra/warmboot.h>
Tom Warren41b68382011-01-27 10:58:05 +000025
Tom Warren021a8bb2015-07-08 08:05:35 -070026void save_boot_params_ret(void);
27
Tom Warren41b68382011-01-27 10:58:05 +000028DECLARE_GLOBAL_DATA_PTR;
29
Simon Glass96b7c432011-11-28 15:04:39 +000030enum {
31 /* UARTs which we can enable */
32 UARTA = 1 << 0,
33 UARTB = 1 << 1,
Tom Warrene3d95bc2013-01-28 13:32:10 +000034 UARTC = 1 << 2,
Simon Glass96b7c432011-11-28 15:04:39 +000035 UARTD = 1 << 3,
Tom Warrene3d95bc2013-01-28 13:32:10 +000036 UARTE = 1 << 4,
37 UART_COUNT = 5,
Simon Glass96b7c432011-11-28 15:04:39 +000038};
39
Simon Glasseec13c42015-05-13 07:02:29 -060040static bool from_spl __attribute__ ((section(".data")));
41
42#ifndef CONFIG_SPL_BUILD
43void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
44{
45 from_spl = r0 != UBOOT_NOT_LOADED_FROM_SPL;
46 save_boot_params_ret();
47}
48#endif
49
50bool spl_was_boot_source(void)
51{
52 return from_spl;
53}
54
Stephen Warren8d1fb312015-01-19 16:25:52 -070055#if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
56#if !defined(CONFIG_TEGRA124)
57#error tegra_cpu_is_non_secure has only been validated on Tegra124
58#endif
59bool tegra_cpu_is_non_secure(void)
60{
61 /*
62 * This register reads 0xffffffff in non-secure mode. This register
63 * only implements bits 31:20, so the lower bits will always read 0 in
64 * secure mode. Thus, the lower bits are an indicator for secure vs.
65 * non-secure mode.
66 */
67 struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE;
68 uint32_t mc_s_cfg0 = readl(&mc->mc_security_cfg0);
69 return (mc_s_cfg0 & 1) == 1;
70}
71#endif
72
Thierry Reding17987bb2019-04-15 11:32:20 +020073#if IS_ENABLED(CONFIG_TEGRA_MC)
Stephen Warren1b4af6b2014-07-02 14:12:30 -060074/* Read the RAM size directly from the memory controller */
Stephen Warren6718af02015-08-07 16:12:44 -060075static phys_size_t query_sdram_size(void)
Stephen Warren1b4af6b2014-07-02 14:12:30 -060076{
77 struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE;
Stephen Warren6718af02015-08-07 16:12:44 -060078 u32 emem_cfg;
79 phys_size_t size_bytes;
Stephen Warren1b4af6b2014-07-02 14:12:30 -060080
Stephen Warren210bdb22014-12-23 10:34:50 -070081 emem_cfg = readl(&mc->mc_emem_cfg);
Marcel Ziswilerc5ecf272014-10-10 23:32:32 +020082#if defined(CONFIG_TEGRA20)
Stephen Warren210bdb22014-12-23 10:34:50 -070083 debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", emem_cfg);
84 size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024);
Marcel Ziswilerc5ecf272014-10-10 23:32:32 +020085#else
Stephen Warren210bdb22014-12-23 10:34:50 -070086 debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", emem_cfg);
Stephen Warren6718af02015-08-07 16:12:44 -060087#ifndef CONFIG_PHYS_64BIT
Stephen Warrenc8018052014-12-23 10:34:51 -070088 /*
89 * If >=4GB RAM is present, the byte RAM size won't fit into 32-bits
90 * and will wrap. Clip the reported size to the maximum that a 32-bit
91 * variable can represent (rounded to a page).
92 */
93 if (emem_cfg >= 4096) {
94 size_bytes = U32_MAX & ~(0x1000 - 1);
Stephen Warren6718af02015-08-07 16:12:44 -060095 } else
96#endif
97 {
Stephen Warrenc8018052014-12-23 10:34:51 -070098 /* RAM size EMC is programmed to. */
Stephen Warren6718af02015-08-07 16:12:44 -060099 size_bytes = (phys_size_t)emem_cfg * 1024 * 1024;
100#ifndef CONFIG_ARM64
Stephen Warrenc8018052014-12-23 10:34:51 -0700101 /*
102 * If all RAM fits within 32-bits, it can be accessed without
103 * LPAE, so go test the RAM size. Otherwise, we can't access
104 * all the RAM, and get_ram_size() would get confused, so
105 * avoid using it. There's no reason we should need this
106 * validation step anyway.
107 */
108 if (emem_cfg <= (0 - PHYS_SDRAM_1) / (1024 * 1024))
109 size_bytes = get_ram_size((void *)PHYS_SDRAM_1,
110 size_bytes);
Stephen Warren6718af02015-08-07 16:12:44 -0600111#endif
Stephen Warrenc8018052014-12-23 10:34:51 -0700112 }
Marcel Ziswilerc5ecf272014-10-10 23:32:32 +0200113#endif
Stephen Warren1b4af6b2014-07-02 14:12:30 -0600114
Marcel Ziswilerc5ecf272014-10-10 23:32:32 +0200115#if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114)
116 /* External memory limited to 2047 MB due to IROM/HI-VEC */
Stephen Warren210bdb22014-12-23 10:34:50 -0700117 if (size_bytes == SZ_2G)
118 size_bytes -= SZ_1M;
Stephen Warren1b4af6b2014-07-02 14:12:30 -0600119#endif
Tom Warren41b68382011-01-27 10:58:05 +0000120
Stephen Warren210bdb22014-12-23 10:34:50 -0700121 return size_bytes;
Marcel Ziswilerc5ecf272014-10-10 23:32:32 +0200122}
Thierry Reding17987bb2019-04-15 11:32:20 +0200123#endif
Marcel Ziswilerc5ecf272014-10-10 23:32:32 +0200124
Tom Warren41b68382011-01-27 10:58:05 +0000125int dram_init(void)
126{
Thierry Reding17987bb2019-04-15 11:32:20 +0200127#if IS_ENABLED(CONFIG_TEGRA_MC)
Tom Warren41b68382011-01-27 10:58:05 +0000128 /* We do not initialise DRAM here. We just query the size */
Simon Glassf6fcbbd2011-11-05 03:56:57 +0000129 gd->ram_size = query_sdram_size();
Thierry Reding17987bb2019-04-15 11:32:20 +0200130#endif
131
Tom Warren41b68382011-01-27 10:58:05 +0000132 return 0;
133}
134
Stephen Warren59f90102012-05-14 13:13:45 +0000135static int uart_configs[] = {
Tom Warren61c6d0e2012-12-11 13:34:15 +0000136#if defined(CONFIG_TEGRA20)
137 #if defined(CONFIG_TEGRA_UARTA_UAA_UAB)
Stephen Warren59f90102012-05-14 13:13:45 +0000138 FUNCMUX_UART1_UAA_UAB,
Tom Warren61c6d0e2012-12-11 13:34:15 +0000139 #elif defined(CONFIG_TEGRA_UARTA_GPU)
Stephen Warrene4c01a82012-05-16 05:59:59 +0000140 FUNCMUX_UART1_GPU,
Tom Warren61c6d0e2012-12-11 13:34:15 +0000141 #elif defined(CONFIG_TEGRA_UARTA_SDIO1)
Lucas Stach4de6eec2012-05-16 08:21:02 +0000142 FUNCMUX_UART1_SDIO1,
Tom Warren61c6d0e2012-12-11 13:34:15 +0000143 #else
Stephen Warren59f90102012-05-14 13:13:45 +0000144 FUNCMUX_UART1_IRRX_IRTX,
Stephen Warren811af732013-01-22 06:20:08 +0000145#endif
146 FUNCMUX_UART2_UAD,
Stephen Warren59f90102012-05-14 13:13:45 +0000147 -1,
148 FUNCMUX_UART4_GMC,
149 -1,
Tom Warrene3d95bc2013-01-28 13:32:10 +0000150#elif defined(CONFIG_TEGRA30)
Tom Warren61c6d0e2012-12-11 13:34:15 +0000151 FUNCMUX_UART1_ULPI, /* UARTA */
152 -1,
153 -1,
154 -1,
155 -1,
Tom Warrene5ffffd2014-01-24 12:46:16 -0700156#elif defined(CONFIG_TEGRA114)
Tom Warrene3d95bc2013-01-28 13:32:10 +0000157 -1,
158 -1,
159 -1,
160 FUNCMUX_UART4_GMI, /* UARTD */
161 -1,
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700162#elif defined(CONFIG_TEGRA124)
Tom Warrene5ffffd2014-01-24 12:46:16 -0700163 FUNCMUX_UART1_KBC, /* UARTA */
164 -1,
165 -1,
166 FUNCMUX_UART4_GPIO, /* UARTD */
167 -1,
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700168#else /* Tegra210 */
169 FUNCMUX_UART1_UART1, /* UARTA */
170 -1,
171 -1,
172 FUNCMUX_UART4_UART4, /* UARTD */
173 -1,
Tom Warren61c6d0e2012-12-11 13:34:15 +0000174#endif
Stephen Warren59f90102012-05-14 13:13:45 +0000175};
176
Simon Glass96b7c432011-11-28 15:04:39 +0000177/**
178 * Set up the specified uarts
179 *
180 * @param uarts_ids Mask containing UARTs to init (UARTx)
181 */
182static void setup_uarts(int uart_ids)
183{
184 static enum periph_id id_for_uart[] = {
185 PERIPH_ID_UART1,
186 PERIPH_ID_UART2,
187 PERIPH_ID_UART3,
188 PERIPH_ID_UART4,
Tom Warrene3d95bc2013-01-28 13:32:10 +0000189 PERIPH_ID_UART5,
Simon Glass96b7c432011-11-28 15:04:39 +0000190 };
191 size_t i;
192
193 for (i = 0; i < UART_COUNT; i++) {
194 if (uart_ids & (1 << i)) {
195 enum periph_id id = id_for_uart[i];
196
Stephen Warren59f90102012-05-14 13:13:45 +0000197 funcmux_select(id, uart_configs[i]);
Simon Glass96b7c432011-11-28 15:04:39 +0000198 clock_ll_start_uart(id);
199 }
200 }
201}
202
203void board_init_uart_f(void)
204{
205 int uart_ids = 0; /* bit mask of which UART ids to enable */
206
Tom Warren22562a42012-09-04 17:00:24 -0700207#ifdef CONFIG_TEGRA_ENABLE_UARTA
Simon Glass96b7c432011-11-28 15:04:39 +0000208 uart_ids |= UARTA;
209#endif
Tom Warren22562a42012-09-04 17:00:24 -0700210#ifdef CONFIG_TEGRA_ENABLE_UARTB
Simon Glass96b7c432011-11-28 15:04:39 +0000211 uart_ids |= UARTB;
212#endif
Tom Warrene3d95bc2013-01-28 13:32:10 +0000213#ifdef CONFIG_TEGRA_ENABLE_UARTC
214 uart_ids |= UARTC;
215#endif
Tom Warren22562a42012-09-04 17:00:24 -0700216#ifdef CONFIG_TEGRA_ENABLE_UARTD
Simon Glass96b7c432011-11-28 15:04:39 +0000217 uart_ids |= UARTD;
218#endif
Tom Warrene3d95bc2013-01-28 13:32:10 +0000219#ifdef CONFIG_TEGRA_ENABLE_UARTE
220 uart_ids |= UARTE;
221#endif
Simon Glass96b7c432011-11-28 15:04:39 +0000222 setup_uarts(uart_ids);
223}
Simon Glass410012f2012-01-09 13:22:15 +0000224
Simon Glassf4402d02015-12-04 08:58:39 -0700225#if !CONFIG_IS_ENABLED(OF_CONTROL)
Thomas Choue3b90262015-11-19 21:48:11 +0800226static struct ns16550_platdata ns16550_com1_pdata = {
227 .base = CONFIG_SYS_NS16550_COM1,
228 .reg_shift = 2,
229 .clock = CONFIG_SYS_NS16550_CLK,
Heiko Schocher06f108e2017-01-18 08:05:49 +0100230 .fcr = UART_FCR_DEFVAL,
Thomas Choue3b90262015-11-19 21:48:11 +0800231};
232
233U_BOOT_DEVICE(ns16550_com1) = {
234 "ns16550_serial", &ns16550_com1_pdata
235};
236#endif
237
Trevor Woerner43ec7e02019-05-03 09:41:00 -0400238#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
Simon Glass410012f2012-01-09 13:22:15 +0000239void enable_caches(void)
240{
241 /* Enable D-cache. I-cache is already enabled in start.S */
242 dcache_enable();
243}
244#endif