From 0f33f50e21de2285727bfb6a3adf0eff762ea330 Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Wed, 9 Dec 2020 14:02:40 +0530 Subject: [PATCH] nxp: warm reset support to retain ddr content NXP: Added warm reset handler to handle SMC PSCI_SYSTEM_RESET2 raised from kernel (> 5.4). As part of first cold boot, DDR training data is stored in NV storage. As part of this SMC handling, following things are done: - DDR is put in self-refresh mode to retain the content of DDR. - Reset cause is saved. - Reset is triggered. On next boot to last warm-reset, DDR training is restored from the NV storage. Signed-off-by: Ashish Kumar Signed-off-by: Kuldeep Singh Signed-off-by: Udit Agarwal Signed-off-by: Priyanka Singh Signed-off-by: Pankaj Gupta Change-Id: I8e4fb0824887af49e959c93825e2ab0ba887fc9d --- plat/nxp/common/warm_reset/plat_warm_reset.c | 121 +++++++++++++++++++ plat/nxp/common/warm_reset/plat_warm_rst.h | 28 +++++ plat/nxp/common/warm_reset/warm_reset.mk | 20 +++ 3 files changed, 169 insertions(+) create mode 100644 plat/nxp/common/warm_reset/plat_warm_reset.c create mode 100644 plat/nxp/common/warm_reset/plat_warm_rst.h create mode 100644 plat/nxp/common/warm_reset/warm_reset.mk diff --git a/plat/nxp/common/warm_reset/plat_warm_reset.c b/plat/nxp/common/warm_reset/plat_warm_reset.c new file mode 100644 index 000000000..966a73c79 --- /dev/null +++ b/plat/nxp/common/warm_reset/plat_warm_reset.c @@ -0,0 +1,121 @@ +/* + * Copyright 2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include + +#include +#include +#ifndef NXP_COINED_BB +#include +#include +#include +#endif +#include +#include +#ifdef NXP_COINED_BB +#include +#endif + +#include +#include "plat_warm_rst.h" +#include "platform_def.h" + +#if defined(IMAGE_BL2) + +uint32_t is_warm_boot(void) +{ + uint32_t ret = mmio_read_32(NXP_RESET_ADDR + RST_RSTRQSR1_OFFSET) + & ~(RSTRQSR1_SWRR); + + const nv_app_data_t *nv_app_data = get_nv_data(); + + if (ret == 0U) { + INFO("Not a SW(Warm) triggered reset.\n"); + return 0U; + } + + ret = (nv_app_data->warm_rst_flag == WARM_BOOT_SUCCESS) ? 1 : 0; + + if (ret != 0U) { + INFO("Warm Reset was triggered..\n"); + } else { + INFO("Warm Reset was not triggered..\n"); + } + + return ret; +} + +#endif + +#if defined(IMAGE_BL31) +int prep_n_execute_warm_reset(void) +{ +#ifdef NXP_COINED_BB +#if !TRUSTED_BOARD_BOOT + snvs_disable_zeroize_lp_gpr(); +#endif +#else + int ret; + uint8_t warm_reset = WARM_BOOT_SUCCESS; + + ret = fspi_init(NXP_FLEXSPI_ADDR, NXP_FLEXSPI_FLASH_ADDR); + + if (ret != 0) { + ERROR("Failed to initialized driver flexspi-nor.\n"); + ERROR("exiting warm-reset request.\n"); + return PSCI_E_INTERN_FAIL; + } + + /* Sector starting from NV_STORAGE_BASE_ADDR is already + * erased for writing. + */ + +#if (ERLY_WRM_RST_FLG_FLSH_UPDT) + ret = xspi_write((uint32_t)NV_STORAGE_BASE_ADDR, + &warm_reset, + sizeof(warm_reset)); +#else + /* Preparation for writing the Warm reset flag. */ + ret = xspi_wren((uint32_t)NV_STORAGE_BASE_ADDR); + + /* IP Control Register0 - SF Address to be read */ + fspi_out32((NXP_FLEXSPI_ADDR + FSPI_IPCR0), + (uint32_t) NV_STORAGE_BASE_ADDR); + + while ((fspi_in32(NXP_FLEXSPI_ADDR + FSPI_INTR) & + FSPI_INTR_IPTXWE_MASK) == 0) { + ; + } + /* Write TX FIFO Data Register */ + fspi_out32(NXP_FLEXSPI_ADDR + FSPI_TFDR, (uint32_t) warm_reset); + + fspi_out32(NXP_FLEXSPI_ADDR + FSPI_INTR, FSPI_INTR_IPTXWE); + + /* IP Control Register1 - SEQID_WRITE operation, Size = 1 Byte */ + fspi_out32(NXP_FLEXSPI_ADDR + FSPI_IPCR1, + (uint32_t)(FSPI_WRITE_SEQ_ID << FSPI_IPCR1_ISEQID_SHIFT) | + (uint16_t) sizeof(warm_reset)); + + /* Trigger XSPI-IP-Write cmd only if: + * - Putting DDR in-self refresh mode is successfully. + * to complete the writing of the warm-reset flag + * to flash. + * + * This code is as part of assembly. + */ +#endif +#endif + INFO("Doing DDR Self refresh.\n"); + _soc_sys_warm_reset(); + + /* Expected behaviour is to do the power cycle */ + while (1 != 0) + ; + + return -1; +} +#endif diff --git a/plat/nxp/common/warm_reset/plat_warm_rst.h b/plat/nxp/common/warm_reset/plat_warm_rst.h new file mode 100644 index 000000000..e0c39c50f --- /dev/null +++ b/plat/nxp/common/warm_reset/plat_warm_rst.h @@ -0,0 +1,28 @@ +/* + * Copyright 2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef PLAT_WARM_RST_H +#define PLAT_WARM_RST_H + +#ifndef NXP_COINED_BB +#define ERLY_WRM_RST_FLG_FLSH_UPDT 0 +#endif + +#ifndef __ASSEMBLER__ + +#if defined(IMAGE_BL2) +uint32_t is_warm_boot(void); +#endif + +#if defined(IMAGE_BL31) +int prep_n_execute_warm_reset(void); +int _soc_sys_warm_reset(void); +#endif + +#endif /* __ASSEMBLER__ */ + +#endif /* PLAT_WARM_RST_H */ diff --git a/plat/nxp/common/warm_reset/warm_reset.mk b/plat/nxp/common/warm_reset/warm_reset.mk new file mode 100644 index 000000000..236004f4e --- /dev/null +++ b/plat/nxp/common/warm_reset/warm_reset.mk @@ -0,0 +1,20 @@ +# +# Copyright 2020 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# +#----------------------------------------------------------------------------- +ifeq (${WARM_RST_ADDED},) + +WARM_RST_ADDED := 1 +NXP_NV_SW_MAINT_LAST_EXEC_DATA := yes + +$(eval $(call add_define,NXP_WARM_BOOT)) + + +WARM_RST_INCLUDES += -I${PLAT_COMMON_PATH}/warm_reset +WARM_RST_BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}_warm_rst.S + +WARM_RST_BL_COMM_SOURCES += ${PLAT_COMMON_PATH}/warm_reset/plat_warm_reset.c + +endif