From patchwork Mon Dec 5 14:59:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 13064592 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1043C4321E for ; Mon, 5 Dec 2022 15:00:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231298AbiLEPAI (ORCPT ); Mon, 5 Dec 2022 10:00:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229970AbiLEPAH (ORCPT ); Mon, 5 Dec 2022 10:00:07 -0500 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 74D05BE3A; Mon, 5 Dec 2022 07:00:06 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.96,219,1665414000"; d="scan'208";a="145045877" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 06 Dec 2022 00:00:05 +0900 Received: from localhost.localdomain (unknown [10.226.92.127]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 1467C4009BCB; Tue, 6 Dec 2022 00:00:02 +0900 (JST) From: Biju Das To: Michael Turquette , Stephen Boyd Cc: Biju Das , Geert Uytterhoeven , linux-renesas-soc@vger.kernel.org, linux-clk@vger.kernel.org, Lad Prabhakar , Fabrizio Castro Subject: [PATCH 1/6] clk: renesas: r9a09g011: Add TIM clock and reset entries Date: Mon, 5 Dec 2022 14:59:50 +0000 Message-Id: <20221205145955.391526-2-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> References: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org 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 Reviewed-by: Geert Uytterhoeven --- 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, From patchwork Mon Dec 5 14:59:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 13064594 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 686CBC47088 for ; Mon, 5 Dec 2022 15:00:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231770AbiLEPAL (ORCPT ); Mon, 5 Dec 2022 10:00:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229970AbiLEPAK (ORCPT ); Mon, 5 Dec 2022 10:00:10 -0500 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 2EC43BC85; Mon, 5 Dec 2022 07:00:09 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.96,219,1665414000"; d="scan'208";a="145045904" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 06 Dec 2022 00:00:08 +0900 Received: from localhost.localdomain (unknown [10.226.92.127]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 1BD2A4009BCB; Tue, 6 Dec 2022 00:00:05 +0900 (JST) From: Biju Das To: Rob Herring , Krzysztof Kozlowski Cc: Biju Das , Daniel Lezcano , Thomas Gleixner , devicetree@vger.kernel.org, Geert Uytterhoeven , Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: [PATCH 2/6] dt-bindings: timer: Add RZ/V2M TIM binding Date: Mon, 5 Dec 2022 14:59:51 +0000 Message-Id: <20221205145955.391526-3-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> References: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add device tree bindings for the RZ/V2{M, MA} Compare Match Timer (TIM). Signed-off-by: Biju Das --- .../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 + +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 + #include + + tim22: tim@a4000b00 { + compatible = "renesas,r9a09g011-tim", "renesas,rzv2m-tim"; + reg = <0xa4000b00 0x80>; + interrupts = ; + 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>; + }; From patchwork Mon Dec 5 14:59:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 13064595 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26D01C47088 for ; Mon, 5 Dec 2022 15:00:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231696AbiLEPAO (ORCPT ); Mon, 5 Dec 2022 10:00:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231793AbiLEPAN (ORCPT ); Mon, 5 Dec 2022 10:00:13 -0500 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id E4533DFCE for ; Mon, 5 Dec 2022 07:00:11 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.96,219,1665414000"; d="scan'208";a="142271719" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 06 Dec 2022 00:00:11 +0900 Received: from localhost.localdomain (unknown [10.226.92.127]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 6DDFC4009BCB; Tue, 6 Dec 2022 00:00:09 +0900 (JST) From: Biju Das To: Philipp Zabel Cc: Biju Das , Daniel Lezcano , Thomas Gleixner , Geert Uytterhoeven , Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: [PATCH 3/6] clocksource/drivers/rzv2m-tim: Add Renesas RZ/V2M compare match timer(TIM) driver Date: Mon, 5 Dec 2022 14:59:52 +0000 Message-Id: <20221205145955.391526-4-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> References: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org 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 --- 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 +#include +#include +#include +#include +#include +#include +#include + +/* 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 "); +MODULE_LICENSE("GPL"); From patchwork Mon Dec 5 14:59:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 13064596 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33977C4321E for ; Mon, 5 Dec 2022 15:00:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231819AbiLEPAR (ORCPT ); Mon, 5 Dec 2022 10:00:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60962 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229970AbiLEPAP (ORCPT ); Mon, 5 Dec 2022 10:00:15 -0500 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A9CE7DF7A; Mon, 5 Dec 2022 07:00:14 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.96,219,1665414000"; d="scan'208";a="142271742" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 06 Dec 2022 00:00:14 +0900 Received: from localhost.localdomain (unknown [10.226.92.127]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 34B134009BED; Tue, 6 Dec 2022 00:00:11 +0900 (JST) From: Biju Das To: Rob Herring , Krzysztof Kozlowski Cc: Biju Das , devicetree@vger.kernel.org, Geert Uytterhoeven , Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: [PATCH 4/6] dt-bindings: counter: Add RZ/V2M TIM counter binding Date: Mon, 5 Dec 2022 14:59:53 +0000 Message-Id: <20221205145955.391526-5-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> References: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add device tree binding for the Renesas RZ/V2M Counter Match Timer (a.k.a TIM). Signed-off-by: Biju Das --- .../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 + +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 + #include + + tim8: tim@a4000400 { + compatible = "renesas,r9a09g011-tim-cnt", "renesas,rzv2m-tim-cnt"; + reg = <0xa4000400 0x80>; + interrupts = ; + 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>; + }; From patchwork Mon Dec 5 14:59:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 13064597 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 22F98C47088 for ; Mon, 5 Dec 2022 15:00:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229970AbiLEPAU (ORCPT ); Mon, 5 Dec 2022 10:00:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231857AbiLEPAT (ORCPT ); Mon, 5 Dec 2022 10:00:19 -0500 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 6C8F91D30A; Mon, 5 Dec 2022 07:00:17 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.96,219,1665414000"; d="scan'208";a="142271763" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 06 Dec 2022 00:00:17 +0900 Received: from localhost.localdomain (unknown [10.226.92.127]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id E98224009BD8; Tue, 6 Dec 2022 00:00:14 +0900 (JST) From: Biju Das To: William Breathitt Gray , Philipp Zabel Cc: Biju Das , linux-iio@vger.kernel.org, Geert Uytterhoeven , Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: [PATCH 5/6] counter: Add Renesas RZ/V2M TIM counter driver Date: Mon, 5 Dec 2022 14:59:54 +0000 Message-Id: <20221205145955.391526-6-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> References: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org 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 --- 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(COUNTER); From patchwork Mon Dec 5 14:59:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 13064598 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70581C47089 for ; Mon, 5 Dec 2022 15:00:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231828AbiLEPAY (ORCPT ); Mon, 5 Dec 2022 10:00:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32894 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231599AbiLEPAX (ORCPT ); Mon, 5 Dec 2022 10:00:23 -0500 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 628A51D0F4; Mon, 5 Dec 2022 07:00:22 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.96,219,1665414000"; d="scan'208";a="145045992" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 06 Dec 2022 00:00:20 +0900 Received: from localhost.localdomain (unknown [10.226.92.127]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id B119B4009F87; Tue, 6 Dec 2022 00:00:17 +0900 (JST) From: Biju Das To: Rob Herring , Krzysztof Kozlowski Cc: Biju Das , Geert Uytterhoeven , Magnus Damm , linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org, Fabrizio Castro Subject: [PATCH 6/6] arm64: dts: renesas: r9a09g011: Add tim nodes Date: Mon, 5 Dec 2022 14:59:55 +0000 Message-Id: <20221205145955.391526-7-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> References: <20221205145955.391526-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org 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 --- 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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";