]>
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 | ||
7 | #include <common.h> | |
1874626b TC |
8 | #include <dm.h> |
9 | #include <ns16550.h> | |
537e9673 | 10 | #include <spl.h> |
3f82b1d3 | 11 | #include <asm/io.h> |
bb6997f8 SG |
12 | #include <asm/arch/clock.h> |
13 | #include <asm/arch/funcmux.h> | |
8c33ba7b | 14 | #include <asm/arch/mc.h> |
150c2493 | 15 | #include <asm/arch/tegra.h> |
73c38934 | 16 | #include <asm/arch-tegra/ap.h> |
516f00b3 | 17 | #include <asm/arch-tegra/board.h> |
150c2493 TW |
18 | #include <asm/arch-tegra/pmc.h> |
19 | #include <asm/arch-tegra/sys_proto.h> | |
20 | #include <asm/arch-tegra/warmboot.h> | |
3f82b1d3 | 21 | |
659a0755 TW |
22 | void save_boot_params_ret(void); |
23 | ||
3f82b1d3 TW |
24 | DECLARE_GLOBAL_DATA_PTR; |
25 | ||
bb6997f8 SG |
26 | enum { |
27 | /* UARTs which we can enable */ | |
28 | UARTA = 1 << 0, | |
29 | UARTB = 1 << 1, | |
e23bb6a4 | 30 | UARTC = 1 << 2, |
bb6997f8 | 31 | UARTD = 1 << 3, |
e23bb6a4 TW |
32 | UARTE = 1 << 4, |
33 | UART_COUNT = 5, | |
bb6997f8 SG |
34 | }; |
35 | ||
537e9673 SG |
36 | static bool from_spl __attribute__ ((section(".data"))); |
37 | ||
38 | #ifndef CONFIG_SPL_BUILD | |
39 | void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) | |
40 | { | |
41 | from_spl = r0 != UBOOT_NOT_LOADED_FROM_SPL; | |
42 | save_boot_params_ret(); | |
43 | } | |
44 | #endif | |
45 | ||
46 | bool spl_was_boot_source(void) | |
47 | { | |
48 | return from_spl; | |
49 | } | |
50 | ||
73c38934 SW |
51 | #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE) |
52 | #if !defined(CONFIG_TEGRA124) | |
53 | #error tegra_cpu_is_non_secure has only been validated on Tegra124 | |
54 | #endif | |
55 | bool tegra_cpu_is_non_secure(void) | |
56 | { | |
57 | /* | |
58 | * This register reads 0xffffffff in non-secure mode. This register | |
59 | * only implements bits 31:20, so the lower bits will always read 0 in | |
60 | * secure mode. Thus, the lower bits are an indicator for secure vs. | |
61 | * non-secure mode. | |
62 | */ | |
63 | struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE; | |
64 | uint32_t mc_s_cfg0 = readl(&mc->mc_security_cfg0); | |
65 | return (mc_s_cfg0 & 1) == 1; | |
66 | } | |
67 | #endif | |
68 | ||
aeb3fcb3 | 69 | /* Read the RAM size directly from the memory controller */ |
a5fc3d0b | 70 | static phys_size_t query_sdram_size(void) |
aeb3fcb3 SW |
71 | { |
72 | struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE; | |
a5fc3d0b SW |
73 | u32 emem_cfg; |
74 | phys_size_t size_bytes; | |
aeb3fcb3 | 75 | |
3a2cab51 | 76 | emem_cfg = readl(&mc->mc_emem_cfg); |
8c33ba7b | 77 | #if defined(CONFIG_TEGRA20) |
3a2cab51 SW |
78 | debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", emem_cfg); |
79 | size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024); | |
8c33ba7b | 80 | #else |
3a2cab51 | 81 | debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", emem_cfg); |
a5fc3d0b | 82 | #ifndef CONFIG_PHYS_64BIT |
56519c4f SW |
83 | /* |
84 | * If >=4GB RAM is present, the byte RAM size won't fit into 32-bits | |
85 | * and will wrap. Clip the reported size to the maximum that a 32-bit | |
86 | * variable can represent (rounded to a page). | |
87 | */ | |
88 | if (emem_cfg >= 4096) { | |
89 | size_bytes = U32_MAX & ~(0x1000 - 1); | |
a5fc3d0b SW |
90 | } else |
91 | #endif | |
92 | { | |
56519c4f | 93 | /* RAM size EMC is programmed to. */ |
a5fc3d0b SW |
94 | size_bytes = (phys_size_t)emem_cfg * 1024 * 1024; |
95 | #ifndef CONFIG_ARM64 | |
56519c4f SW |
96 | /* |
97 | * If all RAM fits within 32-bits, it can be accessed without | |
98 | * LPAE, so go test the RAM size. Otherwise, we can't access | |
99 | * all the RAM, and get_ram_size() would get confused, so | |
100 | * avoid using it. There's no reason we should need this | |
101 | * validation step anyway. | |
102 | */ | |
103 | if (emem_cfg <= (0 - PHYS_SDRAM_1) / (1024 * 1024)) | |
104 | size_bytes = get_ram_size((void *)PHYS_SDRAM_1, | |
105 | size_bytes); | |
a5fc3d0b | 106 | #endif |
56519c4f | 107 | } |
8c33ba7b | 108 | #endif |
aeb3fcb3 | 109 | |
8c33ba7b MZ |
110 | #if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) |
111 | /* External memory limited to 2047 MB due to IROM/HI-VEC */ | |
3a2cab51 SW |
112 | if (size_bytes == SZ_2G) |
113 | size_bytes -= SZ_1M; | |
aeb3fcb3 | 114 | #endif |
3f82b1d3 | 115 | |
3a2cab51 | 116 | return size_bytes; |
8c33ba7b MZ |
117 | } |
118 | ||
3f82b1d3 TW |
119 | int dram_init(void) |
120 | { | |
3f82b1d3 | 121 | /* We do not initialise DRAM here. We just query the size */ |
7f8c070f | 122 | gd->ram_size = query_sdram_size(); |
3f82b1d3 TW |
123 | return 0; |
124 | } | |
125 | ||
b9607e70 | 126 | static int uart_configs[] = { |
b2871037 TW |
127 | #if defined(CONFIG_TEGRA20) |
128 | #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) | |
b9607e70 | 129 | FUNCMUX_UART1_UAA_UAB, |
b2871037 | 130 | #elif defined(CONFIG_TEGRA_UARTA_GPU) |
e21649be | 131 | FUNCMUX_UART1_GPU, |
b2871037 | 132 | #elif defined(CONFIG_TEGRA_UARTA_SDIO1) |
a2cfe63e | 133 | FUNCMUX_UART1_SDIO1, |
b2871037 | 134 | #else |
b9607e70 | 135 | FUNCMUX_UART1_IRRX_IRTX, |
4727a13b SW |
136 | #endif |
137 | FUNCMUX_UART2_UAD, | |
b9607e70 SW |
138 | -1, |
139 | FUNCMUX_UART4_GMC, | |
140 | -1, | |
e23bb6a4 | 141 | #elif defined(CONFIG_TEGRA30) |
b2871037 TW |
142 | FUNCMUX_UART1_ULPI, /* UARTA */ |
143 | -1, | |
144 | -1, | |
145 | -1, | |
146 | -1, | |
2f5dac92 | 147 | #elif defined(CONFIG_TEGRA114) |
e23bb6a4 TW |
148 | -1, |
149 | -1, | |
150 | -1, | |
151 | FUNCMUX_UART4_GMI, /* UARTD */ | |
152 | -1, | |
7aaa5a60 | 153 | #elif defined(CONFIG_TEGRA124) |
2f5dac92 TW |
154 | FUNCMUX_UART1_KBC, /* UARTA */ |
155 | -1, | |
156 | -1, | |
157 | FUNCMUX_UART4_GPIO, /* UARTD */ | |
158 | -1, | |
7aaa5a60 TW |
159 | #else /* Tegra210 */ |
160 | FUNCMUX_UART1_UART1, /* UARTA */ | |
161 | -1, | |
162 | -1, | |
163 | FUNCMUX_UART4_UART4, /* UARTD */ | |
164 | -1, | |
b2871037 | 165 | #endif |
b9607e70 SW |
166 | }; |
167 | ||
bb6997f8 SG |
168 | /** |
169 | * Set up the specified uarts | |
170 | * | |
171 | * @param uarts_ids Mask containing UARTs to init (UARTx) | |
172 | */ | |
173 | static void setup_uarts(int uart_ids) | |
174 | { | |
175 | static enum periph_id id_for_uart[] = { | |
176 | PERIPH_ID_UART1, | |
177 | PERIPH_ID_UART2, | |
178 | PERIPH_ID_UART3, | |
179 | PERIPH_ID_UART4, | |
e23bb6a4 | 180 | PERIPH_ID_UART5, |
bb6997f8 SG |
181 | }; |
182 | size_t i; | |
183 | ||
184 | for (i = 0; i < UART_COUNT; i++) { | |
185 | if (uart_ids & (1 << i)) { | |
186 | enum periph_id id = id_for_uart[i]; | |
187 | ||
b9607e70 | 188 | funcmux_select(id, uart_configs[i]); |
bb6997f8 SG |
189 | clock_ll_start_uart(id); |
190 | } | |
191 | } | |
192 | } | |
193 | ||
194 | void board_init_uart_f(void) | |
195 | { | |
196 | int uart_ids = 0; /* bit mask of which UART ids to enable */ | |
197 | ||
29f3e3f2 | 198 | #ifdef CONFIG_TEGRA_ENABLE_UARTA |
bb6997f8 SG |
199 | uart_ids |= UARTA; |
200 | #endif | |
29f3e3f2 | 201 | #ifdef CONFIG_TEGRA_ENABLE_UARTB |
bb6997f8 SG |
202 | uart_ids |= UARTB; |
203 | #endif | |
e23bb6a4 TW |
204 | #ifdef CONFIG_TEGRA_ENABLE_UARTC |
205 | uart_ids |= UARTC; | |
206 | #endif | |
29f3e3f2 | 207 | #ifdef CONFIG_TEGRA_ENABLE_UARTD |
bb6997f8 | 208 | uart_ids |= UARTD; |
e23bb6a4 TW |
209 | #endif |
210 | #ifdef CONFIG_TEGRA_ENABLE_UARTE | |
211 | uart_ids |= UARTE; | |
bb6997f8 SG |
212 | #endif |
213 | setup_uarts(uart_ids); | |
214 | } | |
bd29cb05 | 215 | |
878a3ed9 | 216 | #if !CONFIG_IS_ENABLED(OF_CONTROL) |
1874626b TC |
217 | static struct ns16550_platdata ns16550_com1_pdata = { |
218 | .base = CONFIG_SYS_NS16550_COM1, | |
219 | .reg_shift = 2, | |
220 | .clock = CONFIG_SYS_NS16550_CLK, | |
17fa0326 | 221 | .fcr = UART_FCR_DEFVAL, |
1874626b TC |
222 | }; |
223 | ||
224 | U_BOOT_DEVICE(ns16550_com1) = { | |
225 | "ns16550_serial", &ns16550_com1_pdata | |
226 | }; | |
227 | #endif | |
228 | ||
10015025 | 229 | #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) |
bd29cb05 SG |
230 | void enable_caches(void) |
231 | { | |
232 | /* Enable D-cache. I-cache is already enabled in start.S */ | |
233 | dcache_enable(); | |
234 | } | |
235 | #endif |