All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
@ 2022-12-05 14:59 Biju Das
  2022-12-05 14:59 ` [PATCH 1/6] clk: renesas: r9a09g011: Add TIM clock and reset entries Biju Das
                   ` (6 more replies)
  0 siblings, 7 replies; 21+ messages in thread
From: Biju Das @ 2022-12-05 14:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Philipp Zabel,
	William Breathitt Gray, Michael Turquette, Stephen Boyd
  Cc: Biju Das, Daniel Lezcano, Thomas Gleixner, devicetree,
	Geert Uytterhoeven, Magnus Damm, linux-renesas-soc, linux-clk,
	linux-iio, Lad Prabhakar, Fabrizio Castro

This patch series aims to add support for Compare-Match Timer (TIM)
module found on RZ/V2M SoC.

it is composed of 32 channels and channels 0-7 and 24-32 are
reserved for ISP usage.

Channel 22 is modelled as clock source and Channel 23 is modelled as clock
event driver and the rest of the channels are modelled as counter driver
as it provides

1) counter for counting
2) configurable counter value for generating timer interrupt
3) userspace event for each interrupt.

logs:-
Counter driver:
Counter driver is tested by reading counts and interrupts tested by
counter-example in tools/counter/counter_example.c

Count snapshot value:
3114
Output from counter_example when it triggers interrupts:
Timestamp 0: 24142152969        Count 0: 5
Error Message 0: Success

Clock source:
Clock source driver is tested by clock-source-switch app.
[ 1275.703567] clocksource: Switched to clocksource arch_sys_counter
[ 1275.710189] clocksource: Switched to clocksource a4000b00.timer
[OK]
# Totals: pass[ 1275.718112] clocksource: Switched to clocksource arch_sys_counter
:0 fail:0 xfail:0 xpass:0 skip:0 error:0
# Totals: pass:0 fail:0 xfail:0 xpass:0 skip:0 error:0

Clock event:
clock event driver is tested by changing the rating as 500.

Biju Das (6):
  clk: renesas: r9a09g011: Add TIM clock and reset entries
  dt-bindings: timer: Add RZ/V2M TIM binding
  clocksource/drivers/rzv2m-tim: Add Renesas RZ/V2M compare match
    timer(TIM) driver
  dt-bindings: counter: Add RZ/V2M TIM counter binding
  counter: Add Renesas RZ/V2M TIM counter driver
  arm64: dts: renesas: r9a09g011: Add tim nodes

 .../counter/renesas,rzv2m-tim-cnt.yaml        |  83 +++++
 .../bindings/timer/renesas,rzv2m-tim.yaml     |  83 +++++
 arch/arm64/boot/dts/renesas/r9a09g011.dtsi    | 192 ++++++++++
 drivers/clk/renesas/r9a09g011-cpg.c           |  22 ++
 drivers/clocksource/Kconfig                   |   7 +
 drivers/clocksource/Makefile                  |   1 +
 drivers/clocksource/rzv2m-tim.c               | 330 ++++++++++++++++++
 drivers/counter/Kconfig                       |  10 +
 drivers/counter/Makefile                      |   1 +
 drivers/counter/rzv2m-tim-cnt.c               | 312 +++++++++++++++++
 10 files changed, 1041 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/counter/renesas,rzv2m-tim-cnt.yaml
 create mode 100644 Documentation/devicetree/bindings/timer/renesas,rzv2m-tim.yaml
 create mode 100644 drivers/clocksource/rzv2m-tim.c
 create mode 100644 drivers/counter/rzv2m-tim-cnt.c

-- 
2.25.1


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

