All of lore.kernel.org
 help / color / mirror / Atom feed
From: Guo Ren <ren_guo@c-sky.com>
To: akpm@linux-foundation.org, arnd@arndb.de,
	daniel.lezcano@linaro.org, davem@davemloft.net,
	gregkh@linuxfoundation.org, jason@lakedaemon.net,
	marc.zyngier@arm.com, mark.rutland@arm.com,
	mchehab+samsung@kernel.org, peterz@infradead.org,
	robh@kernel.org, robh+dt@kernel.org, tglx@linutronix.de
Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	devicetree@vger.kernel.org, green.hu@gmail.com,
	Guo Ren <ren_guo@c-sky.com>
Subject: [PATCH V6 30/33] clocksource: add gx6605s SOC system timer
Date: Fri, 28 Sep 2018 08:51:27 +0800	[thread overview]
Message-ID: <8f77e77744276b0cbdf1d6c9ba6daed49f9452a7.1538058840.git.ren_guo@c-sky.com> (raw)
In-Reply-To: <62098e7d0a7fbdd09f44d7e23333dad258a01bd2.1538058840.git.ren_guo@c-sky.com>
In-Reply-To: <cover.1538058840.git.ren_guo@c-sky.com>

Changelog:
 - Add License and Copyright
 - Use timer-of framework
 - Change name with upstream feedback
 - Use clksource_mmio framework

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 drivers/clocksource/Kconfig         |   8 ++
 drivers/clocksource/Makefile        |   1 +
 drivers/clocksource/timer-gx6605s.c | 150 ++++++++++++++++++++++++++++++++++++
 3 files changed, 159 insertions(+)
 create mode 100644 drivers/clocksource/timer-gx6605s.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a28043f..0f38acc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -628,4 +628,12 @@ config CSKY_MPTIMER
 	  Say yes here to enable C-SKY SMP timer driver used for C-SKY SMP
 	  system.
 
+config GX6605S_TIMER
+	bool "Gx6605s SOC system timer driver"
+	depends on CSKY
+	select CLKSRC_MMIO
+	select TIMER_OF
+	help
+	  This option enables support for gx6605s SOC's timer.
+
 endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 848c676..7a1b0f4 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -80,3 +80,4 @@ obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
 obj-$(CONFIG_ATCPIT100_TIMER)		+= timer-atcpit100.o
 obj-$(CONFIG_RISCV_TIMER)		+= riscv_timer.o
 obj-$(CONFIG_CSKY_MPTIMER)		+= csky_mptimer.o
