From d42d57fe86e98c2ab438e30c247d90504a146646 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Tue, 15 Jun 2021 17:39:29 +0800 Subject: clk: renesas: rzg2l: Remove unneeded semicolon Eliminate the following coccicheck warning: ./drivers/clk/renesas/renesas-rzg2l-cpg.c:299:2-3: Unneeded semicolon Reported-by: Abaci Robot Signed-off-by: Yang Li Link: https://lore.kernel.org/r/1623749970-38020-1-git-send-email-yang.lee@linux.alibaba.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index e7c59af2a1d8..a0bb8b20797d 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -297,7 +297,7 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, break; default: goto fail; - }; + } if (IS_ERR_OR_NULL(clk)) goto fail; -- cgit v1.3-14-g43fede From 97c29755598f98c6c91f68f12bdd3f517e457890 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Thu, 17 Jun 2021 10:22:03 +0800 Subject: clk: renesas: rzg2l: Fix return value and unused assignment Currently the function returns NULL on error, so exact error code is lost. This patch changes return convention of the function to use ERR_PTR() on error instead. Reported-by: Abaci Robot Signed-off-by: Yang Li Link: https://lore.kernel.org/r/1623896524-102058-1-git-send-email-yang.lee@linux.alibaba.com [geert: Drop curly braces] Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index a0bb8b20797d..0ce84a24198c 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -182,10 +182,8 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, return ERR_CAST(parent); pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); - if (!pll_clk) { - clk = ERR_PTR(-ENOMEM); - return NULL; - } + if (!pll_clk) + return ERR_PTR(-ENOMEM); parent_name = __clk_get_name(parent); init.name = core->name; -- cgit v1.3-14-g43fede From 36aaa3a0d9bc13e302dc146a20f022fb6891b605 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 17 Jun 2021 17:14:11 +0300 Subject: clk: renesas: rzg2l: Fix a double free on error The "pll_clk" and "clock" pointers are allocated with devm_kzalloc() so freeing them with kfree() will lead to a double free. This would only happen if probe failed, and the system is not bootable. Fixes: ef3c613ccd68 ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC") Signed-off-by: Dan Carpenter Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/YMtYs7LVveYH4eRe@mwanda Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index 0ce84a24198c..6808390f8ee0 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -175,7 +175,6 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, struct clk_init_data init; const char *parent_name; struct pll_clk *pll_clk; - struct clk *clk; parent = clks[core->parent & 0xffff]; if (IS_ERR(parent)) @@ -198,11 +197,7 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, pll_clk->priv = priv; pll_clk->type = core->type; - clk = clk_register(NULL, &pll_clk->hw); - if (IS_ERR(clk)) - kfree(pll_clk); - - return clk; + return clk_register(NULL, &pll_clk->hw); } static struct clk @@ -471,7 +466,6 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, fail: dev_err(dev, "Failed to register %s clock %s: %ld\n", "module", mod->name, PTR_ERR(clk)); - kfree(clock); } #define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) -- cgit v1.3-14-g43fede From e37868f14416bc5f22235dce073c496381d349c3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 17 Jun 2021 17:15:10 +0300 Subject: clk: renesas: rzg2l: Avoid mixing error pointers and NULL These functions accidentally return both error pointers and NULL when there is an error. It doesn't cause a problem but it is confusing and seems unintentional. Signed-off-by: Dan Carpenter Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/YMtY7nOtqEvTokh7@mwanda Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index 6808390f8ee0..34e90ee46290 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -125,7 +125,7 @@ rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, core->flag, &priv->rmw_lock); if (IS_ERR(clk_hw)) - return NULL; + return ERR_CAST(clk_hw); return clk_hw->clk; } -- cgit v1.3-14-g43fede From 1606e81543f80fc3b1912957cf6d8fa62e40b8e5 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 17 Jun 2021 16:54:32 +0100 Subject: clk: renesas: rzg2l: Fix off-by-one check in rzg2l_cpg_clk_src_twocell_get() Fix clock index out of range check for module clocks in rzg2l_cpg_clk_src_twocell_get(). Fixes: ef3c613ccd68 ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC") Reported-by: Dan Carpenter Signed-off-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210617155432.18827-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index 34e90ee46290..9addc9dae31a 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -222,7 +222,7 @@ static struct clk case CPG_MOD: type = "module"; - if (clkidx > priv->num_mod_clks) { + if (clkidx >= priv->num_mod_clks) { dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); return ERR_PTR(-EINVAL); -- cgit v1.3-14-g43fede From d23fcff14568d5a5e025b9c1185531caccd605db Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 18 Jun 2021 13:46:21 +0200 Subject: clk: renesas: rzg2: Rename i2c-dvfs to iic-pmic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As RZ/G2 SoCs do not support DVFS, the "iic-dvfs" module was renamed to "iic-pmic" in the RZ/G Series, 2nd Generation User’s Manual: Hardware Rev. 1.00. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/3e549b41989ff2797b998a1c749c9f607845f44a.1624016693.git.geert+renesas@glider.be --- drivers/clk/renesas/r8a774a1-cpg-mssr.c | 2 +- drivers/clk/renesas/r8a774b1-cpg-mssr.c | 2 +- drivers/clk/renesas/r8a774c0-cpg-mssr.c | 2 +- drivers/clk/renesas/r8a774e1-cpg-mssr.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c index 4a43ebec7d5e..39b185d8e957 100644 --- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c @@ -210,7 +210,7 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = { DEF_MOD("rpc-if", 917, R8A774A1_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6), DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6), - DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP), + DEF_MOD("iic-pmic", 926, R8A774A1_CLK_CP), DEF_MOD("i2c4", 927, R8A774A1_CLK_S0D6), DEF_MOD("i2c3", 928, R8A774A1_CLK_S0D6), DEF_MOD("i2c2", 929, R8A774A1_CLK_S3D2), diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c index 6f04c40fe237..af602d83c8ce 100644 --- a/drivers/clk/renesas/r8a774b1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c @@ -206,7 +206,7 @@ static const struct mssr_mod_clk r8a774b1_mod_clks[] __initconst = { DEF_MOD("rpc-if", 917, R8A774B1_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A774B1_CLK_S0D6), DEF_MOD("i2c5", 919, R8A774B1_CLK_S0D6), - DEF_MOD("i2c-dvfs", 926, R8A774B1_CLK_CP), + DEF_MOD("iic-pmic", 926, R8A774B1_CLK_CP), DEF_MOD("i2c4", 927, R8A774B1_CLK_S0D6), DEF_MOD("i2c3", 928, R8A774B1_CLK_S0D6), DEF_MOD("i2c2", 929, R8A774B1_CLK_S3D2), diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c index ed3a2cf0e0bb..5b938eb2df25 100644 --- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c @@ -210,7 +210,7 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = { DEF_MOD("rpc-if", 917, R8A774C0_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2), DEF_MOD("i2c5", 919, R8A774C0_CLK_S3D2), - DEF_MOD("i2c-dvfs", 926, R8A774C0_CLK_CP), + DEF_MOD("iic-pmic", 926, R8A774C0_CLK_CP), DEF_MOD("i2c4", 927, R8A774C0_CLK_S3D2), DEF_MOD("i2c3", 928, R8A774C0_CLK_S3D2), DEF_MOD("i2c2", 929, R8A774C0_CLK_S3D2), diff --git a/drivers/clk/renesas/r8a774e1-cpg-mssr.c b/drivers/clk/renesas/r8a774e1-cpg-mssr.c index b96c486abb44..40c71466df37 100644 --- a/drivers/clk/renesas/r8a774e1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774e1-cpg-mssr.c @@ -219,7 +219,7 @@ static const struct mssr_mod_clk r8a774e1_mod_clks[] __initconst = { DEF_MOD("i2c6", 918, R8A774E1_CLK_S0D6), DEF_MOD("i2c5", 919, R8A774E1_CLK_S0D6), DEF_MOD("adg", 922, R8A774E1_CLK_S0D1), - DEF_MOD("i2c-dvfs", 926, R8A774E1_CLK_CP), + DEF_MOD("iic-pmic", 926, R8A774E1_CLK_CP), DEF_MOD("i2c4", 927, R8A774E1_CLK_S0D6), DEF_MOD("i2c3", 928, R8A774E1_CLK_S0D6), DEF_MOD("i2c2", 929, R8A774E1_CLK_S3D2), -- cgit v1.3-14-g43fede From 417ed58dfc5ed6c2ec608d5ee93dd27197190e19 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Wed, 23 Jun 2021 00:27:10 +0100 Subject: clk: renesas: r8a779a0: Add the DU clock The DU clock is added to the S3D1 clock parent. The Renesas BSP lists S2D1 as the clock parent, however there is no S2 clock on this platform. S3D1 is chosen as a best effort guess and demonstrates functionality but is not guaranteed to be correct. Signed-off-by: Kieran Bingham Link: https://lore.kernel.org/r/20210622232711.3219697-2-kieran.bingham@ideasonboard.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a779a0-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index acaf5a93f1d3..a1bd158defb5 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -167,6 +167,7 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("csi41", 400, R8A779A0_CLK_CSI0), DEF_MOD("csi42", 401, R8A779A0_CLK_CSI0), DEF_MOD("csi43", 402, R8A779A0_CLK_CSI0), + DEF_MOD("du", 411, R8A779A0_CLK_S3D1), DEF_MOD("fcpvd0", 508, R8A779A0_CLK_S3D1), DEF_MOD("fcpvd1", 509, R8A779A0_CLK_S3D1), DEF_MOD("hscif0", 514, R8A779A0_CLK_S1D2), -- cgit v1.3-14-g43fede From c346ff5ccc8e87f69a520073f876b740431a5acf Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Wed, 23 Jun 2021 00:27:11 +0100 Subject: clk: renesas: r8a779a0: Add the DSI clocks The DSI clock is incorrectly defined as a fixed clock. This demonstrates itself as the dsi-encoders failing to correctly enable and start their PPI and HS clocks internally, and causes failures. Move the DSI parent clock to match the updates in the BSP, which resolves the initialisation procedures. Signed-off-by: Kieran Bingham Fixes: 17bcc8035d2d19fc ("clk: renesas: cpg-mssr: Add support for R-Car V3U") Link: https://lore.kernel.org/r/20210622232711.3219697-3-kieran.bingham@ideasonboard.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a779a0-cpg-mssr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index a1bd158defb5..f16d125ca009 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -135,7 +135,6 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_FIXED("zt", R8A779A0_CLK_ZT, CLK_PLL1_DIV2, 2, 1), DEF_FIXED("ztr", R8A779A0_CLK_ZTR, CLK_PLL1_DIV2, 2, 1), DEF_FIXED("zr", R8A779A0_CLK_ZR, CLK_PLL1_DIV2, 1, 1), - DEF_FIXED("dsi", R8A779A0_CLK_DSI, CLK_PLL5_DIV4, 1, 1), DEF_FIXED("cnndsp", R8A779A0_CLK_CNNDSP, CLK_PLL5_DIV4, 1, 1), DEF_FIXED("vip", R8A779A0_CLK_VIP, CLK_PLL5, 5, 1), DEF_FIXED("adgh", R8A779A0_CLK_ADGH, CLK_PLL5_DIV4, 1, 1), @@ -151,6 +150,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_DIV6P1("mso", R8A779A0_CLK_MSO, CLK_PLL5_DIV4, 0x87c), DEF_DIV6P1("canfd", R8A779A0_CLK_CANFD, CLK_PLL5_DIV4, 0x878), DEF_DIV6P1("csi0", R8A779A0_CLK_CSI0, CLK_PLL5_DIV4, 0x880), + DEF_DIV6P1("dsi", R8A779A0_CLK_DSI, CLK_PLL5_DIV4, 0x884), DEF_OSC("osc", R8A779A0_CLK_OSC, CLK_EXTAL, 8), DEF_MDSEL("r", R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1), @@ -168,6 +168,8 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("csi42", 401, R8A779A0_CLK_CSI0), DEF_MOD("csi43", 402, R8A779A0_CLK_CSI0), DEF_MOD("du", 411, R8A779A0_CLK_S3D1), + DEF_MOD("dsi0", 415, R8A779A0_CLK_DSI), + DEF_MOD("dsi1", 416, R8A779A0_CLK_DSI), DEF_MOD("fcpvd0", 508, R8A779A0_CLK_S3D1), DEF_MOD("fcpvd1", 509, R8A779A0_CLK_S3D1), DEF_MOD("hscif0", 514, R8A779A0_CLK_S1D2), -- cgit v1.3-14-g43fede From 1962dd36db4ffe0411e3cb06f0797b7aacf0ca99 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sat, 26 Jun 2021 09:13:42 +0100 Subject: clk: renesas: r9a07g044: Add I2C clocks/resets Add I2C{0,1,2,3} clock and reset entries. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210626081344.5783-9-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index ae24e0397d3c..b39a36b317fd 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -90,6 +90,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x518, 0), DEF_MOD("ia55_clk", R9A07G044_IA55_CLK, R9A07G044_CLK_P1, 0x518, 1), + DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0, + 0x580, 0), + DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0, + 0x580, 1), + DEF_MOD("i2c2", R9A07G044_I2C2_PCLK, R9A07G044_CLK_P0, + 0x580, 2), + DEF_MOD("i2c3", R9A07G044_I2C3_PCLK, R9A07G044_CLK_P0, + 0x580, 3), DEF_MOD("scif0", R9A07G044_SCIF0_CLK_PCK, R9A07G044_CLK_P0, 0x584, 0), DEF_MOD("scif1", R9A07G044_SCIF1_CLK_PCK, R9A07G044_CLK_P0, @@ -108,6 +116,10 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_GIC600_GICRESET_N, 0x814, 0), DEF_RST(R9A07G044_GIC600_DBG_GICRESET_N, 0x814, 1), DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), + DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0), + DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1), + DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2), + DEF_RST(R9A07G044_I2C3_MRST, 0x880, 3), DEF_RST(R9A07G044_SCIF0_RST_SYSTEM_N, 0x884, 0), DEF_RST(R9A07G044_SCIF1_RST_SYSTEM_N, 0x884, 1), DEF_RST(R9A07G044_SCIF2_RST_SYSTEM_N, 0x884, 2), -- cgit v1.3-14-g43fede From eb829e549ba65e48b1c16ddecb892a32b366d5e4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sat, 26 Jun 2021 09:13:43 +0100 Subject: clk: renesas: r9a07g044: Add DMAC clocks/resets Add DMAC clock and reset entries in CPG driver. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210626081344.5783-10-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index b39a36b317fd..5d81e59f5cfe 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -37,6 +37,7 @@ enum clk_ids { CLK_PLL5, CLK_PLL5_DIV2, CLK_PLL6, + CLK_P1_DIV2, /* Module Clocks */ MOD_CLK_BASE, @@ -79,6 +80,7 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1), DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), + DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2), DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), }; @@ -90,6 +92,10 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x518, 0), DEF_MOD("ia55_clk", R9A07G044_IA55_CLK, R9A07G044_CLK_P1, 0x518, 1), + DEF_MOD("dmac_aclk", R9A07G044_DMAC_ACLK, R9A07G044_CLK_P1, + 0x52c, 0), + DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, + 0x52c, 1), DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0, 0x580, 0), DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0, @@ -116,6 +122,8 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_GIC600_GICRESET_N, 0x814, 0), DEF_RST(R9A07G044_GIC600_DBG_GICRESET_N, 0x814, 1), DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), + DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), + DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0), DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1), DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2), -- cgit v1.3-14-g43fede From 03fa6e4b2622035389a4beb9699551d63d130493 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Jun 2021 08:30:06 +0100 Subject: clk: renesas: r9a07g044: Add USB clocks/resets Add clock/reset entries for USB PHY control, USB2.0 host and device. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20210630073013.22415-5-biju.das.jz@bp.renesas.com [geert: s/usb0_device/usb0_func] Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 5d81e59f5cfe..7af4b39a0953 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -96,6 +96,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x52c, 0), DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, 0x52c, 1), + DEF_MOD("usb0_host", R9A07G044_USB_U2H0_HCLK, R9A07G044_CLK_P1, + 0x578, 0), + DEF_MOD("usb1_host", R9A07G044_USB_U2H1_HCLK, R9A07G044_CLK_P1, + 0x578, 1), + DEF_MOD("usb0_func", R9A07G044_USB_U2P_EXR_CPUCLK, R9A07G044_CLK_P1, + 0x578, 2), + DEF_MOD("usb_pclk", R9A07G044_USB_PCLK, R9A07G044_CLK_P1, + 0x578, 3), DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0, 0x580, 0), DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0, @@ -124,6 +132,10 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), + DEF_RST(R9A07G044_USB_U2H0_HRESETN, 0x878, 0), + DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1), + DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2), + DEF_RST(R9A07G044_USB_PRESETN, 0x878, 3), DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0), DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1), DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2), -- cgit v1.3-14-g43fede From d520af345189c04095bdd256d3601864601ac562 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 2 Jul 2021 14:50:03 +0100 Subject: clk: renesas: r9a07g044: Add SSIF-2 clock and reset entries Add SSIF-2 clock and reset entries in CPG driver. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210702135010.5937-3-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 7af4b39a0953..ed5f5c11ac12 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -96,6 +96,22 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x52c, 0), DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, 0x52c, 1), + DEF_MOD("ssi0_pclk", R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0, + 0x570, 0), + DEF_MOD("ssi0_sfr", R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0, + 0x570, 1), + DEF_MOD("ssi1_pclk", R9A07G044_SSI1_PCLK2, R9A07G044_CLK_P0, + 0x570, 2), + DEF_MOD("ssi1_sfr", R9A07G044_SSI1_PCLK_SFR, R9A07G044_CLK_P0, + 0x570, 3), + DEF_MOD("ssi2_pclk", R9A07G044_SSI2_PCLK2, R9A07G044_CLK_P0, + 0x570, 4), + DEF_MOD("ssi2_sfr", R9A07G044_SSI2_PCLK_SFR, R9A07G044_CLK_P0, + 0x570, 5), + DEF_MOD("ssi3_pclk", R9A07G044_SSI3_PCLK2, R9A07G044_CLK_P0, + 0x570, 6), + DEF_MOD("ssi3_sfr", R9A07G044_SSI3_PCLK_SFR, R9A07G044_CLK_P0, + 0x570, 7), DEF_MOD("usb0_host", R9A07G044_USB_U2H0_HCLK, R9A07G044_CLK_P1, 0x578, 0), DEF_MOD("usb1_host", R9A07G044_USB_U2H1_HCLK, R9A07G044_CLK_P1, @@ -132,6 +148,10 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), + DEF_RST(R9A07G044_SSI0_RST_M2_REG, 0x870, 0), + DEF_RST(R9A07G044_SSI1_RST_M2_REG, 0x870, 1), + DEF_RST(R9A07G044_SSI2_RST_M2_REG, 0x870, 2), + DEF_RST(R9A07G044_SSI3_RST_M2_REG, 0x870, 3), DEF_RST(R9A07G044_USB_U2H0_HRESETN, 0x878, 0), DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1), DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2), -- cgit v1.3-14-g43fede From d85b82f09a03c2e1f06da740c6c47dd098b16ca5 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 12 Jul 2021 20:44:20 +0100 Subject: clk: renesas: r9a07g044: Add GPIO clock and reset entries Add GPIO clock and reset entries in CPG driver. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210712194422.12405-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index ed5f5c11ac12..78fae93cf249 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -140,6 +140,8 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x584, 4), DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0, 0x588, 0), + DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK, + 0x598, 0), }; static struct rzg2l_reset r9a07g044_resets[] = { @@ -166,6 +168,9 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3), DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4), DEF_RST(R9A07G044_SCI0_RST, 0x888, 0), + DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0), + DEF_RST(R9A07G044_GPIO_PORT_RESETN, 0x898, 1), + DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2), }; static const unsigned int r9a07g044_crit_mod_clks[] __initconst = { -- cgit v1.3-14-g43fede From 0aae437ac5c264e8e2cb6c3fead20b44d2fa31d1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 14 Jul 2021 15:26:01 +0200 Subject: clk: renesas: Rename renesas-rzg2l-cpg.[ch] to rzg2l-cpg.[ch] Rename renesas-rzg2l-cpg.c and renesas-rzg2l-cpg.h to rzg2l-cpg.c resp. rzg2l-cpg.h, for consistency with other (sub)drivers. Signed-off-by: Geert Uytterhoeven Reviewed-by: Lad Prabhakar Acked-by: Biju Das Link: https://lore.kernel.org/r/edc442daaedffcf10e835ff479d906fcae0e59db.1626268821.git.geert+renesas@glider.be --- drivers/clk/renesas/Makefile | 2 +- drivers/clk/renesas/r9a07g044-cpg.c | 2 +- drivers/clk/renesas/renesas-rzg2l-cpg.c | 750 -------------------------------- drivers/clk/renesas/renesas-rzg2l-cpg.h | 155 ------- drivers/clk/renesas/rzg2l-cpg.c | 750 ++++++++++++++++++++++++++++++++ drivers/clk/renesas/rzg2l-cpg.h | 155 +++++++ 6 files changed, 907 insertions(+), 907 deletions(-) delete mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.c delete mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.h create mode 100644 drivers/clk/renesas/rzg2l-cpg.c create mode 100644 drivers/clk/renesas/rzg2l-cpg.h diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 5c6c5c721d98..7d018700d08b 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_CLK_RCAR_CPG_LIB) += rcar-cpg-lib.o obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o -obj-$(CONFIG_CLK_RZG2L) += renesas-rzg2l-cpg.o +obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o # Generic obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 78fae93cf249..6a1d9532a690 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -12,7 +12,7 @@ #include -#include "renesas-rzg2l-cpg.h" +#include "rzg2l-cpg.h" enum clk_ids { /* Core Clock Outputs exported to DT */ diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c deleted file mode 100644 index 9addc9dae31a..000000000000 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ /dev/null @@ -1,750 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * RZ/G2L Clock Pulse Generator - * - * Copyright (C) 2021 Renesas Electronics Corp. - * - * Based on renesas-cpg-mssr.c - * - * Copyright (C) 2015 Glider bvba - * Copyright (C) 2013 Ideas On Board SPRL - * Copyright (C) 2015 Renesas Electronics Corp. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "renesas-rzg2l-cpg.h" - -#ifdef DEBUG -#define WARN_DEBUG(x) WARN_ON(x) -#else -#define WARN_DEBUG(x) do { } while (0) -#endif - -#define DIV_RSMASK(v, s, m) ((v >> s) & m) -#define GET_SHIFT(val) ((val >> 12) & 0xff) -#define GET_WIDTH(val) ((val >> 8) & 0xf) - -#define KDIV(val) DIV_RSMASK(val, 16, 0xffff) -#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff) -#define PDIV(val) DIV_RSMASK(val, 0, 0x3f) -#define SDIV(val) DIV_RSMASK(val, 0, 0x7) - -#define CLK_ON_R(reg) (reg) -#define CLK_MON_R(reg) (0x180 + (reg)) -#define CLK_RST_R(reg) (reg) -#define CLK_MRST_R(reg) (0x180 + (reg)) - -#define GET_REG_OFFSET(val) ((val >> 20) & 0xfff) -#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff) -#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff) - -/** - * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data - * - * @rcdev: Reset controller entity - * @dev: CPG device - * @base: CPG register block base address - * @rmw_lock: protects register accesses - * @clks: Array containing all Core and Module Clocks - * @num_core_clks: Number of Core Clocks in clks[] - * @num_mod_clks: Number of Module Clocks in clks[] - * @last_dt_core_clk: ID of the last Core Clock exported to DT - * @notifiers: Notifier chain to save/restore clock state for system resume - * @info: Pointer to platform data - */ -struct rzg2l_cpg_priv { - struct reset_controller_dev rcdev; - struct device *dev; - void __iomem *base; - spinlock_t rmw_lock; - - struct clk **clks; - unsigned int num_core_clks; - unsigned int num_mod_clks; - unsigned int num_resets; - unsigned int last_dt_core_clk; - - struct raw_notifier_head notifiers; - const struct rzg2l_cpg_info *info; -}; - -static void rzg2l_cpg_del_clk_provider(void *data) -{ - of_clk_del_provider(data); -} - -static struct clk * __init -rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, - struct clk **clks, - void __iomem *base, - struct rzg2l_cpg_priv *priv) -{ - struct device *dev = priv->dev; - const struct clk *parent; - const char *parent_name; - struct clk_hw *clk_hw; - - parent = clks[core->parent & 0xffff]; - if (IS_ERR(parent)) - return ERR_CAST(parent); - - parent_name = __clk_get_name(parent); - - if (core->dtable) - clk_hw = clk_hw_register_divider_table(dev, core->name, - parent_name, 0, - base + GET_REG_OFFSET(core->conf), - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->flag, - core->dtable, - &priv->rmw_lock); - else - clk_hw = clk_hw_register_divider(dev, core->name, - parent_name, 0, - base + GET_REG_OFFSET(core->conf), - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->flag, &priv->rmw_lock); - - if (IS_ERR(clk_hw)) - return ERR_CAST(clk_hw); - - return clk_hw->clk; -} - -struct pll_clk { - struct clk_hw hw; - unsigned int conf; - unsigned int type; - void __iomem *base; - struct rzg2l_cpg_priv *priv; -}; - -#define to_pll(_hw) container_of(_hw, struct pll_clk, hw) - -static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct pll_clk *pll_clk = to_pll(hw); - struct rzg2l_cpg_priv *priv = pll_clk->priv; - unsigned int val1, val2; - unsigned int mult = 1; - unsigned int div = 1; - - if (pll_clk->type != CLK_TYPE_SAM_PLL) - return parent_rate; - - val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); - val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); - mult = MDIV(val1) + KDIV(val1) / 65536; - div = PDIV(val1) * (1 << SDIV(val2)); - - return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div); -} - -static const struct clk_ops rzg2l_cpg_pll_ops = { - .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate, -}; - -static struct clk * __init -rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, - struct clk **clks, - void __iomem *base, - struct rzg2l_cpg_priv *priv) -{ - struct device *dev = priv->dev; - const struct clk *parent; - struct clk_init_data init; - const char *parent_name; - struct pll_clk *pll_clk; - - parent = clks[core->parent & 0xffff]; - if (IS_ERR(parent)) - return ERR_CAST(parent); - - pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); - if (!pll_clk) - return ERR_PTR(-ENOMEM); - - parent_name = __clk_get_name(parent); - init.name = core->name; - init.ops = &rzg2l_cpg_pll_ops; - init.flags = 0; - init.parent_names = &parent_name; - init.num_parents = 1; - - pll_clk->hw.init = &init; - pll_clk->conf = core->conf; - pll_clk->base = base; - pll_clk->priv = priv; - pll_clk->type = core->type; - - return clk_register(NULL, &pll_clk->hw); -} - -static struct clk -*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec, - void *data) -{ - unsigned int clkidx = clkspec->args[1]; - struct rzg2l_cpg_priv *priv = data; - struct device *dev = priv->dev; - const char *type; - struct clk *clk; - - switch (clkspec->args[0]) { - case CPG_CORE: - type = "core"; - if (clkidx > priv->last_dt_core_clk) { - dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); - return ERR_PTR(-EINVAL); - } - clk = priv->clks[clkidx]; - break; - - case CPG_MOD: - type = "module"; - if (clkidx >= priv->num_mod_clks) { - dev_err(dev, "Invalid %s clock index %u\n", type, - clkidx); - return ERR_PTR(-EINVAL); - } - clk = priv->clks[priv->num_core_clks + clkidx]; - break; - - default: - dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); - return ERR_PTR(-EINVAL); - } - - if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, - PTR_ERR(clk)); - else - dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", - clkspec->args[0], clkspec->args[1], clk, - clk_get_rate(clk)); - return clk; -} - -static void __init -rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, - const struct rzg2l_cpg_info *info, - struct rzg2l_cpg_priv *priv) -{ - struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; - struct device *dev = priv->dev; - unsigned int id = core->id, div = core->div; - const char *parent_name; - - WARN_DEBUG(id >= priv->num_core_clks); - WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); - - if (!core->name) { - /* Skip NULLified clock */ - return; - } - - switch (core->type) { - case CLK_TYPE_IN: - clk = of_clk_get_by_name(priv->dev->of_node, core->name); - break; - case CLK_TYPE_FF: - WARN_DEBUG(core->parent >= priv->num_core_clks); - parent = priv->clks[core->parent]; - if (IS_ERR(parent)) { - clk = parent; - goto fail; - } - - parent_name = __clk_get_name(parent); - clk = clk_register_fixed_factor(NULL, core->name, - parent_name, CLK_SET_RATE_PARENT, - core->mult, div); - break; - case CLK_TYPE_SAM_PLL: - clk = rzg2l_cpg_pll_clk_register(core, priv->clks, - priv->base, priv); - break; - case CLK_TYPE_DIV: - clk = rzg2l_cpg_div_clk_register(core, priv->clks, - priv->base, priv); - break; - default: - goto fail; - } - - if (IS_ERR_OR_NULL(clk)) - goto fail; - - dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); - priv->clks[id] = clk; - return; - -fail: - dev_err(dev, "Failed to register %s clock %s: %ld\n", "core", - core->name, PTR_ERR(clk)); -} - -/** - * struct mstp_clock - MSTP gating clock - * - * @hw: handle between common and hardware-specific interfaces - * @off: register offset - * @bit: ON/MON bit - * @priv: CPG/MSTP private data - */ -struct mstp_clock { - struct clk_hw hw; - u16 off; - u8 bit; - struct rzg2l_cpg_priv *priv; -}; - -#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw) - -static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) -{ - struct mstp_clock *clock = to_mod_clock(hw); - struct rzg2l_cpg_priv *priv = clock->priv; - unsigned int reg = clock->off; - struct device *dev = priv->dev; - unsigned long flags; - unsigned int i; - u32 bitmask = BIT(clock->bit); - u32 value; - - if (!clock->off) { - dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk); - return 0; - } - - dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, - enable ? "ON" : "OFF"); - spin_lock_irqsave(&priv->rmw_lock, flags); - - if (enable) - value = (bitmask << 16) | bitmask; - else - value = bitmask << 16; - writel(value, priv->base + CLK_ON_R(reg)); - - spin_unlock_irqrestore(&priv->rmw_lock, flags); - - if (!enable) - return 0; - - for (i = 1000; i > 0; --i) { - if (((readl(priv->base + CLK_MON_R(reg))) & bitmask)) - break; - cpu_relax(); - } - - if (!i) { - dev_err(dev, "Failed to enable CLK_ON %p\n", - priv->base + CLK_ON_R(reg)); - return -ETIMEDOUT; - } - - return 0; -} - -static int rzg2l_mod_clock_enable(struct clk_hw *hw) -{ - return rzg2l_mod_clock_endisable(hw, true); -} - -static void rzg2l_mod_clock_disable(struct clk_hw *hw) -{ - rzg2l_mod_clock_endisable(hw, false); -} - -static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw) -{ - struct mstp_clock *clock = to_mod_clock(hw); - struct rzg2l_cpg_priv *priv = clock->priv; - u32 bitmask = BIT(clock->bit); - u32 value; - - if (!clock->off) { - dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk); - return 1; - } - - value = readl(priv->base + CLK_MON_R(clock->off)); - - return !(value & bitmask); -} - -static const struct clk_ops rzg2l_mod_clock_ops = { - .enable = rzg2l_mod_clock_enable, - .disable = rzg2l_mod_clock_disable, - .is_enabled = rzg2l_mod_clock_is_enabled, -}; - -static void __init -rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, - const struct rzg2l_cpg_info *info, - struct rzg2l_cpg_priv *priv) -{ - struct mstp_clock *clock = NULL; - struct device *dev = priv->dev; - unsigned int id = mod->id; - struct clk_init_data init; - struct clk *parent, *clk; - const char *parent_name; - unsigned int i; - - WARN_DEBUG(id < priv->num_core_clks); - WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); - WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); - WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); - - if (!mod->name) { - /* Skip NULLified clock */ - return; - } - - parent = priv->clks[mod->parent]; - if (IS_ERR(parent)) { - clk = parent; - goto fail; - } - - clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL); - if (!clock) { - clk = ERR_PTR(-ENOMEM); - goto fail; - } - - init.name = mod->name; - init.ops = &rzg2l_mod_clock_ops; - init.flags = CLK_SET_RATE_PARENT; - for (i = 0; i < info->num_crit_mod_clks; i++) - if (id == info->crit_mod_clks[i]) { - dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n", - mod->name); - init.flags |= CLK_IS_CRITICAL; - break; - } - - parent_name = __clk_get_name(parent); - init.parent_names = &parent_name; - init.num_parents = 1; - - clock->off = mod->off; - clock->bit = mod->bit; - clock->priv = priv; - clock->hw.init = &init; - - clk = clk_register(NULL, &clock->hw); - if (IS_ERR(clk)) - goto fail; - - dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); - priv->clks[id] = clk; - return; - -fail: - dev_err(dev, "Failed to register %s clock %s: %ld\n", "module", - mod->name, PTR_ERR(clk)); -} - -#define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) - -static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 dis = BIT(info->resets[id].bit); - u32 we = dis << 16; - - dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); - - /* Reset module */ - writel(we, priv->base + CLK_RST_R(reg)); - - /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ - udelay(35); - - /* Release module from reset state */ - writel(we | dis, priv->base + CLK_RST_R(reg)); - - return 0; -} - -static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 value = BIT(info->resets[id].bit) << 16; - - dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); - - writel(value, priv->base + CLK_RST_R(reg)); - return 0; -} - -static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 dis = BIT(info->resets[id].bit); - u32 value = (dis << 16) | dis; - - dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, - CLK_RST_R(reg)); - - writel(value, priv->base + CLK_RST_R(reg)); - return 0; -} - -static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 bitmask = BIT(info->resets[id].bit); - - return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask); -} - -static const struct reset_control_ops rzg2l_cpg_reset_ops = { - .reset = rzg2l_cpg_reset, - .assert = rzg2l_cpg_assert, - .deassert = rzg2l_cpg_deassert, - .status = rzg2l_cpg_status, -}; - -static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev, - const struct of_phandle_args *reset_spec) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int id = reset_spec->args[0]; - - if (id >= rcdev->nr_resets || !info->resets[id].off) { - dev_err(rcdev->dev, "Invalid reset index %u\n", id); - return -EINVAL; - } - - return id; -} - -static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv) -{ - priv->rcdev.ops = &rzg2l_cpg_reset_ops; - priv->rcdev.of_node = priv->dev->of_node; - priv->rcdev.dev = priv->dev; - priv->rcdev.of_reset_n_cells = 1; - priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate; - priv->rcdev.nr_resets = priv->num_resets; - - return devm_reset_controller_register(priv->dev, &priv->rcdev); -} - -static bool rzg2l_cpg_is_pm_clk(const struct of_phandle_args *clkspec) -{ - if (clkspec->args_count != 2) - return false; - - switch (clkspec->args[0]) { - case CPG_MOD: - return true; - - default: - return false; - } -} - -static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device *dev) -{ - struct device_node *np = dev->of_node; - struct of_phandle_args clkspec; - bool once = true; - struct clk *clk; - int error; - int i = 0; - - while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, - &clkspec)) { - if (rzg2l_cpg_is_pm_clk(&clkspec)) { - if (once) { - once = false; - error = pm_clk_create(dev); - if (error) { - of_node_put(clkspec.np); - goto err; - } - } - clk = of_clk_get_from_provider(&clkspec); - of_node_put(clkspec.np); - if (IS_ERR(clk)) { - error = PTR_ERR(clk); - goto fail_destroy; - } - - error = pm_clk_add_clk(dev, clk); - if (error) { - dev_err(dev, "pm_clk_add_clk failed %d\n", - error); - goto fail_put; - } - } else { - of_node_put(clkspec.np); - } - i++; - } - - return 0; - -fail_put: - clk_put(clk); - -fail_destroy: - pm_clk_destroy(dev); -err: - return error; -} - -static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev) -{ - if (!pm_clk_no_clocks(dev)) - pm_clk_destroy(dev); -} - -static int __init rzg2l_cpg_add_clk_domain(struct device *dev) -{ - struct device_node *np = dev->of_node; - struct generic_pm_domain *genpd; - - genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL); - if (!genpd) - return -ENOMEM; - - genpd->name = np->name; - genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | - GENPD_FLAG_ACTIVE_WAKEUP; - genpd->attach_dev = rzg2l_cpg_attach_dev; - genpd->detach_dev = rzg2l_cpg_detach_dev; - pm_genpd_init(genpd, &pm_domain_always_on_gov, false); - - of_genpd_add_provider_simple(np, genpd); - return 0; -} - -static int __init rzg2l_cpg_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - const struct rzg2l_cpg_info *info; - struct rzg2l_cpg_priv *priv; - unsigned int nclks, i; - struct clk **clks; - int error; - - info = of_device_get_match_data(dev); - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->dev = dev; - priv->info = info; - spin_lock_init(&priv->rmw_lock); - - priv->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - - nclks = info->num_total_core_clks + info->num_hw_mod_clks; - clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); - if (!clks) - return -ENOMEM; - - dev_set_drvdata(dev, priv); - priv->clks = clks; - priv->num_core_clks = info->num_total_core_clks; - priv->num_mod_clks = info->num_hw_mod_clks; - priv->num_resets = info->num_resets; - priv->last_dt_core_clk = info->last_dt_core_clk; - - for (i = 0; i < nclks; i++) - clks[i] = ERR_PTR(-ENOENT); - - for (i = 0; i < info->num_core_clks; i++) - rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv); - - for (i = 0; i < info->num_mod_clks; i++) - rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv); - - error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv); - if (error) - return error; - - error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np); - if (error) - return error; - - error = rzg2l_cpg_add_clk_domain(dev); - if (error) - return error; - - error = rzg2l_cpg_reset_controller_register(priv); - if (error) - return error; - - return 0; -} - -static const struct of_device_id rzg2l_cpg_match[] = { -#ifdef CONFIG_CLK_R9A07G044 - { - .compatible = "renesas,r9a07g044-cpg", - .data = &r9a07g044_cpg_info, - }, -#endif - { /* sentinel */ } -}; - -static struct platform_driver rzg2l_cpg_driver = { - .driver = { - .name = "rzg2l-cpg", - .of_match_table = rzg2l_cpg_match, - }, -}; - -static int __init rzg2l_cpg_init(void) -{ - return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe); -} - -subsys_initcall(rzg2l_cpg_init); - -MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.h b/drivers/clk/renesas/renesas-rzg2l-cpg.h deleted file mode 100644 index 63695280ce8b..000000000000 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.h +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * RZ/G2L Clock Pulse Generator - * - * Copyright (C) 2021 Renesas Electronics Corp. - * - */ - -#ifndef __RENESAS_RZG2L_CPG_H__ -#define __RENESAS_RZG2L_CPG_H__ - -#define CPG_PL2_DDIV (0x204) -#define CPG_PL3A_DDIV (0x208) - -/* n = 0/1/2 for PLL1/4/6 */ -#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) -#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n)) - -#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12) - -#define DDIV_PACK(offset, bitpos, size) \ - (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) -#define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3) -#define DIVPL3A DDIV_PACK(CPG_PL3A_DDIV, 0, 3) -#define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3) - -/** - * Definitions of CPG Core Clocks - * - * These include: - * - Clock outputs exported to DT - * - External input clocks - * - Internal CPG clocks - */ -struct cpg_core_clk { - const char *name; - unsigned int id; - unsigned int parent; - unsigned int div; - unsigned int mult; - unsigned int type; - unsigned int conf; - const struct clk_div_table *dtable; - const char * const *parent_names; - int flag; - int num_parents; -}; - -enum clk_types { - /* Generic */ - CLK_TYPE_IN, /* External Clock Input */ - CLK_TYPE_FF, /* Fixed Factor Clock */ - CLK_TYPE_SAM_PLL, - - /* Clock with divider */ - CLK_TYPE_DIV, -}; - -#define DEF_TYPE(_name, _id, _type...) \ - { .name = _name, .id = _id, .type = _type } -#define DEF_BASE(_name, _id, _type, _parent...) \ - DEF_TYPE(_name, _id, _type, .parent = _parent) -#define DEF_SAMPLL(_name, _id, _parent, _conf) \ - DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf) -#define DEF_INPUT(_name, _id) \ - DEF_TYPE(_name, _id, CLK_TYPE_IN) -#define DEF_FIXED(_name, _id, _parent, _mult, _div) \ - DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) -#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \ - DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ - .parent = _parent, .dtable = _dtable, .flag = _flag) - -/** - * struct rzg2l_mod_clk - Module Clocks definitions - * - * @name: handle between common and hardware-specific interfaces - * @id: clock index in array containing all Core and Module Clocks - * @parent: id of parent clock - * @off: register offset - * @bit: ON/MON bit - */ -struct rzg2l_mod_clk { - const char *name; - unsigned int id; - unsigned int parent; - u16 off; - u8 bit; -}; - -#define DEF_MOD(_name, _id, _parent, _off, _bit) \ - { \ - .name = _name, \ - .id = MOD_CLK_BASE + (_id), \ - .parent = (_parent), \ - .off = (_off), \ - .bit = (_bit), \ - } - -/** - * struct rzg2l_reset - Reset definitions - * - * @off: register offset - * @bit: reset bit - */ -struct rzg2l_reset { - u16 off; - u8 bit; -}; - -#define DEF_RST(_id, _off, _bit) \ - [_id] = { \ - .off = (_off), \ - .bit = (_bit) \ - } - -/** - * struct rzg2l_cpg_info - SoC-specific CPG Description - * - * @core_clks: Array of Core Clock definitions - * @num_core_clks: Number of entries in core_clks[] - * @last_dt_core_clk: ID of the last Core Clock exported to DT - * @num_total_core_clks: Total number of Core Clocks (exported + internal) - * - * @mod_clks: Array of Module Clock definitions - * @num_mod_clks: Number of entries in mod_clks[] - * @num_hw_mod_clks: Number of Module Clocks supported by the hardware - * - * @crit_mod_clks: Array with Module Clock IDs of critical clocks that - * should not be disabled without a knowledgeable driver - * @num_crit_mod_clks: Number of entries in crit_mod_clks[] - */ -struct rzg2l_cpg_info { - /* Core Clocks */ - const struct cpg_core_clk *core_clks; - unsigned int num_core_clks; - unsigned int last_dt_core_clk; - unsigned int num_total_core_clks; - - /* Module Clocks */ - const struct rzg2l_mod_clk *mod_clks; - unsigned int num_mod_clks; - unsigned int num_hw_mod_clks; - - /* Resets */ - const struct rzg2l_reset *resets; - unsigned int num_resets; - - /* Critical Module Clocks that should not be disabled */ - const unsigned int *crit_mod_clks; - unsigned int num_crit_mod_clks; -}; - -extern const struct rzg2l_cpg_info r9a07g044_cpg_info; - -#endif diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c new file mode 100644 index 000000000000..3b3b2c3347f3 --- /dev/null +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -0,0 +1,750 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZ/G2L Clock Pulse Generator + * + * Copyright (C) 2021 Renesas Electronics Corp. + * + * Based on renesas-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2013 Ideas On Board SPRL + * Copyright (C) 2015 Renesas Electronics Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "rzg2l-cpg.h" + +#ifdef DEBUG +#define WARN_DEBUG(x) WARN_ON(x) +#else +#define WARN_DEBUG(x) do { } while (0) +#endif + +#define DIV_RSMASK(v, s, m) ((v >> s) & m) +#define GET_SHIFT(val) ((val >> 12) & 0xff) +#define GET_WIDTH(val) ((val >> 8) & 0xf) + +#define KDIV(val) DIV_RSMASK(val, 16, 0xffff) +#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff) +#define PDIV(val) DIV_RSMASK(val, 0, 0x3f) +#define SDIV(val) DIV_RSMASK(val, 0, 0x7) + +#define CLK_ON_R(reg) (reg) +#define CLK_MON_R(reg) (0x180 + (reg)) +#define CLK_RST_R(reg) (reg) +#define CLK_MRST_R(reg) (0x180 + (reg)) + +#define GET_REG_OFFSET(val) ((val >> 20) & 0xfff) +#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff) +#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff) + +/** + * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data + * + * @rcdev: Reset controller entity + * @dev: CPG device + * @base: CPG register block base address + * @rmw_lock: protects register accesses + * @clks: Array containing all Core and Module Clocks + * @num_core_clks: Number of Core Clocks in clks[] + * @num_mod_clks: Number of Module Clocks in clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + * @notifiers: Notifier chain to save/restore clock state for system resume + * @info: Pointer to platform data + */ +struct rzg2l_cpg_priv { + struct reset_controller_dev rcdev; + struct device *dev; + void __iomem *base; + spinlock_t rmw_lock; + + struct clk **clks; + unsigned int num_core_clks; + unsigned int num_mod_clks; + unsigned int num_resets; + unsigned int last_dt_core_clk; + + struct raw_notifier_head notifiers; + const struct rzg2l_cpg_info *info; +}; + +static void rzg2l_cpg_del_clk_provider(void *data) +{ + of_clk_del_provider(data); +} + +static struct clk * __init +rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, + struct clk **clks, + void __iomem *base, + struct rzg2l_cpg_priv *priv) +{ + struct device *dev = priv->dev; + const struct clk *parent; + const char *parent_name; + struct clk_hw *clk_hw; + + parent = clks[core->parent & 0xffff]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + parent_name = __clk_get_name(parent); + + if (core->dtable) + clk_hw = clk_hw_register_divider_table(dev, core->name, + parent_name, 0, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, + core->dtable, + &priv->rmw_lock); + else + clk_hw = clk_hw_register_divider(dev, core->name, + parent_name, 0, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, &priv->rmw_lock); + + if (IS_ERR(clk_hw)) + return ERR_CAST(clk_hw); + + return clk_hw->clk; +} + +struct pll_clk { + struct clk_hw hw; + unsigned int conf; + unsigned int type; + void __iomem *base; + struct rzg2l_cpg_priv *priv; +}; + +#define to_pll(_hw) container_of(_hw, struct pll_clk, hw) + +static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzg2l_cpg_priv *priv = pll_clk->priv; + unsigned int val1, val2; + unsigned int mult = 1; + unsigned int div = 1; + + if (pll_clk->type != CLK_TYPE_SAM_PLL) + return parent_rate; + + val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); + val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); + mult = MDIV(val1) + KDIV(val1) / 65536; + div = PDIV(val1) * (1 << SDIV(val2)); + + return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div); +} + +static const struct clk_ops rzg2l_cpg_pll_ops = { + .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate, +}; + +static struct clk * __init +rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, + struct clk **clks, + void __iomem *base, + struct rzg2l_cpg_priv *priv) +{ + struct device *dev = priv->dev; + const struct clk *parent; + struct clk_init_data init; + const char *parent_name; + struct pll_clk *pll_clk; + + parent = clks[core->parent & 0xffff]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); + if (!pll_clk) + return ERR_PTR(-ENOMEM); + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &rzg2l_cpg_pll_ops; + init.flags = 0; + init.parent_names = &parent_name; + init.num_parents = 1; + + pll_clk->hw.init = &init; + pll_clk->conf = core->conf; + pll_clk->base = base; + pll_clk->priv = priv; + pll_clk->type = core->type; + + return clk_register(NULL, &pll_clk->hw); +} + +static struct clk +*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec, + void *data) +{ + unsigned int clkidx = clkspec->args[1]; + struct rzg2l_cpg_priv *priv = data; + struct device *dev = priv->dev; + const char *type; + struct clk *clk; + + switch (clkspec->args[0]) { + case CPG_CORE: + type = "core"; + if (clkidx > priv->last_dt_core_clk) { + dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[clkidx]; + break; + + case CPG_MOD: + type = "module"; + if (clkidx >= priv->num_mod_clks) { + dev_err(dev, "Invalid %s clock index %u\n", type, + clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[priv->num_core_clks + clkidx]; + break; + + default: + dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); + return ERR_PTR(-EINVAL); + } + + if (IS_ERR(clk)) + dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + PTR_ERR(clk)); + else + dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", + clkspec->args[0], clkspec->args[1], clk, + clk_get_rate(clk)); + return clk; +} + +static void __init +rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, + const struct rzg2l_cpg_info *info, + struct rzg2l_cpg_priv *priv) +{ + struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; + struct device *dev = priv->dev; + unsigned int id = core->id, div = core->div; + const char *parent_name; + + WARN_DEBUG(id >= priv->num_core_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + if (!core->name) { + /* Skip NULLified clock */ + return; + } + + switch (core->type) { + case CLK_TYPE_IN: + clk = of_clk_get_by_name(priv->dev->of_node, core->name); + break; + case CLK_TYPE_FF: + WARN_DEBUG(core->parent >= priv->num_core_clks); + parent = priv->clks[core->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + parent_name = __clk_get_name(parent); + clk = clk_register_fixed_factor(NULL, core->name, + parent_name, CLK_SET_RATE_PARENT, + core->mult, div); + break; + case CLK_TYPE_SAM_PLL: + clk = rzg2l_cpg_pll_clk_register(core, priv->clks, + priv->base, priv); + break; + case CLK_TYPE_DIV: + clk = rzg2l_cpg_div_clk_register(core, priv->clks, + priv->base, priv); + break; + default: + goto fail; + } + + if (IS_ERR_OR_NULL(clk)) + goto fail; + + dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "core", + core->name, PTR_ERR(clk)); +} + +/** + * struct mstp_clock - MSTP gating clock + * + * @hw: handle between common and hardware-specific interfaces + * @off: register offset + * @bit: ON/MON bit + * @priv: CPG/MSTP private data + */ +struct mstp_clock { + struct clk_hw hw; + u16 off; + u8 bit; + struct rzg2l_cpg_priv *priv; +}; + +#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw) + +static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) +{ + struct mstp_clock *clock = to_mod_clock(hw); + struct rzg2l_cpg_priv *priv = clock->priv; + unsigned int reg = clock->off; + struct device *dev = priv->dev; + unsigned long flags; + unsigned int i; + u32 bitmask = BIT(clock->bit); + u32 value; + + if (!clock->off) { + dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk); + return 0; + } + + dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, + enable ? "ON" : "OFF"); + spin_lock_irqsave(&priv->rmw_lock, flags); + + if (enable) + value = (bitmask << 16) | bitmask; + else + value = bitmask << 16; + writel(value, priv->base + CLK_ON_R(reg)); + + spin_unlock_irqrestore(&priv->rmw_lock, flags); + + if (!enable) + return 0; + + for (i = 1000; i > 0; --i) { + if (((readl(priv->base + CLK_MON_R(reg))) & bitmask)) + break; + cpu_relax(); + } + + if (!i) { + dev_err(dev, "Failed to enable CLK_ON %p\n", + priv->base + CLK_ON_R(reg)); + return -ETIMEDOUT; + } + + return 0; +} + +static int rzg2l_mod_clock_enable(struct clk_hw *hw) +{ + return rzg2l_mod_clock_endisable(hw, true); +} + +static void rzg2l_mod_clock_disable(struct clk_hw *hw) +{ + rzg2l_mod_clock_endisable(hw, false); +} + +static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw) +{ + struct mstp_clock *clock = to_mod_clock(hw); + struct rzg2l_cpg_priv *priv = clock->priv; + u32 bitmask = BIT(clock->bit); + u32 value; + + if (!clock->off) { + dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk); + return 1; + } + + value = readl(priv->base + CLK_MON_R(clock->off)); + + return !(value & bitmask); +} + +static const struct clk_ops rzg2l_mod_clock_ops = { + .enable = rzg2l_mod_clock_enable, + .disable = rzg2l_mod_clock_disable, + .is_enabled = rzg2l_mod_clock_is_enabled, +}; + +static void __init +rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, + const struct rzg2l_cpg_info *info, + struct rzg2l_cpg_priv *priv) +{ + struct mstp_clock *clock = NULL; + struct device *dev = priv->dev; + unsigned int id = mod->id; + struct clk_init_data init; + struct clk *parent, *clk; + const char *parent_name; + unsigned int i; + + WARN_DEBUG(id < priv->num_core_clks); + WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + if (!mod->name) { + /* Skip NULLified clock */ + return; + } + + parent = priv->clks[mod->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL); + if (!clock) { + clk = ERR_PTR(-ENOMEM); + goto fail; + } + + init.name = mod->name; + init.ops = &rzg2l_mod_clock_ops; + init.flags = CLK_SET_RATE_PARENT; + for (i = 0; i < info->num_crit_mod_clks; i++) + if (id == info->crit_mod_clks[i]) { + dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n", + mod->name); + init.flags |= CLK_IS_CRITICAL; + break; + } + + parent_name = __clk_get_name(parent); + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->off = mod->off; + clock->bit = mod->bit; + clock->priv = priv; + clock->hw.init = &init; + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + goto fail; + + dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "module", + mod->name, PTR_ERR(clk)); +} + +#define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) + +static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; + u32 dis = BIT(info->resets[id].bit); + u32 we = dis << 16; + + dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); + + /* Reset module */ + writel(we, priv->base + CLK_RST_R(reg)); + + /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ + udelay(35); + + /* Release module from reset state */ + writel(we | dis, priv->base + CLK_RST_R(reg)); + + return 0; +} + +static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; + u32 value = BIT(info->resets[id].bit) << 16; + + dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); + return 0; +} + +static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; + u32 dis = BIT(info->resets[id].bit); + u32 value = (dis << 16) | dis; + + dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, + CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); + return 0; +} + +static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; + u32 bitmask = BIT(info->resets[id].bit); + + return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask); +} + +static const struct reset_control_ops rzg2l_cpg_reset_ops = { + .reset = rzg2l_cpg_reset, + .assert = rzg2l_cpg_assert, + .deassert = rzg2l_cpg_deassert, + .status = rzg2l_cpg_status, +}; + +static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int id = reset_spec->args[0]; + + if (id >= rcdev->nr_resets || !info->resets[id].off) { + dev_err(rcdev->dev, "Invalid reset index %u\n", id); + return -EINVAL; + } + + return id; +} + +static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv) +{ + priv->rcdev.ops = &rzg2l_cpg_reset_ops; + priv->rcdev.of_node = priv->dev->of_node; + priv->rcdev.dev = priv->dev; + priv->rcdev.of_reset_n_cells = 1; + priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate; + priv->rcdev.nr_resets = priv->num_resets; + + return devm_reset_controller_register(priv->dev, &priv->rcdev); +} + +static bool rzg2l_cpg_is_pm_clk(const struct of_phandle_args *clkspec) +{ + if (clkspec->args_count != 2) + return false; + + switch (clkspec->args[0]) { + case CPG_MOD: + return true; + + default: + return false; + } +} + +static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device *dev) +{ + struct device_node *np = dev->of_node; + struct of_phandle_args clkspec; + bool once = true; + struct clk *clk; + int error; + int i = 0; + + while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, + &clkspec)) { + if (rzg2l_cpg_is_pm_clk(&clkspec)) { + if (once) { + once = false; + error = pm_clk_create(dev); + if (error) { + of_node_put(clkspec.np); + goto err; + } + } + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + if (IS_ERR(clk)) { + error = PTR_ERR(clk); + goto fail_destroy; + } + + error = pm_clk_add_clk(dev, clk); + if (error) { + dev_err(dev, "pm_clk_add_clk failed %d\n", + error); + goto fail_put; + } + } else { + of_node_put(clkspec.np); + } + i++; + } + + return 0; + +fail_put: + clk_put(clk); + +fail_destroy: + pm_clk_destroy(dev); +err: + return error; +} + +static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev) +{ + if (!pm_clk_no_clocks(dev)) + pm_clk_destroy(dev); +} + +static int __init rzg2l_cpg_add_clk_domain(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct generic_pm_domain *genpd; + + genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL); + if (!genpd) + return -ENOMEM; + + genpd->name = np->name; + genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | + GENPD_FLAG_ACTIVE_WAKEUP; + genpd->attach_dev = rzg2l_cpg_attach_dev; + genpd->detach_dev = rzg2l_cpg_detach_dev; + pm_genpd_init(genpd, &pm_domain_always_on_gov, false); + + of_genpd_add_provider_simple(np, genpd); + return 0; +} + +static int __init rzg2l_cpg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct rzg2l_cpg_info *info; + struct rzg2l_cpg_priv *priv; + unsigned int nclks, i; + struct clk **clks; + int error; + + info = of_device_get_match_data(dev); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->info = info; + spin_lock_init(&priv->rmw_lock); + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + nclks = info->num_total_core_clks + info->num_hw_mod_clks; + clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + priv->clks = clks; + priv->num_core_clks = info->num_total_core_clks; + priv->num_mod_clks = info->num_hw_mod_clks; + priv->num_resets = info->num_resets; + priv->last_dt_core_clk = info->last_dt_core_clk; + + for (i = 0; i < nclks; i++) + clks[i] = ERR_PTR(-ENOENT); + + for (i = 0; i < info->num_core_clks; i++) + rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv); + + for (i = 0; i < info->num_mod_clks; i++) + rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv); + + error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv); + if (error) + return error; + + error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np); + if (error) + return error; + + error = rzg2l_cpg_add_clk_domain(dev); + if (error) + return error; + + error = rzg2l_cpg_reset_controller_register(priv); + if (error) + return error; + + return 0; +} + +static const struct of_device_id rzg2l_cpg_match[] = { +#ifdef CONFIG_CLK_R9A07G044 + { + .compatible = "renesas,r9a07g044-cpg", + .data = &r9a07g044_cpg_info, + }, +#endif + { /* sentinel */ } +}; + +static struct platform_driver rzg2l_cpg_driver = { + .driver = { + .name = "rzg2l-cpg", + .of_match_table = rzg2l_cpg_match, + }, +}; + +static int __init rzg2l_cpg_init(void) +{ + return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe); +} + +subsys_initcall(rzg2l_cpg_init); + +MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h new file mode 100644 index 000000000000..63695280ce8b --- /dev/null +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * RZ/G2L Clock Pulse Generator + * + * Copyright (C) 2021 Renesas Electronics Corp. + * + */ + +#ifndef __RENESAS_RZG2L_CPG_H__ +#define __RENESAS_RZG2L_CPG_H__ + +#define CPG_PL2_DDIV (0x204) +#define CPG_PL3A_DDIV (0x208) + +/* n = 0/1/2 for PLL1/4/6 */ +#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) +#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n)) + +#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12) + +#define DDIV_PACK(offset, bitpos, size) \ + (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) +#define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3) +#define DIVPL3A DDIV_PACK(CPG_PL3A_DDIV, 0, 3) +#define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3) + +/** + * Definitions of CPG Core Clocks + * + * These include: + * - Clock outputs exported to DT + * - External input clocks + * - Internal CPG clocks + */ +struct cpg_core_clk { + const char *name; + unsigned int id; + unsigned int parent; + unsigned int div; + unsigned int mult; + unsigned int type; + unsigned int conf; + const struct clk_div_table *dtable; + const char * const *parent_names; + int flag; + int num_parents; +}; + +enum clk_types { + /* Generic */ + CLK_TYPE_IN, /* External Clock Input */ + CLK_TYPE_FF, /* Fixed Factor Clock */ + CLK_TYPE_SAM_PLL, + + /* Clock with divider */ + CLK_TYPE_DIV, +}; + +#define DEF_TYPE(_name, _id, _type...) \ + { .name = _name, .id = _id, .type = _type } +#define DEF_BASE(_name, _id, _type, _parent...) \ + DEF_TYPE(_name, _id, _type, .parent = _parent) +#define DEF_SAMPLL(_name, _id, _parent, _conf) \ + DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf) +#define DEF_INPUT(_name, _id) \ + DEF_TYPE(_name, _id, CLK_TYPE_IN) +#define DEF_FIXED(_name, _id, _parent, _mult, _div) \ + DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) +#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \ + DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ + .parent = _parent, .dtable = _dtable, .flag = _flag) + +/** + * struct rzg2l_mod_clk - Module Clocks definitions + * + * @name: handle between common and hardware-specific interfaces + * @id: clock index in array containing all Core and Module Clocks + * @parent: id of parent clock + * @off: register offset + * @bit: ON/MON bit + */ +struct rzg2l_mod_clk { + const char *name; + unsigned int id; + unsigned int parent; + u16 off; + u8 bit; +}; + +#define DEF_MOD(_name, _id, _parent, _off, _bit) \ + { \ + .name = _name, \ + .id = MOD_CLK_BASE + (_id), \ + .parent = (_parent), \ + .off = (_off), \ + .bit = (_bit), \ + } + +/** + * struct rzg2l_reset - Reset definitions + * + * @off: register offset + * @bit: reset bit + */ +struct rzg2l_reset { + u16 off; + u8 bit; +}; + +#define DEF_RST(_id, _off, _bit) \ + [_id] = { \ + .off = (_off), \ + .bit = (_bit) \ + } + +/** + * struct rzg2l_cpg_info - SoC-specific CPG Description + * + * @core_clks: Array of Core Clock definitions + * @num_core_clks: Number of entries in core_clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + * @num_total_core_clks: Total number of Core Clocks (exported + internal) + * + * @mod_clks: Array of Module Clock definitions + * @num_mod_clks: Number of entries in mod_clks[] + * @num_hw_mod_clks: Number of Module Clocks supported by the hardware + * + * @crit_mod_clks: Array with Module Clock IDs of critical clocks that + * should not be disabled without a knowledgeable driver + * @num_crit_mod_clks: Number of entries in crit_mod_clks[] + */ +struct rzg2l_cpg_info { + /* Core Clocks */ + const struct cpg_core_clk *core_clks; + unsigned int num_core_clks; + unsigned int last_dt_core_clk; + unsigned int num_total_core_clks; + + /* Module Clocks */ + const struct rzg2l_mod_clk *mod_clks; + unsigned int num_mod_clks; + unsigned int num_hw_mod_clks; + + /* Resets */ + const struct rzg2l_reset *resets; + unsigned int num_resets; + + /* Critical Module Clocks that should not be disabled */ + const unsigned int *crit_mod_clks; + unsigned int num_crit_mod_clks; +}; + +extern const struct rzg2l_cpg_info r9a07g044_cpg_info; + +#endif -- cgit v1.3-14-g43fede From 3b5c734592ade51fed3982bc840a830e066e668e Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 15 Jul 2021 19:21:22 +0100 Subject: clk: renesas: r9a07g044: Add clock and reset entries for CANFD Add clock and reset entries for CANFD in CPG driver. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210715182123.23372-6-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 6a1d9532a690..0c8e07c14a22 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -140,6 +140,8 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x584, 4), DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0, 0x588, 0), + DEF_MOD("canfd", R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0, + 0x594, 0), DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK, 0x598, 0), }; @@ -168,6 +170,8 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3), DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4), DEF_RST(R9A07G044_SCI0_RST, 0x888, 0), + DEF_RST(R9A07G044_CANFD_RSTP_N, 0x894, 0), + DEF_RST(R9A07G044_CANFD_RSTC_N, 0x894, 1), DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0), DEF_RST(R9A07G044_GPIO_PORT_RESETN, 0x898, 1), DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2), -- cgit v1.3-14-g43fede From 1b87d5bba32c1f25a12ba0625546e5375e3f998d Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 19 Jul 2021 09:58:39 +0100 Subject: clk: renesas: r9a07g044: Add clock and reset entries for ADC Add clock and reset entries for ADC block in CPG driver. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210719085840.21842-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 0c8e07c14a22..9e9e8fb6d00d 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -144,6 +144,10 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x594, 0), DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK, 0x598, 0), + DEF_MOD("adc_adclk", R9A07G044_ADC_ADCLK, R9A07G044_CLK_TSU, + 0x5a8, 0), + DEF_MOD("adc_pclk", R9A07G044_ADC_PCLK, R9A07G044_CLK_P0, + 0x5a8, 1), }; static struct rzg2l_reset r9a07g044_resets[] = { @@ -175,6 +179,8 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0), DEF_RST(R9A07G044_GPIO_PORT_RESETN, 0x898, 1), DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2), + DEF_RST(R9A07G044_ADC_PRESETN, 0x8a8, 0), + DEF_RST(R9A07G044_ADC_ADRST_N, 0x8a8, 1), }; static const unsigned int r9a07g044_crit_mod_clks[] __initconst = { -- cgit v1.3-14-g43fede From 0b256c403d4082bafc681143913442288010277c Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 19 Jul 2021 15:38:09 +0100 Subject: dt-bindings: clock: r9a07g044-cpg: Add entry for P0_DIV2 core clock Add P0_DIV2 core clock required for CANFD module. CANFD core clock is sourced from P0_DIV2 referenced from HW manual Rev.0.50. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210719143811.2135-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/r9a07g044-cpg.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/r9a07g044-cpg.h b/include/dt-bindings/clock/r9a07g044-cpg.h index 0728ad07ff7a..0bb17ff1a01a 100644 --- a/include/dt-bindings/clock/r9a07g044-cpg.h +++ b/include/dt-bindings/clock/r9a07g044-cpg.h @@ -30,6 +30,7 @@ #define R9A07G044_CLK_P2 19 #define R9A07G044_CLK_AT 20 #define R9A07G044_OSCCLK 21 +#define R9A07G044_CLK_P0_DIV2 22 /* R9A07G044 Module Clocks */ #define R9A07G044_CA55_SCLK 0 -- cgit v1.3-14-g43fede From d28b1e03dc8d1070538ca3ea3f4e6732109ddf42 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 19 Jul 2021 15:38:10 +0100 Subject: clk: renesas: r9a07g044: Add entry for fixed clock P0_DIV2 Add entry for fixed core clock P0_DIV2 and assign LAST_DT_CORE_CLK to R9A07G044_CLK_P0_DIV2. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210719143811.2135-5-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 9e9e8fb6d00d..4c94b94c4125 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -16,7 +16,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A07G044_OSCCLK, + LAST_DT_CORE_CLK = R9A07G044_CLK_P0_DIV2, /* External Input Clocks */ CLK_EXTAL, @@ -77,6 +77,7 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1), DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), + DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2), DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1), DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), -- cgit v1.3-14-g43fede