[PATCH] clk: renesas: rzg2l: Drop DMA driver dependency for system boot

Biju posted 1 patch 1 week, 2 days ago
drivers/clk/renesas/rzg2l-cpg.c | 35 ++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
[PATCH] clk: renesas: rzg2l: Drop DMA driver dependency for system boot
Posted by Biju 1 week, 2 days ago
From: Biju Das <biju.das.jz@bp.renesas.com>

As per section 4.6.1.7.1 of the RZ/G3L hardware manual "Precaution when
use the peripheral modules which can initiate DMA Controller", it is
stated that it needs the below register settings even if DMA controller
is not used:
 - Set CPG_CLKON_DMAC_REG register to supply a clock for DMA Controller.
 - Set CPG_RST_DMAC register to release a reset for DMA Controller.

Currently, the serial IRQ is not routed to the CPU if the DMA ACLK is off,
or if DMA resets being in the asserted state result in not getting serial
IRQs for the console. Fix the issue by explicitly deasserting the DMA
resets during probe, and since the DMA clk is a critical clock, it will be
turned on forever. This will allow booting system without DMA driver.

RZ/G2L SoC loses power during s2ram. Explicitly turn on clk/deassert
resets to get the console during wakeup.

The DMA driver is used by both RZ/G2L and RZ/V2H family SoCs. The latter
does not have any issue related to serial IRQ routing. The reset assert
in DMA driver will impact wakeup using serial IRQ on RZ/G2L SoCs. The
cpg_suspend() is suspend-no-irq which suspends later than DMA driver. So,
deassert thereset in cpg_suspend() for making available the serial IRQ
as a wakeup source for s2idle.

With these changes, the RZ/G2L-based systems:
 1) can boot without the DMA driver
 2) get serial IRQ available as wakeup source for s2idle
 3) get serial console prompt during wakeup of s2ram.
 4) has no dependency on bootloaders for turning on DMA clks/releasing
    the resets.

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

diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index f4deb5d3b837..16771a0101bd 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -86,6 +86,12 @@
 #define PLL5_HSCLK_MIN		10000000
 #define PLL5_HSCLK_MAX		187500000
 
+/* Critical clk/resets to route serial IRQ to CPU by default */
+#define CPG_CLKON_DMAC_REG	0x52c
+#define CPG_RST_DMAC		0x82c
+#define CPG_CLKON_DMAC_REG_ACLK_ON	((BIT(0) << 16) | BIT(0))
+#define CPG_RST_DMAC_DEASSERTED_ALL	((GENMASK(1, 0) << 16) | GENMASK(1, 0))
+
 /**
  * struct clk_hw_data - clock hardware data
  * @hw: clock hw
@@ -2051,21 +2057,48 @@ static int __init rzg2l_cpg_probe(struct platform_device *pdev)
 	if (error)
 		return error;
 
+	/*
+	 * Deassert DMA resets to route the serial IRQ to CPU for serial
+	 * console during boot. DMA clk is critical clk and it will be
+	 * turned on forever.
+	 */
+	writel(CPG_RST_DMAC_DEASSERTED_ALL, priv->base + CPG_RST_DMAC);
+
 	debugfs_create_file("mstop", 0444, NULL, priv, &rzg2l_mod_clock_mstop_fops);
 	return 0;
 }
 