+obj-$(CONFIG_GX6605S_TIMER)		+= timer-gx6605s.o
diff --git a/drivers/clocksource/timer-gx6605s.c b/drivers/clocksource/timer-gx6605s.c
new file mode 100644
index 0000000..10194c9
--- /dev/null
+++ b/drivers/clocksource/timer-gx6605s.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched_clock.h>
+
+#include "timer-of.h"
+
+#define CLKSRC_OFFSET	0x40
+
+#define TIMER_STATUS	0x00
+#define TIMER_VALUE	0x04
+#define TIMER_CONTRL	0x10
+#define TIMER_CONFIG	0x20
+#define TIMER_DIV	0x24
+#define TIMER_INI	0x28
+
+#define GX6605S_STATUS_CLR	BIT(0)
+#define GX6605S_CONTRL_RST	BIT(0)
+#define GX6605S_CONTRL_START	BIT(1)
+#define GX6605S_CONFIG_EN	BIT(0)
+#define GX6605S_CONFIG_IRQ_EN	BIT(1)
+
+static irqreturn_t gx6605s_timer_interrupt(int irq, void *dev)
+{
+	struct clock_event_device *ce = (struct clock_event_device *) dev;
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	writel_relaxed(GX6605S_STATUS_CLR, base + TIMER_STATUS);
+
+	ce->event_handler(ce);
+
+	return IRQ_HANDLED;
+}
+
+static int gx6605s_timer_set_oneshot(struct clock_event_device *ce)
+{
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	/* reset and stop counter */
+	writel_relaxed(GX6605S_CONTRL_RST, base + TIMER_CONTRL);
+
+	/* enable with irq and start */
+	writel_relaxed(GX6605S_CONFIG_EN | GX6605S_CONFIG_IRQ_EN, base + TIMER_CONFIG);
+
+	return 0;
+}
+
+static int gx6605s_timer_set_next_event(unsigned long delta, struct clock_event_device *ce)
+{
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	/* use reset to pause timer */
+	writel_relaxed(GX6605S_CONTRL_RST, base + TIMER_CONTRL);
+
+	/* config next timeout value */
+	writel_relaxed(ULONG_MAX - delta, base + TIMER_INI);
+	writel_relaxed(GX6605S_CONTRL_START, base + TIMER_CONTRL);
+
+	return 0;
+}
+
+static int gx6605s_timer_shutdown(struct clock_event_device *ce)
+{
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	writel_relaxed(0, base + TIMER_CONTRL);
+	writel_relaxed(0, base + TIMER_CONFIG);
+
+	return 0;
+}
+
+static struct timer_of to = {
+	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
+	.clkevt = {
+		.rating			= 300,
+		.features		= CLOCK_EVT_FEAT_DYNIRQ |
+					  CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown	= gx6605s_timer_shutdown,
+		.set_state_oneshot	= gx6605s_timer_set_oneshot,
+		.set_next_event		= gx6605s_timer_set_next_event,
+		.cpumask		= cpu_possible_mask,
+	},
+	.of_irq = {
+		.handler		= gx6605s_timer_interrupt,
+		.flags			= IRQF_TIMER | IRQF_IRQPOLL,
+	},
+};
+
+static u64 notrace gx6605s_sched_clock_read(void)
+{
+	void __iomem *base;
+
+	base = timer_of_base(&to) + CLKSRC_OFFSET;
+
+	return (u64) readl_relaxed(base + TIMER_VALUE);
+}
+
+static void gx6605s_clkevt_init(void __iomem *base)
+{
+	writel_relaxed(0, base + TIMER_DIV);
+	writel_relaxed(0, base + TIMER_CONFIG);
+
+	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 2, ULONG_MAX);
+}
+
+static int gx6605s_clksrc_init(void __iomem *base)
+{
+	writel_relaxed(0, base + TIMER_DIV);
+	writel_relaxed(0, base + TIMER_INI);
+
+	writel_relaxed(GX6605S_CONTRL_RST, base + TIMER_CONTRL);
+
+	writel_relaxed(GX6605S_CONFIG_EN, base + TIMER_CONFIG);
+
+	writel_relaxed(GX6605S_CONTRL_START, base + TIMER_CONTRL);
+
+	sched_clock_register(gx6605s_sched_clock_read, 32, timer_of_rate(&to));
+
+	return clocksource_mmio_init(base + TIMER_VALUE, "gx6605s", timer_of_rate(&to),
+				     200, 32, clocksource_mmio_readl_up);
+}
+
+static int __init gx6605s_timer_init(struct device_node *np)
+{
+	int ret;
+
+	/*
+	 * The timer driver is for nationalchip gx6605s SOC and there are two same timer
+	 * in gx6605s. We use one for clkevt and another for clksrc.
+	 *
+	 * The timer is mmio map to access, so we need give mmio addres in dts.
+	 *
+	 * It provides a 32bit countup timer and interrupt will be caused by count-overflow.
+	 * So we need set-next-event by ULONG_MAX - delta in TIMER_INI reg.
+	 *
+	 * The counter at 0x0  offset is clock event.
+	 * The counter at 0x40 offset is clock source.
+	 * They are the same in hardware, just different used by driver.
+	 */
+	ret = timer_of_init(np, &to);
+	if (ret)
+		return ret;
+
+	gx6605s_clkevt_init(timer_of_base(&to));
+
+	return gx6605s_clksrc_init(timer_of_base(&to) + CLKSRC_OFFSET);
+}
+TIMER_OF_DECLARE(csky_gx6605s_timer, "csky,gx6605s-timer", gx6605s_timer_init);
-- 
2.7.4


  parent reply	other threads:[~2018-09-28  0:53 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-27 14:47 [PATCH V6 00/33] C-SKY(csky) Linux Kernel Port Guo Ren
2018-09-27 14:47 ` [PATCH V6 01/33] csky: Build infrastructure Guo Ren
2018-09-28 16:11   ` Christoph Hellwig
2018-09-29 17:20     ` Guo Ren
2018-09-27 14:47 ` [PATCH V6 02/33] csky: defconfig Guo Ren
2018-09-27 14:47 ` [PATCH V6 03/33] csky: Kernel booting Guo Ren
2018-09-28 16:13   ` Christoph Hellwig
2018-09-29 17:09     ` Guo Ren
2018-09-27 14:47 ` [PATCH V6 04/33] csky: Exception handling and mm-fault Guo Ren
2018-09-28 16:15   ` Christoph Hellwig
2018-09-29 17:07     ` Guo Ren
2018-09-27 14:47 ` [PATCH V6 05/33] csky: System Call Guo Ren
2018-09-28 16:16   ` Christoph Hellwig
2018-09-29 17:05     ` Guo Ren
2018-09-27 14:47 ` [PATCH V6 06/33] csky: Cache and TLB routines Guo Ren
2018-09-27 14:47 ` [PATCH V6 07/33] csky: MMU and page table management Guo Ren
2018-09-27 15:47   ` Christoph Hellwig
2018-09-28 13:08     ` Guo Ren
2018-09-29 17:04     ` Guo Ren
2018-09-27 14:47 ` [PATCH V6 08/33] csky: Process management and Signal Guo Ren
2018-09-27 19:50   ` Eric W. Biederman
2018-09-28 13:10     ` Guo Ren
2018-09-29 17:01     ` Guo Ren
2018-09-27 14:47 ` [PATCH V6 09/33] csky: VDSO and rt_sigreturn Guo Ren
2018-09-27 14:47 ` [PATCH V6 10/33] csky: IRQ handling Guo Ren
2018-09-27 15:49   ` Christoph Hellwig
2018-09-28 13:09     ` Guo Ren
2018-09-29 17:00     ` Guo Ren
2018-09-27 14:47 ` [PATCH V6 11/33] csky: Atomic operations Guo Ren
2018-09-27 14:47 ` [PATCH V6 12/33] csky: ELF and module probe Guo Ren
2018-09-27 14:47 ` [PATCH V6 13/33] csky: Library functions Guo Ren
2018-09-28 16:20   ` Christoph Hellwig
2018-09-29 17:00     ` Guo Ren
2018-09-27 14:47 ` [PATCH V6 14/33] csky: User access Guo Ren
2018-09-27 14:47 ` [PATCH V6 15/33] csky: Debug and Ptrace GDB Guo Ren
2018-09-27 14:47 ` [PATCH V6 16/33] csky: SMP support Guo Ren
2018-09-27 14:47 ` [PATCH V6 17/33] csky: Misc headers Guo Ren
2018-09-28  0:51 ` [PATCH V6 18/33] dt-bindings: csky CPU Bindings Guo Ren
2018-09-28  0:51 ` [PATCH V6 19/33] dt-bindings: Add vendor prefix for csky Guo Ren
2018-09-28  0:51 ` [PATCH V6 20/33] csky/dma: fix up dma_mapping error Guo Ren
2018-09-28 16:21   ` Christoph Hellwig
2018-09-29 15:08     ` Guo Ren
2018-09-30 11:10       ` Guo Ren
2018-09-28  0:51 ` [PATCH V6 21/33] csky: remove irq_mapping from smp.c Guo Ren
2018-09-28  0:51 ` [PATCH V6 22/33] irqchip: add C-SKY SMP interrupt controller Guo Ren
2018-09-28  0:51 ` [PATCH V6 23/33] dt-bindings: interrupt-controller: C-SKY SMP intc Guo Ren
2018-09-28  0:51 ` [PATCH V6 24/33] clocksource: add C-SKY SMP timer Guo Ren
2018-09-28  0:51 ` [PATCH V6 25/33] dt-bindings: timer: C-SKY Multi-processor timer Guo Ren
2018-09-28  0:51 ` [PATCH V6 26/33] MAINTAINERS: Add csky Guo Ren
2018-09-28  0:51 ` [PATCH V6 27/33] dt-bindings: interrupt-controller: C-SKY APB intc Guo Ren
2018-09-28  0:51 ` [PATCH V6 28/33] irqchip: add C-SKY APB bus interrupt controller Guo Ren
2018-09-28  0:51 ` [PATCH V6 29/33] dt-bindings: timer: gx6605s SOC timer Guo Ren
2018-09-28  0:51 ` Guo Ren [this message]
2018-09-28  0:51 ` [PATCH V6 31/33] csky: fix compile error in linux/bug.h with SMP enabled Guo Ren
2018-09-28  0:51 ` [PATCH V6 32/33] csky: fix flush_cache_range and tlb_start_vma Guo Ren
2018-09-28  0:51 ` [PATCH V6 33/33] csky: use asm-generic/bitops/atomic.h for all Guo Ren

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=8f77e77744276b0cbdf1d6c9ba6daed49f9452a7.1538058840.git.ren_guo@c-sky.com \
    --to=ren_guo@c-sky.com \
    --cc=akpm@linux-foundation.org \
    --cc=arnd@arndb.de \
    --cc=daniel.lezcano@linaro.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=green.hu@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jason@lakedaemon.net \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=mchehab+samsung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=robh+dt@kernel.org \
    --cc=robh@kernel.org \
    --cc=tglx@linutronix.de \
    /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.