* [PATCH 1/6] clk: renesas: r9a09g011: Add TIM clock and reset entries
  2022-12-05 14:59 [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Biju Das
@ 2022-12-05 14:59 ` Biju Das
  2022-12-21 14:47   ` Geert Uytterhoeven
  2022-12-05 14:59 ` [PATCH 2/6] dt-bindings: timer: Add RZ/V2M TIM binding Biju Das
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Biju Das @ 2022-12-05 14:59 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: Biju Das, Geert Uytterhoeven, linux-renesas-soc, linux-clk,
	Lad Prabhakar, Fabrizio Castro

Add Compare-Match Timer (TIM) clock and reset entries to CPG
driver.

The TIM IP on the RZ/V2M comes with 32 channels, but the ISP has
full control of channels 0 to 7, and channels 24 to 31. Therefore
Linux is only allowed to use channels 8 to 23.

The TIM has shared peripheral clock with other modules, so mark it
as critical clock.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/clk/renesas/r9a09g011-cpg.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/clk/renesas/r9a09g011-cpg.c b/drivers/clk/renesas/r9a09g011-cpg.c
index dd5e442ec4a9..b32f82860b2b 100644
--- a/drivers/clk/renesas/r9a09g011-cpg.c
+++ b/drivers/clk/renesas/r9a09g011-cpg.c
@@ -133,7 +133,25 @@ static const struct rzg2l_mod_clk r9a09g011_mod_clks[] __initconst = {
 	DEF_MOD("eth_clk_gptp",	R9A09G011_ETH0_GPTP_EXT, CLK_PLL2_100, 0x40c, 9),
 	DEF_MOD("syc_cnt_clk",	R9A09G011_SYC_CNT_CLK,	 CLK_MAIN_24,  0x41c, 12),
 	DEF_MOD("iic_pclk0",	R9A09G011_IIC_PCLK0,	 CLK_SEL_E,    0x420, 12),
+	DEF_MOD("cperi_grpb",	R9A09G011_CPERI_GRPB_PCLK, CLK_SEL_E,  0x424, 0),
+	DEF_MOD("tim_clk_8",	R9A09G011_TIM8_CLK,	 CLK_MAIN_2,   0x424, 4),
+	DEF_MOD("tim_clk_9",	R9A09G011_TIM9_CLK,	 CLK_MAIN_2,   0x424, 5),
+	DEF_MOD("tim_clk_10",	R9A09G011_TIM10_CLK,	 CLK_MAIN_2,   0x424, 6),
+	DEF_MOD("tim_clk_11",	R9A09G011_TIM11_CLK,	 CLK_MAIN_2,   0x424, 7),
+	DEF_MOD("tim_clk_12",	R9A09G011_TIM12_CLK,	 CLK_MAIN_2,   0x424, 8),
+	DEF_MOD("tim_clk_13",	R9A09G011_TIM13_CLK,	 CLK_MAIN_2,   0x424, 9),
+	DEF_MOD("tim_clk_14",	R9A09G011_TIM14_CLK,	 CLK_MAIN_2,   0x424, 10),
+	DEF_MOD("tim_clk_15",	R9A09G011_TIM15_CLK,	 CLK_MAIN_2,   0x424, 11),
 	DEF_MOD("iic_pclk1",	R9A09G011_IIC_PCLK1,	 CLK_SEL_E,    0x424, 12),
+	DEF_MOD("cperi_grpc",	R9A09G011_CPERI_GRPC_PCLK, CLK_SEL_E,  0x428, 0),
+	DEF_MOD("tim_clk_16",	R9A09G011_TIM16_CLK,	 CLK_MAIN_2,   0x428, 4),
+	DEF_MOD("tim_clk_17",	R9A09G011_TIM17_CLK,	 CLK_MAIN_2,   0x428, 5),
+	DEF_MOD("tim_clk_18",	R9A09G011_TIM18_CLK,	 CLK_MAIN_2,   0x428, 6),
+	DEF_MOD("tim_clk_19",	R9A09G011_TIM19_CLK,	 CLK_MAIN_2,   0x428, 7),
+	DEF_MOD("tim_clk_20",	R9A09G011_TIM20_CLK,	 CLK_MAIN_2,   0x428, 8),
+	DEF_MOD("tim_clk_21",	R9A09G011_TIM21_CLK,	 CLK_MAIN_2,   0x428, 9),
+	DEF_MOD("tim_clk_22",	R9A09G011_TIM22_CLK,	 CLK_MAIN_2,   0x428, 10),
+	DEF_MOD("tim_clk_23",	R9A09G011_TIM23_CLK,	 CLK_MAIN_2,   0x428, 11),
 	DEF_MOD("wdt0_pclk",	R9A09G011_WDT0_PCLK,	 CLK_SEL_E,    0x428, 12),
 	DEF_MOD("wdt0_clk",	R9A09G011_WDT0_CLK,	 CLK_MAIN,     0x428, 13),
 	DEF_MOD("cperi_grpf",	R9A09G011_CPERI_GRPF_PCLK, CLK_SEL_E,  0x434, 0),
@@ -153,6 +171,8 @@ static const struct rzg2l_reset r9a09g011_resets[] = {
 	DEF_RST(R9A09G011_PFC_PRESETN,		0x600, 2),
 	DEF_RST_MON(R9A09G011_ETH0_RST_HW_N,	0x608, 11, 11),
 	DEF_RST_MON(R9A09G011_SYC_RST_N,	0x610, 9,  13),
+	DEF_RST(R9A09G011_TIM_GPB_PRESETN,	0x614, 1),
+	DEF_RST(R9A09G011_TIM_GPC_PRESETN,	0x614, 2),
 	DEF_RST(R9A09G011_IIC_GPA_PRESETN,	0x614, 8),
 	DEF_RST(R9A09G011_IIC_GPB_PRESETN,	0x614, 9),
 	DEF_RST_MON(R9A09G011_PWM_GPF_PRESETN,	0x614, 5, 23),
@@ -161,6 +181,8 @@ static const struct rzg2l_reset r9a09g011_resets[] = {
 
 static const unsigned int r9a09g011_crit_mod_clks[] __initconst = {
 	MOD_CLK_BASE + R9A09G011_CA53_CLK,
+	MOD_CLK_BASE + R9A09G011_CPERI_GRPB_PCLK,
+	MOD_CLK_BASE + R9A09G011_CPERI_GRPC_PCLK,
 	MOD_CLK_BASE + R9A09G011_CPERI_GRPF_PCLK,
 	MOD_CLK_BASE + R9A09G011_GIC_CLK,
 	MOD_CLK_BASE + R9A09G011_SYC_CNT_CLK,
-- 
2.25.1


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

* [PATCH 2/6] dt-bindings: timer: Add RZ/V2M TIM binding
  2022-12-05 14:59 [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Biju Das
  2022-12-05 14:59 ` [PATCH 1/6] clk: renesas: r9a09g011: Add TIM clock and reset entries Biju Das
@ 2022-12-05 14:59 ` Biju Das
  2022-12-05 14:59 ` [PATCH 3/6] clocksource/drivers/rzv2m-tim: Add Renesas RZ/V2M compare match timer(TIM) driver Biju Das
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Biju Das @ 2022-12-05 14:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski
  Cc: Biju Das, Daniel Lezcano, Thomas Gleixner, devicetree,
	Geert Uytterhoeven, Fabrizio Castro, linux-renesas-soc

Add device tree bindings for the RZ/V2{M, MA} Compare Match Timer
(TIM).

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 .../bindings/timer/renesas,rzv2m-tim.yaml     | 83 +++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/renesas,rzv2m-tim.yaml

diff --git a/Documentation/devicetree/bindings/timer/renesas,rzv2m-tim.yaml b/Documentation/devicetree/bindings/timer/renesas,rzv2m-tim.yaml
new file mode 100644
index 000000000000..9d692725bcbb
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/renesas,rzv2m-tim.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/timer/renesas,rzv2m-tim.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/V2M Compare Match Timer (TIM)
+
+maintainers:
+  - Biju Das <biju.das.jz@bp.renesas.com>
+
+description: |
+  The Compare Match Timer(TIM) on RZ/V2M like SoCs has an internal 32-bit
+  counter that can be used as an interval timer. This LSI has a total of 32
+  channels of TIM from ch. 0 to ch. 31. It supports the following features
+  * Configured with a 32-bit counter operating at INCLOCK (2 MHz)
+  * The clock input from the count clock input pin can be divided by 2, 4,
+    8, 16, 32, 64, 128, or 256, and one of these divided clocks can be
+    used as the count clock.
+  * The counter period can be set in the range of 1 to 4294967296
+    (32-bit timer) using the selected divider clock as the count clock.
+  * Generates an interrupt request signal every cycle set in the TIM
+    counter.
+  * The counter operation and the bus interface are asynchronous and
+    can operate independently regardless of the size of the respective
+    clock cycles.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r9a09g011-tim  # RZ/V2M
+          - renesas,r9a09g055-tim  # RZ/V2MA
+      - const: renesas,rzv2m-tim
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: APB clock
+      - description: TIM clock
+
+  clock-names:
+    items:
+      - const: apb
+      - const: tim
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - power-domains
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r9a09g011-cpg.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tim22: tim@a4000b00 {
+        compatible = "renesas,r9a09g011-tim", "renesas,rzv2m-tim";
+        reg = <0xa4000b00 0x80>;
+        interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+                 <&cpg CPG_MOD R9A09G011_TIM22_CLK>;
+        clock-names = "apb", "tim";
+        power-domains = <&cpg>;
+        resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+    };
-- 
2.25.1


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

* [PATCH 3/6] clocksource/drivers/rzv2m-tim: Add Renesas RZ/V2M compare match timer(TIM) driver
  2022-12-05 14:59 [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Biju Das
  2022-12-05 14:59 ` [PATCH 1/6] clk: renesas: r9a09g011: Add TIM clock and reset entries Biju Das
  2022-12-05 14:59 ` [PATCH 2/6] dt-bindings: timer: Add RZ/V2M TIM binding Biju Das
@ 2022-12-05 14:59 ` Biju Das
  2022-12-05 14:59 ` [PATCH 4/6] dt-bindings: counter: Add RZ/V2M TIM counter binding Biju Das
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Biju Das @ 2022-12-05 14:59 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Biju Das, Daniel Lezcano, Thomas Gleixner, Geert Uytterhoeven,
	Fabrizio Castro, linux-renesas-soc

This patch adds a TIM driver for the Renesas architecture.
The compare match Timer (TIM) Generates an interrupt request
signal every cycle set in the TIM counter.

This driver uses the first probed device as a clocksource
and then any additional devices as clock events.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/clocksource/Kconfig     |   7 +
 drivers/clocksource/Makefile    |   1 +
 drivers/clocksource/rzv2m-tim.c | 330 ++++++++++++++++++++++++++++++++
 3 files changed, 338 insertions(+)
 create mode 100644 drivers/clocksource/rzv2m-tim.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 4469e7f555e9..127a65cd44f6 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -532,6 +532,13 @@ config RENESAS_OSTM
 	help
 	  Enables the support for the Renesas OSTM.
 
+config RZV2M_TIM
+	bool "Renesas RZ/V2M Compare-Match Timer driver"
+	depends on ARCH_R9A09G011 || COMPILE_TEST
+	select CLKSRC_MMIO
+	help
+	  Enables the support for the Renesas RZ/V2M Compare-Match Timer (TIM).
+
 config SH_TIMER_TMU
 	bool "Renesas TMU timer driver" if COMPILE_TEST
 	depends on HAS_IOMEM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 64ab547de97b..c6d33fbeb889 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_CLKSRC_JCORE_PIT)		+= jcore-pit.o
 obj-$(CONFIG_SH_TIMER_CMT)	+= sh_cmt.o
 obj-$(CONFIG_SH_TIMER_MTU2)	+= sh_mtu2.o
 obj-$(CONFIG_RENESAS_OSTM)	+= renesas-ostm.o
+obj-$(CONFIG_RZV2M_TIM)	+= rzv2m-tim.o
 obj-$(CONFIG_SH_TIMER_TMU)	+= sh_tmu.o
 obj-$(CONFIG_EM_TIMER_STI)	+= em_sti.o
 obj-$(CONFIG_CLKBLD_I8253)	+= i8253.o
diff --git a/drivers/clocksource/rzv2m-tim.c b/drivers/clocksource/rzv2m-tim.c
new file mode 100644
index 000000000000..15fd3bde63c6
--- /dev/null
+++ b/drivers/clocksource/rzv2m-tim.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/V2M Compare Match Timer (TIM) driver
+ *
+ * Copyright (C) 2022 Renesas Electronics Corporation
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+/* TIM REGISTERS */
+#define RZV2M_TIM_TMD			0x0
+#define RZV2M_TIM_CMD			0x4
+#define RZV2M_TIM_TMCD			0x8
+#define RZV2M_TIM_INTCLR		0xc
+
+#define RZV2M_TIM_TMCD_CS		GENMASK(6, 4)
+#define RZV2M_TIM_TMCD_INTMODE		BIT(2)
+#define RZV2M_TIM_TMCD_CE		BIT(1)
+#define RZV2M_TIM_TMCD_CAE		BIT(0)
+
+#define RZV2M_TIM_INTCLR_INTCLR		BIT(0)
+
+#define RZV2M_TIM_TMCD_CH_EN	(RZV2M_TIM_TMCD_CE | RZV2M_TIM_TMCD_CAE)
+#define RZV2M_TIM_TMCD_START	(RZV2M_TIM_TMCD_CH_EN | RZV2M_TIM_TMCD_INTMODE)
+
+#define F2CYCLE_NSEC(f)		(1000000000 / (f))
+
+struct rzv2m_tim_channel {
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *rstc;
+	struct clock_event_device ced;
+	struct clocksource cs;
+	unsigned long period;
+	unsigned long delay;
+};
+
+static atomic_t clock_src_cnt = ATOMIC_INIT(-1);
+
+static inline struct
+rzv2m_tim_channel *ced_to_rzv2m_tim_channel(struct clock_event_device *ced)
+{
+	return container_of(ced, struct rzv2m_tim_channel, ced);
+}
+
+static inline struct
+rzv2m_tim_channel *cs_to_rzv2m_tim_channel(struct clocksource *cs)
+{
+	return container_of(cs, struct rzv2m_tim_channel, cs);
+}
+
+static void rzv2m_tim_wait_delay(struct rzv2m_tim_channel *ch)
+{
+	/* delay required when changing the register settings */
+	ndelay(ch->delay);
+}
+
+static void rzv2m_tim_timer_stop(struct rzv2m_tim_channel *ch)
+{
+	unsigned long tmcd;
+
+	tmcd = readl(ch->base + RZV2M_TIM_TMCD);
+	if (FIELD_GET(RZV2M_TIM_TMCD_CH_EN, tmcd)) {
+		writel(FIELD_GET(RZV2M_TIM_TMCD_CS, tmcd),
+		       ch->base + RZV2M_TIM_TMCD);
+		rzv2m_tim_wait_delay(ch);
+	}
+}
+
+static void rzv2m_tim_timer_start(struct rzv2m_tim_channel *ch)
+{
+	unsigned long tmcd;
+
+	tmcd = readl(ch->base + RZV2M_TIM_TMCD);
+	writel(tmcd | RZV2M_TIM_TMCD_START, ch->base + RZV2M_TIM_TMCD);
+	rzv2m_tim_wait_delay(ch);
+}
+
+static u64 rzv2m_tim_read_clock_source(struct clocksource *cs)
+{
+	struct rzv2m_tim_channel *ch = cs_to_rzv2m_tim_channel(cs);
+
+	return readl(ch->base + RZV2M_TIM_TMD);
+}
+
+static int rzv2m_tim_clock_event_next(unsigned long delta,
+				      struct clock_event_device *ced)
+{
+	struct rzv2m_tim_channel *ch = ced_to_rzv2m_tim_channel(ced);
+
+	rzv2m_tim_timer_stop(ch);
+	writel(delta, ch->base + RZV2M_TIM_CMD);
+	rzv2m_tim_timer_start(ch);
+
+	return 0;
+}
+
+static int rzv2m_tim_shutdown(struct clock_event_device *ced)
+{
+	struct rzv2m_tim_channel *ch = ced_to_rzv2m_tim_channel(ced);
+
+	rzv2m_tim_timer_stop(ch);
+
+	return 0;
+}
+
+static int rzv2m_tim_set_periodic(struct clock_event_device *ced)
+{
+	struct rzv2m_tim_channel *ch = ced_to_rzv2m_tim_channel(ced);
+
+	if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced))
+		rzv2m_tim_timer_stop(ch);
+
+	writel(ch->period, ch->base + RZV2M_TIM_CMD);
+	rzv2m_tim_timer_start(ch);
+
+	return 0;
+}
+
+static int rzv2m_tim_set_oneshot(struct clock_event_device *ced)
+{
+	rzv2m_tim_timer_stop(ced_to_rzv2m_tim_channel(ced));
+
+	return 0;
+}
+
+static irqreturn_t rzv2m_tim_timer_interrupt(int irq, void *dev_id)
+{
+	struct rzv2m_tim_channel *ch = dev_id;
+	struct clock_event_device *ced = &ch->ced;
+
+	if (clockevent_state_oneshot(ced))
+		rzv2m_tim_timer_stop(ch);
+
+	writel(RZV2M_TIM_INTCLR_INTCLR, ch->base + RZV2M_TIM_INTCLR);
+
+	/* notify clockevent layer */
+	if (ced->event_handler)
+		ced->event_handler(ced);
+
+	return IRQ_HANDLED;
+}
+
+static int rzv2m_tim_clocksource_enable(struct clocksource *cs)
+{
+	struct rzv2m_tim_channel *ch = cs_to_rzv2m_tim_channel(cs);
+
+	pm_runtime_get_sync(ch->dev);
+	rzv2m_tim_timer_start(ch);
+
+	return 0;
+}
+
+static void rzv2m_tim_clocksource_disable(struct clocksource *cs)
+{
+	struct rzv2m_tim_channel *ch = cs_to_rzv2m_tim_channel(cs);
+
+	rzv2m_tim_timer_stop(ch);
+	pm_runtime_put(ch->dev);
+}
+
+static int rzv2m_tim_init_clksrc(struct rzv2m_tim_channel *ch, unsigned long rate)
+{
+	struct clocksource *cs = &ch->cs;
+
+	rzv2m_tim_timer_stop(ch);
+
+	writel(U32_MAX, ch->base + RZV2M_TIM_CMD);
+	writel(FIELD_PREP(RZV2M_TIM_TMCD_CS, 0) | RZV2M_TIM_TMCD_START,
+	       ch->base  + RZV2M_TIM_TMCD);
+
+	cs->name = dev_name(ch->dev);
+	cs->rating = 300;
+	cs->read = rzv2m_tim_read_clock_source;
+	cs->enable = rzv2m_tim_clocksource_enable;
+	cs->disable = rzv2m_tim_clocksource_disable;
+	cs->mask = CLOCKSOURCE_MASK(32);
+	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
+
+	return clocksource_register_hz(cs, rate);
+}
+
+static void rzv2m_tim_init_clkevt(struct rzv2m_tim_channel *ch,
+				  unsigned long rate)
+{
+	struct clock_event_device *ced = &ch->ced;
+
+	pm_runtime_get_sync(ch->dev);
+
+	ced->name = dev_name(ch->dev);
+	ced->features = CLOCK_EVT_FEAT_ONESHOT;
+	ced->set_state_shutdown = rzv2m_tim_shutdown;
+	ced->set_state_periodic = rzv2m_tim_set_periodic;
+	ced->set_state_oneshot = rzv2m_tim_set_oneshot;
+	ced->set_next_event = rzv2m_tim_clock_event_next;
+	ced->shift = 32;
+	ced->rating = 125;
+	ced->cpumask = cpu_possible_mask;
+	clockevents_config_and_register(ced, rate, 0xf,
+					0xffffffff);
+}
+
+static int rzv2m_tim_probe(struct platform_device *pdev)
+{
+	struct rzv2m_tim_channel *rzv2m_tim;
+	unsigned long apb_rate, rate;
+	struct clk *clk;
+	int irq;
+	int ret;
+
+	rzv2m_tim = devm_kzalloc(&pdev->dev, sizeof(*rzv2m_tim), GFP_KERNEL);
+	if (!rzv2m_tim)
+		return -ENOMEM;
+
+	rzv2m_tim->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(rzv2m_tim->base))
+		return PTR_ERR(rzv2m_tim->base);
+
+	rzv2m_tim->rstc = devm_reset_control_get_optional_shared(&pdev->dev,
+								 NULL);
+	if (IS_ERR(rzv2m_tim->rstc))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rzv2m_tim->rstc),
+				     "get reset failed\n");
+
+	rzv2m_tim->dev = &pdev->dev;
+	clk = clk_get(&pdev->dev, "tim");
+	if (IS_ERR(clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(clk),
+				     "cannot get tim clock\n");
+	rate = clk_get_rate(clk);
+	clk_put(clk);
+	if (!rate)
+		return dev_err_probe(&pdev->dev, -EINVAL, "tim clk rate is 0");
+
+	clk = clk_get(&pdev->dev, "apb");
+	if (IS_ERR(clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(clk),
+				     "cannot get apb clock\n");
+	apb_rate = clk_get_rate(clk);
+	clk_put(clk);
+	if (!apb_rate)
+		return dev_err_probe(&pdev->dev, -EINVAL, "apb clk rate is 0");
+
+	/* delay = 5 * PCLK + 5 * INCLK */
+	rzv2m_tim->delay = F2CYCLE_NSEC(apb_rate) * 5 + F2CYCLE_NSEC(rate) * 5;
+
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret < 0) {
+		pm_runtime_disable(&pdev->dev);
+		return dev_err_probe(&pdev->dev, ret,
+				     "pm_runtime_resume_and_get failed");
+	}
+
+	reset_control_deassert(rzv2m_tim->rstc);
+	platform_set_drvdata(pdev, rzv2m_tim);
+
+	/*
+	 * First probed device will be used as system clocksource. Any
+	 * additional devices will be used as clock events.
+	 */
+	if (atomic_inc_and_test(&clock_src_cnt)) {
+		ret = rzv2m_tim_init_clksrc(rzv2m_tim, rate);
+		if (ret)
+			goto err_cleanup;
+
+		dev_info(&pdev->dev, "%pOF: used for clocksource\n",
+			 rzv2m_tim->dev->of_node);
+	} else {
+		rzv2m_tim->period = DIV_ROUND_CLOSEST(rate, HZ);
+		/* clock sources don't use interrupts, clock events do */
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0) {
+			ret = irq;
+			goto err_cleanup;
+		}
+
+		ret = devm_request_irq(&pdev->dev, irq,
+				       rzv2m_tim_timer_interrupt,
+				       IRQF_TIMER | IRQF_NOBALANCING,
+				       dev_name(&pdev->dev), rzv2m_tim);
+		if (ret) {
+			dev_err_probe(&pdev->dev, ret,
+				      "failed to request irq%d\n", irq);
+			goto err_cleanup;
+		}
+
+		rzv2m_tim_init_clkevt(rzv2m_tim, rate);
+
+		dev_info(&pdev->dev, "%pOF: used for clock events\n",
+			 rzv2m_tim->dev->of_node);
+	}
+
+	pm_runtime_put(&pdev->dev);
+	pm_runtime_irq_safe(&pdev->dev);
+
+	return 0;
+
+err_cleanup:
+	reset_control_assert(rzv2m_tim->rstc);
+	pm_runtime_put(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	return ret;
+}
+
+static const struct of_device_id rzv2m_tim_of_table[] = {
+	{ .compatible = "renesas,rzv2m-tim", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rzv2m_tim_of_table);
+
+static struct platform_driver rzv2m_tim_device_driver = {
+	.driver = {
+		.name = "rzv2m_tim",
+		.of_match_table = of_match_ptr(rzv2m_tim_of_table),
+	},
+	.probe = rzv2m_tim_probe,
+};
+module_platform_driver(rzv2m_tim_device_driver);
+
+MODULE_DESCRIPTION("Renesas RZ/V2M Compare Match Timer Driver");
+MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
+MODULE_LICENSE("GPL");
-- 
2.25.1


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

* [PATCH 4/6] dt-bindings: counter: Add RZ/V2M TIM counter binding
  2022-12-05 14:59 [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Biju Das
                   ` (2 preceding siblings ...)
  2022-12-05 14:59 ` [PATCH 3/6] clocksource/drivers/rzv2m-tim: Add Renesas RZ/V2M compare match timer(TIM) driver Biju Das
@ 2022-12-05 14:59 ` Biju Das
  2022-12-05 14:59 ` [PATCH 5/6] counter: Add Renesas RZ/V2M TIM counter driver Biju Das
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 21+ messages in thread
From: Biju Das @ 2022-12-05 14:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski
  Cc: Biju Das, devicetree, Geert Uytterhoeven, Fabrizio Castro,
	linux-renesas-soc

Add device tree binding for the Renesas RZ/V2M Counter Match Timer
(a.k.a TIM).

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 .../counter/renesas,rzv2m-tim-cnt.yaml        | 83 +++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/counter/renesas,rzv2m-tim-cnt.yaml

diff --git a/Documentation/devicetree/bindings/counter/renesas,rzv2m-tim-cnt.yaml b/Documentation/devicetree/bindings/counter/renesas,rzv2m-tim-cnt.yaml
new file mode 100644
index 000000000000..963dffe1c957
--- /dev/null
+++ b/Documentation/devicetree/bindings/counter/renesas,rzv2m-tim-cnt.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/counter/renesas,rzv2m-tim-cnt.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/V2M Compare Match Timer (TIM)
+
+maintainers:
+  - Biju Das <biju.das.jz@bp.renesas.com>
+
+description: |
+  The Compare Match Timer(TIM) on RZ/V2M like SoCs has an internal 32-bit
+  counter that can be used as an interval timer. This LSI has a total of 32
+  channels of TIM from ch. 0 to ch. 31. It supports the following features
+  * Configured with a 32-bit counter operating at INCLOCK (2 MHz)
+  * The clock input from the count clock input pin can be divided by 2, 4,
+    8, 16, 32, 64, 128, or 256, and one of these divided clocks can be
+    used as the count clock.
+  * The counter period can be set in the range of 1 to 4294967296
+    (32-bit timer) using the selected divider clock as the count clock.
+  * Generates an interrupt request signal every cycle set in the TIM
+    counter.
+  * The counter operation and the bus interface are asynchronous and
+    can operate independently regardless of the size of the respective
+    clock cycles.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r9a09g011-tim-cnt  # RZ/V2M
+          - renesas,r9a09g055-tim-cnt  # RZ/V2MA
+      - const: renesas,rzv2m-tim-cnt
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: APB clock
+      - description: TIM clock
+
+  clock-names:
+    items:
+      - const: apb
+      - const: tim
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - power-domains
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r9a09g011-cpg.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tim8: tim@a4000400 {
+        compatible = "renesas,r9a09g011-tim-cnt", "renesas,rzv2m-tim-cnt";
+        reg = <0xa4000400 0x80>;
+        interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+                 <&cpg CPG_MOD R9A09G011_TIM8_CLK>;
+        clock-names = "apb", "tim";
+        power-domains = <&cpg>;
+        resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+    };
-- 
2.25.1


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

* [PATCH 5/6] counter: Add Renesas RZ/V2M TIM counter driver
  2022-12-05 14:59 [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Biju Das
                   ` (3 preceding siblings ...)
  2022-12-05 14:59 ` [PATCH 4/6] dt-bindings: counter: Add RZ/V2M TIM counter binding Biju Das
@ 2022-12-05 14:59 ` Biju Das
  2022-12-05 14:59 ` [PATCH 6/6] arm64: dts: renesas: r9a09g011: Add tim nodes Biju Das
  2022-12-05 22:50 ` [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Rob Herring
  6 siblings, 0 replies; 21+ messages in thread
From: Biju Das @ 2022-12-05 14:59 UTC (permalink / raw)
  To: William Breathitt Gray, Philipp Zabel
  Cc: Biju Das, linux-iio, Geert Uytterhoeven, Fabrizio Castro,
	linux-renesas-soc

Add Renesas RZ/V2M TIM(Compare Match Timer) counter driver. This IP
supports 32 bit counter and it generates an interrupt request
signal every cycle set in the TIM counter.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/counter/Kconfig         |  10 +
 drivers/counter/Makefile        |   1 +
 drivers/counter/rzv2m-tim-cnt.c | 312 ++++++++++++++++++++++++++++++++
 3 files changed, 323 insertions(+)
 create mode 100644 drivers/counter/rzv2m-tim-cnt.c

diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index d388bf26f4dc..c705b557117f 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -39,6 +39,16 @@ config INTERRUPT_CNT
 	  To compile this driver as a module, choose M here: the
 	  module will be called interrupt-cnt.
 
+config RZV2M_TIM_CNT
+	tristate "Renesas RZ/V2M counter driver"
+	depends on ARCH_R9A09G011 || COMPILE_TEST
+	help
+	  Enable support for RZ/V2M counter driver found on Renesas RZ/V2M alike
+	  SoCs. This IP supports 32 bit counter.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rzv2m-tim-cnt.
+
 config STM32_TIMER_CNT
 	tristate "STM32 Timer encoder counter driver"
 	depends on MFD_STM32_TIMERS || COMPILE_TEST
diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
index b9a369e0d4fc..1f09ea735ddf 100644
--- a/drivers/counter/Makefile
+++ b/drivers/counter/Makefile
@@ -8,6 +8,7 @@ counter-y := counter-core.o counter-sysfs.o counter-chrdev.o
 
 obj-$(CONFIG_104_QUAD_8)	+= 104-quad-8.o
 obj-$(CONFIG_INTERRUPT_CNT)		+= interrupt-cnt.o
+obj-$(CONFIG_RZV2M_TIM_CNT)	+= rzv2m-tim-cnt.o
 obj-$(CONFIG_STM32_TIMER_CNT)	+= stm32-timer-cnt.o
 obj-$(CONFIG_STM32_LPTIMER_CNT)	+= stm32-lptimer-cnt.o
 obj-$(CONFIG_TI_EQEP)		+= ti-eqep.o
diff --git a/drivers/counter/rzv2m-tim-cnt.c b/drivers/counter/rzv2m-tim-cnt.c
new file mode 100644
index 000000000000..6c3b738a3e39
--- /dev/null
+++ b/drivers/counter/rzv2m-tim-cnt.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/V2M Compare Match Timer (TIM) driver
+ *
+ * Copyright (C) 2022 Renesas Electronics Corporation
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/counter.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+/* TIM REGISTERS */
+#define RZV2M_TIM_TMD			0x0
+#define RZV2M_TIM_CMD			0x4
+#define RZV2M_TIM_TMCD			0x8
+#define RZV2M_TIM_INTCLR		0xc
+
+#define RZV2M_TIM_TMCD_CS		GENMASK(6, 4)
+#define RZV2M_TIM_TMCD_INTMODE		BIT(2)
+#define RZV2M_TIM_TMCD_CE		BIT(1)
+#define RZV2M_TIM_TMCD_CAE		BIT(0)
+
+#define RZV2M_TIM_INTCLR_INTCLR		BIT(0)
+
+#define RZV2M_TIM_TMCD_CH_EN	(RZV2M_TIM_TMCD_CE | RZV2M_TIM_TMCD_CAE)
+#define RZV2M_TIM_TMCD_START	(RZV2M_TIM_TMCD_CH_EN | RZV2M_TIM_TMCD_INTMODE)
+
+#define F2CYCLE_NSEC(f)		(1000000000 / (f))
+
+/**
+ * struct rzv2m_tim_channel - TIM counter private data
+ *
+ * @dev: Channel device
+ * @base: Base address of the chanel
+ * @rstc: Reset handle
+ * @delay: write intervel for register writes
+ * @ceiling: Cache for ceiling value
+ */
+
+struct rzv2m_tim_channel {
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *rstc;
+	unsigned long delay;
+	u32 ceiling;
+};
+
+static void rzv2m_tim_cnt_wait_delay(struct rzv2m_tim_channel *ch)
+{
+	/* delay required when changing the register settings */
+	ndelay(ch->delay);
+}
+
+static bool rzv2m_tim_cnt_is_counter_enabled(struct counter_device *counter)
+{
+	struct rzv2m_tim_channel *const ch = counter_priv(counter);
+	unsigned long tmcd;
+
+	tmcd = readl(ch->base + RZV2M_TIM_TMCD);
+	return !!FIELD_GET(RZV2M_TIM_TMCD_CH_EN, tmcd);
+}
+
+static void rzv2m_tim_cnt_stop(struct rzv2m_tim_channel *ch)
+{
+	unsigned long tmcd;
+
+	tmcd = readl(ch->base + RZV2M_TIM_TMCD);
+	if (FIELD_GET(RZV2M_TIM_TMCD_CH_EN, tmcd)) {
+		writel(FIELD_GET(RZV2M_TIM_TMCD_CS, tmcd),
+		       ch->base + RZV2M_TIM_TMCD);
+		rzv2m_tim_cnt_wait_delay(ch);
+	}
+}
+
+static void rzv2m_tim_cnt_start(struct rzv2m_tim_channel *ch)
+{
+	unsigned long tmcd;
+
+	tmcd = readl(ch->base + RZV2M_TIM_TMCD);
+	writel(tmcd | RZV2M_TIM_TMCD_START, ch->base + RZV2M_TIM_TMCD);
+	rzv2m_tim_cnt_wait_delay(ch);
+}
+
+static irqreturn_t rzv2m_tim_cnt_interrupt(int irq, void *dev_id)
+{
+	struct rzv2m_tim_channel *const ch = counter_priv(dev_id);
+
+	writel(RZV2M_TIM_INTCLR_INTCLR, ch->base + RZV2M_TIM_INTCLR);
+	counter_push_event(dev_id, COUNTER_EVENT_OVERFLOW, 0);
+
+	return IRQ_HANDLED;
+}
+
+static int rzv2m_tim_cnt_read(struct counter_device *counter,
+			      struct counter_count *count, u64 *val)
+{
+	struct rzv2m_tim_channel *const ch = counter_priv(counter);
+
+	*val = readl(ch->base + RZV2M_TIM_TMD);
+
+	return 0;
+}
+
+static int rzv2m_tim_cnt_ceiling_read(struct counter_device *counter,
+				      struct counter_count *count,
+				      u64 *ceiling)
+{
+	struct rzv2m_tim_channel *const ch = counter_priv(counter);
+
+	*ceiling = ch->ceiling;
+
+	return 0;
+}
+
+static int rzv2m_tim_cnt_ceiling_write(struct counter_device *counter,
+				       struct counter_count *count,
+				       u64 ceiling)
+{
+	struct rzv2m_tim_channel *const ch = counter_priv(counter);
+	bool enable = rzv2m_tim_cnt_is_counter_enabled(counter);
+
+	if (ceiling > U32_MAX)
+		return -ERANGE;
+
+	if (enable)
+		rzv2m_tim_cnt_stop(ch);
+	ch->ceiling = ceiling;
+	writel(ceiling, ch->base + RZV2M_TIM_CMD);
+	if (enable)
+		rzv2m_tim_cnt_start(ch);
+
+	return 0;
+}
+
+static int rzv2m_tim_cnt_enable_read(struct counter_device *counter,
+				     struct counter_count *count, u8 *enable)
+{
+	struct rzv2m_tim_channel *const ch = counter_priv(counter);
+
+	pm_runtime_get_sync(ch->dev);
+	*enable = rzv2m_tim_cnt_is_counter_enabled(counter);
+	pm_runtime_put(ch->dev);
+
+	return 0;
+}
+
+static int rzv2m_tim_cnt_enable_write(struct counter_device *counter,
+				      struct counter_count *count, u8 enable)
+{
+	struct rzv2m_tim_channel *const ch = counter_priv(counter);
+
+	if (enable) {
+		pm_runtime_get_sync(ch->dev);
+		rzv2m_tim_cnt_start(ch);
+	} else {
+		rzv2m_tim_cnt_stop(ch);
+		pm_runtime_put(ch->dev);
+	}
+
+	return 0;
+}
+
+static const struct counter_ops rzv2m_tim_cnt_ops = {
+	.count_read = rzv2m_tim_cnt_read,
+};
+
+static struct counter_comp rzv2m_tim_cnt_ext[] = {
+	COUNTER_COMP_ENABLE(rzv2m_tim_cnt_enable_read,
+			    rzv2m_tim_cnt_enable_write),
+	COUNTER_COMP_CEILING(rzv2m_tim_cnt_ceiling_read,
+			     rzv2m_tim_cnt_ceiling_write),
+};
+
+static struct counter_count rzv2m_tim_counts[] = {
+	{
+		.id = 0,
+		.name = "Channel Count",
+		.ext = rzv2m_tim_cnt_ext,
+		.num_ext = ARRAY_SIZE(rzv2m_tim_cnt_ext),
+	},
+};
+
+static void rzv2m_tim_cnt_reset_assert_pm_disable(void *data)
+{
+	struct rzv2m_tim_channel *ch = data;
+
+	reset_control_assert(ch->rstc);
+	pm_runtime_disable(ch->dev);
+}
+
+static int rzv2m_tim_cnt_probe(struct platform_device *pdev)
+{
+	struct counter_device *counter;
+	struct rzv2m_tim_channel *ch;
+	unsigned long apb_rate, rate;
+	struct clk *clk;
+	int irq;
+	int ret;
+
+	counter = devm_counter_alloc(&pdev->dev, sizeof(*ch));
+	if (!counter)
+		return -ENOMEM;
+
+	ch = counter_priv(counter);
+	ch->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(ch->base))
+		return PTR_ERR(ch->base);
+
+	ch->rstc = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+	if (IS_ERR(ch->rstc))
+		return dev_err_probe(&pdev->dev, PTR_ERR(ch->rstc),
+				     "get reset failed\n");
+
+	ch->dev = &pdev->dev;
+	clk = clk_get(&pdev->dev, "tim");
+	if (IS_ERR(clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(clk),
+				     "cannot get tim clock\n");
+	rate = clk_get_rate(clk);
+	clk_put(clk);
+	if (!rate)
+		return dev_err_probe(&pdev->dev, -EINVAL, "tim clk rate is 0");
+
+	clk = clk_get(&pdev->dev, "apb");
+	if (IS_ERR(clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(clk),
+				     "cannot get apb clock\n");
+	apb_rate = clk_get_rate(clk);
+	clk_put(clk);
+	if (!apb_rate)
+		return dev_err_probe(&pdev->dev, -EINVAL, "apb clk rate is 0");
+
+	/* delay = 5 * PCLK + 5 * INCLK */
+	ch->delay = F2CYCLE_NSEC(apb_rate) * 5 + F2CYCLE_NSEC(rate) * 5;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret < 0) {
+		dev_err_probe(&pdev->dev, ret,
+			      "pm_runtime_resume_and_get failed");
+		goto err_pm_disable;
+	}
+
+	reset_control_deassert(ch->rstc);
+	writel(U32_MAX, ch->base + RZV2M_TIM_CMD);
+	writel(FIELD_PREP(RZV2M_TIM_TMCD_CS, 0), ch->base  + RZV2M_TIM_TMCD);
+	pm_runtime_put(&pdev->dev);
+	platform_set_drvdata(pdev, ch);
+
+	ret = devm_add_action_or_reset(&pdev->dev,
+				       rzv2m_tim_cnt_reset_assert_pm_disable,
+				       ch);
+	if (ret < 0)
+		return ret;
+
+	ret = devm_request_irq(&pdev->dev, irq,
+			       rzv2m_tim_cnt_interrupt,
+			       0,
+			       dev_name(&pdev->dev), counter);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to request irq%d\n", irq);
+
+	counter->name = dev_name(&pdev->dev);
+	counter->parent = &pdev->dev;
+	counter->ops = &rzv2m_tim_cnt_ops;
+	counter->counts = rzv2m_tim_counts;
+	counter->num_counts = ARRAY_SIZE(rzv2m_tim_counts);
+
+	/* Register Counter device */
+	ret = devm_counter_add(&pdev->dev, counter);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n");
+
+	return 0;
+
+err_pm_disable:
+	pm_runtime_disable(&pdev->dev);
+	return ret;
+}
+
+static const struct of_device_id rzv2m_tim_of_table[] = {
+	{ .compatible = "renesas,rzv2m-tim-cnt", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rzv2m_tim_of_table);
+
+static struct platform_driver rzv2m_tim_cnt_device_driver = {
+	.driver = {
+		.name = "rzv2m_tim_cnt",
+		.of_match_table = of_match_ptr(rzv2m_tim_of_table),
+	},
+	.probe = rzv2m_tim_cnt_probe,
+};
+module_platform_driver(rzv2m_tim_cnt_device_driver);
+
+MODULE_DESCRIPTION("Renesas RZ/V2M Compare Match Timer Driver");
+MODULE_ALIAS("platform:rzv2m-tim-counter");
+MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(COUNTER);
-- 
2.25.1


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

* [PATCH 6/6] arm64: dts: renesas: r9a09g011: Add tim nodes
  2022-12-05 14:59 [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Biju Das
                   ` (4 preceding siblings ...)
  2022-12-05 14:59 ` [PATCH 5/6] counter: Add Renesas RZ/V2M TIM counter driver Biju Das
@ 2022-12-05 14:59 ` Biju Das
  2022-12-05 22:50 ` [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Rob Herring
  6 siblings, 0 replies; 21+ messages in thread
From: Biju Das @ 2022-12-05 14:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski
  Cc: Biju Das, Geert Uytterhoeven, Magnus Damm, linux-renesas-soc,
	devicetree, Fabrizio Castro

Add device nodes for the compare match timer(TIM) channels that are
not assigned to the ISP.

The channels 22 is assigned for clock source and channel 23 for
clock event and rest of the channels are assigned for counter
operation.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 arch/arm64/boot/dts/renesas/r9a09g011.dtsi | 192 +++++++++++++++++++++
 1 file changed, 192 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
index dcd3a05e54fe..69c1ebc5e0dd 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
@@ -135,6 +135,198 @@ sys: system-controller@a3f03000 {
 			reg = <0 0xa3f03000 0 0x400>;
 		};
 
+		tim8: timer@a4000400 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000400 0 0x80>;
+			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM8_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim9: timer@a4000480 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000480 0 0x80>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM9_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim10: timer@a4000500 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000500 0 0x80>;
+			interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM10_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim11: timer@a4000580 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000580 0 0x80>;
+			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM11_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim12: timer@a4000600 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000600 0 0x80>;
+			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM12_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim13: timer@a4000680 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000680 0 0x80>;
+			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM13_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim14: timer@a4000700 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000700 0 0x80>;
+			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM14_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim15: timer@a4000780 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000780 0 0x80>;
+			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPB_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM15_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPB_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim16: timer@a4000800 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000800 0 0x80>;
+			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM16_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim17: timer@a4000880 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000880 0 0x80>;
+			interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM17_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim18: timer@a4000900 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000900 0 0x80>;
+			interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM18_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim19: timer@a4000980 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000980 0 0x80>;
+			interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM19_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim20: timer@a4000a00 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000a00 0 0x80>;
+			interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM20_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim21: timer@a4000a80 {
+			compatible = "renesas,r9a09g011-tim-cnt",
+				     "renesas,rzv2m-tim-cnt";
+			reg = <0 0xa4000a80 0 0x80>;
+			interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM21_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim22: timer@a4000b00 {
+			compatible = "renesas,r9a09g011-tim",
+				     "renesas,rzv2m-tim";
+			reg = <0 0xa4000b00 0 0x80>;
+			interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM22_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
+		tim23: timer@a4000b80 {
+			compatible = "renesas,r9a09g011-tim",
+				     "renesas,rzv2m-tim";
+			reg = <0 0xa4000b80 0 0x80>;
+			interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPC_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_TIM23_CLK>;
+			clock-names = "apb", "tim";
+			resets = <&cpg R9A09G011_TIM_GPC_PRESETN>;
+			power-domains = <&cpg>;
+		};
+
 		pwm8: pwm@a4010400 {
 			compatible = "renesas,r9a09g011-pwm",
 				     "renesas,rzv2m-pwm";
-- 
2.25.1


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

* Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-05 14:59 [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Biju Das
                   ` (5 preceding siblings ...)
  2022-12-05 14:59 ` [PATCH 6/6] arm64: dts: renesas: r9a09g011: Add tim nodes Biju Das
@ 2022-12-05 22:50 ` Rob Herring
  2022-12-06  8:13   ` Biju Das
  6 siblings, 1 reply; 21+ messages in thread
From: Rob Herring @ 2022-12-05 22:50 UTC (permalink / raw)
  To: Biju Das
  Cc: Krzysztof Kozlowski, Philipp Zabel, William Breathitt Gray,
	Michael Turquette, Stephen Boyd, Daniel Lezcano, Thomas Gleixner,
	devicetree, Geert Uytterhoeven, Magnus Damm, linux-renesas-soc,
	linux-clk, linux-iio, Lad Prabhakar, Fabrizio Castro

On Mon, Dec 05, 2022 at 02:59:49PM +0000, Biju Das wrote:
> This patch series aims to add support for Compare-Match Timer (TIM)
> module found on RZ/V2M SoC.
> 
> it is composed of 32 channels and channels 0-7 and 24-32 are
> reserved for ISP usage.
> 
> Channel 22 is modelled as clock source and Channel 23 is modelled as clock
> event driver and the rest of the channels are modelled as counter driver
> as it provides

Why did you pick those 2 counters for those functions?

Unless the h/w blocks are different, this is an abuse of compatible 
strings. What's the h/w difference that makes you care which counter the 
OS picks? That's what the DT should describe. If any timer will do, just 
let the OS pick.

> 
> 1) counter for counting
> 2) configurable counter value for generating timer interrupt
> 3) userspace event for each interrupt.
> 
> logs:-
> Counter driver:
> Counter driver is tested by reading counts and interrupts tested by
> counter-example in tools/counter/counter_example.c
> 
> Count snapshot value:
> 3114
> Output from counter_example when it triggers interrupts:
> Timestamp 0: 24142152969        Count 0: 5
> Error Message 0: Success
> 
> Clock source:
> Clock source driver is tested by clock-source-switch app.
> [ 1275.703567] clocksource: Switched to clocksource arch_sys_counter
> [ 1275.710189] clocksource: Switched to clocksource a4000b00.timer

Do you have any use case to really switch. Doing so disables the vDSO 
access to the clocksource.

Rob

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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-05 22:50 ` [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Rob Herring
@ 2022-12-06  8:13   ` Biju Das
  2022-12-06  8:40     ` Geert Uytterhoeven
  0 siblings, 1 reply; 21+ messages in thread
From: Biju Das @ 2022-12-06  8:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: Krzysztof Kozlowski, Philipp Zabel, William Breathitt Gray,
	Michael Turquette, Stephen Boyd, Daniel Lezcano, Thomas Gleixner,
	devicetree, Geert Uytterhoeven, Magnus Damm, linux-renesas-soc,
	linux-clk, linux-iio, Prabhakar Mahadev Lad, Fabrizio Castro

Hi Rob,

Thanks for the feedback.

> Subject: Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
> 
> On Mon, Dec 05, 2022 at 02:59:49PM +0000, Biju Das wrote:
> > This patch series aims to add support for Compare-Match Timer (TIM)
> > module found on RZ/V2M SoC.
> >
> > it is composed of 32 channels and channels 0-7 and 24-32 are reserved
> > for ISP usage.
> >
> > Channel 22 is modelled as clock source and Channel 23 is modelled as
> > clock event driver and the rest of the channels are modelled as
> > counter driver as it provides
> 
> Why did you pick those 2 counters for those functions?

Currently it uses architecture timer for broadcast timer, so I thought
Since TIM has 24 channels, use 1 channel for broadcast timer and 1
Channel for clock source. But having said that SoC has an aarch64 architecture
clock source strictly speaking we don't need this.

> 
> Unless the h/w blocks are different, this is an abuse of compatible
> strings. What's the h/w difference that makes you care which counter the
> OS picks? That's what the DT should describe. If any timer will do, just
> let the OS pick.

There is no HW difference. Same HW block can be used for mutually exclusive
functionality.

One is for Linux Clock source/event functionality((scheduler tick/broadcast tick etc) and 

the other purpose is to expose count and event ticks from this module to user space,
so that wide range of applications can make use of it.

If it is an abuse of compatible strings for mutually exclusive functionality
, then I would like to drop clock source and use all the channels as 
Either clock events(for broadcast ticks and real time usage??) or as counters.

If this is not OK, then I need to pick one. I will go with counters.

Please share your thoughts.

> 
> >
> > 1) counter for counting
> > 2) configurable counter value for generating timer interrupt
> > 3) userspace event for each interrupt.
> >
> > logs:-
> > Counter driver:
> > Counter driver is tested by reading counts and interrupts tested by
> > counter-example in tools/counter/counter_example.c
> >
> > Count snapshot value:
> > 3114
> > Output from counter_example when it triggers interrupts:
> > Timestamp 0: 24142152969        Count 0: 5
> > Error Message 0: Success
> >
> > Clock source:
> > Clock source driver is tested by clock-source-switch app.
> > [ 1275.703567] clocksource: Switched to clocksource arch_sys_counter
> > [ 1275.710189] clocksource: Switched to clocksource a4000b00.timer
> 
> Do you have any use case to really switch. Doing so disables the vDSO
> access to the clocksource.

Not really. Architecture timer should be sufficient for clocksource.

Cheers,
Biju

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

* Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-06  8:13   ` Biju Das
@ 2022-12-06  8:40     ` Geert Uytterhoeven
  2022-12-06  8:57       ` Thomas Gleixner
  2022-12-06  8:59       ` Biju Das
  0 siblings, 2 replies; 21+ messages in thread
From: Geert Uytterhoeven @ 2022-12-06  8:40 UTC (permalink / raw)
  To: Biju Das
  Cc: Rob Herring, Krzysztof Kozlowski, Philipp Zabel,
	William Breathitt Gray, Michael Turquette, Stephen Boyd,
	Daniel Lezcano, Thomas Gleixner, devicetree, Geert Uytterhoeven,
	Magnus Damm, linux-renesas-soc, linux-clk, linux-iio,
	Prabhakar Mahadev Lad, Fabrizio Castro

Hi Biju,

On Tue, Dec 6, 2022 at 9:13 AM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > Subject: Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
> > On Mon, Dec 05, 2022 at 02:59:49PM +0000, Biju Das wrote:
> > > This patch series aims to add support for Compare-Match Timer (TIM)
> > > module found on RZ/V2M SoC.
> > >
> > > it is composed of 32 channels and channels 0-7 and 24-32 are reserved
> > > for ISP usage.
> > >
> > > Channel 22 is modelled as clock source and Channel 23 is modelled as
> > > clock event driver and the rest of the channels are modelled as
> > > counter driver as it provides
> >
> > Why did you pick those 2 counters for those functions?
>
> Currently it uses architecture timer for broadcast timer, so I thought
> Since TIM has 24 channels, use 1 channel for broadcast timer and 1
> Channel for clock source. But having said that SoC has an aarch64 architecture
> clock source strictly speaking we don't need this.
>
> > Unless the h/w blocks are different, this is an abuse of compatible
> > strings. What's the h/w difference that makes you care which counter the
> > OS picks? That's what the DT should describe. If any timer will do, just
> > let the OS pick.
>
> There is no HW difference. Same HW block can be used for mutually exclusive
> functionality.
>
> One is for Linux Clock source/event functionality((scheduler tick/broadcast tick etc) and
>
> the other purpose is to expose count and event ticks from this module to user space,
> so that wide range of applications can make use of it.
>
> If it is an abuse of compatible strings for mutually exclusive functionality
> , then I would like to drop clock source and use all the channels as
> Either clock events(for broadcast ticks and real time usage??) or as counters.
>
> If this is not OK, then I need to pick one. I will go with counters.
>
> Please share your thoughts.

Can't you handle this like sh_cmt.c does:

        /*
         * Use the first channel as a clock event device and the second channel
         * as a clock source. If only one channel is available use it for both.
         */

> > > 1) counter for counting
> > > 2) configurable counter value for generating timer interrupt
> > > 3) userspace event for each interrupt.
> > >
> > > logs:-
> > > Counter driver:
> > > Counter driver is tested by reading counts and interrupts tested by
> > > counter-example in tools/counter/counter_example.c
> > >
> > > Count snapshot value:
> > > 3114
> > > Output from counter_example when it triggers interrupts:
> > > Timestamp 0: 24142152969        Count 0: 5
> > > Error Message 0: Success
> > >
> > > Clock source:
> > > Clock source driver is tested by clock-source-switch app.
> > > [ 1275.703567] clocksource: Switched to clocksource arch_sys_counter
> > > [ 1275.710189] clocksource: Switched to clocksource a4000b00.timer
> >
> > Do you have any use case to really switch. Doing so disables the vDSO
> > access to the clocksource.
>
> Not really. Architecture timer should be sufficient for clocksource.

