Skip to content

Commit

Permalink
LF-13051 fix(imx8ulp): Update auto LP disable and enable operation.
Browse files Browse the repository at this point in the history
1. Do one read and one write operation to make sure DRAM is
   out of Self-Refresh
2. Save CTL 144 but need keep LPI_WAKEUP_EN as 0.
3. Add auto LP disable and enable in DFS opeartion.
4. Use SRPD short with MEM clock gating in DFS.

Signed-off-by: Hongting Ting <[email protected]>
Reviewed-by: Jacky Bai <[email protected]>
  • Loading branch information
donghongting authored and Ye Li committed Jul 31, 2024
1 parent 840993b commit c45c023
Showing 1 changed file with 28 additions and 21 deletions.
49 changes: 28 additions & 21 deletions plat/imx/imx8ulp/dram.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@

#define IMX_DDRC_BASE U(0x2E060000)
#define SAVED_DRAM_DATA_BASE U(0x20055000)
#define DENALI_CTL_137 U(0x224)
#define DENALI_CTL_143 U(0x23C)
#define DENALI_CTL_144 U(0x240)
#define DENALI_CTL_146 U(0x248)
#define DENALI_CTL_148 U(0x250)
#define LPI_WAKEUP_EN_SHIFT U(8)
#define IMX_LPAV_SIM_BASE 0x2DA50000
#define LPDDR_CTRL 0x14
Expand Down Expand Up @@ -121,7 +123,7 @@ struct dram_timing_info {
#define PI_NUM U(298)
#define PHY_NUM U(1654)
#define PHY_DIFF_NUM U(49)
#define AUTO_LP_NUM U(3)
#define AUTO_LP_NUM U(4)
struct dram_cfg {
uint32_t ctl_cfg[CTL_NUM];
uint32_t pi_cfg[PI_NUM];
Expand All @@ -137,7 +139,7 @@ struct dram_cfg *dram_timing_cfg;
/* mark if dram cfg is already saved */
static bool dram_cfg_saved = false;
static bool dram_auto_lp_true = false;
static uint32_t dram_class, dram_ctl_143;
static uint32_t dram_class;

/* PHY register index for frequency diff */
uint32_t freq_specific_reg_array[PHY_DIFF_NUM]= {
Expand Down Expand Up @@ -200,25 +202,23 @@ static void ddr_init(void)

void dram_lp_auto_disable(void)
{
uint32_t lp_auto_en;
uint32_t lp_auto_en, tmp;

dram_timing_cfg = (struct dram_cfg *) (SAVED_DRAM_DATA_BASE + sizeof(struct dram_timing_info));
lp_auto_en = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) & (LP_AUTO_ENTRY_EN << 24));
/* Save initial config */
dram_ctl_143 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_143);

/* Set LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2 to Maximum */
mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_143, 0xF << 24);
lp_auto_en = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) & (0xF << 24));

if (lp_auto_en && !dram_auto_lp_true) {
/* 0.a Save DDRC auto low-power mode parameter */
dram_timing_cfg->auto_lp_cfg[0] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
dram_timing_cfg->auto_lp_cfg[1] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_147);
dram_timing_cfg->auto_lp_cfg[2] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146);
dram_timing_cfg->auto_lp_cfg[0] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_147);
dram_timing_cfg->auto_lp_cfg[1] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_148);
dram_timing_cfg->auto_lp_cfg[2] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
dram_timing_cfg->auto_lp_cfg[3] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146);
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_148, 0);
/* 0.b Disable DDRC auto low-power mode interface */
mmio_clrbits_32(IMX_DDRC_BASE + DENALI_CTL_146, LP_AUTO_ENTRY_EN << 24);
mmio_clrbits_32(IMX_DDRC_BASE + DENALI_CTL_146, 0xF << 24);
/* 0.c Read any location to get DRAM out of Self-refresh */
mmio_read_32(DEVICE2_BASE);
tmp = mmio_read_32(DEVICE2_BASE);
mmio_write_32(DEVICE2_BASE, tmp);
/* 0.d Confirm DRAM is out of Self-refresh */
while((mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) & 0x004F4F00) != 0x00404000)
;
Expand All @@ -231,11 +231,12 @@ void dram_lp_auto_disable(void)

