blob: 87d4712efd45f52894eb3cb3527de1a28b03e835 [file] [log] [blame]
Andrew Davis5eb8d572024-02-01 18:24:44 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * K3: R5 Common Architecture initialization
4 *
5 * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
6 */
7
Andrew Davisef880db2024-02-01 18:24:45 -06008#include <linux/printk.h>
Andrew Davis5eb8d572024-02-01 18:24:44 -06009#include <linux/types.h>
10#include <asm/hardware.h>
11#include <asm/io.h>
Andrew Davisef880db2024-02-01 18:24:45 -060012#include <image.h>
13#include <fs_loader.h>
14#include <linux/soc/ti/ti_sci_protocol.h>
15#include <spl.h>
16#include <remoteproc.h>
17#include <elf.h>
Andrew Davis5eb8d572024-02-01 18:24:44 -060018
19#include "../common.h"
20
Andrew Davisef880db2024-02-01 18:24:45 -060021#if IS_ENABLED(CONFIG_SYS_K3_SPL_ATF)
22enum {
23 IMAGE_ID_ATF,
24 IMAGE_ID_OPTEE,
25 IMAGE_ID_SPL,
26 IMAGE_ID_DM_FW,
27 IMAGE_AMT,
28};
29
30#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS)
31static const char *image_os_match[IMAGE_AMT] = {
32 "arm-trusted-firmware",
33 "tee",
34 "U-Boot",
35 "DM",
36};
37#endif
38
39static struct image_info fit_image_info[IMAGE_AMT];
40
41void init_env(void)
42{
43#ifdef CONFIG_SPL_ENV_SUPPORT
44 char *part;
45
46 env_init();
47 env_relocate();
48 switch (spl_boot_device()) {
49 case BOOT_DEVICE_MMC2:
50 part = env_get("bootpart");
51 env_set("storage_interface", "mmc");
52 env_set("fw_dev_part", part);
53 break;
54 case BOOT_DEVICE_SPI:
55 env_set("storage_interface", "ubi");
56 env_set("fw_ubi_mtdpart", "UBI");
57 env_set("fw_ubi_volume", "UBI0");
58 break;
59 default:
60 printf("%s from device %u not supported!\n",
61 __func__, spl_boot_device());
62 return;
63 }
64#endif
65}
66
67int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
68{
69 struct udevice *fsdev;
70 char *name = NULL;
71 int size = 0;
72
73 if (!IS_ENABLED(CONFIG_FS_LOADER))
74 return 0;
75
76 *loadaddr = 0;
77#ifdef CONFIG_SPL_ENV_SUPPORT
78 switch (spl_boot_device()) {
79 case BOOT_DEVICE_MMC2:
80 name = env_get(name_fw);
81 *loadaddr = env_get_hex(name_loadaddr, *loadaddr);
82 break;
83 default:
84 printf("Loading rproc fw image from device %u not supported!\n",
85 spl_boot_device());
86 return 0;
87 }
88#endif
89 if (!*loadaddr)
90 return 0;
91
92 if (!get_fs_loader(&fsdev)) {
93 size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr,
94 0, 0);
95 }
96
97 return size;
98}
99
100void release_resources_for_core_shutdown(void)
101{
102 struct ti_sci_handle *ti_sci = get_ti_sci_handle();
103 struct ti_sci_dev_ops *dev_ops = &ti_sci->ops.dev_ops;
104 struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops;
105 int ret;
106 u32 i;
107
108 /* Iterate through list of devices to put (shutdown) */
109 for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) {
110 u32 id = put_device_ids[i];
111
112 ret = dev_ops->put_device(ti_sci, id);
113 if (ret)
114 panic("Failed to put device %u (%d)\n", id, ret);
115 }
116
117 /* Iterate through list of cores to put (shutdown) */
118 for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) {
119 u32 id = put_core_ids[i];
120
121 /*
122 * Queue up the core shutdown request. Note that this call
123 * needs to be followed up by an actual invocation of an WFE
124 * or WFI CPU instruction.
125 */
126 ret = proc_ops->proc_shutdown_no_wait(ti_sci, id);
127 if (ret)
128 panic("Failed sending core %u shutdown message (%d)\n",
129 id, ret);
130 }
131}
132
133void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
134{
135 typedef void __noreturn (*image_entry_noargs_t)(void);
136 struct ti_sci_handle *ti_sci = get_ti_sci_handle();
137 u32 loadaddr = 0;
138 int ret, size = 0, shut_cpu = 0;
139
140 /* Release all the exclusive devices held by SPL before starting ATF */
141 ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci);
142
143 ret = rproc_init();
144 if (ret)
145 panic("rproc failed to be initialized (%d)\n", ret);
146
147 init_env();
148
149 if (!fit_image_info[IMAGE_ID_DM_FW].image_start) {
150 size = load_firmware("name_mcur5f0_0fw", "addr_mcur5f0_0load",
151 &loadaddr);
152 }
153
154 /*
155 * It is assumed that remoteproc device 1 is the corresponding
156 * Cortex-A core which runs ATF. Make sure DT reflects the same.
157 */
158 if (!fit_image_info[IMAGE_ID_ATF].image_start)
159 fit_image_info[IMAGE_ID_ATF].image_start =
160 spl_image->entry_point;
161
162 ret = rproc_load(1, fit_image_info[IMAGE_ID_ATF].image_start, 0x200);
163 if (ret)
164 panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret);
165
166#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS)
167 /* Authenticate ATF */
168 void *image_addr = (void *)fit_image_info[IMAGE_ID_ATF].image_start;
169
170 debug("%s: Authenticating image: addr=%lx, size=%ld, os=%s\n", __func__,
171 fit_image_info[IMAGE_ID_ATF].image_start,
172 fit_image_info[IMAGE_ID_ATF].image_len,
173 image_os_match[IMAGE_ID_ATF]);
174
175 ti_secure_image_post_process(&image_addr,
176 (size_t *)&fit_image_info[IMAGE_ID_ATF].image_len);
177
178 /* Authenticate OPTEE */
179 image_addr = (void *)fit_image_info[IMAGE_ID_OPTEE].image_start;
180
181 debug("%s: Authenticating image: addr=%lx, size=%ld, os=%s\n", __func__,
182 fit_image_info[IMAGE_ID_OPTEE].image_start,
183 fit_image_info[IMAGE_ID_OPTEE].image_len,
184 image_os_match[IMAGE_ID_OPTEE]);
185
186 ti_secure_image_post_process(&image_addr,
187 (size_t *)&fit_image_info[IMAGE_ID_OPTEE].image_len);
188#endif
189
190 if (!fit_image_info[IMAGE_ID_DM_FW].image_len &&
191 !(size > 0 && valid_elf_image(loadaddr))) {
192 shut_cpu = 1;
193 goto start_arm64;
194 }
195
196 if (!fit_image_info[IMAGE_ID_DM_FW].image_start) {
197 loadaddr = load_elf_image_phdr(loadaddr);
198 } else {
199 loadaddr = fit_image_info[IMAGE_ID_DM_FW].image_start;
200 if (valid_elf_image(loadaddr))
201 loadaddr = load_elf_image_phdr(loadaddr);
202 }
203
204 debug("%s: jumping to address %x\n", __func__, loadaddr);
205
206start_arm64:
207 /* Add an extra newline to differentiate the ATF logs from SPL */
208 printf("Starting ATF on ARM64 core...\n\n");
209
210 ret = rproc_start(1);
211 if (ret)
212 panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret);
213
214 if (shut_cpu) {
215 debug("Shutting down...\n");
216 release_resources_for_core_shutdown();
217
218 while (1)
219 asm volatile("wfe");
220 }
221 image_entry_noargs_t image_entry = (image_entry_noargs_t)loadaddr;
222
223 image_entry();
224}
225#endif
226
Andrew Davis5eb8d572024-02-01 18:24:44 -0600227void disable_linefill_optimization(void)
228{
229 u32 actlr;
230
231 /*
232 * On K3 devices there are 2 conditions where R5F can deadlock:
233 * 1.When software is performing series of store operations to
234 * cacheable write back/write allocate memory region and later
235 * on software execute barrier operation (DSB or DMB). R5F may
236 * hang at the barrier instruction.
237 * 2.When software is performing a mix of load and store operations
238 * within a tight loop and store operations are all writing to
239 * cacheable write back/write allocates memory regions, R5F may
240 * hang at one of the load instruction.
241 *
242 * To avoid the above two conditions disable linefill optimization
243 * inside Cortex R5F.
244 */
245 asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (actlr));
246 actlr |= (1 << 13); /* Set DLFO bit */
247 asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr));
248}
Andrew Davisef880db2024-02-01 18:24:45 -0600249
250#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS)
251void board_fit_image_post_process(const void *fit, int node, void **p_image,
252 size_t *p_size)
253{
254 int len;
255 int i;
256 const char *os;
257 u32 addr;
258
259 os = fdt_getprop(fit, node, "os", &len);
260 addr = fdt_getprop_u32_default_node(fit, node, 0, "entry", -1);
261
262 debug("%s: processing image: addr=%x, size=%d, os=%s\n", __func__,
263 addr, *p_size, os);
264
265 for (i = 0; i < IMAGE_AMT; i++) {
266 if (!strcmp(os, image_os_match[i])) {
267 fit_image_info[i].image_start = addr;
268 fit_image_info[i].image_len = *p_size;
269 debug("%s: matched image for ID %d\n", __func__, i);
270 break;
271 }
272 }
273 /*
274 * Only DM and the DTBs are being authenticated here,
275 * rest will be authenticated when A72 cluster is up
276 */
277 if ((i != IMAGE_ID_ATF) && (i != IMAGE_ID_OPTEE)) {
278 ti_secure_image_check_binary(p_image, p_size);
279 ti_secure_image_post_process(p_image, p_size);
280 } else {
281 ti_secure_image_check_binary(p_image, p_size);
282 }
283}
284#endif