blob: 74631a4ce93a583cdb8131b83d716fd051c49ad7 [file] [log] [blame]
Bryan Brattlofa4d5cc22024-03-12 15:20:24 -05001// SPDX-License-Identifier: GPL-2.0
2/*
3 * AM62P5: SoC specific initialization
4 *
5 * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
6 */
7
8#include <spl.h>
9#include <asm/io.h>
10#include <asm/arch/hardware.h>
Bryan Brattlofa4d5cc22024-03-12 15:20:24 -050011#include <dm.h>
12#include <dm/uclass-internal.h>
13#include <dm/pinctrl.h>
Aparna Patra29b9f0e2025-01-08 10:19:39 +053014#include <dm/ofnode.h>
Bryan Brattlofa4d5cc22024-03-12 15:20:24 -050015
Andrew Davis336b0792024-05-10 15:21:24 -050016#include "../sysfw-loader.h"
17#include "../common.h"
18
Aparna Patra29b9f0e2025-01-08 10:19:39 +053019/* TISCI DEV ID for A53 Clock */
20#define AM62PX_DEV_A53SS0_CORE_0_DEV_ID 135
21
Bryan Brattlofa4d5cc22024-03-12 15:20:24 -050022struct fwl_data cbass_main_fwls[] = {
23 { "FSS_DAT_REG3", 7, 8 },
24};
25
26/*
27 * This uninitialized global variable would normal end up in the .bss section,
28 * but the .bss is cleared between writing and reading this variable, so move
29 * it to the .data section.
30 */
31u32 bootindex __section(".data");
32static struct rom_extended_boot_data bootdata __section(".data");
33
34static void store_boot_info_from_rom(void)
35{
36 bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
37 memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO,
38 sizeof(struct rom_extended_boot_data));
39}
40
41static void ctrl_mmr_unlock(void)
42{
43 /* Unlock all WKUP_CTRL_MMR0 module registers */
44 mmr_unlock(WKUP_CTRL_MMR0_BASE, 0);
45 mmr_unlock(WKUP_CTRL_MMR0_BASE, 1);
46 mmr_unlock(WKUP_CTRL_MMR0_BASE, 2);
47 mmr_unlock(WKUP_CTRL_MMR0_BASE, 3);
48 mmr_unlock(WKUP_CTRL_MMR0_BASE, 4);
49 mmr_unlock(WKUP_CTRL_MMR0_BASE, 5);
50 mmr_unlock(WKUP_CTRL_MMR0_BASE, 6);
51 mmr_unlock(WKUP_CTRL_MMR0_BASE, 7);
52
53 /* Unlock all CTRL_MMR0 module registers */
54 mmr_unlock(CTRL_MMR0_BASE, 0);
55 mmr_unlock(CTRL_MMR0_BASE, 1);
56 mmr_unlock(CTRL_MMR0_BASE, 2);
57 mmr_unlock(CTRL_MMR0_BASE, 4);
58 mmr_unlock(CTRL_MMR0_BASE, 5);
59 mmr_unlock(CTRL_MMR0_BASE, 6);
60
61 /* Unlock all MCU_CTRL_MMR0 module registers */
62 mmr_unlock(MCU_CTRL_MMR0_BASE, 0);
63 mmr_unlock(MCU_CTRL_MMR0_BASE, 1);
64 mmr_unlock(MCU_CTRL_MMR0_BASE, 2);
65 mmr_unlock(MCU_CTRL_MMR0_BASE, 3);
66 mmr_unlock(MCU_CTRL_MMR0_BASE, 4);
67 mmr_unlock(MCU_CTRL_MMR0_BASE, 6);
68
69 /* Unlock PADCFG_CTRL_MMR padconf registers */
70 mmr_unlock(PADCFG_MMR0_BASE, 1);
71 mmr_unlock(PADCFG_MMR1_BASE, 1);
72}
Aparna Patra29b9f0e2025-01-08 10:19:39 +053073
74#if CONFIG_IS_ENABLED(OF_CONTROL)
75static int get_a53_cpu_clock_index(ofnode node)
76{
77 int count, i;
78 struct ofnode_phandle_args *args;
79 ofnode clknode;
80
81 clknode = ofnode_path("/bus@f0000/system-controller@44043000/clock-controller");
82 if (!ofnode_valid(clknode))
83 return -1;
84
85 count = ofnode_count_phandle_with_args(node, "assigned-clocks", "#clock-cells", 0);
86
87 for (i = 0; i < count; i++) {
88 if (!ofnode_parse_phandle_with_args(node, "assigned-clocks",
89 "#clock-cells", 0, i, args)) {
90 if (ofnode_equal(clknode, args->node) &&
91 args->args[0] == AM62PX_DEV_A53SS0_CORE_0_DEV_ID)
92 return i;
93 }
94 }
95
96 return -1;
97}
98
99static void fixup_a53_cpu_freq_by_speed_grade(void)
100{
101 int index, size;
102 u32 *rates;
103 ofnode node;
104
105 node = ofnode_path("/a53@0");
106 if (!ofnode_valid(node))
107 return;
108
109 rates = fdt_getprop_w(ofnode_to_fdt(node), ofnode_to_offset(node),
110 "assigned-clock-rates", &size);
111
112 index = get_a53_cpu_clock_index(node);
113
114 if (!rates || index < 0 || index >= (size / sizeof(u32))) {
115 printf("Wrong A53 assigned-clocks configuration\n");
116 return;
117 }
118
119 rates[index] = cpu_to_fdt32(k3_get_a53_max_frequency());
120
121 printf("Changed A53 CPU frequency to %dHz (%c grade) in DT\n",
122 k3_get_a53_max_frequency(), k3_get_speed_grade());
123}
124#else
125static void fixup_a53_cpu_freq_by_speed_grade(void)
126{
127}
128#endif
Bryan Brattlofa4d5cc22024-03-12 15:20:24 -0500129
130void board_init_f(ulong dummy)
131{
132 struct udevice *dev;
133 int ret;
134
135 if (IS_ENABLED(CONFIG_CPU_V7R))
136 setup_k3_mpu_regions();
137
138 /*
139 * Cannot delay this further as there is a chance that
140 * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section.
141 */
142 store_boot_info_from_rom();
143
144 ctrl_mmr_unlock();
145
146 /* Init DM early */
147 ret = spl_early_init();
148 if (ret)
149 panic("spl_early_init() failed: %d\n", ret);
150
151 /*
152 * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and
153 * MAIN_UART1 modules and continue regardless of the result of pinctrl.
154 * Do this without probing the device, but instead by searching the
155 * device that would request the given sequence number if probed. The
156 * UARTs will be used by the DM firmware and TIFS firmware images
157 * respectively and the firmware depend on SPL to initialize the pin
158 * settings.
159 */
160 ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev);
161 if (!ret)
162 pinctrl_select_state(dev, "default");
163
164 ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev);
165 if (!ret)
166 pinctrl_select_state(dev, "default");
167
168 /*
169 * Allow establishing an early console as required for example when
170 * doing a UART-based boot. Note that this console may not "survive"
171 * through a SYSFW PM-init step and will need a re-init in some way
172 * due to changing module clock frequencies.
173 */
174 if (IS_ENABLED(CONFIG_K3_EARLY_CONS)) {
175 ret = early_console_init();
176 if (ret)
177 panic("early_console_init() failed: %d\n", ret);
178 }
179
180 /*
181 * Configure and start up system controller firmware. Provide
182 * the U-Boot console init function to the SYSFW post-PM configuration
183 * callback hook, effectively switching on (or over) the console
184 * output.
185 */
186 if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) {
187 ret = is_rom_loaded_sysfw(&bootdata);
188 if (!ret)
189 panic("ROM has not loaded TIFS firmware\n");
190
191 k3_sysfw_loader(true, NULL, NULL);
192
193 /* Disable ROM configured firewalls */
194 remove_fwl_configs(cbass_main_fwls,
195 ARRAY_SIZE(cbass_main_fwls));
196 }
197
198 /*
199 * Force probe of clk_k3 driver here to ensure basic default clock
200 * configuration is always done.
201 */
202 if (IS_ENABLED(CONFIG_SPL_CLK_K3)) {
203 ret = uclass_get_device_by_driver(UCLASS_CLK,
204 DM_DRIVER_GET(ti_clk),
205 &dev);
206 if (ret)
207 printf("Failed to initialize clk-k3!\n");
208 }
209
210 preloader_console_init();
211
212 /* Output System Firmware version info */
213 k3_sysfw_print_ver();
214
215 if (IS_ENABLED(CONFIG_K3_AM62A_DDRSS)) {
216 ret = uclass_get_device(UCLASS_RAM, 0, &dev);
217 if (ret)
218 panic("DRAM init failed: %d\n", ret);
219 }
220
221 spl_enable_cache();
222 debug("am62px_init: %s done\n", __func__);
Aparna Patra29b9f0e2025-01-08 10:19:39 +0530223
224 fixup_a53_cpu_freq_by_speed_grade();
Bryan Brattlofa4d5cc22024-03-12 15:20:24 -0500225}
226
227u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
228{
229 u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT);
230 u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >>
231 MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT;
232 u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >>
233 MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT;
234
235 switch (bootmode) {
236 case BOOT_DEVICE_EMMC:
237 return MMCSD_MODE_EMMCBOOT;
238 case BOOT_DEVICE_MMC:
239 if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_FS_RAW_MASK)
240 return MMCSD_MODE_RAW;
241 default:
242 return MMCSD_MODE_FS;
243 }
244}
245
246static u32 __get_backup_bootmedia(u32 devstat)
247{
248 u32 bkup_bootmode = (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_MASK) >>
249 MAIN_DEVSTAT_BACKUP_BOOTMODE_SHIFT;
250 u32 bkup_bootmode_cfg =
251 (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_MASK) >>
252 MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_SHIFT;
253
254 switch (bkup_bootmode) {
255 case BACKUP_BOOT_DEVICE_UART:
256 return BOOT_DEVICE_UART;
257
258 case BACKUP_BOOT_DEVICE_USB:
259 return BOOT_DEVICE_USB;
260
261 case BACKUP_BOOT_DEVICE_ETHERNET:
262 return BOOT_DEVICE_ETHERNET;
263
264 case BACKUP_BOOT_DEVICE_MMC:
265 if (bkup_bootmode_cfg)
266 return BOOT_DEVICE_MMC2;
267 return BOOT_DEVICE_MMC1;
268
269 case BACKUP_BOOT_DEVICE_SPI:
270 return BOOT_DEVICE_SPI;
271
272 case BACKUP_BOOT_DEVICE_I2C:
273 return BOOT_DEVICE_I2C;
274
275 case BACKUP_BOOT_DEVICE_DFU:
276 if (bkup_bootmode_cfg & MAIN_DEVSTAT_BACKUP_USB_MODE_MASK)
277 return BOOT_DEVICE_USB;
278 return BOOT_DEVICE_DFU;
279 };
280
281 return BOOT_DEVICE_RAM;
282}
283
284static u32 __get_primary_bootmedia(u32 devstat)
285{
286 u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >>
287 MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT;
288 u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >>
289 MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT;
290
291 switch (bootmode) {
292 case BOOT_DEVICE_OSPI:
293 fallthrough;
294 case BOOT_DEVICE_QSPI:
295 fallthrough;
296 case BOOT_DEVICE_XSPI:
297 fallthrough;
298 case BOOT_DEVICE_SPI:
299 return BOOT_DEVICE_SPI;
300
301 case BOOT_DEVICE_ETHERNET_RGMII:
302 fallthrough;
303 case BOOT_DEVICE_ETHERNET_RMII:
304 return BOOT_DEVICE_ETHERNET;
305
306 case BOOT_DEVICE_EMMC:
307 return BOOT_DEVICE_MMC1;
308
309 case BOOT_DEVICE_SPI_NAND:
310 return BOOT_DEVICE_SPINAND;
311
312 case BOOT_DEVICE_MMC:
313 if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_PORT_MASK) >>
314 MAIN_DEVSTAT_PRIMARY_MMC_PORT_SHIFT)
315 return BOOT_DEVICE_MMC2;
316 return BOOT_DEVICE_MMC1;
317
318 case BOOT_DEVICE_DFU:
319 if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_USB_MODE_MASK) >>
320 MAIN_DEVSTAT_PRIMARY_USB_MODE_SHIFT)
321 return BOOT_DEVICE_USB;
322 return BOOT_DEVICE_DFU;
323
324 case BOOT_DEVICE_NOBOOT:
325 return BOOT_DEVICE_RAM;
326 }
327
328 return bootmode;
329}
330
331u32 spl_boot_device(void)
332{
333 u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT);
334 u32 bootmedia;
335
336 if (bootindex == K3_PRIMARY_BOOTMODE)
337 bootmedia = __get_primary_bootmedia(devstat);
338 else
339 bootmedia = __get_backup_bootmedia(devstat);
340
341 debug("am62px_init: %s: devstat = 0x%x bootmedia = 0x%x bootindex = %d\n",
342 __func__, devstat, bootmedia, bootindex);
343 return bootmedia;
344}