void dram_lp_auto_enable(void)
{
/* restore ctl config */
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_143, dram_ctl_143);
uint32_t tmp;

/* Switch back to Auto Low-power mode */
if (dram_auto_lp_true) {
tmp = mmio_read_32(DEVICE2_BASE);
mmio_write_32(DEVICE2_BASE, tmp);
/* 12.a Confirm DRAM is out of Self-refresh */
while((mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) & 0x004F4F00) != 0x00404000)
;
Expand All @@ -245,10 +246,11 @@ void dram_lp_auto_enable(void)
* to default settings = 1b'1.
*/
/* 12.d Reconfigure DENALI_CTL_144 [LPI_WAKEUP_EN[5:0]] bit LPI_WAKEUP_EN[3] = 1b'1. */
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, dram_timing_cfg->auto_lp_cfg[0]);
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_147, dram_timing_cfg->auto_lp_cfg[1]);
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_147, dram_timing_cfg->auto_lp_cfg[0]);
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_148, dram_timing_cfg->auto_lp_cfg[1]);
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, dram_timing_cfg->auto_lp_cfg[2]);
/* 12.e Re-enable DDRC auto low-power mode interface */
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_146, dram_timing_cfg->auto_lp_cfg[2]);
mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_146, dram_timing_cfg->auto_lp_cfg[3]);
/* dram low power mode flag */
dram_auto_lp_true = false;
}
Expand Down Expand Up @@ -336,6 +338,7 @@ void dram_enter_retention(void)
for (i = 0; i < CTL_NUM; i++)
dram_timing_cfg->ctl_cfg[i] = mmio_read_32(IMX_DDRC_BASE + i * 4);
dram_timing_cfg->ctl_cfg[0] = dram_timing_cfg->ctl_cfg[0] & 0xFFFFFFFE;
dram_timing_cfg->ctl_cfg[144] = dram_timing_cfg->ctl_cfg[144] & 0xFFFFC0FF;

/* save the PI registers */
for (i = 0; i < PI_NUM; i++)
Expand Down Expand Up @@ -469,7 +472,6 @@ void dram_exit_retention(void)
mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_65, 0x10000); /* WDQLVL */

/* 11. Wait for trainings to get complete by polling PI_INT_STATUS */
while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x07E00000) != 0x07E00000)
;
Expand Down Expand Up @@ -566,13 +568,15 @@ int lpddr4_dfs(uint32_t freq_index)
if (freq_index == 2 && sys_dvfs)
upower_pmic_i2c_write(0x22, 0x28);

dram_lp_auto_disable();

/* Enable LPI_WAKEUP_EN */
ddr_ctl_144 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, LPI_WAKEUP_EN);

/* put DRAM into long self-refresh & clock gating */
lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
lpddr_ctrl = (lpddr_ctrl & ~((0x3f << 15) | (0x3 << 9))) | (0x28 << 15) | (freq_index << 9);
lpddr_ctrl = (lpddr_ctrl & ~((0x3f << 15) | (0x3 << 9))) | (0x14 << 15) | (freq_index << 9);
mmio_write_32(AVD_SIM_LPDDR_CTRL, lpddr_ctrl);

/* Gating the clock */
Expand Down Expand Up @@ -625,6 +629,9 @@ int lpddr4_dfs(uint32_t freq_index)
upower_pmic_i2c_write(0x22, 0x20);

/* DFS done successfully */

dram_lp_auto_enable();

return 0;
}

Expand Down

0 comments on commit c45c023

Please sign in to comment.