1 /**
2 * \file sbl_slave_core_boot.c
3 *
4 * \brief This file contain functions related to slave core boot-up.
5 *
6 */
8 /*
9 * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the
21 * distribution.
22 *
23 * Neither the name of Texas Instruments Incorporated nor the names of
24 * its contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 */
41 /* ========================================================================== */
42 /* Include Files */
43 /* ========================================================================== */
45 #include <stdint.h>
46 #include <string.h>
47 #include <ti/csl/csl_types.h>
48 #include <ti/csl/cslr_device.h>
49 #include <ti/csl/hw_types.h>
50 #include <ti/csl/arch/csl_arch.h>
51 #include <ti/drv/uart/UART_stdio.h>
53 #include "sbl_soc.h"
54 #include "sbl_log.h"
55 #include "sbl_soc_cfg.h"
56 #include "sbl_profile.h"
57 #include "sbl_err_trap.h"
58 #include "sbl_sci_client.h"
59 #include "sbl_slave_core_boot.h"
61 #if defined(BOOT_OSPI)
62 #include "sbl_ospi.h"
63 #endif
65 #if defined(BOOT_MMCSD)
66 #include "sbl_mmcsd.h"
67 #endif
69 #if defined(BOOT_UART)
70 #include "sbl_uart.h"
71 #endif
73 #if defined(BOOT_HYPERFLASH)
74 #include "sbl_hyperflash.h"
75 #endif
76 /* ========================================================================== */
77 /* Macros & Typedefs */
78 /* ========================================================================== */
79 #define SBL_DISABLE_MCU_LOCKSTEP (0)
80 #define SBL_ENABLE_MCU_LOCKSTEP (1)
82 /* Don't forget to update parameter OPP of the AVS */
83 /* setup function in SBL_SocLateInit if the CPU freq */
84 /* are changed to a higher or lower operating point */
85 static const sblSlaveCoreInfo_t sbl_slave_core_info[] =
86 {
87 /* MPU1_CPU0 info */
88 {
89 SBL_PROC_ID_MPU1_CPU0,
90 SBL_DEV_ID_MPU1_CPU0,
91 SBL_CLK_ID_MPU1_CPU0,
92 SBL_MPU1_CPU0_FREQ_HZ,
93 },
94 /* MPU1_CPU1 info */
95 {
96 SBL_PROC_ID_MPU1_CPU1,
97 SBL_DEV_ID_MPU1_CPU1,
98 SBL_CLK_ID_MPU1_CPU1,
99 SBL_MPU1_CPU1_FREQ_HZ,
100 },
101 /* MPU2_CPU0 info */
102 {
103 SBL_PROC_ID_MPU2_CPU0,
104 SBL_DEV_ID_MPU2_CPU0,
105 SBL_CLK_ID_MPU2_CPU0,
106 SBL_MPU2_CPU0_FREQ_HZ,
107 },
108 /* MPU2_CPU1 info */
109 {
110 SBL_PROC_ID_MPU2_CPU1,
111 SBL_DEV_ID_MPU2_CPU1,
112 SBL_CLK_ID_MPU2_CPU1,
113 SBL_MPU2_CPU1_FREQ_HZ,
114 },
115 /* MCU1_CPU0 info */
116 {
117 SBL_PROC_ID_MCU1_CPU0,
118 SBL_DEV_ID_MCU1_CPU0,
119 SBL_CLK_ID_MCU1_CPU0,
120 SBL_MCU1_CPU0_FREQ_HZ,
121 },
122 /* MCU1_CPU1 info */
123 {
124 SBL_PROC_ID_MCU1_CPU1,
125 SBL_DEV_ID_MCU1_CPU1,
126 SBL_CLK_ID_MCU1_CPU1,
127 SBL_MCU1_CPU1_FREQ_HZ,
128 },
129 /* MCU2_CPU0 info */
130 {
131 SBL_PROC_ID_MCU2_CPU0,
132 SBL_DEV_ID_MCU2_CPU0,
133 SBL_CLK_ID_MCU2_CPU0,
134 SBL_MCU2_CPU0_FREQ_HZ,
135 },
136 /* MCU2_CPU1 info */
137 {
138 SBL_PROC_ID_MCU2_CPU1,
139 SBL_DEV_ID_MCU2_CPU1,
140 SBL_CLK_ID_MCU2_CPU1,
141 SBL_MCU2_CPU1_FREQ_HZ,
142 },
143 /* MCU3_CPU0 info */
144 {
145 SBL_PROC_ID_MCU3_CPU0,
146 SBL_DEV_ID_MCU3_CPU0,
147 SBL_CLK_ID_MCU3_CPU0,
148 SBL_MCU3_CPU0_FREQ_HZ,
149 },
150 /* MCU3_CPU1 info */
151 {
152 SBL_PROC_ID_MCU3_CPU1,
153 SBL_DEV_ID_MCU3_CPU1,
154 SBL_CLK_ID_MCU3_CPU1,
155 SBL_MCU3_CPU1_FREQ_HZ,
156 },
157 /* DSP1_C66X info */
158 {
159 SBL_PROC_ID_DSP1_C66X,
160 SBL_DEV_ID_DSP1_C66X,
161 SBL_CLK_ID_DSP1_C66X,
162 SBL_DSP1_C66X_FREQ_HZ,
163 },
164 /* DSP2_C66X info */
165 {
166 SBL_PROC_ID_DSP2_C66X,
167 SBL_DEV_ID_DSP2_C66X,
168 SBL_CLK_ID_DSP2_C66X,
169 SBL_DSP2_C66X_FREQ_HZ,
170 },
171 /* DSP1_C7X info */
172 {
173 SBL_PROC_ID_DSP1_C7X,
174 SBL_DEV_ID_DSP1_C7X,
175 SBL_CLK_ID_DSP1_C7X,
176 SBL_DSP1_C7X_FREQ_HZ,
177 },
178 /* DSP2_C7X info */
179 {
180 SBL_PROC_ID_DSP2_C7X,
181 SBL_DEV_ID_DSP2_C7X,
182 SBL_CLK_ID_DSP2_C7X,
183 SBL_DSP2_C7X_FREQ_HZ,
184 },
185 /* M4F Core0 info*/
186 {
187 SBL_PROC_ID_M4F_CPU0,
188 SBL_DEV_ID_M4F_CPU0,
189 SBL_CLK_ID_M4F_CPU0,
190 SBL_M4F_CPU0_FREQ_HZ,
191 }
192 };
194 static const uint32_t SblAtcmAddr[] =
195 {
196 SBL_MCU_ATCM_BASE,
197 SBL_MCU1_CPU1_ATCM_BASE_ADDR_SOC,
198 SBL_MCU2_CPU0_ATCM_BASE_ADDR_SOC,
199 SBL_MCU2_CPU1_ATCM_BASE_ADDR_SOC,
200 SBL_MCU3_CPU0_ATCM_BASE_ADDR_SOC,
201 SBL_MCU3_CPU1_ATCM_BASE_ADDR_SOC
202 };
204 #if !defined(SOC_AM65XX)
205 static const uint32_t SblBtcmAddr[] =
206 {
207 SBL_MCU_BTCM_BASE,
208 SBL_MCU1_CPU1_BTCM_BASE_ADDR_SOC,
209 SBL_MCU2_CPU0_BTCM_BASE_ADDR_SOC,
210 SBL_MCU2_CPU1_BTCM_BASE_ADDR_SOC,
211 SBL_MCU3_CPU0_BTCM_BASE_ADDR_SOC,
212 SBL_MCU3_CPU1_BTCM_BASE_ADDR_SOC
213 };
214 #endif
215 /* ========================================================================== */
216 /* Internal Functions */
217 /* ========================================================================== */
219 static void SBL_RequestCore(cpu_core_id_t core_id)
220 {
221 #if !defined(SBL_SKIP_BRD_CFG_BOARD) && !defined(SBL_SKIP_SYSFW_INIT)
222 int32_t proc_id = sbl_slave_core_info[core_id].tisci_proc_id;
223 int32_t status = CSL_EFAIL;
225 #if defined(SOC_AM64X)
226 /* Do not touch the M4 if reset isolation is enabled */
227 uint32_t mmrMagicRegister;
228 mmrMagicRegister = (*((volatile uint32_t *)(CSL_CTRL_MMR0_CFG0_BASE+CSL_MAIN_CTRL_MMR_CFG0_RST_MAGIC_WORD)));
229 if (core_id == M4F_CPU0_ID && mmrMagicRegister != 0)
230 {
231 return;
232 }
233 #endif
235 if (proc_id != 0xBAD00000)
236 {
237 SBL_log(SBL_LOG_MAX, "Calling Sciclient_procBootRequestProcessor, ProcId 0x%x... \n", proc_id);
239 status = Sciclient_procBootRequestProcessor(proc_id, SCICLIENT_SERVICE_WAIT_FOREVER);
240 if (status != CSL_PASS)
241 {
242 SBL_log(SBL_LOG_ERR, "Sciclient_procBootRequestProcessor, ProcId 0x%x...FAILED \n", proc_id);
243 SblErrLoop(__FILE__, __LINE__);
244 }
245 }
246 #endif
248 return;
249 }
251 static void SBL_RequestAllCores(void)
252 {
253 #if !defined(SBL_SKIP_BRD_CFG_BOARD) && !defined(SBL_SKIP_SYSFW_INIT)
254 cpu_core_id_t core_id;
255 uint32_t num_cores = sizeof(sbl_slave_core_info)/ sizeof(sblSlaveCoreInfo_t);
257 SBL_ADD_PROFILE_POINT;
259 for (core_id = 0; core_id < num_cores; core_id++)
260 {
261 SBL_RequestCore(core_id);
262 }
264 SBL_ADD_PROFILE_POINT;
265 #endif
267 return;
268 }
270 static void SBL_ReleaseCore(cpu_core_id_t core_id)
271 {
272 #if !defined(SBL_SKIP_BRD_CFG_BOARD) && !defined(SBL_SKIP_SYSFW_INIT)
273 int32_t proc_id = sbl_slave_core_info[core_id].tisci_proc_id;
274 int32_t status = CSL_EFAIL;
276 #if defined(SOC_AM64X)
277 /* Do not touch the M4 if reset isolation is enabled */
278 uint32_t mmrMagicRegister;
279 mmrMagicRegister = (*((volatile uint32_t *)(CSL_CTRL_MMR0_CFG0_BASE+CSL_MAIN_CTRL_MMR_CFG0_RST_MAGIC_WORD)));
280 if (core_id == M4F_CPU0_ID && mmrMagicRegister != 0)
281 {
282 return;
283 }
284 #endif
286 if(proc_id != 0xBAD00000)
287 {
288 SBL_log(SBL_LOG_MAX, "Sciclient_procBootReleaseProcessor, ProcId 0x%x...\n", proc_id);
289 status = Sciclient_procBootReleaseProcessor(proc_id, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
291 if (status != CSL_PASS)
292 {
293 SBL_log(SBL_LOG_ERR, "Sciclient_procBootReleaseProcessor, ProcId 0x%x...FAILED \n", proc_id);
294 SblErrLoop(__FILE__, __LINE__);
295 }
296 }
297 #endif
299 return;
300 }
302 static void SBL_ReleaseAllCores(void)
303 {
304 #if !defined(SBL_SKIP_BRD_CFG_BOARD) && !defined(SBL_SKIP_SYSFW_INIT)
305 cpu_core_id_t core_id;
306 uint32_t num_cores = sizeof(sbl_slave_core_info)/sizeof(sblSlaveCoreInfo_t);
308 SBL_ADD_PROFILE_POINT;
310 for (core_id = 0; core_id < num_cores; core_id++)
311 {
312 SBL_ReleaseCore(core_id);
313 }
315 SBL_ADD_PROFILE_POINT;
316 #endif
318 return;
319 }
321 static void SBL_ConfigMcuLockStep(uint8_t enableLockStep, const sblSlaveCoreInfo_t *sblCoreInfoPtr)
322 {
323 int32_t status = CSL_EFAIL;
324 struct tisci_msg_proc_get_status_resp cpuStatus;
325 struct tisci_msg_proc_set_config_req proc_set_config_req;
327 SBL_ADD_PROFILE_POINT;
329 SBL_log(SBL_LOG_MAX, "Calling Sciclient_procBootGetProcessorState, ProcId 0x%x... \n", sblCoreInfoPtr->tisci_proc_id);
330 status = Sciclient_procBootGetProcessorState(sblCoreInfoPtr->tisci_proc_id, &cpuStatus, SCICLIENT_SERVICE_WAIT_FOREVER);
331 if (status != CSL_PASS)
332 {
333 SBL_log(SBL_LOG_ERR, "Sciclient_procBootGetProcessorState...FAILED \n");
334 SblErrLoop(__FILE__, __LINE__);
335 }
337 proc_set_config_req.processor_id = cpuStatus.processor_id;
338 proc_set_config_req.bootvector_lo = cpuStatus.bootvector_lo;
339 proc_set_config_req.bootvector_hi = cpuStatus.bootvector_hi;
340 proc_set_config_req.config_flags_1_set = 0;
341 proc_set_config_req.config_flags_1_clear = 0;
343 if (enableLockStep)
344 {
345 SBL_log(SBL_LOG_MAX, "Sciclient_procBootSetProcessorCfg, ProcId 0x%x, enabling Lockstep mode...\n", cpuStatus.processor_id);
346 proc_set_config_req.config_flags_1_set |= TISCI_MSG_VAL_PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
347 }
348 else
349 {
350 SBL_log(SBL_LOG_MAX, "Sciclient_procBootSetProcessorCfg, ProcId 0x%x, enabling split mode...\n", cpuStatus.processor_id);
351 proc_set_config_req.config_flags_1_clear |= TISCI_MSG_VAL_PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
352 }
354 SBL_ADD_PROFILE_POINT;
356 status = Sciclient_procBootSetProcessorCfg(&proc_set_config_req, SCICLIENT_SERVICE_WAIT_FOREVER);
357 if (status != CSL_PASS)
358 {
359 SBL_log(SBL_LOG_MAX, "Sciclient_procBootSetProcessorCfg lockstep...NOT DONE \n");
360 }
362 SBL_ADD_PROFILE_POINT;
364 return;
365 }
367 int32_t SBL_BootImage(sblEntryPoint_t *pEntry)
368 {
369 int32_t retval = 0;
370 cpu_core_id_t core_id;
372 SBL_ADD_PROFILE_POINT;
374 /* Initialize the entry point array to 0. */
375 for (core_id = MPU1_CPU0_ID; core_id < NUM_CORES; core_id ++)
376 pEntry->CpuEntryPoint[core_id] = SBL_INVALID_ENTRY_ADDR;
378 /* Request SYSW for control of all cores */
379 SBL_RequestAllCores();
381 SBL_ADD_PROFILE_POINT;
383 #if defined(BOOT_MMCSD)
384 /* MMCSD Boot Mode Image Copy function. */
385 if (SBL_MMCBootImage(pEntry) != E_PASS)
386 #elif defined(BOOT_OSPI)
387 if (SBL_OSPIBootImage(pEntry) != E_PASS)
388 #elif defined(BOOT_UART)
389 if (SBL_UARTBootImage(pEntry) != E_PASS)
390 #elif defined(BOOT_HYPERFLASH)
391 if (SBL_HYPERFLASHBootImage(pEntry) != E_PASS)
392 #endif
393 {
394 retval = E_FAIL;
395 }
397 SBL_ADD_PROFILE_POINT;
399 #if defined(SBL_ENABLE_HLOS_BOOT)
400 /* Ensure all the key MMCSD & Flash memory interfaces are handed off properly, for HLOS control */
401 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId: %d \n", TISCI_DEV_MMCSD0);
402 Sciclient_pmSetModuleState(TISCI_DEV_MMCSD0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
403 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId: %d \n", TISCI_DEV_MMCSD1);
404 Sciclient_pmSetModuleState(TISCI_DEV_MMCSD1, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
406 #if defined(SOC_J721E)
407 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId: %d \n", TISCI_DEV_MCU_FSS0_OSPI_0);
408 Sciclient_pmSetModuleState(TISCI_DEV_MCU_FSS0_OSPI_0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
409 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId: %d \n", TISCI_DEV_MCU_FSS0_OSPI_1);
410 Sciclient_pmSetModuleState(TISCI_DEV_MCU_FSS0_OSPI_1, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
411 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId: %d \n", TISCI_DEV_MCU_FSS0_HYPERBUS1P0_0);
412 Sciclient_pmSetModuleState(TISCI_DEV_MCU_FSS0_HYPERBUS1P0_0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
413 #endif
414 #endif
416 /* Release control of all cores */
417 SBL_ReleaseAllCores();
419 SBL_ADD_PROFILE_POINT;
421 return retval;
422 }
424 /**
425 * \brief SBL_SetupCoreMem function sets up the CPUs internal memory
426 *
427 * \param[in] core_id - CPU ID
428 * \param[in] pAppEntry - Core info struct
429 *
430 * \return none
431 */
432 void SBL_SetupCoreMem(uint32_t core_id)
433 {
434 int32_t status = CSL_EFAIL;
435 uint8_t runLockStep = 0;
436 uint8_t mcuModeConfigured = 0;
437 #if !defined(SOC_AM65XX)
438 struct tisci_msg_proc_get_status_resp cpuStatus;
439 struct tisci_msg_proc_set_config_req proc_set_config_req;
440 #endif
441 const sblSlaveCoreInfo_t *sblSlaveCoreInfoPtr;
443 SBL_ADD_PROFILE_POINT;
445 #if defined(SOC_AM64X)
446 /* Do not touch the M4 if reset isolation is enabled */
447 uint32_t mmrMagicRegister;
448 mmrMagicRegister = (*((volatile uint32_t *)(CSL_CTRL_MMR0_CFG0_BASE+CSL_MAIN_CTRL_MMR_CFG0_RST_MAGIC_WORD)));
449 if (core_id == M4F_CPU0_ID && mmrMagicRegister != 0)
450 {
451 return;
452 }
453 #endif
455 /* Remap virtual core-ids if needed */
456 switch (core_id)
457 {
458 case MCU1_SMP_ID:
459 runLockStep = 1;
460 core_id = MCU1_CPU0_ID;
461 break;
462 case MCU2_SMP_ID:
463 runLockStep = 1;
464 core_id = MCU2_CPU0_ID;
465 break;
466 case MCU3_SMP_ID:
467 runLockStep = 1;
468 core_id = MCU3_CPU0_ID;
469 break;
470 default:
471 break;
472 }
474 sblSlaveCoreInfoPtr = &(sbl_slave_core_info[core_id]);
476 if(runLockStep)
477 {
478 SBL_log(SBL_LOG_MAX, "Detected lockstep for core_id %d, proc_id 0x%x... \n", core_id, sblSlaveCoreInfoPtr->tisci_proc_id);
479 SBL_ConfigMcuLockStep(SBL_ENABLE_MCU_LOCKSTEP, sblSlaveCoreInfoPtr);
480 mcuModeConfigured = 1;
481 }
483 switch (core_id)
484 {
486 case DSP1_C66X_ID:
487 break;
488 case DSP2_C66X_ID:
489 break;
490 case DSP1_C7X_ID:
491 break;
492 case DSP2_C7X_ID:
493 break;
495 case MCU1_CPU1_ID:
496 case MCU2_CPU1_ID:
497 case MCU3_CPU1_ID:
498 SBL_log(SBL_LOG_MAX, "Switching core id %d, proc_id 0x%x to split mode... \n", core_id-1, sbl_slave_core_info[core_id-1].tisci_proc_id);
499 /* Image for second MCU core present, disable lock step for the cluster */
500 SBL_ConfigMcuLockStep(SBL_DISABLE_MCU_LOCKSTEP, &(sbl_slave_core_info[core_id-1]));
501 mcuModeConfigured = 1;
502 /* DOnt break, fall through for enabling TCMs */
503 case MCU1_CPU0_ID:
504 case MCU2_CPU0_ID:
505 case MCU3_CPU0_ID:
506 if (!mcuModeConfigured)
507 {
508 SBL_log(SBL_LOG_MAX, "Switching core id %d, proc_id 0x%x to split mode... \n", core_id, sbl_slave_core_info[core_id].tisci_proc_id);
509 /* Non-SMP image used, disable lock step for the cluster */
510 SBL_ConfigMcuLockStep(SBL_DISABLE_MCU_LOCKSTEP, &(sbl_slave_core_info[core_id]));
511 }
513 /* Ensure Power is OFF for each core before configuring TCMs */
514 /* SBL running on MCU0, don't fool around with its power */
515 if (core_id != MCU1_CPU0_ID)
516 {
517 if (runLockStep)
518 {
519 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_dev_id + 1);
520 Sciclient_pmSetModuleState(sblSlaveCoreInfoPtr->tisci_dev_id + 1, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
521 }
522 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_dev_id);
523 Sciclient_pmSetModuleState(sblSlaveCoreInfoPtr->tisci_dev_id, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
524 }
526 #if !defined(SOC_AM65XX)
527 /* Leave TCM defaults, for AM65xx. TCMs must be loaded by the app itself to avoid losing data during power cycle */
528 SBL_log(SBL_LOG_MAX, "Calling Sciclient_procBootGetProcessorState, ProcId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_proc_id);
529 status = Sciclient_procBootGetProcessorState(sblSlaveCoreInfoPtr->tisci_proc_id, &cpuStatus, SCICLIENT_SERVICE_WAIT_FOREVER);
530 if (status != CSL_PASS)
531 {
532 SBL_log(SBL_LOG_ERR, "Sciclient_procBootGetProcessorState...FAILED \n");
533 SblErrLoop(__FILE__, __LINE__);
534 }
536 proc_set_config_req.processor_id = cpuStatus.processor_id;
537 proc_set_config_req.bootvector_lo = cpuStatus.bootvector_lo;
538 proc_set_config_req.bootvector_hi = cpuStatus.bootvector_hi;
539 proc_set_config_req.config_flags_1_set = 0;
540 proc_set_config_req.config_flags_1_clear = 0;
541 proc_set_config_req.config_flags_1_set |= TISCI_MSG_VAL_PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
543 SBL_log(SBL_LOG_MAX, "Enabling MCU TCMs after reset for core %d\n", core_id);
544 proc_set_config_req.config_flags_1_set |= (TISCI_MSG_VAL_PROC_BOOT_CFG_FLAG_R5_BTCM_EN |
545 TISCI_MSG_VAL_PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE);
547 #if defined(SOC_J7200) || defined(SOC_AM64X)
548 /* Only need to set mem_init disable bit for MCU1_0 or MCU2_0 (for each cluster) */
549 if ((core_id == MCU1_CPU0_ID) || (core_id == MCU2_CPU0_ID))
550 {
551 SBL_log(SBL_LOG_MAX, "Disabling HW-based memory init of MCU TCMs for core %d\n", core_id);
552 proc_set_config_req.config_flags_1_set |= TISCI_MSG_VAL_PROC_BOOT_CFG_FLAG_R5_MEM_INIT_DIS;
553 }
554 #endif
556 SBL_log(SBL_LOG_MAX, "Sciclient_procBootSetProcessorCfg enabling TCMs...\n");
557 status = Sciclient_procBootSetProcessorCfg(&proc_set_config_req, SCICLIENT_SERVICE_WAIT_FOREVER);
558 if (status != CSL_PASS)
559 {
560 SBL_log(SBL_LOG_ERR, "Sciclient_procBootSetProcessorCfg...FAILED \n");
561 SblErrLoop(__FILE__, __LINE__);
562 }
564 /* For lockstep R5 pairs, this section will naturally only set HALT bit for MCU2_CPU0_ID or MCU3_CPU0_ID */
565 if (core_id != MCU1_CPU0_ID)
566 {
567 SBL_log(SBL_LOG_MAX, "Setting HALT for ProcId 0x%x...\n", sblSlaveCoreInfoPtr->tisci_proc_id);
568 status = Sciclient_procBootSetSequenceCtrl(sblSlaveCoreInfoPtr->tisci_proc_id, TISCI_MSG_VAL_PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
569 if (status != CSL_PASS)
570 {
571 SBL_log(SBL_LOG_ERR, "Sciclient_procBootSetSequenceCtrl...FAILED \n");
572 SblErrLoop(__FILE__, __LINE__);
573 }
574 }
576 /* SBL running on MCU0, don't fool around with its power & TCMs */
577 if (core_id != MCU1_CPU0_ID)
578 {
579 if (runLockStep)
580 {
581 /* If in lock-step mode, need to bring Core 1 out of reset, before Core 0, in order to init TCMs */
582 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState On, DevId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_dev_id + 1);
583 Sciclient_pmSetModuleState(sblSlaveCoreInfoPtr->tisci_dev_id + 1, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
584 }
585 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState On, DevId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_dev_id);
586 Sciclient_pmSetModuleState(sblSlaveCoreInfoPtr->tisci_dev_id, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
588 /* Initialize the TCMs - TCMs of MCU running SBL are already initialized by ROM & SBL */
589 #if defined(SOC_J7200)
590 /* J7200: ATCM in lock-step is the combined size of both the split-mode ATCMs */
591 if (runLockStep)
592 {
593 SBL_log(SBL_LOG_MAX, "Clearing core_id %d (lock-step) ATCM @ 0x%x\n", core_id, SblAtcmAddr[core_id - MCU1_CPU0_ID]);
594 memset(((void *)(SblAtcmAddr[core_id - MCU1_CPU0_ID])), 0xFF, 0x10000);
595 }
596 else
597 /* Clear the normal size of ATCM for non-lockstep cores */
598 #endif
599 {
600 SBL_log(SBL_LOG_MAX, "Clearing core_id %d ATCM @ 0x%x\n", core_id, SblAtcmAddr[core_id - MCU1_CPU0_ID]);
601 memset(((void *)(SblAtcmAddr[core_id - MCU1_CPU0_ID])), 0xFF, 0x8000);
602 }
604 #ifndef VLAB_SIM
605 #if defined(SOC_J7200)
606 /* J7200: BTCM in lock-step is the combined size of both the split-mode BTCMs */
607 if (runLockStep)
608 {
609 SBL_log(SBL_LOG_MAX, "Clearing core_id %d (lock-step) BTCM @ 0x%x\n", core_id, SblBtcmAddr[core_id - MCU1_CPU0_ID]);
610 memset(((void *)(SblBtcmAddr[core_id - MCU1_CPU0_ID])), 0xFF, 0x10000);
611 }
612 else
613 /* Clear the normal size of BTCM for non-lockstep cores */
614 #endif
615 {
616 SBL_log(SBL_LOG_MAX, "Clearing core_id %d BTCM @ 0x%x\n", core_id, SblBtcmAddr[core_id - MCU1_CPU0_ID]);
617 memset(((void *)(SblBtcmAddr[core_id - MCU1_CPU0_ID])), 0xFF, 0x8000);
618 }
619 #else
620 /* BTCM is not recognized in VLAB : ASTC TICKET # TBD */
621 SBL_log(SBL_LOG_MAX, "***Not Clearing*** BTCM @0x%x\n", SblBtcmAddr[core_id - MCU1_CPU0_ID]);
622 #endif
623 }
624 #endif /* #if !defined(SOC_AM65XX) */
625 break;
626 case MPU1_SMP_ID:
627 case MPU1_CPU0_ID:
628 case MPU1_CPU1_ID:
629 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState On, DevId 0x%x... \n", SBL_DEV_ID_MPU_CLUSTER0);
630 Sciclient_pmSetModuleState(SBL_DEV_ID_MPU_CLUSTER0, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
631 break;
632 case MPU2_SMP_ID:
633 case MPU2_CPU0_ID:
634 case MPU2_CPU1_ID:
635 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState On, DevId 0x%x... \n", SBL_DEV_ID_MPU_CLUSTER1);
636 Sciclient_pmSetModuleState(SBL_DEV_ID_MPU_CLUSTER1, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
637 break;
638 case M4F_CPU0_ID:
639 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_dev_id);
640 status = Sciclient_pmSetModuleState(sblSlaveCoreInfoPtr->tisci_dev_id, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
641 if (status != CSL_PASS)
642 {
643 SBL_log(SBL_LOG_ERR, "Sciclient_pmSetModuleState Off...FAILED \n");
644 SblErrLoop(__FILE__, __LINE__);
645 }
646 SBL_log(SBL_LOG_MAX, "Calling Sciclient_pmSetModuleRst, DevId 0x%x with RESET \n", sblSlaveCoreInfoPtr->tisci_dev_id);
647 status = Sciclient_pmSetModuleRst(sblSlaveCoreInfoPtr->tisci_dev_id, 1, SCICLIENT_SERVICE_WAIT_FOREVER);
648 if (status != CSL_PASS)
649 {
650 SBL_log(SBL_LOG_ERR, "Sciclient_pmSetModuleRst RESET ...FAILED \n");
651 SblErrLoop(__FILE__, __LINE__);
652 }
654 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState On, DevId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_dev_id);
655 status = Sciclient_pmSetModuleState(sblSlaveCoreInfoPtr->tisci_dev_id, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
656 if (status != CSL_PASS)
657 {
658 SBL_log(SBL_LOG_ERR, "Sciclient_pmSetModuleState...FAILED \n");
659 SblErrLoop(__FILE__, __LINE__);
660 }
661 break;
662 case MPU_SMP_ID:
663 /* Enable SMP on all MPU clusters. Enable SMP only if cluster is present */
664 if (SBL_DEV_ID_MPU_CLUSTER0 != 0xBAD00000)
665 {
666 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState On, DevId 0x%x... \n", SBL_DEV_ID_MPU_CLUSTER0);
667 Sciclient_pmSetModuleState(SBL_DEV_ID_MPU_CLUSTER0, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
668 }
669 if (SBL_DEV_ID_MPU_CLUSTER1 != 0xBAD00000)
670 {
671 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState On, DevId 0x%x... \n", SBL_DEV_ID_MPU_CLUSTER1);
672 Sciclient_pmSetModuleState(SBL_DEV_ID_MPU_CLUSTER1, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
673 }
674 break;
675 default:
676 /* No special memory setup needed */
677 break;
678 }
680 SBL_ADD_PROFILE_POINT;
682 return;
683 }
685 /**
686 * \brief SBL_SlaveCoreBoot function sets the entry point, sets up clocks
687 * and enable to core to start executing from entry point.
688 *
689 * \param core_id = Selects a core on the SOC, refer to cpu_core_id_t enum
690 * freqHz = Speed of core at boot up, 0 indicates use SBL default freqs.
691 * pAppEntry = SBL entry point struct
692 * requestCoresFlag = Specify whether cores should be requested/released
693 * from within SBL_SlaveCoreBoot. Accepts the values SBL_REQUEST_CORE
694 * and SBL_DONT_REQUEST_CORE.
695 *
696 **/
697 void SBL_SlaveCoreBoot(cpu_core_id_t core_id, uint32_t freqHz, sblEntryPoint_t *pAppEntry, uint32_t requestCoresFlag)
698 {
699 int32_t status = CSL_EFAIL;
700 struct tisci_msg_proc_set_config_req proc_set_config_req;
701 const sblSlaveCoreInfo_t *sblSlaveCoreInfoPtr = &(sbl_slave_core_info[core_id]);
703 SBL_ADD_PROFILE_POINT;
705 #if defined(SOC_AM64X)
706 /* Do not touch the M4 if reset isolation is enabled */
707 uint32_t mmrMagicRegister;
708 mmrMagicRegister = (*((volatile uint32_t *)(CSL_CTRL_MMR0_CFG0_BASE+CSL_MAIN_CTRL_MMR_CFG0_RST_MAGIC_WORD)));
709 if (core_id == M4F_CPU0_ID && mmrMagicRegister != 0)
710 {
711 return;
712 }
713 #endif
715 #if defined(SBL_SKIP_MCU_RESET) && (defined(SBL_SKIP_BRD_CFG_BOARD) || defined(SBL_SKIP_BRD_CFG_PM) || defined(SBL_SKIP_SYSFW_INIT))
716 /* Skip copy if R5 app entry point is already 0 */
717 #if !defined(SOC_AM65XX) /* Pre-loading ATCM is not permitted for AM65xx */
718 if ((core_id == MCU1_CPU0_ID) &&
719 (pAppEntry->CpuEntryPoint[core_id]) &&
720 (pAppEntry->CpuEntryPoint[core_id] < SBL_INVALID_ENTRY_ADDR))
721 {
722 SBL_log(SBL_LOG_MAX, "Copying first 128 bytes from app to MCU ATCM @ 0x%x for core %d\n", SblAtcmAddr[core_id - MCU1_CPU0_ID], core_id);
723 memcpy(((void *)(SblAtcmAddr[core_id - MCU1_CPU0_ID])), (void *)(pAppEntry->CpuEntryPoint[core_id]), 128);
724 return;
725 }
726 #endif
728 /* Finished processing images for all cores, start MCU_0 */
729 if ((core_id == MCU1_CPU1_ID) &&
730 (pAppEntry->CpuEntryPoint[core_id] >= SBL_INVALID_ENTRY_ADDR))
731 {
732 /* Display profile logs */
733 SBL_printProfileLog();
735 SBL_log(SBL_LOG_MAX, "Starting app, branching to 0x0 \n");
736 /* Branch to start of ATCM */
737 ((void(*)(void))0x0)();
738 }
739 #endif
741 /* Request core */
742 if (requestCoresFlag == SBL_REQUEST_CORE)
743 {
744 SBL_RequestCore(core_id);
745 }
747 /* Set entry point as boot vector */
748 proc_set_config_req.processor_id = sblSlaveCoreInfoPtr->tisci_proc_id;
749 proc_set_config_req.bootvector_lo = pAppEntry->CpuEntryPoint[core_id];
750 proc_set_config_req.bootvector_hi = 0x0;
751 proc_set_config_req.config_flags_1_set = 0;
752 proc_set_config_req.config_flags_1_clear = 0;
754 if (pAppEntry->CpuEntryPoint[core_id] < SBL_INVALID_ENTRY_ADDR) /* Set entry point only is valid */
755 {
756 SBL_log(SBL_LOG_MAX, "Sciclient_procBootSetProcessorCfg, ProcId 0x%x, EntryPoint 0x%x...\n", proc_set_config_req.processor_id, proc_set_config_req.bootvector_lo);
757 SBL_ADD_PROFILE_POINT;
758 status = Sciclient_procBootSetProcessorCfg(&proc_set_config_req, SCICLIENT_SERVICE_WAIT_FOREVER);
759 if (status != CSL_PASS)
760 {
761 SBL_log(SBL_LOG_ERR, "Sciclient_procBootSetProcessorCfg...FAILED \n");
762 SblErrLoop(__FILE__, __LINE__);
763 }
765 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleClkFreq, DevId 0x%x @ %dHz... \n", sblSlaveCoreInfoPtr->tisci_dev_id, sblSlaveCoreInfoPtr->slave_clk_freq_hz);
766 SBL_ADD_PROFILE_POINT;
767 Sciclient_pmSetModuleClkFreq(sblSlaveCoreInfoPtr->tisci_dev_id,
768 sblSlaveCoreInfoPtr->tisci_clk_id,
769 sblSlaveCoreInfoPtr->slave_clk_freq_hz,
770 TISCI_MSG_FLAG_AOP,
771 SCICLIENT_SERVICE_WAIT_FOREVER);
772 SBL_ADD_PROFILE_POINT;
773 }
774 else
775 {
776 SBL_log(SBL_LOG_MAX, "Skipping Sciclient_procBootSetProcessorCfg for ProcId 0x%x, EntryPoint 0x%x...\n", proc_set_config_req.processor_id, proc_set_config_req.bootvector_lo);
777 }
778 /* Power down and then power up each core*/
779 switch (core_id)
780 {
781 case MCU1_CPU1_ID:
782 /* Display profile logs */
783 SBL_printProfileLog();
785 #if !defined(SOC_AM65XX) /* Pre-loading ATCM is not permitted for AM65xx */
786 if (pAppEntry->CpuEntryPoint[core_id] < SBL_INVALID_ENTRY_ADDR)
787 {
788 /* Skip copy if R5 app entry point is already 0 */
789 if (pAppEntry->CpuEntryPoint[core_id])
790 {
791 SBL_log(SBL_LOG_MAX, "Copying first 128 bytes from app to MCU ATCM @ 0x%x for core %d\n", SblAtcmAddr[core_id - MCU1_CPU0_ID], core_id);
792 memcpy(((void *)(SblAtcmAddr[core_id - MCU1_CPU0_ID])), (void *)(pAppEntry->CpuEntryPoint[core_id]), 128);
793 }
794 }
795 #endif
797 #ifdef SBL_SKIP_MCU_RESET
798 if (pAppEntry->CpuEntryPoint[core_id] < SBL_INVALID_ENTRY_ADDR)
799 {
800 #if !defined(SOC_AM65XX)
801 SBL_log(SBL_LOG_MAX, "Un-HALT for ProcId 0x%x...\n", sblSlaveCoreInfoPtr->tisci_proc_id);
802 Sciclient_procBootSetSequenceCtrl(SBL_PROC_ID_MCU1_CPU1, 0, TISCI_MSG_VAL_PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
803 Sciclient_pmSetModuleState(SBL_DEV_ID_MCU1_CPU1, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
804 #endif
805 Sciclient_pmSetModuleState(SBL_DEV_ID_MCU1_CPU1, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
806 }
808 /* Release the CPU and branch to app */
809 if (requestCoresFlag == SBL_REQUEST_CORE)
810 {
811 SBL_ReleaseCore(core_id);
812 }
814 SBL_log(SBL_LOG_MAX, "Starting app, branching to 0x0 \n");
815 /* Branch to start of ATCM */
816 ((void(*)(void))0x0)();
817 #else
818 /* Request MCU1_0 */
819 if (requestCoresFlag == SBL_REQUEST_CORE)
820 {
821 SBL_RequestCore(core_id - 1);
822 }
824 /**
825 * Reset sequence for cluster running SBL
826 *
827 * The reset sequence for the cluster running SBL has to be done differently from
828 * that of other clusters. More detail is described in comments below, but a high-
829 * level overview of the reset sequence is as follows:
830 *
831 * 1. Processor Boot Wait (holds the queue)
832 * 2. MCU1_1 Enter Reset - (AM65x case: already powered OFF)
833 * 3. MCU1_0 Enter Reset - (AM65x case: Power OFF)
834 * 4. Un-halt MCU1_1
835 * 5. Release control of MCU1_0
836 * 6. Release control of MCU1_1
837 * 7. MCU1_0 Leave Reset - (AM65x case: Power ON)
838 * 8. MCU1_1 Leave Reset (if an application is requested to run there) - (AM65x case: Power ON)
839 */
841 /**
842 * Processor Boot Wait
843 *
844 * DMSC will block until a WFI is issued, thus allowing the following commands
845 * to be queued so this cluster may be reset by DMSC (queue length is defined in
846 * "drv/sciclient/soc/sysfw/include/<soc>/tisci_sec_proxy.h"). If these commands
847 * were to be issued and executed prior to WFI, the cluster would enter reset and
848 * SBL would quite sensibly not be able to tell DMSC to take itself out of reset.
849 */
850 SBL_log(SBL_LOG_MAX, "Sciclient_procBootWaitProcessorState, ProcId 0x%x... \n", SBL_PROC_ID_MCU1_CPU0);
851 status = Sciclient_procBootWaitProcessorState(SBL_PROC_ID_MCU1_CPU0, 1, 1, 0, 3, 0, 0, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
852 if (status != CSL_PASS)
853 {
854 SBL_log(SBL_LOG_ERR, "Sciclient_procBootWaitProcessorState...FAILED \n");
855 SblErrLoop(__FILE__, __LINE__);
856 }
858 /**
859 * Both cores enter reset
860 *
861 * It is necessary to reset MCU1_1 before MCU1_0, so as to maintain the specification that
862 * MCU1_1 may never ben in a higher functional state than MCU1_0.
863 */
864 #if !defined(SOC_AM65XX)
865 Sciclient_pmSetModuleRst_flags(SBL_DEV_ID_MCU1_CPU1, 1, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
866 Sciclient_pmSetModuleRst_flags(SBL_DEV_ID_MCU1_CPU0, 1, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
868 /**
869 * Un-halt MCU1_1 (MCU1_0 is not halted)
870 */
871 Sciclient_procBootSetSequenceCtrl(SBL_PROC_ID_MCU1_CPU1, 0, TISCI_MSG_VAL_PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
872 #else
873 /* AM65x case (can't use local reset flags): Power down core running SBL */
874 Sciclient_pmSetModuleState(SBL_DEV_ID_MCU1_CPU0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
875 #endif
876 /**
877 * Notify SYSFW that the SBL is relinquishing the MCU cluster running the SBL
878 */
879 if (requestCoresFlag == SBL_REQUEST_CORE)
880 {
881 Sciclient_procBootReleaseProcessor(SBL_PROC_ID_MCU1_CPU0, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
882 Sciclient_procBootReleaseProcessor(SBL_PROC_ID_MCU1_CPU1, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
883 }
885 /**
886 * MCU1_0 and (optionally) MCU1_1 leave reset
887 *
888 * Ensuring that MCU1_1 is never in a higher functional state than MCU1_0, both cores
889 * shall leave reset. Only take MCU1_1 out of reset if an application will be running
890 * on it.
891 */
892 #if !defined(SOC_AM65XX)
893 Sciclient_pmSetModuleRst_flags(SBL_DEV_ID_MCU1_CPU0, 0, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
894 if (pAppEntry->CpuEntryPoint[core_id] < SBL_INVALID_ENTRY_ADDR)
895 {
896 Sciclient_pmSetModuleRst_flags(SBL_DEV_ID_MCU1_CPU1, 0, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
897 }
898 #else
899 /* AM65x case (can't use local reset flags): Power ON CPU0 core, then power ON CPU1 core if necessary */
900 Sciclient_pmSetModuleState(SBL_DEV_ID_MCU1_CPU0, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
901 if (pAppEntry->CpuEntryPoint[core_id] < SBL_INVALID_ENTRY_ADDR)
902 {
903 Sciclient_pmSetModuleState(SBL_DEV_ID_MCU1_CPU1, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
904 }
905 #endif
907 /* Execute a WFI */
908 asm volatile (" wfi");
909 #endif
910 break;
912 case MCU1_CPU0_ID:
913 /* Skip copy if R5 app entry point is already 0 */
914 #if !defined(SOC_AM65XX) /* Pre-loading ATCM is not permitted for AM65xx */
915 if (pAppEntry->CpuEntryPoint[core_id])
916 {
917 SBL_log(SBL_LOG_MAX, "Copying first 128 bytes from app to MCU ATCM @ 0x%x for core %d\n", SblAtcmAddr[core_id - MCU1_CPU0_ID], core_id);
918 memcpy(((void *)(SblAtcmAddr[core_id - MCU1_CPU0_ID])), (void *)(proc_set_config_req.bootvector_lo), 128);
919 }
920 #endif
921 break;
922 case MCU2_CPU0_ID:
923 case MCU2_CPU1_ID:
924 case MCU3_CPU0_ID:
925 case MCU3_CPU1_ID:
926 if (pAppEntry->CpuEntryPoint[core_id] < SBL_INVALID_ENTRY_ADDR)
927 {
928 /* Skip copy if R5 app entry point is already 0 */
929 if (pAppEntry->CpuEntryPoint[core_id])
930 {
931 SBL_log(SBL_LOG_MAX, "Copying first 128 bytes from app to MCU ATCM @ 0x%x for core %d\n", SblAtcmAddr[core_id - MCU1_CPU0_ID], core_id);
932 memcpy(((void *)(SblAtcmAddr[core_id - MCU1_CPU0_ID])), (void *)(proc_set_config_req.bootvector_lo), 128);
933 }
934 SBL_log(SBL_LOG_MAX, "Clearing HALT for ProcId 0x%x...\n", sblSlaveCoreInfoPtr->tisci_proc_id);
935 status = Sciclient_procBootSetSequenceCtrl(sblSlaveCoreInfoPtr->tisci_proc_id, 0, TISCI_MSG_VAL_PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
936 if (status != CSL_PASS)
937 {
938 SBL_log(SBL_LOG_ERR, "Sciclient_procBootSetSequenceCtrl...FAILED \n");
939 SblErrLoop(__FILE__, __LINE__);
940 }
941 }
943 /* Release core */
944 if (requestCoresFlag == SBL_REQUEST_CORE)
945 {
946 SBL_ReleaseCore(core_id);
947 }
949 SBL_ADD_PROFILE_POINT;
950 break;
951 case M4F_CPU0_ID:
952 SBL_log(SBL_LOG_MAX, "Calling Sciclient_pmSetModuleRst, ProcId 0x%x with RELEASE \n", sblSlaveCoreInfoPtr->tisci_proc_id);
953 status = Sciclient_pmSetModuleRst(sblSlaveCoreInfoPtr->tisci_dev_id, 0, SCICLIENT_SERVICE_WAIT_FOREVER);
954 if (status != CSL_PASS)
955 {
956 SBL_log(SBL_LOG_ERR, "Sciclient_pmSetModuleRst RELEASE...FAILED \n");
957 SblErrLoop(__FILE__, __LINE__);
958 }
960 /* Release core */
961 if (requestCoresFlag == SBL_REQUEST_CORE)
962 {
963 SBL_ReleaseCore(core_id);
964 }
966 SBL_ADD_PROFILE_POINT;
967 break;
968 default:
969 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState Off, DevId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_dev_id);
970 Sciclient_pmSetModuleState(sblSlaveCoreInfoPtr->tisci_dev_id, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
971 SBL_log(SBL_LOG_MAX, "Sciclient_pmSetModuleState On, DevId 0x%x... \n", sblSlaveCoreInfoPtr->tisci_dev_id);
972 Sciclient_pmSetModuleState(sblSlaveCoreInfoPtr->tisci_dev_id, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
974 /* Release core */
975 if (requestCoresFlag == SBL_REQUEST_CORE)
976 {
977 SBL_ReleaseCore(core_id);
978 }
980 SBL_ADD_PROFILE_POINT;
981 break;
982 }
983 }