diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2011-09-27 11:04:33 +0530 |
---|---|---|
committer | Rabin VINCENT <rabin.vincent@stericsson.com> | 2011-10-28 05:03:33 +0200 |
commit | c03e09ea5245e207b581a4b44016f0e989e56e33 (patch) | |
tree | d39e7766d763ea40d11aec1cd4cb3dbd07e93d18 | |
parent | 83f9d2918ef0c8da5e0b07fc83e3da83cf3f7cd8 (diff) |
u5500: add MTIMER clocksource
ST-Ericsson ID: 368260
ST-Ericsson Linux next: NA
ST-Ericsson FOSS-OUT ID: Trivial
Depends-On: I5307cb7f58fdf890896d641a8e4f49098a90b68e
Change-Id: I9ef4ff1c63f6ec9293ece4013f13cf3caa707d9d
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/34307
Reviewed-by: QATOOLS
Reviewed-by: QABUILD
-rw-r--r-- | arch/arm/mach-ux500/cpu-db5500.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/db5500-regs.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-ux500/timer.c | 11 | ||||
-rw-r--r-- | drivers/clocksource/Kconfig | 21 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 1 | ||||
-rw-r--r-- | drivers/clocksource/db5500-mtimer.c | 52 | ||||
-rw-r--r-- | include/linux/clksrc-db5500-mtimer.h | 17 |
7 files changed, 100 insertions, 4 deletions
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 9518c6db7f7..ea4fbbb1fc6 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -41,6 +41,7 @@ static struct map_desc u5500_io_desc[] __initdata = { __IO_DEV_DESC(U5500_MTU1_BASE, SZ_4K), __IO_DEV_DESC(U5500_SCU_BASE, SZ_4K), __IO_DEV_DESC(U5500_RTC_BASE, SZ_4K), + __IO_DEV_DESC(U5500_MTIMER_BASE, SZ_4K), __IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K), __MEM_DEV_DESC(U5500_BOOT_ROM_BASE, SZ_1M), diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h index 870c3ff574c..f853c20587a 100644 --- a/arch/arm/mach-ux500/include/mach/db5500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h @@ -66,6 +66,7 @@ #define U5500_PRCMU_TIMER_4_BASE (U5500_PER4_BASE + 0x07450) #define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000) #define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000) +#define U5500_MTIMER_BASE (U5500_PER4_BASE + 0xC000) #define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000) #define U5500_PRCMU_TCDM_BASE (U5500_PER4_BASE + 0x18000) #define U5500_PRCMU_TCPM_BASE (U5500_PER4_BASE + 0x10000) diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c index c395f5c8992..df1945b1991 100644 --- a/arch/arm/mach-ux500/timer.c +++ b/arch/arm/mach-ux500/timer.c @@ -7,6 +7,7 @@ #include <linux/io.h> #include <linux/errno.h> #include <linux/clksrc-dbx500-prcmu.h> +#include <linux/clksrc-db5500-mtimer.h> #include <asm/localtimer.h> @@ -67,12 +68,18 @@ static void __init ux500_timer_init(void) * depending on delay which is not yet calibrated. RTC-RTT is in the * always-on powerdomain and is used as clockevent instead of twd when * sleeping. - * The PRCMU timer 4(3 for DB5500) register a clocksource and - * sched_clock with higher rating then MTU since is always-on. * + * The PRCMU timer 4 (3 for DB5500) registers a clocksource and + * sched_clock with higher rating than the MTU since it is + * always-on. + * + * On DB5500, the MTIMER is the best clocksource since, unlike the + * PRCMU timer, it doesn't occasionally go backwards. */ nmdk_timer_init(); + if (cpu_is_u5500()) + db5500_mtimer_init(__io_address(U5500_MTIMER_BASE)); clksrc_dbx500_prcmu_init(prcmu_timer_base); #ifdef CONFIG_UX500_CONTEXT diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 206f35f7d8c..75935af43f2 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -7,13 +7,30 @@ config CLKSRC_MMIO config CLKSRC_DBX500_PRCMU bool "Clocksource PRCMU Timer" depends on UX500_SOC_DB5500 || UX500_SOC_DB8500 - default y + default y if UX500_SOC_DB8500 help Use the always on PRCMU Timer as clocksource config CLKSRC_DBX500_PRCMU_SCHED_CLOCK bool "Clocksource PRCMU Timer sched_clock" - depends on (CLKSRC_DBX500_PRCMU && !NOMADIK_MTU_SCHED_CLOCK) + depends on (CLKSRC_DBX500_PRCMU && !NOMADIK_MTU_SCHED_CLOCK && \ + !CLKSRC_DB5500_MTIMER_SCHED_CLOCK) + select HAVE_SCHED_CLOCK + default y + help + Use the always on PRCMU Timer as sched_clock + +config CLKSRC_DB5500_MTIMER + bool "Clocksource MTIMER" + depends on UX500_SOC_DB5500 + default y + help + Use the always on MTIMER as clocksource + +config CLKSRC_DB5500_MTIMER_SCHED_CLOCK + bool "Clocksource MTIMER sched_clock" + depends on (CLKSRC_DB5500_MTIMER && !NOMADIK_MTU_SCHED_CLOCK && \ + !CLKSRC_DBX500_PRCMU_SCHED_CLOCK) select HAVE_SCHED_CLOCK default y help diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 285e9a3a61f..027e71d6d05 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o obj-$(CONFIG_CLKSRC_I8253) += i8253.o obj-$(CONFIG_CLKSRC_MMIO) += mmio.o obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o +obj-$(CONFIG_CLKSRC_DB5500_MTIMER) += db5500-mtimer.o diff --git a/drivers/clocksource/db5500-mtimer.c b/drivers/clocksource/db5500-mtimer.c new file mode 100644 index 00000000000..641279707a8 --- /dev/null +++ b/drivers/clocksource/db5500-mtimer.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + */ + +#include <linux/io.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/clockchips.h> +#include <linux/clksrc-db5500-mtimer.h> + +#include <asm/sched_clock.h> + +#define MTIMER_PRIMARY_COUNTER 0x18 + +static void __iomem *db5500_mtimer_base; + +#ifdef CONFIG_CLKSRC_DB5500_MTIMER_SCHED_CLOCK +static DEFINE_CLOCK_DATA(cd); + +unsigned long long notrace sched_clock(void) +{ + u32 cyc; + + if (unlikely(!db5500_mtimer_base)) + return 0; + + cyc = readl_relaxed(db5500_mtimer_base + MTIMER_PRIMARY_COUNTER); + + return cyc_to_sched_clock(&cd, cyc, (u32)~0); +} + +static void notrace db5500_mtimer_update_sched_clock(void) +{ + u32 cyc = readl_relaxed(db5500_mtimer_base + MTIMER_PRIMARY_COUNTER); + update_sched_clock(&cd, cyc, (u32)~0); +} +#endif + +void __init db5500_mtimer_init(void __iomem *base) +{ + db5500_mtimer_base = base; + + clocksource_mmio_init(base + MTIMER_PRIMARY_COUNTER, "mtimer", 32768, + 400, 32, clocksource_mmio_readl_up); + +#ifdef CONFIG_CLKSRC_DB5500_MTIMER_SCHED_CLOCK + init_sched_clock(&cd, db5500_mtimer_update_sched_clock, + 32, 32768); +#endif +} diff --git a/include/linux/clksrc-db5500-mtimer.h b/include/linux/clksrc-db5500-mtimer.h new file mode 100644 index 00000000000..3112c7f2709 --- /dev/null +++ b/include/linux/clksrc-db5500-mtimer.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + */ +#ifndef __CLKSRC_DB5500_MTIMER_H +#define __CLKSRC_DB5500_MTIMER_H + +#include <linux/io.h> + +#ifdef CONFIG_CLKSRC_DB5500_MTIMER +void db5500_mtimer_init(void __iomem *base); +#else +static inline void db5500_mtimer_init(void __iomem *base) {} +#endif + +#endif |