1436223deSYatharth Kochar /*
2*fdcd5413STamas Ban * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
3436223deSYatharth Kochar *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5436223deSYatharth Kochar */
6436223deSYatharth Kochar
7436223deSYatharth Kochar #include <errno.h>
809d40e0eSAntonio Nino Diaz
909d40e0eSAntonio Nino Diaz #include <common/bl_common.h>
1009d40e0eSAntonio Nino Diaz #include <common/debug.h>
1109d40e0eSAntonio Nino Diaz #include <common/tbbr/tbbr_img_def.h>
125932d194SAntonio Nino Diaz #include <drivers/arm/css/sds.h>
1309d40e0eSAntonio Nino Diaz #include <drivers/arm/sp805.h>
14bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h>
15b0c97dafSAditya Angadi #include <plat/arm/common/arm_def.h>
1609d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
17234bc7f8SAntonio Nino Diaz #include <platform_def.h>
1809d40e0eSAntonio Nino Diaz
1907570d59SYatharth Kochar void juno_reset_to_aarch32_state(void);
2007570d59SYatharth Kochar
is_watchdog_reset(void)214da6f6cdSSathees Balya static int is_watchdog_reset(void)
224da6f6cdSSathees Balya {
234da6f6cdSSathees Balya #if !CSS_USE_SCMI_SDS_DRIVER
244da6f6cdSSathees Balya #define RESET_REASON_WDOG_RESET (0x2)
254da6f6cdSSathees Balya const uint32_t *reset_flags_ptr = (const uint32_t *)SSC_GPRETN;
264da6f6cdSSathees Balya
274da6f6cdSSathees Balya if ((*reset_flags_ptr & RESET_REASON_WDOG_RESET) != 0)
284da6f6cdSSathees Balya return 1;
294da6f6cdSSathees Balya
304da6f6cdSSathees Balya return 0;
314da6f6cdSSathees Balya #else
324da6f6cdSSathees Balya int ret;
334da6f6cdSSathees Balya uint32_t scp_reset_synd_flags;
344da6f6cdSSathees Balya
35*fdcd5413STamas Ban ret = sds_init(SDS_SCP_AP_REGION_ID);
364da6f6cdSSathees Balya if (ret != SDS_OK) {
374da6f6cdSSathees Balya ERROR("SCP SDS initialization failed\n");
384da6f6cdSSathees Balya panic();
394da6f6cdSSathees Balya }
404da6f6cdSSathees Balya
41*fdcd5413STamas Ban ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
42*fdcd5413STamas Ban SDS_RESET_SYNDROME_STRUCT_ID,
434da6f6cdSSathees Balya SDS_RESET_SYNDROME_OFFSET,
444da6f6cdSSathees Balya &scp_reset_synd_flags,
454da6f6cdSSathees Balya SDS_RESET_SYNDROME_SIZE,
464da6f6cdSSathees Balya SDS_ACCESS_MODE_NON_CACHED);
474da6f6cdSSathees Balya if (ret != SDS_OK) {
484da6f6cdSSathees Balya ERROR("Getting reset reason from SDS failed\n");
494da6f6cdSSathees Balya panic();
504da6f6cdSSathees Balya }
514da6f6cdSSathees Balya
524da6f6cdSSathees Balya /* Check if the WATCHDOG_RESET_BIT is set in the reset syndrome */
534da6f6cdSSathees Balya if (scp_reset_synd_flags & SDS_RESET_SYNDROME_AP_WD_RESET_BIT)
544da6f6cdSSathees Balya return 1;
554da6f6cdSSathees Balya
564da6f6cdSSathees Balya return 0;
574da6f6cdSSathees Balya #endif
584da6f6cdSSathees Balya }
594da6f6cdSSathees Balya
604da6f6cdSSathees Balya /*******************************************************************************
614da6f6cdSSathees Balya * The following function checks if Firmware update is needed,
624da6f6cdSSathees Balya * by checking if TOC in FIP image is valid or watchdog reset happened.
634da6f6cdSSathees Balya ******************************************************************************/
plat_arm_bl1_fwu_needed(void)64d6dcbcadSLouis Mayencourt bool plat_arm_bl1_fwu_needed(void)
654da6f6cdSSathees Balya {
66aa79421cSManish V Badarkhe int32_t nv_flags = (int32_t)mmio_read_32(V2M_SYS_NVFLAGS_ADDR);
674da6f6cdSSathees Balya
684da6f6cdSSathees Balya /* Check if TOC is invalid or watchdog reset happened. */
69aa79421cSManish V Badarkhe return (!arm_io_is_toc_valid() || (((nv_flags == -EAUTH) ||
70aa79421cSManish V Badarkhe (nv_flags == -ENOENT)) && is_watchdog_reset()));
714da6f6cdSSathees Balya }
724da6f6cdSSathees Balya
73436223deSYatharth Kochar /*******************************************************************************
74436223deSYatharth Kochar * On JUNO update the arg2 with address of SCP_BL2U image info.
75436223deSYatharth Kochar ******************************************************************************/
bl1_plat_set_ep_info(unsigned int image_id,entry_point_info_t * ep_info)76436223deSYatharth Kochar void bl1_plat_set_ep_info(unsigned int image_id,
77436223deSYatharth Kochar entry_point_info_t *ep_info)
78436223deSYatharth Kochar {
79436223deSYatharth Kochar if (image_id == BL2U_IMAGE_ID) {
80436223deSYatharth Kochar image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID);
81436223deSYatharth Kochar ep_info->args.arg2 = (unsigned long)&image_desc->image_info;
82436223deSYatharth Kochar }
83436223deSYatharth Kochar }
84436223deSYatharth Kochar
85436223deSYatharth Kochar /*******************************************************************************
86436223deSYatharth Kochar * On Juno clear SYS_NVFLAGS and wait for watchdog reset.
87436223deSYatharth Kochar ******************************************************************************/
bl1_plat_fwu_done(void * client_cookie,void * reserved)881f37b944SDan Handley __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
89436223deSYatharth Kochar {
90aa79421cSManish V Badarkhe uint32_t nv_flags = mmio_read_32(V2M_SYS_NVFLAGS_ADDR);
91436223deSYatharth Kochar
92436223deSYatharth Kochar /* Clear the NV flags register. */
93aa79421cSManish V Badarkhe mmio_write_32((V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR),
94aa79421cSManish V Badarkhe nv_flags);
95436223deSYatharth Kochar
9637b70031SAmbroise Vincent /* Setup the watchdog to reset the system as soon as possible */
9737b70031SAmbroise Vincent sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
9837b70031SAmbroise Vincent
9992069086SJimmy Brisson while (true)
100436223deSYatharth Kochar wfi();
101436223deSYatharth Kochar }
10207570d59SYatharth Kochar
10307570d59SYatharth Kochar #if JUNO_AARCH32_EL3_RUNTIME
bl1_plat_prepare_exit(entry_point_info_t * ep_info)10407570d59SYatharth Kochar void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
10507570d59SYatharth Kochar {
10607570d59SYatharth Kochar #if !ARM_DISABLE_TRUSTED_WDOG
10707570d59SYatharth Kochar /* Disable watchdog before leaving BL1 */
10807570d59SYatharth Kochar sp805_stop(ARM_SP805_TWDG_BASE);
10907570d59SYatharth Kochar #endif
11007570d59SYatharth Kochar
11107570d59SYatharth Kochar juno_reset_to_aarch32_state();
11207570d59SYatharth Kochar }
11307570d59SYatharth Kochar #endif /* JUNO_AARCH32_EL3_RUNTIME */
114b0c97dafSAditya Angadi
plat_arm_secure_wdt_start(void)115b0c97dafSAditya Angadi void plat_arm_secure_wdt_start(void)
116b0c97dafSAditya Angadi {
117b0c97dafSAditya Angadi sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
118b0c97dafSAditya Angadi }
119b0c97dafSAditya Angadi
plat_arm_secure_wdt_stop(void)120b0c97dafSAditya Angadi void plat_arm_secure_wdt_stop(void)
121b0c97dafSAditya Angadi {
122b0c97dafSAditya Angadi sp805_stop(ARM_SP805_TWDG_BASE);
123b0c97dafSAditya Angadi }
124