diff options
| -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 | } |
