rk30: pmu: support idle request

This commit is contained in:
黄涛
2012-03-21 19:15:36 +08:00
parent 1fa9da832d
commit bc7a9bc32b
2 changed files with 53 additions and 0 deletions

View File

@@ -34,6 +34,7 @@ enum pmu_power_domain {
PD_PERI = 6,
PD_VIO,
PD_VIDEO,
PD_VCODEC = PD_VIDEO,
PD_GPU,
PD_DBG,
};
@@ -45,4 +46,14 @@ static inline bool pmu_power_domain_is_on(enum pmu_power_domain pd)
void pmu_set_power_domain(enum pmu_power_domain pd, bool on);
enum pmu_idle_req {
IDLE_REQ_CPU = 0,
IDLE_REQ_PERI,
IDLE_REQ_GPU,
IDLE_REQ_VIDEO,
IDLE_REQ_VIO,
};
void pmu_set_idle_request(enum pmu_idle_req req, bool idle);
#endif

View File

@@ -39,6 +39,48 @@ void pmu_set_power_domain(enum pmu_power_domain pd, bool on)
unsigned long flags;
spin_lock_irqsave(&pmu_pd_lock, flags);
if (!on) {
/* if power down, idle request to NIU first */
if (pd == PD_VIO)
pmu_set_idle_request(IDLE_REQ_VIO, true);
else if (pd == PD_VIDEO)
pmu_set_idle_request(IDLE_REQ_VIDEO, true);
else if (pd == PD_GPU)
pmu_set_idle_request(IDLE_REQ_GPU, true);
}
do_pmu_set_power_domain(pd, on);
if (on) {
/* if power up, idle request release to NIU */
if (pd == PD_VIO)
pmu_set_idle_request(IDLE_REQ_VIO, false);
else if (pd == PD_VIDEO)
pmu_set_idle_request(IDLE_REQ_VIDEO, false);
else if (pd == PD_GPU)
pmu_set_idle_request(IDLE_REQ_GPU, false);
}
spin_unlock_irqrestore(&pmu_pd_lock, flags);
}
static DEFINE_SPINLOCK(pmu_misc_con1_lock);
void pmu_set_idle_request(enum pmu_idle_req req, bool idle)
{
u32 idle_mask = 1 << (26 - req);
u32 idle_target = idle << (26 - req);
u32 mask = 1 << (req + 1);
u32 val;
unsigned long flags;
spin_lock_irqsave(&pmu_misc_con1_lock, flags);
val = readl_relaxed(RK30_PMU_BASE + PMU_MISC_CON1);
if (idle)
val |= mask;
else
val &= ~mask;
writel_relaxed(val, RK30_PMU_BASE + PMU_MISC_CON1);
dsb();
while ((readl_relaxed(RK30_PMU_BASE + PMU_PWRDN_ST) & idle_mask) != idle_target)
;
spin_unlock_irqrestore(&pmu_misc_con1_lock, flags);
}