msm: mdss: Update memory retention and periph control setting
Previously memory retention and preiph control are only set when device enters/exits idle power collapse mode. The memory retention and periph setting will remain ON when device is actually in suspend state, which will cause unnecessary power consumption. This change updates those setting for both idle power collapse cases and suspend/resume case. With this change, the memory retention and periph will be set to OFF in suspend case to optimize power consumption. Change-Id: I1598dbc97cb9d02b946de5c9803a49d923c7edc1 Signed-off-by: Ping Li <pingli@codeaurora.org>
This commit is contained in:
parent
3c7400dc73
commit
ceb0faf9e3
2 changed files with 48 additions and 46 deletions
|
@ -459,6 +459,7 @@ struct mdss_data_type {
|
|||
u32 nmax_concurrent_ad_hw;
|
||||
struct workqueue_struct *ad_calc_wq;
|
||||
u32 ad_debugen;
|
||||
bool mem_retain;
|
||||
|
||||
struct mdss_intr hist_intr;
|
||||
|
||||
|
|
|
@ -1345,7 +1345,12 @@ int mdss_iommu_ctrl(int enable)
|
|||
return mdata->iommu_ref_cnt;
|
||||
}
|
||||
|
||||
static void mdss_mdp_memory_retention_enter(void)
|
||||
#define MEM_RETAIN_ON 1
|
||||
#define MEM_RETAIN_OFF 0
|
||||
#define PERIPH_RETAIN_ON 1
|
||||
#define PERIPH_RETAIN_OFF 0
|
||||
|
||||
static void mdss_mdp_memory_retention_ctrl(bool mem_ctrl, bool periph_ctrl)
|
||||
{
|
||||
struct clk *mdss_mdp_clk = NULL;
|
||||
struct clk *mdp_vote_clk = mdss_mdp_get_clk(MDSS_CLK_MDP_CORE);
|
||||
|
@ -1366,49 +1371,35 @@ static void mdss_mdp_memory_retention_enter(void)
|
|||
|
||||
__mdss_mdp_reg_access_clk_enable(mdata, true);
|
||||
if (mdss_mdp_clk) {
|
||||
if (mem_ctrl)
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_RETAIN_MEM);
|
||||
else
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_NORETAIN_MEM);
|
||||
|
||||
if (periph_ctrl) {
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_RETAIN_PERIPH);
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_PERIPH_OFF_CLEAR);
|
||||
} else {
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_PERIPH_OFF_SET);
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_NORETAIN_PERIPH);
|
||||
}
|
||||
|
||||
if (mdss_mdp_lut_clk) {
|
||||
clk_set_flags(mdss_mdp_lut_clk, CLKFLAG_RETAIN_MEM);
|
||||
clk_set_flags(mdss_mdp_lut_clk, CLKFLAG_PERIPH_OFF_SET);
|
||||
clk_set_flags(mdss_mdp_lut_clk, CLKFLAG_NORETAIN_PERIPH);
|
||||
}
|
||||
__mdss_mdp_reg_access_clk_enable(mdata, false);
|
||||
}
|
||||
|
||||
static void mdss_mdp_memory_retention_exit(void)
|
||||
{
|
||||
struct clk *mdss_mdp_clk = NULL;
|
||||
struct clk *mdp_vote_clk = mdss_mdp_get_clk(MDSS_CLK_MDP_CORE);
|
||||
struct clk *mdss_mdp_lut_clk = NULL;
|
||||
struct clk *mdp_lut_vote_clk = mdss_mdp_get_clk(MDSS_CLK_MDP_LUT);
|
||||
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
|
||||
|
||||
if (mdp_vote_clk) {
|
||||
if (test_bit(MDSS_CAPS_MDP_VOTE_CLK_NOT_SUPPORTED,
|
||||
mdata->mdss_caps_map)) {
|
||||
mdss_mdp_clk = mdp_vote_clk;
|
||||
mdss_mdp_lut_clk = mdp_lut_vote_clk;
|
||||
} else {
|
||||
mdss_mdp_clk = clk_get_parent(mdp_vote_clk);
|
||||
mdss_mdp_lut_clk = clk_get_parent(mdp_lut_vote_clk);
|
||||
}
|
||||
}
|
||||
|
||||
__mdss_mdp_reg_access_clk_enable(mdata, true);
|
||||
if (mdss_mdp_clk) {
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_RETAIN_MEM);
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_RETAIN_PERIPH);
|
||||
clk_set_flags(mdss_mdp_clk, CLKFLAG_PERIPH_OFF_CLEAR);
|
||||
}
|
||||
|
||||
if (mdss_mdp_lut_clk) {
|
||||
if (mem_ctrl)
|
||||
clk_set_flags(mdss_mdp_lut_clk, CLKFLAG_RETAIN_MEM);
|
||||
else
|
||||
clk_set_flags(mdss_mdp_lut_clk, CLKFLAG_NORETAIN_MEM);
|
||||
|
||||
if (periph_ctrl) {
|
||||
clk_set_flags(mdss_mdp_lut_clk, CLKFLAG_RETAIN_PERIPH);
|
||||
clk_set_flags(mdss_mdp_lut_clk, CLKFLAG_PERIPH_OFF_CLEAR);
|
||||
clk_set_flags(mdss_mdp_lut_clk,
|
||||
CLKFLAG_PERIPH_OFF_CLEAR);
|
||||
} else {
|
||||
clk_set_flags(mdss_mdp_lut_clk, CLKFLAG_PERIPH_OFF_SET);
|
||||
clk_set_flags(mdss_mdp_lut_clk,
|
||||
CLKFLAG_NORETAIN_PERIPH);
|
||||
}
|
||||
}
|
||||
__mdss_mdp_reg_access_clk_enable(mdata, false);
|
||||
}
|
||||
|
@ -1441,17 +1432,21 @@ static int mdss_mdp_idle_pc_restore(void)
|
|||
mdss_hw_init(mdata);
|
||||
mdss_iommu_ctrl(0);
|
||||
|
||||
mdss_mdp_ctl_restore(true);
|
||||
mdata->idle_pc = false;
|
||||
|
||||
end:
|
||||
if (mdata->mem_retain) {
|
||||
/**
|
||||
* sleep 10 microseconds to make sure AD auto-reinitialization
|
||||
* is done
|
||||
*/
|
||||
udelay(10);
|
||||
mdss_mdp_memory_retention_exit();
|
||||
mdss_mdp_memory_retention_ctrl(MEM_RETAIN_ON,
|
||||
PERIPH_RETAIN_ON);
|
||||
mdata->mem_retain = false;
|
||||
}
|
||||
|
||||
mdss_mdp_ctl_restore(true);
|
||||
mdata->idle_pc = false;
|
||||
|
||||
end:
|
||||
mutex_unlock(&mdp_fs_idle_pc_lock);
|
||||
return rc;
|
||||
}
|
||||
|
@ -4910,10 +4905,12 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
|
|||
* Turning off GDSC while overlays are still
|
||||
* active.
|
||||
*/
|
||||
|
||||
mdss_mdp_memory_retention_ctrl(MEM_RETAIN_ON,
|
||||
PERIPH_RETAIN_OFF);
|
||||
mdata->idle_pc = true;
|
||||
pr_debug("idle pc. active overlays=%d\n",
|
||||
active_cnt);
|
||||
mdss_mdp_memory_retention_enter();
|
||||
} else {
|
||||
/*
|
||||
* Advise RPM to turn MMSS GDSC off during
|
||||
|
@ -4925,7 +4922,11 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
|
|||
|
||||
mdss_mdp_cx_ctrl(mdata, false);
|
||||
mdss_mdp_batfet_ctrl(mdata, false);
|
||||
mdss_mdp_memory_retention_ctrl(
|
||||
MEM_RETAIN_OFF,
|
||||
PERIPH_RETAIN_OFF);
|
||||
}
|
||||
mdata->mem_retain = true;
|
||||
if (mdata->en_svs_high)
|
||||
mdss_mdp_config_cx_voltage(mdata, false);
|
||||
regulator_disable(mdata->fs);
|
||||
|
|
Loading…
Add table
Reference in a new issue