All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greentime Hu <green.hu@gmail.com>
To: greentime@andestech.com, linux-kernel@vger.kernel.org,
	arnd@arndb.de, linux-arch@vger.kernel.org, tglx@linutronix.de,
	jason@lakedaemon.net, marc.zyngier@arm.com, robh+dt@kernel.org,
	netdev@vger.kernel.org, deanbo422@gmail.com,
	devicetree@vger.kernel.org, viro@zeniv.linux.org.uk,
	dhowells@redhat.com, will.deacon@arm.com,
	daniel.lezcano@linaro.org, linux-serial@vger.kernel.org
Cc: Rick Chen <rickchen36@gmail.com>, green.hu@gmail.com
Subject: [PATCH v2 33/35] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
Date: Mon, 27 Nov 2017 20:28:20 +0800	[thread overview]
Message-ID: <672e0b3843953d1ab69bc19baf1a0f217ec1b1fa.1511785528.git.green.hu@gmail.com> (raw)
In-Reply-To: <cover.1511785528.git.green.hu@gmail.com>
In-Reply-To: <cover.1511785528.git.green.hu@gmail.com>

From: Rick Chen <rickchen36@gmail.com>

ATCPIT100 is often used on the Andes architecture,
This timer provide 4 PIT channels. Each PIT channel is a
multi-function timer, can be configured as 32,16,8 bit timers
or PWM as well.

For system timer it will set channel 1 32-bit timer0 as clock
source and count downwards until underflow and restart again.

It also set channel 0 32-bit timer0 as clock event and count
downwards until condition match. It will generate an interrupt
for handling periodically.

Signed-off-by: Rick Chen <rickchen36@gmail.com>
Signed-off-by: Greentime Hu <green.hu@gmail.com>
---
 drivers/clocksource/timer-atcpit100.c |  247 +++++++++++++++++++++++++++++++++
 1 file changed, 247 insertions(+)
 create mode 100644 drivers/clocksource/timer-atcpit100.c

diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c
new file mode 100644
index 0000000..76ddd2f
--- /dev/null
+++ b/drivers/clocksource/timer-atcpit100.c
@@ -0,0 +1,247 @@
+/*
+ *  Andestech ATCPIT100 Timer Device Driver Implementation
+ *
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sched.h>
+#include <linux/sched_clock.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include "timer-of.h"
+
+/*
+ * Definition of register offsets
+ */
+
+/* ID and Revision Register */
+#define ID_REV		0x0
+
+/* Configuration Register */
+#define CFG		0x10
+
+/* Interrupt Enable Register */
+#define INT_EN		0x14
+#define CH_INT_EN(c, i)	((1<<i)<<(4*c))
+#define CH0INT0EN	0x01
+
+/* Interrupt Status Register */
+#define INT_STA		0x18
+#define CH0INT0		0x01
+
+/* Channel Enable Register */
+#define CH_EN		0x1C
+#define CH0TMR0EN	0x1
+#define CH1TMR0EN	0x10
+
+/* Channel 0 , 1 Control Register */
+#define CH0_CTL		(0x20)
+#define CH1_CTL		(0x20 + 0x10)
+
+/* Channel clock source , bit 3 , 0:External clock , 1:APB clock */
+#define APB_CLK		BIT(3)
+
+/* Channel mode , bit 0~2 */
+#define TMR_32		0x1
+#define TMR_16		0x2
+#define TMR_8		0x3
+
+/* Channel 0 , 1 Reload Register */
+#define CH0_REL		(0x24)
+#define CH1_REL		(0x24 + 0x10)
+
+/* Channel 0 , 1 Counter Register */
+#define CH0_CNT		(0x28)
+#define CH1_CNT		(0x28 + 0x10)
+
+#define TIMER_SYNC_TICKS	3
+
+static void atcpit100_ch1_tmr0_en(void __iomem *base)
+{
+	writel(~0, base + CH1_REL);
+	writel(APB_CLK|TMR_32, base + CH1_CTL);
+}
+
+static void atcpit100_ch0_tmr0_en(void __iomem *base)
+{
+	writel(APB_CLK|TMR_32, base + CH0_CTL);
+}
+
+static void atcpit100_clkevt_time_setup(void __iomem *base, unsigned long delay)
+{
+	writel(delay, base + CH0_CNT);
+	writel(delay, base + CH0_REL);
+}
+
+static void atcpit100_timer_clear_interrupt(void __iomem *base)
+{
+	u32 val;
+
+	val = readl(base + INT_STA);
+	writel(val | CH0INT0, base + INT_STA);
+}
+
+static void atcpit100_clocksource_start(void __iomem *base)
+{
+	u32 val;
+
+	val = readl(base + CH_EN);
+	writel(val | CH1TMR0EN, base + CH_EN);
+}
+
+static void atcpit100_clkevt_time_start(void __iomem *base)
+{
+	u32 val;
+
+	val = readl(base + CH_EN);
+	writel(val | CH0TMR0EN, base + CH_EN);
+}
+
+static void atcpit100_clkevt_time_stop(void __iomem *base)
+{
+	u32 val;
+
+	atcpit100_timer_clear_interrupt(base);
+	val = readl(base + CH_EN);
+	writel(val & ~CH0TMR0EN, base + CH_EN);
+}
+
+static int atcpit100_clkevt_next_event(unsigned long evt,
+	struct clock_event_device *clkevt)
+{
+	struct timer_of *to = to_timer_of(clkevt);
+
+	writel(evt, timer_of_base(to) + CH0_REL);
+
+	return 0;
+}
+
+static int atcpit100_clkevt_set_periodic(struct clock_event_device *evt)
+{
+	struct timer_of *to = to_timer_of(evt);
+
+	atcpit100_clkevt_time_setup(timer_of_base(to), timer_of_period(to));
+	atcpit100_clkevt_time_start(timer_of_base(to));
+
+	return 0;
+}
+static int atcpit100_clkevt_shutdown(struct clock_event_device *evt)
+{
+	struct timer_of *to = to_timer_of(evt);
+
+	atcpit100_clkevt_time_stop(timer_of_base(to));
+
+	return 0;
+}
+static int atcpit100_clkevt_set_oneshot(struct clock_event_device *evt)
+{
+	struct timer_of *to = to_timer_of(evt);
+	u32 val;
+
+	writel(~0x0, timer_of_base(to) + CH0_REL);
+	val = readl(timer_of_base(to) + CH_EN);
+	writel(val | CH0TMR0EN, timer_of_base(to) + CH_EN);
+
+	return 0;
+}
+
+static irqreturn_t atcpit100_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+	struct timer_of *to = to_timer_of(evt);
+
+	atcpit100_timer_clear_interrupt(timer_of_base(to));
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct timer_of to = {
+	.flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE,
+
+	.clkevt = {
+		.name = "atcpit100_tick",
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown = atcpit100_clkevt_shutdown,
+		.set_state_periodic = atcpit100_clkevt_set_periodic,
+		.set_state_oneshot = atcpit100_clkevt_set_oneshot,
+		.tick_resume = atcpit100_clkevt_shutdown,
+		.set_next_event = atcpit100_clkevt_next_event,
+		.cpumask = cpu_all_mask,
+	},
+
+	.of_irq = {
+		.handler = atcpit100_timer_interrupt,
+		.flags = IRQF_TIMER | IRQF_IRQPOLL,
+	},
+};
+
+static u64 notrace atcpit100_timer_sched_read(void)
+{
+	return ~readl(timer_of_base(&to) + CH1_CNT);
+}
+
+static int __init atcpit100_timer_init(struct device_node *node)
+{
+	int ret;
+	u32 val;
+	void __iomem *base;
+
+	ret = timer_of_init(node, &to);
+	if (ret)
+		return ret;
+
+	base = timer_of_base(&to);
+
+	sched_clock_register(atcpit100_timer_sched_read, 32,
+		timer_of_rate(&to));
+
+	ret = clocksource_mmio_init(base + CH1_CNT,
+		node->name, timer_of_rate(&to), 300, 32,
+		clocksource_mmio_readl_down);
+
+	if (ret) {
+		pr_err("Failed to register clocksource\n");
+		return ret;
+	}
+
+	/* clear channel 0 timer0 interrupt */
+	atcpit100_timer_clear_interrupt(base);
+
+	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
+					TIMER_SYNC_TICKS, 0xffffffff);
+	atcpit100_ch0_tmr0_en(base);
+	atcpit100_ch1_tmr0_en(base);
+	atcpit100_clocksource_start(base);
+	atcpit100_clkevt_time_start(base);
+
+	/* Enable channel 0 timer0 interrupt */
+	val = readl(base + INT_EN);
+	writel(val | CH0INT0EN, base + INT_EN);
+
+	return ret;
+}
+
+TIMER_OF_DECLARE(atcpit100, "andestech,atcpit100", atcpit100_timer_init);
-- 
1.7.9.5

  parent reply	other threads:[~2017-11-27 12:55 UTC|newest]

