Skip to content
Snippets Groups Projects
Commit 7e2080c1 authored by Nicolas Le Bayon's avatar Nicolas Le Bayon Committed by Sebastien Pasdeloup
Browse files

stm32mp1: add DDR Self Refresh adaptive management


Define DDR Self Refresh (SR) mode read/set/save/restore API functions.
At the end of DDR initialization in BL2, switch SR mode to the one
indicated by DDR updated registers. Save mode at BL32 init.
When entering in cstop/cstandby, switch to SSR (Software).
When exiting, go back to the saved mode.

Change-Id: Iadd795d20fdea2d7be30c1ba6f02eb172e33f4b1
Signed-off-by: default avatarNicolas Le Bayon <nicolas.le.bayon@st.com>
parent c2ce850b
No related branches found
No related tags found
No related merge requests found
......@@ -9,11 +9,15 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/st/stm32mp1_ddr.h>
#include <drivers/st/stm32mp1_ddr_helpers.h>
#include <drivers/st/stm32mp1_ddr_regs.h>
#include <lib/mmio.h>
#define TIMEOUT_500US 500U
static enum stm32mp1_ddr_sr_mode saved_ddr_sr_mode;
void ddr_enable_clock(void)
{
stm32mp1_clk_rcc_regs_lock();
......@@ -380,7 +384,7 @@ int ddr_standby_sr_entry(void)
return 0;
}
void ddr_sr_mode_ssr(void)
static void ddr_sr_mode_ssr(void)
{
uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR;
uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
......@@ -432,7 +436,7 @@ void ddr_sr_mode_ssr(void)
DDRCTRL_PWRCTL_SELFREF_EN);
}
void ddr_sr_mode_asr(void)
static void ddr_sr_mode_asr(void)
{
uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR;
uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
......@@ -473,7 +477,7 @@ void ddr_sr_mode_asr(void)
DDRCTRL_PWRCTL_SELFREF_EN);
}
void ddr_sr_mode_hsr(void)
static void ddr_sr_mode_hsr(void)
{
uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR;
uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
......@@ -509,3 +513,54 @@ void ddr_sr_mode_hsr(void)
mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL,
DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE);
}
enum stm32mp1_ddr_sr_mode ddr_read_sr_mode(void)
{
uint32_t pwrctl = mmio_read_32(stm32mp_ddrctrl_base() + DDRCTRL_PWRCTL);
switch (pwrctl & (DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE |
DDRCTRL_PWRCTL_SELFREF_EN)) {
case 0U:
return DDR_SSR_MODE;
case DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE:
return DDR_HSR_MODE;
case DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE | DDRCTRL_PWRCTL_SELFREF_EN:
return DDR_ASR_MODE;
default:
return DDR_SR_MODE_INVALID;
}
}
void ddr_set_sr_mode(enum stm32mp1_ddr_sr_mode mode)
{
switch (mode) {
case DDR_SSR_MODE:
ddr_sr_mode_ssr();
break;
case DDR_HSR_MODE:
ddr_sr_mode_hsr();
break;
case DDR_ASR_MODE:
ddr_sr_mode_asr();
break;
default:
ERROR("Unknown Self Refresh mode\n");
panic();
}
}
void ddr_save_sr_mode(void)
{
saved_ddr_sr_mode = ddr_read_sr_mode();
}
void ddr_restore_sr_mode(void)
{
ddr_set_sr_mode(saved_ddr_sr_mode);
}
......@@ -344,8 +344,12 @@ static int stm32mp1_ddr_setup(void)
}
}
/* Switch to Automatic Self-Refresh */
ddr_sr_mode_asr();
/*
* Initialization sequence has configured DDR registers with settings.
* The Self Refresh (SR) mode corresponding to these settings has now
* to be set.
*/
ddr_set_sr_mode(ddr_read_sr_mode());
if (stm32mp_unmap_ddr() != 0) {
panic();
......
......@@ -9,12 +9,20 @@
#include <stdint.h>
enum stm32mp1_ddr_sr_mode {
DDR_SR_MODE_INVALID = 0,
DDR_SSR_MODE,
DDR_HSR_MODE,
DDR_ASR_MODE,
};
void ddr_enable_clock(void);
int ddr_sw_self_refresh_exit(void);
uint32_t ddr_get_io_calibration_val(void);
int ddr_standby_sr_entry(void);
void ddr_sr_mode_ssr(void);
void ddr_sr_mode_asr(void);
void ddr_sr_mode_hsr(void);
enum stm32mp1_ddr_sr_mode ddr_read_sr_mode(void);
void ddr_set_sr_mode(enum stm32mp1_ddr_sr_mode mode);
void ddr_save_sr_mode(void);
void ddr_restore_sr_mode(void);
#endif /* STM32MP1_DDR_HELPERS_H */
......@@ -28,6 +28,7 @@
#include <drivers/st/stm32mp_clkfunc.h>
#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_ddr_helpers.h>
#include <drivers/st/stpmic1.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <lib/el3_runtime/context_mgmt.h>
......@@ -415,6 +416,8 @@ static void init_sec_peripherals(void)
******************************************************************************/
void sp_min_platform_setup(void)
{
ddr_save_sr_mode();
/* Initialize tzc400 after DDR initialization */
stm32mp1_security_setup();
......
......@@ -133,8 +133,8 @@ static void enter_cstop(uint32_t mode, uint32_t nsec_addr)
stm32mp1_syscfg_disable_io_compensation();
/* Switch to Software Self-Refresh */
ddr_sr_mode_ssr();
/* Switch to Software Self-Refresh mode */
ddr_set_sr_mode(DDR_SSR_MODE);
dcsw_op_all(DC_OP_CISW);
......@@ -252,8 +252,8 @@ void stm32_exit_cstop(void)
panic();
}
/* Switch to Automatic Self-Refresh */
ddr_sr_mode_asr();
/* Switch to memorized Self-Refresh mode */
ddr_restore_sr_mode();
plat_ic_set_priority_mask(gicc_pmr);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment