about system time incorrect after changing cpu frequency
vichy
vichy.kuo at gmail.com
Tue Sep 1 00:21:40 PDT 2015
hi Viresh:
2015-09-01 14:02 GMT+08:00 Viresh Kumar <viresh.kumar at linaro.org>:
> On 01-09-15, 13:36, vichy wrote:
>> >> I try to call below 2 functions to change the frequency of clocksource
>> >> and clockevent, but the above b) sleep time is still incorrect when
>> >> cpu runs in 500Mhz.
>> >> clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
>> >> __clocksource_updatefreq_hz(>_clocksource, gt_clk_rate);
>
> How and when were you calling them? What kernel version is it ?
Belwo is what I did in my cpufreq driver and my kernel version is 3.0.33.
plat_cpufreq_target()
{
........
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
PLAT_Mpll(freqs.new / 1000);
PLAT_gt_change_freq();
/* post change notification */
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
....
}
and I add PLAT_gt_change_freq in arm_global_timer.c like below:
PLAT_gt_change_freq calling() {
gt_clk_rate = get_periph_clk();
clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
__clocksource_updatefreq_hz(>_clocksource, gt_clk_rate);
}
I also do another experiment that DIDN'T change any REAL HW setting
but change mult/shift to the half value like below:
(But I measure out the "sleep 1" --> still 1secs, even I modify mult/shift)
(in my opinion, the "seep 1" I measured should be 500ms, since HW NO
change but mult/shift change)
plat_cpufreq_target()
{
........
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
// PLAT_Mpll(freqs.new / 1000); //NO HW FREQ change
PLAT_gt_change_freq();
/* post change notification */
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
....
}
PLAT_gt_change_freq in arm_global_timer.c like below:
PLAT_gt_change_freq calling() {
gt_clk_rate = get_periph_clk()/2; //purposely chage 1/2
clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
__clocksource_updatefreq_hz(>_clocksource, gt_clk_rate);
}
>
>> Clock Event Device: arm_global_timer
>
> This driver doesn't have support to update clkevt device's freq. You
> may need to modify that based on how arch/arm/kernel/smp_twd.c is
> updated. look for: clockevents_update_freq().
I have check the latest kernel about arch/arm/kernel/smp_twd.c
it almost do the same thing like I did, except it use cpufreq notifier
for calling clockevents_update_freq like below:
(the final target of them is the same --> clling
clockevents_update_freq to change mult/shift.
static void twd_update_frequency(void *data)
{
twd_timer_rate = clk_get_rate(twd_clk);
clockevents_update_freq(raw_cpu_ptr(twd_evt), twd_timer_rate);
}
I know so far arm global timer seems not support cpu frequcy chage flow.
But like my experiment above to fake change gt_clk_rate, the sleep
should be 1/2 of the original.
if smp_twd call twd_update_frequency to change multi/shift can work,
why purposely adding clockevents_update_freq in global timer not
working?
or there is something else except Mult/shift need to be modify when
gt_clk_rate changed?
appreciate your help in advance,
>
> --
> viresh
More information about the linux-arm-kernel
mailing list