From: "Heiko Stübner" <heiko@sntech.de>
To: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Jamie Iles <jamie@jamieiles.com>,
Dinh Nguyen <dinguyen@altera.com>,
Grant Likely <grant.likely@linaro.org>,
linux-arm-kernel@lists.infradead.org,
Rob Herring <rob.herring@calxeda.com>,
devicetree-discuss@lists.ozlabs.org,
linux-kernel@vger.kernel.org, Arnd Bergmann <arnd@arndb.de>,
Olof Johansson <olof@lixom.net>,
Ulrich Prinz <ulrich.prinz@googlemail.com>
Subject: [PATCH 3/9] clocksource: dw_apb_timer: quirk for variants with 64bit counter
Date: Sat, 6 Jul 2013 00:53:09 +0200 [thread overview]
Message-ID: <201307060053.10182.heiko@sntech.de> (raw)
In-Reply-To: <201307060051.09716.heiko@sntech.de>
This adds a quirk for IP variants containing two load_count and value
registers that are used to provide 64bit accuracy on 32bit systems.
The added accuracy is currently not used, the driver is only adapted to
handle the different register layout and make it work on affected devices.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/clocksource/dw_apb_timer.c | 27 +++++++++++++++++++++++++++
include/linux/dw_apb_timer.h | 6 ++++++
2 files changed, 33 insertions(+)
diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c
index f5e7be8..bd45351 100644
--- a/drivers/clocksource/dw_apb_timer.c
+++ b/drivers/clocksource/dw_apb_timer.c
@@ -56,6 +56,17 @@ static void apbt_init_regs(struct dw_apb_timer *timer, int quirks)
timer->reg_control = APBTMR_N_CONTROL;
timer->reg_eoi = APBTMR_N_EOI;
timer->reg_int_status = APBTMR_N_INT_STATUS;
+
+ /*
+ * On variants with 64bit counters some registers are
+ * moved further down.
+ */
+ if (quirks & APBTMR_QUIRK_64BIT_COUNTER) {
+ timer->reg_current_value += 0x4;
+ timer->reg_control += 0x8;
+ timer->reg_eoi += 0x8;
+ timer->reg_int_status += 0x8;
+ }
}
static unsigned long apbt_readl(struct dw_apb_timer *timer, unsigned long offs)
@@ -145,6 +156,10 @@ static void apbt_set_mode(enum clock_event_mode mode,
udelay(1);
pr_debug("Setting clock period %lu for HZ %d\n", period, HZ);
apbt_writel(timer, period, timer->reg_load_count);
+
+ if (timer->quirks & APBTMR_QUIRK_64BIT_COUNTER)
+ apbt_writel(timer, 0, timer->reg_load_count + 0x4);
+
ctrl |= APBTMR_CONTROL_ENABLE;
apbt_writel(timer, ctrl, timer->reg_control);
break;
@@ -168,6 +183,10 @@ static void apbt_set_mode(enum clock_event_mode mode,
* running mode.
*/
apbt_writel(timer, ~0, timer->reg_load_count);
+
+ if (timer->quirks & APBTMR_QUIRK_64BIT_COUNTER)
+ apbt_writel(timer, 0, timer->reg_load_count + 0x4);
+
ctrl &= ~APBTMR_CONTROL_INT;
ctrl |= APBTMR_CONTROL_ENABLE;
apbt_writel(timer, ctrl, timer->reg_control);
@@ -199,6 +218,10 @@ static int apbt_next_event(unsigned long delta,
apbt_writel(timer, ctrl, timer->reg_control);
/* write new count */
apbt_writel(timer, delta, timer->reg_load_count);
+
+ if (timer->quirks & APBTMR_QUIRK_64BIT_COUNTER)
+ apbt_writel(timer, 0, timer->reg_load_count + 0x4);
+
ctrl |= APBTMR_CONTROL_ENABLE;
apbt_writel(timer, ctrl, timer->reg_control);
@@ -325,6 +348,10 @@ void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs)
ctrl &= ~APBTMR_CONTROL_ENABLE;
apbt_writel(timer, ctrl, timer->reg_control);
apbt_writel(timer, ~0, timer->reg_load_count);
+
+ if (timer->quirks & APBTMR_QUIRK_64BIT_COUNTER)
+ apbt_writel(timer, 0, timer->reg_load_count + 0x4);
+
/* enable, mask interrupt */
ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
diff --git a/include/linux/dw_apb_timer.h b/include/linux/dw_apb_timer.h
index 7dc7166..80f6686 100644
--- a/include/linux/dw_apb_timer.h
+++ b/include/linux/dw_apb_timer.h
@@ -19,6 +19,12 @@
#define APBTMRS_REG_SIZE 0x14
+/* The IP uses two registers for count and values, to provide 64bit accuracy
+ * on 32bit platforms. The additional registers move the following registers
+ * down by 0x8 byte, as both the count and value registers are duplicated.
+ */
+#define APBTMR_QUIRK_64BIT_COUNTER BIT(0)
+
struct dw_apb_timer {
void __iomem *base;
unsigned long freq;
--
1.7.10.4
next prev parent reply other threads:[~2013-07-05 22:53 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-05 22:51 [PATCH 0/9] clocksource: dw_apb_timer: support for timer variant used in rk3188 SoCs Heiko Stübner
2013-07-05 22:51 ` [PATCH 1/9] clocksource: dw_apb_timer: infrastructure to handle quirks Heiko Stübner
2013-07-05 22:52 ` [PATCH 2/9] clocksource: dw_apb_timer: flexible register addresses Heiko Stübner
2013-07-05 22:53 ` Heiko Stübner [this message]
[not found] ` <201307060053.10182.heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2013-07-05 23:45 ` [PATCH 3/9] clocksource: dw_apb_timer: quirk for variants with 64bit counter Thomas Gleixner
2013-07-06 20:19 ` Ulrich Prinz
2013-07-05 22:53 ` [PATCH 4/9] clocksource: dw_apb_timer: use the eoi callback to clear pending interrupts Heiko Stübner
2013-07-05 22:59 ` Heiko Stübner
2013-07-05 22:54 ` [PATCH 5/9] clocksource: dw_apb_timer: quirk for variants without EOI register Heiko Stübner
[not found] ` <201307060054.07784.heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2013-07-05 22:58 ` Heiko Stübner
2013-07-05 23:49 ` Thomas Gleixner
2013-07-05 22:54 ` [PATCH 6/9] clocksource: dw_apb_timer: quirk for inverted int mask Heiko Stübner
2013-07-05 22:58 ` Heiko Stübner
[not found] ` <201307060054.35996.heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2013-07-05 23:51 ` Thomas Gleixner
[not found] ` <201307060051.09716.heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2013-07-05 22:55 ` [PATCH 7/9] clocksource: dw_apb_timer: quirk for inverted timer mode setting Heiko Stübner
2013-07-05 22:56 ` [PATCH 8/9] clocksource: dw_apb_timer_of: add quirk handling Heiko Stübner
2013-07-05 22:56 ` [PATCH 9/9] clocksource: dw_apb_timer: special variant for rockchip rk3188 timers Heiko Stübner
[not found] ` <201307060056.29370.heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2013-07-06 0:12 ` Thomas Gleixner
2013-07-06 20:28 ` Ulrich Prinz
[not found] ` <51D87E04.3060704-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
2013-07-06 21:00 ` Thomas Gleixner
2013-07-11 22:44 ` Ulrich Prinz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201307060053.10182.heiko@sntech.de \
--to=heiko@sntech.de \
--cc=arnd@arndb.de \
--cc=devicetree-discuss@lists.ozlabs.org \
--cc=dinguyen@altera.com \
--cc=grant.likely@linaro.org \
--cc=jamie@jamieiles.com \
--cc=john.stultz@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=olof@lixom.net \
--cc=rob.herring@calxeda.com \
--cc=tglx@linutronix.de \
--cc=ulrich.prinz@googlemail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).