When multiple clocksources are registered, the clocksource
subsystems picks the best one anyway, right?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-06  8:40     ` Geert Uytterhoeven
@ 2022-12-06  8:57       ` Thomas Gleixner
  2022-12-06  9:45         ` Biju Das
  2022-12-07  7:52         ` Biju Das
  2022-12-06  8:59       ` Biju Das
  1 sibling, 2 replies; 21+ messages in thread
From: Thomas Gleixner @ 2022-12-06  8:57 UTC (permalink / raw)
  To: Geert Uytterhoeven, Biju Das
  Cc: Rob Herring, Krzysztof Kozlowski, Philipp Zabel,
	William Breathitt Gray, Michael Turquette, Stephen Boyd,
	Daniel Lezcano, devicetree, Geert Uytterhoeven, Magnus Damm,
	linux-renesas-soc, linux-clk, linux-iio, Prabhakar Mahadev Lad,
	Fabrizio Castro

On Tue, Dec 06 2022 at 09:40, Geert Uytterhoeven wrote:
> On Tue, Dec 6, 2022 at 9:13 AM Biju Das <biju.das.jz@bp.renesas.com> wrote:
>> > Do you have any use case to really switch. Doing so disables the vDSO
>> > access to the clocksource.
>>
>> Not really. Architecture timer should be sufficient for clocksource.
>
> When multiple clocksources are registered, the clocksource
> subsystems picks the best one anyway, right?

As it does for the clock event devices. If there is an architected timer
then that should be always preferred.

No idea why there is a need for the extra hardware and the drivers which
are both never utilized.

Thanks,

        tglx

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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-06  8:40     ` Geert Uytterhoeven
  2022-12-06  8:57       ` Thomas Gleixner
@ 2022-12-06  8:59       ` Biju Das
  1 sibling, 0 replies; 21+ messages in thread
