mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
rk30: pmu: support idle request
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user