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