+static int rzg2l_cpg_suspend(struct device *dev)
+{
+	struct rzg2l_cpg_priv *priv = dev_get_drvdata(dev);
+
+	/*
+	 * Deassert DMA resets to route the serial IRQ to CPU for making
+	 * serial IRQ available as wakeup source for s2idle.
+	 */
+	writel(CPG_RST_DMAC_DEASSERTED_ALL, priv->base + CPG_RST_DMAC);
+	return 0;
+}
+
 static int rzg2l_cpg_resume(struct device *dev)
 {
 	struct rzg2l_cpg_priv *priv = dev_get_drvdata(dev);
 
 	rzg2l_mod_clock_init_mstop(priv);
 
+	/*
+	 * Deassert DMA resets and enable clk to route serial IRQ to CPU for
+	 * serial console during wakeup from s2ram as the SoC is in DDR
+	 * retention mode.
+	 */
+	writel(CPG_CLKON_DMAC_REG_ACLK_ON, priv->base + CPG_CLKON_DMAC_REG);
+	writel(CPG_RST_DMAC_DEASSERTED_ALL, priv->base + CPG_RST_DMAC);
+
 	return 0;
 }
 
 static const struct dev_pm_ops rzg2l_cpg_pm_ops = {
-	NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, rzg2l_cpg_resume)
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg2l_cpg_suspend, rzg2l_cpg_resume)
 };
 
 static const struct of_device_id rzg2l_cpg_match[] = {
-- 
2.43.0

Re: [PATCH] clk: renesas: rzg2l: Drop DMA driver dependency for system boot
Posted by Claudiu Beznea 4 days, 7 hours ago
Hi, Biju,

On 1/30/26 16:34, Biju wrote:
> From: Biju Das <biju.das.jz@bp.renesas.com>
> 
> As per section 4.6.1.7.1 of the RZ/G3L hardware manual "Precaution when
> use the peripheral modules which can initiate DMA Controller", it is
> stated that it needs the below register settings even if DMA controller
> is not used:
>   - Set CPG_CLKON_DMAC_REG register to supply a clock for DMA Controller.
>   - Set CPG_RST_DMAC register to release a reset for DMA Controller.
> 
> Currently, the serial IRQ is not routed to the CPU if the DMA ACLK is off,
> or if DMA resets being in the asserted state result in not getting serial
> IRQs for the console. Fix the issue by explicitly deasserting the DMA
> resets during probe, and since the DMA clk is a critical clock, it will be
> turned on forever. This will allow booting system without DMA driver.
> 
> RZ/G2L SoC loses power during s2ram. Explicitly turn on clk/deassert
> resets to get the console during wakeup.
> 
> The DMA driver is used by both RZ/G2L and RZ/V2H family SoCs. The latter
> does not have any issue related to serial IRQ routing. The reset assert
> in DMA driver will impact wakeup using serial IRQ on RZ/G2L SoCs. The
> cpg_suspend() is suspend-no-irq which suspends later than DMA driver. So,
> deassert thereset in cpg_suspend() for making available the serial IRQ
> as a wakeup source for s2idle.
> 
> With these changes, the RZ/G2L-based systems:
>   1) can boot without the DMA driver
>   2) get serial IRQ available as wakeup source for s2idle
>   3) get serial console prompt during wakeup of s2ram.
>   4) has no dependency on bootloaders for turning on DMA clks/releasing
>      the resets.
> 
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> ---
>   drivers/clk/renesas/rzg2l-cpg.c | 35 ++++++++++++++++++++++++++++++++-
>   1 file changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
> index f4deb5d3b837..16771a0101bd 100644
> --- a/drivers/clk/renesas/rzg2l-cpg.c
> +++ b/drivers/clk/renesas/rzg2l-cpg.c
> @@ -86,6 +86,12 @@
>   #define PLL5_HSCLK_MIN		10000000
>   #define PLL5_HSCLK_MAX		187500000
>   
> +/* Critical clk/resets to route serial IRQ to CPU by default */
> +#define CPG_CLKON_DMAC_REG	0x52c
> +#define CPG_RST_DMAC		0x82c
> +#define CPG_CLKON_DMAC_REG_ACLK_ON	((BIT(0) << 16) | BIT(0))
> +#define CPG_RST_DMAC_DEASSERTED_ALL	((GENMASK(1, 0) << 16) | GENMASK(1, 0))
> +
>   /**
>    * struct clk_hw_data - clock hardware data
>    * @hw: clock hw
> @@ -2051,21 +2057,48 @@ static int __init rzg2l_cpg_probe(struct platform_device *pdev)
>   	if (error)
>   		return error;
>   
> +	/*
> +	 * Deassert DMA resets to route the serial IRQ to CPU for serial
> +	 * console during boot. DMA clk is critical clk and it will be
> +	 * turned on forever.
> +	 */
> +	writel(CPG_RST_DMAC_DEASSERTED_ALL, priv->base + CPG_RST_DMAC);
> +
>   	debugfs_create_file("mstop", 0444, NULL, priv, &rzg2l_mod_clock_mstop_fops);
>   	return 0;
>   }
>   
> +static int rzg2l_cpg_suspend(struct device *dev)
> +{
> +	struct rzg2l_cpg_priv *priv = dev_get_drvdata(dev);
> +
> +	/*
> +	 * Deassert DMA resets to route the serial IRQ to CPU for making
> +	 * serial IRQ available as wakeup source for s2idle.
> +	 */
> +	writel(CPG_RST_DMAC_DEASSERTED_ALL, priv->base + CPG_RST_DMAC);

Instead of this, you can mark these resets as critical from the SoC specific 
drivers and based on that, don't ever assert them in __rzg2l_cpg_assert(), to 
avoid any potential window when this can be asserted by the user and then 
de-asserted back here.

> +	return 0;
> +}
> +
>   static int rzg2l_cpg_resume(struct device *dev)
>   {
>   	struct rzg2l_cpg_priv *priv = dev_get_drvdata(dev);
>   
>   	rzg2l_mod_clock_init_mstop(priv);
>   
> +	/*
> +	 * Deassert DMA resets and enable clk to route serial IRQ to CPU for
> +	 * serial console during wakeup from s2ram as the SoC is in DDR
> +	 * retention mode.
> +	 */
> +	writel(CPG_CLKON_DMAC_REG_ACLK_ON, priv->base + CPG_CLKON_DMAC_REG);

This need to be set before MSTOP to follow the MSTOP and clock configuration 
sequence described in the HW manual (section 42.2.2. in RZ/G2L HW manual, rev.1.30).

Thank you,
Claudiu