Thread overview: 116+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-27 12:27 [PATCH v2 00/35] Andes(nds32) Linux Kernel Port Greentime Hu
2017-11-27 12:27 ` [PATCH v2 01/35] nds32: Assembly macros and definitions Greentime Hu
2017-11-27 12:27 ` [PATCH v2 02/35] nds32: Kernel booting and initialization Greentime Hu
2017-11-27 12:27 ` [PATCH v2 03/35] nds32: Exception handling Greentime Hu
2017-11-27 12:27 ` [PATCH v2 04/35] nds32: MMU definitions Greentime Hu
2017-11-27 12:27 ` [PATCH v2 05/35] nds32: MMU initialization Greentime Hu
2017-11-27 12:27 ` [PATCH v2 06/35] nds32: MMU fault handling and page table management Greentime Hu
2017-11-27 13:51   ` Mark Rutland
2017-11-27 13:51     ` Mark Rutland
2017-11-29  7:24     ` Greentime Hu
2017-11-29  7:24       ` Greentime Hu
2017-12-07 16:40   ` Al Viro
2017-12-08  5:26     ` Greentime Hu
2017-12-08  5:26       ` Greentime Hu
2017-11-27 12:27 ` [PATCH v2 07/35] nds32: Cache and TLB routines Greentime Hu
2017-11-27 12:27 ` [PATCH v2 08/35] nds32: Process management Greentime Hu
2017-12-07 16:45   ` Al Viro
2017-12-08  5:27     ` Greentime Hu
2017-11-27 12:27 ` [PATCH v2 09/35] nds32: IRQ handling Greentime Hu
2017-11-27 12:27 ` [PATCH v2 10/35] nds32: Atomic operations Greentime Hu
2017-11-27 12:27   ` Greentime Hu
2017-11-27 13:57   ` Mark Rutland
2017-11-28  4:24     ` Vincent Chen
2017-11-27 12:27 ` [PATCH v2 11/35] nds32: Device specific operations Greentime Hu
2017-11-27 14:51   ` Arnd Bergmann
2017-11-27 12:27 ` [PATCH v2 12/35] nds32: DMA mapping API Greentime Hu
2017-11-27 12:28 ` [PATCH v2 13/35] nds32: ELF definitions Greentime Hu
2017-11-27 12:28 ` [PATCH v2 14/35] nds32: System calls handling Greentime Hu
2017-11-27 14:46   ` Arnd Bergmann
2017-11-28  2:18     ` Vincent Chen
2017-11-28  9:23       ` Arnd Bergmann
2017-11-27 12:28 ` [PATCH v2 15/35] nds32: VDSO support Greentime Hu
2017-11-27 12:28 ` [PATCH v2 16/35] nds32: Signal handling support Greentime Hu
2017-11-27 14:37   ` Arnd Bergmann
2017-11-27 14:37     ` Arnd Bergmann
2017-11-28  2:21     ` Vincent Chen
2017-11-28  2:21       ` Vincent Chen
2017-11-27 12:28 ` [PATCH v2 17/35] nds32: Library functions Greentime Hu
2017-11-27 12:28 ` [PATCH v2 18/35] nds32: Debugging support Greentime Hu
2017-11-27 14:34   ` Arnd Bergmann
2017-11-28  2:21     ` Vincent Chen
2017-11-28  2:21       ` Vincent Chen
2017-11-27 12:28 ` [PATCH v2 19/35] nds32: L2 cache support Greentime Hu
2017-11-27 14:33   ` Arnd Bergmann
2017-11-29 11:53     ` Greentime Hu
2017-11-27 12:28 ` [PATCH v2 20/35] nds32: Loadable modules Greentime Hu
2017-11-27 12:28 ` [PATCH v2 21/35] nds32: Generic timers support Greentime Hu
2017-11-27 12:28 ` [PATCH v2 22/35] nds32: Device tree support Greentime Hu
2017-11-27 14:30   ` Arnd Bergmann
2017-11-28  6:54     ` Greentime Hu
2017-11-28  6:54       ` Greentime Hu
2017-11-27 19:07   ` Rob Herring
2017-11-27 19:14     ` Rob Herring
2017-12-02 16:47     ` Greentime Hu
2017-12-02 16:47       ` Greentime Hu
2017-11-27 12:28 ` [PATCH v2 23/35] nds32: Miscellaneous header files Greentime Hu
2017-11-27 12:28   ` Greentime Hu
2017-11-27 12:28 ` [PATCH v2 24/35] nds32: defconfig Greentime Hu
2017-11-27 14:27   ` Arnd Bergmann
2017-11-27 12:28 ` [PATCH v2 25/35] nds32: Build infrastructure Greentime Hu
2017-11-27 12:28   ` Greentime Hu
2017-11-27 14:21   ` Arnd Bergmann
2017-11-29  8:39     ` Greentime Hu
2017-11-29  8:58       ` Arnd Bergmann
2017-11-29  9:10         ` Geert Uytterhoeven
2017-11-29  9:25           ` Arnd Bergmann
2017-11-29 11:39             ` Greentime Hu
2017-11-29 11:57               ` Arnd Bergmann
2017-11-29 14:10                 ` Greentime Hu
2017-11-29 20:27                   ` Arnd Bergmann
2017-11-30  5:48                     ` Greentime Hu
2017-11-30  7:52                       ` Geert Uytterhoeven
2017-11-30  7:52                         ` Geert Uytterhoeven
2017-11-30  9:29                         ` Greentime Hu
2017-11-30  9:30                       ` Arnd Bergmann
2017-11-30  9:30                         ` Arnd Bergmann
2017-11-30 10:01                         ` Greentime Hu
2017-11-27 12:28 ` [PATCH v2 26/35] dt-bindings: interrupt-controller: Andestech Internal Vector Interrupt Controller Greentime Hu
2017-11-27 12:28   ` Greentime Hu
2017-11-28 14:05   ` Rob Herring
2017-11-27 12:28 ` [PATCH v2 27/35] irqchip: Andestech Internal Vector Interrupt Controller driver Greentime Hu
2017-11-28  9:37   ` Marc Zyngier
2017-11-28  9:37     ` Marc Zyngier
2017-11-29 15:23     ` Greentime Hu
2017-11-29 15:23       ` Greentime Hu
2017-11-30 10:57       ` Marc Zyngier
2017-11-27 12:28 ` [PATCH v2 28/35] MAINTAINERS: Add nds32 Greentime Hu
2017-11-27 12:28 ` [PATCH v2 29/35] dt-bindings: nds32 CPU Bindings Greentime Hu
2017-11-27 13:42   ` Mark Rutland
2017-11-28  3:18     ` Greentime Hu
2017-11-28  3:18       ` Greentime Hu
2017-11-27 12:28 ` [PATCH v2 30/35] net: faraday add nds32 support Greentime Hu
2017-11-27 14:15   ` Arnd Bergmann
2017-11-28  2:55     ` Greentime Hu
2017-11-28  2:55       ` Greentime Hu
2017-11-27 12:28 ` [PATCH v2 31/35] earlycon: add reg-offset to physical address before mapping Greentime Hu
2017-11-28 14:25   ` Greg KH
2017-11-29  5:40     ` Greentime Hu
2017-11-27 12:28 ` [PATCH v2 32/35] asm-generic/io.h: move ioremap_nocache/ioremap_uc/ioremap_wc/ioremap_wt out of ifndef CONFIG_MMU Greentime Hu
2017-11-27 14:14   ` Arnd Bergmann
2017-11-27 12:28 ` Greentime Hu [this message]
2017-12-01 12:30   ` [PATCH v2 33/35] clocksource/drivers/atcpit100: Add andestech atcpit100 timer Linus Walleij
2017-12-01 12:30     ` Linus Walleij
2017-12-07  8:44   ` Daniel Lezcano
2017-11-27 12:28 ` [PATCH v2 34/35] clocksource/drivers/Kconfig: Support " Greentime Hu
2017-11-27 14:11   ` Arnd Bergmann
2017-11-28  2:53     ` Greentime Hu
2017-11-28  2:53       ` Greentime Hu
2017-12-07  8:40       ` Daniel Lezcano
2017-12-07  8:39   ` Daniel Lezcano
2017-12-07  8:39     ` Daniel Lezcano
2017-11-27 12:28 ` [PATCH v2 35/35] dt-bindings: timer: Add andestech atcpit100 timer binding doc Greentime Hu
2017-12-01 12:19   ` Linus Walleij
2017-12-01 12:19     ` Linus Walleij
2017-12-04  1:07     ` 陳建志
2017-12-04  1:07       ` 陳建志

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=672e0b3843953d1ab69bc19baf1a0f217ec1b1fa.1511785528.git.green.hu@gmail.com \
    --to=green.hu@gmail.com \
    --cc=arnd@arndb.de \
    --cc=daniel.lezcano@linaro.org \
    --cc=deanbo422@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dhowells@redhat.com \
    --cc=greentime@andestech.com \
    --cc=jason@lakedaemon.net \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=netdev@vger.kernel.org \
    --cc=rickchen36@gmail.com \
    --cc=robh+dt@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=viro@zeniv.linux.org.uk \
    --cc=will.deacon@arm.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.