linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: zoss@devai.org (Zoltan Devai)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 3/5] ARM: SPMP8000: Add clocksource and clockevent drivers
Date: Wed, 19 Oct 2011 18:01:56 +0200	[thread overview]
Message-ID: <1319040118-29773-4-git-send-email-zoss@devai.org> (raw)
In-Reply-To: <1319040118-29773-1-git-send-email-zoss@devai.org>

This adds a clocksource and clockevent for the SPMP8000 machine.

Cc: John Stultz <johnstul@us.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Zoltan Devai <zoss@devai.org>
---
 drivers/clocksource/Makefile        |    3 +-
 drivers/clocksource/spmp8000_tmrb.c |  159 +++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 1 deletions(-)
 create mode 100644 drivers/clocksource/spmp8000_tmrb.c

diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 8d81a1d..adb575e 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -9,4 +9,5 @@ obj-$(CONFIG_SH_TIMER_TMU)	+= sh_tmu.o
 obj-$(CONFIG_CLKBLD_I8253)	+= i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
 obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
-obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
\ No newline at end of file
+obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
+obj-$(CONFIG_ARCH_SPMP8000)	+= spmp8000_tmrb.o
diff --git a/drivers/clocksource/spmp8000_tmrb.c b/drivers/clocksource/spmp8000_tmrb.c
new file mode 100644
index 0000000..8c0f042
--- /dev/null
+++ b/drivers/clocksource/spmp8000_tmrb.c
@@ -0,0 +1,159 @@
+/*
+ * SPMP8000 machines timer functions
+ *
+ * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <asm/mach/time.h>
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+/* Timer constraints:
+ * - WDT: Can't clear the irq directly, only by resetting the whole counter
+ *   in the ISR, which means that IRQs will jitter
+ * - Timer_B: Can't reset the timer value, so at start, the first IRQ
+ *   will happen at some random time.
+ */
+#define SPMP8000_TMRB(tnum)	(tnum * 0x20)
+#define SPMP8000_TMRB_CTR	0x00
+#define SPMP8000_TMRB_CTR_TE	BIT(0)
+#define SPMP8000_TMRB_CTR_IE	BIT(1)
+#define SPMP8000_TMRB_CTR_OE	BIT(2)
+#define SPMP8000_TMRB_CTR_PWMON	BIT(3)
+#define SPMP8000_TMRB_CTR_UD	BIT(4)
+#define SPMP8000_TMRB_CTR_UDS	BIT(5)
+#define SPMP8000_TMRB_CTR_OM	BIT(6)
+#define SPMP8000_TMRB_CTR_ES_SH	8
+#define SPMP8000_TMRB_CTR_M_SH	10
+#define SPMP8000_TMRB_PSR	0x04
+#define SPMP8000_TMRB_LDR	0x08
+#define SPMP8000_TMRB_VLR	0x08
+#define SPMP8000_TMRB_ISR	0x0C
+#define SPMP8000_TMRB_CMP	0x10
+
+static unsigned long clkrate;
+static const unsigned int tickrate = 1012500;
+
+#define CS_TIMER	2
+#define CE_TIMER	1
+static void __iomem *cs_base;
+static void __iomem *ce_base;
+
+static void tmrb_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *dev)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		writel((tickrate / HZ), ce_base + SPMP8000_TMRB_LDR);
+		/* Configure as periodic, down counter, IEN, enable timer */
+		writel(SPMP8000_TMRB_CTR_TE | SPMP8000_TMRB_CTR_IE |
+				(1 << SPMP8000_TMRB_CTR_M_SH),
+				ce_base + SPMP8000_TMRB_CTR);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		/* Disable timer */
+		writel(0, ce_base + SPMP8000_TMRB_CTR);
+		break;
+	default:
+		BUG();
+		break;
+	}
+}
+
+static struct clock_event_device tmrb1_clkevt = {
+	.name		= "tmrb1",
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.rating		= 200,
+	.set_mode	= tmrb_set_mode,
+};
+
+static irqreturn_t tmrb1_isr(int irq, void *dev_id)
+{
+	tmrb1_clkevt.event_handler(&tmrb1_clkevt);
+
+	/* Clear IRQ */
+	writel(0, ce_base + SPMP8000_TMRB_ISR);
+
+	return IRQ_HANDLED;
+};
+
+static struct irqaction tmrb1_irq = {
+	.name		= "tmrb1_irq",
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= tmrb1_isr,
+};
+
+void __init spmp8000_sys_timer_init(void)
+{
+	struct device_node *np;
+	unsigned int irq;
+	void *tmrb_base;
+	const __be32 *prop;
+
+	np = of_find_compatible_node(NULL, NULL, "sunplus,spmp8000-timer");
+	if (!np)
+		panic("spmp8000: unable to find timer node in dtb\n");
+
+	tmrb_base = of_iomap(np, 0);
+	if (!tmrb_base)
+		panic("spmp8000: unable to map timer cpu registers\n");
+
+	irq = of_irq_to_resource(np, CE_TIMER, NULL);
+	if (irq == NO_IRQ)
+		panic("spmp8000: unable to get interrupts of timer\n");
+
+	prop = of_get_property(np, "clock-freq", NULL);
+	if (!prop)
+		panic("spmp8000: Can't get boot clock rate of timer\n");
+	clkrate = be32_to_cpup(prop);
+
+	of_node_put(np);
+
+	cs_base = tmrb_base + SPMP8000_TMRB(CS_TIMER);
+	ce_base = tmrb_base + SPMP8000_TMRB(CE_TIMER);
+
+	/* Clocksource */
+	/* Disable timer */
+	writel(0, cs_base + SPMP8000_TMRB_CTR);
+
+	/* Reset counter value
+	 * Not really possible unless setting end-1 LDR value and waiting
+	 * until the counter reaches that */
+
+	/* Prescale timer */
+	writel((clkrate / tickrate) - 1, cs_base + SPMP8000_TMRB_PSR);
+
+	/* Register the clocksource */
+	clocksource_mmio_init(cs_base + SPMP8000_TMRB_VLR, "tmrb2",
+				tickrate, 200, 16, clocksource_mmio_readl_up);
+
+	/* Configure as free running (0 - 0xFFFF), up counter, enable timer */
+	writel(SPMP8000_TMRB_CTR_TE | SPMP8000_TMRB_CTR_UD,
+		cs_base + SPMP8000_TMRB_CTR);
+
+	/* Clockevent */
+	setup_irq(irq, &tmrb1_irq);
+
+	/* Disable timer */
+	writel(0, ce_base + SPMP8000_TMRB_CTR);
+
+	/* Prescale timer */
+	writel((clkrate / tickrate) - 1, ce_base + SPMP8000_TMRB_PSR);
+
+	clockevents_register_device(&tmrb1_clkevt);
+}
-- 
1.7.4.1

  parent reply	other threads:[~2011-10-19 16:01 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-09 16:36 Add support for the SPMP8000 SoC and Letcool board Zoltan Devai
2011-10-09 16:36 ` [PATCH 1/9] ARM: vic: Don't write to the read-only register VIC_IRQ_STATUS Zoltan Devai
2011-10-10  1:35   ` Linus Walleij
2011-10-10 13:59     ` Zoltan Devai
2011-10-09 16:36 ` [PATCH 2/9] ARM: SPMP8000: Add machine base files Zoltan Devai
2011-10-09 17:22   ` Jamie Iles
2011-10-10 11:36     ` Zoltan Devai
2011-10-10 11:52       ` Jamie Iles
2011-10-11 14:44   ` Arnd Bergmann
2011-10-16 14:10     ` Zoltan Devai
2011-10-16 15:57       ` Russell King - ARM Linux
2011-10-16 20:59       ` Arnd Bergmann
2011-10-16 20:52         ` Jean-Christophe PLAGNIOL-VILLARD
2011-10-17 11:44           ` Arnd Bergmann
2011-10-09 16:36 ` [PATCH 3/9] ARM: SPMP8000: Add clk support Zoltan Devai
2011-10-13  9:38   ` Russell King - ARM Linux
2011-10-16 14:16     ` Zoltan Devai
2011-10-17 12:15       ` Mark Brown
2011-10-18 10:18         ` Russell King - ARM Linux
2011-10-09 16:36 ` [PATCH 4/9] ARM: SPMP8000: Add ADC driver Zoltan Devai
2011-10-10  1:29   ` Linus Walleij
2011-10-10  9:42     ` Jonathan Cameron
2011-10-10  9:46       ` Jonathan Cameron
2011-10-10 10:00       ` Mark Brown
2011-10-10 11:42         ` Zoltan Devai
2011-10-10 11:44           ` Mark Brown
2011-10-11 14:17             ` Arnd Bergmann
2011-10-11 14:40               ` Mark Brown
2011-10-11 15:24                 ` Arnd Bergmann
2011-10-11 15:39                   ` Jonathan Cameron
2011-10-12 14:42                   ` Mark Brown
2011-10-12 15:41                     ` Jonathan Cameron
2011-10-13  9:47             ` Russell King - ARM Linux
2011-10-13 11:09               ` Linus Walleij
2011-10-13 11:35                 ` Jonathan Cameron
2011-10-13 11:35               ` Mark Brown
2011-10-13 12:17                 ` Russell King - ARM Linux
2011-10-13 14:19                   ` Arnd Bergmann
2011-10-13 14:27                     ` Mark Brown
2011-10-13 14:38                   ` Mark Brown
2011-10-13 14:56                     ` Arnd Bergmann
2011-10-13 16:25                       ` Mark Brown
2011-10-09 16:36 ` [PATCH 5/9] ARM: SPMP8000: Add pinmux driver Zoltan Devai
2011-10-10  1:32   ` Linus Walleij
2011-10-10  8:01     ` Barry Song
2011-10-10  8:34       ` Linus Walleij
2011-10-09 16:36 ` [PATCH 6/9] ARM: SPMP8000: Add pwm driver Zoltan Devai
2011-10-10  1:50   ` Linus Walleij
2011-10-10  9:30     ` Sascha Hauer
2011-10-09 16:36 ` [PATCH 7/9] ARM: SPMP8000: Add dts file of SPMP8000 SoC and Letcool board Zoltan Devai
2011-10-10  8:54   ` Jamie Iles
2011-10-09 16:36 ` [PATCH 8/9] ARM: SPMP8000: Add support for the " Zoltan Devai
2011-10-11 14:09   ` Arnd Bergmann
2011-10-11 14:43     ` Zoltan Devai
2011-10-11 15:18       ` Arnd Bergmann
2011-10-13  9:54   ` Russell King - ARM Linux
2011-10-09 16:36 ` [PATCH 9/9] ARM: SPMP8000: Add Kconfig and Makefile entries to build the machine Zoltan Devai
2011-10-09 17:25   ` Jamie Iles
2011-10-10  1:43   ` Linus Walleij
2011-10-13  9:53   ` Russell King - ARM Linux
2011-10-10  8:55 ` Add support for the SPMP8000 SoC and Letcool board Jamie Iles
2011-10-10 12:00   ` Zoltan Devai
2011-10-10 12:03     ` Jamie Iles
2011-10-11 14:57 ` Arnd Bergmann
     [not found] ` <1319040118-29773-1-git-send-email-zoss@devai.org>
2011-10-19 16:01   ` [PATCH v2 1/5] ARM: SPMP8000: Add machine base files Zoltan Devai
2011-10-19 19:15     ` Arnd Bergmann
2011-10-21 22:54       ` Russell King - ARM Linux
2011-10-23 21:47         ` Zoltan Devai
2011-10-23 21:37       ` Zoltan Devai
2011-10-24  9:13         ` Arnd Bergmann
2011-10-24 11:00           ` Jamie Iles
2011-11-02 13:29             ` Zoltan Devai
2011-11-03 15:08               ` Arnd Bergmann
2011-10-19 16:01   ` [PATCH v2 2/5] ARM: SPMP8000: Add clk support Zoltan Devai
2011-10-19 16:01   ` Zoltan Devai [this message]
2011-10-19 16:01   ` [PATCH v2 4/5] ARM: SPMP8000: Add SPMP8000 SoC and Letcool board dts descriptions Zoltan Devai
2011-10-24 12:47     ` Rob Herring
2011-10-19 16:01   ` [PATCH v2 5/5] ARM: SPMP8000: Add Kconfig and Makefile entries Zoltan Devai

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=1319040118-29773-4-git-send-email-zoss@devai.org \
    --to=zoss@devai.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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).