Commit 9d1303b38b0e18392cc3e14943173a3574283306

Authored by Andreas Dannenberg
Committed by Tom Rini
1 parent 9c0ff866b3

armv7R: K3: j721e: Load SYSFW binary and config from boot media

Use the System Firmware (SYSFW) loader framework to load and start
the SYSFW as part of the J721E early initialization sequence. While
at it also initialize the MCU_UART0 pinmux as it is used by SYSFW
to print diagnostic messages.

Signed-off-by: Andreas Dannenberg <dannenberg@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>

Showing 1 changed file with 30 additions and 0 deletions Inline Diff

arch/arm/mach-k3/j721e_init.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * J721E: SoC specific initialization 3 * J721E: SoC specific initialization
4 * 4 *
5 * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/ 5 * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Lokesh Vutla <lokeshvutla@ti.com> 6 * Lokesh Vutla <lokeshvutla@ti.com>
7 */ 7 */
8 8
9 #include <common.h> 9 #include <common.h>
10 #include <spl.h> 10 #include <spl.h>
11 #include <asm/io.h> 11 #include <asm/io.h>
12 #include <asm/armv7_mpu.h> 12 #include <asm/armv7_mpu.h>
13 #include <asm/arch/hardware.h> 13 #include <asm/arch/hardware.h>
14 #include <asm/arch/sysfw-loader.h>
14 #include "common.h" 15 #include "common.h"
15 #include <asm/arch/sys_proto.h> 16 #include <asm/arch/sys_proto.h>
16 #include <linux/soc/ti/ti_sci_protocol.h> 17 #include <linux/soc/ti/ti_sci_protocol.h>
18 #include <dm.h>
19 #include <dm/uclass-internal.h>
20 #include <dm/pinctrl.h>
17 21
18 #ifdef CONFIG_SPL_BUILD 22 #ifdef CONFIG_SPL_BUILD
19 static void mmr_unlock(u32 base, u32 partition) 23 static void mmr_unlock(u32 base, u32 partition)
20 { 24 {
21 /* Translate the base address */ 25 /* Translate the base address */
22 phys_addr_t part_base = base + partition * CTRL_MMR0_PARTITION_SIZE; 26 phys_addr_t part_base = base + partition * CTRL_MMR0_PARTITION_SIZE;
23 27
24 /* Unlock the requested partition if locked using two-step sequence */ 28 /* Unlock the requested partition if locked using two-step sequence */
25 writel(CTRLMMR_LOCK_KICK0_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK0); 29 writel(CTRLMMR_LOCK_KICK0_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK0);
26 writel(CTRLMMR_LOCK_KICK1_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK1); 30 writel(CTRLMMR_LOCK_KICK1_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK1);
27 } 31 }
28 32
29 static void ctrl_mmr_unlock(void) 33 static void ctrl_mmr_unlock(void)
30 { 34 {
31 /* Unlock all WKUP_CTRL_MMR0 module registers */ 35 /* Unlock all WKUP_CTRL_MMR0 module registers */
32 mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); 36 mmr_unlock(WKUP_CTRL_MMR0_BASE, 0);
33 mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); 37 mmr_unlock(WKUP_CTRL_MMR0_BASE, 1);
34 mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); 38 mmr_unlock(WKUP_CTRL_MMR0_BASE, 2);
35 mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); 39 mmr_unlock(WKUP_CTRL_MMR0_BASE, 3);
36 mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); 40 mmr_unlock(WKUP_CTRL_MMR0_BASE, 4);
37 mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); 41 mmr_unlock(WKUP_CTRL_MMR0_BASE, 6);
38 mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); 42 mmr_unlock(WKUP_CTRL_MMR0_BASE, 7);
39 43
40 /* Unlock all MCU_CTRL_MMR0 module registers */ 44 /* Unlock all MCU_CTRL_MMR0 module registers */
41 mmr_unlock(MCU_CTRL_MMR0_BASE, 0); 45 mmr_unlock(MCU_CTRL_MMR0_BASE, 0);
42 mmr_unlock(MCU_CTRL_MMR0_BASE, 1); 46 mmr_unlock(MCU_CTRL_MMR0_BASE, 1);
43 mmr_unlock(MCU_CTRL_MMR0_BASE, 2); 47 mmr_unlock(MCU_CTRL_MMR0_BASE, 2);
44 mmr_unlock(MCU_CTRL_MMR0_BASE, 3); 48 mmr_unlock(MCU_CTRL_MMR0_BASE, 3);
45 mmr_unlock(MCU_CTRL_MMR0_BASE, 4); 49 mmr_unlock(MCU_CTRL_MMR0_BASE, 4);
46 50
47 /* Unlock all CTRL_MMR0 module registers */ 51 /* Unlock all CTRL_MMR0 module registers */
48 mmr_unlock(CTRL_MMR0_BASE, 0); 52 mmr_unlock(CTRL_MMR0_BASE, 0);
49 mmr_unlock(CTRL_MMR0_BASE, 1); 53 mmr_unlock(CTRL_MMR0_BASE, 1);
50 mmr_unlock(CTRL_MMR0_BASE, 2); 54 mmr_unlock(CTRL_MMR0_BASE, 2);
51 mmr_unlock(CTRL_MMR0_BASE, 3); 55 mmr_unlock(CTRL_MMR0_BASE, 3);
52 mmr_unlock(CTRL_MMR0_BASE, 4); 56 mmr_unlock(CTRL_MMR0_BASE, 4);
53 mmr_unlock(CTRL_MMR0_BASE, 5); 57 mmr_unlock(CTRL_MMR0_BASE, 5);
54 mmr_unlock(CTRL_MMR0_BASE, 6); 58 mmr_unlock(CTRL_MMR0_BASE, 6);
55 mmr_unlock(CTRL_MMR0_BASE, 7); 59 mmr_unlock(CTRL_MMR0_BASE, 7);
56 } 60 }
57 61
58 /* 62 /*
59 * This uninitialized global variable would normal end up in the .bss section, 63 * This uninitialized global variable would normal end up in the .bss section,
60 * but the .bss is cleared between writing and reading this variable, so move 64 * but the .bss is cleared between writing and reading this variable, so move
61 * it to the .data section. 65 * it to the .data section.
62 */ 66 */
63 u32 bootindex __attribute__((section(".data"))); 67 u32 bootindex __attribute__((section(".data")));
64 68
65 static void store_boot_index_from_rom(void) 69 static void store_boot_index_from_rom(void)
66 { 70 {
67 bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); 71 bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
68 } 72 }
69 73
70 void board_init_f(ulong dummy) 74 void board_init_f(ulong dummy)
71 { 75 {
76 #if defined(CONFIG_K3_LOAD_SYSFW)
77 struct udevice *dev;
78 int ret;
79 #endif
72 /* 80 /*
73 * Cannot delay this further as there is a chance that 81 * Cannot delay this further as there is a chance that
74 * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. 82 * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section.
75 */ 83 */
76 store_boot_index_from_rom(); 84 store_boot_index_from_rom();
77 85
78 /* Make all control module registers accessible */ 86 /* Make all control module registers accessible */
79 ctrl_mmr_unlock(); 87 ctrl_mmr_unlock();
80 88
81 #ifdef CONFIG_CPU_V7R 89 #ifdef CONFIG_CPU_V7R
82 setup_k3_mpu_regions(); 90 setup_k3_mpu_regions();
83 #endif 91 #endif
84 92
85 /* Init DM early */ 93 /* Init DM early */
86 spl_early_init(); 94 spl_early_init();
87 95
96 #ifdef CONFIG_K3_LOAD_SYSFW
97 /*
98 * Process pinctrl for the serial0 a.k.a. MCU_UART0 module and continue
99 * regardless of the result of pinctrl. Do this without probing the
100 * device, but instead by searching the device that would request the
101 * given sequence number if probed. The UART will be used by the system
102 * firmware (SYSFW) image for various purposes and SYSFW depends on us
103 * to initialize its pin settings.
104 */
105 ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, true, &dev);
106 if (!ret)
107 pinctrl_select_state(dev, "default");
108
109 /*
110 * Load, start up, and configure system controller firmware. Provide
111 * the U-Boot console init function to the SYSFW post-PM configuration
112 * callback hook, effectively switching on (or over) the console
113 * output.
114 */
115 k3_sysfw_loader(preloader_console_init);
116 #else
88 /* Prepare console output */ 117 /* Prepare console output */
89 preloader_console_init(); 118 preloader_console_init();
119 #endif
90 } 120 }
91 121
92 u32 spl_boot_mode(const u32 boot_device) 122 u32 spl_boot_mode(const u32 boot_device)
93 { 123 {
94 switch (boot_device) { 124 switch (boot_device) {
95 case BOOT_DEVICE_MMC1: 125 case BOOT_DEVICE_MMC1:
96 return MMCSD_MODE_EMMCBOOT; 126 return MMCSD_MODE_EMMCBOOT;
97 case BOOT_DEVICE_MMC2: 127 case BOOT_DEVICE_MMC2:
98 return MMCSD_MODE_FS; 128 return MMCSD_MODE_FS;
99 default: 129 default:
100 return MMCSD_MODE_RAW; 130 return MMCSD_MODE_RAW;
101 } 131 }
102 } 132 }
103 133
104 static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat) 134 static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat)
105 { 135 {
106 136
107 u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> 137 u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >>
108 WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; 138 WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT;
109 139
110 bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << 140 bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) <<
111 BOOT_MODE_B_SHIFT; 141 BOOT_MODE_B_SHIFT;
112 142
113 if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI) 143 if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI)
114 bootmode = BOOT_DEVICE_SPI; 144 bootmode = BOOT_DEVICE_SPI;
115 145
116 if (bootmode == BOOT_DEVICE_MMC2) { 146 if (bootmode == BOOT_DEVICE_MMC2) {
117 u32 port = (main_devstat & 147 u32 port = (main_devstat &
118 MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >> 148 MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >>
119 MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT; 149 MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT;
120 if (port == 0x0) 150 if (port == 0x0)
121 bootmode = BOOT_DEVICE_MMC1; 151 bootmode = BOOT_DEVICE_MMC1;
122 } 152 }
123 153
124 return bootmode; 154 return bootmode;
125 } 155 }
126 156
127 u32 spl_boot_device(void) 157 u32 spl_boot_device(void)
128 { 158 {
129 u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); 159 u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT);
130 u32 main_devstat; 160 u32 main_devstat;
131 161
132 if (wkup_devstat & WKUP_DEVSTAT_MCU_OMLY_MASK) { 162 if (wkup_devstat & WKUP_DEVSTAT_MCU_OMLY_MASK) {
133 printf("ERROR: MCU only boot is not yet supported\n"); 163 printf("ERROR: MCU only boot is not yet supported\n");
134 return BOOT_DEVICE_RAM; 164 return BOOT_DEVICE_RAM;
135 } 165 }
136 166
137 /* MAIN CTRL MMR can only be read if MCU ONLY is 0 */ 167 /* MAIN CTRL MMR can only be read if MCU ONLY is 0 */
138 main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); 168 main_devstat = readl(CTRLMMR_MAIN_DEVSTAT);
139 169
140 /* ToDo: Add support for backup boot media */ 170 /* ToDo: Add support for backup boot media */
141 return __get_primary_bootmedia(main_devstat, wkup_devstat); 171 return __get_primary_bootmedia(main_devstat, wkup_devstat);
142 } 172 }
143 #endif 173 #endif
144 174
145 #ifdef CONFIG_SYS_K3_SPL_ATF 175 #ifdef CONFIG_SYS_K3_SPL_ATF
146 176
147 #define J721E_DEV_MCU_RTI0 262 177 #define J721E_DEV_MCU_RTI0 262
148 #define J721E_DEV_MCU_RTI1 263 178 #define J721E_DEV_MCU_RTI1 263
149 #define J721E_DEV_MCU_ARMSS0_CPU0 250 179 #define J721E_DEV_MCU_ARMSS0_CPU0 250
150 #define J721E_DEV_MCU_ARMSS0_CPU1 251 180 #define J721E_DEV_MCU_ARMSS0_CPU1 251
151 181
152 void release_resources_for_core_shutdown(void) 182 void release_resources_for_core_shutdown(void)
153 { 183 {
154 struct ti_sci_handle *ti_sci; 184 struct ti_sci_handle *ti_sci;
155 struct ti_sci_dev_ops *dev_ops; 185 struct ti_sci_dev_ops *dev_ops;
156 struct ti_sci_proc_ops *proc_ops; 186 struct ti_sci_proc_ops *proc_ops;
157 int ret; 187 int ret;
158 u32 i; 188 u32 i;
159 189
160 const u32 put_device_ids[] = { 190 const u32 put_device_ids[] = {
161 J721E_DEV_MCU_RTI0, 191 J721E_DEV_MCU_RTI0,
162 J721E_DEV_MCU_RTI1, 192 J721E_DEV_MCU_RTI1,
163 }; 193 };
164 194
165 ti_sci = get_ti_sci_handle(); 195 ti_sci = get_ti_sci_handle();
166 dev_ops = &ti_sci->ops.dev_ops; 196 dev_ops = &ti_sci->ops.dev_ops;
167 proc_ops = &ti_sci->ops.proc_ops; 197 proc_ops = &ti_sci->ops.proc_ops;
168 198
169 /* Iterate through list of devices to put (shutdown) */ 199 /* Iterate through list of devices to put (shutdown) */
170 for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) { 200 for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) {
171 u32 id = put_device_ids[i]; 201 u32 id = put_device_ids[i];
172 202
173 ret = dev_ops->put_device(ti_sci, id); 203 ret = dev_ops->put_device(ti_sci, id);
174 if (ret) 204 if (ret)
175 panic("Failed to put device %u (%d)\n", id, ret); 205 panic("Failed to put device %u (%d)\n", id, ret);
176 } 206 }
177 207
178 const u32 put_core_ids[] = { 208 const u32 put_core_ids[] = {
179 J721E_DEV_MCU_ARMSS0_CPU1, 209 J721E_DEV_MCU_ARMSS0_CPU1,
180 J721E_DEV_MCU_ARMSS0_CPU0, /* Handle CPU0 after CPU1 */ 210 J721E_DEV_MCU_ARMSS0_CPU0, /* Handle CPU0 after CPU1 */
181 }; 211 };
182 212
183 /* Iterate through list of cores to put (shutdown) */ 213 /* Iterate through list of cores to put (shutdown) */
184 for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) { 214 for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) {
185 u32 id = put_core_ids[i]; 215 u32 id = put_core_ids[i];
186 216
187 /* 217 /*
188 * Queue up the core shutdown request. Note that this call 218 * Queue up the core shutdown request. Note that this call
189 * needs to be followed up by an actual invocation of an WFE 219 * needs to be followed up by an actual invocation of an WFE
190 * or WFI CPU instruction. 220 * or WFI CPU instruction.
191 */ 221 */
192 ret = proc_ops->proc_shutdown_no_wait(ti_sci, id); 222 ret = proc_ops->proc_shutdown_no_wait(ti_sci, id);
193 if (ret) 223 if (ret)
194 panic("Failed sending core %u shutdown message (%d)\n", 224 panic("Failed sending core %u shutdown message (%d)\n",
195 id, ret); 225 id, ret);
196 } 226 }
197 } 227 }
198 #endif 228 #endif
199 229