mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
ARM: rockchip: rv1106_pm: improve the accuracy of recovering hptimer
Signed-off-by: XiaoDong Huang <derrick.huang@rock-chips.com> Change-Id: I5ccc5f5fba0f7696fc2c0563ed715b78b5adf451
This commit is contained in:
committed by
Tao Huang
parent
0196404b4f
commit
21f57eaf2d
@@ -92,18 +92,23 @@ static int rk_hptimer_wait_begin_end_valid(void __iomem *base, u64 wait_us)
|
||||
}
|
||||
}
|
||||
|
||||
static u64 rk_hptimer_get_soft_adjust_delt_cnt(void __iomem *base)
|
||||
static u64 rk_hptimer_get_soft_adjust_delt_cnt(void __iomem *base, u32 hf, u32 lf)
|
||||
{
|
||||
u64 begin, end, delt;
|
||||
u32 tmp;
|
||||
|
||||
if (rk_hptimer_wait_begin_end_valid(base, HPTIMER_WAIT_MAX_US))
|
||||
return 0;
|
||||
|
||||
/* (T32_24END - T24_32BEGIN + 2) * (T24 - T32) / T32 + 2.5 * T24/T32 + 2 */
|
||||
begin = (u64)readl_relaxed(base + TIMER_HP_T24_32BEGIN0) |
|
||||
(u64)readl_relaxed(base + TIMER_HP_T24_32BEGIN1) << 32;
|
||||
end = (u64)readl_relaxed(base + TIMER_HP_T32_24END0) |
|
||||
(u64)readl_relaxed(base + TIMER_HP_T32_24END1) << 32;
|
||||
delt = (end - begin) * T24M_GCD / T32K_GCD;
|
||||
delt = (end - begin + 2) * (hf - lf);
|
||||
delt = div_u64(delt, lf);
|
||||
tmp = (2 * hf + hf / 2) / lf;
|
||||
delt = delt + tmp + 2;
|
||||
|
||||
writel_relaxed(0x3, base + TIMER_HP_BEGIN_END_VALID);
|
||||
|
||||
@@ -167,18 +172,18 @@ int rk_hptimer_wait_mode(void __iomem *base, enum rk_hptimer_mode_t mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rk_hptimer_do_soft_adjust(void __iomem *base)
|
||||
void rk_hptimer_do_soft_adjust(void __iomem *base, u32 hf, u32 lf)
|
||||
{
|
||||
u64 delt = rk_hptimer_get_soft_adjust_delt_cnt(base);
|
||||
u64 delt = rk_hptimer_get_soft_adjust_delt_cnt(base, hf, lf);
|
||||
|
||||
rk_hptimer_soft_adjust_req(base, delt);
|
||||
|
||||
rk_hptimer_wait_mode(base, RK_HPTIMER_SOFT_ADJUST_MODE);
|
||||
}
|
||||
|
||||
void rk_hptimer_do_soft_adjust_no_wait(void __iomem *base)
|
||||
void rk_hptimer_do_soft_adjust_no_wait(void __iomem *base, u32 hf, u32 lf)
|
||||
{
|
||||
u64 delt = rk_hptimer_get_soft_adjust_delt_cnt(base);
|
||||
u64 delt = rk_hptimer_get_soft_adjust_delt_cnt(base, hf, lf);
|
||||
|
||||
rk_hptimer_soft_adjust_req(base, delt);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ int rk_hptimer_is_enabled(void __iomem *base);
|
||||
int rk_hptimer_get_mode(void __iomem *base);
|
||||
u64 rk_hptimer_get_count(void __iomem *base);
|
||||
int rk_hptimer_wait_mode(void __iomem *base, enum rk_hptimer_mode_t mode);
|
||||
void rk_hptimer_do_soft_adjust(void __iomem *base);
|
||||
void rk_hptimer_do_soft_adjust_no_wait(void __iomem *base);
|
||||
void rk_hptimer_do_soft_adjust(void __iomem *base, u32 hf, u32 lf);
|
||||
void rk_hptimer_do_soft_adjust_no_wait(void __iomem *base, u32 hf, u32 lf);
|
||||
void rk_hptimer_mode_init(void __iomem *base, enum rk_hptimer_mode_t mode);
|
||||
#endif
|
||||
|
||||
@@ -55,6 +55,7 @@ struct rv1106_sleep_ddr_data {
|
||||
u32 gpio0a_iomux_l, gpio0a_iomux_h, gpio0a0_pull;
|
||||
u32 gpio0_ddr_l, gpio0_ddr_h;
|
||||
u32 pmu_wkup_int_st, gpio0_int_st;
|
||||
u32 sleep_clk_freq_hz;
|
||||
};
|
||||
|
||||
static struct rv1106_sleep_ddr_data ddr_data;
|
||||
@@ -604,9 +605,9 @@ static void clock_resume(void)
|
||||
|
||||
static void pvtm_32k_config(int flag)
|
||||
{
|
||||
int value;
|
||||
int pvtm_freq_khz, pvtm_div;
|
||||
int sleep_clk_freq_khz;
|
||||
u64 value, pvtm_freq_hz;
|
||||
int pvtm_div;
|
||||
u32 pvtm_div_freq_hz;
|
||||
|
||||
ddr_data.pmucru_sel_con7 =
|
||||
readl_relaxed(pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
|
||||
@@ -623,7 +624,7 @@ static void pvtm_32k_config(int flag)
|
||||
pmupvtm_base + RV1106_PVTM_CON(2));
|
||||
writel_relaxed(RV1106_PVTM_CALC_CNT,
|
||||
pmupvtm_base + RV1106_PVTM_CON(1));
|
||||
writel_relaxed(BITS_WITH_WMASK(0, 0x3, PVTM_START),
|
||||
writel_relaxed(BITS_WITH_WMASK(0, 0x1, PVTM_START),
|
||||
pmupvtm_base + RV1106_PVTM_CON(0));
|
||||
dsb();
|
||||
|
||||
@@ -648,8 +649,11 @@ static void pvtm_32k_config(int flag)
|
||||
;
|
||||
|
||||
value = (readl_relaxed(pmupvtm_base + RV1106_PVTM_STATUS(1)));
|
||||
pvtm_freq_khz = (value * 24000 + RV1106_PVTM_CALC_CNT / 2) / RV1106_PVTM_CALC_CNT;
|
||||
pvtm_div = (pvtm_freq_khz + 16) / 32 - 1;
|
||||
pvtm_freq_hz = (value * 24000000 + RV1106_PVTM_CALC_CNT / 2);
|
||||
pvtm_freq_hz = div_u64(pvtm_freq_hz, RV1106_PVTM_CALC_CNT);
|
||||
|
||||
pvtm_div = ((u32)pvtm_freq_hz + RV1106_PVTM_TARGET_FREQ / 2) /
|
||||
RV1106_PVTM_TARGET_FREQ - 1;
|
||||
if (pvtm_div > 0xfff)
|
||||
pvtm_div = 0xfff;
|
||||
|
||||
@@ -660,12 +664,19 @@ static void pvtm_32k_config(int flag)
|
||||
writel_relaxed(BITS_WITH_WMASK(0x2, 0x3, 0),
|
||||
pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
|
||||
|
||||
sleep_clk_freq_khz = pvtm_freq_khz / (pvtm_div + 1);
|
||||
pvtm_div_freq_hz = (u32)pvtm_freq_hz / (pvtm_div + 1);
|
||||
ddr_data.sleep_clk_freq_hz = pvtm_div_freq_hz;
|
||||
|
||||
rkpm_printstr("pvtm real_freq (khz):");
|
||||
rkpm_printhex(sleep_clk_freq_khz);
|
||||
rkpm_printstr("pvtm freq (hz):");
|
||||
rkpm_printdec(pvtm_freq_hz);
|
||||
rkpm_printch('-');
|
||||
rkpm_printdec(pvtm_div_freq_hz);
|
||||
rkpm_printch('\n');
|
||||
}
|
||||
|
||||
rkpm_printstr("sleep freq (hz):");
|
||||
rkpm_printdec(ddr_data.sleep_clk_freq_hz);
|
||||
rkpm_printch('\n');
|
||||
}
|
||||
|
||||
static void pvtm_32k_config_restore(void)
|
||||
@@ -674,7 +685,9 @@ static void pvtm_32k_config_restore(void)
|
||||
pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
|
||||
|
||||
if (rk_hptimer_get_mode(hptimer_base) == RK_HPTIMER_SOFT_ADJUST_MODE)
|
||||
rk_hptimer_do_soft_adjust_no_wait(hptimer_base);
|
||||
rk_hptimer_do_soft_adjust_no_wait(hptimer_base,
|
||||
24000000,
|
||||
ddr_data.sleep_clk_freq_hz);
|
||||
}
|
||||
|
||||
static void ddr_sleep_config(void)
|
||||
|
||||
@@ -129,7 +129,8 @@
|
||||
#define RV1106_PVTM_INTSTS 0x74
|
||||
#define RV1106_PVTM_STATUS(i) (0x80 + (i) * 4)
|
||||
|
||||
#define RV1106_PVTM_CALC_CNT 0x200
|
||||
#define RV1106_PVTM_CALC_CNT 24000
|
||||
#define RV1106_PVTM_TARGET_FREQ 32768
|
||||
|
||||
/* gpio */
|
||||
#define RV1106_GPIO_SWPORT_DR_L 0x0000
|
||||
|
||||
Reference in New Issue
Block a user