]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
3f82b1d3 | 2 | /* |
7aaa5a60 | 3 | * (C) Copyright 2010-2015 |
3f82b1d3 | 4 | * NVIDIA Corporation <www.nvidia.com> |
3f82b1d3 TW |
5 | */ |
6 | ||
d678a59d | 7 | #include <common.h> |
9edefc27 | 8 | #include <cpu_func.h> |
1874626b | 9 | #include <dm.h> |
9b4a205f | 10 | #include <init.h> |
f7ae49fc | 11 | #include <log.h> |
1874626b | 12 | #include <ns16550.h> |
537e9673 | 13 | #include <spl.h> |
90526e9f | 14 | #include <asm/cache.h> |
401d1c4f | 15 | #include <asm/global_data.h> |
3f82b1d3 | 16 | #include <asm/io.h> |
b64e0b92 | 17 | #if IS_ENABLED(CONFIG_TEGRA_CLKRST) |
bb6997f8 | 18 | #include <asm/arch/clock.h> |
b64e0b92 | 19 | #endif |
b98bed0e | 20 | #if CONFIG_IS_ENABLED(PINCTRL_TEGRA) |
bb6997f8 | 21 | #include <asm/arch/funcmux.h> |
07ea02bc | 22 | #endif |
1a869c70 | 23 | #if IS_ENABLED(CONFIG_TEGRA_MC) |
8c33ba7b | 24 | #include <asm/arch/mc.h> |
1a869c70 | 25 | #endif |
150c2493 | 26 | #include <asm/arch/tegra.h> |
73c38934 | 27 | #include <asm/arch-tegra/ap.h> |
516f00b3 | 28 | #include <asm/arch-tegra/board.h> |
a0dbc131 | 29 | #include <asm/arch-tegra/cboot.h> |
150c2493 TW |
30 | #include <asm/arch-tegra/pmc.h> |
31 | #include <asm/arch-tegra/sys_proto.h> | |
32 | #include <asm/arch-tegra/warmboot.h> | |
3f82b1d3 | 33 | |
659a0755 TW |
34 | void save_boot_params_ret(void); |
35 | ||
3f82b1d3 TW |
36 | DECLARE_GLOBAL_DATA_PTR; |
37 | ||
bb6997f8 SG |
38 | enum { |
39 | /* UARTs which we can enable */ | |
40 | UARTA = 1 << 0, | |
41 | UARTB = 1 << 1, | |
e23bb6a4 | 42 | UARTC = 1 << 2, |
bb6997f8 | 43 | UARTD = 1 << 3, |
e23bb6a4 TW |
44 | UARTE = 1 << 4, |
45 | UART_COUNT = 5, | |
bb6997f8 SG |
46 | }; |
47 | ||
236f2ec4 | 48 | static bool from_spl __section(".data"); |
537e9673 SG |
49 | |
50 | #ifndef CONFIG_SPL_BUILD | |
8f60d18f TR |
51 | void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2, |
52 | unsigned long r3) | |
537e9673 SG |
53 | { |
54 | from_spl = r0 != UBOOT_NOT_LOADED_FROM_SPL; | |
a0dbc131 TR |
55 | |
56 | /* | |
57 | * The logic for this is somewhat indirect. The purpose of the marker | |
58 | * (UBOOT_NOT_LOADED_FROM_SPL) is in fact used to determine if U-Boot | |
59 | * was loaded from a read-only instance of itself, which is something | |
60 | * that can happen in secure boot setups. So basically the presence | |
61 | * of the marker is an indication that U-Boot was loaded by one such | |
62 | * special variant of U-Boot. Conversely, the absence of the marker | |
63 | * indicates that this instance of U-Boot was loaded by something | |
64 | * other than a special U-Boot. This could be SPL, but it could just | |
65 | * as well be one of any number of other first stage bootloaders. | |
66 | */ | |
67 | if (from_spl) | |
68 | cboot_save_boot_params(r0, r1, r2, r3); | |
69 | ||
537e9673 SG |
70 | save_boot_params_ret(); |
71 | } | |
72 | #endif | |
73 | ||
74 | bool spl_was_boot_source(void) | |
75 | { | |
76 | return from_spl; | |
77 | } | |
78 | ||
73c38934 | 79 | #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE) |
73c38934 SW |
80 | bool tegra_cpu_is_non_secure(void) |
81 | { | |
82 | /* | |
83 | * This register reads 0xffffffff in non-secure mode. This register | |
84 | * only implements bits 31:20, so the lower bits will always read 0 in | |
85 | * secure mode. Thus, the lower bits are an indicator for secure vs. | |
86 | * non-secure mode. | |
87 | */ | |
88 | struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE; | |
89 | uint32_t mc_s_cfg0 = readl(&mc->mc_security_cfg0); | |
90 | return (mc_s_cfg0 & 1) == 1; | |
91 | } | |
92 | #endif | |
93 | ||
1a869c70 | 94 | #if IS_ENABLED(CONFIG_TEGRA_MC) |
aeb3fcb3 | 95 | /* Read the RAM size directly from the memory controller */ |
a5fc3d0b | 96 | static phys_size_t query_sdram_size(void) |
aeb3fcb3 SW |
97 | { |
98 | struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE; | |
a5fc3d0b SW |
99 | u32 emem_cfg; |
100 | phys_size_t size_bytes; | |
aeb3fcb3 | 101 | |
3a2cab51 | 102 | emem_cfg = readl(&mc->mc_emem_cfg); |
8c33ba7b | 103 | #if defined(CONFIG_TEGRA20) |
3a2cab51 SW |
104 | debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", emem_cfg); |
105 | size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024); | |
8c33ba7b | 106 | #else |
3a2cab51 | 107 | debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", emem_cfg); |
a5fc3d0b | 108 | #ifndef CONFIG_PHYS_64BIT |
56519c4f SW |
109 | /* |
110 | * If >=4GB RAM is present, the byte RAM size won't fit into 32-bits | |
111 | * and will wrap. Clip the reported size to the maximum that a 32-bit | |
112 | * variable can represent (rounded to a page). | |
113 | */ | |
114 | if (emem_cfg >= 4096) { | |
115 | size_bytes = U32_MAX & ~(0x1000 - 1); | |
a5fc3d0b SW |
116 | } else |
117 | #endif | |
118 | { | |
56519c4f | 119 | /* RAM size EMC is programmed to. */ |
a5fc3d0b SW |
120 | size_bytes = (phys_size_t)emem_cfg * 1024 * 1024; |
121 | #ifndef CONFIG_ARM64 | |
56519c4f SW |
122 | /* |
123 | * If all RAM fits within 32-bits, it can be accessed without | |
124 | * LPAE, so go test the RAM size. Otherwise, we can't access | |
125 | * all the RAM, and get_ram_size() would get confused, so | |
126 | * avoid using it. There's no reason we should need this | |
127 | * validation step anyway. | |
128 | */ | |
129 | if (emem_cfg <= (0 - PHYS_SDRAM_1) / (1024 * 1024)) | |
130 | size_bytes = get_ram_size((void *)PHYS_SDRAM_1, | |
131 | size_bytes); | |
a5fc3d0b | 132 | #endif |
56519c4f | 133 | } |
8c33ba7b | 134 | #endif |
aeb3fcb3 | 135 | |
8c33ba7b MZ |
136 | #if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) |
137 | /* External memory limited to 2047 MB due to IROM/HI-VEC */ | |
3a2cab51 SW |
138 | if (size_bytes == SZ_2G) |
139 | size_bytes -= SZ_1M; | |
aeb3fcb3 | 140 | #endif |
3f82b1d3 | 141 | |
3a2cab51 | 142 | return size_bytes; |
8c33ba7b | 143 | } |
1a869c70 | 144 | #endif |
8c33ba7b | 145 | |
3f82b1d3 TW |
146 | int dram_init(void) |
147 | { | |
a0dbc131 TR |
148 | int err; |
149 | ||
150 | /* try to initialize DRAM from cboot DTB first */ | |
151 | err = cboot_dram_init(); | |
152 | if (err == 0) | |
153 | return 0; | |
154 | ||
1a869c70 | 155 | #if IS_ENABLED(CONFIG_TEGRA_MC) |
3f82b1d3 | 156 | /* We do not initialise DRAM here. We just query the size */ |
7f8c070f | 157 | gd->ram_size = query_sdram_size(); |
1a869c70 TR |
158 | #endif |
159 | ||
3f82b1d3 TW |
160 | return 0; |
161 | } | |
162 | ||
b98bed0e | 163 | #if CONFIG_IS_ENABLED(PINCTRL_TEGRA) |
b9607e70 | 164 | static int uart_configs[] = { |
b2871037 TW |
165 | #if defined(CONFIG_TEGRA20) |
166 | #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) | |
b9607e70 | 167 | FUNCMUX_UART1_UAA_UAB, |
b2871037 | 168 | #elif defined(CONFIG_TEGRA_UARTA_GPU) |
e21649be | 169 | FUNCMUX_UART1_GPU, |
b2871037 | 170 | #elif defined(CONFIG_TEGRA_UARTA_SDIO1) |
a2cfe63e | 171 | FUNCMUX_UART1_SDIO1, |
b2871037 | 172 | #else |
b9607e70 | 173 | FUNCMUX_UART1_IRRX_IRTX, |
4727a13b SW |
174 | #endif |
175 | FUNCMUX_UART2_UAD, | |
b9607e70 SW |
176 | -1, |
177 | FUNCMUX_UART4_GMC, | |
178 | -1, | |
e23bb6a4 | 179 | #elif defined(CONFIG_TEGRA30) |
b2871037 TW |
180 | FUNCMUX_UART1_ULPI, /* UARTA */ |
181 | -1, | |
182 | -1, | |
183 | -1, | |
184 | -1, | |
2f5dac92 | 185 | #elif defined(CONFIG_TEGRA114) |
e23bb6a4 TW |
186 | -1, |
187 | -1, | |
188 | -1, | |
189 | FUNCMUX_UART4_GMI, /* UARTD */ | |
190 | -1, | |
7aaa5a60 | 191 | #elif defined(CONFIG_TEGRA124) |
2f5dac92 TW |
192 | FUNCMUX_UART1_KBC, /* UARTA */ |
193 | -1, | |
194 | -1, | |
195 | FUNCMUX_UART4_GPIO, /* UARTD */ | |
196 | -1, | |
7aaa5a60 TW |
197 | #else /* Tegra210 */ |
198 | FUNCMUX_UART1_UART1, /* UARTA */ | |
199 | -1, | |
200 | -1, | |
201 | FUNCMUX_UART4_UART4, /* UARTD */ | |
202 | -1, | |
b2871037 | 203 | #endif |
b9607e70 SW |
204 | }; |
205 | ||
bb6997f8 SG |
206 | /** |
207 | * Set up the specified uarts | |
208 | * | |
209 | * @param uarts_ids Mask containing UARTs to init (UARTx) | |
210 | */ | |
211 | static void setup_uarts(int uart_ids) | |
212 | { | |
213 | static enum periph_id id_for_uart[] = { | |
214 | PERIPH_ID_UART1, | |
215 | PERIPH_ID_UART2, | |
216 | PERIPH_ID_UART3, | |
217 | PERIPH_ID_UART4, | |
e23bb6a4 | 218 | PERIPH_ID_UART5, |
bb6997f8 SG |
219 | }; |
220 | size_t i; | |
221 | ||
222 | for (i = 0; i < UART_COUNT; i++) { | |
223 | if (uart_ids & (1 << i)) { | |
224 | enum periph_id id = id_for_uart[i]; | |
225 | ||
b9607e70 | 226 | funcmux_select(id, uart_configs[i]); |
bb6997f8 SG |
227 | clock_ll_start_uart(id); |
228 | } | |
229 | } | |
230 | } | |
07ea02bc | 231 | #endif |
bb6997f8 SG |
232 | |
233 | void board_init_uart_f(void) | |
234 | { | |
b98bed0e | 235 | #if CONFIG_IS_ENABLED(PINCTRL_TEGRA) |
bb6997f8 SG |
236 | int uart_ids = 0; /* bit mask of which UART ids to enable */ |
237 | ||
29f3e3f2 | 238 | #ifdef CONFIG_TEGRA_ENABLE_UARTA |
bb6997f8 SG |
239 | uart_ids |= UARTA; |
240 | #endif | |
29f3e3f2 | 241 | #ifdef CONFIG_TEGRA_ENABLE_UARTB |
bb6997f8 SG |
242 | uart_ids |= UARTB; |
243 | #endif | |
e23bb6a4 TW |
244 | #ifdef CONFIG_TEGRA_ENABLE_UARTC |
245 | uart_ids |= UARTC; | |
246 | #endif | |
29f3e3f2 | 247 | #ifdef CONFIG_TEGRA_ENABLE_UARTD |
bb6997f8 | 248 | uart_ids |= UARTD; |
e23bb6a4 TW |
249 | #endif |
250 | #ifdef CONFIG_TEGRA_ENABLE_UARTE | |
251 | uart_ids |= UARTE; | |
bb6997f8 SG |
252 | #endif |
253 | setup_uarts(uart_ids); | |
07ea02bc | 254 | #endif |
bb6997f8 | 255 | } |
bd29cb05 | 256 | |
878a3ed9 | 257 | #if !CONFIG_IS_ENABLED(OF_CONTROL) |
8a8d24bd | 258 | static struct ns16550_plat ns16550_com1_pdata = { |
91092132 | 259 | .base = CFG_SYS_NS16550_COM1, |
1874626b | 260 | .reg_shift = 2, |
91092132 | 261 | .clock = CFG_SYS_NS16550_CLK, |
17fa0326 | 262 | .fcr = UART_FCR_DEFVAL, |
1874626b TC |
263 | }; |
264 | ||
20e442ab | 265 | U_BOOT_DRVINFO(ns16550_com1) = { |
1874626b TC |
266 | "ns16550_serial", &ns16550_com1_pdata |
267 | }; | |
268 | #endif | |
269 | ||
10015025 | 270 | #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) |
bd29cb05 SG |
271 | void enable_caches(void) |
272 | { | |
273 | /* Enable D-cache. I-cache is already enabled in start.S */ | |
274 | dcache_enable(); | |
275 | } | |
276 | #endif |