From patchwork Thu Jun 2 09:35:30 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mattias Wallin X-Patchwork-Id: 1721 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:54:46 -0000 Delivered-To: patches@linaro.org Received: by 10.52.181.10 with SMTP id ds10cs359961vdc; Thu, 2 Jun 2011 02:35:41 -0700 (PDT) Received: by 10.213.19.6 with SMTP id y6mr2323942eba.122.1307007340668; Thu, 02 Jun 2011 02:35:40 -0700 (PDT) Received: from eu1sys200aog102.obsmtp.com (eu1sys200aog102.obsmtp.com [207.126.144.113]) by mx.google.com with SMTP id c1si1057086eei.93.2011.06.02.02.35.35 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 02 Jun 2011 02:35:40 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.113 is neither permitted nor denied by best guess record for domain of mattias.wallin@stericsson.com) client-ip=207.126.144.113; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.113 is neither permitted nor denied by best guess record for domain of mattias.wallin@stericsson.com) smtp.mail=mattias.wallin@stericsson.com Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob102.postini.com ([207.126.147.11]) with SMTP ID DSNKTedZZ3A5l6cc8Al8Bdf491q/Q5l+gQgL@postini.com; Thu, 02 Jun 2011 09:35:40 UTC Received: from zeta.dmz-eu.st.com (ns2.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id CCC26108; Thu, 2 Jun 2011 09:35:34 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 777B21C88; Thu, 2 Jun 2011 09:35:34 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id D8D6624C075; Thu, 2 Jun 2011 11:35:28 +0200 (CEST) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Thu, 2 Jun 2011 11:35:33 +0200 From: Mattias Wallin To: Thomas Gleixner , , Cc: Lee Jones , Mattias Wallin Subject: [PATCHv2 2/3] clocksource: add DB8500 PRCMU Timer support Date: Thu, 2 Jun 2011 11:35:30 +0200 Message-ID: <1307007330-1113-1-git-send-email-mattias.wallin@stericsson.com> X-Mailer: git-send-email 1.7.5.1 MIME-Version: 1.0 The DB8500 PRCMU Timer is a low resolution timer (32KHz) but have the advantage of beeing always on. I.e continue to count in all cpuidle sleep states. To be able to alternate between another sched_clk driver an config option is added to be able to remove the sched_clk part. Signed-off-by: Mattias Wallin Acked-by: Linus Walleij --- drivers/clocksource/Kconfig | 15 +++++ drivers/clocksource/Makefile | 1 + drivers/clocksource/clksrc-db8500-prcmu.c | 90 +++++++++++++++++++++++++++++ include/linux/clksrc-db8500-prcmu.h | 17 ++++++ 4 files changed, 123 insertions(+), 0 deletions(-) create mode 100644 drivers/clocksource/clksrc-db8500-prcmu.c create mode 100644 include/linux/clksrc-db8500-prcmu.h diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 96c9219..d7ee415 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -3,3 +3,18 @@ config CLKSRC_I8253 config CLKSRC_MMIO bool + +config CLKSRC_DB8500_PRCMU + bool "Clocksource PRCMU Timer" + depends on MFD_DB8500_PRCMU + default y + help + Use the always on PRCMU Timer as clocksource + +config CLKSRC_DB8500_PRCMU_SCHED_CLOCK + bool "Clocksource PRCMU Timer sched_clock" + depends on (CLKSRC_DB8500_PRCMU && !NOMADIK_MTU_SCHED_CLOCK) + select HAVE_SCHED_CLOCK + default y + help + Use the always on PRCMU Timer as sched_clock diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index b995942..f2308ba 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o obj-$(CONFIG_CLKSRC_I8253) += i8253.o obj-$(CONFIG_CLKSRC_MMIO) += mmio.o +obj-$(CONFIG_CLKSRC_DB8500_PRCMU) += clksrc-db8500-prcmu.o diff --git a/drivers/clocksource/clksrc-db8500-prcmu.c b/drivers/clocksource/clksrc-db8500-prcmu.c new file mode 100644 index 0000000..f18973d --- /dev/null +++ b/drivers/clocksource/clksrc-db8500-prcmu.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + * Author: Mattias Wallin for ST-Ericsson + * sched_clock implementation is based on: + * plat-nomadik/timer.c Linus Walleij + * + * Clocksource DB8500 PRCMU Timer + * The PRCMU in the DB8500 chip has 5 timers which + * are available in an always-on power domain. + * Timer 4 is dedicated to our always-on clock source. + */ +#include +#include +#include +#include +#include +#include + +#define RATE_32K (32768) + +#define TIMER_MODE_CONTINOUS (0x1) +#define TIMER_DOWNCOUNT_VAL (0xffffffff) + +/* PRCMU Timer 4 */ +#define PRCMU_TIMER_4_REF (prcmu_base + 0x450) +#define PRCMU_TIMER_4_DOWNCOUNT (prcmu_base + 0x454) +#define PRCMU_TIMER_4_MODE (prcmu_base + 0x458) + +static __iomem void *prcmu_base; + +#define SCHED_CLOCK_MIN_WRAP (131072) /* 2^32 / 32768 */ + +/* + * We read the timer twice to make sure the value is stable. + * Timer glitches will otherwise occur when reading during a transition. + */ +static cycle_t clksrc_db8500_prcmu_read(struct clocksource *cs) +{ + u32 count, count2; + + do { + count = readl(PRCMU_TIMER_4_DOWNCOUNT); + count2 = readl(PRCMU_TIMER_4_DOWNCOUNT); + } while (count2 != count); + + /* Negate because the timer is a decrementing counter */ + return ~count; +} + +static struct clocksource clocksource_db8500_prcmu = { + .name = "clksrc-db8500-prcmu-timer4", + .rating = 300, + .read = clksrc_db8500_prcmu_read, + .shift = 10, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +#ifdef CONFIG_CLKSRC_DB8500_PRCMU_SCHED_CLOCK +static DEFINE_CLOCK_DATA(cd); + +static void notrace clksrc_db8500_prcmu_update_sched_clock(void) +{ + u32 cyc = clksrc_db8500_prcmu_read(&clocksource_db8500_prcmu); + update_sched_clock(&cd, cyc, (u32)~0); +} +#endif + +void __init clksrc_db8500_prcmu_init(void) +{ + prcmu_base = __io_address(U8500_PRCMU_BASE); + + /* + * The A9 sub system expects the timer to be configured as + * a continous looping timer. + * The PRCMU should configure it but if it for some reason + * don't we do it here. + */ + if (readl(PRCMU_TIMER_4_MODE) != TIMER_MODE_CONTINOUS) { + writel(TIMER_MODE_CONTINOUS, PRCMU_TIMER_4_MODE); + writel(TIMER_DOWNCOUNT_VAL, PRCMU_TIMER_4_REF); + } +#ifdef CONFIG_CLKSRC_DB8500_PRCMU_SCHED_CLOCK + init_sched_clock(&cd, clksrc_db8500_prcmu_update_sched_clock, + 32, RATE_32K); +#endif + clocksource_register_hz(&clocksource_db8500_prcmu, RATE_32K); +} diff --git a/include/linux/clksrc-db8500-prcmu.h b/include/linux/clksrc-db8500-prcmu.h new file mode 100644 index 0000000..42b8587 --- /dev/null +++ b/include/linux/clksrc-db8500-prcmu.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * License Terms: GNU General Public License v2 + * Author: Mattias Wallin + * + */ +#ifndef __CLKSRC_DB8500_PRCMU_H +#define __CLKSRC_DB8500_PRCMU_H + +#ifdef CONFIG_CLKSRC_DB8500_PRCMU +void __init clksrc_db8500_prcmu_init(void); +#else +void __init clksrc_db8500_prcmu_init(void) {} +#endif + +#endif