intel: Implement platform specific system reset 2
Add support for platform specific warm-reset through psci system reset 2.
- system_reset2 implementation that calls for l2 cache reset
- Check for magic number and request for warm reset in bl2
- Create a shared reset manager header file for Agilex and Stratix 10
- Clean up parameter info in plat_get_next_bl_params
Signed-off-by: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
Change-Id: I3fdd9a2711c80d9bd3dc05b81527781d840bd726
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 27b538a..5cb9b69 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -66,12 +66,34 @@
ret
endfunc plat_my_core_pos
+func warm_reset_req
+ str xzr, [x4]
+ bl plat_is_my_cpu_primary
+ cbz x0, cpu_in_wfi
+ mov_imm x1, PLAT_SEC_ENTRY
+ str xzr, [x1]
+ mrs x1, rmr_el3
+ orr x1, x1, #0x02
+ msr rmr_el3, x1
+ isb
+ dsb sy
+cpu_in_wfi:
+ wfi
+ b cpu_in_wfi
+endfunc warm_reset_req
+
func plat_get_my_entrypoint
+ ldr x4, =L2_RESET_DONE_REG
+ ldr x5, [x4]
+ ldr x1, =L2_RESET_DONE_STATUS
+ cmp x1, x5
+ b.eq warm_reset_req
mov_imm x1, PLAT_SEC_ENTRY
ldr x0, [x1]
ret
endfunc plat_get_my_entrypoint
+
/* ---------------------------------------------
* int plat_crash_console_init(void)
* Function to initialize the crash console
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index d6014d3..06f3a1b 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -19,6 +19,15 @@
/* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
#define PLAT_CPU_RELEASE_ADDR 0xffd12210
+/*
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ */
+#define L2_RESET_DONE_REG 0xFFD12218
+
+/* Magic word to indicate L2 reset is completed */
+#define L2_RESET_DONE_STATUS 0x1228E5E7
+
/* Define next boot image name and offset */
#define PLAT_NS_IMAGE_OFFSET 0x50000
#define PLAT_HANDOFF_OFFSET 0xFFE3F000
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
new file mode 100644
index 0000000..3fbf242
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_RESETMANAGER_H
+#define SOCFPGA_RESETMANAGER_H
+
+#define SOCFPGA_RSTMGR_STAT 0xffd11000
+#define SOCFPGA_RSTMGR_HDSKEN 0xffd11010
+#define SOCFPGA_RSTMGR_COLDMODRST 0xffd11034
+#define SOCFPGA_RSTMGR_HDSKTIMEOUT 0xffd11064
+
+#define SOCFPGA_RSTMGR_HDSKEN_SET 0x0000010D
+#define SOCFPGA_RSTMGR_SDMWARMRST 0x00000002
+
+#endif /* SOCFPGA_RESETMANAGER_H */
diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c
index 67c02bc..a5c3279 100644
--- a/plat/intel/soc/common/socfpga_image_load.c
+++ b/plat/intel/soc/common/socfpga_image_load.c
@@ -28,5 +28,31 @@
******************************************************************************/
bl_params_t *plat_get_next_bl_params(void)
{
+ unsigned int count;
+ unsigned int img_id = 0U;
+ unsigned int link_index = 0U;
+ bl_params_node_t *bl_exec_node = NULL;
+ bl_mem_params_node_t *desc_ptr;
+
+ /* If there is no image to start with, return NULL */
+ if (bl_mem_params_desc_num == 0U)
+ return NULL;
+
+ /* Clean next_params_info in BL image node */
+ for (count = 0U; count < bl_mem_params_desc_num; count++) {
+
+ desc_ptr = &bl_mem_params_desc_ptr[link_index];
+ bl_exec_node = &desc_ptr->params_node_mem;
+ bl_exec_node->next_params_info = NULL;
+
+ /* If no next hand-off image then break out */
+ img_id = desc_ptr->next_handoff_image_id;
+ if (img_id == INVALID_IMAGE_ID)
+ break;
+
+ /* Get the index for the next hand-off image */
+ link_index = get_bl_params_node_index(img_id);
+ }
+
return get_next_bl_params_from_mem_params_desc();
}
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index 65a4b09..1ba48ea 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -13,6 +13,7 @@
#include "socfpga_mailbox.h"
#include "socfpga_plat_def.h"
+#include "socfpga_reset_manager.h"
@@ -75,6 +76,7 @@
for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+
/* assert core reset */
mmio_setbits_32(SOCFPGA_RSTMGR_MPUMODRST_OFST, 1 << cpu_id);
@@ -136,6 +138,31 @@
wfi();
}
+static int socfpga_system_reset2(int is_vendor, int reset_type,
+ u_register_t cookie)
+{
+ /* disable cpuif */
+ gicv2_cpuif_disable();
+
+ /* Store magic number */
+ mmio_write_32(L2_RESET_DONE_REG, L2_RESET_DONE_STATUS);
+
+ /* Increase timeout */
+ mmio_write_32(SOCFPGA_RSTMGR_HDSKTIMEOUT, 0xffffff);
+
+ /* Enable handshakes */
+ mmio_setbits_32(SOCFPGA_RSTMGR_HDSKEN, SOCFPGA_RSTMGR_HDSKEN_SET);
+
+ /* Reset L2 module */
+ mmio_setbits_32(SOCFPGA_RSTMGR_COLDMODRST, 0x100);
+
+ while (1)
+ wfi();
+
+ /* Should not reach here */
+ return 0;
+}
+
int socfpga_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
@@ -169,6 +196,7 @@
.pwr_domain_suspend_finish = socfpga_pwr_domain_suspend_finish,
.system_off = socfpga_system_off,
.system_reset = socfpga_system_reset,
+ .system_reset2 = socfpga_system_reset2,
.validate_power_state = socfpga_validate_power_state,
.validate_ns_entrypoint = socfpga_validate_ns_entrypoint,
.get_sys_suspend_power_state = socfpga_get_sys_suspend_power_state