From: Biju Das @ 2022-12-06  8:59 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Rob Herring, Krzysztof Kozlowski, Philipp Zabel,
	William Breathitt Gray, Michael Turquette, Stephen Boyd,
	Daniel Lezcano, Thomas Gleixner, devicetree, Geert Uytterhoeven,
	Magnus Damm, linux-renesas-soc, linux-clk, linux-iio,
	Prabhakar Mahadev Lad, Fabrizio Castro

Hi Geert,

Thanks for the feedback.

> Subject: Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
> 
> Hi Biju,
> 
> On Tue, Dec 6, 2022 at 9:13 AM Biju Das <biju.das.jz@bp.renesas.com>
> wrote:
> > > Subject: Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM)
> > > support On Mon, Dec 05, 2022 at 02:59:49PM +0000, Biju Das wrote:
> > > > This patch series aims to add support for Compare-Match Timer
> > > > (TIM) module found on RZ/V2M SoC.
> > > >
> > > > it is composed of 32 channels and channels 0-7 and 24-32 are
> > > > reserved for ISP usage.
> > > >
> > > > Channel 22 is modelled as clock source and Channel 23 is modelled
> > > > as clock event driver and the rest of the channels are modelled as
> > > > counter driver as it provides
> > >
> > > Why did you pick those 2 counters for those functions?
> >
> > Currently it uses architecture timer for broadcast timer, so I thought
> > Since TIM has 24 channels, use 1 channel for broadcast timer and 1
> > Channel for clock source. But having said that SoC has an aarch64
> > architecture clock source strictly speaking we don't need this.
> >
> > > Unless the h/w blocks are different, this is an abuse of compatible
> > > strings. What's the h/w difference that makes you care which counter
> > > the OS picks? That's what the DT should describe. If any timer will
> > > do, just let the OS pick.
> >
> > There is no HW difference. Same HW block can be used for mutually
> > exclusive functionality.
> >
> > One is for Linux Clock source/event functionality((scheduler
> > tick/broadcast tick etc) and
> >
> > the other purpose is to expose count and event ticks from this module
> > to user space, so that wide range of applications can make use of it.
> >
> > If it is an abuse of compatible strings for mutually exclusive
> > functionality , then I would like to drop clock source and use all the
> > channels as Either clock events(for broadcast ticks and real time
> usage??) or as counters.
> >
> > If this is not OK, then I need to pick one. I will go with counters.
> >
> > Please share your thoughts.
> 
> Can't you handle this like sh_cmt.c does:
> 
>         /*
>          * Use the first channel as a clock event device and the second
> channel
>          * as a clock source. If only one channel is available use it for
> both.
>          */

Currently it is handled like above except for the case " If only one channel is available use it for
Both", see patch#3 [1] probe function.
The only difference is here we have separate address space, clocks, and interrupts for each channel.
[1]
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20221205145955.391526-4-biju.das.jz@bp.renesas.com/

Our customer BSP, uses this hw module for exposing timer interrupt event to user space
by using custom driver. The same functionality can be achieved through counter driver.
That is the reason, I have added counter driver to expose this functionality as well.

> 
> > > > 1) counter for counting
> > > > 2) configurable counter value for generating timer interrupt
> > > > 3) userspace event for each interrupt.
> > > >
> > > > logs:-
> > > > Counter driver:
> > > > Counter driver is tested by reading counts and interrupts tested
> > > > by counter-example in tools/counter/counter_example.c
> > > >
> > > > Count snapshot value:
> > > > 3114
> > > > Output from counter_example when it triggers interrupts:
> > > > Timestamp 0: 24142152969        Count 0: 5
> > > > Error Message 0: Success
> > > >
> > > > Clock source:
> > > > Clock source driver is tested by clock-source-switch app.
> > > > [ 1275.703567] clocksource: Switched to clocksource
> > > > arch_sys_counter [ 1275.710189] clocksource: Switched to
> > > > clocksource a4000b00.timer
> > >
> > > Do you have any use case to really switch. Doing so disables the
> > > vDSO access to the clocksource.
> >
> > Not really. Architecture timer should be sufficient for clocksource.
> 
> When multiple clocksources are registered, the clocksource subsystems
> picks the best one anyway, right?

