Commit 1da0c89c66753860ccfe81eb327c25db46c2a24a

Authored by Russell King
1 parent f06a162462

ARM: versatile: convert sched_clock() to use new infrastructure

Convert versatile platforms to use the new sched_clock() infrastructure
for extending 32bit counters to full 64-bit nanoseconds.

Tested-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Showing 5 changed files with 54 additions and 22 deletions Side-by-side Diff

... ... @@ -236,6 +236,7 @@
236 236 bool "ARM Ltd. RealView family"
237 237 select ARM_AMBA
238 238 select COMMON_CLKDEV
  239 + select HAVE_SCHED_CLOCK
239 240 select ICST
240 241 select GENERIC_CLOCKEVENTS
241 242 select ARCH_WANT_OPTIONAL_GPIOLIB
... ... @@ -250,6 +251,7 @@
250 251 select ARM_AMBA
251 252 select ARM_VIC
252 253 select COMMON_CLKDEV
  254 + select HAVE_SCHED_CLOCK
253 255 select ICST
254 256 select GENERIC_CLOCKEVENTS
255 257 select ARCH_WANT_OPTIONAL_GPIOLIB
arch/arm/mach-realview/core.c
... ... @@ -52,6 +52,8 @@
52 52 #include <mach/irqs.h>
53 53 #include <plat/timer-sp.h>
54 54  
  55 +#include <plat/sched_clock.h>
  56 +
55 57 #include "core.h"
56 58  
57 59 /* used by entry-macro.S and platsmp.c */
... ... @@ -658,6 +660,12 @@
658 660 #endif /* CONFIG_LEDS */
659 661  
660 662 /*
  663 + * The sched_clock counter
  664 + */
  665 +#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + \
  666 + REALVIEW_SYS_24MHz_OFFSET)
  667 +
  668 +/*
661 669 * Where is the timer (VA)?
662 670 */
663 671 void __iomem *timer0_va_base;
... ... @@ -671,6 +679,8 @@
671 679 void __init realview_timer_init(unsigned int timer_irq)
672 680 {
673 681 u32 val;
  682 +
  683 + versatile_sched_clock_init(REFCOUNTER, 24000000);
674 684  
675 685 /*
676 686 * set clock frequency:
arch/arm/mach-versatile/core.c
... ... @@ -51,6 +51,8 @@
51 51 #include <mach/platform.h>
52 52 #include <plat/timer-sp.h>
53 53  
  54 +#include <plat/sched_clock.h>
  55 +
54 56 #include "core.h"
55 57  
56 58 /*
... ... @@ -886,6 +888,12 @@
886 888 }
887 889  
888 890 /*
  891 + * The sched_clock counter
  892 + */
  893 +#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + \
  894 + VERSATILE_SYS_24MHz_OFFSET)
  895 +
  896 +/*
889 897 * Where is the timer (VA)?
890 898 */
891 899 #define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE)
... ... @@ -899,6 +907,8 @@
899 907 static void __init versatile_timer_init(void)
900 908 {
901 909 u32 val;
  910 +
  911 + versatile_sched_clock_init(REFCOUNTER, 24000000);
902 912  
903 913 /*
904 914 * set clock frequency:
arch/arm/plat-versatile/include/plat/sched_clock.h
  1 +#ifndef ARM_PLAT_SCHED_CLOCK_H
  2 +#define ARM_PLAT_SCHED_CLOCK_H
  3 +
  4 +void versatile_sched_clock_init(void __iomem *, unsigned long);
  5 +
  6 +#endif
arch/arm/plat-versatile/sched-clock.c
... ... @@ -18,38 +18,42 @@
18 18 * along with this program; if not, write to the Free Software
19 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 20 */
21   -#include <linux/cnt32_to_63.h>
22 21 #include <linux/io.h>
23 22 #include <linux/sched.h>
24   -#include <asm/div64.h>
25 23  
26   -#include <mach/hardware.h>
27   -#include <mach/platform.h>
  24 +#include <asm/sched_clock.h>
  25 +#include <plat/sched_clock.h>
28 26  
29   -#ifdef VERSATILE_SYS_BASE
30   -#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
31   -#endif
  27 +static DEFINE_CLOCK_DATA(cd);
  28 +static void __iomem *ctr;
32 29  
33   -#ifdef REALVIEW_SYS_BASE
34   -#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
35   -#endif
36   -
37 30 /*
38   - * This is the Realview and Versatile sched_clock implementation. This
39   - * has a resolution of 41.7ns, and a maximum value of about 35583 days.
40   - *
41   - * The return value is guaranteed to be monotonic in that range as
42   - * long as there is always less than 89 seconds between successive
43   - * calls to this function.
  31 + * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60).
  32 + * This gives a resolution of about 41ns and a wrap period of about 178s.
44 33 */
  34 +#define SC_MULT 2796202667u
  35 +#define SC_SHIFT 26
  36 +
45 37 unsigned long long notrace sched_clock(void)
46 38 {
47   - unsigned long long v = cnt32_to_63(readl(REFCOUNTER));
  39 + if (ctr) {
  40 + u32 cyc = readl(ctr);
  41 + return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0,
  42 + SC_MULT, SC_SHIFT);
  43 + } else
  44 + return 0;
  45 +}
48 46  
49   - /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
50   - v *= 125<<1;
51   - do_div(v, 3<<1);
  47 +static void notrace versatile_update_sched_clock(void)
  48 +{
  49 + u32 cyc = readl(ctr);
  50 + update_sched_clock(&cd, cyc, (u32)~0);
  51 +}
52 52  
53   - return v;
  53 +void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
  54 +{
  55 + ctr = reg;
  56 + init_fixed_sched_clock(&cd, versatile_update_sched_clock,
  57 + 32, rate, SC_MULT, SC_SHIFT);
54 58 }