[PATCH 19/20] imx8ulp:ddr: saving the dram config timing data into sram

Peng Fan (OSS) peng.fan at oss.nxp.com
Fri Oct 29 03:46:33 CEST 2021


From: Jacky Bai <ping.bai at nxp.com>

On i.MX8ULP, The dram config timing need to be saved into sram for
ddr retention when APD enter PD mode, so add this support on i.MX8ULP.

Reviewed-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Jacky Bai <ping.bai at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/ddr/imx/imx8ulp/Kconfig    |  7 +++++
 drivers/ddr/imx/imx8ulp/ddr_init.c | 45 ++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/ddr/imx/imx8ulp/Kconfig b/drivers/ddr/imx/imx8ulp/Kconfig
index e56062a1d0..42848863aa 100644
--- a/drivers/ddr/imx/imx8ulp/Kconfig
+++ b/drivers/ddr/imx/imx8ulp/Kconfig
@@ -8,4 +8,11 @@ config IMX8ULP_DRAM_PHY_PLL_BYPASS
 	bool "Enable the DDR PHY PLL bypass mode, so PHY clock is from DDR_CLK "
 	depends on IMX8ULP_DRAM
 
+config SAVED_DRAM_TIMING_BASE
+	hex "Define the base address for saved dram timing"
+	help
+	  The DRAM config timing data need to be saved into sram
+	  for low power use.
+	default 0x2006c000
+
 endmenu
diff --git a/drivers/ddr/imx/imx8ulp/ddr_init.c b/drivers/ddr/imx/imx8ulp/ddr_init.c
index 16aaf56103..9730dd6450 100644
--- a/drivers/ddr/imx/imx8ulp/ddr_init.c
+++ b/drivers/ddr/imx/imx8ulp/ddr_init.c
@@ -178,6 +178,48 @@ int ddr_calibration(unsigned int fsp_table[3])
 	return 0;
 }
 
+static void save_dram_config(struct dram_timing_info2 *timing_info, unsigned long saved_timing_base)
+{
+	int i = 0;
+	struct dram_timing_info2 *saved_timing = (struct dram_timing_info2 *)saved_timing_base;
+	struct dram_cfg_param *cfg;
+
+	saved_timing->ctl_cfg_num = timing_info->ctl_cfg_num;
+	saved_timing->phy_f1_cfg_num = timing_info->phy_f1_cfg_num;
+	saved_timing->phy_f2_cfg_num = timing_info->phy_f2_cfg_num;
+
+	/* save the fsp table */
+	for (i = 0; i < 3; i++)
+		saved_timing->fsp_table[i] = timing_info->fsp_table[i];
+
+	cfg = (struct dram_cfg_param *)(saved_timing_base +
+					sizeof(*timing_info));
+
+	/* save ctl config */
+	saved_timing->ctl_cfg = cfg;
+	for (i = 0; i < timing_info->ctl_cfg_num; i++) {
+		cfg->reg = timing_info->ctl_cfg[i].reg;
+		cfg->val = timing_info->ctl_cfg[i].val;
+		cfg++;
+	}
+
+	/* save phy f1 config */
+	saved_timing->phy_f1_cfg = cfg;
+	for (i = 0; i < timing_info->phy_f1_cfg_num; i++) {
+		cfg->reg = timing_info->phy_f1_cfg[i].reg;
+		cfg->val = timing_info->phy_f1_cfg[i].val;
+		cfg++;
+	}
+
+	/* save phy f2 config */
+	saved_timing->phy_f2_cfg = cfg;
+	for (i = 0; i < timing_info->phy_f2_cfg_num; i++) {
+		cfg->reg = timing_info->phy_f2_cfg[i].reg;
+		cfg->val = timing_info->phy_f2_cfg[i].val;
+		cfg++;
+	}
+}
+
 int ddr_init(struct dram_timing_info2 *dram_timing)
 {
 	int i;
@@ -192,6 +234,9 @@ int ddr_init(struct dram_timing_info2 *dram_timing)
 		clrbits_le32(AVD_SIM_BASE_ADDR, 0x1); /* SIM_DDR_CTRL_DIV2_EN */
 	}
 
+	/* save the dram config into sram for low power mode */
+	save_dram_config(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE);
+
 	/* Initialize CTL registers */
 	for (i = 0; i < dram_timing->ctl_cfg_num; i++)
 		writel(dram_timing->ctl_cfg[i].val, (ulong)dram_timing->ctl_cfg[i].reg);
-- 
2.30.0



More information about the U-Boot mailing list