* about system time incorrect after changing cpu frequency
@ 2015-08-31 14:03 ` vichy
0 siblings, 0 replies; 16+ messages in thread
From: vichy @ 2015-08-31 14:03 UTC (permalink / raw)
To: linux-arm-kernel
hi all:
My platform is like below:
1. single core Cortex A9
2. use global timer for system timer
after I porting cpu frequency driver based on snow ball, the cpu
frequency did change as I expected.
But the system time is incorrect( since pherial clk is got from cpu frequency)
for example:
a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
b) cpu 500M (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)
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);
in Arm cortex A9 single core system with Global timer as system timer,
is there any kernel api to change system timer period when cpu/pherial
frequency change?
appreciate your kind help in advance,
^ permalink raw reply [flat|nested] 16+ messages in thread
* about system time incorrect after changing cpu frequency
@ 2015-08-31 14:03 ` vichy
0 siblings, 0 replies; 16+ messages in thread
From: vichy @ 2015-08-31 14:03 UTC (permalink / raw)
To: cpufreq, linux-arm-kernel
hi all:
My platform is like below:
1. single core Cortex A9
2. use global timer for system timer
after I porting cpu frequency driver based on snow ball, the cpu
frequency did change as I expected.
But the system time is incorrect( since pherial clk is got from cpu frequency)
for example:
a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
b) cpu 500M (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)
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);
in Arm cortex A9 single core system with Global timer as system timer,
is there any kernel api to change system timer period when cpu/pherial
frequency change?
appreciate your kind help in advance,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: about system time incorrect after changing cpu frequency
2015-08-31 14:03 ` vichy
@ 2015-09-01 3:57 ` Viresh Kumar
-1 siblings, 0 replies; 16+ messages in thread
From: Viresh Kumar @ 2015-09-01 3:57 UTC (permalink / raw)
To: vichy; +Cc: cpufreq, linux-arm-kernel, Linux PM list
On Mon, Aug 31, 2015 at 7:33 PM, vichy <vichy.kuo@gmail.com> wrote:
> hi all:
> My platform is like below:
> 1. single core Cortex A9
> 2. use global timer for system timer
>
> after I porting cpu frequency driver based on snow ball, the cpu
> frequency did change as I expected.
> But the system time is incorrect( since pherial clk is got from cpu frequency)
>
> for example:
> a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
> b) cpu 500M (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)
>
> 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);
>
> in Arm cortex A9 single core system with Global timer as system timer,
> is there any kernel api to change system timer period when cpu/pherial
> frequency change?
>
> appreciate your kind help in advance,
The list cpufreq@vger.kernel.org is the wrong list for posting cpufreq queries
as we have moved to Linux PM list <linux-pm@vger.kernel.org> list now.
Try unsetting CPUFREQ_CONST_LOOPS flag in your driver, if you have it
set.
^ permalink raw reply [flat|nested] 16+ messages in thread
* about system time incorrect after changing cpu frequency
@ 2015-09-01 3:57 ` Viresh Kumar
0 siblings, 0 replies; 16+ messages in thread
From: Viresh Kumar @ 2015-09-01 3:57 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Aug 31, 2015 at 7:33 PM, vichy <vichy.kuo@gmail.com> wrote:
> hi all:
> My platform is like below:
> 1. single core Cortex A9
> 2. use global timer for system timer
>
> after I porting cpu frequency driver based on snow ball, the cpu
> frequency did change as I expected.
> But the system time is incorrect( since pherial clk is got from cpu frequency)
>
> for example:
> a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
> b) cpu 500M (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)
>
> 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);
>
> in Arm cortex A9 single core system with Global timer as system timer,
> is there any kernel api to change system timer period when cpu/pherial
> frequency change?
>
> appreciate your kind help in advance,
The list cpufreq at vger.kernel.org is the wrong list for posting cpufreq queries
as we have moved to Linux PM list <linux-pm@vger.kernel.org> list now.
Try unsetting CPUFREQ_CONST_LOOPS flag in your driver, if you have it
set.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: about system time incorrect after changing cpu frequency
2015-09-01 3:57 ` Viresh Kumar
@ 2015-09-01 5:36 ` vichy
-1 siblings, 0 replies; 16+ messages in thread
From: vichy @ 2015-09-01 5:36 UTC (permalink / raw)
To: Viresh Kumar; +Cc: cpufreq, linux-arm-kernel, Linux PM list
hi Viresh:
2015-09-01 11:57 GMT+08:00 Viresh Kumar <viresh.kumar@linaro.org>:
> On Mon, Aug 31, 2015 at 7:33 PM, vichy <vichy.kuo@gmail.com> wrote:
>> hi all:
>> My platform is like below:
>> 1. single core Cortex A9
>> 2. use global timer for system timer
>>
>> after I porting cpu frequency driver based on snow ball, the cpu
>> frequency did change as I expected.
>> But the system time is incorrect( since pherial clk is got from cpu frequency)
>>
>> for example:
>> a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
>> b) cpu 500M (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)
>>
>> 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);
>>
>> in Arm cortex A9 single core system with Global timer as system timer,
>> is there any kernel api to change system timer period when cpu/pherial
>> frequency change?
>>
>> appreciate your kind help in advance,
>
> The list cpufreq@vger.kernel.org is the wrong list for posting cpufreq queries
> as we have moved to Linux PM list <linux-pm@vger.kernel.org> list now.
>
> Try unsetting CPUFREQ_CONST_LOOPS flag in your driver, if you have it
> set.
I DIDN'T set the CPUFREQ_CONST_LOOPS when I register my cpufreq driver
I pasted my cpufreq driver declariation as below:
static struct cpufreq_driver plat_cpufreq_driver = {
.flags = CPUFREQ_STICKY,
.verify = plat_cpufreq_verify_speed,
.target = plat_cpufreq_target,
.get = plat_cpufreq_getspeed,
.init = plat_cpufreq_init,
.name = "plat-cpufreq",
.attr = plat_cpufreq_attr,
};
I have traced the kernel code
if I guess correctly, the sleep accurate is based on jiffies and
tick_handle_periodic will periodically update the next event interval
void tick_handle_periodic
-->
for (;;) {
if (!clockevents_program_event(dev, next, false))
return;
/*
* Have to be careful here. If we're in oneshot mode,
* before we call tick_periodic() in a loop, we need
* to be sure we're using a real hardware clocksource.
* Otherwise we could get trapped in an infinite
* loop, as the tick_periodic() increments jiffies,
* when then will increment time, posibly causing
* the loop to trigger again and again.
*/
if (timekeeping_valid_for_hres())
tick_periodic(cpu);
next = ktime_add(next, tick_period);
}
and in clockevents_program_event, we will use mult, shift to calculate
the cycles need for global timer triggering next interrupt event.
clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
rc = dev->set_next_event((unsigned long) clc, dev);
belwo is my tick device information in /proc/timer_list
and multi did change to 1/2 when I change cpu freq from 1G to 500Mhz.
when cpu run 1GHz
except multi and shift, is there any place I need to take care for
system timer accurate?
appreciate your kind help,
Tick Device: mode: 1
Per CPU device: 0
Clock Event Device: arm_global_timer
max_delta_ns: 17043521021
min_delta_ns: 1000
mult: 541165879
shift: 31
mode: 3
next_event: 2176344000000 nsecs
set_next_event: gt_clockevent_set_next_event
set_mode: gt_clockevent_set_mode
event_handler: hrtimer_interrupt
retries: 0
when cpu run in 500Mhz
Tick Device: mode: 1
Per CPU device: 0
Clock Event Device: arm_global_timer
max_delta_ns: 34087041979
min_delta_ns: 1000
mult: 270582940
shift: 31
mode: 3
next_event: 2230100000000 nsecs
set_next_event: gt_clockevent_set_next_event
set_mode: gt_clockevent_set_mode
event_handler: hrtimer_interrupt
retries: 0
^ permalink raw reply [flat|nested] 16+ messages in thread
* about system time incorrect after changing cpu frequency
@ 2015-09-01 5:36 ` vichy
0 siblings, 0 replies; 16+ messages in thread
From: vichy @ 2015-09-01 5:36 UTC (permalink / raw)
To: linux-arm-kernel
hi Viresh:
2015-09-01 11:57 GMT+08:00 Viresh Kumar <viresh.kumar@linaro.org>:
> On Mon, Aug 31, 2015 at 7:33 PM, vichy <vichy.kuo@gmail.com> wrote:
>> hi all:
>> My platform is like below:
>> 1. single core Cortex A9
>> 2. use global timer for system timer
>>
>> after I porting cpu frequency driver based on snow ball, the cpu
>> frequency did change as I expected.
>> But the system time is incorrect( since pherial clk is got from cpu frequency)
>>
>> for example:
>> a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
>> b) cpu 500M (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)
>>
>> 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);
>>
>> in Arm cortex A9 single core system with Global timer as system timer,
>> is there any kernel api to change system timer period when cpu/pherial
>> frequency change?
>>
>> appreciate your kind help in advance,
>
> The list cpufreq at vger.kernel.org is the wrong list for posting cpufreq queries
> as we have moved to Linux PM list <linux-pm@vger.kernel.org> list now.
>
> Try unsetting CPUFREQ_CONST_LOOPS flag in your driver, if you have it
> set.
I DIDN'T set the CPUFREQ_CONST_LOOPS when I register my cpufreq driver
I pasted my cpufreq driver declariation as below:
static struct cpufreq_driver plat_cpufreq_driver = {
.flags = CPUFREQ_STICKY,
.verify = plat_cpufreq_verify_speed,
.target = plat_cpufreq_target,
.get = plat_cpufreq_getspeed,
.init = plat_cpufreq_init,
.name = "plat-cpufreq",
.attr = plat_cpufreq_attr,
};
I have traced the kernel code
if I guess correctly, the sleep accurate is based on jiffies and
tick_handle_periodic will periodically update the next event interval
void tick_handle_periodic
-->
for (;;) {
if (!clockevents_program_event(dev, next, false))
return;
/*
* Have to be careful here. If we're in oneshot mode,
* before we call tick_periodic() in a loop, we need
* to be sure we're using a real hardware clocksource.
* Otherwise we could get trapped in an infinite
* loop, as the tick_periodic() increments jiffies,
* when then will increment time, posibly causing
* the loop to trigger again and again.
*/
if (timekeeping_valid_for_hres())
tick_periodic(cpu);
next = ktime_add(next, tick_period);
}
and in clockevents_program_event, we will use mult, shift to calculate
the cycles need for global timer triggering next interrupt event.
clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
rc = dev->set_next_event((unsigned long) clc, dev);
belwo is my tick device information in /proc/timer_list
and multi did change to 1/2 when I change cpu freq from 1G to 500Mhz.
when cpu run 1GHz
except multi and shift, is there any place I need to take care for
system timer accurate?
appreciate your kind help,
Tick Device: mode: 1
Per CPU device: 0
Clock Event Device: arm_global_timer
max_delta_ns: 17043521021
min_delta_ns: 1000
mult: 541165879
shift: 31
mode: 3
next_event: 2176344000000 nsecs
set_next_event: gt_clockevent_set_next_event
set_mode: gt_clockevent_set_mode
event_handler: hrtimer_interrupt
retries: 0
when cpu run in 500Mhz
Tick Device: mode: 1
Per CPU device: 0
Clock Event Device: arm_global_timer
max_delta_ns: 34087041979
min_delta_ns: 1000
mult: 270582940
shift: 31
mode: 3
next_event: 2230100000000 nsecs
set_next_event: gt_clockevent_set_next_event
set_mode: gt_clockevent_set_mode
event_handler: hrtimer_interrupt
retries: 0
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: about system time incorrect after changing cpu frequency
2015-09-01 5:36 ` vichy
@ 2015-09-01 6:02 ` Viresh Kumar
-1 siblings, 0 replies; 16+ messages in thread
From: Viresh Kumar @ 2015-09-01 6:02 UTC (permalink / raw)
To: vichy; +Cc: cpufreq, linux-arm-kernel, Linux PM list
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 ?
> 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().
--
viresh
^ permalink raw reply [flat|nested] 16+ messages in thread
* about system time incorrect after changing cpu frequency
@ 2015-09-01 6:02 ` Viresh Kumar
0 siblings, 0 replies; 16+ messages in thread
From: Viresh Kumar @ 2015-09-01 6:02 UTC (permalink / raw)
To: linux-arm-kernel
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 ?
> 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().
--
viresh
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: about system time incorrect after changing cpu frequency
2015-09-01 6:02 ` Viresh Kumar
@ 2015-09-01 6:39 ` Jisheng Zhang
-1 siblings, 0 replies; 16+ messages in thread
From: Jisheng Zhang @ 2015-09-01 6:39 UTC (permalink / raw)
To: Viresh Kumar; +Cc: vichy, linux-arm-kernel, cpufreq, Linux PM list
On Tue, 1 Sep 2015 11:32:36 +0530
Viresh Kumar <viresh.kumar@linaro.org> wrote:
> 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 ?
>
> > 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().
>
This can only help the clockevent. Even with this cpufreq notifier
update, the globaltimer clocksource still can't hold correct/accurate time.
I think the arm global timer is not suitable for clocksource if cpufreq is
enabled.
^ permalink raw reply [flat|nested] 16+ messages in thread
* about system time incorrect after changing cpu frequency
@ 2015-09-01 6:39 ` Jisheng Zhang
0 siblings, 0 replies; 16+ messages in thread
From: Jisheng Zhang @ 2015-09-01 6:39 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, 1 Sep 2015 11:32:36 +0530
Viresh Kumar <viresh.kumar@linaro.org> wrote:
> 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 ?
>
> > 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().
>
This can only help the clockevent. Even with this cpufreq notifier
update, the globaltimer clocksource still can't hold correct/accurate time.
I think the arm global timer is not suitable for clocksource if cpufreq is
enabled.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: about system time incorrect after changing cpu frequency
2015-09-01 6:02 ` Viresh Kumar
@ 2015-09-01 7:21 ` vichy
-1 siblings, 0 replies; 16+ messages in thread
From: vichy @ 2015-09-01 7:21 UTC (permalink / raw)
To: Viresh Kumar; +Cc: cpufreq, linux-arm-kernel, Linux PM list
hi Viresh:
2015-09-01 14:02 GMT+08:00 Viresh Kumar <viresh.kumar@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
^ permalink raw reply [flat|nested] 16+ messages in thread
* about system time incorrect after changing cpu frequency
@ 2015-09-01 7:21 ` vichy
0 siblings, 0 replies; 16+ messages in thread
From: vichy @ 2015-09-01 7:21 UTC (permalink / raw)
To: linux-arm-kernel
hi Viresh:
2015-09-01 14:02 GMT+08:00 Viresh Kumar <viresh.kumar@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
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: about system time incorrect after changing cpu frequency
2015-09-01 6:39 ` Jisheng Zhang
@ 2015-09-01 7:37 ` vichy
-1 siblings, 0 replies; 16+ messages in thread
From: vichy @ 2015-09-01 7:37 UTC (permalink / raw)
To: Jisheng Zhang; +Cc: Viresh Kumar, linux-arm-kernel, cpufreq, Linux PM list
hi Jisheng:
2015-09-01 14:39 GMT+08:00 Jisheng Zhang <jszhang@marvell.com>:
> On Tue, 1 Sep 2015 11:32:36 +0530
> Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
>> 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 ?
>>
>> > 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().
>>
>
> This can only help the clockevent. Even with this cpufreq notifier
> update, the globaltimer clocksource still can't hold correct/accurate time.
Why even global timer add clockevents_update_freq, it stilll CANNOT
hold currect/accurate time?
When I trace the kernel, clockevents_program_event will calculate the
cycles with mult/shift then put in comparator.
if we put the write mult/shift, the global timer should hold
correct/accurate time under different phepherial clock, right?
Appreciate all your kind help,
^ permalink raw reply [flat|nested] 16+ messages in thread
* about system time incorrect after changing cpu frequency
@ 2015-09-01 7:37 ` vichy
0 siblings, 0 replies; 16+ messages in thread
From: vichy @ 2015-09-01 7:37 UTC (permalink / raw)
To: linux-arm-kernel
hi Jisheng:
2015-09-01 14:39 GMT+08:00 Jisheng Zhang <jszhang@marvell.com>:
> On Tue, 1 Sep 2015 11:32:36 +0530
> Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
>> 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 ?
>>
>> > 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().
>>
>
> This can only help the clockevent. Even with this cpufreq notifier
> update, the globaltimer clocksource still can't hold correct/accurate time.
Why even global timer add clockevents_update_freq, it stilll CANNOT
hold currect/accurate time?
When I trace the kernel, clockevents_program_event will calculate the
cycles with mult/shift then put in comparator.
if we put the write mult/shift, the global timer should hold
correct/accurate time under different phepherial clock, right?
Appreciate all your kind help,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: about system time incorrect after changing cpu frequency
2015-09-01 7:21 ` vichy
@ 2015-09-01 7:42 ` Viresh Kumar
-1 siblings, 0 replies; 16+ messages in thread
From: Viresh Kumar @ 2015-09-01 7:42 UTC (permalink / raw)
To: vichy; +Cc: cpufreq, linux-arm-kernel, Linux PM list
On 01-09-15, 15:21, vichy wrote:
> 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);
In earlier versions of kernel, this had a problem that it works only
for ONESHOT mode and simply returns in PERIODIC mode. I do see that
your's mode is ONESHOT only, and so it should have worked.
Anyway, few prints into that routine to see where we are reaching
might help.
> __clocksource_updatefreq_hz(>_clocksource, gt_clk_rate);
AFAIR, there is a difference between how different mdelay/udelay are
implemented. One of them is using the loops_per_jiffie variable to
calculate the time, other uses clkevt device. I am not 100% sure about
the theory, but that's what I remember. So, have a look from that
perspective as well..
--
viresh
^ permalink raw reply [flat|nested] 16+ messages in thread
* about system time incorrect after changing cpu frequency
@ 2015-09-01 7:42 ` Viresh Kumar
0 siblings, 0 replies; 16+ messages in thread
From: Viresh Kumar @ 2015-09-01 7:42 UTC (permalink / raw)
To: linux-arm-kernel
On 01-09-15, 15:21, vichy wrote:
> 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);
In earlier versions of kernel, this had a problem that it works only
for ONESHOT mode and simply returns in PERIODIC mode. I do see that
your's mode is ONESHOT only, and so it should have worked.
Anyway, few prints into that routine to see where we are reaching
might help.
> __clocksource_updatefreq_hz(>_clocksource, gt_clk_rate);
AFAIR, there is a difference between how different mdelay/udelay are
implemented. One of them is using the loops_per_jiffie variable to
calculate the time, other uses clkevt device. I am not 100% sure about
the theory, but that's what I remember. So, have a look from that
perspective as well..
--
viresh
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2015-09-01 7:42 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-31 14:03 about system time incorrect after changing cpu frequency vichy
2015-08-31 14:03 ` vichy
2015-09-01 3:57 ` Viresh Kumar
2015-09-01 3:57 ` Viresh Kumar
2015-09-01 5:36 ` vichy
2015-09-01 5:36 ` vichy
2015-09-01 6:02 ` Viresh Kumar
2015-09-01 6:02 ` Viresh Kumar
2015-09-01 6:39 ` Jisheng Zhang
2015-09-01 6:39 ` Jisheng Zhang
2015-09-01 7:37 ` vichy
2015-09-01 7:37 ` vichy
2015-09-01 7:21 ` vichy
2015-09-01 7:21 ` vichy
2015-09-01 7:42 ` Viresh Kumar
2015-09-01 7:42 ` Viresh Kumar
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.