Yes, it picks based on the rating.

Cheers,
Biju

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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-06  8:57       ` Thomas Gleixner
@ 2022-12-06  9:45         ` Biju Das
  2022-12-07  7:52         ` Biju Das
  1 sibling, 0 replies; 21+ messages in thread
From: Biju Das @ 2022-12-06  9:45 UTC (permalink / raw)
  To: Thomas Gleixner, Geert Uytterhoeven
  Cc: Rob Herring, Krzysztof Kozlowski, Philipp Zabel,
	William Breathitt Gray, Michael Turquette, Stephen Boyd,
	Daniel Lezcano, devicetree, Geert Uytterhoeven, Magnus Damm,
	linux-renesas-soc, linux-clk, linux-iio, Prabhakar Mahadev Lad,
	Fabrizio Castro

> Subject: Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
> 
> On Tue, Dec 06 2022 at 09:40, Geert Uytterhoeven wrote:
> > On Tue, Dec 6, 2022 at 9:13 AM Biju Das <biju.das.jz@bp.renesas.com>
> wrote:
> >> > Do you have any use case to really switch. Doing so disables the
> >> > vDSO access to the clocksource.
> >>
> >> Not really. Architecture timer should be sufficient for clocksource.
> >
> > When multiple clocksources are registered, the clocksource subsystems
> > picks the best one anyway, right?
> 
> As it does for the clock event devices. If there is an architected timer
> then that should be always preferred.
> 
> No idea why there is a need for the extra hardware and the drivers which
> are both never utilized.

Maybe, if you use secure OS, this timer hardware can be used there.

If you use PM deep states, Maybe, it could be used as broadcast event for waking up the system??

Cheers,
Biju





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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-06  8:57       ` Thomas Gleixner
  2022-12-06  9:45         ` Biju Das
@ 2022-12-07  7:52         ` Biju Das
  2022-12-07 10:53           ` Thomas Gleixner
  1 sibling, 1 reply; 21+ messages in thread
From: Biju Das @ 2022-12-07  7:52 UTC (permalink / raw)
  To: Thomas Gleixner, Geert Uytterhoeven, William Breathitt Gray, Rob Herring
  Cc: Krzysztof Kozlowski, Philipp Zabel, William Breathitt Gray,
	Michael Turquette, Stephen Boyd, Daniel Lezcano, devicetree,
	Geert Uytterhoeven, Magnus Damm, linux-renesas-soc, linux-clk,
	linux-iio, Prabhakar Mahadev Lad, Fabrizio Castro

Hi Thomas Gleixner and Geert,

> Subject: Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
> 
> On Tue, Dec 06 2022 at 09:40, Geert Uytterhoeven wrote:
> > On Tue, Dec 6, 2022 at 9:13 AM Biju Das <biju.das.jz@bp.renesas.com>
> wrote:
> >> > Do you have any use case to really switch. Doing so disables the
> >> > vDSO access to the clocksource.
> >>
> >> Not really. Architecture timer should be sufficient for clocksource.
> >
> > When multiple clocksources are registered, the clocksource subsystems
> > picks the best one anyway, right?
> 
> As it does for the clock event devices. If there is an architected timer
> then that should be always preferred.
> 
> No idea why there is a need for the extra hardware and the drivers which
> are both never utilized.

I got feedback from BSP team for the actual usage of this timer.

Basically, this HW timer is used for measuring the processing time
of DRP-AI accurately compared to the CPU timer normally we use.

The example use cases,
Timer in FREERUN mode, Check the timer value after the restart(1usec)"
Timer in FREERUN mode, Check the timer value after the restart(10000000usec)"

What is the model to be used for this kind of HW usage? Counter or Timer?

I can think of one possible HW usage by using Counter model.
Not sure how timer model can be used for this kind of HW usage??

Eg: we can set ceiling values 1usec and 10000000usec using counter framework
  And that will trigger interrupt events corresponding to the ceiling values
  to user space and user space app can accurately measure the DRP-AI processing time.

Also counter model exposes count values to user space from the counter HW.

Cheers,
Biju

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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-07  7:52         ` Biju Das
@ 2022-12-07 10:53           ` Thomas Gleixner
  2022-12-07 11:35             ` Biju Das
  0 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2022-12-07 10:53 UTC (permalink / raw)
  To: Biju Das, Geert Uytterhoeven, William Breathitt Gray, Rob Herring
  Cc: Krzysztof Kozlowski, Philipp Zabel, William Breathitt Gray,
	Michael Turquette, Stephen Boyd, Daniel Lezcano, devicetree,
	Geert Uytterhoeven, Magnus Damm, linux-renesas-soc, linux-clk,
	linux-iio, Prabhakar Mahadev Lad, Fabrizio Castro

