
Add is_ddr_init_skipped function to check if need to skip DDR initialization for N5X. This patch is preparation for N5X DDR driver support.
Signed-off-by: Siew Chin Lim elly.siew.chin.lim@intel.com Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com --- arch/arm/mach-socfpga/include/mach/misc.h | 4 ++ arch/arm/mach-socfpga/misc_soc64.c | 67 ++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h index 649d2f6ce2..c41b7c14cd 100644 --- a/arch/arm/mach-socfpga/include/mach/misc.h +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -44,6 +44,10 @@ void socfpga_sdram_remap_zero(void); int is_fpga_config_ready(void); #endif
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X) +bool is_ddr_init_skipped(void); +#endif + void do_bridge_reset(int enable, unsigned int mask); void socfpga_pl310_clear(void); void socfpga_get_managers_addr(void); diff --git a/arch/arm/mach-socfpga/misc_soc64.c b/arch/arm/mach-socfpga/misc_soc64.c index 7b973a79e8..d3945e55aa 100644 --- a/arch/arm/mach-socfpga/misc_soc64.c +++ b/arch/arm/mach-socfpga/misc_soc64.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2016-2018 Intel Corporation <www.intel.com> + * Copyright (C) 2016-2021 Intel Corporation <www.intel.com> * */
@@ -19,6 +19,13 @@
DECLARE_GLOBAL_DATA_PTR;
+/* Reset type */ +enum reset_type { + POR_RESET, + WARM_RESET, + COLD_RESET +}; + /* * FPGA programming support for SoC FPGA Stratix 10 */ @@ -88,3 +95,61 @@ void do_bridge_reset(int enable, unsigned int mask)
socfpga_bridges_reset(enable); } + +#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X) +static bool is_ddr_retention_enabled(u32 boot_scratch_cold0_reg) +{ + return boot_scratch_cold0_reg & + ALT_SYSMGR_SCRATCH_REG_0_DDR_RETENTION_MASK; +} + +static bool is_ddr_bitstream_sha_matching(u32 boot_scratch_cold0_reg) +{ + return boot_scratch_cold0_reg & ALT_SYSMGR_SCRATCH_REG_0_DDR_SHA_MASK; +} + +static enum reset_type get_reset_type(u32 boot_scratch_cold0_reg) +{ + return (boot_scratch_cold0_reg & + ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_MASK) >> + ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_SHIFT; +} + +bool is_ddr_init_skipped(void) +{ + u32 reg = readl(socfpga_get_sysmgr_addr() + + SYSMGR_SOC64_BOOT_SCRATCH_COLD0); + + if (get_reset_type(reg) == POR_RESET) { + debug("%s: POR reset is triggered\n", __func__); + debug("%s: DDR init is required\n", __func__); + return false; + } + + if (get_reset_type(reg) == WARM_RESET) { + debug("%s: Warm reset is triggered\n", __func__); + debug("%s: DDR init is skipped\n", __func__); + return true; + } + + if (get_reset_type(reg) == COLD_RESET) { + debug("%s: Cold reset is triggered\n", __func__); + + if (is_ddr_retention_enabled(reg)) { + debug("%s: DDR retention bit is set\n", __func__); + + if (is_ddr_bitstream_sha_matching(reg)) { + debug("%s: Matching in DDR bistream\n", + __func__); + debug("%s: DDR init is skipped\n", __func__); + return true; + } + + debug("%s: Mismatch in DDR bistream\n", __func__); + } + } + + debug("%s: DDR init is required\n", __func__); + return false; +} +#endif