diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-15 16:56:47 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-22 17:44:50 -0500 |
commit | 1da0c89c66753860ccfe81eb327c25db46c2a24a (patch) | |
tree | 565710dc2a57dca18a17d3e34465485f32191b81 /arch/arm | |
parent | f06a1624621527ef597ae4b3b795553fc1b2eff2 (diff) |
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>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-realview/core.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-versatile/core.c | 10 | ||||
-rw-r--r-- | arch/arm/plat-versatile/include/plat/sched_clock.h | 6 | ||||
-rw-r--r-- | arch/arm/plat-versatile/sched-clock.c | 48 |
5 files changed, 54 insertions, 22 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92e8c0174dd0..34311f40d713 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -236,6 +236,7 @@ config ARCH_REALVIEW | |||
236 | bool "ARM Ltd. RealView family" | 236 | bool "ARM Ltd. RealView family" |
237 | select ARM_AMBA | 237 | select ARM_AMBA |
238 | select COMMON_CLKDEV | 238 | select COMMON_CLKDEV |
239 | select HAVE_SCHED_CLOCK | ||
239 | select ICST | 240 | select ICST |
240 | select GENERIC_CLOCKEVENTS | 241 | select GENERIC_CLOCKEVENTS |
241 | select ARCH_WANT_OPTIONAL_GPIOLIB | 242 | select ARCH_WANT_OPTIONAL_GPIOLIB |
@@ -250,6 +251,7 @@ config ARCH_VERSATILE | |||
250 | select ARM_AMBA | 251 | select ARM_AMBA |
251 | select ARM_VIC | 252 | select ARM_VIC |
252 | select COMMON_CLKDEV | 253 | select COMMON_CLKDEV |
254 | select HAVE_SCHED_CLOCK | ||
253 | select ICST | 255 | select ICST |
254 | select GENERIC_CLOCKEVENTS | 256 | select GENERIC_CLOCKEVENTS |
255 | select ARCH_WANT_OPTIONAL_GPIOLIB | 257 | select ARCH_WANT_OPTIONAL_GPIOLIB |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 07c08151dfe6..3d653e05b75d 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <mach/irqs.h> | 52 | #include <mach/irqs.h> |
53 | #include <plat/timer-sp.h> | 53 | #include <plat/timer-sp.h> |
54 | 54 | ||
55 | #include <plat/sched_clock.h> | ||
56 | |||
55 | #include "core.h" | 57 | #include "core.h" |
56 | 58 | ||
57 | /* used by entry-macro.S and platsmp.c */ | 59 | /* used by entry-macro.S and platsmp.c */ |
@@ -658,6 +660,12 @@ void realview_leds_event(led_event_t ledevt) | |||
658 | #endif /* CONFIG_LEDS */ | 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 | * Where is the timer (VA)? | 669 | * Where is the timer (VA)? |
662 | */ | 670 | */ |
663 | void __iomem *timer0_va_base; | 671 | void __iomem *timer0_va_base; |
@@ -672,6 +680,8 @@ void __init realview_timer_init(unsigned int timer_irq) | |||
672 | { | 680 | { |
673 | u32 val; | 681 | u32 val; |
674 | 682 | ||
683 | versatile_sched_clock_init(REFCOUNTER, 24000000); | ||
684 | |||
675 | /* | 685 | /* |
676 | * set clock frequency: | 686 | * set clock frequency: |
677 | * REALVIEW_REFCLK is 32KHz | 687 | * REALVIEW_REFCLK is 32KHz |
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index e38acb0f89c8..56cdc2257424 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -51,6 +51,8 @@ | |||
51 | #include <mach/platform.h> | 51 | #include <mach/platform.h> |
52 | #include <plat/timer-sp.h> | 52 | #include <plat/timer-sp.h> |
53 | 53 | ||
54 | #include <plat/sched_clock.h> | ||
55 | |||
54 | #include "core.h" | 56 | #include "core.h" |
55 | 57 | ||
56 | /* | 58 | /* |
@@ -886,6 +888,12 @@ void __init versatile_init(void) | |||
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 | * Where is the timer (VA)? | 897 | * Where is the timer (VA)? |
890 | */ | 898 | */ |
891 | #define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE) | 899 | #define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE) |
@@ -900,6 +908,8 @@ static void __init versatile_timer_init(void) | |||
900 | { | 908 | { |
901 | u32 val; | 909 | u32 val; |
902 | 910 | ||
911 | versatile_sched_clock_init(REFCOUNTER, 24000000); | ||
912 | |||
903 | /* | 913 | /* |
904 | * set clock frequency: | 914 | * set clock frequency: |
905 | * VERSATILE_REFCLK is 32KHz | 915 | * VERSATILE_REFCLK is 32KHz |
diff --git a/arch/arm/plat-versatile/include/plat/sched_clock.h b/arch/arm/plat-versatile/include/plat/sched_clock.h new file mode 100644 index 000000000000..5c3e4fc9fa0c --- /dev/null +++ b/arch/arm/plat-versatile/include/plat/sched_clock.h | |||
@@ -0,0 +1,6 @@ | |||
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 | ||
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c index 42efd14ed4b3..3d6a4c292cab 100644 --- a/arch/arm/plat-versatile/sched-clock.c +++ b/arch/arm/plat-versatile/sched-clock.c | |||
@@ -18,37 +18,41 @@ | |||
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | #include <linux/cnt32_to_63.h> | ||
22 | #include <linux/io.h> | 21 | #include <linux/io.h> |
23 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
24 | #include <asm/div64.h> | ||
25 | 23 | ||
26 | #include <mach/hardware.h> | 24 | #include <asm/sched_clock.h> |
27 | #include <mach/platform.h> | 25 | #include <plat/sched_clock.h> |
28 | 26 | ||
29 | #ifdef VERSATILE_SYS_BASE | 27 | static DEFINE_CLOCK_DATA(cd); |
30 | #define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET) | 28 | static void __iomem *ctr; |
31 | #endif | ||
32 | |||
33 | #ifdef REALVIEW_SYS_BASE | ||
34 | #define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET) | ||
35 | #endif | ||
36 | 29 | ||
37 | /* | 30 | /* |
38 | * This is the Realview and Versatile sched_clock implementation. This | 31 | * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60). |
39 | * has a resolution of 41.7ns, and a maximum value of about 35583 days. | 32 | * This gives a resolution of about 41ns and a wrap period of about 178s. |
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. | ||
44 | */ | 33 | */ |
34 | #define SC_MULT 2796202667u | ||
35 | #define SC_SHIFT 26 | ||
36 | |||
45 | unsigned long long notrace sched_clock(void) | 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 */ | 47 | static void notrace versatile_update_sched_clock(void) |
50 | v *= 125<<1; | 48 | { |
51 | do_div(v, 3<<1); | 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 | } |