Biju!

On Wed, Dec 07 2022 at 07:52, Biju Das wrote:
>> On Tue, Dec 06 2022 at 09:40, Geert Uytterhoeven wrote:
>> > When multiple clocksources are registered, the clocksource subsystems
>> > picks the best one anyway, right?
>> 
>> As it does for the clock event devices. If there is an architected timer
>> then that should be always preferred.
>> 
>> No idea why there is a need for the extra hardware and the drivers which
>> are both never utilized.
>
> I got feedback from BSP team for the actual usage of this timer.
>
> Basically, this HW timer is used for measuring the processing time
> of DRP-AI accurately compared to the CPU timer normally we use.

How is a slow to access timer with a lower clock frequency more
accurate?

> The example use cases,
> Timer in FREERUN mode, Check the timer value after the restart(1usec)"
> Timer in FREERUN mode, Check the timer value after the restart(10000000usec)"
>
> What is the model to be used for this kind of HW usage? Counter or Timer?
>
> I can think of one possible HW usage by using Counter model.
> Not sure how timer model can be used for this kind of HW usage??
>
> Eg: we can set ceiling values 1usec and 10000000usec using counter framework
>   And that will trigger interrupt events corresponding to the ceiling values
>   to user space and user space app can accurately measure the DRP-AI processing time.
>
> Also counter model exposes count values to user space from the counter HW.

