mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 07:31:15 +00:00
imx8ulp:ddr: saving the dram config timing data into sram
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@nxp.com> Signed-off-by: Jacky Bai <ping.bai@nxp.com> Signed-off-by: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
parent
6293b73d0f
commit
b80ec768a3
2 changed files with 52 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue