linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] Add RZ/V2{M, MA} driver support
@ 2022-11-18 13:16 Biju Das
  2022-11-18 13:16 ` [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries Biju Das
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Biju Das @ 2022-11-18 13:16 UTC (permalink / raw)
  To: Thierry Reding, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Philipp Zabel
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, devicetree, linux-renesas-soc, linux-clk,
	Fabrizio Castro

The RZ/V2{M, MA} PWM Timer (PWM) is composed of 16 channels. Linux is only
allowed access to channels 8 to 14 on RZ/V2M, while there is no restriction
for RZ/V2MA.

The RZ/V2{M, MA} PWM Timer (PWM) supports the following functions:
 * The PWM has 24-bit counters which operate at PWM_CLK (48 MHz).
 * The frequency division ratio for internal counter operation is selectable
    as PWM_CLK divided by 1, 16, 256, or 2048.
 * The period as well as the duty cycle is adjustable.
 * The low-level and high-level order of the PWM signals can be inverted.
 * The duty cycle of the PWM signal is selectable in the range from 0 to 100%.
 * The minimum resolution is 20.83 ns.
 * Three interrupt sources: Rising and falling edges of the PWM signal and
   clearing of the counter
 * Counter operation and the bus interface are asynchronous and both can
   operate independently of the magnitude relationship of the respective
   clock periods.

Note:
 Hardware manual for this IP can be found here
 https://www.renesas.com/in/en/document/mah/rzv2m-users-manual-hardware?language=en

Biju Das (5):
  clk: renesas: r9a09g011: Add PWM clock entries
  dt-bindings: pwm: Add RZ/V2M PWM binding
  pwm: Add support for RZ/V2M PWM driver
  arm64: dts: renesas: r9a09g011: Add pwm nodes
  arm64: dts: renesas: rzv2m evk: Enable pwm

 .../bindings/pwm/renesas,rzv2m-pwm.yaml       |  98 +++++
 .../boot/dts/renesas/r9a09g011-v2mevk2.dts    |  70 ++++
 arch/arm64/boot/dts/renesas/r9a09g011.dtsi    |  91 ++++
 drivers/clk/renesas/r9a09g011-cpg.c           |   9 +
 drivers/pwm/Kconfig                           |  11 +
 drivers/pwm/Makefile                          |   1 +
 drivers/pwm/pwm-rzv2m.c                       | 390 ++++++++++++++++++
 7 files changed, 670 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/renesas,rzv2m-pwm.yaml
 create mode 100644 drivers/pwm/pwm-rzv2m.c

-- 
2.25.1


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

* [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries
  2022-11-18 13:16 [PATCH 0/5] Add RZ/V2{M, MA} driver support Biju Das
@ 2022-11-18 13:16 ` Biju Das
  2022-11-24  8:40   ` Geert Uytterhoeven
  2022-11-18 13:16 ` [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding Biju Das
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Biju Das @ 2022-11-18 13:16 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: Biju Das, Geert Uytterhoeven, linux-renesas-soc, linux-clk,
	Fabrizio Castro

The PWM IP on the RZ/V2M comes with 16 channels, but the ISP has
full control of channels 0 to 7, and channel 15, therefore Linux
is only allowed to use channels 8 to 14.

The PWM channel 15 shares apb clock and reset with PWM{8..14}.
The reset is deasserted by the bootloader/ISP.

Add PWM{8..14} clocks to CPG driver and mark apb clock as
critical clock, so that the apb clock will be always on.

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

diff --git a/drivers/clk/renesas/r9a09g011-cpg.c b/drivers/clk/renesas/r9a09g011-cpg.c
index fbef1b35d254..536725762c61 100644
--- a/drivers/clk/renesas/r9a09g011-cpg.c
+++ b/drivers/clk/renesas/r9a09g011-cpg.c
@@ -136,6 +136,14 @@ static const struct rzg2l_mod_clk r9a09g011_mod_clks[] __initconst = {
 	DEF_MOD("iic_pclk1",	R9A09G011_IIC_PCLK1,	 CLK_SEL_E,    0x424, 12),
 	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("pwm8_15_pclk",	R9A09G011_CPERI_GRPF_PCLK, CLK_SEL_E,  0x434, 0),
+	DEF_MOD("pwm8_clk",	R9A09G011_PWM8_CLK,	 CLK_MAIN,     0x434, 4),
+	DEF_MOD("pwm9_clk",	R9A09G011_PWM9_CLK,	 CLK_MAIN,     0x434, 5),
+	DEF_MOD("pwm10_clk",	R9A09G011_PWM10_CLK,	 CLK_MAIN,     0x434, 6),
+	DEF_MOD("pwm11_clk",	R9A09G011_PWM11_CLK,	 CLK_MAIN,     0x434, 7),
+	DEF_MOD("pwm12_clk",	R9A09G011_PWM12_CLK,	 CLK_MAIN,     0x434, 8),
+	DEF_MOD("pwm13_clk",	R9A09G011_PWM13_CLK,	 CLK_MAIN,     0x434, 9),
+	DEF_MOD("pwm14_clk",	R9A09G011_PWM14_CLK,	 CLK_MAIN,     0x434, 10),
 	DEF_MOD("urt_pclk",	R9A09G011_URT_PCLK,	 CLK_SEL_E,    0x438, 4),
 	DEF_MOD("urt0_clk",	R9A09G011_URT0_CLK,	 CLK_SEL_W0,   0x438, 5),
 	DEF_MOD("ca53",		R9A09G011_CA53_CLK,	 CLK_DIV_A,    0x448, 0),
@@ -152,6 +160,7 @@ 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_GRPF_PCLK,
 	MOD_CLK_BASE + R9A09G011_GIC_CLK,
 	MOD_CLK_BASE + R9A09G011_SYC_CNT_CLK,
 	MOD_CLK_BASE + R9A09G011_URT_PCLK,
-- 
2.25.1


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

* [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding
  2022-11-18 13:16 [PATCH 0/5] Add RZ/V2{M, MA} driver support Biju Das
  2022-11-18 13:16 ` [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries Biju Das
@ 2022-11-18 13:16 ` Biju Das
  2022-11-22 11:46   ` Krzysztof Kozlowski
  2022-11-24  8:43   ` Geert Uytterhoeven
  2022-11-18 13:16 ` [PATCH 3/5] pwm: Add support for RZ/V2M PWM driver Biju Das
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 12+ messages in thread
From: Biju Das @ 2022-11-18 13:16 UTC (permalink / raw)
  To: Thierry Reding, Rob Herring, Krzysztof Kozlowski
  Cc: Biju Das, Uwe Kleine-König, linux-pwm, devicetree,
	Geert Uytterhoeven, Fabrizio Castro, linux-renesas-soc

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

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

diff --git a/Documentation/devicetree/bindings/pwm/renesas,rzv2m-pwm.yaml b/Documentation/devicetree/bindings/pwm/renesas,rzv2m-pwm.yaml
new file mode 100644
index 000000000000..d615213357ad
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/renesas,rzv2m-pwm.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/renesas,rzv2m-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/V2{M, MA} PWM Timer (PWM)
+
+maintainers:
+  - Biju Das <biju.das.jz@bp.renesas.com>
+
+description: |
+  The RZ/V2{M, MA} PWM Timer (PWM) composed of 16 channels. It supports the
+  following functions
+  * The PWM has 24-bit counters which operate at PWM_CLK (48 MHz).
+  * The frequency division ratio for internal counter operation is selectable
+    as PWM_CLK divided by 1, 16, 256, or 2048.
+  * The period as well as the duty cycle is adjustable.
+  * The low-level and high-level order of the PWM signals can be inverted.
+  * The duty cycle of the PWM signal is selectable in the range from 0 to 100%.
+  * The minimum resolution is 20.83 ns.
+  * Three interrupt sources: Rising and falling edges of the PWM signal and
+    clearing of the counter
+  * Counter operation and the bus interface are asynchronous and both can
+    operate independently of the magnitude relationship of the respective
+    clock periods.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r9a09g011-pwm  # RZ/V2M
+          - renesas,r9a09g055-pwm  # RZ/V2MA
+      - const: renesas,rzv2m-pwm
+
+  reg:
+    maxItems: 1
+
+  '#pwm-cells':
+    const: 2
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: CPU Peripheral Group F APB clock
+      - description: PWM clock
+
+  clock-names:
+    items:
+      - const: apb
+      - const: pwm
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - power-domains
+
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - renesas,r9a09g055-pwm
+then:
+  required:
+    - resets
+
+allOf:
+  - $ref: pwm.yaml#
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r9a09g011-cpg.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    pwm8: pwm@a4010400 {
+        compatible = "renesas,r9a09g011-pwm", "renesas,rzv2m-pwm";
+        reg = <0xa4010400 0x80>;
+        interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPF_PCLK>,
+                 <&cpg CPG_MOD R9A09G011_PWM8_CLK>;
+        clock-names = "apb", "pwm";
+        power-domains = <&cpg>;
+        #pwm-cells = <2>;
+    };
-- 
2.25.1


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

* [PATCH 3/5] pwm: Add support for RZ/V2M PWM driver
  2022-11-18 13:16 [PATCH 0/5] Add RZ/V2{M, MA} driver support Biju Das
  2022-11-18 13:16 ` [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries Biju Das
  2022-11-18 13:16 ` [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding Biju Das
@ 2022-11-18 13:16 ` Biju Das
  2022-11-18 13:16 ` [PATCH 4/5] arm64: dts: renesas: r9a09g011: Add pwm nodes Biju Das
  2022-11-18 13:16 ` [PATCH 5/5] arm64: dts: renesas: rzv2m evk: Enable pwm Biju Das
  4 siblings, 0 replies; 12+ messages in thread
From: Biju Das @ 2022-11-18 13:16 UTC (permalink / raw)
  To: Thierry Reding, Philipp Zabel
  Cc: Biju Das, Uwe Kleine-König, linux-pwm, Geert Uytterhoeven,
	Fabrizio Castro, linux-renesas-soc

The RZ/V2{M, MA} PWM Timer supports the following functions:

 * The PWM has 24-bit counters which operate at PWM_CLK (48 MHz).
 * The frequency division ratio for internal counter operation is
   selectable as PWM_CLK divided by 1, 16, 256, or 2048.
 * The period as well as the duty cycle is adjustable.
 * The low-level and high-level order of the PWM signals can be
   inverted.
 * The duty cycle of the PWM signal is selectable in the range from
   0 to 100%.
 * The minimum resolution is 20.83 ns.
 * Three interrupt sources: Rising and falling edges of the PWM signal
   and clearing of the counter
 * Counter operation and the bus interface are asynchronous and both
   can operate independently of the magnitude relationship of the
   respective clock periods.

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

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 60d13a949bc5..4ed68495a611 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -473,6 +473,17 @@ config PWM_RENESAS_TPU
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-renesas-tpu.
 
+config PWM_RZV2M
+       tristate "Renesas RZ/V2M PWM support"
+       depends on ARCH_R9A09G011 || COMPILE_TEST
+       depends on HAS_IOMEM
+       help
+         This driver exposes the PWM controller found in Renesas
+         RZ/V2M like chips through the PWM API.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-rzv2m.
+
 config PWM_ROCKCHIP
 	tristate "Rockchip PWM support"
 	depends on ARCH_ROCKCHIP || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 7bf1a29f02b8..a95aabae9115 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RASPBERRYPI_POE)	+= pwm-raspberrypi-poe.o
 obj-$(CONFIG_PWM_RCAR)		+= pwm-rcar.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
+obj-$(CONFIG_PWM_RZV2M)		+= pwm-rzv2m.o
 obj-$(CONFIG_PWM_ROCKCHIP)	+= pwm-rockchip.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SIFIVE)	+= pwm-sifive.o
diff --git a/drivers/pwm/pwm-rzv2m.c b/drivers/pwm/pwm-rzv2m.c
new file mode 100644
index 000000000000..fded64128445
--- /dev/null
+++ b/drivers/pwm/pwm-rzv2m.c
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/V2M PWM Timer (PWM) driver
+ *
+ * Copyright (C) 2022 Renesas Electronics Corporation
+ *
+ * Hardware manual for this IP can be found here
+ * https://www.renesas.com/in/en/document/mah/rzv2m-users-manual-hardware?language=en
+ *
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pwm.h>
+#include <linux/reset.h>
+#include <linux/time.h>
+
+#define U24_MASK	GENMASK(23, 0)
+#define U24_MAX		(U24_MASK)
+
+#define RZV2M_PWMCTR	0x0
+#define RZV2M_PWMCYC	0x4
+#define RZV2M_PWMLOW	0x8
+#define RZV2M_PWMCNT	0xc
+
+#define RZV2M_PWMCTR_PWMPS	GENMASK(17, 16)
+#define RZV2M_PWMCTR_PWMHL	BIT(3)
+#define RZV2M_PWMCTR_PWMTM	BIT(2)
+#define RZV2M_PWMCTR_PWME	BIT(1)
+
+#define F2CYCLE_NSEC(f)		(1000000000 / (f))
+
+struct rzv2m_pwm_chip {
+	struct pwm_chip chip;
+	void __iomem *mmio;
+	struct reset_control *rstc;
+	struct clk *apb_clk;
+	struct clk *pwm_clk;
+	unsigned long rate;
+	unsigned long delay;
+};
+
+static const int rzv2m_pwm_freq_div[] = { 1, 16, 256, 2048 };
+
+static inline struct rzv2m_pwm_chip *to_rzv2m_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct rzv2m_pwm_chip, chip);
+}
+
+static void rzv2m_pwm_wait_delay(struct rzv2m_pwm_chip *chip)
+{
+	/* delay timer when change the setting register */
+	ndelay(chip->delay);
+}
+
+static void rzv2m_pwm_write(struct rzv2m_pwm_chip *rzv2m_pwm, u32 reg, u32 data)
+{
+	writel(data, rzv2m_pwm->mmio + reg);
+}
+
+static u32 rzv2m_pwm_read(struct rzv2m_pwm_chip *rzv2m_pwm, u32 reg)
+{
+	return readl(rzv2m_pwm->mmio + reg);
+}
+
+static void rzv2m_pwm_modify(struct rzv2m_pwm_chip *rzv2m_pwm, u32 reg, u32 clr,
+			     u32 set)
+{
+	rzv2m_pwm_write(rzv2m_pwm, reg,
+			(rzv2m_pwm_read(rzv2m_pwm, reg) & ~clr) | set);
+}
+
+static u8 rzv2m_pwm_calculate_prescale(struct rzv2m_pwm_chip *rzv2m_pwm,
+				       u64 period_cycles)
+{
+	u32 prescaled_period_cycles;
+	u8 prescale;
+
+	prescaled_period_cycles = period_cycles >> 24;
+	if (prescaled_period_cycles >= 256)
+		prescale = 3;
+	else
+		prescale = (fls(prescaled_period_cycles) + 3) / 4;
+
+	return prescale;
+}
+
+static bool rzv2m_pwm_is_ch_enabled(struct rzv2m_pwm_chip *rzv2m_pwm)
+{
+	return !!(rzv2m_pwm_read(rzv2m_pwm, RZV2M_PWMCTR) & RZV2M_PWMCTR_PWME);
+}
+
+static int rzv2m_pwm_enable(struct rzv2m_pwm_chip *rzv2m_pwm)
+{
+	int rc;
+
+	rc = pm_runtime_resume_and_get(rzv2m_pwm->chip.dev);
+	if (rc)
+		return rc;
+
+	rzv2m_pwm_modify(rzv2m_pwm, RZV2M_PWMCTR, RZV2M_PWMCTR_PWME,
+			 RZV2M_PWMCTR_PWME);
+	rzv2m_pwm_wait_delay(rzv2m_pwm);
+
+	return 0;
+}
+
+static void rzv2m_pwm_disable(struct rzv2m_pwm_chip *rzv2m_pwm)
+{
+	rzv2m_pwm_modify(rzv2m_pwm, RZV2M_PWMCTR, RZV2M_PWMCTR_PWME, 0);
+	rzv2m_pwm_wait_delay(rzv2m_pwm);
+
+	pm_runtime_put_sync(rzv2m_pwm->chip.dev);
+}
+
+static int rzv2m_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			    const struct pwm_state *state)
+{
+	struct rzv2m_pwm_chip *rzv2m_pwm = to_rzv2m_pwm_chip(chip);
+	unsigned long pwm_cyc, pwm_low;
+	u8 prescale;
+	u64 pc, dc;
+	int err;
+
+	/*
+	 * Refuse clk rates > 1 GHz to prevent overflowing the following
+	 * calculation.
+	 */
+	if (rzv2m_pwm->rate > NSEC_PER_SEC)
+		return -EINVAL;
+
+	/*
+	 * Formula for calculating PWM Cycle Setting Register
+	 * PWM cycle = (PWM period(ns) / (PWM_CLK period(ns) × Div ratio)) - 1
+	 */
+
+	pc = mul_u64_u32_div(state->period, rzv2m_pwm->rate, NSEC_PER_SEC);
+	dc = mul_u64_u32_div(state->duty_cycle, rzv2m_pwm->rate, NSEC_PER_SEC);
+	prescale = rzv2m_pwm_calculate_prescale(rzv2m_pwm, pc);
+
+	pwm_cyc = pc / rzv2m_pwm_freq_div[prescale];
+	if (pc / rzv2m_pwm_freq_div[prescale] <= U24_MAX)
+		pwm_cyc = pwm_cyc ? (pwm_cyc - 1) : 0;
+	else
+		pwm_cyc = U24_MAX;
+
+	pwm_low = dc / rzv2m_pwm_freq_div[prescale];
+	if (pwm_low <= U24_MAX)
+		pwm_low = pwm_low ? (pwm_low - 1) : 0;
+	else
+		pwm_low = U24_MAX;
+
+	/*
+	 * If the PWM channel is disabled, make sure to turn on the clock
+	 * before writing the register.
+	 */
+	if (!pwm_is_enabled(pwm)) {
+		err = pm_runtime_resume_and_get(rzv2m_pwm->chip.dev);
+		if (err)
+			return err;
+	}
+
+	rzv2m_pwm_modify(rzv2m_pwm, RZV2M_PWMCTR, RZV2M_PWMCTR_PWMTM, 0);
+	rzv2m_pwm_modify(rzv2m_pwm, RZV2M_PWMCTR, RZV2M_PWMCTR_PWMPS,
+			 FIELD_PREP(RZV2M_PWMCTR_PWMPS, prescale));
+
+	rzv2m_pwm_write(rzv2m_pwm, RZV2M_PWMCYC, pwm_cyc);
+	rzv2m_pwm_write(rzv2m_pwm, RZV2M_PWMLOW, pwm_low);
+
+	if (state->polarity == PWM_POLARITY_NORMAL)
+		rzv2m_pwm_modify(rzv2m_pwm, RZV2M_PWMCTR, RZV2M_PWMCTR_PWMHL, 0);
+	else
+		rzv2m_pwm_modify(rzv2m_pwm, RZV2M_PWMCTR, RZV2M_PWMCTR_PWMHL,
+				 RZV2M_PWMCTR_PWMHL);
+
+	rzv2m_pwm_wait_delay(rzv2m_pwm);
+
+	/*
+	 * If the PWM is not enabled, turn the clock off again to save power.
+	 */
+	if (!pwm_is_enabled(pwm))
+		pm_runtime_put(rzv2m_pwm->chip.dev);
+
+	return 0;
+}
+
+static void rzv2m_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+				struct pwm_state *state)
+{
+	struct rzv2m_pwm_chip *rzv2m_pwm = to_rzv2m_pwm_chip(chip);
+	u8 prescale;
+	u64 tmp;
+	u32 val;
+
+	pm_runtime_get_sync(chip->dev);
+	val = rzv2m_pwm_read(rzv2m_pwm, RZV2M_PWMCTR);
+	state->enabled = FIELD_GET(RZV2M_PWMCTR_PWME, val);
+	state->polarity = FIELD_GET(RZV2M_PWMCTR_PWMHL, val);
+	prescale = FIELD_GET(RZV2M_PWMCTR_PWMPS, val);
+	val = rzv2m_pwm_read(rzv2m_pwm, RZV2M_PWMCYC);
+	val = val ? val + 1 : 0;
+	tmp = DIV_ROUND_UP_ULL(NSEC_PER_SEC * (u64)val, rzv2m_pwm->rate);
+	state->period = tmp * rzv2m_pwm_freq_div[prescale];
+
+	val = rzv2m_pwm_read(rzv2m_pwm, RZV2M_PWMLOW);
+	val = val ? val + 1 : 0;
+	tmp = DIV_ROUND_UP_ULL(NSEC_PER_SEC * (u64)val, rzv2m_pwm->rate);
+	state->duty_cycle = tmp * rzv2m_pwm_freq_div[prescale];
+	pm_runtime_put(chip->dev);
+}
+
+static int rzv2m_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			   const struct pwm_state *state)
+{
+	struct rzv2m_pwm_chip *rzv2m_pwm = to_rzv2m_pwm_chip(chip);
+	bool enabled = pwm->state.enabled;
+	int ret;
+
+	if (!state->enabled) {
+		if (enabled)
+			rzv2m_pwm_disable(rzv2m_pwm);
+
+		return 0;
+	}
+
+	ret = rzv2m_pwm_config(chip, pwm, state);
+	if (ret)
+		return ret;
+
+	if (!enabled)
+		ret = rzv2m_pwm_enable(rzv2m_pwm);
+
+	return ret;
+}
+
+static const struct pwm_ops rzv2m_pwm_ops = {
+	.get_state = rzv2m_pwm_get_state,
+	.apply = rzv2m_pwm_apply,
+	.owner = THIS_MODULE,
+};
+
+static int rzv2m_pwm_pm_runtime_suspend(struct device *dev)
+{
+	struct rzv2m_pwm_chip *rzv2m_pwm = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(rzv2m_pwm->pwm_clk);
+	clk_disable_unprepare(rzv2m_pwm->apb_clk);
+
+	return 0;
+}
+
+static int rzv2m_pwm_pm_runtime_resume(struct device *dev)
+{
+	struct rzv2m_pwm_chip *rzv2m_pwm = dev_get_drvdata(dev);
+
+	clk_prepare_enable(rzv2m_pwm->apb_clk);
+	clk_prepare_enable(rzv2m_pwm->pwm_clk);
+
+	return 0;
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(rzv2m_pwm_pm_ops,
+				 rzv2m_pwm_pm_runtime_suspend,
+				 rzv2m_pwm_pm_runtime_resume, NULL);
+
+static void rzv2m_pwm_reset_assert_pm_disable(void *data)
+{
+	struct rzv2m_pwm_chip *rzv2m_pwm = data;
+
+	clk_prepare_enable(rzv2m_pwm->apb_clk);
+	clk_prepare_enable(rzv2m_pwm->pwm_clk);
+
+	if (rzv2m_pwm_is_ch_enabled(rzv2m_pwm))
+		pm_runtime_put(rzv2m_pwm->chip.dev);
+
+	clk_disable_unprepare(rzv2m_pwm->pwm_clk);
+	clk_disable_unprepare(rzv2m_pwm->apb_clk);
+
+	pm_runtime_disable(rzv2m_pwm->chip.dev);
+	pm_runtime_set_suspended(rzv2m_pwm->chip.dev);
+	reset_control_assert(rzv2m_pwm->rstc);
+}
+
+static int rzv2m_pwm_probe(struct platform_device *pdev)
+{
+	struct rzv2m_pwm_chip *rzv2m_pwm;
+	unsigned long apb_clk_rate;
+	int ret;
+
+	rzv2m_pwm = devm_kzalloc(&pdev->dev, sizeof(*rzv2m_pwm), GFP_KERNEL);
+	if (!rzv2m_pwm)
+		return -ENOMEM;
+
+	rzv2m_pwm->mmio = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(rzv2m_pwm->mmio))
+		return PTR_ERR(rzv2m_pwm->mmio);
+
+	rzv2m_pwm->apb_clk = devm_clk_get(&pdev->dev, "apb");
+	if (IS_ERR(rzv2m_pwm->apb_clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rzv2m_pwm->apb_clk),
+				     "cannot get apb clock\n");
+
+	apb_clk_rate = clk_get_rate(rzv2m_pwm->apb_clk);
+	if (!apb_clk_rate)
+		return dev_err_probe(&pdev->dev, -EINVAL, "apb clk rate is 0");
+
+	rzv2m_pwm->pwm_clk = devm_clk_get(&pdev->dev, "pwm");
+	if (IS_ERR(rzv2m_pwm->pwm_clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rzv2m_pwm->pwm_clk),
+				     "cannot get pwm clock\n");
+
+	rzv2m_pwm->rate = clk_get_rate(rzv2m_pwm->pwm_clk);
+	if (!rzv2m_pwm->rate)
+		return dev_err_probe(&pdev->dev, -EINVAL, "pwm clk rate is 0");
+
+	/* delay = 6 * PCLK + 9 * PWM_CLK */
+	rzv2m_pwm->delay = F2CYCLE_NSEC(apb_clk_rate) * 6 +
+		F2CYCLE_NSEC(rzv2m_pwm->rate) * 9;
+
+	rzv2m_pwm->rstc = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+	if (IS_ERR(rzv2m_pwm->rstc))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rzv2m_pwm->rstc),
+				     "get reset failed\n");
+
+	platform_set_drvdata(pdev, rzv2m_pwm);
+	clk_prepare_enable(rzv2m_pwm->apb_clk);
+	clk_prepare_enable(rzv2m_pwm->pwm_clk);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	ret = reset_control_deassert(rzv2m_pwm->rstc);
+	if (ret) {
+		dev_err_probe(&pdev->dev, ret,
+			      "cannot deassert reset control\n");
+		goto clk_disable;
+	}
+
+	ret = devm_add_action_or_reset(&pdev->dev,
+				       rzv2m_pwm_reset_assert_pm_disable,
+				       rzv2m_pwm);
+	if (ret < 0)
+		goto clk_disable;
+
+	/*
+	 *  We need to keep the clock on, in case the bootloader has enabled the
+	 *  PWM and is running during probe().
+	 */
+	if (rzv2m_pwm_is_ch_enabled(rzv2m_pwm))
+		pm_runtime_get_sync(&pdev->dev);
+
+	rzv2m_pwm->chip.dev = &pdev->dev;
+	rzv2m_pwm->chip.ops = &rzv2m_pwm_ops;
+	rzv2m_pwm->chip.npwm = 1;
+	ret = devm_pwmchip_add(&pdev->dev, &rzv2m_pwm->chip);
+	if (ret) {
+		dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
+		goto clk_disable;
+	}
+
+	return 0;
+
+clk_disable:
+	clk_disable_unprepare(rzv2m_pwm->pwm_clk);
+	clk_disable_unprepare(rzv2m_pwm->apb_clk);
+	return ret;
+}
+
+static const struct of_device_id rzv2m_pwm_of_table[] = {
+	{ .compatible = "renesas,rzv2m-pwm", },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rzv2m_pwm_of_table);
+
+static struct platform_driver rzv2m_pwm_driver = {
+	.driver = {
+		.name = "pwm-rzv2m",
+		.pm = pm_ptr(&rzv2m_pwm_pm_ops),
+		.of_match_table = of_match_ptr(rzv2m_pwm_of_table),
+	},
+	.probe = rzv2m_pwm_probe,
+};
+module_platform_driver(rzv2m_pwm_driver);
+
+MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
+MODULE_DESCRIPTION("Renesas RZ/V2M PWM Timer Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pwm-rzv2m");
-- 
2.25.1


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

* [PATCH 4/5] arm64: dts: renesas: r9a09g011: Add pwm nodes
  2022-11-18 13:16 [PATCH 0/5] Add RZ/V2{M, MA} driver support Biju Das
                   ` (2 preceding siblings ...)
  2022-11-18 13:16 ` [PATCH 3/5] pwm: Add support for RZ/V2M PWM driver Biju Das
@ 2022-11-18 13:16 ` Biju Das
  2022-11-18 13:16 ` [PATCH 5/5] arm64: dts: renesas: rzv2m evk: Enable pwm Biju Das
  4 siblings, 0 replies; 12+ messages in thread
From: Biju Das @ 2022-11-18 13:16 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 pwm timer channels that are not assigned
to the ISP.

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

diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
index 0373ec409d54..9a4690f8d18f 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
@@ -135,6 +135,97 @@ sys: system-controller@a3f03000 {
 			reg = <0 0xa3f03000 0 0x400>;
 		};
 
+		pwm8: pwm@a4010400 {
+			compatible = "renesas,r9a09g011-pwm",
+				     "renesas,rzv2m-pwm";
+			reg = <0 0xa4010400 0 0x80>;
+			interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPF_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_PWM8_CLK>;
+			clock-names = "apb", "pwm";
+			power-domains = <&cpg>;
+			#pwm-cells = <2>;
+			status = "disabled";
+		};
+
+		pwm9: pwm@a4010480 {
+			compatible = "renesas,r9a09g011-pwm",
+				     "renesas,rzv2m-pwm";
+			reg = <0 0xa4010480 0 0x80>;
+			interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPF_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_PWM9_CLK>;
+			clock-names = "apb", "pwm";
+			power-domains = <&cpg>;
+			#pwm-cells = <2>;
+			status = "disabled";
+		};
+
+		pwm10: pwm@a4010500 {
+			compatible = "renesas,r9a09g011-pwm",
+				     "renesas,rzv2m-pwm";
+			reg = <0 0xa4010500 0 0x80>;
+			interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPF_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_PWM10_CLK>;
+			clock-names = "apb", "pwm";
+			power-domains = <&cpg>;
+			#pwm-cells = <2>;
+			status = "disabled";
+		};
+
+		pwm11: pwm@a4010580 {
+			compatible = "renesas,r9a09g011-pwm",
+				     "renesas,rzv2m-pwm";
+			reg = <0 0xa4010580 0 0x80>;
+			interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPF_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_PWM11_CLK>;
+			clock-names = "apb", "pwm";
+			power-domains = <&cpg>;
+			#pwm-cells = <2>;
+			status = "disabled";
+		};
+
+		pwm12: pwm@a4010600 {
+			compatible = "renesas,r9a09g011-pwm",
+				     "renesas,rzv2m-pwm";
+			reg = <0 0xa4010600 0 0x80>;
+			interrupts = <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPF_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_PWM12_CLK>;
+			clock-names = "apb", "pwm";
+			power-domains = <&cpg>;
+			#pwm-cells = <2>;
+			status = "disabled";
+		};
+
+		pwm13: pwm@a4010680 {
+			compatible = "renesas,r9a09g011-pwm",
+				     "renesas,rzv2m-pwm";
+			reg = <0 0xa4010680 0 0x80>;
+			interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPF_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_PWM13_CLK>;
+			clock-names = "apb", "pwm";
+			power-domains = <&cpg>;
+			#pwm-cells = <2>;
+			status = "disabled";
+		};
+
+		pwm14: pwm@a4010700 {
+			compatible = "renesas,r9a09g011-pwm",
+				     "renesas,rzv2m-pwm";
+			reg = <0 0xa4010700 0 0x80>;
+			interrupts = <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A09G011_CPERI_GRPF_PCLK>,
+				 <&cpg CPG_MOD R9A09G011_PWM14_CLK>;
+			clock-names = "apb", "pwm";
+			power-domains = <&cpg>;
+			#pwm-cells = <2>;
+			status = "disabled";
+		};
+
 		i2c0: i2c@a4030000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
2.25.1


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

* [PATCH 5/5] arm64: dts: renesas: rzv2m evk: Enable pwm
  2022-11-18 13:16 [PATCH 0/5] Add RZ/V2{M, MA} driver support Biju Das
                   ` (3 preceding siblings ...)
  2022-11-18 13:16 ` [PATCH 4/5] arm64: dts: renesas: r9a09g011: Add pwm nodes Biju Das
@ 2022-11-18 13:16 ` Biju Das
  4 siblings, 0 replies; 12+ messages in thread
From: Biju Das @ 2022-11-18 13:16 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski
  Cc: Biju Das, Geert Uytterhoeven, Magnus Damm, linux-renesas-soc,
	devicetree, Fabrizio Castro

Enable pwm{8..14} on RZ/V2M EVK.

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

diff --git a/arch/arm64/boot/dts/renesas/r9a09g011-v2mevk2.dts b/arch/arm64/boot/dts/renesas/r9a09g011-v2mevk2.dts
index 11e1d51c7c0e..73d7481b468e 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g011-v2mevk2.dts
+++ b/arch/arm64/boot/dts/renesas/r9a09g011-v2mevk2.dts
@@ -78,6 +78,76 @@ i2c2_pins: i2c2 {
 		pinmux = <RZV2M_PORT_PINMUX(3, 8, 2)>, /* SDA */
 			 <RZV2M_PORT_PINMUX(3, 9, 2)>; /* SCL */
 	};
+
+	pwm8_pins: pwm8 {
+		pinmux = <RZV2M_PORT_PINMUX(1, 8, 1)>;  /* PM8 */
+	};
+
+	pwm9_pins: pwm9 {
+		pinmux = <RZV2M_PORT_PINMUX(1, 9, 1)>;  /* PM9 */
+	};
+
+	pwm10_pins: pwm10 {
+		pinmux = <RZV2M_PORT_PINMUX(1, 10, 1)>; /* PM10 */
+	};
+
+	pwm11_pins: pwm11 {
+		pinmux = <RZV2M_PORT_PINMUX(1, 11, 1)>; /* PM11 */
+	};
+
+	pwm12_pins: pwm12 {
+		pinmux = <RZV2M_PORT_PINMUX(1, 12, 1)>; /* PM12 */
+	};
+
+	pwm13_pins: pwm13 {
+		pinmux = <RZV2M_PORT_PINMUX(1, 13, 1)>; /* PM13 */
+	};
+
+	pwm14_pins: pwm14 {
+		pinmux = <RZV2M_PORT_PINMUX(1, 14, 1)>; /* PM14 */
+	};
+};
+
+&pwm8 {
+	pinctrl-0 = <&pwm8_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&pwm9 {
+	pinctrl-0 = <&pwm9_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&pwm10 {
+	pinctrl-0 = <&pwm10_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&pwm11 {
+	pinctrl-0 = <&pwm11_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&pwm12 {
+	pinctrl-0 = <&pwm12_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&pwm13 {
+	pinctrl-0 = <&pwm13_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&pwm14 {
+	pinctrl-0 = <&pwm14_pins>;
+	pinctrl-names = "default";
+	status = "okay";
 };
 
 &uart0 {
-- 
2.25.1


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

* Re: [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding
  2022-11-18 13:16 ` [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding Biju Das
@ 2022-11-22 11:46   ` Krzysztof Kozlowski
  2022-11-22 11:53     ` Biju Das
  2022-11-24  8:43   ` Geert Uytterhoeven
  1 sibling, 1 reply; 12+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-22 11:46 UTC (permalink / raw)
  To: Biju Das, Thierry Reding, Rob Herring, Krzysztof Kozlowski
  Cc: Uwe Kleine-König, linux-pwm, devicetree, Geert Uytterhoeven,
	Fabrizio Castro, linux-renesas-soc

On 18/11/2022 14:16, Biju Das wrote:
> Add device tree bindings for the RZ/V2{M, MA} PWM Timer (PWM).
> 
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>

Thank you for your patch. There is something to discuss/improve.

> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - power-domains
> +
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +        enum:
> +          - renesas,r9a09g055-pwm
> +then:
> +  required:
> +    - resets
> +
> +allOf:
> +  - $ref: pwm.yaml#

Put the if under allOf:

allOf:
 - $ref...
 - if:
     then:

This allows easier growth.

With above:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>


Best regards,
Krzysztof


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

* RE: [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding
  2022-11-22 11:46   ` Krzysztof Kozlowski
@ 2022-11-22 11:53     ` Biju Das
  0 siblings, 0 replies; 12+ messages in thread
From: Biju Das @ 2022-11-22 11:53 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Thierry Reding, Rob Herring, Krzysztof Kozlowski
  Cc: Uwe Kleine-König, linux-pwm, devicetree, Geert Uytterhoeven,
	Fabrizio Castro, linux-renesas-soc

Hi Krzysztof Kozlowski,

thanks for the feedback.

> Subject: Re: [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding
> 
> On 18/11/2022 14:16, Biju Das wrote:
> > Add device tree bindings for the RZ/V2{M, MA} PWM Timer (PWM).
> >
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> 
> Thank you for your patch. There is something to discuss/improve.
> 
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +  - clock-names
> > +  - power-domains
> > +
> > +if:
> > +  properties:
> > +    compatible:
> > +      contains:
> > +        enum:
> > +          - renesas,r9a09g055-pwm
> > +then:
> > +  required:
> > +    - resets
> > +
> > +allOf:
> > +  - $ref: pwm.yaml#
> 
> Put the if under allOf:
> 
> allOf:
>  - $ref...
>  - if:
>      then:
> 
> This allows easier growth.

OK will send v2, along with feedback for driver patches if any.

Cheers,
Biju

> 
> With above:
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> 
> 
> Best regards,
> Krzysztof


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

* Re: [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries
  2022-11-18 13:16 ` [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries Biju Das
@ 2022-11-24  8:40   ` Geert Uytterhoeven
  2022-11-24  9:25     ` Biju Das
  0 siblings, 1 reply; 12+ messages in thread
From: Geert Uytterhoeven @ 2022-11-24  8:40 UTC (permalink / raw)
  To: Biju Das
  Cc: Michael Turquette, Stephen Boyd, linux-renesas-soc, linux-clk,
	Fabrizio Castro

Hi Biju,

Thanks for your patch!

On Fri, Nov 18, 2022 at 2:16 PM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> The PWM IP on the RZ/V2M comes with 16 channels, but the ISP has
> full control of channels 0 to 7, and channel 15, therefore Linux
> is only allowed to use channels 8 to 14.
>
> The PWM channel 15 shares apb clock and reset with PWM{8..14}.
> The reset is deasserted by the bootloader/ISP.

Shouldn't you add the reset anyway, but make sure it stays deasserted
by increasing its refcount, cfr. critical clocks?

> Add PWM{8..14} clocks to CPG driver and mark apb clock as
> critical clock, so that the apb clock will be always on.
>
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>

> --- a/drivers/clk/renesas/r9a09g011-cpg.c
> +++ b/drivers/clk/renesas/r9a09g011-cpg.c
> @@ -136,6 +136,14 @@ static const struct rzg2l_mod_clk r9a09g011_mod_clks[] __initconst = {
>         DEF_MOD("iic_pclk1",    R9A09G011_IIC_PCLK1,     CLK_SEL_E,    0x424, 12),
>         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("pwm8_15_pclk", R9A09G011_CPERI_GRPF_PCLK, CLK_SEL_E,  0x434, 0),

"cperi_grpf"?

> +       DEF_MOD("pwm8_clk",     R9A09G011_PWM8_CLK,      CLK_MAIN,     0x434, 4),
> +       DEF_MOD("pwm9_clk",     R9A09G011_PWM9_CLK,      CLK_MAIN,     0x434, 5),
> +       DEF_MOD("pwm10_clk",    R9A09G011_PWM10_CLK,     CLK_MAIN,     0x434, 6),
> +       DEF_MOD("pwm11_clk",    R9A09G011_PWM11_CLK,     CLK_MAIN,     0x434, 7),
> +       DEF_MOD("pwm12_clk",    R9A09G011_PWM12_CLK,     CLK_MAIN,     0x434, 8),
> +       DEF_MOD("pwm13_clk",    R9A09G011_PWM13_CLK,     CLK_MAIN,     0x434, 9),
> +       DEF_MOD("pwm14_clk",    R9A09G011_PWM14_CLK,     CLK_MAIN,     0x434, 10),
>         DEF_MOD("urt_pclk",     R9A09G011_URT_PCLK,      CLK_SEL_E,    0x438, 4),
>         DEF_MOD("urt0_clk",     R9A09G011_URT0_CLK,      CLK_SEL_W0,   0x438, 5),
>         DEF_MOD("ca53",         R9A09G011_CA53_CLK,      CLK_DIV_A,    0x448, 0),

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] 12+ messages in thread

* Re: [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding
  2022-11-18 13:16 ` [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding Biju Das
  2022-11-22 11:46   ` Krzysztof Kozlowski
@ 2022-11-24  8:43   ` Geert Uytterhoeven
  2022-11-24  9:45     ` Biju Das
  1 sibling, 1 reply; 12+ messages in thread
From: Geert Uytterhoeven @ 2022-11-24  8:43 UTC (permalink / raw)
  To: Biju Das
  Cc: Thierry Reding, Rob Herring, Krzysztof Kozlowski,
	Uwe Kleine-König, linux-pwm, devicetree, Fabrizio Castro,
	linux-renesas-soc

Hi Biju,

On Fri, Nov 18, 2022 at 2:16 PM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> Add device tree bindings for the RZ/V2{M, MA} PWM Timer (PWM).
>
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>

Thanks for your patch!

> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/renesas,rzv2m-pwm.yaml
> @@ -0,0 +1,98 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pwm/renesas,rzv2m-pwm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Renesas RZ/V2{M, MA} PWM Timer (PWM)
> +
> +maintainers:
> +  - Biju Das <biju.das.jz@bp.renesas.com>
> +
> +description: |
> +  The RZ/V2{M, MA} PWM Timer (PWM) composed of 16 channels. It supports the
> +  following functions
> +  * The PWM has 24-bit counters which operate at PWM_CLK (48 MHz).
> +  * The frequency division ratio for internal counter operation is selectable
> +    as PWM_CLK divided by 1, 16, 256, or 2048.
> +  * The period as well as the duty cycle is adjustable.
> +  * The low-level and high-level order of the PWM signals can be inverted.
> +  * The duty cycle of the PWM signal is selectable in the range from 0 to 100%.
> +  * The minimum resolution is 20.83 ns.
> +  * Three interrupt sources: Rising and falling edges of the PWM signal and
> +    clearing of the counter
> +  * Counter operation and the bus interface are asynchronous and both can
> +    operate independently of the magnitude relationship of the respective
> +    clock periods.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - renesas,r9a09g011-pwm  # RZ/V2M
> +          - renesas,r9a09g055-pwm  # RZ/V2MA
> +      - const: renesas,rzv2m-pwm
> +
> +  reg:
> +    maxItems: 1
> +
> +  '#pwm-cells':
> +    const: 2
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: CPU Peripheral Group F APB clock

"APB clock"

PWM0-7] are part of Peripheral Group E, and the block might be
reused on SoCs not using CPU Peripheral Group clock signals.

> +      - description: PWM clock
> +
> +  clock-names:
> +    items:
> +      - const: apb
> +      - const: pwm
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - power-domains
> +
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +        enum:
> +          - renesas,r9a09g055-pwm
> +then:
> +  required:
> +    - resets

I think you should make the resets property required unconditionally.
DT describes hardware, not software policy.

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] 12+ messages in thread

* RE: [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries
  2022-11-24  8:40   ` Geert Uytterhoeven
@ 2022-11-24  9:25     ` Biju Das
  0 siblings, 0 replies; 12+ messages in thread
From: Biju Das @ 2022-11-24  9:25 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Michael Turquette, Stephen Boyd, linux-renesas-soc, linux-clk,
	Fabrizio Castro

Hi Geert,

Thanks for the feedback.

> Subject: Re: [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries
> 
> Hi Biju,
> 
> Thanks for your patch!
> 
> On Fri, Nov 18, 2022 at 2:16 PM Biju Das <biju.das.jz@bp.renesas.com>
> wrote:
> > The PWM IP on the RZ/V2M comes with 16 channels, but the ISP has full
> > control of channels 0 to 7, and channel 15, therefore Linux is only
> > allowed to use channels 8 to 14.
> >
> > The PWM channel 15 shares apb clock and reset with PWM{8..14}.
> > The reset is deasserted by the bootloader/ISP.
> 
> Shouldn't you add the reset anyway, but make sure it stays deasserted by
> increasing its refcount, cfr. critical clocks?

I just confused, deasserting will give some glitch on ISP,

TYPE-A: A type which does not require clock supply at the time of a reset.
TYPE-B: A type which requires clock supply at the time of a reset.

Figure 48.6-27 TYPE-B Reset Timing by the CPG Register
And Figure 48.6-28 TYPE-B Reset Timing by the Reset Source

But that diagram follows a reset followed by deassert.

Yes, you are correct deassert won't create any glitches. But reset followed by
deassert may create clock glitch, this will be done by either ISP or bootloader.

Current assumption is handling of shared resource will be handled by bootloader or ISP.

Linux Just increment the refcount.

OK, I will send V2 with this change.

Cheers,
Biju


> 
> > Add PWM{8..14} clocks to CPG driver and mark apb clock as critical
> > clock, so that the apb clock will be always on.
> >
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> 
> > --- a/drivers/clk/renesas/r9a09g011-cpg.c
> > +++ b/drivers/clk/renesas/r9a09g011-cpg.c
> > @@ -136,6 +136,14 @@ static const struct rzg2l_mod_clk
> r9a09g011_mod_clks[] __initconst = {
> >         DEF_MOD("iic_pclk1",    R9A09G011_IIC_PCLK1,     CLK_SEL_E,
> 0x424, 12),
> >         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("pwm8_15_pclk", R9A09G011_CPERI_GRPF_PCLK, CLK_SEL_E,
> > + 0x434, 0),
> 
> "cperi_grpf"?
> 
> > +       DEF_MOD("pwm8_clk",     R9A09G011_PWM8_CLK,      CLK_MAIN,
> 0x434, 4),
> > +       DEF_MOD("pwm9_clk",     R9A09G011_PWM9_CLK,      CLK_MAIN,
> 0x434, 5),
> > +       DEF_MOD("pwm10_clk",    R9A09G011_PWM10_CLK,     CLK_MAIN,
> 0x434, 6),
> > +       DEF_MOD("pwm11_clk",    R9A09G011_PWM11_CLK,     CLK_MAIN,
> 0x434, 7),
> > +       DEF_MOD("pwm12_clk",    R9A09G011_PWM12_CLK,     CLK_MAIN,
> 0x434, 8),
> > +       DEF_MOD("pwm13_clk",    R9A09G011_PWM13_CLK,     CLK_MAIN,
> 0x434, 9),
> > +       DEF_MOD("pwm14_clk",    R9A09G011_PWM14_CLK,     CLK_MAIN,
> 0x434, 10),
> >         DEF_MOD("urt_pclk",     R9A09G011_URT_PCLK,      CLK_SEL_E,
> 0x438, 4),
> >         DEF_MOD("urt0_clk",     R9A09G011_URT0_CLK,      CLK_SEL_W0,
> 0x438, 5),
> >         DEF_MOD("ca53",         R9A09G011_CA53_CLK,      CLK_DIV_A,
> 0x448, 0),
> 
> 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] 12+ messages in thread

* RE: [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding
  2022-11-24  8:43   ` Geert Uytterhoeven
@ 2022-11-24  9:45     ` Biju Das
  0 siblings, 0 replies; 12+ messages in thread
From: Biju Das @ 2022-11-24  9:45 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Thierry Reding, Rob Herring, Krzysztof Kozlowski,
	Uwe Kleine-König, linux-pwm, devicetree, Fabrizio Castro,
	linux-renesas-soc

Hi Geert,

Thanks for the feedback.

> Subject: Re: [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding
> 
> Hi Biju,
> 
> On Fri, Nov 18, 2022 at 2:16 PM Biju Das <biju.das.jz@bp.renesas.com>
> wrote:
> > Add device tree bindings for the RZ/V2{M, MA} PWM Timer (PWM).
> >
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> 
> Thanks for your patch!
> 
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pwm/renesas,rzv2m-pwm.yaml
> > @@ -0,0 +1,98 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> > +
> > +title: Renesas RZ/V2{M, MA} PWM Timer (PWM)
> > +
> > +maintainers:
> > +  - Biju Das <biju.das.jz@bp.renesas.com>
> > +
> > +description: |
> > +  The RZ/V2{M, MA} PWM Timer (PWM) composed of 16 channels. It
> > +supports the
> > +  following functions
> > +  * The PWM has 24-bit counters which operate at PWM_CLK (48 MHz).
> > +  * The frequency division ratio for internal counter operation is
> selectable
> > +    as PWM_CLK divided by 1, 16, 256, or 2048.
> > +  * The period as well as the duty cycle is adjustable.
> > +  * The low-level and high-level order of the PWM signals can be
> inverted.
> > +  * The duty cycle of the PWM signal is selectable in the range from
> 0 to 100%.
> > +  * The minimum resolution is 20.83 ns.
> > +  * Three interrupt sources: Rising and falling edges of the PWM
> signal and
> > +    clearing of the counter
> > +  * Counter operation and the bus interface are asynchronous and both
> can
> > +    operate independently of the magnitude relationship of the
> respective
> > +    clock periods.
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - enum:
> > +          - renesas,r9a09g011-pwm  # RZ/V2M
> > +          - renesas,r9a09g055-pwm  # RZ/V2MA
> > +      - const: renesas,rzv2m-pwm
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  '#pwm-cells':
> > +    const: 2
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: CPU Peripheral Group F APB clock
> 
> "APB clock"
Agreed.

> 
> PWM0-7] are part of Peripheral Group E, and the block might be reused on
> SoCs not using CPU Peripheral Group clock signals.
> 
> > +      - description: PWM clock
> > +
> > +  clock-names:
> > +    items:
> > +      - const: apb
> > +      - const: pwm
> > +
> > +  power-domains:
> > +    maxItems: 1
> > +
> > +  resets:
> > +    maxItems: 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +  - clock-names
> > +  - power-domains
> > +
> > +if:
> > +  properties:
> > +    compatible:
> > +      contains:
> > +        enum:
> > +          - renesas,r9a09g055-pwm
> > +then:
> > +  required:
> > +    - resets
> 
> I think you should make the resets property required unconditionally.
> DT describes hardware, not software policy.

OK will send V2 with these changes.

Cheers,
Biju

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

end of thread, other threads:[~2022-11-24  9:46 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-18 13:16 [PATCH 0/5] Add RZ/V2{M, MA} driver support Biju Das
2022-11-18 13:16 ` [PATCH 1/5] clk: renesas: r9a09g011: Add PWM clock entries Biju Das
2022-11-24  8:40   ` Geert Uytterhoeven
2022-11-24  9:25     ` Biju Das
2022-11-18 13:16 ` [PATCH 2/5] dt-bindings: pwm: Add RZ/V2M PWM binding Biju Das
2022-11-22 11:46   ` Krzysztof Kozlowski
2022-11-22 11:53     ` Biju Das
2022-11-24  8:43   ` Geert Uytterhoeven
2022-11-24  9:45     ` Biju Das
2022-11-18 13:16 ` [PATCH 3/5] pwm: Add support for RZ/V2M PWM driver Biju Das
2022-11-18 13:16 ` [PATCH 4/5] arm64: dts: renesas: r9a09g011: Add pwm nodes Biju Das
2022-11-18 13:16 ` [PATCH 5/5] arm64: dts: renesas: rzv2m evk: Enable pwm Biju Das

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).