Counter subsystem != clocksource/event subsystem.

We are debating a clocksource/clockevent driver and not a counter
driver, right?

Thanks,

        tglx


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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-07 10:53           ` Thomas Gleixner
@ 2022-12-07 11:35             ` Biju Das
  2022-12-07 16:49               ` Thomas Gleixner
  0 siblings, 1 reply; 21+ messages in thread
From: Biju Das @ 2022-12-07 11:35 UTC (permalink / raw)
  To: Thomas Gleixner, Geert Uytterhoeven, William Breathitt Gray, Rob Herring
  Cc: Krzysztof Kozlowski, Philipp Zabel, William Breathitt Gray,
	Michael Turquette, Stephen Boyd, Daniel Lezcano, devicetree,
	Geert Uytterhoeven, Magnus Damm, linux-renesas-soc, linux-clk,
	linux-iio, Prabhakar Mahadev Lad, Fabrizio Castro

Hi Thomas Gleixner,

Thanks for the feedback.

> Subject: RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
> 
> Biju!
> 
> On Wed, Dec 07 2022 at 07:52, Biju Das wrote:
> >> On Tue, Dec 06 2022 at 09:40, Geert Uytterhoeven wrote:
> >> > When multiple clocksources are registered, the clocksource
> >> > subsystems picks the best one anyway, right?
> >>
> >> As it does for the clock event devices. If there is an architected
> >> timer then that should be always preferred.
> >>
> >> No idea why there is a need for the extra hardware and the drivers
> >> which are both never utilized.
> >
> > I got feedback from BSP team for the actual usage of this timer.
> >
> > Basically, this HW timer is used for measuring the processing time of
> > DRP-AI accurately compared to the CPU timer normally we use.
> 
> How is a slow to access timer with a lower clock frequency more accurate?

But our tick frequency for arm64 defconfig is CONFIG_HZ_250=y. So we get timer interrupt
at every 4 msec. 

How do we get timer event interrupt, eg: for 1 microsec?

> 
> > The example use cases,
> > Timer in FREERUN mode, Check the timer value after the restart(1usec)"
> > Timer in FREERUN mode, Check the timer value after the
> restart(10000000usec)"
> >
> > What is the model to be used for this kind of HW usage? Counter or
> Timer?
> >
> > I can think of one possible HW usage by using Counter model.
> > Not sure how timer model can be used for this kind of HW usage??
> >
> > Eg: we can set ceiling values 1usec and 10000000usec using counter
> framework
> >   And that will trigger interrupt events corresponding to the ceiling
> values
> >   to user space and user space app can accurately measure the DRP-AI
> processing time.
> >
> > Also counter model exposes count values to user space from the counter
> HW.
> 
> Counter subsystem != clocksource/event subsystem.
> 
> We are debating a clocksource/clockevent driver and not a counter driver,
> right?

Yes, Rob pointed out we should not misuse the compatibles as I have both
Timer and counter bindings for a given HW timer.

Timer, It can be used as broadcast and highres timer for RT.

Counter, It can be used as measuring the processing time of DRP-AI.

What is the best way to use this hardware to take care of all this use cases? 

So far all the Renesas timers used timer model. But for RZ/V2M the HW usage is different.
The customer BSP mainly uses this timer for measuring the processing time of DRP-AI, 
so the expectation is we should at least have support for this use case.

Cheers,
Biju


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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-07 11:35             ` Biju Das
@ 2022-12-07 16:49               ` Thomas Gleixner
  2022-12-09 22:24                 ` William Breathitt Gray
  0 siblings, 1 reply; 21+ messages in thread
From: Thomas Gleixner @ 2022-12-07 16:49 UTC (permalink / raw)
  To: Biju Das, Geert Uytterhoeven, William Breathitt Gray, Rob Herring
  Cc: Krzysztof Kozlowski, Philipp Zabel, William Breathitt Gray,
	Michael Turquette, Stephen Boyd, Daniel Lezcano, devicetree,
	Geert Uytterhoeven, Magnus Damm, linux-renesas-soc, linux-clk,
	linux-iio, Prabhakar Mahadev Lad, Fabrizio Castro

Biju!

