[PATCH] ddr: altera: n5x: Checking DDR init hang before reset due to watchdog

Jit Loon Lim jit.loon.lim at intel.com
Wed Nov 23 15:27:04 CET 2022


From: Tien Fong Chee <tien.fong.chee at intel.com>

DDR need to be initialized and running calibration if DDR init hang
before reset due to watchdog.

Signed-off-by: Tien Fong Chee <tien.fong.chee at intel.com>
Signed-off-by: Jit Loon Lim <jit.loon.lim at intel.com>
---
 drivers/ddr/altera/sdram_n5x.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
index 7d4225e471..5117a5c4cf 100644
--- a/drivers/ddr/altera/sdram_n5x.c
+++ b/drivers/ddr/altera/sdram_n5x.c
@@ -428,6 +428,17 @@ enum data_process {
 	LOADING
 };
 
+bool is_ddr_init_hang(void)
+{
+	u32 reg = readl(socfpga_get_sysmgr_addr() +
+			SYSMGR_SOC64_BOOT_SCRATCH_COLD8);
+
+	if (reg & ALT_SYSMGR_SCRATCH_REG_8_DDR_PROGRESS_MASK)
+		return true;
+
+	return false;
+}
+
 bool is_ddr_dbe_triggered(void)
 {
 	u32 reg = readl(socfpga_get_sysmgr_addr() +
@@ -491,13 +502,13 @@ void reset_type_print(enum reset_type reset_t)
 	}
 }
 
-bool is_ddr_init_skipped(u32 reg)
+bool is_ddr_init_skipped(u32 reg, bool is_ddr_hang_be4_rst)
 {
 	enum reset_type reset_t = get_reset_type(reg);
 
 	reset_type_print(reset_t);
 
-	if (!is_ddr_dbe_triggered()) {
+	if (!is_ddr_dbe_triggered() && !is_ddr_hang_be4_rst) {
 		if (reset_t == WARM_RESET) {
 			debug("%s: DDR init is skipped\n", __func__);
 			return true;
@@ -517,13 +528,13 @@ bool is_ddr_init_skipped(u32 reg)
 	return false;
 }
 
-bool is_ddr_calibration_skipped(u32 reg)
+bool is_ddr_calibration_skipped(u32 reg, bool is_ddr_hang_be4_rst)
 {
 	enum reset_type reset_t = get_reset_type(reg);
 
 	if ((reset_t == NCONFIG || reset_t == JTAG_CONFIG ||
 	    reset_t == RSU_RECONFIG) && is_ddr_retention_enabled(reg) &&
-	    !is_ddr_dbe_triggered()) {
+	    !is_ddr_dbe_triggered() && !is_ddr_hang_be4_rst) {
 		debug("%s: DDR retention bit is set\n", __func__);
 		return true;
 	}
@@ -1579,7 +1590,8 @@ static bool is_cal_bak_data_valid(void)
 	return true;
 }
 
-static int init_phy(struct ddr_handoff *ddr_handoff_info)
+static int init_phy(struct ddr_handoff *ddr_handoff_info,
+		    bool *need_calibrate, bool is_ddr_hang_be4_rst)
 {
 	u32 handoff_table[ddr_handoff_info->phy_handoff_length];
 	u32 i, value;
@@ -1609,7 +1621,7 @@ static int init_phy(struct ddr_handoff *ddr_handoff_info)
 	handoff_process(ddr_handoff_info, ddr_handoff_info->phy_handoff_base,
 			ddr_handoff_info->phy_handoff_length,
 			ddr_handoff_info->phy_base);
-	if (is_ddr_calibration_skipped(reg)) {
+	if (is_ddr_calibration_skipped(reg, is_ddr_hang_be4_rst)) {
 		if (is_cal_bak_data_valid())
 			*need_calibrate = false;
 		else
@@ -2848,6 +2860,7 @@ int sdram_mmr_init_full(struct udevice *dev)
 	u32 reg = readl(socfpga_get_sysmgr_addr() +
 			SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
 	int ret;
+	bool is_ddr_hang_be4_rst = is_ddr_init_hang();
 	bool need_calibrate = true;
 	ulong ddr_offset;
 	char *endptr;
@@ -2873,7 +2886,7 @@ int sdram_mmr_init_full(struct udevice *dev)
 	 */
 	writel(SOC64_CRAM_PHY_BACKUP_SKIP_MAGIC, SOC64_OCRAM_PHY_BACKUP_BASE);
 
-	if (!is_ddr_init_skipped(reg)) {
+	if (!is_ddr_init_skipped(reg, is_ddr_hang_be4_rst)) {
 		printf("SDRAM init in progress ...\n");
 		ddr_init_inprogress(true);
 
@@ -2915,7 +2928,8 @@ int sdram_mmr_init_full(struct udevice *dev)
 		printf("DDR controller configuration is completed\n");
 
 		/* Initialize DDR PHY */
-		ret = init_phy(&ddr_handoff_info, &need_calibrate);
+		ret = init_phy(&ddr_handoff_info, &need_calibrate,
+			       is_ddr_hang_be4_rst);
 		if (ret) {
 			debug("%s: Failed to inilialize DDR PHY\n", __func__);
 			return ret;
-- 
2.26.2



More information about the U-Boot mailing list