linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files
@ 2021-03-18  5:04 Evan Benn
  2021-03-18  5:04 ` [PATCH 2/2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown Evan Benn
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Evan Benn @ 2021-03-18  5:04 UTC (permalink / raw)
  To: LKML
  Cc: Thomas Gleixner, Evan Benn, Yingjoe Chen, Julia Lawall,
	linux-arm-kernel, Stanley Chu, Daniel Lezcano, Matthias Brugger,
	Viresh Kumar, Fabien Parent, linux-mediatek, Alexey Klimov,
	Catalin Marinas, Russell King, Will Deacon

mtk_gpt and mtk_syst drivers for mt6577 and mt6765 devices were not
sharing any code. So split them into separate files.

Signed-off-by: Evan Benn <evanbenn@chromium.org>
---

 arch/arm/mach-mediatek/Kconfig                |   3 +-
 arch/arm64/Kconfig.platforms                  |   3 +-
 drivers/clocksource/Kconfig                   |  13 +-
 drivers/clocksource/Makefile                  |   3 +-
 ...mer-mediatek.c => timer-mediatek-mt6577.c} | 100 -------------
 drivers/clocksource/timer-mediatek-mt6765.c   | 135 ++++++++++++++++++
 6 files changed, 151 insertions(+), 106 deletions(-)
 rename drivers/clocksource/{timer-mediatek.c => timer-mediatek-mt6577.c} (69%)
 create mode 100644 drivers/clocksource/timer-mediatek-mt6765.c

diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index 9e0f592d87d8..8686f992c4b6 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -4,7 +4,8 @@ menuconfig ARCH_MEDIATEK
 	depends on ARCH_MULTI_V7
 	select ARM_GIC
 	select PINCTRL
-	select MTK_TIMER
+	select TIMER_MEDIATEK_MT6577
+	select TIMER_MEDIATEK_MT6765
 	select MFD_SYSCON
 	help
 	  Support for Mediatek MT65xx & MT81xx SoCs
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index cdfd5fed457f..d4752375ab0b 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -161,7 +161,8 @@ config ARCH_MEDIATEK
 	bool "MediaTek SoC Family"
 	select ARM_GIC
 	select PINCTRL
-	select MTK_TIMER
+	select TIMER_MEDIATEK_MT6577
+	select TIMER_MEDIATEK_MT6765
 	help
 	  This enables support for MediaTek MT27xx, MT65xx, MT76xx
 	  & MT81xx ARMv8 SoCs
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 39aa21d01e05..d697c799284e 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -438,13 +438,20 @@ config OXNAS_RPS_TIMER
 config SYS_SUPPORTS_SH_CMT
 	bool
 
-config MTK_TIMER
-	bool "Mediatek timer driver" if COMPILE_TEST
+config TIMER_MEDIATEK_MT6577
+	bool "Mediatek mt6577 timer driver" if COMPILE_TEST
 	depends on HAS_IOMEM
 	select TIMER_OF
 	select CLKSRC_MMIO
 	help
-	  Support for Mediatek timer driver.
+	  Enables clocksource and clockevent driver for Mediatek mt6577 timer.
+
+config TIMER_MEDIATEK_MT6765
+	bool "Mediatek mt6765 timer driver" if COMPILE_TEST
+	depends on HAS_IOMEM
+	select TIMER_OF
+	help
+	  Enables clockevent driver for Mediatek mt6765 timer.
 
 config SPRD_TIMER
 	bool "Spreadtrum timer driver" if EXPERT
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c17ee32a7151..b1f06ce114f9 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -49,7 +49,8 @@ obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
 obj-$(CONFIG_FSL_FTM_TIMER)	+= timer-fsl-ftm.o
 obj-$(CONFIG_VF_PIT_TIMER)	+= timer-vf-pit.o
 obj-$(CONFIG_CLKSRC_QCOM)	+= timer-qcom.o
-obj-$(CONFIG_MTK_TIMER)		+= timer-mediatek.o
+obj-$(CONFIG_TIMER_MEDIATEK_MT6577)		+= timer-mediatek-mt6577.o
+obj-$(CONFIG_TIMER_MEDIATEK_MT6765)		+= timer-mediatek-mt6765.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= timer-pistachio.o
 obj-$(CONFIG_CLKSRC_TI_32K)	+= timer-ti-32k.o
 obj-$(CONFIG_OXNAS_RPS_TIMER)	+= timer-oxnas-rps.o
diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek-mt6577.c
similarity index 69%
rename from drivers/clocksource/timer-mediatek.c
rename to drivers/clocksource/timer-mediatek-mt6577.c
index 9318edcd8963..9e5241d1876d 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek-mt6577.c
@@ -47,86 +47,8 @@
 #define GPT_CNT_REG(val)        (0x08 + (0x10 * (val)))
 #define GPT_CMP_REG(val)        (0x0C + (0x10 * (val)))
 
-/* system timer */
-#define SYST_BASE               (0x40)
-
-#define SYST_CON                (SYST_BASE + 0x0)
-#define SYST_VAL                (SYST_BASE + 0x4)
-
-#define SYST_CON_REG(to)        (timer_of_base(to) + SYST_CON)
-#define SYST_VAL_REG(to)        (timer_of_base(to) + SYST_VAL)
-
-/*
- * SYST_CON_EN: Clock enable. Shall be set to
- *   - Start timer countdown.
- *   - Allow timeout ticks being updated.
- *   - Allow changing interrupt functions.
- *
- * SYST_CON_IRQ_EN: Set to allow interrupt.
- *
- * SYST_CON_IRQ_CLR: Set to clear interrupt.
- */
-#define SYST_CON_EN              BIT(0)
-#define SYST_CON_IRQ_EN          BIT(1)
-#define SYST_CON_IRQ_CLR         BIT(4)
-
 static void __iomem *gpt_sched_reg __read_mostly;
 
-static void mtk_syst_ack_irq(struct timer_of *to)
-{
-	/* Clear and disable interrupt */
-	writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to));
-}
-
-static irqreturn_t mtk_syst_handler(int irq, void *dev_id)
-{
-	struct clock_event_device *clkevt = dev_id;
-	struct timer_of *to = to_timer_of(clkevt);
-
-	mtk_syst_ack_irq(to);
-	clkevt->event_handler(clkevt);
-
-	return IRQ_HANDLED;
-}
-
-static int mtk_syst_clkevt_next_event(unsigned long ticks,
-				      struct clock_event_device *clkevt)
-{
-	struct timer_of *to = to_timer_of(clkevt);
-
-	/* Enable clock to allow timeout tick update later */
-	writel(SYST_CON_EN, SYST_CON_REG(to));
-
-	/*
-	 * Write new timeout ticks. Timer shall start countdown
-	 * after timeout ticks are updated.
-	 */
-	writel(ticks, SYST_VAL_REG(to));
-
-	/* Enable interrupt */
-	writel(SYST_CON_EN | SYST_CON_IRQ_EN, SYST_CON_REG(to));
-
-	return 0;
-}
-
-static int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt)
-{
-	/* Disable timer */
-	writel(0, SYST_CON_REG(to_timer_of(clkevt)));
-
-	return 0;
-}
-
-static int mtk_syst_clkevt_resume(struct clock_event_device *clkevt)
-{
-	return mtk_syst_clkevt_shutdown(clkevt);
-}
-
-static int mtk_syst_clkevt_oneshot(struct clock_event_device *clkevt)
-{
-	return 0;
-}
-
 static u64 notrace mtk_gpt_read_sched_clock(void)
 {
 	return readl_relaxed(gpt_sched_reg);
@@ -255,27 +177,6 @@ static struct timer_of to = {
 	},
 };
 
-static int __init mtk_syst_init(struct device_node *node)
-{
-	int ret;
-
-	to.clkevt.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT;
-	to.clkevt.set_state_shutdown = mtk_syst_clkevt_shutdown;
-	to.clkevt.set_state_oneshot = mtk_syst_clkevt_oneshot;
-	to.clkevt.tick_resume = mtk_syst_clkevt_resume;
-	to.clkevt.set_next_event = mtk_syst_clkevt_next_event;
-	to.of_irq.handler = mtk_syst_handler;
-
-	ret = timer_of_init(node, &to);
-	if (ret)
-		return ret;
-
-	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
-					TIMER_SYNC_TICKS, 0xffffffff);
-
-	return 0;
-}
-
 static int __init mtk_gpt_init(struct device_node *node)
 {
 	int ret;
@@ -310,4 +211,3 @@ static int __init mtk_gpt_init(struct device_node *node)
 	return 0;
 }
 TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
-TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
diff --git a/drivers/clocksource/timer-mediatek-mt6765.c b/drivers/clocksource/timer-mediatek-mt6765.c
new file mode 100644
index 000000000000..b4f22f226feb
--- /dev/null
+++ b/drivers/clocksource/timer-mediatek-mt6765.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Mediatek SoCs General-Purpose Timer handling.
+ *
+ * Copyright (C) 2014 Matthias Brugger
+ *
+ * Matthias Brugger <matthias.bgg@gmail.com>
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/sched_clock.h>
+#include <linux/slab.h>
+#include "timer-of.h"
+
+#define TIMER_SYNC_TICKS        (3)
+
+/* system timer */
+#define SYST_BASE               (0x40)
+
+#define SYST_CON                (SYST_BASE + 0x0)
+#define SYST_VAL                (SYST_BASE + 0x4)
+
+#define SYST_CON_REG(to)        (timer_of_base(to) + SYST_CON)
+#define SYST_VAL_REG(to)        (timer_of_base(to) + SYST_VAL)
+
+/*
+ * SYST_CON_EN: Clock enable. Shall be set to
+ *   - Start timer countdown.
+ *   - Allow timeout ticks being updated.
+ *   - Allow changing interrupt functions.
+ *
+ * SYST_CON_IRQ_EN: Set to allow interrupt.
+ *
+ * SYST_CON_IRQ_CLR: Set to clear interrupt.
+ */
+#define SYST_CON_EN              BIT(0)
+#define SYST_CON_IRQ_EN          BIT(1)
+#define SYST_CON_IRQ_CLR         BIT(4)
+
+static void mtk_syst_ack_irq(struct timer_of *to)
+{
+	/* Clear and disable interrupt */
+	writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to));
+}
+
+static irqreturn_t mtk_syst_handler(int irq, void *dev_id)
+{
+	struct clock_event_device *clkevt = dev_id;
+	struct timer_of *to = to_timer_of(clkevt);
+
+	mtk_syst_ack_irq(to);
+	clkevt->event_handler(clkevt);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_syst_clkevt_next_event(unsigned long ticks,
+				      struct clock_event_device *clkevt)
+{
+	struct timer_of *to = to_timer_of(clkevt);
+
+	/* Enable clock to allow timeout tick update later */
+	writel(SYST_CON_EN, SYST_CON_REG(to));
+
+	/*
+	 * Write new timeout ticks. Timer shall start countdown
+	 * after timeout ticks are updated.
+	 */
+	writel(ticks, SYST_VAL_REG(to));
+
+	/* Enable interrupt */
+	writel(SYST_CON_EN | SYST_CON_IRQ_EN, SYST_CON_REG(to));
+
+	return 0;
+}
+
+static int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt)
+{
+	/* Disable timer */
+	writel(0, SYST_CON_REG(to_timer_of(clkevt)));
+
+	return 0;
+}
+
+static int mtk_syst_clkevt_resume(struct clock_event_device *clkevt)
+{
+	return mtk_syst_clkevt_shutdown(clkevt);
+}
+
+static int mtk_syst_clkevt_oneshot(struct clock_event_device *clkevt)
+{
+	return 0;
+}
+
+static struct timer_of to = {
+	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
+
+	.clkevt = {
+		.name = "mtk-clkevt",
+		.rating = 300,
+		.cpumask = cpu_possible_mask,
+	},
+
+	.of_irq = {
+		.flags = IRQF_TIMER | IRQF_IRQPOLL,
+	},
+};
+
+static int __init mtk_syst_init(struct device_node *node)
+{
+	int ret;
+
+	to.clkevt.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT;
+	to.clkevt.set_state_shutdown = mtk_syst_clkevt_shutdown;
+	to.clkevt.set_state_oneshot = mtk_syst_clkevt_oneshot;
+	to.clkevt.tick_resume = mtk_syst_clkevt_resume;
+	to.clkevt.set_next_event = mtk_syst_clkevt_next_event;
+	to.of_irq.handler = mtk_syst_handler;
+
+	ret = timer_of_init(node, &to);
+	if (ret)
+		return ret;
+
+	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
+					TIMER_SYNC_TICKS, 0xffffffff);
+
+	return 0;
+}
+
+TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
-- 
2.31.0.rc2.261.g7f71774620-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown
  2021-03-18  5:04 [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files Evan Benn
@ 2021-03-18  5:04 ` Evan Benn
  2021-03-18 23:46   ` Evan Benn
  2021-03-22 11:19 ` [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files Daniel Lezcano
  2021-03-29 15:33 ` Matthias Brugger
  2 siblings, 1 reply; 6+ messages in thread
From: Evan Benn @ 2021-03-18  5:04 UTC (permalink / raw)
  To: LKML
  Cc: Thomas Gleixner, Evan Benn, Yingjoe Chen, Julia Lawall,
	linux-arm-kernel, Stanley Chu, Daniel Lezcano, Matthias Brugger,
	Viresh Kumar, Fabien Parent, linux-mediatek, Alexey Klimov

set_state_shutdown is called during system suspend after interrupts have
been disabled. If the timer has fired in the meantime, there will be
a pending IRQ. So we ack that now and disable the timer. Without this
ARM trusted firmware will abort the suspend due to the pending
interrupt.

Now always disable the IRQ in state transitions, and re-enable in
set_periodic and next_event.

Signed-off-by: Evan Benn <evanbenn@chromium.org>
---

 drivers/clocksource/timer-mediatek-mt6577.c | 49 +++++++++++++--------
 1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/drivers/clocksource/timer-mediatek-mt6577.c b/drivers/clocksource/timer-mediatek-mt6577.c
index 9e5241d1876d..44598121585c 100644
--- a/drivers/clocksource/timer-mediatek-mt6577.c
+++ b/drivers/clocksource/timer-mediatek-mt6577.c
@@ -54,13 +54,33 @@ static u64 notrace mtk_gpt_read_sched_clock(void)
 	return readl_relaxed(gpt_sched_reg);
 }
 
+static void mtk_gpt_disable_ack_interrupts(struct timer_of *to, u8 timer)
+{
+	u32 val;
+
+	/* Disable interrupts */
+	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
+	writel(val & ~GPT_IRQ_ENABLE(timer), timer_of_base(to) +
+	       GPT_IRQ_EN_REG);
+
+	/* Ack interrupts */
+	writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
+}
+
 static void mtk_gpt_clkevt_time_stop(struct timer_of *to, u8 timer)
 {
 	u32 val;
 
+	/* Disable timer */
 	val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
 	writel(val & ~GPT_CTRL_ENABLE, timer_of_base(to) +
 	       GPT_CTRL_REG(timer));
+
+	/* This may be called with interrupts disabled,
+	 * so we need to ack any interrupt that is pending
+	 * Or for example ATF will prevent a suspend from completing.
+	 */
+	mtk_gpt_disable_ack_interrupts(to, timer);
 }
 
 static void mtk_gpt_clkevt_time_setup(struct timer_of *to,
@@ -74,8 +94,10 @@ static void mtk_gpt_clkevt_time_start(struct timer_of *to,
 {
 	u32 val;
 
-	/* Acknowledge interrupt */
-	writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
+	/* Enable interrupts */
+	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
+	writel(val | GPT_IRQ_ENABLE(timer),
+	       timer_of_base(to) + GPT_IRQ_EN_REG);
 
 	val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
 
@@ -148,21 +170,6 @@ __init mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option)
 	       timer_of_base(to) + GPT_CTRL_REG(timer));
 }
 
-static void mtk_gpt_enable_irq(struct timer_of *to, u8 timer)
-{
-	u32 val;
-
-	/* Disable all interrupts */
-	writel(0x0, timer_of_base(to) + GPT_IRQ_EN_REG);
-
-	/* Acknowledge all spurious pending interrupts */
-	writel(0x3f, timer_of_base(to) + GPT_IRQ_ACK_REG);
-
-	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
-	writel(val | GPT_IRQ_ENABLE(timer),
-	       timer_of_base(to) + GPT_IRQ_EN_REG);
-}
-
 static struct timer_of to = {
 	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
 
@@ -193,6 +200,12 @@ static int __init mtk_gpt_init(struct device_node *node)
 	if (ret)
 		return ret;
 
+	/* In case the firmware left the interrupts enabled
+	 * disable and ack those now
+	 */
+	mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_SRC);
+	mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_EVT);
+
 	/* Configure clock source */
 	mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN);
 	clocksource_mmio_init(timer_of_base(&to) + GPT_CNT_REG(TIMER_CLK_SRC),
@@ -206,8 +219,6 @@ static int __init mtk_gpt_init(struct device_node *node)
 	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
 					TIMER_SYNC_TICKS, 0xffffffff);
 
-	mtk_gpt_enable_irq(&to, TIMER_CLK_EVT);
-
 	return 0;
 }
 TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
-- 
2.31.0.rc2.261.g7f71774620-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown
  2021-03-18  5:04 ` [PATCH 2/2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown Evan Benn
@ 2021-03-18 23:46   ` Evan Benn
  0 siblings, 0 replies; 6+ messages in thread
From: Evan Benn @ 2021-03-18 23:46 UTC (permalink / raw)
  To: LKML
  Cc: Thomas Gleixner, Yingjoe Chen, Julia Lawall,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Stanley Chu, Daniel Lezcano, Matthias Brugger, Viresh Kumar,
	Fabien Parent, moderated list:ARM/Mediatek SoC support

Hello,

There is a suspend failure on mt8173 chromebooks that use this timer.
The failure shows as an errno: -95 failure with none device.

I tracked this down to the arm trusted firmware aborting the suspend
due to this timer having a pending IRQ, due to not being disabled
during suspend / clockevents_shutdown.

Also reviewed here vs the 4.19 chromeos kernel branch:

https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2766504

Thanks

Evan Benn


On Thu, Mar 18, 2021 at 4:05 PM Evan Benn <evanbenn@chromium.org> wrote:
>
> set_state_shutdown is called during system suspend after interrupts have
> been disabled. If the timer has fired in the meantime, there will be
> a pending IRQ. So we ack that now and disable the timer. Without this
> ARM trusted firmware will abort the suspend due to the pending
> interrupt.
>
> Now always disable the IRQ in state transitions, and re-enable in
> set_periodic and next_event.
>
> Signed-off-by: Evan Benn <evanbenn@chromium.org>
> ---
>
>  drivers/clocksource/timer-mediatek-mt6577.c | 49 +++++++++++++--------
>  1 file changed, 30 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/clocksource/timer-mediatek-mt6577.c b/drivers/clocksource/timer-mediatek-mt6577.c
> index 9e5241d1876d..44598121585c 100644
> --- a/drivers/clocksource/timer-mediatek-mt6577.c
> +++ b/drivers/clocksource/timer-mediatek-mt6577.c
> @@ -54,13 +54,33 @@ static u64 notrace mtk_gpt_read_sched_clock(void)
>         return readl_relaxed(gpt_sched_reg);
>  }
>
> +static void mtk_gpt_disable_ack_interrupts(struct timer_of *to, u8 timer)
> +{
> +       u32 val;
> +
> +       /* Disable interrupts */
> +       val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> +       writel(val & ~GPT_IRQ_ENABLE(timer), timer_of_base(to) +
> +              GPT_IRQ_EN_REG);
> +
> +       /* Ack interrupts */
> +       writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
> +}
> +
>  static void mtk_gpt_clkevt_time_stop(struct timer_of *to, u8 timer)
>  {
>         u32 val;
>
> +       /* Disable timer */
>         val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
>         writel(val & ~GPT_CTRL_ENABLE, timer_of_base(to) +
>                GPT_CTRL_REG(timer));
> +
> +       /* This may be called with interrupts disabled,
> +        * so we need to ack any interrupt that is pending
> +        * Or for example ATF will prevent a suspend from completing.
> +        */
> +       mtk_gpt_disable_ack_interrupts(to, timer);
>  }
>
>  static void mtk_gpt_clkevt_time_setup(struct timer_of *to,
> @@ -74,8 +94,10 @@ static void mtk_gpt_clkevt_time_start(struct timer_of *to,
>  {
>         u32 val;
>
> -       /* Acknowledge interrupt */
> -       writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
> +       /* Enable interrupts */
> +       val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> +       writel(val | GPT_IRQ_ENABLE(timer),
> +              timer_of_base(to) + GPT_IRQ_EN_REG);
>
>         val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
>
> @@ -148,21 +170,6 @@ __init mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option)
>                timer_of_base(to) + GPT_CTRL_REG(timer));
>  }
>
> -static void mtk_gpt_enable_irq(struct timer_of *to, u8 timer)
> -{
> -       u32 val;
> -
> -       /* Disable all interrupts */
> -       writel(0x0, timer_of_base(to) + GPT_IRQ_EN_REG);
> -
> -       /* Acknowledge all spurious pending interrupts */
> -       writel(0x3f, timer_of_base(to) + GPT_IRQ_ACK_REG);
> -
> -       val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> -       writel(val | GPT_IRQ_ENABLE(timer),
> -              timer_of_base(to) + GPT_IRQ_EN_REG);
> -}
> -
>  static struct timer_of to = {
>         .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
>
> @@ -193,6 +200,12 @@ static int __init mtk_gpt_init(struct device_node *node)
>         if (ret)
>                 return ret;
>
> +       /* In case the firmware left the interrupts enabled
> +        * disable and ack those now
> +        */
> +       mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_SRC);
> +       mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_EVT);
> +
>         /* Configure clock source */
>         mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN);
>         clocksource_mmio_init(timer_of_base(&to) + GPT_CNT_REG(TIMER_CLK_SRC),
> @@ -206,8 +219,6 @@ static int __init mtk_gpt_init(struct device_node *node)
>         clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
>                                         TIMER_SYNC_TICKS, 0xffffffff);
>
> -       mtk_gpt_enable_irq(&to, TIMER_CLK_EVT);
> -
>         return 0;
>  }
>  TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
> --
> 2.31.0.rc2.261.g7f71774620-goog
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files
  2021-03-18  5:04 [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files Evan Benn
  2021-03-18  5:04 ` [PATCH 2/2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown Evan Benn
@ 2021-03-22 11:19 ` Daniel Lezcano
  2021-03-24  0:53   ` Evan Benn
  2021-03-29 15:33 ` Matthias Brugger
  2 siblings, 1 reply; 6+ messages in thread
From: Daniel Lezcano @ 2021-03-22 11:19 UTC (permalink / raw)
  To: Evan Benn, LKML
  Cc: Thomas Gleixner, Yingjoe Chen, Julia Lawall, linux-arm-kernel,
	Stanley Chu, Matthias Brugger, Viresh Kumar, Fabien Parent,
	linux-mediatek, Alexey Klimov, Catalin Marinas, Russell King,
	Will Deacon


Hi Evan,

On 18/03/2021 06:04, Evan Benn wrote:
> mtk_gpt and mtk_syst drivers for mt6577 and mt6765 devices were not
> sharing any code. So split them into separate files.

For the sake of consistency, keeping all in one is better.

Thanks
  -- Daniel

> Signed-off-by: Evan Benn <evanbenn@chromium.org>
> ---
> 
>  arch/arm/mach-mediatek/Kconfig                |   3 +-
>  arch/arm64/Kconfig.platforms                  |   3 +-
>  drivers/clocksource/Kconfig                   |  13 +-
>  drivers/clocksource/Makefile                  |   3 +-
>  ...mer-mediatek.c => timer-mediatek-mt6577.c} | 100 -------------
>  drivers/clocksource/timer-mediatek-mt6765.c   | 135 ++++++++++++++++++
>  6 files changed, 151 insertions(+), 106 deletions(-)
>  rename drivers/clocksource/{timer-mediatek.c => timer-mediatek-mt6577.c} (69%)
>  create mode 100644 drivers/clocksource/timer-mediatek-mt6765.c
> 
> diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
> index 9e0f592d87d8..8686f992c4b6 100644
> --- a/arch/arm/mach-mediatek/Kconfig
> +++ b/arch/arm/mach-mediatek/Kconfig
> @@ -4,7 +4,8 @@ menuconfig ARCH_MEDIATEK
>  	depends on ARCH_MULTI_V7
>  	select ARM_GIC
>  	select PINCTRL
> -	select MTK_TIMER
> +	select TIMER_MEDIATEK_MT6577
> +	select TIMER_MEDIATEK_MT6765
>  	select MFD_SYSCON
>  	help
>  	  Support for Mediatek MT65xx & MT81xx SoCs
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index cdfd5fed457f..d4752375ab0b 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -161,7 +161,8 @@ config ARCH_MEDIATEK
>  	bool "MediaTek SoC Family"
>  	select ARM_GIC
>  	select PINCTRL
> -	select MTK_TIMER
> +	select TIMER_MEDIATEK_MT6577
> +	select TIMER_MEDIATEK_MT6765
>  	help
>  	  This enables support for MediaTek MT27xx, MT65xx, MT76xx
>  	  & MT81xx ARMv8 SoCs
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 39aa21d01e05..d697c799284e 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -438,13 +438,20 @@ config OXNAS_RPS_TIMER
>  config SYS_SUPPORTS_SH_CMT
>  	bool
>  
> -config MTK_TIMER
> -	bool "Mediatek timer driver" if COMPILE_TEST
> +config TIMER_MEDIATEK_MT6577
> +	bool "Mediatek mt6577 timer driver" if COMPILE_TEST
>  	depends on HAS_IOMEM
>  	select TIMER_OF
>  	select CLKSRC_MMIO
>  	help
> -	  Support for Mediatek timer driver.
> +	  Enables clocksource and clockevent driver for Mediatek mt6577 timer.
> +
> +config TIMER_MEDIATEK_MT6765
> +	bool "Mediatek mt6765 timer driver" if COMPILE_TEST
> +	depends on HAS_IOMEM
> +	select TIMER_OF
> +	help
> +	  Enables clockevent driver for Mediatek mt6765 timer.
>  
>  config SPRD_TIMER
>  	bool "Spreadtrum timer driver" if EXPERT
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index c17ee32a7151..b1f06ce114f9 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -49,7 +49,8 @@ obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
>  obj-$(CONFIG_FSL_FTM_TIMER)	+= timer-fsl-ftm.o
>  obj-$(CONFIG_VF_PIT_TIMER)	+= timer-vf-pit.o
>  obj-$(CONFIG_CLKSRC_QCOM)	+= timer-qcom.o
> -obj-$(CONFIG_MTK_TIMER)		+= timer-mediatek.o
> +obj-$(CONFIG_TIMER_MEDIATEK_MT6577)		+= timer-mediatek-mt6577.o
> +obj-$(CONFIG_TIMER_MEDIATEK_MT6765)		+= timer-mediatek-mt6765.o
>  obj-$(CONFIG_CLKSRC_PISTACHIO)	+= timer-pistachio.o
>  obj-$(CONFIG_CLKSRC_TI_32K)	+= timer-ti-32k.o
>  obj-$(CONFIG_OXNAS_RPS_TIMER)	+= timer-oxnas-rps.o
> diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek-mt6577.c
> similarity index 69%
> rename from drivers/clocksource/timer-mediatek.c
> rename to drivers/clocksource/timer-mediatek-mt6577.c
> index 9318edcd8963..9e5241d1876d 100644
> --- a/drivers/clocksource/timer-mediatek.c
> +++ b/drivers/clocksource/timer-mediatek-mt6577.c
> @@ -47,86 +47,8 @@
>  #define GPT_CNT_REG(val)        (0x08 + (0x10 * (val)))
>  #define GPT_CMP_REG(val)        (0x0C + (0x10 * (val)))
>  
> -/* system timer */
> -#define SYST_BASE               (0x40)
> -
> -#define SYST_CON                (SYST_BASE + 0x0)
> -#define SYST_VAL                (SYST_BASE + 0x4)
> -
> -#define SYST_CON_REG(to)        (timer_of_base(to) + SYST_CON)
> -#define SYST_VAL_REG(to)        (timer_of_base(to) + SYST_VAL)
> -
> -/*
> - * SYST_CON_EN: Clock enable. Shall be set to
> - *   - Start timer countdown.
> - *   - Allow timeout ticks being updated.
> - *   - Allow changing interrupt functions.
> - *
> - * SYST_CON_IRQ_EN: Set to allow interrupt.
> - *
> - * SYST_CON_IRQ_CLR: Set to clear interrupt.
> - */
> -#define SYST_CON_EN              BIT(0)
> -#define SYST_CON_IRQ_EN          BIT(1)
> -#define SYST_CON_IRQ_CLR         BIT(4)
> -
>  static void __iomem *gpt_sched_reg __read_mostly;
>  
> -static void mtk_syst_ack_irq(struct timer_of *to)
> -{
> -	/* Clear and disable interrupt */
> -	writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to));
> -}
> -
> -static irqreturn_t mtk_syst_handler(int irq, void *dev_id)
> -{
> -	struct clock_event_device *clkevt = dev_id;
> -	struct timer_of *to = to_timer_of(clkevt);
> -
> -	mtk_syst_ack_irq(to);
> -	clkevt->event_handler(clkevt);
> -
> -	return IRQ_HANDLED;
> -}
> -
> -static int mtk_syst_clkevt_next_event(unsigned long ticks,
> -				      struct clock_event_device *clkevt)
> -{
> -	struct timer_of *to = to_timer_of(clkevt);
> -
> -	/* Enable clock to allow timeout tick update later */
> -	writel(SYST_CON_EN, SYST_CON_REG(to));
> -
> -	/*
> -	 * Write new timeout ticks. Timer shall start countdown
> -	 * after timeout ticks are updated.
> -	 */
> -	writel(ticks, SYST_VAL_REG(to));
> -
> -	/* Enable interrupt */
> -	writel(SYST_CON_EN | SYST_CON_IRQ_EN, SYST_CON_REG(to));
> -
> -	return 0;
> -}
> -
> -static int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt)
> -{
> -	/* Disable timer */
> -	writel(0, SYST_CON_REG(to_timer_of(clkevt)));
> -
> -	return 0;
> -}
> -
> -static int mtk_syst_clkevt_resume(struct clock_event_device *clkevt)
> -{
> -	return mtk_syst_clkevt_shutdown(clkevt);
> -}
> -
> -static int mtk_syst_clkevt_oneshot(struct clock_event_device *clkevt)
> -{
> -	return 0;
> -}
> -
>  static u64 notrace mtk_gpt_read_sched_clock(void)
>  {
>  	return readl_relaxed(gpt_sched_reg);
> @@ -255,27 +177,6 @@ static struct timer_of to = {
>  	},
>  };
>  
> -static int __init mtk_syst_init(struct device_node *node)
> -{
> -	int ret;
> -
> -	to.clkevt.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT;
> -	to.clkevt.set_state_shutdown = mtk_syst_clkevt_shutdown;
> -	to.clkevt.set_state_oneshot = mtk_syst_clkevt_oneshot;
> -	to.clkevt.tick_resume = mtk_syst_clkevt_resume;
> -	to.clkevt.set_next_event = mtk_syst_clkevt_next_event;
> -	to.of_irq.handler = mtk_syst_handler;
> -
> -	ret = timer_of_init(node, &to);
> -	if (ret)
> -		return ret;
> -
> -	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
> -					TIMER_SYNC_TICKS, 0xffffffff);
> -
> -	return 0;
> -}
> -
>  static int __init mtk_gpt_init(struct device_node *node)
>  {
>  	int ret;
> @@ -310,4 +211,3 @@ static int __init mtk_gpt_init(struct device_node *node)
>  	return 0;
>  }
>  TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
> -TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
> diff --git a/drivers/clocksource/timer-mediatek-mt6765.c b/drivers/clocksource/timer-mediatek-mt6765.c
> new file mode 100644
> index 000000000000..b4f22f226feb
> --- /dev/null
> +++ b/drivers/clocksource/timer-mediatek-mt6765.c
> @@ -0,0 +1,135 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Mediatek SoCs General-Purpose Timer handling.
> + *
> + * Copyright (C) 2014 Matthias Brugger
> + *
> + * Matthias Brugger <matthias.bgg@gmail.com>
> + */
> +
> +#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
> +
> +#include <linux/clockchips.h>
> +#include <linux/clocksource.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqreturn.h>
> +#include <linux/sched_clock.h>
> +#include <linux/slab.h>
> +#include "timer-of.h"
> +
> +#define TIMER_SYNC_TICKS        (3)
> +
> +/* system timer */
> +#define SYST_BASE               (0x40)
> +
> +#define SYST_CON                (SYST_BASE + 0x0)
> +#define SYST_VAL                (SYST_BASE + 0x4)
> +
> +#define SYST_CON_REG(to)        (timer_of_base(to) + SYST_CON)
> +#define SYST_VAL_REG(to)        (timer_of_base(to) + SYST_VAL)
> +
> +/*
> + * SYST_CON_EN: Clock enable. Shall be set to
> + *   - Start timer countdown.
> + *   - Allow timeout ticks being updated.
> + *   - Allow changing interrupt functions.
> + *
> + * SYST_CON_IRQ_EN: Set to allow interrupt.
> + *
> + * SYST_CON_IRQ_CLR: Set to clear interrupt.
> + */
> +#define SYST_CON_EN              BIT(0)
> +#define SYST_CON_IRQ_EN          BIT(1)
> +#define SYST_CON_IRQ_CLR         BIT(4)
> +
> +static void mtk_syst_ack_irq(struct timer_of *to)
> +{
> +	/* Clear and disable interrupt */
> +	writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to));
> +}
> +
> +static irqreturn_t mtk_syst_handler(int irq, void *dev_id)
> +{
> +	struct clock_event_device *clkevt = dev_id;
> +	struct timer_of *to = to_timer_of(clkevt);
> +
> +	mtk_syst_ack_irq(to);
> +	clkevt->event_handler(clkevt);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int mtk_syst_clkevt_next_event(unsigned long ticks,
> +				      struct clock_event_device *clkevt)
> +{
> +	struct timer_of *to = to_timer_of(clkevt);
> +
> +	/* Enable clock to allow timeout tick update later */
> +	writel(SYST_CON_EN, SYST_CON_REG(to));
> +
> +	/*
> +	 * Write new timeout ticks. Timer shall start countdown
> +	 * after timeout ticks are updated.
> +	 */
> +	writel(ticks, SYST_VAL_REG(to));
> +
> +	/* Enable interrupt */
> +	writel(SYST_CON_EN | SYST_CON_IRQ_EN, SYST_CON_REG(to));
> +
> +	return 0;
> +}
> +
> +static int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt)
> +{
> +	/* Disable timer */
> +	writel(0, SYST_CON_REG(to_timer_of(clkevt)));
> +
> +	return 0;
> +}
> +
> +static int mtk_syst_clkevt_resume(struct clock_event_device *clkevt)
> +{
> +	return mtk_syst_clkevt_shutdown(clkevt);
> +}
> +
> +static int mtk_syst_clkevt_oneshot(struct clock_event_device *clkevt)
> +{
> +	return 0;
> +}
> +
> +static struct timer_of to = {
> +	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
> +
> +	.clkevt = {
> +		.name = "mtk-clkevt",
> +		.rating = 300,
> +		.cpumask = cpu_possible_mask,
> +	},
> +
> +	.of_irq = {
> +		.flags = IRQF_TIMER | IRQF_IRQPOLL,
> +	},
> +};
> +
> +static int __init mtk_syst_init(struct device_node *node)
> +{
> +	int ret;
> +
> +	to.clkevt.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT;
> +	to.clkevt.set_state_shutdown = mtk_syst_clkevt_shutdown;
> +	to.clkevt.set_state_oneshot = mtk_syst_clkevt_oneshot;
> +	to.clkevt.tick_resume = mtk_syst_clkevt_resume;
> +	to.clkevt.set_next_event = mtk_syst_clkevt_next_event;
> +	to.of_irq.handler = mtk_syst_handler;
> +
> +	ret = timer_of_init(node, &to);
> +	if (ret)
> +		return ret;
> +
> +	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
> +					TIMER_SYNC_TICKS, 0xffffffff);
> +
> +	return 0;
> +}
> +
> +TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
> 


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files
  2021-03-22 11:19 ` [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files Daniel Lezcano
@ 2021-03-24  0:53   ` Evan Benn
  0 siblings, 0 replies; 6+ messages in thread
From: Evan Benn @ 2021-03-24  0:53 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: LKML, Thomas Gleixner, Yingjoe Chen, Julia Lawall,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Stanley Chu, Matthias Brugger, Viresh Kumar, Fabien Parent,
	moderated list:ARM/Mediatek SoC support, Alexey Klimov,
	Catalin Marinas, Russell King, Will Deacon

On Mon, Mar 22, 2021 at 10:19 PM Daniel Lezcano
<daniel.lezcano@linaro.org> wrote:
>
>
> Hi Evan,
>
> On 18/03/2021 06:04, Evan Benn wrote:
> > mtk_gpt and mtk_syst drivers for mt6577 and mt6765 devices were not
> > sharing any code. So split them into separate files.
>
> For the sake of consistency, keeping all in one is better.

Thanks Daniel,

I think you are right.
The other patch does apply cleanly without this one, so please just
ignore this patch.

>
> Thanks
>   -- Daniel
>
> > Signed-off-by: Evan Benn <evanbenn@chromium.org>
> > ---
> >
> >  arch/arm/mach-mediatek/Kconfig                |   3 +-
> >  arch/arm64/Kconfig.platforms                  |   3 +-
> >  drivers/clocksource/Kconfig                   |  13 +-
> >  drivers/clocksource/Makefile                  |   3 +-
> >  ...mer-mediatek.c => timer-mediatek-mt6577.c} | 100 -------------
> >  drivers/clocksource/timer-mediatek-mt6765.c   | 135 ++++++++++++++++++
> >  6 files changed, 151 insertions(+), 106 deletions(-)
> >  rename drivers/clocksource/{timer-mediatek.c => timer-mediatek-mt6577.c} (69%)
> >  create mode 100644 drivers/clocksource/timer-mediatek-mt6765.c
> >
> > diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
> > index 9e0f592d87d8..8686f992c4b6 100644
> > --- a/arch/arm/mach-mediatek/Kconfig
> > +++ b/arch/arm/mach-mediatek/Kconfig
> > @@ -4,7 +4,8 @@ menuconfig ARCH_MEDIATEK
> >       depends on ARCH_MULTI_V7
> >       select ARM_GIC
> >       select PINCTRL
> > -     select MTK_TIMER
> > +     select TIMER_MEDIATEK_MT6577
> > +     select TIMER_MEDIATEK_MT6765
> >       select MFD_SYSCON
> >       help
> >         Support for Mediatek MT65xx & MT81xx SoCs
> > diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> > index cdfd5fed457f..d4752375ab0b 100644
> > --- a/arch/arm64/Kconfig.platforms
> > +++ b/arch/arm64/Kconfig.platforms
> > @@ -161,7 +161,8 @@ config ARCH_MEDIATEK
> >       bool "MediaTek SoC Family"
> >       select ARM_GIC
> >       select PINCTRL
> > -     select MTK_TIMER
> > +     select TIMER_MEDIATEK_MT6577
> > +     select TIMER_MEDIATEK_MT6765
> >       help
> >         This enables support for MediaTek MT27xx, MT65xx, MT76xx
> >         & MT81xx ARMv8 SoCs
> > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> > index 39aa21d01e05..d697c799284e 100644
> > --- a/drivers/clocksource/Kconfig
> > +++ b/drivers/clocksource/Kconfig
> > @@ -438,13 +438,20 @@ config OXNAS_RPS_TIMER
> >  config SYS_SUPPORTS_SH_CMT
> >       bool
> >
> > -config MTK_TIMER
> > -     bool "Mediatek timer driver" if COMPILE_TEST
> > +config TIMER_MEDIATEK_MT6577
> > +     bool "Mediatek mt6577 timer driver" if COMPILE_TEST
> >       depends on HAS_IOMEM
> >       select TIMER_OF
> >       select CLKSRC_MMIO
> >       help
> > -       Support for Mediatek timer driver.
> > +       Enables clocksource and clockevent driver for Mediatek mt6577 timer.
> > +
> > +config TIMER_MEDIATEK_MT6765
> > +     bool "Mediatek mt6765 timer driver" if COMPILE_TEST
> > +     depends on HAS_IOMEM
> > +     select TIMER_OF
> > +     help
> > +       Enables clockevent driver for Mediatek mt6765 timer.
> >
> >  config SPRD_TIMER
> >       bool "Spreadtrum timer driver" if EXPERT
> > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> > index c17ee32a7151..b1f06ce114f9 100644
> > --- a/drivers/clocksource/Makefile
> > +++ b/drivers/clocksource/Makefile
> > @@ -49,7 +49,8 @@ obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)    += samsung_pwm_timer.o
> >  obj-$(CONFIG_FSL_FTM_TIMER)  += timer-fsl-ftm.o
> >  obj-$(CONFIG_VF_PIT_TIMER)   += timer-vf-pit.o
> >  obj-$(CONFIG_CLKSRC_QCOM)    += timer-qcom.o
> > -obj-$(CONFIG_MTK_TIMER)              += timer-mediatek.o
> > +obj-$(CONFIG_TIMER_MEDIATEK_MT6577)          += timer-mediatek-mt6577.o
> > +obj-$(CONFIG_TIMER_MEDIATEK_MT6765)          += timer-mediatek-mt6765.o
> >  obj-$(CONFIG_CLKSRC_PISTACHIO)       += timer-pistachio.o
> >  obj-$(CONFIG_CLKSRC_TI_32K)  += timer-ti-32k.o
> >  obj-$(CONFIG_OXNAS_RPS_TIMER)        += timer-oxnas-rps.o
> > diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek-mt6577.c
> > similarity index 69%
> > rename from drivers/clocksource/timer-mediatek.c
> > rename to drivers/clocksource/timer-mediatek-mt6577.c
> > index 9318edcd8963..9e5241d1876d 100644
> > --- a/drivers/clocksource/timer-mediatek.c
> > +++ b/drivers/clocksource/timer-mediatek-mt6577.c
> > @@ -47,86 +47,8 @@
> >  #define GPT_CNT_REG(val)        (0x08 + (0x10 * (val)))
> >  #define GPT_CMP_REG(val)        (0x0C + (0x10 * (val)))
> >
> > -/* system timer */
> > -#define SYST_BASE               (0x40)
> > -
> > -#define SYST_CON                (SYST_BASE + 0x0)
> > -#define SYST_VAL                (SYST_BASE + 0x4)
> > -
> > -#define SYST_CON_REG(to)        (timer_of_base(to) + SYST_CON)
> > -#define SYST_VAL_REG(to)        (timer_of_base(to) + SYST_VAL)
> > -
> > -/*
> > - * SYST_CON_EN: Clock enable. Shall be set to
> > - *   - Start timer countdown.
> > - *   - Allow timeout ticks being updated.
> > - *   - Allow changing interrupt functions.
> > - *
> > - * SYST_CON_IRQ_EN: Set to allow interrupt.
> > - *
> > - * SYST_CON_IRQ_CLR: Set to clear interrupt.
> > - */
> > -#define SYST_CON_EN              BIT(0)
> > -#define SYST_CON_IRQ_EN          BIT(1)
> > -#define SYST_CON_IRQ_CLR         BIT(4)
> > -
> >  static void __iomem *gpt_sched_reg __read_mostly;
> >
> > -static void mtk_syst_ack_irq(struct timer_of *to)
> > -{
> > -     /* Clear and disable interrupt */
> > -     writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to));
> > -}
> > -
> > -static irqreturn_t mtk_syst_handler(int irq, void *dev_id)
> > -{
> > -     struct clock_event_device *clkevt = dev_id;
> > -     struct timer_of *to = to_timer_of(clkevt);
> > -
> > -     mtk_syst_ack_irq(to);
> > -     clkevt->event_handler(clkevt);
> > -
> > -     return IRQ_HANDLED;
> > -}
> > -
> > -static int mtk_syst_clkevt_next_event(unsigned long ticks,
> > -                                   struct clock_event_device *clkevt)
> > -{
> > -     struct timer_of *to = to_timer_of(clkevt);
> > -
> > -     /* Enable clock to allow timeout tick update later */
> > -     writel(SYST_CON_EN, SYST_CON_REG(to));
> > -
> > -     /*
> > -      * Write new timeout ticks. Timer shall start countdown
> > -      * after timeout ticks are updated.
> > -      */
> > -     writel(ticks, SYST_VAL_REG(to));
> > -
> > -     /* Enable interrupt */
> > -     writel(SYST_CON_EN | SYST_CON_IRQ_EN, SYST_CON_REG(to));
> > -
> > -     return 0;
> > -}
> > -
> > -static int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt)
> > -{
> > -     /* Disable timer */
> > -     writel(0, SYST_CON_REG(to_timer_of(clkevt)));
> > -
> > -     return 0;
> > -}
> > -
> > -static int mtk_syst_clkevt_resume(struct clock_event_device *clkevt)
> > -{
> > -     return mtk_syst_clkevt_shutdown(clkevt);
> > -}
> > -
> > -static int mtk_syst_clkevt_oneshot(struct clock_event_device *clkevt)
> > -{
> > -     return 0;
> > -}
> > -
> >  static u64 notrace mtk_gpt_read_sched_clock(void)
> >  {
> >       return readl_relaxed(gpt_sched_reg);
> > @@ -255,27 +177,6 @@ static struct timer_of to = {
> >       },
> >  };
> >
> > -static int __init mtk_syst_init(struct device_node *node)
> > -{
> > -     int ret;
> > -
> > -     to.clkevt.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT;
> > -     to.clkevt.set_state_shutdown = mtk_syst_clkevt_shutdown;
> > -     to.clkevt.set_state_oneshot = mtk_syst_clkevt_oneshot;
> > -     to.clkevt.tick_resume = mtk_syst_clkevt_resume;
> > -     to.clkevt.set_next_event = mtk_syst_clkevt_next_event;
> > -     to.of_irq.handler = mtk_syst_handler;
> > -
> > -     ret = timer_of_init(node, &to);
> > -     if (ret)
> > -             return ret;
> > -
> > -     clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
> > -                                     TIMER_SYNC_TICKS, 0xffffffff);
> > -
> > -     return 0;
> > -}
> > -
> >  static int __init mtk_gpt_init(struct device_node *node)
> >  {
> >       int ret;
> > @@ -310,4 +211,3 @@ static int __init mtk_gpt_init(struct device_node *node)
> >       return 0;
> >  }
> >  TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
> > -TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
> > diff --git a/drivers/clocksource/timer-mediatek-mt6765.c b/drivers/clocksource/timer-mediatek-mt6765.c
> > new file mode 100644
> > index 000000000000..b4f22f226feb
> > --- /dev/null
> > +++ b/drivers/clocksource/timer-mediatek-mt6765.c
> > @@ -0,0 +1,135 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Mediatek SoCs General-Purpose Timer handling.
> > + *
> > + * Copyright (C) 2014 Matthias Brugger
> > + *
> > + * Matthias Brugger <matthias.bgg@gmail.com>
> > + */
> > +
> > +#define pr_fmt(fmt)  KBUILD_MODNAME ": " fmt
> > +
> > +#include <linux/clockchips.h>
> > +#include <linux/clocksource.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irqreturn.h>
> > +#include <linux/sched_clock.h>
> > +#include <linux/slab.h>
> > +#include "timer-of.h"
> > +
> > +#define TIMER_SYNC_TICKS        (3)
> > +
> > +/* system timer */
> > +#define SYST_BASE               (0x40)
> > +
> > +#define SYST_CON                (SYST_BASE + 0x0)
> > +#define SYST_VAL                (SYST_BASE + 0x4)
> > +
> > +#define SYST_CON_REG(to)        (timer_of_base(to) + SYST_CON)
> > +#define SYST_VAL_REG(to)        (timer_of_base(to) + SYST_VAL)
> > +
> > +/*
> > + * SYST_CON_EN: Clock enable. Shall be set to
> > + *   - Start timer countdown.
> > + *   - Allow timeout ticks being updated.
> > + *   - Allow changing interrupt functions.
> > + *
> > + * SYST_CON_IRQ_EN: Set to allow interrupt.
> > + *
> > + * SYST_CON_IRQ_CLR: Set to clear interrupt.
> > + */
> > +#define SYST_CON_EN              BIT(0)
> > +#define SYST_CON_IRQ_EN          BIT(1)
> > +#define SYST_CON_IRQ_CLR         BIT(4)
> > +
> > +static void mtk_syst_ack_irq(struct timer_of *to)
> > +{
> > +     /* Clear and disable interrupt */
> > +     writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to));
> > +}
> > +
> > +static irqreturn_t mtk_syst_handler(int irq, void *dev_id)
> > +{
> > +     struct clock_event_device *clkevt = dev_id;
> > +     struct timer_of *to = to_timer_of(clkevt);
> > +
> > +     mtk_syst_ack_irq(to);
> > +     clkevt->event_handler(clkevt);
> > +
> > +     return IRQ_HANDLED;
> > +}
> > +
> > +static int mtk_syst_clkevt_next_event(unsigned long ticks,
> > +                                   struct clock_event_device *clkevt)
> > +{
> > +     struct timer_of *to = to_timer_of(clkevt);
> > +
> > +     /* Enable clock to allow timeout tick update later */
> > +     writel(SYST_CON_EN, SYST_CON_REG(to));
> > +
> > +     /*
> > +      * Write new timeout ticks. Timer shall start countdown
> > +      * after timeout ticks are updated.
> > +      */
> > +     writel(ticks, SYST_VAL_REG(to));
> > +
> > +     /* Enable interrupt */
> > +     writel(SYST_CON_EN | SYST_CON_IRQ_EN, SYST_CON_REG(to));
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt)
> > +{
> > +     /* Disable timer */
> > +     writel(0, SYST_CON_REG(to_timer_of(clkevt)));
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_syst_clkevt_resume(struct clock_event_device *clkevt)
> > +{
> > +     return mtk_syst_clkevt_shutdown(clkevt);
> > +}
> > +
> > +static int mtk_syst_clkevt_oneshot(struct clock_event_device *clkevt)
> > +{
> > +     return 0;
> > +}
> > +
> > +static struct timer_of to = {
> > +     .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
> > +
> > +     .clkevt = {
> > +             .name = "mtk-clkevt",
> > +             .rating = 300,
> > +             .cpumask = cpu_possible_mask,
> > +     },
> > +
> > +     .of_irq = {
> > +             .flags = IRQF_TIMER | IRQF_IRQPOLL,
> > +     },
> > +};
> > +
> > +static int __init mtk_syst_init(struct device_node *node)
> > +{
> > +     int ret;
> > +
> > +     to.clkevt.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT;
> > +     to.clkevt.set_state_shutdown = mtk_syst_clkevt_shutdown;
> > +     to.clkevt.set_state_oneshot = mtk_syst_clkevt_oneshot;
> > +     to.clkevt.tick_resume = mtk_syst_clkevt_resume;
> > +     to.clkevt.set_next_event = mtk_syst_clkevt_next_event;
> > +     to.of_irq.handler = mtk_syst_handler;
> > +
> > +     ret = timer_of_init(node, &to);
> > +     if (ret)
> > +             return ret;
> > +
> > +     clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
> > +                                     TIMER_SYNC_TICKS, 0xffffffff);
> > +
> > +     return 0;
> > +}
> > +
> > +TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
> >
>
>
> --
> <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files
  2021-03-18  5:04 [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files Evan Benn
  2021-03-18  5:04 ` [PATCH 2/2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown Evan Benn
  2021-03-22 11:19 ` [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files Daniel Lezcano
@ 2021-03-29 15:33 ` Matthias Brugger
  2 siblings, 0 replies; 6+ messages in thread
From: Matthias Brugger @ 2021-03-29 15:33 UTC (permalink / raw)
  To: Evan Benn, LKML, Stanley Chu
  Cc: Thomas Gleixner, Yingjoe Chen, Julia Lawall, linux-arm-kernel,
	Stanley Chu, Daniel Lezcano, Viresh Kumar, Fabien Parent,
	linux-mediatek, Alexey Klimov, Catalin Marinas, Russell King,
	Will Deacon



On 18/03/2021 06:04, Evan Benn wrote:
> mtk_gpt and mtk_syst drivers for mt6577 and mt6765 devices were not
> sharing any code. So split them into separate files.
> 
> Signed-off-by: Evan Benn <evanbenn@chromium.org>
> ---
> 
>  arch/arm/mach-mediatek/Kconfig                |   3 +-
>  arch/arm64/Kconfig.platforms                  |   3 +-
>  drivers/clocksource/Kconfig                   |  13 +-
>  drivers/clocksource/Makefile                  |   3 +-
>  ...mer-mediatek.c => timer-mediatek-mt6577.c} | 100 -------------
>  drivers/clocksource/timer-mediatek-mt6765.c   | 135 ++++++++++++++++++
>  6 files changed, 151 insertions(+), 106 deletions(-)
>  rename drivers/clocksource/{timer-mediatek.c => timer-mediatek-mt6577.c} (69%)
>  create mode 100644 drivers/clocksource/timer-mediatek-mt6765.c
> 
[...]
> diff --git a/drivers/clocksource/timer-mediatek-mt6765.c b/drivers/clocksource/timer-mediatek-mt6765.c
> new file mode 100644
> index 000000000000..b4f22f226feb
> --- /dev/null
> +++ b/drivers/clocksource/timer-mediatek-mt6765.c
> @@ -0,0 +1,135 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Mediatek SoCs General-Purpose Timer handling.
> + *
> + * Copyright (C) 2014 Matthias Brugger
> + *
> + * Matthias Brugger <matthias.bgg@gmail.com>

The mt6765 was written by Stanley, I think we should reflcet that. Please see:
e3af677607d9 ("clocksource/drivers/timer-mediatek: Add support for system timer")

Regards,
Matthias

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-03-29 15:33 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-18  5:04 [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files Evan Benn
2021-03-18  5:04 ` [PATCH 2/2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown Evan Benn
2021-03-18 23:46   ` Evan Benn
2021-03-22 11:19 ` [PATCH 1/2] drivers/clocksource/mediatek: Split mediatek drivers into 2 files Daniel Lezcano
2021-03-24  0:53   ` Evan Benn
2021-03-29 15:33 ` Matthias Brugger

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).