On Wed, Dec 07 2022 at 11:35, Biju Das wrote:
>> Subject: RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
>> On Wed, Dec 07 2022 at 07:52, Biju Das wrote:
>> > Basically, this HW timer is used for measuring the processing time of
>> > DRP-AI accurately compared to the CPU timer normally we use.
>> 
>> How is a slow to access timer with a lower clock frequency more accurate?
>
> But our tick frequency for arm64 defconfig is CONFIG_HZ_250=y. So we
> get timer interrupt at every 4 msec.

CONFIG_HIGH_RES_TIMERS=y

> How do we get timer event interrupt, eg: for 1 microsec?

clock_nanosleep(...);

Though 1usec is wishful thinking with either variant of timer hardware.

>> 
>> We are debating a clocksource/clockevent driver and not a counter driver,
>> right?
>
> Yes, Rob pointed out we should not misuse the compatibles as I have both
> Timer and counter bindings for a given HW timer.
>
> Timer, It can be used as broadcast and highres timer for RT.

I buy the broadcast part if you really have a ARM architected timer
which stops in deep idle states. Highres for RT, no! The arm architected
timer works perfectly fine for that.

> Counter, It can be used as measuring the processing time of DRP-AI.

Sigh. You can do that with the architected timer too, especially when
you are going to do the measurement in user space.

clock_gettime(), which uses the VDSO with the architected timer is fast
to access and accurate.

Thanks,

        tglx

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

* Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-07 16:49               ` Thomas Gleixner
@ 2022-12-09 22:24                 ` William Breathitt Gray
  2022-12-10  7:52                   ` Biju Das
  0 siblings, 1 reply; 21+ messages in thread
From: William Breathitt Gray @ 2022-12-09 22:24 UTC (permalink / raw)
  To: Biju Das
  Cc: Thomas Gleixner, Geert Uytterhoeven, Rob Herring,
	Krzysztof Kozlowski, Philipp Zabel, Michael Turquette,
	Stephen Boyd, Daniel Lezcano, devicetree, Geert Uytterhoeven,
	Magnus Damm, linux-renesas-soc, linux-clk, linux-iio,
	Prabhakar Mahadev Lad, Fabrizio Castro

[-- Attachment #1: Type: text/plain, Size: 1642 bytes --]

On Wed, Dec 07, 2022 at 05:49:09PM +0100, Thomas Gleixner wrote:
> On Wed, Dec 07 2022 at 11:35, Biju Das wrote:
> > Counter, It can be used as measuring the processing time of DRP-AI.
> 
> Sigh. You can do that with the architected timer too, especially when
> you are going to do the measurement in user space.
> 
> clock_gettime(), which uses the VDSO with the architected timer is fast
> to access and accurate.
> 
> Thanks,
> 
>         tglx

Hi Biju,

It's true that you could implement a Counter driver to achieve what you
want here, but I don't think that's the most apt interface for this
device. Your device is used to measure the processing time of DRP-AI, so
modeling this as a clocksource seems like the right approach to take.

Of course, if there is something missing from clocksource/clockevent
that you need, then it should be added to the subsystem. So let's try to
narrow down exactly what functionality you need.

You gave a Counter use-case example earlier where you can configure the
ceiling value of the timer (e.g. to 1usec or 10000000usec) and push
Counter events on the interrupts that trigger off that that
configuration; the Counter subsystem can logs the current system time
everytime a Counter event is pushed.

Could the same thing be achieved using clockevents framework instead?
With this approach you would register an event to fire in the future
(e.g. 1usec or 10000000usec) and then call clock_gettime() to get the
current system when you're notified of the event. Would this approach
work for your use-case, or is something else missing here?

William Breathitt Gray

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-09 22:24                 ` William Breathitt Gray
@ 2022-12-10  7:52                   ` Biju Das
  2022-12-10 10:59                     ` Thomas Gleixner
  0 siblings, 1 reply; 21+ messages in thread
From: Biju Das @ 2022-12-10  7:52 UTC (permalink / raw)
  To: William Breathitt Gray
  Cc: Thomas Gleixner, Geert Uytterhoeven, Rob Herring,
	Krzysztof Kozlowski, Philipp Zabel, Michael Turquette,
	Stephen Boyd, Daniel Lezcano, devicetree, Geert Uytterhoeven,
	Magnus Damm, linux-renesas-soc, linux-clk, linux-iio,
	Prabhakar Mahadev Lad, Fabrizio Castro

Hi William Breathitt Gray,

Thanks for the feedback.

> Subject: Re: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
> 
> On Wed, Dec 07, 2022 at 05:49:09PM +0100, Thomas Gleixner wrote:
> > On Wed, Dec 07 2022 at 11:35, Biju Das wrote:
> > > Counter, It can be used as measuring the processing time of DRP-AI.
> >
> > Sigh. You can do that with the architected timer too, especially when
> > you are going to do the measurement in user space.
> >
> > clock_gettime(), which uses the VDSO with the architected timer is
> > fast to access and accurate.
> >
> > Thanks,
> >
> >         tglx
> 
> Hi Biju,
> 
> It's true that you could implement a Counter driver to achieve what you
> want here, but I don't think that's the most apt interface for this
> device. Your device is used to measure the processing time of DRP-AI, so
> modeling this as a clocksource seems like the right approach to take.
> 
> Of course, if there is something missing from clocksource/clockevent that
> you need, then it should be added to the subsystem. So let's try to narrow
> down exactly what functionality you need.
> 
> You gave a Counter use-case example earlier where you can configure the
> ceiling value of the timer (e.g. to 1usec or 10000000usec) and push
> Counter events on the interrupts that trigger off that that configuration;
> the Counter subsystem can logs the current system time everytime a Counter
> event is pushed.
> 
> Could the same thing be achieved using clockevents framework instead?

If I am correct, from this thread discussion, we can make use of architecture timer
with hrtimer, which will give call back events to user space after time expires. 
In the callback, we could call clock_gettime(), which uses the VDSO which is fast
and accurate.

So there is no need to use any extra HW timer.

scheduling tick is 4millisec. so if we want callback at 1 microsec, then we need to 
use clock_nanosleep. Getting 1 microsec callback to user space is challenging as
the scheduling tick is only 4 millisec.

Cheers,
Biju

> With this approach you would register an event to fire in the future (e.g.
> 1usec or 10000000usec) and then call clock_gettime() to get the current
> system when you're notified of the event. Would this approach work for
> your use-case, or is something else missing here?

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

* RE: [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support
  2022-12-10  7:52                   ` Biju Das
@ 2022-12-10 10:59                     ` Thomas Gleixner
  0 siblings, 0 replies; 21+ messages in thread
From: Thomas Gleixner @ 2022-12-10 10:59 UTC (permalink / raw)
  To: Biju Das, William Breathitt Gray
  Cc: Geert Uytterhoeven, Rob Herring, Krzysztof Kozlowski,
	Philipp Zabel, Michael Turquette, Stephen Boyd, Daniel Lezcano,
	devicetree, Geert Uytterhoeven, Magnus Damm, linux-renesas-soc,
	linux-clk, linux-iio, Prabhakar Mahadev Lad, Fabrizio Castro

On Sat, Dec 10 2022 at 07:52, Biju Das wrote:
> scheduling tick is 4millisec. so if we want callback at 1 microsec,
> then we need to use clock_nanosleep. Getting 1 microsec callback to
> user space is challenging as the scheduling tick is only 4 millisec.

The tick is only relevant if high resolution timers are disabled because
then hrtimers are expired in the tick. If high resolution timers are
enabled then the hrtimer expiry happens at the exact expiry time.

What's challenging about the 1 microsecond accuracy is that the system
immanent latencies are already in that range. So while the timer fires
exactly, the actual execution of the woken up task in user space is not
exact as that is subject to the worst case sum of latencies in the
system.

Thanks,

        tglx

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

* Re: [PATCH 1/6] clk: renesas: r9a09g011: Add TIM clock and reset entries
  2022-12-05 14:59 ` [PATCH 1/6] clk: renesas: r9a09g011: Add TIM clock and reset entries Biju Das
@ 2022-12-21 14:47   ` Geert Uytterhoeven
  0 siblings, 0 replies; 21+ messages in thread
From: Geert Uytterhoeven @ 2022-12-21 14:47 UTC (permalink / raw)
  To: biju.das.jz
  Cc: Michael Turquette, Stephen Boyd, linux-renesas-soc, linux-clk,
	Lad Prabhakar, Fabrizio Castro

On Mon, Dec 5, 2022 at 4:00 PM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> Add Compare-Match Timer (TIM) clock and reset entries to CPG
> driver.
>
> The TIM IP on the RZ/V2M comes with 32 channels, but the ISP has
> full control of channels 0 to 7, and channels 24 to 31. Therefore
> Linux is only allowed to use channels 8 to 23.
>
> The TIM has shared peripheral clock with other modules, so mark it
> as critical clock.
>
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-clk-for-v6.3.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

end of thread, other threads:[~2022-12-21 14:48 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-05 14:59 [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Biju Das
2022-12-05 14:59 ` [PATCH 1/6] clk: renesas: r9a09g011: Add TIM clock and reset entries Biju Das
2022-12-21 14:47   ` Geert Uytterhoeven
2022-12-05 14:59 ` [PATCH 2/6] dt-bindings: timer: Add RZ/V2M TIM binding Biju Das
2022-12-05 14:59 ` [PATCH 3/6] clocksource/drivers/rzv2m-tim: Add Renesas RZ/V2M compare match timer(TIM) driver Biju Das
2022-12-05 14:59 ` [PATCH 4/6] dt-bindings: counter: Add RZ/V2M TIM counter binding Biju Das
2022-12-05 14:59 ` [PATCH 5/6] counter: Add Renesas RZ/V2M TIM counter driver Biju Das
2022-12-05 14:59 ` [PATCH 6/6] arm64: dts: renesas: r9a09g011: Add tim nodes Biju Das
2022-12-05 22:50 ` [PATCH 0/6] Add RZ/V2M Compare-Match Timer (TIM) support Rob Herring
2022-12-06  8:13   ` Biju Das
2022-12-06  8:40     ` Geert Uytterhoeven
2022-12-06  8:57       ` Thomas Gleixner
2022-12-06  9:45         ` Biju Das
2022-12-07  7:52         ` Biju Das
2022-12-07 10:53           ` Thomas Gleixner
2022-12-07 11:35             ` Biju Das
2022-12-07 16:49               ` Thomas Gleixner
2022-12-09 22:24                 ` William Breathitt Gray
2022-12-10  7:52                   ` Biju Das
2022-12-10 10:59                     ` Thomas Gleixner
2022-12-06  8:59       ` Biju Das

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.