diff options
author | Tom Rini <trini@konsulko.com> | 2022-02-07 12:13:53 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-02-07 12:13:53 -0500 |
commit | 8b139f4e1c08c4ffb1a8e739db128ed02cbc637f (patch) | |
tree | 0bff6bd0fadc7230538d712b1b1f112e424dbea0 /drivers/ddr/imx/imx8ulp/ddr_init.c | |
parent | b5c5b9a0bee56030f9f05ece52334b5207b72673 (diff) | |
parent | 530780a69cb5d32a7794dcc322afaa25cdbdab96 (diff) |
Merge tag 'u-boot-imx-20220207' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
u-boot-imx-20211022
-------------------
CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/10887
- imx8 : Toradex Verdin MX8M Plus
Kontron pitx-imx8m
- imx8ulp: several fixes and improvements
- imx6ull fixes
- switching to binman
Diffstat (limited to 'drivers/ddr/imx/imx8ulp/ddr_init.c')
-rw-r--r-- | drivers/ddr/imx/imx8ulp/ddr_init.c | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/drivers/ddr/imx/imx8ulp/ddr_init.c b/drivers/ddr/imx/imx8ulp/ddr_init.c index 16aaf56103..a5a9fd8d7c 100644 --- a/drivers/ddr/imx/imx8ulp/ddr_init.c +++ b/drivers/ddr/imx/imx8ulp/ddr_init.c @@ -129,8 +129,8 @@ int ddr_calibration(unsigned int fsp_table[3]) * Polling SIM LPDDR_CTRL2 Bit phy_freq_chg_req until be 1'b1 */ reg_val = readl(AVD_SIM_LPDDR_CTRL2); - phy_freq_req = (reg_val >> 7) & 0x1; - + /* DFS interrupt is set */ + phy_freq_req = ((reg_val >> 7) & 0x1) && ((reg_val >> 15) & 0x1); if (phy_freq_req) { phy_freq_type = reg_val & 0x1F; if (phy_freq_type == 0x00) { @@ -159,7 +159,11 @@ int ddr_calibration(unsigned int fsp_table[3]) if (freq_chg_pt == 2) freq_chg_cnt--; } - reg_val = readl(AVD_SIM_LPDDR_CTRL2); + + /* Hardware clear the ack on falling edge of LPDDR_CTRL2:phy_freq_chg_reg */ + /* Ensure the ack is clear before starting to poll request again */ + while ((readl(AVD_SIM_LPDDR_CTRL2) & BIT(6))) + ; } } while (1); @@ -178,6 +182,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 +238,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); |