All of lore.kernel.org
 help / color / mirror / Atom feed
* 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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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(&gt_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.