Commit 1da0c89c66753860ccfe81eb327c25db46c2a24a
1 parent
f06a162462
Exists in
master
and in
39 other branches
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
arch/arm/Kconfig
... | ... | @@ -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
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 | } |