From 8c644749ab6e42f51fce82e3325f58ffb70f87b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Tue, 7 Oct 2025 17:03:10 +0100 Subject: [PATCH 001/117] dt-bindings: clock: google,gs101-clock: add power-domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CMU can be part of a power domain, so we need to allow the relevant property 'power-domains'. Signed-off-by: AndrĂ© Draszik Acked-by: Rob Herring (Arm) Reviewed-by: Peter Griffin Signed-off-by: Krzysztof Kozlowski --- .../devicetree/bindings/clock/google,gs101-clock.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml index caf442ead24b..31e106ef913d 100644 --- a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml +++ b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml @@ -46,6 +46,9 @@ properties: "#clock-cells": const: 1 + power-domains: + maxItems: 1 + reg: maxItems: 1 From 4914c17a76047ccbde24397cf9d406558183d756 Mon Sep 17 00:00:00 2001 From: Raghav Sharma Date: Mon, 15 Sep 2025 15:23:59 +0530 Subject: [PATCH 002/117] dt-bindings: clock: exynosautov920: add m2m clock definitions Add device tree clock binding definitions for CMU_M2M Signed-off-by: Raghav Sharma Acked-by: Rob Herring (Arm) Reviewed-by: Alim Akhtar Signed-off-by: Krzysztof Kozlowski --- .../clock/samsung,exynosautov920-clock.yaml | 21 +++++++++++++++++++ .../clock/samsung,exynosautov920.h | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml index 72f59db73f76..b2dfe6ed353a 100644 --- a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml +++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml @@ -38,6 +38,7 @@ properties: - samsung,exynosautov920-cmu-hsi0 - samsung,exynosautov920-cmu-hsi1 - samsung,exynosautov920-cmu-hsi2 + - samsung,exynosautov920-cmu-m2m - samsung,exynosautov920-cmu-misc - samsung,exynosautov920-cmu-peric0 - samsung,exynosautov920-cmu-peric1 @@ -226,6 +227,26 @@ allOf: - const: embd - const: ethernet + - if: + properties: + compatible: + contains: + const: samsung,exynosautov920-cmu-m2m + + then: + properties: + clocks: + items: + - description: External reference clock (38.4 MHz) + - description: CMU_M2M NOC clock (from CMU_TOP) + - description: CMU_M2M JPEG clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: noc + - const: jpeg + required: - compatible - "#clock-cells" diff --git a/include/dt-bindings/clock/samsung,exynosautov920.h b/include/dt-bindings/clock/samsung,exynosautov920.h index 93e6233d1358..0342a988565a 100644 --- a/include/dt-bindings/clock/samsung,exynosautov920.h +++ b/include/dt-bindings/clock/samsung,exynosautov920.h @@ -295,4 +295,9 @@ #define CLK_DOUT_HSI2_ETHERNET 6 #define CLK_DOUT_HSI2_ETHERNET_PTP 7 +/* CMU_M2M */ +#define CLK_MOUT_M2M_JPEG_USER 1 +#define CLK_MOUT_M2M_NOC_USER 2 +#define CLK_DOUT_M2M_NOCP 3 + #endif /* _DT_BINDINGS_CLOCK_EXYNOSAUTOV920_H */ From 0b94201e327471d034d81cf5fd2131a5529eea19 Mon Sep 17 00:00:00 2001 From: Raghav Sharma Date: Thu, 25 Sep 2025 18:34:55 +0530 Subject: [PATCH 003/117] dt-bindings: clock: exynosautov920: add mfc clock definitions Add device tree clock binding definitions for CMU_MFC Signed-off-by: Raghav Sharma Reviewed-by: Krzysztof Kozlowski Signed-off-by: Krzysztof Kozlowski --- .../clock/samsung,exynosautov920-clock.yaml | 21 +++++++++++++++++++ .../clock/samsung,exynosautov920.h | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml index b2dfe6ed353a..5bf905f88a1a 100644 --- a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml +++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml @@ -39,6 +39,7 @@ properties: - samsung,exynosautov920-cmu-hsi1 - samsung,exynosautov920-cmu-hsi2 - samsung,exynosautov920-cmu-m2m + - samsung,exynosautov920-cmu-mfc - samsung,exynosautov920-cmu-misc - samsung,exynosautov920-cmu-peric0 - samsung,exynosautov920-cmu-peric1 @@ -247,6 +248,26 @@ allOf: - const: noc - const: jpeg + - if: + properties: + compatible: + contains: + const: samsung,exynosautov920-cmu-mfc + + then: + properties: + clocks: + items: + - description: External reference clock (38.4 MHz) + - description: CMU_MFC MFC clock (from CMU_TOP) + - description: CMU_MFC WFD clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: mfc + - const: wfd + required: - compatible - "#clock-cells" diff --git a/include/dt-bindings/clock/samsung,exynosautov920.h b/include/dt-bindings/clock/samsung,exynosautov920.h index 0342a988565a..970d05167fc6 100644 --- a/include/dt-bindings/clock/samsung,exynosautov920.h +++ b/include/dt-bindings/clock/samsung,exynosautov920.h @@ -300,4 +300,9 @@ #define CLK_MOUT_M2M_NOC_USER 2 #define CLK_DOUT_M2M_NOCP 3 +/* CMU_MFC */ +#define CLK_MOUT_MFC_MFC_USER 1 +#define CLK_MOUT_MFC_WFD_USER 2 +#define CLK_DOUT_MFC_NOCP 3 + #endif /* _DT_BINDINGS_CLOCK_EXYNOSAUTOV920_H */ From ac5d829873c737edae220ee654e423d383163630 Mon Sep 17 00:00:00 2001 From: Raghav Sharma Date: Mon, 15 Sep 2025 15:24:00 +0530 Subject: [PATCH 004/117] clk: samsung: exynosautov920: add clock support Add support for CMU_M2M which provides clocks to M2M block, and register the required compatible and cmu_info for the same. Signed-off-by: Raghav Sharma Reviewed-by: Alim Akhtar Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-exynosautov920.c | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/clk/samsung/clk-exynosautov920.c b/drivers/clk/samsung/clk-exynosautov920.c index 572b6ace14ac..75deec8bece5 100644 --- a/drivers/clk/samsung/clk-exynosautov920.c +++ b/drivers/clk/samsung/clk-exynosautov920.c @@ -27,6 +27,7 @@ #define CLKS_NR_HSI0 (CLK_DOUT_HSI0_PCIE_APB + 1) #define CLKS_NR_HSI1 (CLK_MOUT_HSI1_USBDRD + 1) #define CLKS_NR_HSI2 (CLK_DOUT_HSI2_ETHERNET_PTP + 1) +#define CLKS_NR_M2M (CLK_DOUT_M2M_NOCP + 1) /* ---- CMU_TOP ------------------------------------------------------------ */ @@ -1821,6 +1822,47 @@ static const struct samsung_cmu_info hsi2_cmu_info __initconst = { .clk_name = "noc", }; +/* ---- CMU_M2M --------------------------------------------------------- */ + +/* Register Offset definitions for CMU_M2M (0x1a800000) */ +#define PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER 0x600 +#define PLL_CON0_MUX_CLKCMU_M2M_NOC_USER 0x610 +#define CLK_CON_DIV_DIV_CLK_M2M_NOCP 0x1800 + +static const unsigned long m2m_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER, + PLL_CON0_MUX_CLKCMU_M2M_NOC_USER, + CLK_CON_DIV_DIV_CLK_M2M_NOCP, +}; + +/* List of parent clocks for Muxes in CMU_M2M */ +PNAME(mout_clkcmu_m2m_noc_user_p) = { "oscclk", "dout_clkcmu_m2m_noc" }; +PNAME(mout_clkcmu_m2m_jpeg_user_p) = { "oscclk", "dout_clkcmu_m2m_jpeg" }; + +static const struct samsung_mux_clock m2m_mux_clks[] __initconst = { + MUX(CLK_MOUT_M2M_JPEG_USER, "mout_clkcmu_m2m_jpeg_user", + mout_clkcmu_m2m_jpeg_user_p, PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER, 4, 1), + MUX(CLK_MOUT_M2M_NOC_USER, "mout_clkcmu_m2m_noc_user", + mout_clkcmu_m2m_noc_user_p, PLL_CON0_MUX_CLKCMU_M2M_NOC_USER, 4, 1), +}; + +static const struct samsung_div_clock m2m_div_clks[] __initconst = { + DIV(CLK_DOUT_M2M_NOCP, "dout_m2m_nocp", + "mout_clkcmu_m2m_noc_user", CLK_CON_DIV_DIV_CLK_M2M_NOCP, + 0, 3), +}; + +static const struct samsung_cmu_info m2m_cmu_info __initconst = { + .mux_clks = m2m_mux_clks, + .nr_mux_clks = ARRAY_SIZE(m2m_mux_clks), + .div_clks = m2m_div_clks, + .nr_div_clks = ARRAY_SIZE(m2m_div_clks), + .nr_clk_ids = CLKS_NR_M2M, + .clk_regs = m2m_clk_regs, + .nr_clk_regs = ARRAY_SIZE(m2m_clk_regs), + .clk_name = "noc", +}; + static int __init exynosautov920_cmu_probe(struct platform_device *pdev) { const struct samsung_cmu_info *info; @@ -1851,6 +1893,9 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { }, { .compatible = "samsung,exynosautov920-cmu-hsi2", .data = &hsi2_cmu_info, + }, { + .compatible = "samsung,exynosautov920-cmu-m2m", + .data = &m2m_cmu_info, }, { } }; From 25e476632cf7135aba11b27e3807a2692a3e5e13 Mon Sep 17 00:00:00 2001 From: Raghav Sharma Date: Thu, 25 Sep 2025 18:34:56 +0530 Subject: [PATCH 005/117] clk: samsung: exynosautov920: add block mfc clock support Add support for CMU_MFC which provides clocks to MFC block, and register the required compatible and cmu_info for the same. Signed-off-by: Raghav Sharma Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-exynosautov920.c | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/clk/samsung/clk-exynosautov920.c b/drivers/clk/samsung/clk-exynosautov920.c index 75deec8bece5..b90b73c3518f 100644 --- a/drivers/clk/samsung/clk-exynosautov920.c +++ b/drivers/clk/samsung/clk-exynosautov920.c @@ -28,6 +28,7 @@ #define CLKS_NR_HSI1 (CLK_MOUT_HSI1_USBDRD + 1) #define CLKS_NR_HSI2 (CLK_DOUT_HSI2_ETHERNET_PTP + 1) #define CLKS_NR_M2M (CLK_DOUT_M2M_NOCP + 1) +#define CLKS_NR_MFC (CLK_DOUT_MFC_NOCP + 1) /* ---- CMU_TOP ------------------------------------------------------------ */ @@ -1863,6 +1864,47 @@ static const struct samsung_cmu_info m2m_cmu_info __initconst = { .clk_name = "noc", }; +/* ---- CMU_MFC --------------------------------------------------------- */ + +/* Register Offset definitions for CMU_MFC (0x19c00000) */ +#define PLL_CON0_MUX_CLKCMU_MFC_MFC_USER 0x600 +#define PLL_CON0_MUX_CLKCMU_MFC_WFD_USER 0x610 +#define CLK_CON_DIV_DIV_CLK_MFC_NOCP 0x1800 + +static const unsigned long mfc_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_MFC_MFC_USER, + PLL_CON0_MUX_CLKCMU_MFC_WFD_USER, + CLK_CON_DIV_DIV_CLK_MFC_NOCP, +}; + +/* List of parent clocks for Muxes in CMU_MFC */ +PNAME(mout_clkcmu_mfc_mfc_user_p) = { "oscclk", "dout_clkcmu_mfc_mfc" }; +PNAME(mout_clkcmu_mfc_wfd_user_p) = { "oscclk", "dout_clkcmu_mfc_wfd" }; + +static const struct samsung_mux_clock mfc_mux_clks[] __initconst = { + MUX(CLK_MOUT_MFC_MFC_USER, "mout_clkcmu_mfc_mfc_user", + mout_clkcmu_mfc_mfc_user_p, PLL_CON0_MUX_CLKCMU_MFC_MFC_USER, 4, 1), + MUX(CLK_MOUT_MFC_WFD_USER, "mout_clkcmu_mfc_wfd_user", + mout_clkcmu_mfc_wfd_user_p, PLL_CON0_MUX_CLKCMU_MFC_WFD_USER, 4, 1), +}; + +static const struct samsung_div_clock mfc_div_clks[] __initconst = { + DIV(CLK_DOUT_MFC_NOCP, "dout_mfc_nocp", + "mout_clkcmu_mfc_mfc_user", CLK_CON_DIV_DIV_CLK_MFC_NOCP, + 0, 3), +}; + +static const struct samsung_cmu_info mfc_cmu_info __initconst = { + .mux_clks = mfc_mux_clks, + .nr_mux_clks = ARRAY_SIZE(mfc_mux_clks), + .div_clks = mfc_div_clks, + .nr_div_clks = ARRAY_SIZE(mfc_div_clks), + .nr_clk_ids = CLKS_NR_MFC, + .clk_regs = mfc_clk_regs, + .nr_clk_regs = ARRAY_SIZE(mfc_clk_regs), + .clk_name = "noc", +}; + static int __init exynosautov920_cmu_probe(struct platform_device *pdev) { const struct samsung_cmu_info *info; @@ -1896,6 +1938,9 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { }, { .compatible = "samsung,exynosautov920-cmu-m2m", .data = &m2m_cmu_info, + }, { + .compatible = "samsung,exynosautov920-cmu-mfc", + .data = &mfc_cmu_info, }, { } }; From 62abfd7bedc2b3d86d4209a4146f9d2b5ae21fab Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 18 Sep 2025 05:04:43 +0200 Subject: [PATCH 006/117] clk: renesas: cpg-mssr: Add missing 1ms delay into reset toggle callback R-Car V4H Reference Manual R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 page 583 Figure 9.3.1(a) Software Reset flow (A) as well as flow (B) / (C) indicate after reset has been asserted by writing a matching reset bit into register SRCR, it is mandatory to wait 1ms. This 1ms delay is documented on R-Car V4H and V4M, it is currently unclear whether S4 is affected as well. This patch does apply the extra delay on R-Car S4 as well. Fix the reset driver to respect the additional delay when toggling resets. Drivers which use separate reset_control_(de)assert() must assure matching delay in their driver code. Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") Signed-off-by: Marek Vasut Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20250918030552.331389-1-marek.vasut+renesas@mailbox.org Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index de1cf7ba45b7..7063d896249e 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -689,8 +689,15 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, /* Reset module */ writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); - /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ - udelay(35); + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. + * On older SoCs, delay after SRCR has been written is 35us + * (one cycle of the RCLK clock @ ca. 32 kHz). + */ + if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) + usleep_range(1000, 2000); + else + usleep_range(35, 1000); /* Release module from reset state */ writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); From b91401af6c00ffab003698bfabd4c166df30748b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 22 Sep 2025 18:20:38 +0200 Subject: [PATCH 007/117] clk: renesas: cpg-mssr: Read back reset registers to assure values latched On R-Car V4H, the PCIEC controller DBI read would generate an SError in case the controller reset is released by writing SRSTCLR register first, and immediately afterward reading some PCIEC controller DBI register. The issue triggers in rcar_gen4_pcie_additional_common_init() on dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW), which on V4H is the first read after reset_control_deassert(dw->core_rsts[DW_PCIE_PWR_RST].rstc). The reset controller which contains the SRSTCLR register and the PCIEC controller which contains the DBI register share the same root access bus, but the bus then splits into separate segments before reaching each IP. Even if the SRSTCLR write access was posted on the bus before the DBI read access, it seems the DBI read access may reach the PCIEC controller before the SRSTCLR write completed, and trigger the SError. Mitigate the issue by adding a dummy SRSTCLR read, which assures the SRSTCLR write completes fully and is latched into the reset controller, before the PCIEC DBI read access can occur. Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") Reviewed-by: Wolfram Sang Tested-by: Geert Uytterhoeven Signed-off-by: Marek Vasut Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20250922162113.113223-1-marek.vasut+renesas@mailbox.org Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 46 ++++++++++++-------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 7063d896249e..a0a68ec0490f 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -676,18 +676,32 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, #define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev) -static int cpg_mssr_reset(struct reset_controller_dev *rcdev, - unsigned long id) +static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev, + const char *func, bool set, unsigned long id) { struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); unsigned int reg = id / 32; unsigned int bit = id % 32; + const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg]; u32 bitmask = BIT(bit); - dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); + if (func) + dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit); + + writel(bitmask, priv->pub.base0 + off); + readl(priv->pub.base0 + off); + barrier_data(priv->pub.base0 + off); + + return 0; +} + +static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); /* Reset module */ - writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + cpg_mssr_reset_operate(rcdev, "reset", true, id); /* * On R-Car Gen4, delay after SRCR has been written is 1ms. @@ -700,36 +714,18 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, usleep_range(35, 1000); /* Release module from reset state */ - writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); - - return 0; + return cpg_mssr_reset_operate(rcdev, NULL, false, id); } static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) { - struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); - unsigned int reg = id / 32; - unsigned int bit = id % 32; - u32 bitmask = BIT(bit); - - dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); - - writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); - return 0; + return cpg_mssr_reset_operate(rcdev, "assert", true, id); } static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, unsigned long id) { - struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); - unsigned int reg = id / 32; - unsigned int bit = id % 32; - u32 bitmask = BIT(bit); - - dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); - - writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); - return 0; + return cpg_mssr_reset_operate(rcdev, "deassert", false, id); } static int cpg_mssr_status(struct reset_controller_dev *rcdev, From ba1ec92ccfe22c93afd5b20e2176e290d268381b Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Tue, 23 Sep 2025 19:05:15 +0300 Subject: [PATCH 008/117] clk: renesas: r9a09g077: Add ADC module clocks Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have three 12-bit ADC peripherals, each with their own peripheral clock. For conversion, they use the PCLKL clock. Add their clocks to the list of module clocks. Signed-off-by: Cosmin Tanislav Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20250923160524.1096720-2-cosmin-gabriel.tanislav.xa@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index af3ef6d58c87..4ec6c4ddc5f5 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -188,6 +188,9 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("sci4fck", 12, CLK_SCI4ASYNC), DEF_MOD("iic0", 100, R9A09G077_CLK_PCLKL), DEF_MOD("iic1", 101, R9A09G077_CLK_PCLKL), + DEF_MOD("adc0", 206, R9A09G077_CLK_PCLKH), + DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH), + DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM), DEF_MOD("gmac0", 400, R9A09G077_CLK_PCLKM), DEF_MOD("ethsw", 401, R9A09G077_CLK_PCLKM), DEF_MOD("ethss", 403, R9A09G077_CLK_PCLKM), From 06e6ea35e9886cf2f5997d3a27d49351511af18e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 24 Sep 2025 15:03:09 +0200 Subject: [PATCH 009/117] clk: renesas: cpg-lib: Remove unneeded semicolon Semicolons after end of function braces are not needed, remove them. Signed-off-by: Geert Uytterhoeven Link: https://patch.msgid.link/deb1537b5f96d991332db5c8088bae705f7e17e3.1758718886.git.geert+renesas@glider.be --- drivers/clk/renesas/rcar-cpg-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c index a45f8e7e9ab6..7b271de7037a 100644 --- a/drivers/clk/renesas/rcar-cpg-lib.c +++ b/drivers/clk/renesas/rcar-cpg-lib.c @@ -35,7 +35,7 @@ void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set) val |= set; writel(val, reg); spin_unlock_irqrestore(&cpg_lock, flags); -}; +} static int cpg_simple_notifier_call(struct notifier_block *nb, unsigned long action, void *data) From c510368bce39cbaf4cb66f4acf788f5efa8692a6 Mon Sep 17 00:00:00 2001 From: Tommaso Merciai Date: Wed, 1 Oct 2025 23:26:52 +0200 Subject: [PATCH 010/117] dt-bindings: clock: renesas,r9a09g047-cpg: Add USB2 PHY core clocks Add definitions for USB2 PHY core clocks in the R9A09G047 CPG DT bindings header file. Signed-off-by: Tommaso Merciai Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251001212709.579080-9-tommaso.merciai.xr@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/renesas,r9a09g047-cpg.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/clock/renesas,r9a09g047-cpg.h b/include/dt-bindings/clock/renesas,r9a09g047-cpg.h index f165df8a6f5a..dab24740de3c 100644 --- a/include/dt-bindings/clock/renesas,r9a09g047-cpg.h +++ b/include/dt-bindings/clock/renesas,r9a09g047-cpg.h @@ -22,5 +22,7 @@ #define R9A09G047_GBETH_1_CLK_PTP_REF_I 11 #define R9A09G047_USB3_0_REF_ALT_CLK_P 12 #define R9A09G047_USB3_0_CLKCORE 13 +#define R9A09G047_USB2_0_CLK_CORE0 14 +#define R9A09G047_USB2_0_CLK_CORE1 15 #endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G047_CPG_H__ */ From 6a636d203cc8d29ae73116bbca8b0ea2c7a90d7f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 25 Sep 2025 11:53:24 +0200 Subject: [PATCH 011/117] clk: renesas: Use IS_ERR() for pointers that cannot be NULL The use of IS_ERR_OR_NULL() suggests that "clk" can be a NULL pointer. Hence smatch assumes so, and issues a "passing zero to 'PTR_ERR'" warning. At these checkpoints, "clk" always contains either a valid pointer, or an error pointer (none of the functions called return NULL pointers). Hence replace IS_ERR_OR_NULL() by IS_ERR(). Reported-by: kernel test robot Reported-by: Dan Carpenter Closes: https://lore.kernel.org/r/202408032025.ve2JMaoV-lkp@intel.com/ Signed-off-by: Geert Uytterhoeven Reviewed-by: Lad Prabhakar Link: https://patch.msgid.link/81260328acb5c78e915ab04afad3901a31c16128.1758793709.git.geert+renesas@glider.be --- drivers/clk/renesas/renesas-cpg-mssr.c | 2 +- drivers/clk/renesas/rzg2l-cpg.c | 2 +- drivers/clk/renesas/rzv2h-cpg.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index a0a68ec0490f..a3d171ddaab9 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -451,7 +451,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, break; } - if (IS_ERR_OR_NULL(clk)) + if (IS_ERR(clk)) goto fail; dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 07909e80bae2..64d1ef6e4c94 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -1177,7 +1177,7 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, goto fail; } - if (IS_ERR_OR_NULL(clk)) + if (IS_ERR(clk)) goto fail; dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 2197d1d2453a..ff688dc88ba3 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -591,7 +591,7 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core, goto fail; } - if (IS_ERR_OR_NULL(clk)) + if (IS_ERR(clk)) goto fail; dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); From e43b186df5c4635059f6213d100c9314c1570d02 Mon Sep 17 00:00:00 2001 From: Tommaso Merciai Date: Wed, 1 Oct 2025 23:26:53 +0200 Subject: [PATCH 012/117] clk: renesas: r9a09g047: Add clock and reset entries for USB2 Add clock and reset entries for USB2. Signed-off-by: Tommaso Merciai Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251001212709.579080-10-tommaso.merciai.xr@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g047-cpg.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a09g047-cpg.c b/drivers/clk/renesas/r9a09g047-cpg.c index ef115f9ec0e6..68f8b08bd16f 100644 --- a/drivers/clk/renesas/r9a09g047-cpg.c +++ b/drivers/clk/renesas/r9a09g047-cpg.c @@ -16,7 +16,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G047_USB3_0_CLKCORE, + LAST_DT_CORE_CLK = R9A09G047_USB2_0_CLK_CORE1, /* External Input Clocks */ CLK_AUDIO_EXTAL, @@ -177,6 +177,8 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { CDDIV1_DIVCTL3, dtable_1_8), DEF_FIXED("iotop_0_shclk", R9A09G047_IOTOP_0_SHCLK, CLK_PLLCM33_DIV16, 1, 1), DEF_FIXED("spi_clk_spi", R9A09G047_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2), + DEF_FIXED("usb2_0_clk_core0", R9A09G047_USB2_0_CLK_CORE0, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb2_0_clk_core1", R9A09G047_USB2_0_CLK_CORE1, CLK_QEXTAL, 1, 1), DEF_FIXED("gbeth_0_clk_ptp_ref_i", R9A09G047_GBETH_0_CLK_PTP_REF_I, CLK_PLLETH_DIV_125_FIX, 1, 1), DEF_FIXED("gbeth_1_clk_ptp_ref_i", R9A09G047_GBETH_1_CLK_PTP_REF_I, @@ -282,6 +284,16 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { BUS_MSTOP(7, BIT(12))), DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16, BUS_MSTOP(7, BIT(14))), + DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19, + BUS_MSTOP(7, BIT(7))), + DEF_MOD("usb2_0_u2h1_hclk", CLK_PLLDTY_DIV8, 11, 4, 5, 20, + BUS_MSTOP(7, BIT(8))), + DEF_MOD("usb2_0_u2p_exr_cpuclk", CLK_PLLDTY_ACPU_DIV4, 11, 5, 5, 21, + BUS_MSTOP(7, BIT(9))), + DEF_MOD("usb2_0_pclk_usbtst0", CLK_PLLDTY_ACPU_DIV4, 11, 6, 5, 22, + BUS_MSTOP(7, BIT(10))), + DEF_MOD("usb2_0_pclk_usbtst1", CLK_PLLDTY_ACPU_DIV4, 11, 7, 5, 23, + BUS_MSTOP(7, BIT(11))), DEF_MOD_MUX_EXTERNAL("gbeth_0_clk_tx_i", CLK_SMUX2_GBE0_TXCLK, 11, 8, 5, 24, BUS_MSTOP(8, BIT(5)), 1), DEF_MOD_MUX_EXTERNAL("gbeth_0_clk_rx_i", CLK_SMUX2_GBE0_RXCLK, 11, 9, 5, 25, @@ -359,6 +371,10 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = { DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */ DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */ DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */ + DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */ + DEF_RST(10, 13, 4, 30), /* USB2_0_U2H1_HRESETN */ + DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */ + DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */ DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */ DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */ DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */ From 0f537c41831aea18e54d889350e706e221beda63 Mon Sep 17 00:00:00 2001 From: Daniel Scally Date: Fri, 10 Oct 2025 10:43:10 +0100 Subject: [PATCH 013/117] clk: renesas: r9a09g057: Add clock and reset entries for ISP Add entries detailing the clocks and resets for the ISP in the RZ/V2H(P) SoC. Signed-off-by: Daniel Scally Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251010-rzv2h_isp_clk-v2-1-2c8853a9af7c@ideasonboard.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g057-cpg.c | 14 ++++++++++++++ drivers/clk/renesas/rzv2h-cpg.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index 6389c4b6a523..c9c117c6782c 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -55,6 +55,7 @@ enum clk_ids { CLK_PLLVDO_CRU1, CLK_PLLVDO_CRU2, CLK_PLLVDO_CRU3, + CLK_PLLVDO_ISP, CLK_PLLETH_DIV_250_FIX, CLK_PLLETH_DIV_125_FIX, CLK_CSDIV_PLLETH_GBE0, @@ -157,6 +158,7 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4), DEF_DDIV(".pllvdo_cru2", CLK_PLLVDO_CRU2, CLK_PLLVDO, CDDIV4_DIVCTL1, dtable_2_4), DEF_DDIV(".pllvdo_cru3", CLK_PLLVDO_CRU3, CLK_PLLVDO, CDDIV4_DIVCTL2, dtable_2_4), + DEF_DDIV(".pllvdo_isp", CLK_PLLVDO_ISP, CLK_PLLVDO, CDDIV2_DIVCTL3, dtable_2_64), DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4), DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2), @@ -371,6 +373,14 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(9, BIT(7))), DEF_MOD("cru_3_pclk", CLK_PLLDTY_DIV16, 13, 13, 6, 29, BUS_MSTOP(9, BIT(7))), + DEF_MOD("isp_0_reg_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 2, 7, 2, + BUS_MSTOP(9, BIT(8))), + DEF_MOD("isp_0_pclk", CLK_PLLDTY_DIV16, 14, 3, 7, 3, + BUS_MSTOP(9, BIT(8))), + DEF_MOD("isp_0_vin_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 4, 7, 4, + BUS_MSTOP(9, BIT(9))), + DEF_MOD("isp_0_isp_sclk", CLK_PLLVDO_ISP, 14, 5, 7, 5, + BUS_MSTOP(9, BIT(9))), DEF_MOD("gpu_0_clk", CLK_PLLGPU_GEAR, 15, 0, 7, 16, BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17, @@ -442,6 +452,10 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(12, 14, 5, 31), /* CRU_3_PRESETN */ DEF_RST(12, 15, 6, 0), /* CRU_3_ARESETN */ DEF_RST(13, 0, 6, 1), /* CRU_3_S_RESETN */ + DEF_RST(13, 1, 6, 2), /* ISP_0_VIN_ARESETN */ + DEF_RST(13, 2, 6, 3), /* ISP_0_REG_ARESETN */ + DEF_RST(13, 3, 6, 4), /* ISP_0_ISP_SRESETN */ + DEF_RST(13, 4, 6, 5), /* ISP_0_PRESETN */ DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */ DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */ diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h index 840eed25aeda..e020d9624dfd 100644 --- a/drivers/clk/renesas/rzv2h-cpg.h +++ b/drivers/clk/renesas/rzv2h-cpg.h @@ -115,6 +115,7 @@ struct fixed_mod_conf { #define CPG_SSEL1 (0x304) #define CPG_CDDIV0 (0x400) #define CPG_CDDIV1 (0x404) +#define CPG_CDDIV2 (0x408) #define CPG_CDDIV3 (0x40C) #define CPG_CDDIV4 (0x410) #define CPG_CSDIV0 (0x500) @@ -125,6 +126,7 @@ struct fixed_mod_conf { #define CDDIV1_DIVCTL1 DDIV_PACK(CPG_CDDIV1, 4, 2, 5) #define CDDIV1_DIVCTL2 DDIV_PACK(CPG_CDDIV1, 8, 2, 6) #define CDDIV1_DIVCTL3 DDIV_PACK(CPG_CDDIV1, 12, 2, 7) +#define CDDIV2_DIVCTL3 DDIV_PACK(CPG_CDDIV2, 12, 3, 11) #define CDDIV3_DIVCTL1 DDIV_PACK(CPG_CDDIV3, 4, 3, 13) #define CDDIV3_DIVCTL2 DDIV_PACK(CPG_CDDIV3, 8, 3, 14) #define CDDIV3_DIVCTL3 DDIV_PACK(CPG_CDDIV3, 12, 1, 15) From 8abe970efea56f44773713cf91032cd2fd4d8c01 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 3 Oct 2025 20:14:39 +0200 Subject: [PATCH 014/117] clk: qcom: gcc-x1e80100: Add missing USB4 clocks/resets Currently, some of the USB4 clocks/resets are described, but not all of the back-end muxes are present. Configuring them properly is necessary for proper operation of the hardware. Add all the resets & muxes and wire up any unaccounted USB4 clock paths. Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") Reviewed-by: Bryan O'Donoghue Signed-off-by: Konrad Dybcio Reviewed-by: Taniya Das Reviewed-by: Abel Vesa Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251003-topic-hamoa_gcc_usb4-v2-2-61d27a14ee65@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-x1e80100.c | 698 +++++++++++++++++++++++++++++++- 1 file changed, 681 insertions(+), 17 deletions(-) diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index 301fc9fc32d8..8804ad5d70be 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -32,6 +32,33 @@ enum { DT_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE, DT_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE, DT_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE, + DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_QUSB4PHY_0_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_0_GCC_USB4_RX1_CLK, + DT_QUSB4PHY_1_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_1_GCC_USB4_RX1_CLK, + DT_QUSB4PHY_2_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_2_GCC_USB4_RX1_CLK, + DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, }; enum { @@ -42,10 +69,40 @@ enum { P_GCC_GPLL7_OUT_MAIN, P_GCC_GPLL8_OUT_MAIN, P_GCC_GPLL9_OUT_MAIN, + P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, + P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, + P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, + P_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, + P_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, + P_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC, + P_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC, + P_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, + P_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, + P_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, + P_QUSB4PHY_0_GCC_USB4_RX0_CLK, + P_QUSB4PHY_0_GCC_USB4_RX1_CLK, + P_QUSB4PHY_1_GCC_USB4_RX0_CLK, + P_QUSB4PHY_1_GCC_USB4_RX1_CLK, + P_QUSB4PHY_2_GCC_USB4_RX0_CLK, + P_QUSB4PHY_2_GCC_USB4_RX1_CLK, P_SLEEP_CLK, P_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE_CLK, P_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE_CLK, P_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, }; static struct clk_alpha_pll gcc_gpll0 = { @@ -320,6 +377,342 @@ static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { { } }; +static const struct clk_parent_data gcc_parent_data_13[] = { + { .index = DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_14[] = { + { .index = DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_15[] = { + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_16[] = { + { .index = DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_17[] = { + { .index = DT_QUSB4PHY_0_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_18[] = { + { .index = DT_QUSB4PHY_0_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_19[] = { + { .index = DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_20[] = { + { .index = DT_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_21[] = { + { .index = DT_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_22[] = { + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_23[] = { + { .index = DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_24[] = { + { .index = DT_QUSB4PHY_1_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_25[] = { + { .index = DT_QUSB4PHY_1_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_26[] = { + { .index = DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_27[] = { + { .index = DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_28[] = { + { .index = DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_29[] = { + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_30[] = { + { .index = DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct clk_parent_data gcc_parent_data_31[] = { + { .index = DT_QUSB4PHY_2_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_32[] = { + { .index = DT_QUSB4PHY_2_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data gcc_parent_data_33[] = { + { .index = DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp0_clk_src = { + .reg = 0x9f06c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_dp0_clk_src", + .parent_data = gcc_parent_data_13, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp1_clk_src = { + .reg = 0x9f114, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_dp1_clk_src", + .parent_data = gcc_parent_data_14, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_p2rr2p_pipe_clk_src = { + .reg = 0x9f0d4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_15, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_pcie_pipe_mux_clk_src = { + .reg = 0x9f104, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_16, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_rx0_clk_src = { + .reg = 0x9f0ac, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx0_clk_src", + .parent_data = gcc_parent_data_17, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_rx1_clk_src = { + .reg = 0x9f0bc, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx1_clk_src", + .parent_data = gcc_parent_data_18, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_0_phy_sys_clk_src = { + .reg = 0x9f0e4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_sys_clk_src", + .parent_data = gcc_parent_data_19, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_dp0_clk_src = { + .reg = 0x2b06c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_dp0_clk_src", + .parent_data = gcc_parent_data_20, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_dp1_clk_src = { + .reg = 0x2b114, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_dp1_clk_src", + .parent_data = gcc_parent_data_21, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_p2rr2p_pipe_clk_src = { + .reg = 0x2b0d4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_22, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_pcie_pipe_mux_clk_src = { + .reg = 0x2b104, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_23, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_rx0_clk_src = { + .reg = 0x2b0ac, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx0_clk_src", + .parent_data = gcc_parent_data_24, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_rx1_clk_src = { + .reg = 0x2b0bc, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx1_clk_src", + .parent_data = gcc_parent_data_25, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_1_phy_sys_clk_src = { + .reg = 0x2b0e4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_sys_clk_src", + .parent_data = gcc_parent_data_26, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_dp0_clk_src = { + .reg = 0x1106c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_dp0_clk_src", + .parent_data = gcc_parent_data_27, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_dp1_clk_src = { + .reg = 0x11114, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_dp1_clk_src", + .parent_data = gcc_parent_data_28, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_p2rr2p_pipe_clk_src = { + .reg = 0x110d4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_29, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_pcie_pipe_mux_clk_src = { + .reg = 0x11104, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_30, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_rx0_clk_src = { + .reg = 0x110ac, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx0_clk_src", + .parent_data = gcc_parent_data_31, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_rx1_clk_src = { + .reg = 0x110bc, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx1_clk_src", + .parent_data = gcc_parent_data_32, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb4_2_phy_sys_clk_src = { + .reg = 0x110e4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_sys_clk_src", + .parent_data = gcc_parent_data_33, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + static struct clk_rcg2 gcc_gp1_clk_src = { .cmd_rcgr = 0x64004, .mnd_width = 16, @@ -2790,6 +3183,11 @@ static struct clk_branch gcc_pcie_0_pipe_clk = { .enable_mask = BIT(25), .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -2879,6 +3277,11 @@ static struct clk_branch gcc_pcie_1_pipe_clk = { .enable_mask = BIT(30), .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_1_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -2968,6 +3371,11 @@ static struct clk_branch gcc_pcie_2_pipe_clk = { .enable_mask = BIT(23), .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_2_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5156,6 +5564,33 @@ static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { }, }; +static const struct parent_map gcc_parent_map_34[] = { + { P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_34[] = { + { .hw = &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .index = DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC }, +}; + +static struct clk_regmap_mux gcc_usb34_prim_phy_pipe_clk_src = { + .reg = 0x39070, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_34, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_prim_phy_pipe_clk_src", + .parent_data = gcc_parent_data_34, + .num_parents = ARRAY_SIZE(gcc_parent_data_34), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .halt_reg = 0x39068, .halt_check = BRANCH_HALT_SKIP, @@ -5167,7 +5602,7 @@ static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_prim_phy_pipe_clk", .parent_hws = (const struct clk_hw*[]) { - &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, + &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -5227,6 +5662,33 @@ static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src = { }, }; +static const struct parent_map gcc_parent_map_35[] = { + { P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_35[] = { + { .hw = &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .index = DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC }, +}; + +static struct clk_regmap_mux gcc_usb34_sec_phy_pipe_clk_src = { + .reg = 0xa1070, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_35, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_sec_phy_pipe_clk_src", + .parent_data = gcc_parent_data_35, + .num_parents = ARRAY_SIZE(gcc_parent_data_35), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { .halt_reg = 0xa1068, .halt_check = BRANCH_HALT_SKIP, @@ -5238,7 +5700,7 @@ static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_sec_phy_pipe_clk", .parent_hws = (const struct clk_hw*[]) { - &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw, + &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -5298,6 +5760,33 @@ static struct clk_regmap_mux gcc_usb3_tert_phy_pipe_clk_src = { }, }; +static const struct parent_map gcc_parent_map_36[] = { + { P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_36[] = { + { .hw = &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .index = DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC }, +}; + +static struct clk_regmap_mux gcc_usb34_tert_phy_pipe_clk_src = { + .reg = 0xa2070, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_36, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_tert_phy_pipe_clk_src", + .parent_data = gcc_parent_data_36, + .num_parents = ARRAY_SIZE(gcc_parent_data_36), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { .halt_reg = 0xa2068, .halt_check = BRANCH_HALT_SKIP, @@ -5309,7 +5798,7 @@ static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_tert_phy_pipe_clk", .parent_hws = (const struct clk_hw*[]) { - &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw, + &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -5335,12 +5824,17 @@ static struct clk_branch gcc_usb4_0_cfg_ahb_clk = { static struct clk_branch gcc_usb4_0_dp0_clk = { .halt_reg = 0x9f060, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f060, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5348,12 +5842,17 @@ static struct clk_branch gcc_usb4_0_dp0_clk = { static struct clk_branch gcc_usb4_0_dp1_clk = { .halt_reg = 0x9f108, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f108, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5385,6 +5884,11 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5398,6 +5902,11 @@ static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { .enable_mask = BIT(19), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5405,12 +5914,17 @@ static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { static struct clk_branch gcc_usb4_0_phy_rx0_clk = { .halt_reg = 0x9f0b0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f0b0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5418,12 +5932,17 @@ static struct clk_branch gcc_usb4_0_phy_rx0_clk = { static struct clk_branch gcc_usb4_0_phy_rx1_clk = { .halt_reg = 0x9f0c0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f0c0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5439,6 +5958,11 @@ static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5470,6 +5994,11 @@ static struct clk_branch gcc_usb4_0_sys_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_0_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5512,12 +6041,17 @@ static struct clk_branch gcc_usb4_1_cfg_ahb_clk = { static struct clk_branch gcc_usb4_1_dp0_clk = { .halt_reg = 0x2b060, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b060, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5525,12 +6059,17 @@ static struct clk_branch gcc_usb4_1_dp0_clk = { static struct clk_branch gcc_usb4_1_dp1_clk = { .halt_reg = 0x2b108, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b108, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5562,6 +6101,11 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5575,6 +6119,11 @@ static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5582,12 +6131,17 @@ static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { static struct clk_branch gcc_usb4_1_phy_rx0_clk = { .halt_reg = 0x2b0b0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b0b0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5595,12 +6149,17 @@ static struct clk_branch gcc_usb4_1_phy_rx0_clk = { static struct clk_branch gcc_usb4_1_phy_rx1_clk = { .halt_reg = 0x2b0c0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b0c0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5616,6 +6175,11 @@ static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5647,6 +6211,11 @@ static struct clk_branch gcc_usb4_1_sys_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_1_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5689,12 +6258,17 @@ static struct clk_branch gcc_usb4_2_cfg_ahb_clk = { static struct clk_branch gcc_usb4_2_dp0_clk = { .halt_reg = 0x11060, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x11060, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5702,12 +6276,17 @@ static struct clk_branch gcc_usb4_2_dp0_clk = { static struct clk_branch gcc_usb4_2_dp1_clk = { .halt_reg = 0x11108, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x11108, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5739,6 +6318,11 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5752,6 +6336,11 @@ static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { .enable_mask = BIT(1), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5759,12 +6348,17 @@ static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { static struct clk_branch gcc_usb4_2_phy_rx0_clk = { .halt_reg = 0x110b0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x110b0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5772,12 +6366,17 @@ static struct clk_branch gcc_usb4_2_phy_rx0_clk = { static struct clk_branch gcc_usb4_2_phy_rx1_clk = { .halt_reg = 0x110c0, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x110c0, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5793,6 +6392,11 @@ static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_usb4_2_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -6483,6 +7087,9 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB30_TERT_MOCK_UTMI_CLK_SRC] = &gcc_usb30_tert_mock_utmi_clk_src.clkr, [GCC_USB30_TERT_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_tert_mock_utmi_postdiv_clk_src.clkr, [GCC_USB30_TERT_SLEEP_CLK] = &gcc_usb30_tert_sleep_clk.clkr, + [GCC_USB34_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb34_prim_phy_pipe_clk_src.clkr, + [GCC_USB34_SEC_PHY_PIPE_CLK_SRC] = &gcc_usb34_sec_phy_pipe_clk_src.clkr, + [GCC_USB34_TERT_PHY_PIPE_CLK_SRC] = &gcc_usb34_tert_phy_pipe_clk_src.clkr, [GCC_USB3_MP_PHY_AUX_CLK] = &gcc_usb3_mp_phy_aux_clk.clkr, [GCC_USB3_MP_PHY_AUX_CLK_SRC] = &gcc_usb3_mp_phy_aux_clk_src.clkr, [GCC_USB3_MP_PHY_COM_AUX_CLK] = &gcc_usb3_mp_phy_com_aux_clk.clkr, @@ -6508,11 +7115,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_0_DP1_CLK] = &gcc_usb4_0_dp1_clk.clkr, [GCC_USB4_0_MASTER_CLK] = &gcc_usb4_0_master_clk.clkr, [GCC_USB4_0_MASTER_CLK_SRC] = &gcc_usb4_0_master_clk_src.clkr, + [GCC_USB4_0_PHY_DP0_CLK_SRC] = &gcc_usb4_0_phy_dp0_clk_src.clkr, + [GCC_USB4_0_PHY_DP1_CLK_SRC] = &gcc_usb4_0_phy_dp1_clk_src.clkr, [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_0_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr, [GCC_USB4_0_PHY_PCIE_PIPE_CLK] = &gcc_usb4_0_phy_pcie_pipe_clk.clkr, [GCC_USB4_0_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr, [GCC_USB4_0_PHY_RX0_CLK] = &gcc_usb4_0_phy_rx0_clk.clkr, + [GCC_USB4_0_PHY_RX0_CLK_SRC] = &gcc_usb4_0_phy_rx0_clk_src.clkr, [GCC_USB4_0_PHY_RX1_CLK] = &gcc_usb4_0_phy_rx1_clk.clkr, + [GCC_USB4_0_PHY_RX1_CLK_SRC] = &gcc_usb4_0_phy_rx1_clk_src.clkr, + [GCC_USB4_0_PHY_SYS_CLK_SRC] = &gcc_usb4_0_phy_sys_clk_src.clkr, [GCC_USB4_0_PHY_USB_PIPE_CLK] = &gcc_usb4_0_phy_usb_pipe_clk.clkr, [GCC_USB4_0_SB_IF_CLK] = &gcc_usb4_0_sb_if_clk.clkr, [GCC_USB4_0_SB_IF_CLK_SRC] = &gcc_usb4_0_sb_if_clk_src.clkr, @@ -6524,11 +7138,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_1_DP1_CLK] = &gcc_usb4_1_dp1_clk.clkr, [GCC_USB4_1_MASTER_CLK] = &gcc_usb4_1_master_clk.clkr, [GCC_USB4_1_MASTER_CLK_SRC] = &gcc_usb4_1_master_clk_src.clkr, + [GCC_USB4_1_PHY_DP0_CLK_SRC] = &gcc_usb4_1_phy_dp0_clk_src.clkr, + [GCC_USB4_1_PHY_DP1_CLK_SRC] = &gcc_usb4_1_phy_dp1_clk_src.clkr, [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_1_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr, [GCC_USB4_1_PHY_PCIE_PIPE_CLK] = &gcc_usb4_1_phy_pcie_pipe_clk.clkr, [GCC_USB4_1_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr, [GCC_USB4_1_PHY_RX0_CLK] = &gcc_usb4_1_phy_rx0_clk.clkr, + [GCC_USB4_1_PHY_RX0_CLK_SRC] = &gcc_usb4_1_phy_rx0_clk_src.clkr, [GCC_USB4_1_PHY_RX1_CLK] = &gcc_usb4_1_phy_rx1_clk.clkr, + [GCC_USB4_1_PHY_RX1_CLK_SRC] = &gcc_usb4_1_phy_rx1_clk_src.clkr, + [GCC_USB4_1_PHY_SYS_CLK_SRC] = &gcc_usb4_1_phy_sys_clk_src.clkr, [GCC_USB4_1_PHY_USB_PIPE_CLK] = &gcc_usb4_1_phy_usb_pipe_clk.clkr, [GCC_USB4_1_SB_IF_CLK] = &gcc_usb4_1_sb_if_clk.clkr, [GCC_USB4_1_SB_IF_CLK_SRC] = &gcc_usb4_1_sb_if_clk_src.clkr, @@ -6540,11 +7161,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_2_DP1_CLK] = &gcc_usb4_2_dp1_clk.clkr, [GCC_USB4_2_MASTER_CLK] = &gcc_usb4_2_master_clk.clkr, [GCC_USB4_2_MASTER_CLK_SRC] = &gcc_usb4_2_master_clk_src.clkr, + [GCC_USB4_2_PHY_DP0_CLK_SRC] = &gcc_usb4_2_phy_dp0_clk_src.clkr, + [GCC_USB4_2_PHY_DP1_CLK_SRC] = &gcc_usb4_2_phy_dp1_clk_src.clkr, [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_2_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr, [GCC_USB4_2_PHY_PCIE_PIPE_CLK] = &gcc_usb4_2_phy_pcie_pipe_clk.clkr, [GCC_USB4_2_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr, [GCC_USB4_2_PHY_RX0_CLK] = &gcc_usb4_2_phy_rx0_clk.clkr, + [GCC_USB4_2_PHY_RX0_CLK_SRC] = &gcc_usb4_2_phy_rx0_clk_src.clkr, [GCC_USB4_2_PHY_RX1_CLK] = &gcc_usb4_2_phy_rx1_clk.clkr, + [GCC_USB4_2_PHY_RX1_CLK_SRC] = &gcc_usb4_2_phy_rx1_clk_src.clkr, + [GCC_USB4_2_PHY_SYS_CLK_SRC] = &gcc_usb4_2_phy_sys_clk_src.clkr, [GCC_USB4_2_PHY_USB_PIPE_CLK] = &gcc_usb4_2_phy_usb_pipe_clk.clkr, [GCC_USB4_2_SB_IF_CLK] = &gcc_usb4_2_sb_if_clk.clkr, [GCC_USB4_2_SB_IF_CLK_SRC] = &gcc_usb4_2_sb_if_clk_src.clkr, @@ -6660,16 +7288,52 @@ static const struct qcom_reset_map gcc_x1e80100_resets[] = { [GCC_USB3_UNIPHY_MP0_BCR] = { 0x19000 }, [GCC_USB3_UNIPHY_MP1_BCR] = { 0x54000 }, [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB4PHY_PHY_PRIM_BCR] = { 0x5000c }, [GCC_USB3PHY_PHY_SEC_BCR] = { 0x2a004 }, + [GCC_USB4PHY_PHY_SEC_BCR] = { 0x2a00c }, [GCC_USB3PHY_PHY_TERT_BCR] = { 0xa3004 }, + [GCC_USB4PHY_PHY_TERT_BCR] = { 0xa300c }, [GCC_USB3UNIPHY_PHY_MP0_BCR] = { 0x19004 }, [GCC_USB3UNIPHY_PHY_MP1_BCR] = { 0x54004 }, [GCC_USB4_0_BCR] = { 0x9f000 }, [GCC_USB4_0_DP0_PHY_PRIM_BCR] = { 0x50010 }, - [GCC_USB4_1_DP0_PHY_SEC_BCR] = { 0x2a010 }, - [GCC_USB4_2_DP0_PHY_TERT_BCR] = { 0xa3010 }, + [GCC_USB4_0_MISC_USB4_SYS_BCR] = { .reg = 0xad0f8, .bit = 0 }, + [GCC_USB4_0_MISC_RX_CLK_0_BCR] = { .reg = 0xad0f8, .bit = 1 }, + [GCC_USB4_0_MISC_RX_CLK_1_BCR] = { .reg = 0xad0f8, .bit = 2 }, + [GCC_USB4_0_MISC_USB_PIPE_BCR] = { .reg = 0xad0f8, .bit = 3 }, + [GCC_USB4_0_MISC_PCIE_PIPE_BCR] = { .reg = 0xad0f8, .bit = 4 }, + [GCC_USB4_0_MISC_TMU_BCR] = { .reg = 0xad0f8, .bit = 5 }, + [GCC_USB4_0_MISC_SB_IF_BCR] = { .reg = 0xad0f8, .bit = 6 }, + [GCC_USB4_0_MISC_HIA_MSTR_BCR] = { .reg = 0xad0f8, .bit = 7 }, + [GCC_USB4_0_MISC_AHB_BCR] = { .reg = 0xad0f8, .bit = 8 }, + [GCC_USB4_0_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xad0f8, .bit = 9 }, + [GCC_USB4_0_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xad0f8, .bit = 10 }, [GCC_USB4_1_BCR] = { 0x2b000 }, + [GCC_USB4_1_DP0_PHY_SEC_BCR] = { 0x2a010 }, + [GCC_USB4_1_MISC_USB4_SYS_BCR] = { .reg = 0xae0f8, .bit = 0 }, + [GCC_USB4_1_MISC_RX_CLK_0_BCR] = { .reg = 0xae0f8, .bit = 1 }, + [GCC_USB4_1_MISC_RX_CLK_1_BCR] = { .reg = 0xae0f8, .bit = 2 }, + [GCC_USB4_1_MISC_USB_PIPE_BCR] = { .reg = 0xae0f8, .bit = 3 }, + [GCC_USB4_1_MISC_PCIE_PIPE_BCR] = { .reg = 0xae0f8, .bit = 4 }, + [GCC_USB4_1_MISC_TMU_BCR] = { .reg = 0xae0f8, .bit = 5 }, + [GCC_USB4_1_MISC_SB_IF_BCR] = { .reg = 0xae0f8, .bit = 6 }, + [GCC_USB4_1_MISC_HIA_MSTR_BCR] = { .reg = 0xae0f8, .bit = 7 }, + [GCC_USB4_1_MISC_AHB_BCR] = { .reg = 0xae0f8, .bit = 8 }, + [GCC_USB4_1_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xae0f8, .bit = 9 }, + [GCC_USB4_1_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xae0f8, .bit = 10 }, [GCC_USB4_2_BCR] = { 0x11000 }, + [GCC_USB4_2_DP0_PHY_TERT_BCR] = { 0xa3010 }, + [GCC_USB4_2_MISC_USB4_SYS_BCR] = { .reg = 0xaf0f8, .bit = 0 }, + [GCC_USB4_2_MISC_RX_CLK_0_BCR] = { .reg = 0xaf0f8, .bit = 1 }, + [GCC_USB4_2_MISC_RX_CLK_1_BCR] = { .reg = 0xaf0f8, .bit = 2 }, + [GCC_USB4_2_MISC_USB_PIPE_BCR] = { .reg = 0xaf0f8, .bit = 3 }, + [GCC_USB4_2_MISC_PCIE_PIPE_BCR] = { .reg = 0xaf0f8, .bit = 4 }, + [GCC_USB4_2_MISC_TMU_BCR] = { .reg = 0xaf0f8, .bit = 5 }, + [GCC_USB4_2_MISC_SB_IF_BCR] = { .reg = 0xaf0f8, .bit = 6 }, + [GCC_USB4_2_MISC_HIA_MSTR_BCR] = { .reg = 0xaf0f8, .bit = 7 }, + [GCC_USB4_2_MISC_AHB_BCR] = { .reg = 0xaf0f8, .bit = 8 }, + [GCC_USB4_2_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xaf0f8, .bit = 9 }, + [GCC_USB4_2_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xaf0f8, .bit = 10 }, [GCC_USB_0_PHY_BCR] = { 0x50020 }, [GCC_USB_1_PHY_BCR] = { 0x2a020 }, [GCC_USB_2_PHY_BCR] = { 0xa3020 }, From d669ec6be0b1965c67248407d87c848b1b7c12ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Mon, 13 Oct 2025 06:27:16 +0100 Subject: [PATCH 015/117] clk: samsung: clk-pll: simplify samsung_pll_lock_wait() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit readl_relaxed_poll_timeout_atomic() has been updated in 2023 in commit 7349a69cf312 ("iopoll: Do not use timekeeping in read_poll_timeout_atomic()") to avoid usage of timekeeping APIs. It also never used udelay() when no delay was given. With the implementation avoiding timekeeping APIs, and with a caller not passing a delay, the timeout argument simply becomes a loop counter. Therefore the code here can be simplified to unconditionally use readl_relaxed_poll_timeout_atomic(). The difference being the last argument, the timeout (loop counter). Simply adjust it to pass the more generous counter in all cases. This change also allows us to drop all code around the pll_early_timeout variable as it is unused now. Reviewed-by: Sam Protsenko Signed-off-by: AndrĂ© Draszik Link: https://patch.msgid.link/20251013-samsung-clk-pll-simplification-v2-1-b9aab610878c@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-pll.c | 41 +++++++++-------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 7bea7be1d7e4..0a8fc9649ae2 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -11,14 +11,12 @@ #include #include #include -#include #include #include #include "clk.h" #include "clk-pll.h" -#define PLL_TIMEOUT_US 20000U -#define PLL_TIMEOUT_LOOPS 1000000U +#define PLL_TIMEOUT_LOOPS 20000U struct samsung_clk_pll { struct clk_hw hw; @@ -71,20 +69,11 @@ static int samsung_pll_determine_rate(struct clk_hw *hw, return 0; } -static bool pll_early_timeout = true; - -static int __init samsung_pll_disable_early_timeout(void) -{ - pll_early_timeout = false; - return 0; -} -arch_initcall(samsung_pll_disable_early_timeout); - /* Wait until the PLL is locked */ static int samsung_pll_lock_wait(struct samsung_clk_pll *pll, unsigned int reg_mask) { - int i, ret; + int ret; u32 val; /* @@ -93,25 +82,15 @@ static int samsung_pll_lock_wait(struct samsung_clk_pll *pll, * initialized, another when the timekeeping is suspended. udelay() also * cannot be used when the clocksource is not running on arm64, since * the current timer is used as cycle counter. So a simple busy loop - * is used here in that special cases. The limit of iterations has been - * derived from experimental measurements of various PLLs on multiple - * Exynos SoC variants. Single register read time was usually in range - * 0.4...1.5 us, never less than 0.4 us. + * is used here. + * The limit of iterations has been derived from experimental + * measurements of various PLLs on multiple Exynos SoC variants. Single + * register read time was usually in range 0.4...1.5 us, never less than + * 0.4 us. */ - if (pll_early_timeout || timekeeping_suspended) { - i = PLL_TIMEOUT_LOOPS; - while (i-- > 0) { - if (readl_relaxed(pll->con_reg) & reg_mask) - return 0; - - cpu_relax(); - } - ret = -ETIMEDOUT; - } else { - ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val, - val & reg_mask, 0, PLL_TIMEOUT_US); - } - + ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val, + val & reg_mask, 0, + PLL_TIMEOUT_LOOPS); if (ret < 0) pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw)); From 84a222d1b369ba83f8947948670f775367e653f1 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 10 Oct 2025 12:46:32 +0000 Subject: [PATCH 016/117] firmware: exynos-acpm: add DVFS protocol Add ACPM DVFS protocol handler. It constructs DVFS messages that the APM firmware can understand. Signed-off-by: Tudor Ambarus Reviewed-by: Peter Griffin Tested-by: Peter Griffin # on gs101-oriole Link: https://patch.msgid.link/20251010-acpm-clk-v6-2-321ee8826fd4@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/firmware/samsung/Makefile | 4 +- drivers/firmware/samsung/exynos-acpm-dvfs.c | 80 +++++++++++++++++++ drivers/firmware/samsung/exynos-acpm-dvfs.h | 21 +++++ drivers/firmware/samsung/exynos-acpm.c | 5 ++ .../firmware/samsung/exynos-acpm-protocol.h | 10 +++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/samsung/exynos-acpm-dvfs.c create mode 100644 drivers/firmware/samsung/exynos-acpm-dvfs.h diff --git a/drivers/firmware/samsung/Makefile b/drivers/firmware/samsung/Makefile index 7b4c9f6f34f5..80d4f89b33a9 100644 --- a/drivers/firmware/samsung/Makefile +++ b/drivers/firmware/samsung/Makefile @@ -1,4 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -acpm-protocol-objs := exynos-acpm.o exynos-acpm-pmic.o +acpm-protocol-objs := exynos-acpm.o +acpm-protocol-objs += exynos-acpm-pmic.o +acpm-protocol-objs += exynos-acpm-dvfs.o obj-$(CONFIG_EXYNOS_ACPM_PROTOCOL) += acpm-protocol.o diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c new file mode 100644 index 000000000000..1c5b2b143bcc --- /dev/null +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2020 Samsung Electronics Co., Ltd. + * Copyright 2020 Google LLC. + * Copyright 2025 Linaro Ltd. + */ + +#include +#include +#include +#include +#include + +#include "exynos-acpm.h" +#include "exynos-acpm-dvfs.h" + +#define ACPM_DVFS_ID GENMASK(11, 0) +#define ACPM_DVFS_REQ_TYPE GENMASK(15, 0) + +#define ACPM_DVFS_FREQ_REQ 0 +#define ACPM_DVFS_FREQ_GET 1 + +static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen, + unsigned int acpm_chan_id, bool response) +{ + xfer->acpm_chan_id = acpm_chan_id; + xfer->txd = cmd; + xfer->txlen = cmdlen; + + if (response) { + xfer->rxd = cmd; + xfer->rxlen = cmdlen; + } +} + +static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id, + unsigned long rate) +{ + cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id); + cmd[1] = rate / HZ_PER_KHZ; + cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_REQ); + cmd[3] = ktime_to_ms(ktime_get()); +} + +int acpm_dvfs_set_rate(const struct acpm_handle *handle, + unsigned int acpm_chan_id, unsigned int clk_id, + unsigned long rate) +{ + struct acpm_xfer xfer = {0}; + u32 cmd[4]; + + acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate); + acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, false); + + return acpm_do_xfer(handle, &xfer); +} + +static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id) +{ + cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id); + cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_GET); + cmd[3] = ktime_to_ms(ktime_get()); +} + +unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle, + unsigned int acpm_chan_id, unsigned int clk_id) +{ + struct acpm_xfer xfer; + unsigned int cmd[4] = {0}; + int ret; + + acpm_dvfs_init_get_rate_cmd(cmd, clk_id); + acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, true); + + ret = acpm_do_xfer(handle, &xfer); + if (ret) + return 0; + + return xfer.rxd[1] * HZ_PER_KHZ; +} diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.h b/drivers/firmware/samsung/exynos-acpm-dvfs.h new file mode 100644 index 000000000000..9f2778e649c9 --- /dev/null +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2020 Samsung Electronics Co., Ltd. + * Copyright 2020 Google LLC. + * Copyright 2025 Linaro Ltd. + */ +#ifndef __EXYNOS_ACPM_DVFS_H__ +#define __EXYNOS_ACPM_DVFS_H__ + +#include + +struct acpm_handle; + +int acpm_dvfs_set_rate(const struct acpm_handle *handle, + unsigned int acpm_chan_id, unsigned int id, + unsigned long rate); +unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle, + unsigned int acpm_chan_id, + unsigned int clk_id); + +#endif /* __EXYNOS_ACPM_DVFS_H__ */ diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c index 3a69fe3234c7..9fa0335ccf5d 100644 --- a/drivers/firmware/samsung/exynos-acpm.c +++ b/drivers/firmware/samsung/exynos-acpm.c @@ -29,6 +29,7 @@ #include #include "exynos-acpm.h" +#include "exynos-acpm-dvfs.h" #include "exynos-acpm-pmic.h" #define ACPM_PROTOCOL_SEQNUM GENMASK(21, 16) @@ -590,8 +591,12 @@ static int acpm_channels_init(struct acpm_info *acpm) */ static void acpm_setup_ops(struct acpm_info *acpm) { + struct acpm_dvfs_ops *dvfs_ops = &acpm->handle.ops.dvfs_ops; struct acpm_pmic_ops *pmic_ops = &acpm->handle.ops.pmic_ops; + dvfs_ops->set_rate = acpm_dvfs_set_rate; + dvfs_ops->get_rate = acpm_dvfs_get_rate; + pmic_ops->read_reg = acpm_pmic_read_reg; pmic_ops->bulk_read = acpm_pmic_bulk_read; pmic_ops->write_reg = acpm_pmic_write_reg; diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h index f628bf1862c2..b1e95435240f 100644 --- a/include/linux/firmware/samsung/exynos-acpm-protocol.h +++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h @@ -13,6 +13,15 @@ struct acpm_handle; struct device_node; +struct acpm_dvfs_ops { + int (*set_rate)(const struct acpm_handle *handle, + unsigned int acpm_chan_id, unsigned int clk_id, + unsigned long rate); + unsigned long (*get_rate)(const struct acpm_handle *handle, + unsigned int acpm_chan_id, + unsigned int clk_id); +}; + struct acpm_pmic_ops { int (*read_reg)(const struct acpm_handle *handle, unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan, @@ -32,6 +41,7 @@ struct acpm_pmic_ops { }; struct acpm_ops { + struct acpm_dvfs_ops dvfs_ops; struct acpm_pmic_ops pmic_ops; }; From bad0d1260b6dc229657b942400c5fc4f257f50cd Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 10 Oct 2025 12:46:33 +0000 Subject: [PATCH 017/117] firmware: exynos-acpm: register ACPM clocks pdev Register by hand a platform device for the ACPM clocks. The ACPM clocks are not modeled as a DT child of ACPM because: 1/ they don't have their own resources. 2/ they are not a block that can be reused. The clock identifying data is reduced (clock ID, clock name and mailbox channel ID) and may differ from a SoC to another. Signed-off-by: Tudor Ambarus Reviewed-by: Peter Griffin Tested-by: Peter Griffin # on gs101-oriole Link: https://patch.msgid.link/20251010-acpm-clk-v6-3-321ee8826fd4@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/firmware/samsung/exynos-acpm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c index 9fa0335ccf5d..0cb269c70460 100644 --- a/drivers/firmware/samsung/exynos-acpm.c +++ b/drivers/firmware/samsung/exynos-acpm.c @@ -177,9 +177,11 @@ struct acpm_info { /** * struct acpm_match_data - of_device_id data. * @initdata_base: offset in SRAM where the channels configuration resides. + * @acpm_clk_dev_name: base name for the ACPM clocks device that we're registering. */ struct acpm_match_data { loff_t initdata_base; + const char *acpm_clk_dev_name; }; #define client_to_acpm_chan(c) container_of(c, struct acpm_chan, cl) @@ -604,9 +606,15 @@ static void acpm_setup_ops(struct acpm_info *acpm) pmic_ops->update_reg = acpm_pmic_update_reg; } +static void acpm_clk_pdev_unregister(void *data) +{ + platform_device_unregister(data); +} + static int acpm_probe(struct platform_device *pdev) { const struct acpm_match_data *match_data; + struct platform_device *acpm_clk_pdev; struct device *dev = &pdev->dev; struct device_node *shmem; struct acpm_info *acpm; @@ -647,6 +655,18 @@ static int acpm_probe(struct platform_device *pdev) platform_set_drvdata(pdev, acpm); + acpm_clk_pdev = platform_device_register_data(dev, + match_data->acpm_clk_dev_name, + PLATFORM_DEVID_NONE, NULL, 0); + if (IS_ERR(acpm_clk_pdev)) + return dev_err_probe(dev, PTR_ERR(acpm_clk_pdev), + "Failed to register ACPM clocks device.\n"); + + ret = devm_add_action_or_reset(dev, acpm_clk_pdev_unregister, + acpm_clk_pdev); + if (ret) + return dev_err_probe(dev, ret, "Failed to add devm action.\n"); + return devm_of_platform_populate(dev); } @@ -746,6 +766,7 @@ EXPORT_SYMBOL_GPL(devm_acpm_get_by_node); static const struct acpm_match_data acpm_gs101 = { .initdata_base = ACPM_GS101_INITDATA_BASE, + .acpm_clk_dev_name = "gs101-acpm-clk", }; static const struct of_device_id acpm_match[] = { From 40498a74205371400a5b0088acb886ac47a523aa Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 10 Oct 2025 12:46:34 +0000 Subject: [PATCH 018/117] clk: samsung: add Exynos ACPM clock driver Add the Exynos ACPM clock driver. It provides support for clocks that are controlled by firmware that implements the ACPM interface. Signed-off-by: Tudor Ambarus Reviewed-by: Peter Griffin Tested-by: Peter Griffin # on gs101-oriole Link: https://patch.msgid.link/20251010-acpm-clk-v6-4-321ee8826fd4@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/Kconfig | 10 ++ drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-acpm.c | 185 +++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 drivers/clk/samsung/clk-acpm.c diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig index 76a494e95027..70a8b82a0136 100644 --- a/drivers/clk/samsung/Kconfig +++ b/drivers/clk/samsung/Kconfig @@ -95,6 +95,16 @@ config EXYNOS_CLKOUT status of the certains clocks from SoC, but it could also be tied to other devices as an input clock. +config EXYNOS_ACPM_CLK + tristate "Clock driver controlled via ACPM interface" + depends on EXYNOS_ACPM_PROTOCOL || (COMPILE_TEST && !EXYNOS_ACPM_PROTOCOL) + help + This driver provides support for clocks that are controlled by + firmware that implements the ACPM interface. + + This driver uses the ACPM interface to interact with the firmware + providing all the clock controlls. + config TESLA_FSD_COMMON_CLK bool "Tesla FSD clock controller support" if COMPILE_TEST depends on COMMON_CLK_SAMSUNG diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index ef464f434740..f3657f2e1b98 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos990.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynosautov9.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynosautov920.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-gs101.o +obj-$(CONFIG_EXYNOS_ACPM_CLK) += clk-acpm.o obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o obj-$(CONFIG_TESLA_FSD_COMMON_CLK) += clk-fsd.o diff --git a/drivers/clk/samsung/clk-acpm.c b/drivers/clk/samsung/clk-acpm.c new file mode 100644 index 000000000000..b90809ce3f88 --- /dev/null +++ b/drivers/clk/samsung/clk-acpm.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Samsung Exynos ACPM protocol based clock driver. + * + * Copyright 2025 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct acpm_clk { + u32 id; + struct clk_hw hw; + unsigned int mbox_chan_id; + const struct acpm_handle *handle; +}; + +struct acpm_clk_variant { + const char *name; +}; + +struct acpm_clk_driver_data { + const struct acpm_clk_variant *clks; + unsigned int nr_clks; + unsigned int mbox_chan_id; +}; + +#define to_acpm_clk(clk) container_of(clk, struct acpm_clk, hw) + +#define ACPM_CLK(cname) \ + { \ + .name = cname, \ + } + +static const struct acpm_clk_variant gs101_acpm_clks[] = { + ACPM_CLK("mif"), + ACPM_CLK("int"), + ACPM_CLK("cpucl0"), + ACPM_CLK("cpucl1"), + ACPM_CLK("cpucl2"), + ACPM_CLK("g3d"), + ACPM_CLK("g3dl2"), + ACPM_CLK("tpu"), + ACPM_CLK("intcam"), + ACPM_CLK("tnr"), + ACPM_CLK("cam"), + ACPM_CLK("mfc"), + ACPM_CLK("disp"), + ACPM_CLK("bo"), +}; + +static const struct acpm_clk_driver_data acpm_clk_gs101 = { + .clks = gs101_acpm_clks, + .nr_clks = ARRAY_SIZE(gs101_acpm_clks), + .mbox_chan_id = 0, +}; + +static unsigned long acpm_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct acpm_clk *clk = to_acpm_clk(hw); + + return clk->handle->ops.dvfs_ops.get_rate(clk->handle, + clk->mbox_chan_id, clk->id); +} + +static int acpm_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + /* + * We can't figure out what rate it will be, so just return the + * rate back to the caller. acpm_clk_recalc_rate() will be called + * after the rate is set and we'll know what rate the clock is + * running at then. + */ + return 0; +} + +static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct acpm_clk *clk = to_acpm_clk(hw); + + return clk->handle->ops.dvfs_ops.set_rate(clk->handle, + clk->mbox_chan_id, clk->id, rate); +} + +static const struct clk_ops acpm_clk_ops = { + .recalc_rate = acpm_clk_recalc_rate, + .determine_rate = acpm_clk_determine_rate, + .set_rate = acpm_clk_set_rate, +}; + +static int acpm_clk_register(struct device *dev, struct acpm_clk *aclk, + const char *name) +{ + struct clk_init_data init = {}; + + init.name = name; + init.ops = &acpm_clk_ops; + aclk->hw.init = &init; + + return devm_clk_hw_register(dev, &aclk->hw); +} + +static int acpm_clk_probe(struct platform_device *pdev) +{ + const struct acpm_handle *acpm_handle; + struct clk_hw_onecell_data *clk_data; + struct clk_hw **hws; + struct device *dev = &pdev->dev; + struct acpm_clk *aclks; + unsigned int mbox_chan_id; + int i, err, count; + + acpm_handle = devm_acpm_get_by_node(dev, dev->parent->of_node); + if (IS_ERR(acpm_handle)) + return dev_err_probe(dev, PTR_ERR(acpm_handle), + "Failed to get acpm handle\n"); + + count = acpm_clk_gs101.nr_clks; + mbox_chan_id = acpm_clk_gs101.mbox_chan_id; + + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->num = count; + hws = clk_data->hws; + + aclks = devm_kcalloc(dev, count, sizeof(*aclks), GFP_KERNEL); + if (!aclks) + return -ENOMEM; + + for (i = 0; i < count; i++) { + struct acpm_clk *aclk = &aclks[i]; + + /* + * The code assumes the clock IDs start from zero, + * are sequential and do not have gaps. + */ + aclk->id = i; + aclk->handle = acpm_handle; + aclk->mbox_chan_id = mbox_chan_id; + + hws[i] = &aclk->hw; + + err = acpm_clk_register(dev, aclk, + acpm_clk_gs101.clks[i].name); + if (err) + return dev_err_probe(dev, err, + "Failed to register clock\n"); + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + clk_data); +} + +static const struct platform_device_id acpm_clk_id[] = { + { "gs101-acpm-clk" }, + {} +}; +MODULE_DEVICE_TABLE(platform, acpm_clk_id); + +static struct platform_driver acpm_clk_driver = { + .driver = { + .name = "acpm-clocks", + }, + .probe = acpm_clk_probe, + .id_table = acpm_clk_id, +}; +module_platform_driver(acpm_clk_driver); + +MODULE_AUTHOR("Tudor Ambarus "); +MODULE_DESCRIPTION("Samsung Exynos ACPM clock driver"); +MODULE_LICENSE("GPL"); From ad97aba3e64f8e474ecbce0c4e08486023ce8ab2 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 10 Oct 2025 12:46:36 +0000 Subject: [PATCH 019/117] MAINTAINERS: add ACPM clock bindings and driver Extend the Google Tensor SoC support list of files to include the GS101 ACPM clock bindings. Add the ACPM clock driver under the Samsung Exynos ACPM Protocol entry. Signed-off-by: Tudor Ambarus Link: https://patch.msgid.link/20251010-acpm-clk-v6-6-321ee8826fd4@linaro.org Signed-off-by: Krzysztof Kozlowski --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 46126ce2f968..5d24c16d3ead 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10601,7 +10601,7 @@ F: Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml F: arch/arm64/boot/dts/exynos/google/ F: drivers/clk/samsung/clk-gs101.c F: drivers/phy/samsung/phy-gs101-ufs.c -F: include/dt-bindings/clock/google,gs101.h +F: include/dt-bindings/clock/google,gs101* K: [gG]oogle.?[tT]ensor GPD FAN DRIVER @@ -22761,6 +22761,7 @@ L: linux-kernel@vger.kernel.org L: linux-samsung-soc@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml +F: drivers/clk/samsung/clk-acpm.c F: drivers/firmware/samsung/exynos-acpm* F: include/linux/firmware/samsung/exynos-acpm-protocol.h From 3b37979dcbef0dc3fc1aaba75b21ff9a21799055 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 29 Sep 2025 12:23:24 +0100 Subject: [PATCH 020/117] clk: renesas: cpg-mssr: Add module reset support for RZ/T2H Add support for module reset handling on the RZ/T2H SoC. Unlike earlier CPG/MSSR variants, RZ/T2H uses a unified set of Module Reset Control Registers (MRCR) where both reset and deassert actions are done via read-modify-write (RMW) to the same register. Introduce a new MRCR offset table (mrcr_for_rzt2h) for RZ/T2H and assign it to reset_regs. For this SoC, the number of resets is based on the number of MRCR registers rather than the number of module clocks. Also add cpg_mrcr_reset_ops to implement reset, assert, and deassert using RMW while holding the spinlock. This follows the RZ/T2H requirements, where processing after releasing a module reset must be secured by performing seven dummy reads of the same register, and where a module that is reset and released again must ensure the target bit in the Module Reset Control Register is set to 1. Update the reset controller registration to select cpg_mrcr_reset_ops for RZ/T2H, while keeping the existing cpg_mssr_reset_ops for other SoCs. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Reviewed-by: Philipp Zabel Link: https://patch.msgid.link/20250929112324.3622148-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 111 ++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index a3d171ddaab9..0ffe6ee8f165 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -40,6 +40,8 @@ #define WARN_DEBUG(x) do { } while (0) #endif +#define RZT2H_RESET_REG_READ_COUNT 7 + /* * Module Standby and Software Reset register offets. * @@ -137,6 +139,22 @@ static const u16 srcr_for_gen4[] = { 0x2C60, 0x2C64, 0x2C68, 0x2C6C, 0x2C70, 0x2C74, }; +static const u16 mrcr_for_rzt2h[] = { + 0x240, /* MRCTLA */ + 0x244, /* Reserved */ + 0x248, /* Reserved */ + 0x24C, /* Reserved */ + 0x250, /* MRCTLE */ + 0x254, /* Reserved */ + 0x258, /* Reserved */ + 0x25C, /* Reserved */ + 0x260, /* MRCTLI */ + 0x264, /* Reserved */ + 0x268, /* Reserved */ + 0x26C, /* Reserved */ + 0x270, /* MRCTLM */ +}; + /* * Software Reset Clearing Register offsets */ @@ -739,6 +757,72 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev, return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask); } +static int cpg_mrcr_set_reset_state(struct reset_controller_dev *rcdev, + unsigned long id, bool set) +{ + struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + unsigned int reg = id / 32; + unsigned int bit = id % 32; + u32 bitmask = BIT(bit); + void __iomem *reg_addr; + unsigned long flags; + unsigned int i; + u32 val; + + dev_dbg(priv->dev, "%s %u%02u\n", set ? "assert" : "deassert", reg, bit); + + spin_lock_irqsave(&priv->pub.rmw_lock, flags); + + reg_addr = priv->pub.base0 + priv->reset_regs[reg]; + /* Read current value and modify */ + val = readl(reg_addr); + if (set) + val |= bitmask; + else + val &= ~bitmask; + writel(val, reg_addr); + + /* + * For secure processing after release from a module reset, one must + * perform multiple dummy reads of the same register. + */ + for (i = 0; !set && i < RZT2H_RESET_REG_READ_COUNT; i++) + readl(reg_addr); + + /* Verify the operation */ + val = readl(reg_addr); + if (set == !(bitmask & val)) { + dev_err(priv->dev, "Reset register %u%02u operation failed\n", reg, bit); + spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); + return -EIO; + } + + spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); + + return 0; +} + +static int cpg_mrcr_reset(struct reset_controller_dev *rcdev, unsigned long id) +{ + int ret; + + ret = cpg_mrcr_set_reset_state(rcdev, id, true); + if (ret) + return ret; + + return cpg_mrcr_set_reset_state(rcdev, id, false); +} + +static int cpg_mrcr_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return cpg_mrcr_set_reset_state(rcdev, id, true); +} + +static int cpg_mrcr_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return cpg_mrcr_set_reset_state(rcdev, id, false); +} + static const struct reset_control_ops cpg_mssr_reset_ops = { .reset = cpg_mssr_reset, .assert = cpg_mssr_assert, @@ -746,6 +830,13 @@ static const struct reset_control_ops cpg_mssr_reset_ops = { .status = cpg_mssr_status, }; +static const struct reset_control_ops cpg_mrcr_reset_ops = { + .reset = cpg_mrcr_reset, + .assert = cpg_mrcr_assert, + .deassert = cpg_mrcr_deassert, + .status = cpg_mssr_status, +}; + static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev, const struct of_phandle_args *reset_spec) { @@ -763,11 +854,23 @@ static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev, static int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv) { - priv->rcdev.ops = &cpg_mssr_reset_ops; + /* + * RZ/T2H (and family) has the Module Reset Control Registers + * which allows control resets of certain modules. + * The number of resets is not equal to the number of module clocks. + */ + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + priv->rcdev.ops = &cpg_mrcr_reset_ops; + priv->rcdev.nr_resets = ARRAY_SIZE(mrcr_for_rzt2h) * 32; + } else { + priv->rcdev.ops = &cpg_mssr_reset_ops; + priv->rcdev.nr_resets = priv->num_mod_clks; + } + priv->rcdev.of_node = priv->dev->of_node; priv->rcdev.of_reset_n_cells = 1; priv->rcdev.of_xlate = cpg_mssr_reset_xlate; - priv->rcdev.nr_resets = priv->num_mod_clks; + return devm_reset_controller_register(priv->dev, &priv->rcdev); } @@ -1172,6 +1275,7 @@ static int __init cpg_mssr_common_init(struct device *dev, priv->control_regs = stbcr; } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { priv->control_regs = mstpcr_for_rzt2h; + priv->reset_regs = mrcr_for_rzt2h; } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) { priv->status_regs = mstpsr_for_gen4; priv->control_regs = mstpcr_for_gen4; @@ -1268,8 +1372,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) goto reserve_exit; /* Reset Controller not supported for Standby Control SoCs */ - if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A || - priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) goto reserve_exit; error = cpg_mssr_reset_controller_register(priv); From 6837c006d4e72d6add451411bcf407e0dea4ad25 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Tue, 21 Oct 2025 15:24:47 +0000 Subject: [PATCH 021/117] firmware: exynos-acpm: add empty method to allow compile test Provide empty method for devm_acpm_get_by_node() if we aren't building in the CONFIG_EXYNOS_ACPM_PROTOCOL. This allows to test-build the CONFIG_EXYNOS_ACPM_CLK code. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202510211905.RgfWkgss-lkp@intel.com/ Fixes: 40498a742053 ("clk: samsung: add Exynos ACPM clock driver") Signed-off-by: Tudor Ambarus Link: https://patch.msgid.link/20251021-fix-acpm-clk-build-test-v1-1-236a3d6db7f5@linaro.org Signed-off-by: Krzysztof Kozlowski --- include/linux/firmware/samsung/exynos-acpm-protocol.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h index b1e95435240f..2091da965a5a 100644 --- a/include/linux/firmware/samsung/exynos-acpm-protocol.h +++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h @@ -55,7 +55,16 @@ struct acpm_handle { struct device; +#if IS_ENABLED(CONFIG_EXYNOS_ACPM_PROTOCOL) const struct acpm_handle *devm_acpm_get_by_node(struct device *dev, struct device_node *np); +#else + +static inline const struct acpm_handle *devm_acpm_get_by_node(struct device *dev, + struct device_node *np) +{ + return NULL; +} +#endif #endif /* __EXYNOS_ACPM_PROTOCOL_H */ From d8f1121ebf4036884fc9ab1968f606523dd1c1fe Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 22 Oct 2025 02:44:45 +0300 Subject: [PATCH 022/117] clk: qcom: camcc-sm8550: Specify Titan GDSC power domain as a parent to other When a consumer turns on/off a power domain dependent on another power domain in hardware, the parent power domain shall be turned on/off by the power domain provider as well, and to get it the power domain hardware hierarchy shall be described in the CAMCC driver. Establish the power domain hierarchy with a Titan GDSC set as a parent of all other GDSC power domains provided by the SM8550 camera clock controller to enforce a correct sequence of enabling and disabling power domains by the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS IP and its driver. Fixes: ccc4e6a061a2 ("clk: qcom: camcc-sm8550: Add camera clock controller driver for SM8550") Reviewed-by: Konrad Dybcio Reviewed-by: Imran Shaik Reviewed-by: Bryan O'Donoghue Signed-off-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251021234450.2271279-2-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sm8550.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/clk/qcom/camcc-sm8550.c b/drivers/clk/qcom/camcc-sm8550.c index 63aed9e4c362..b8ece8a57a8a 100644 --- a/drivers/clk/qcom/camcc-sm8550.c +++ b/drivers/clk/qcom/camcc-sm8550.c @@ -3204,6 +3204,8 @@ static struct clk_branch cam_cc_sfe_1_fast_ahb_clk = { }, }; +static struct gdsc cam_cc_titan_top_gdsc; + static struct gdsc cam_cc_bps_gdsc = { .gdscr = 0x10004, .en_rest_wait_val = 0x2, @@ -3213,6 +3215,7 @@ static struct gdsc cam_cc_bps_gdsc = { .name = "cam_cc_bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3225,6 +3228,7 @@ static struct gdsc cam_cc_ife_0_gdsc = { .name = "cam_cc_ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3237,6 +3241,7 @@ static struct gdsc cam_cc_ife_1_gdsc = { .name = "cam_cc_ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3249,6 +3254,7 @@ static struct gdsc cam_cc_ife_2_gdsc = { .name = "cam_cc_ife_2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3261,6 +3267,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = { .name = "cam_cc_ipe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3273,6 +3280,7 @@ static struct gdsc cam_cc_sbi_gdsc = { .name = "cam_cc_sbi_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3285,6 +3293,7 @@ static struct gdsc cam_cc_sfe_0_gdsc = { .name = "cam_cc_sfe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3297,6 +3306,7 @@ static struct gdsc cam_cc_sfe_1_gdsc = { .name = "cam_cc_sfe_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; From a76ce61d7225934b0a52c8172a8cd944002a8c6f Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 22 Oct 2025 02:44:46 +0300 Subject: [PATCH 023/117] clk: qcom: camcc-sm6350: Specify Titan GDSC power domain as a parent to other When a consumer turns on/off a power domain dependent on another power domain in hardware, the parent power domain shall be turned on/off by the power domain provider as well, and to get it the power domain hardware hierarchy shall be described in the CAMCC driver. Establish the power domain hierarchy with a Titan GDSC set as a parent of all other GDSC power domains provided by the SM6350 camera clock controller to enforce a correct sequence of enabling and disabling power domains by the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS IP and its driver. Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") Reviewed-by: Konrad Dybcio Reviewed-by: Imran Shaik Reviewed-by: Bryan O'Donoghue Signed-off-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251021234450.2271279-3-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sm6350.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c index 8aac97d29ce3..6c272f7b0721 100644 --- a/drivers/clk/qcom/camcc-sm6350.c +++ b/drivers/clk/qcom/camcc-sm6350.c @@ -1693,6 +1693,8 @@ static struct clk_branch camcc_sys_tmr_clk = { }, }; +static struct gdsc titan_top_gdsc; + static struct gdsc bps_gdsc = { .gdscr = 0x6004, .en_rest_wait_val = 0x2, @@ -1702,6 +1704,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, .flags = VOTABLE, }; @@ -1714,6 +1717,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, .flags = VOTABLE, }; @@ -1726,6 +1730,7 @@ static struct gdsc ife_0_gdsc = { .name = "ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc ife_1_gdsc = { @@ -1737,6 +1742,7 @@ static struct gdsc ife_1_gdsc = { .name = "ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc ife_2_gdsc = { @@ -1748,6 +1754,7 @@ static struct gdsc ife_2_gdsc = { .name = "ife_2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc titan_top_gdsc = { From ee2867ca99e2b5b6788ff421f7e784d9a0da426f Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 22 Oct 2025 02:44:47 +0300 Subject: [PATCH 024/117] clk: qcom: camcc-sdm845: Specify Titan GDSC power domain as a parent to other When a consumer turns on/off a power domain dependent on another power domain in hardware, the parent power domain shall be turned on/off by the power domain provider as well, and to get it the power domain hardware hierarchy shall be properly described in the power domain provider driver. Establish the power domain hierarchy with a Titan GDSC set as a parent of other GDSC power domains provided by the SDM845 camera clock controller, including IPE0/1 and BPS ones. Reviewed-by: Konrad Dybcio Reviewed-by: Imran Shaik Reviewed-by: Bryan O'Donoghue Signed-off-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251021234450.2271279-4-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sdm845.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c index cf60e8dd292a..fb313da7165b 100644 --- a/drivers/clk/qcom/camcc-sdm845.c +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -1543,6 +1543,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1552,6 +1553,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1561,6 +1563,7 @@ static struct gdsc ipe_1_gdsc = { .name = "ipe_1_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; From 37cf953a120a69114b810eee74530a8836d9a781 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 22 Oct 2025 02:44:48 +0300 Subject: [PATCH 025/117] clk: qcom: camcc-sm7150: Specify Titan GDSC power domain as a parent to IPEx and BPS When a consumer turns on/off a power domain dependent on another power domain in hardware, the parent power domain shall be turned on/off by the power domain provider as well, and to get it the power domain hardware hierarchy shall be described in the CAMCC driver. Establish the power domain hierarchy with a Titan GDSC set as a parent of other GDSC power domains provided by the SM7150 camera clock controller, including IPE0/1 and BPS ones. Reviewed-by: Konrad Dybcio Reviewed-by: Imran Shaik Reviewed-by: Bryan O'Donoghue Signed-off-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251021234450.2271279-5-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sm7150.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c index 4a3baf5d8e85..0e072ae39ec0 100644 --- a/drivers/clk/qcom/camcc-sm7150.c +++ b/drivers/clk/qcom/camcc-sm7150.c @@ -1846,6 +1846,7 @@ static struct gdsc camcc_bps_gdsc = { .name = "camcc_bps_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &camcc_titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1875,6 +1876,7 @@ static struct gdsc camcc_ipe_0_gdsc = { .name = "camcc_ipe_0_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &camcc_titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1884,6 +1886,7 @@ static struct gdsc camcc_ipe_1_gdsc = { .name = "camcc_ipe_1_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &camcc_titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; From fc3985b21f86db33e4ec8a820d211e4e505c9048 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 22 Oct 2025 02:44:49 +0300 Subject: [PATCH 026/117] clk: qcom: camcc-sm8250: Specify Titan GDSC power domain as a parent to IPE/BPS/SBI When a consumer turns on/off a power domain dependent on another power domain in hardware, the parent power domain shall be turned on/off by the power domain provider as well, and to get it the power domain hardware hierarchy shall be described in the CAMCC driver. Establish the power domain hierarchy with a Titan GDSC set as a parent of other GDSC power domains provided by the SM8250 camera clock controller, including IPE, BPS and SBI ones. Reviewed-by: Konrad Dybcio Reviewed-by: Imran Shaik Reviewed-by: Bryan O'Donoghue Signed-off-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251021234450.2271279-6-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sm8250.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c index 6da89c49ba3d..c95a00628630 100644 --- a/drivers/clk/qcom/camcc-sm8250.c +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -2213,6 +2213,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2222,6 +2223,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2231,6 +2233,7 @@ static struct gdsc sbi_gdsc = { .name = "sbi_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; From 70dc5425fe1af90901d8109941e09005de38b7ea Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 22 Oct 2025 02:44:50 +0300 Subject: [PATCH 027/117] clk: qcom: camcc-sm8450: Specify Titan GDSC power domain as a parent to IPE/BPS/SBI When a consumer turns on/off a power domain dependent on another power domain in hardware, the parent power domain shall be turned on/off by the power domain provider as well, and to get it the power domain hardware hierarchy shall be described in the CAMCC driver. Establish the power domain hierarchy with a Titan GDSC set as a parent of other GDSC power domains provided by the SM8450 camera clock controller, including IPE, BPS and SBI ones. Reviewed-by: Konrad Dybcio Reviewed-by: Imran Shaik Reviewed-by: Bryan O'Donoghue Signed-off-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251021234450.2271279-7-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sm8450.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/camcc-sm8450.c b/drivers/clk/qcom/camcc-sm8450.c index 4dd8be8cc988..ef8cf54d0eed 100644 --- a/drivers/clk/qcom/camcc-sm8450.c +++ b/drivers/clk/qcom/camcc-sm8450.c @@ -2935,6 +2935,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2944,6 +2945,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .flags = HW_CTRL | POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2953,6 +2955,7 @@ static struct gdsc sbi_gdsc = { .name = "sbi_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; From 17e4db05930e455770b15b77708a07681ed24efc Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 27 Jun 2025 21:37:58 +0200 Subject: [PATCH 028/117] clk: qcom: rpmh: Define RPMH_IPA_CLK on QCS615 This was previously (mis)represented in the interconnect driver, move the resource under the clk-rpmh driver control, just like we did for all platforms in the past, see e.g. Commit aa055bf158cd ("clk: qcom: rpmh: define IPA clocks where required") Fixes: 42a1905a10d6 ("clk: qcom: rpmhcc: Add support for QCS615 Clocks") Signed-off-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250627-topic-qcs615_icc_ipa-v1-4-dc47596cde69@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpmh.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 63c38cb47bc4..1a98b3a0c528 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -855,6 +855,7 @@ static struct clk_hw *qcs615_rpmh_clocks[] = { [RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw, [RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw, [RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw, + [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, }; static const struct clk_rpmh_desc clk_rpmh_qcs615 = { From 502099e9c832c95b485835ff58a5f735d9d956a1 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 19 Sep 2025 11:57:24 +0200 Subject: [PATCH 029/117] clk: qcom: dispcc-sm6350: Add MDSS_CORE & MDSS_RSCC resets Add the offsets for two resets inside the dispcc on SM6350 SoC. Signed-off-by: Luca Weiss Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250919-sm6350-mdss-reset-v1-2-48dcac917c73@fairphone.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sm6350.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c index b0bd163a449c..5b1d8f86515f 100644 --- a/drivers/clk/qcom/dispcc-sm6350.c +++ b/drivers/clk/qcom/dispcc-sm6350.c @@ -679,6 +679,11 @@ static struct clk_branch disp_cc_xo_clk = { }, }; +static const struct qcom_reset_map disp_cc_sm6350_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x1000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0x2000 }, +}; + static struct gdsc mdss_gdsc = { .gdscr = 0x1004, .en_rest_wait_val = 0x2, @@ -746,6 +751,8 @@ static const struct qcom_cc_desc disp_cc_sm6350_desc = { .num_clks = ARRAY_SIZE(disp_cc_sm6350_clocks), .gdscs = disp_cc_sm6350_gdscs, .num_gdscs = ARRAY_SIZE(disp_cc_sm6350_gdscs), + .resets = disp_cc_sm6350_resets, + .num_resets = ARRAY_SIZE(disp_cc_sm6350_resets), }; static const struct of_device_id disp_cc_sm6350_match_table[] = { From 2238840342af8e8d37a9355f0a2ad4285c32f854 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Fri, 19 Sep 2025 14:34:30 +0200 Subject: [PATCH 030/117] dt-bindings: clock: sm7150-dispcc: Add MDSS_CORE reset Add the index for a reset inside the dispcc on SM7150 SoC. Signed-off-by: Jens Reidel Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250919-sm7150-dispcc-fixes-v1-1-308ad47c5fce@mainlining.org Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,sm7150-dispcc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/dt-bindings/clock/qcom,sm7150-dispcc.h b/include/dt-bindings/clock/qcom,sm7150-dispcc.h index fc1fefe8fd72..1e4e6432d506 100644 --- a/include/dt-bindings/clock/qcom,sm7150-dispcc.h +++ b/include/dt-bindings/clock/qcom,sm7150-dispcc.h @@ -53,6 +53,9 @@ #define DISPCC_SLEEP_CLK 41 #define DISPCC_SLEEP_CLK_SRC 42 +/* DISPCC resets */ +#define DISPCC_MDSS_CORE_BCR 0 + /* DISPCC GDSCR */ #define MDSS_GDSC 0 From 176465fd8c4e2cbb4410b5a66f6ba74ed491d2a5 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Fri, 19 Sep 2025 14:34:31 +0200 Subject: [PATCH 031/117] clk: qcom: dispcc-sm7150: Add MDSS_CORE reset Add the offsets for a reset inside the dispcc on SM7150 SoC. Signed-off-by: Jens Reidel Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250919-sm7150-dispcc-fixes-v1-2-308ad47c5fce@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sm7150.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/qcom/dispcc-sm7150.c b/drivers/clk/qcom/dispcc-sm7150.c index bdfff246ed3f..0a7f6ec7a2a7 100644 --- a/drivers/clk/qcom/dispcc-sm7150.c +++ b/drivers/clk/qcom/dispcc-sm7150.c @@ -20,6 +20,7 @@ #include "clk-regmap-divider.h" #include "common.h" #include "gdsc.h" +#include "reset.h" enum { DT_BI_TCXO, @@ -951,6 +952,10 @@ static struct gdsc *dispcc_sm7150_gdscs[] = { [MDSS_GDSC] = &mdss_gdsc, }; +static const struct qcom_reset_map dispcc_sm7150_resets[] = { + [DISPCC_MDSS_CORE_BCR] = { 0x2000 }, +}; + static const struct regmap_config dispcc_sm7150_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -965,6 +970,8 @@ static const struct qcom_cc_desc dispcc_sm7150_desc = { .num_clks = ARRAY_SIZE(dispcc_sm7150_clocks), .gdscs = dispcc_sm7150_gdscs, .num_gdscs = ARRAY_SIZE(dispcc_sm7150_gdscs), + .resets = dispcc_sm7150_resets, + .num_resets = ARRAY_SIZE(dispcc_sm7150_resets), }; static const struct of_device_id dispcc_sm7150_match_table[] = { From e3c13e0caa8ceb7dec1a7c4fcfd9dbef56a69fbe Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Fri, 19 Sep 2025 14:34:32 +0200 Subject: [PATCH 032/117] clk: qcom: dispcc-sm7150: Fix dispcc_mdss_pclk0_clk_src Set CLK_OPS_PARENT_ENABLE to ensure the parent gets prepared and enabled when switching to it, fixing an "rcg didn't update its configuration" warning. Signed-off-by: Jens Reidel Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250919-sm7150-dispcc-fixes-v1-3-308ad47c5fce@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sm7150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/dispcc-sm7150.c b/drivers/clk/qcom/dispcc-sm7150.c index 0a7f6ec7a2a7..811d380a8e9f 100644 --- a/drivers/clk/qcom/dispcc-sm7150.c +++ b/drivers/clk/qcom/dispcc-sm7150.c @@ -357,7 +357,7 @@ static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = { .name = "dispcc_mdss_pclk0_clk_src", .parent_data = dispcc_parent_data_4, .num_parents = ARRAY_SIZE(dispcc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .ops = &clk_pixel_ops, }, }; From 393f7834cd2b1eaf4a9eff2701e706e73e660dd7 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 24 Sep 2025 00:08:30 +0530 Subject: [PATCH 033/117] clk: qcom: gcc-sm8750: Add a new frequency for sdcc2 clock The SD card support requires a 37.5MHz clock; add it to the frequency list for the storage SW driver to be able to request for the frequency. Fixes: 3267c774f3ff ("clk: qcom: Add support for GCC on SM8750") Signed-off-by: Taniya Das Reviewed-by: Imran Shaik Link: https://lore.kernel.org/r/20250924-sm8750_gcc_sdcc2_frequency-v1-1-541fd321125f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm8750.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/gcc-sm8750.c b/drivers/clk/qcom/gcc-sm8750.c index 8092dd6b37b5..def86b71a3da 100644 --- a/drivers/clk/qcom/gcc-sm8750.c +++ b/drivers/clk/qcom/gcc-sm8750.c @@ -1012,6 +1012,7 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { F(400000, P_BI_TCXO, 12, 1, 4), F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0), F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), From 18da820eb632fbd99167f3fc6650a30db714ddfd Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Thu, 25 Sep 2025 15:49:00 +0530 Subject: [PATCH 034/117] clk: qcom: gcc-glymur: Update the halt check flags for pipe clocks The pipe clocks for PCIE and USB are externally sourced and they should not be polled by the clock driver. Update the halt_check flags to 'SKIP' to disable polling for these clocks. This helps avoid the clock status stuck at 'off' warnings, which are benign, since all consumers of the PHYs must initialize a given instance before performing any operations. Fixes: efe504300a17 ("clk: qcom: gcc: Add support for Global Clock Controller") Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250925-glymur_gcc_usb_fixes-v2-1-ee4619571efe@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-glymur.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c index 62059120f972..d938e7dc5b66 100644 --- a/drivers/clk/qcom/gcc-glymur.c +++ b/drivers/clk/qcom/gcc-glymur.c @@ -6760,7 +6760,7 @@ static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .halt_reg = 0x3f088, - .halt_check = BRANCH_HALT_DELAY, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x3f088, .hwcg_bit = 1, .clkr = { @@ -6816,7 +6816,7 @@ static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = { static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { .halt_reg = 0xe2078, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xe2078, .hwcg_bit = 1, .clkr = { @@ -6872,7 +6872,7 @@ static struct clk_branch gcc_usb3_tert_phy_com_aux_clk = { static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { .halt_reg = 0xe1078, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xe1078, .hwcg_bit = 1, .clkr = { @@ -6961,7 +6961,7 @@ static struct clk_branch gcc_usb4_0_master_clk = { static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { .halt_reg = 0x2b0f4, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b0f4, .enable_mask = BIT(0), @@ -6979,7 +6979,7 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { .halt_reg = 0x2b04c, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x62010, .enable_mask = BIT(11), @@ -7033,7 +7033,7 @@ static struct clk_branch gcc_usb4_0_phy_rx1_clk = { static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { .halt_reg = 0x2b0bc, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x2b0bc, .hwcg_bit = 1, .clkr = { @@ -7196,7 +7196,7 @@ static struct clk_branch gcc_usb4_1_master_clk = { static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { .halt_reg = 0x2d118, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2d118, .enable_mask = BIT(0), @@ -7214,7 +7214,7 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { .halt_reg = 0x2d04c, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x62010, .enable_mask = BIT(12), @@ -7268,7 +7268,7 @@ static struct clk_branch gcc_usb4_1_phy_rx1_clk = { static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { .halt_reg = 0x2d0e0, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x2d0e0, .hwcg_bit = 1, .clkr = { @@ -7431,7 +7431,7 @@ static struct clk_branch gcc_usb4_2_master_clk = { static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { .halt_reg = 0xe00f8, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0xe00f8, .enable_mask = BIT(0), @@ -7449,7 +7449,7 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { .halt_reg = 0xe004c, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x62010, .enable_mask = BIT(13), @@ -7503,7 +7503,7 @@ static struct clk_branch gcc_usb4_2_phy_rx1_clk = { static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { .halt_reg = 0xe00c0, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xe00c0, .hwcg_bit = 1, .clkr = { From f0691a3f7558d33b5b4a900e8312613fbe4afb9d Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 30 Sep 2025 11:56:08 -0700 Subject: [PATCH 035/117] clk: qcom: Fix SM_VIDEOCC_6350 dependencies It is possible to select CONFIG_SM_GCC_6350 when targeting ARCH=arm, causing a Kconfig warning when selecting CONFIG_SM_GCC_6350 without its dependencies, CONFIG_ARM64 or CONFIG_COMPILE_TEST. WARNING: unmet direct dependencies detected for SM_GCC_6350 Depends on [n]: COMMON_CLK [=y] && COMMON_CLK_QCOM [=m] && (ARM64 || COMPILE_TEST [=n]) Selected by [m]: - SM_VIDEOCC_6350 [=m] && COMMON_CLK [=y] && COMMON_CLK_QCOM [=m] Add the same dependency to clear up the warning. Cc: stable@vger.kernel.org Fixes: 720b1e8f2004 ("clk: qcom: Add video clock controller driver for SM6350") Signed-off-by: Nathan Chancellor Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250930-clk-qcom-kconfig-fixes-arm-v1-1-15ae1ae9ec9f@kernel.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 78a303842613..ec7d1a9b578e 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1448,6 +1448,7 @@ config SA_VIDEOCC_8775P config SM_VIDEOCC_6350 tristate "SM6350 Video Clock Controller" + depends on ARM64 || COMPILE_TEST select SM_GCC_6350 select QCOM_GDSC help From 7ec1ba01ae37897f0ecf6ab0c980378cb8a2f388 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 30 Sep 2025 11:56:09 -0700 Subject: [PATCH 036/117] clk: qcom: Fix dependencies of QCS_{DISP,GPU,VIDEO}CC_615 It is possible to select CONFIG_QCS_{DISP,GPU,VIDEO}CC_615 when targeting ARCH=arm, causing a Kconfig warning when selecting CONFIG_QCS_GCC_615 without its dependencies, CONFIG_ARM64 or CONFIG_COMPILE_TEST. WARNING: unmet direct dependencies detected for QCS_GCC_615 Depends on [n]: COMMON_CLK [=y] && COMMON_CLK_QCOM [=m] && (ARM64 || COMPILE_TEST [=n]) Selected by [m]: - QCS_DISPCC_615 [=m] && COMMON_CLK [=y] && COMMON_CLK_QCOM [=m] - QCS_GPUCC_615 [=m] && COMMON_CLK [=y] && COMMON_CLK_QCOM [=m] - QCS_VIDEOCC_615 [=m] && COMMON_CLK [=y] && COMMON_CLK_QCOM [=m] Add the same dependency to these configurations to clear up the warnings. Cc: stable@vger.kernel.org Fixes: 9b47105f5434 ("clk: qcom: dispcc-qcs615: Add QCS615 display clock controller driver") Fixes: f4b5b40805ab ("clk: qcom: gpucc-qcs615: Add QCS615 graphics clock controller driver") Fixes: f6a8abe0cc16 ("clk: qcom: videocc-qcs615: Add QCS615 video clock controller driver") Signed-off-by: Nathan Chancellor Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250930-clk-qcom-kconfig-fixes-arm-v1-2-15ae1ae9ec9f@kernel.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index ec7d1a9b578e..6fef0bfc1773 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -531,6 +531,7 @@ config QCM_DISPCC_2290 config QCS_DISPCC_615 tristate "QCS615 Display Clock Controller" + depends on ARM64 || COMPILE_TEST select QCS_GCC_615 help Support for the display clock controller on Qualcomm Technologies, Inc @@ -586,6 +587,7 @@ config QCS_GCC_615 config QCS_GPUCC_615 tristate "QCS615 Graphics clock controller" + depends on ARM64 || COMPILE_TEST select QCS_GCC_615 help Support for the graphics clock controller on QCS615 devices. @@ -594,6 +596,7 @@ config QCS_GPUCC_615 config QCS_VIDEOCC_615 tristate "QCS615 Video Clock Controller" + depends on ARM64 || COMPILE_TEST select QCS_GCC_615 help Support for the video clock controller on QCS615 devices. From 205a5d29b47ecd6ffbc53b02a3952684d6720fd7 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 10 Oct 2025 12:24:50 +0200 Subject: [PATCH 037/117] clk: qcom: gcc-sc8280xp: Remove 85.71 MHz USB4 master clock frequency The USB4 HPG says this frequency remains unused, remove it from the frequency table to avoid any misunderstandings. The reason it's unused seems to be that the lower RPMh level required to support it (LOW_SVS) is not enough for other pieces of the pipeline which require SVS, which in turn is enough to support a faster, 175 MHz rate. Signed-off-by: Konrad Dybcio Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20251010-topic-gcc_usb4_unused_freq-v1-1-4be5e77d2307@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sc8280xp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c index b683795475e3..2ab111585d7f 100644 --- a/drivers/clk/qcom/gcc-sc8280xp.c +++ b/drivers/clk/qcom/gcc-sc8280xp.c @@ -2224,7 +2224,6 @@ static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = { }; static const struct freq_tbl ftbl_gcc_usb4_1_master_clk_src[] = { - F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0), F(175000000, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0), F(350000000, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0), { } From 54e5da4d1fbccf03042de1ecfa33987e2ff80268 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 10 Oct 2025 12:24:51 +0200 Subject: [PATCH 038/117] clk: qcom: gcc-x1e80100: Remove 85.71 MHz USB4 master clock frequency The USB4 HPG says this frequency remains unused, remove it from the frequency table to avoid any misunderstandings. The reason it's unused seems to be that the lower RPMh level required to support it (LOW_SVS) is not enough for other pieces of the pipeline which require SVS, which in turn is enough to support a faster, 175 MHz rate. Signed-off-by: Konrad Dybcio Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20251010-topic-gcc_usb4_unused_freq-v1-2-4be5e77d2307@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-x1e80100.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index 8804ad5d70be..b63c8abdd2fc 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -1849,7 +1849,6 @@ static struct clk_rcg2 gcc_usb3_tert_phy_aux_clk_src = { }; static const struct freq_tbl ftbl_gcc_usb4_0_master_clk_src[] = { - F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0), F(175000000, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0), F(350000000, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0), { } From 5e26bb2a17789754e44aec2519fa719bd1fc04e0 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 10 Oct 2025 12:24:52 +0200 Subject: [PATCH 039/117] clk: qcom: gcc-glymur: Remove 85.71 MHz USB4 master clock frequency The USB4 HPG says this frequency remains unused, remove it from the frequency table to avoid any misunderstandings. The reason it's unused seems to be that the lower RPMh level required to support it (LOW_SVS) is not enough for other pieces of the pipeline which require SVS, which in turn is enough to support a faster, 175-ish MHz rate. Signed-off-by: Konrad Dybcio Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20251010-topic-gcc_usb4_unused_freq-v1-3-4be5e77d2307@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-glymur.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c index d938e7dc5b66..deab819576d0 100644 --- a/drivers/clk/qcom/gcc-glymur.c +++ b/drivers/clk/qcom/gcc-glymur.c @@ -2643,7 +2643,6 @@ static struct clk_rcg2 gcc_usb3_tert_phy_aux_clk_src = { }; static const struct freq_tbl ftbl_gcc_usb4_0_master_clk_src[] = { - F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0), F(177666750, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0), F(355333500, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0), { } From 464ce94531f5a62ce29081a9d3c70eb4d525f443 Mon Sep 17 00:00:00 2001 From: Luo Jie Date: Tue, 14 Oct 2025 22:35:26 +0800 Subject: [PATCH 040/117] clk: qcom: gcc-ipq5424: Correct the icc_first_node_id Update to use the expected icc_first_node_id for registering the icc clocks, ensuring correct association of clocks with interconnect nodes. Fixes: 170f3d2c065e ("clk: qcom: ipq5424: Use icc-clk for enabling NoC related clocks") Reviewed-by: Konrad Dybcio Signed-off-by: Luo Jie Link: https://lore.kernel.org/r/20251014-qcom_ipq5424_nsscc-v7-1-081f4956be02@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5424.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 3d42f3d85c7a..71afa1b86b72 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -3284,6 +3284,7 @@ static const struct qcom_cc_desc gcc_ipq5424_desc = { .num_clk_hws = ARRAY_SIZE(gcc_ipq5424_hws), .icc_hws = icc_ipq5424_hws, .num_icc_hws = ARRAY_SIZE(icc_ipq5424_hws), + .icc_first_node_id = IPQ_APPS_ID, }; static int gcc_ipq5424_probe(struct platform_device *pdev) From e2cf3b73573e24283e1c640eb9a186cfe3c01d84 Mon Sep 17 00:00:00 2001 From: Luo Jie Date: Tue, 14 Oct 2025 22:35:29 +0800 Subject: [PATCH 041/117] clk: qcom: gcc-ipq5424: Enable NSS NoC clocks to use icc-clk Add NSS NoC clocks using the icc-clk framework to create interconnect paths. The network subsystem (NSS) can be connected to these NoCs. Additionally, add the LPASS CNOC and SNOC nodes to establish the complete interconnect path. Reviewed-by: Konrad Dybcio Signed-off-by: Luo Jie Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251014-qcom_ipq5424_nsscc-v7-4-081f4956be02@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5424.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 71afa1b86b72..6cfe4f2b2888 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -3250,6 +3250,16 @@ static const struct qcom_icc_hws_data icc_ipq5424_hws[] = { { MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK }, { MASTER_CNOC_PCIE3, SLAVE_CNOC_PCIE3, GCC_CNOC_PCIE3_2LANE_S_CLK }, { MASTER_CNOC_USB, SLAVE_CNOC_USB, GCC_CNOC_USB_CLK }, + { MASTER_NSSNOC_NSSCC, SLAVE_NSSNOC_NSSCC, GCC_NSSNOC_NSSCC_CLK }, + { MASTER_NSSNOC_SNOC_0, SLAVE_NSSNOC_SNOC_0, GCC_NSSNOC_SNOC_CLK }, + { MASTER_NSSNOC_SNOC_1, SLAVE_NSSNOC_SNOC_1, GCC_NSSNOC_SNOC_1_CLK }, + { MASTER_NSSNOC_PCNOC_1, SLAVE_NSSNOC_PCNOC_1, GCC_NSSNOC_PCNOC_1_CLK }, + { MASTER_NSSNOC_QOSGEN_REF, SLAVE_NSSNOC_QOSGEN_REF, GCC_NSSNOC_QOSGEN_REF_CLK }, + { MASTER_NSSNOC_TIMEOUT_REF, SLAVE_NSSNOC_TIMEOUT_REF, GCC_NSSNOC_TIMEOUT_REF_CLK }, + { MASTER_NSSNOC_XO_DCD, SLAVE_NSSNOC_XO_DCD, GCC_NSSNOC_XO_DCD_CLK }, + { MASTER_NSSNOC_ATB, SLAVE_NSSNOC_ATB, GCC_NSSNOC_ATB_CLK }, + { MASTER_CNOC_LPASS_CFG, SLAVE_CNOC_LPASS_CFG, GCC_CNOC_LPASS_CFG_CLK }, + { MASTER_SNOC_LPASS, SLAVE_SNOC_LPASS, GCC_SNOC_LPASS_CLK }, }; static const struct of_device_id gcc_ipq5424_match_table[] = { From d08882c66d7a929c321cfaca9dee64e40eba3bd2 Mon Sep 17 00:00:00 2001 From: Luo Jie Date: Tue, 14 Oct 2025 22:35:31 +0800 Subject: [PATCH 042/117] clk: qcom: gcc-ipq5424: Add gpll0_out_aux clock The clock gpll0_out_aux acts as the parent clock for some of the NSS (Network Subsystem) clocks. Reviewed-by: Konrad Dybcio Signed-off-by: Luo Jie Link: https://lore.kernel.org/r/20251014-qcom_ipq5424_nsscc-v7-6-081f4956be02@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5424.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 6cfe4f2b2888..35af6ffeeb85 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -79,6 +79,20 @@ static struct clk_fixed_factor gpll0_div2 = { }, }; +static struct clk_alpha_pll_postdiv gpll0_out_aux = { + .offset = 0x20000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll0_out_aux", + .parent_hws = (const struct clk_hw *[]) { + &gpll0.clkr.hw + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + static struct clk_alpha_pll gpll2 = { .offset = 0x21000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_NSS_HUAYRA], @@ -2934,6 +2948,7 @@ static struct clk_regmap *gcc_ipq5424_clocks[] = { [GPLL2] = &gpll2.clkr, [GPLL2_OUT_MAIN] = &gpll2_out_main.clkr, [GPLL4] = &gpll4.clkr, + [GPLL0_OUT_AUX] = &gpll0_out_aux.clkr, }; static const struct qcom_reset_map gcc_ipq5424_resets[] = { From fd0b632efbbdf427678a7a880abeb828bc4633fe Mon Sep 17 00:00:00 2001 From: Luo Jie Date: Tue, 14 Oct 2025 22:35:33 +0800 Subject: [PATCH 043/117] clk: qcom: Add NSS clock controller driver for IPQ5424 NSS (Network Subsystem) clock controller provides the clocks and resets to the networking hardware blocks of the IPQ5424 SoC. The icc-clk framework is used to enable NoC related clocks to create paths so that the networking blocks can connect to these NoCs. Acked-by: Konrad Dybcio Signed-off-by: Luo Jie Link: https://lore.kernel.org/r/20251014-qcom_ipq5424_nsscc-v7-8-081f4956be02@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 11 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/nsscc-ipq5424.c | 1340 ++++++++++++++++++++++++++++++ 3 files changed, 1352 insertions(+) create mode 100644 drivers/clk/qcom/nsscc-ipq5424.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 6fef0bfc1773..4a78099e706c 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -317,6 +317,17 @@ config IPQ_GCC_9574 i2c, USB, SD/eMMC, etc. Select this for the root clock of ipq9574. +config IPQ_NSSCC_5424 + tristate "IPQ5424 NSS Clock Controller" + depends on ARM64 || COMPILE_TEST + depends on IPQ_GCC_5424 + help + Support for NSS clock controller on ipq5424 devices. + NSSCC receives the clock sources from GCC, CMN PLL and UNIPHY (PCS). + It in turn supplies the clocks and resets to the networking hardware. + Say Y or M if you want to enable networking function on the + IPQ5424 devices. + config IPQ_NSSCC_9574 tristate "IPQ9574 NSS Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 8051d481c439..5a0fd1d843c8 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o obj-$(CONFIG_IPQ_GCC_9574) += gcc-ipq9574.o +obj-$(CONFIG_IPQ_NSSCC_5424) += nsscc-ipq5424.o obj-$(CONFIG_IPQ_NSSCC_9574) += nsscc-ipq9574.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o obj-$(CONFIG_IPQ_NSSCC_QCA8K) += nsscc-qca8k.o diff --git a/drivers/clk/qcom/nsscc-ipq5424.c b/drivers/clk/qcom/nsscc-ipq5424.c new file mode 100644 index 000000000000..5893c7146180 --- /dev/null +++ b/drivers/clk/qcom/nsscc-ipq5424.c @@ -0,0 +1,1340 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "reset.h" + +/* Need to match the order of clocks in DT binding */ +enum { + DT_CMN_PLL_XO_CLK, + DT_CMN_PLL_NSS_300M_CLK, + DT_CMN_PLL_NSS_375M_CLK, + DT_GCC_GPLL0_OUT_AUX, + DT_UNIPHY0_NSS_RX_CLK, + DT_UNIPHY0_NSS_TX_CLK, + DT_UNIPHY1_NSS_RX_CLK, + DT_UNIPHY1_NSS_TX_CLK, + DT_UNIPHY2_NSS_RX_CLK, + DT_UNIPHY2_NSS_TX_CLK, +}; + +enum { + P_CMN_PLL_XO_CLK, + P_CMN_PLL_NSS_300M_CLK, + P_CMN_PLL_NSS_375M_CLK, + P_GCC_GPLL0_OUT_AUX, + P_UNIPHY0_NSS_RX_CLK, + P_UNIPHY0_NSS_TX_CLK, + P_UNIPHY1_NSS_RX_CLK, + P_UNIPHY1_NSS_TX_CLK, + P_UNIPHY2_NSS_RX_CLK, + P_UNIPHY2_NSS_TX_CLK, +}; + +static const struct parent_map nss_cc_parent_map_0[] = { + { P_CMN_PLL_XO_CLK, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_CMN_PLL_NSS_300M_CLK, 5 }, + { P_CMN_PLL_NSS_375M_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_0[] = { + { .index = DT_CMN_PLL_XO_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_CMN_PLL_NSS_300M_CLK }, + { .index = DT_CMN_PLL_NSS_375M_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_1[] = { + { P_CMN_PLL_XO_CLK, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_UNIPHY0_NSS_RX_CLK, 3 }, + { P_UNIPHY0_NSS_TX_CLK, 4 }, + { P_CMN_PLL_NSS_300M_CLK, 5 }, + { P_CMN_PLL_NSS_375M_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_1[] = { + { .index = DT_CMN_PLL_XO_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_UNIPHY0_NSS_RX_CLK }, + { .index = DT_UNIPHY0_NSS_TX_CLK }, + { .index = DT_CMN_PLL_NSS_300M_CLK }, + { .index = DT_CMN_PLL_NSS_375M_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_2[] = { + { P_CMN_PLL_XO_CLK, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_UNIPHY1_NSS_RX_CLK, 3 }, + { P_UNIPHY1_NSS_TX_CLK, 4 }, + { P_CMN_PLL_NSS_300M_CLK, 5 }, + { P_CMN_PLL_NSS_375M_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_2[] = { + { .index = DT_CMN_PLL_XO_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_UNIPHY1_NSS_RX_CLK }, + { .index = DT_UNIPHY1_NSS_TX_CLK }, + { .index = DT_CMN_PLL_NSS_300M_CLK }, + { .index = DT_CMN_PLL_NSS_375M_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_3[] = { + { P_CMN_PLL_XO_CLK, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_UNIPHY2_NSS_RX_CLK, 3 }, + { P_UNIPHY2_NSS_TX_CLK, 4 }, + { P_CMN_PLL_NSS_300M_CLK, 5 }, + { P_CMN_PLL_NSS_375M_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_3[] = { + { .index = DT_CMN_PLL_XO_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_UNIPHY2_NSS_RX_CLK }, + { .index = DT_UNIPHY2_NSS_TX_CLK }, + { .index = DT_CMN_PLL_NSS_300M_CLK }, + { .index = DT_CMN_PLL_NSS_375M_CLK }, +}; + +static const struct freq_tbl ftbl_nss_cc_ce_clk_src[] = { + F(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + F(375000000, P_CMN_PLL_NSS_375M_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_ce_clk_src = { + .cmd_rcgr = 0x5e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ce_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_cfg_clk_src[] = { + F(100000000, P_GCC_GPLL0_OUT_AUX, 8, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_cfg_clk_src = { + .cmd_rcgr = 0x6a8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_tbl = ftbl_nss_cc_cfg_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_cfg_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_eip_bfdcd_clk_src[] = { + F(300000000, P_CMN_PLL_NSS_300M_CLK, 1, 0, 0), + F(375000000, P_CMN_PLL_NSS_375M_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_eip_bfdcd_clk_src = { + .cmd_rcgr = 0x644, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_tbl = ftbl_nss_cc_eip_bfdcd_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_eip_bfdcd_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port1_rx_clk_src_25[] = { + C(P_UNIPHY0_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port1_rx_clk_src_125[] = { + C(P_UNIPHY0_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port1_rx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port1_rx_clk_src_25), + FMS(78125000, P_UNIPHY0_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port1_rx_clk_src_125), + FMS(156250000, P_UNIPHY0_NSS_RX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY0_NSS_RX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port1_rx_clk_src = { + .cmd_rcgr = 0x4b4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_rx_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port1_tx_clk_src_25[] = { + C(P_UNIPHY0_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port1_tx_clk_src_125[] = { + C(P_UNIPHY0_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port1_tx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port1_tx_clk_src_25), + FMS(78125000, P_UNIPHY0_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port1_tx_clk_src_125), + FMS(156250000, P_UNIPHY0_NSS_TX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY0_NSS_TX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port1_tx_clk_src = { + .cmd_rcgr = 0x4c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_tx_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port2_rx_clk_src_25[] = { + C(P_UNIPHY1_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY1_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port2_rx_clk_src_125[] = { + C(P_UNIPHY1_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY1_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port2_rx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port2_rx_clk_src_25), + FMS(78125000, P_UNIPHY1_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port2_rx_clk_src_125), + FMS(156250000, P_UNIPHY1_NSS_RX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY1_NSS_RX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port2_rx_clk_src = { + .cmd_rcgr = 0x4cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_2, + .freq_multi_tbl = ftbl_nss_cc_port2_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_rx_clk_src", + .parent_data = nss_cc_parent_data_2, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_2), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port2_tx_clk_src_25[] = { + C(P_UNIPHY1_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY1_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port2_tx_clk_src_125[] = { + C(P_UNIPHY1_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY1_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port2_tx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port2_tx_clk_src_25), + FMS(78125000, P_UNIPHY1_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port2_tx_clk_src_125), + FMS(156250000, P_UNIPHY1_NSS_TX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY1_NSS_TX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port2_tx_clk_src = { + .cmd_rcgr = 0x4d8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_2, + .freq_multi_tbl = ftbl_nss_cc_port2_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_tx_clk_src", + .parent_data = nss_cc_parent_data_2, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_2), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port3_rx_clk_src_25[] = { + C(P_UNIPHY2_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY2_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port3_rx_clk_src_125[] = { + C(P_UNIPHY2_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY2_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port3_rx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port3_rx_clk_src_25), + FMS(78125000, P_UNIPHY2_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port3_rx_clk_src_125), + FMS(156250000, P_UNIPHY2_NSS_RX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY2_NSS_RX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port3_rx_clk_src = { + .cmd_rcgr = 0x4e4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_3, + .freq_multi_tbl = ftbl_nss_cc_port3_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_rx_clk_src", + .parent_data = nss_cc_parent_data_3, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_3), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port3_tx_clk_src_25[] = { + C(P_UNIPHY2_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY2_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port3_tx_clk_src_125[] = { + C(P_UNIPHY2_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY2_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port3_tx_clk_src[] = { + FMS(24000000, P_CMN_PLL_XO_CLK, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port3_tx_clk_src_25), + FMS(78125000, P_UNIPHY2_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port3_tx_clk_src_125), + FMS(156250000, P_UNIPHY2_NSS_TX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY2_NSS_TX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port3_tx_clk_src = { + .cmd_rcgr = 0x4f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_3, + .freq_multi_tbl = ftbl_nss_cc_port3_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_tx_clk_src", + .parent_data = nss_cc_parent_data_3, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_3), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_ppe_clk_src = { + .cmd_rcgr = 0x3ec, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port1_rx_div_clk_src = { + .reg = 0x4bc, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_rx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port1_tx_div_clk_src = { + .reg = 0x4c8, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_tx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port2_rx_div_clk_src = { + .reg = 0x4d4, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_rx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port2_tx_div_clk_src = { + .reg = 0x4e0, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_tx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port3_rx_div_clk_src = { + .reg = 0x4ec, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_rx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port3_tx_div_clk_src = { + .reg = 0x4f8, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_tx_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac0_ptp_ref_div_clk_src = { + .reg = 0x3f4, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac0_ptp_ref_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac1_ptp_ref_div_clk_src = { + .reg = 0x3f8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac1_ptp_ref_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac2_ptp_ref_div_clk_src = { + .reg = 0x3fc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac2_ptp_ref_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch nss_cc_ce_apb_clk = { + .halt_reg = 0x5e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ce_apb_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ce_axi_clk = { + .halt_reg = 0x5ec, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ce_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_debug_clk = { + .halt_reg = 0x70c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x70c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_debug_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_eip_clk = { + .halt_reg = 0x658, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x658, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_eip_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_eip_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nss_csr_clk = { + .halt_reg = 0x6b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nss_csr_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ce_apb_clk = { + .halt_reg = 0x5f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_ce_apb_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ce_axi_clk = { + .halt_reg = 0x5f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_ce_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_eip_clk = { + .halt_reg = 0x660, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x660, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_eip_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_eip_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_nss_csr_clk = { + .halt_reg = 0x6b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_nss_csr_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ppe_cfg_clk = { + .halt_reg = 0x444, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x444, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_ppe_cfg_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ppe_clk = { + .halt_reg = 0x440, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x440, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_nssnoc_ppe_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_mac_clk = { + .halt_reg = 0x428, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x428, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_mac_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_rx_clk = { + .halt_reg = 0x4fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_tx_clk = { + .halt_reg = 0x504, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x504, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port1_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_mac_clk = { + .halt_reg = 0x430, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x430, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_mac_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_rx_clk = { + .halt_reg = 0x50c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_tx_clk = { + .halt_reg = 0x514, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x514, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port2_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_mac_clk = { + .halt_reg = 0x438, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x438, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_mac_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_rx_clk = { + .halt_reg = 0x51c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_tx_clk = { + .halt_reg = 0x524, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x524, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_port3_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_edma_cfg_clk = { + .halt_reg = 0x424, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x424, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_edma_cfg_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_edma_clk = { + .halt_reg = 0x41c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_edma_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_btq_clk = { + .halt_reg = 0x408, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x408, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_switch_btq_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_cfg_clk = { + .halt_reg = 0x418, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x418, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_switch_cfg_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_clk = { + .halt_reg = 0x410, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x410, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_switch_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_ipe_clk = { + .halt_reg = 0x400, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x400, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_ppe_switch_ipe_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port1_rx_clk = { + .halt_reg = 0x57c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x57c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port1_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port1_tx_clk = { + .halt_reg = 0x580, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x580, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port1_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port2_rx_clk = { + .halt_reg = 0x584, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x584, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port2_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port2_tx_clk = { + .halt_reg = 0x588, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x588, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port2_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port3_rx_clk = { + .halt_reg = 0x58c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port3_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port3_tx_clk = { + .halt_reg = 0x590, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x590, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_uniphy_port3_tx_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_port3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac0_ptp_ref_clk = { + .halt_reg = 0x448, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x448, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_xgmac0_ptp_ref_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_xgmac0_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac1_ptp_ref_clk = { + .halt_reg = 0x44c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x44c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_xgmac1_ptp_ref_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_xgmac1_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac2_ptp_ref_clk = { + .halt_reg = 0x450, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x450, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "nss_cc_xgmac2_ptp_ref_clk", + .parent_hws = (const struct clk_hw*[]){ + &nss_cc_xgmac2_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *nss_cc_ipq5424_clocks[] = { + [NSS_CC_CE_APB_CLK] = &nss_cc_ce_apb_clk.clkr, + [NSS_CC_CE_AXI_CLK] = &nss_cc_ce_axi_clk.clkr, + [NSS_CC_CE_CLK_SRC] = &nss_cc_ce_clk_src.clkr, + [NSS_CC_CFG_CLK_SRC] = &nss_cc_cfg_clk_src.clkr, + [NSS_CC_DEBUG_CLK] = &nss_cc_debug_clk.clkr, + [NSS_CC_EIP_BFDCD_CLK_SRC] = &nss_cc_eip_bfdcd_clk_src.clkr, + [NSS_CC_EIP_CLK] = &nss_cc_eip_clk.clkr, + [NSS_CC_NSS_CSR_CLK] = &nss_cc_nss_csr_clk.clkr, + [NSS_CC_NSSNOC_CE_APB_CLK] = &nss_cc_nssnoc_ce_apb_clk.clkr, + [NSS_CC_NSSNOC_CE_AXI_CLK] = &nss_cc_nssnoc_ce_axi_clk.clkr, + [NSS_CC_NSSNOC_EIP_CLK] = &nss_cc_nssnoc_eip_clk.clkr, + [NSS_CC_NSSNOC_NSS_CSR_CLK] = &nss_cc_nssnoc_nss_csr_clk.clkr, + [NSS_CC_NSSNOC_PPE_CFG_CLK] = &nss_cc_nssnoc_ppe_cfg_clk.clkr, + [NSS_CC_NSSNOC_PPE_CLK] = &nss_cc_nssnoc_ppe_clk.clkr, + [NSS_CC_PORT1_MAC_CLK] = &nss_cc_port1_mac_clk.clkr, + [NSS_CC_PORT1_RX_CLK] = &nss_cc_port1_rx_clk.clkr, + [NSS_CC_PORT1_RX_CLK_SRC] = &nss_cc_port1_rx_clk_src.clkr, + [NSS_CC_PORT1_RX_DIV_CLK_SRC] = &nss_cc_port1_rx_div_clk_src.clkr, + [NSS_CC_PORT1_TX_CLK] = &nss_cc_port1_tx_clk.clkr, + [NSS_CC_PORT1_TX_CLK_SRC] = &nss_cc_port1_tx_clk_src.clkr, + [NSS_CC_PORT1_TX_DIV_CLK_SRC] = &nss_cc_port1_tx_div_clk_src.clkr, + [NSS_CC_PORT2_MAC_CLK] = &nss_cc_port2_mac_clk.clkr, + [NSS_CC_PORT2_RX_CLK] = &nss_cc_port2_rx_clk.clkr, + [NSS_CC_PORT2_RX_CLK_SRC] = &nss_cc_port2_rx_clk_src.clkr, + [NSS_CC_PORT2_RX_DIV_CLK_SRC] = &nss_cc_port2_rx_div_clk_src.clkr, + [NSS_CC_PORT2_TX_CLK] = &nss_cc_port2_tx_clk.clkr, + [NSS_CC_PORT2_TX_CLK_SRC] = &nss_cc_port2_tx_clk_src.clkr, + [NSS_CC_PORT2_TX_DIV_CLK_SRC] = &nss_cc_port2_tx_div_clk_src.clkr, + [NSS_CC_PORT3_MAC_CLK] = &nss_cc_port3_mac_clk.clkr, + [NSS_CC_PORT3_RX_CLK] = &nss_cc_port3_rx_clk.clkr, + [NSS_CC_PORT3_RX_CLK_SRC] = &nss_cc_port3_rx_clk_src.clkr, + [NSS_CC_PORT3_RX_DIV_CLK_SRC] = &nss_cc_port3_rx_div_clk_src.clkr, + [NSS_CC_PORT3_TX_CLK] = &nss_cc_port3_tx_clk.clkr, + [NSS_CC_PORT3_TX_CLK_SRC] = &nss_cc_port3_tx_clk_src.clkr, + [NSS_CC_PORT3_TX_DIV_CLK_SRC] = &nss_cc_port3_tx_div_clk_src.clkr, + [NSS_CC_PPE_CLK_SRC] = &nss_cc_ppe_clk_src.clkr, + [NSS_CC_PPE_EDMA_CFG_CLK] = &nss_cc_ppe_edma_cfg_clk.clkr, + [NSS_CC_PPE_EDMA_CLK] = &nss_cc_ppe_edma_clk.clkr, + [NSS_CC_PPE_SWITCH_BTQ_CLK] = &nss_cc_ppe_switch_btq_clk.clkr, + [NSS_CC_PPE_SWITCH_CFG_CLK] = &nss_cc_ppe_switch_cfg_clk.clkr, + [NSS_CC_PPE_SWITCH_CLK] = &nss_cc_ppe_switch_clk.clkr, + [NSS_CC_PPE_SWITCH_IPE_CLK] = &nss_cc_ppe_switch_ipe_clk.clkr, + [NSS_CC_UNIPHY_PORT1_RX_CLK] = &nss_cc_uniphy_port1_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT1_TX_CLK] = &nss_cc_uniphy_port1_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT2_RX_CLK] = &nss_cc_uniphy_port2_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT2_TX_CLK] = &nss_cc_uniphy_port2_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT3_RX_CLK] = &nss_cc_uniphy_port3_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT3_TX_CLK] = &nss_cc_uniphy_port3_tx_clk.clkr, + [NSS_CC_XGMAC0_PTP_REF_CLK] = &nss_cc_xgmac0_ptp_ref_clk.clkr, + [NSS_CC_XGMAC0_PTP_REF_DIV_CLK_SRC] = &nss_cc_xgmac0_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC1_PTP_REF_CLK] = &nss_cc_xgmac1_ptp_ref_clk.clkr, + [NSS_CC_XGMAC1_PTP_REF_DIV_CLK_SRC] = &nss_cc_xgmac1_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC2_PTP_REF_CLK] = &nss_cc_xgmac2_ptp_ref_clk.clkr, + [NSS_CC_XGMAC2_PTP_REF_DIV_CLK_SRC] = &nss_cc_xgmac2_ptp_ref_div_clk_src.clkr, +}; + +static const struct qcom_reset_map nss_cc_ipq5424_resets[] = { + [NSS_CC_CE_APB_CLK_ARES] = { 0x5e8, 2 }, + [NSS_CC_CE_AXI_CLK_ARES] = { 0x5ec, 2 }, + [NSS_CC_DEBUG_CLK_ARES] = { 0x70c, 2 }, + [NSS_CC_EIP_CLK_ARES] = { 0x658, 2 }, + [NSS_CC_NSS_CSR_CLK_ARES] = { 0x6b0, 2 }, + [NSS_CC_NSSNOC_CE_APB_CLK_ARES] = { 0x5f4, 2 }, + [NSS_CC_NSSNOC_CE_AXI_CLK_ARES] = { 0x5f8, 2 }, + [NSS_CC_NSSNOC_EIP_CLK_ARES] = { 0x660, 2 }, + [NSS_CC_NSSNOC_NSS_CSR_CLK_ARES] = { 0x6b4, 2 }, + [NSS_CC_NSSNOC_PPE_CLK_ARES] = { 0x440, 2 }, + [NSS_CC_NSSNOC_PPE_CFG_CLK_ARES] = { 0x444, 2 }, + [NSS_CC_PORT1_MAC_CLK_ARES] = { 0x428, 2 }, + [NSS_CC_PORT1_RX_CLK_ARES] = { 0x4fc, 2 }, + [NSS_CC_PORT1_TX_CLK_ARES] = { 0x504, 2 }, + [NSS_CC_PORT2_MAC_CLK_ARES] = { 0x430, 2 }, + [NSS_CC_PORT2_RX_CLK_ARES] = { 0x50c, 2 }, + [NSS_CC_PORT2_TX_CLK_ARES] = { 0x514, 2 }, + [NSS_CC_PORT3_MAC_CLK_ARES] = { 0x438, 2 }, + [NSS_CC_PORT3_RX_CLK_ARES] = { 0x51c, 2 }, + [NSS_CC_PORT3_TX_CLK_ARES] = { 0x524, 2 }, + [NSS_CC_PPE_BCR] = { 0x3e8 }, + [NSS_CC_PPE_EDMA_CLK_ARES] = { 0x41c, 2 }, + [NSS_CC_PPE_EDMA_CFG_CLK_ARES] = { 0x424, 2 }, + [NSS_CC_PPE_SWITCH_BTQ_CLK_ARES] = { 0x408, 2 }, + [NSS_CC_PPE_SWITCH_CLK_ARES] = { 0x410, 2 }, + [NSS_CC_PPE_SWITCH_CFG_CLK_ARES] = { 0x418, 2 }, + [NSS_CC_PPE_SWITCH_IPE_CLK_ARES] = { 0x400, 2 }, + [NSS_CC_UNIPHY_PORT1_RX_CLK_ARES] = { 0x57c, 2 }, + [NSS_CC_UNIPHY_PORT1_TX_CLK_ARES] = { 0x580, 2 }, + [NSS_CC_UNIPHY_PORT2_RX_CLK_ARES] = { 0x584, 2 }, + [NSS_CC_UNIPHY_PORT2_TX_CLK_ARES] = { 0x588, 2 }, + [NSS_CC_UNIPHY_PORT3_RX_CLK_ARES] = { 0x58c, 2 }, + [NSS_CC_UNIPHY_PORT3_TX_CLK_ARES] = { 0x590, 2 }, + [NSS_CC_XGMAC0_PTP_REF_CLK_ARES] = { 0x448, 2 }, + [NSS_CC_XGMAC1_PTP_REF_CLK_ARES] = { 0x44c, 2 }, + [NSS_CC_XGMAC2_PTP_REF_CLK_ARES] = { 0x450, 2 }, +}; + +static const struct regmap_config nss_cc_ipq5424_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x800, + .fast_io = true, +}; + +static const struct qcom_icc_hws_data icc_ipq5424_nss_hws[] = { + { MASTER_NSSNOC_PPE, SLAVE_NSSNOC_PPE, NSS_CC_NSSNOC_PPE_CLK }, + { MASTER_NSSNOC_PPE_CFG, SLAVE_NSSNOC_PPE_CFG, NSS_CC_NSSNOC_PPE_CFG_CLK }, + { MASTER_NSSNOC_NSS_CSR, SLAVE_NSSNOC_NSS_CSR, NSS_CC_NSSNOC_NSS_CSR_CLK }, + { MASTER_NSSNOC_CE_AXI, SLAVE_NSSNOC_CE_AXI, NSS_CC_NSSNOC_CE_AXI_CLK}, + { MASTER_NSSNOC_CE_APB, SLAVE_NSSNOC_CE_APB, NSS_CC_NSSNOC_CE_APB_CLK}, + { MASTER_NSSNOC_EIP, SLAVE_NSSNOC_EIP, NSS_CC_NSSNOC_EIP_CLK}, +}; + +#define IPQ_NSSCC_ID (5424 * 2) /* some unique value */ + +static const struct qcom_cc_desc nss_cc_ipq5424_desc = { + .config = &nss_cc_ipq5424_regmap_config, + .clks = nss_cc_ipq5424_clocks, + .num_clks = ARRAY_SIZE(nss_cc_ipq5424_clocks), + .resets = nss_cc_ipq5424_resets, + .num_resets = ARRAY_SIZE(nss_cc_ipq5424_resets), + .icc_hws = icc_ipq5424_nss_hws, + .num_icc_hws = ARRAY_SIZE(icc_ipq5424_nss_hws), + .icc_first_node_id = IPQ_NSSCC_ID, +}; + +static const struct dev_pm_ops nss_cc_ipq5424_pm_ops = { + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) +}; + +static const struct of_device_id nss_cc_ipq5424_match_table[] = { + { .compatible = "qcom,ipq5424-nsscc" }, + { } +}; +MODULE_DEVICE_TABLE(of, nss_cc_ipq5424_match_table); + +static int nss_cc_ipq5424_probe(struct platform_device *pdev) +{ + int ret; + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to enable runtime PM\n"); + + ret = devm_pm_clk_create(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to create PM clock\n"); + + ret = pm_clk_add(&pdev->dev, "bus"); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to add bus clock\n"); + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to resume\n"); + + ret = qcom_cc_probe(pdev, &nss_cc_ipq5424_desc); + pm_runtime_put(&pdev->dev); + + return ret; +} + +static struct platform_driver nss_cc_ipq5424_driver = { + .probe = nss_cc_ipq5424_probe, + .driver = { + .name = "qcom,ipq5424-nsscc", + .of_match_table = nss_cc_ipq5424_match_table, + .pm = &nss_cc_ipq5424_pm_ops, + .sync_state = icc_sync_state, + }, +}; +module_platform_driver(nss_cc_ipq5424_driver); + +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. NSSCC IPQ5424 Driver"); +MODULE_LICENSE("GPL"); From ab0e13141d679fdffdd3463a272c5c1b10be1794 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Tue, 21 Oct 2025 20:08:54 +0200 Subject: [PATCH 044/117] clk: qcom: camcc-sm6350: Fix PLL config of PLL2 The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the parameters that are provided in the vendor driver. Instead the upstream configuration should provide the final user_ctl value that is written to the USER_CTL register. Fix the config so that the PLL is configured correctly, and fixes CAMCC_MCLK* being stuck off. Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") Suggested-by: Taniya Das Signed-off-by: Luca Weiss Reviewed-by: Abel Vesa Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-1-8c1d8aff4afc@fairphone.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sm6350.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c index 6c272f7b0721..7df12c1311c6 100644 --- a/drivers/clk/qcom/camcc-sm6350.c +++ b/drivers/clk/qcom/camcc-sm6350.c @@ -145,15 +145,11 @@ static struct clk_alpha_pll_postdiv camcc_pll1_out_even = { static const struct alpha_pll_config camcc_pll2_config = { .l = 0x64, .alpha = 0x0, - .post_div_val = 0x3 << 8, - .post_div_mask = 0x3 << 8, - .aux_output_mask = BIT(1), - .main_output_mask = BIT(0), - .early_output_mask = BIT(3), .config_ctl_val = 0x20000800, .config_ctl_hi_val = 0x400003d2, .test_ctl_val = 0x04000400, .test_ctl_hi_val = 0x00004000, + .user_ctl_val = 0x0000030b, }; static struct clk_alpha_pll camcc_pll2 = { From 415aad75c7e5cdb72e0672dc1159be1a99535ecd Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Tue, 21 Oct 2025 20:08:55 +0200 Subject: [PATCH 045/117] clk: qcom: camcc-sm7150: Fix PLL config of PLL2 The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the parameters that are provided in the vendor driver. Instead the upstream configuration should provide the final user_ctl value that is written to the USER_CTL register. Fix the config so that the PLL is configured correctly. Fixes: 9f0532da4226 ("clk: qcom: Add Camera Clock Controller driver for SM7150") Suggested-by: Taniya Das Signed-off-by: Luca Weiss Reviewed-by: Abel Vesa Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-2-8c1d8aff4afc@fairphone.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sm7150.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c index 0e072ae39ec0..8b06af8d1509 100644 --- a/drivers/clk/qcom/camcc-sm7150.c +++ b/drivers/clk/qcom/camcc-sm7150.c @@ -139,13 +139,9 @@ static struct clk_fixed_factor camcc_pll1_out_even = { /* 1920MHz configuration */ static const struct alpha_pll_config camcc_pll2_config = { .l = 0x64, - .post_div_val = 0x3 << 8, - .post_div_mask = 0x3 << 8, - .early_output_mask = BIT(3), - .aux_output_mask = BIT(1), - .main_output_mask = BIT(0), .config_ctl_hi_val = 0x400003d6, .config_ctl_val = 0x20000954, + .user_ctl_val = 0x0000030b, }; static struct clk_alpha_pll camcc_pll2 = { From 2050b57ecda040010ec797fb07713889372c5041 Mon Sep 17 00:00:00 2001 From: Khairul Anuar Romli Date: Mon, 6 Oct 2025 11:10:15 +0800 Subject: [PATCH 046/117] clk: socfpga: agilex5: add clock driver for Agilex5 Add the new Clock manager driver to support new Agilex5 platform. The new driver got rid of the clk_parent_data structures as there are no 'clock-names' property in the DT bindings and use parent_names internally. This is based on the previous feedback from the maintainer. Signed-off-by: Ang Tien Sung Signed-off-by: Khairul Anuar Romli Signed-off-by: Dinh Nguyen --- drivers/clk/socfpga/Kconfig | 2 +- drivers/clk/socfpga/Makefile | 2 +- drivers/clk/socfpga/clk-agilex5.c | 561 +++++++++++++++++++++++++++ drivers/clk/socfpga/clk-gate-s10.c | 53 +++ drivers/clk/socfpga/clk-periph-s10.c | 41 ++ drivers/clk/socfpga/clk-pll-s10.c | 36 ++ drivers/clk/socfpga/stratix10-clk.h | 43 ++ 7 files changed, 736 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/socfpga/clk-agilex5.c diff --git a/drivers/clk/socfpga/Kconfig b/drivers/clk/socfpga/Kconfig index 0cf16b894efb..d88277e2a898 100644 --- a/drivers/clk/socfpga/Kconfig +++ b/drivers/clk/socfpga/Kconfig @@ -13,7 +13,7 @@ config CLK_INTEL_SOCFPGA32 default ARM && ARCH_INTEL_SOCFPGA config CLK_INTEL_SOCFPGA64 - bool "Intel Stratix / Agilex / N5X clock controller support" if COMPILE_TEST && (!ARM64 || !ARCH_INTEL_SOCFPGA) + bool "Intel Stratix / Agilex / N5X / Agilex5 clock controller support" if COMPILE_TEST && (!ARM64 || !ARCH_INTEL_SOCFPGA) default ARM64 && ARCH_INTEL_SOCFPGA endif # CLK_INTEL_SOCFPGA diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile index e8dfce339c91..a1ea2b988eaf 100644 --- a/drivers/clk/socfpga/Makefile +++ b/drivers/clk/socfpga/Makefile @@ -3,4 +3,4 @@ obj-$(CONFIG_CLK_INTEL_SOCFPGA32) += clk.o clk-gate.o clk-pll.o clk-periph.o \ clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o obj-$(CONFIG_CLK_INTEL_SOCFPGA64) += clk-s10.o \ clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o \ - clk-agilex.o + clk-agilex.o clk-agilex5.o diff --git a/drivers/clk/socfpga/clk-agilex5.c b/drivers/clk/socfpga/clk-agilex5.c new file mode 100644 index 000000000000..f7f0ad884f64 --- /dev/null +++ b/drivers/clk/socfpga/clk-agilex5.c @@ -0,0 +1,561 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022-2024, Intel Corporation + * Copyright (C) 2025, Altera Corporation + */ +#include +#include +#include +#include +#include +#include "stratix10-clk.h" +#include "clk.h" + +/* External parent clocks come from DT via fw_name */ +static const char * const boot_pll_parents[] = { + "osc1", + "cb-intosc-hs-div2-clk", +}; + +static const char * const main_pll_parents[] = { + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const periph_pll_parents[] = { + "osc1", + "cb-intosc-hs-div2-clk", +}; + +/* Core free muxes */ +static const char * const core0_free_mux[] = { + "main_pll_c1", + "peri_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const core1_free_mux[] = { + "main_pll_c1", + "peri_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const core2_free_mux[] = { + "main_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const core3_free_mux[] = { + "main_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const dsu_free_mux[] = { + "main_pll_c2", + "peri_pll_c0", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const noc_free_mux[] = { + "main_pll_c3", + "peri_pll_c1", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const emac_ptp_free_mux[] = { + "main_pll_c3", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const emaca_free_mux[] = { + "main_pll_c2", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const emacb_free_mux[] = { + "main_pll_c3", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const gpio_db_free_mux[] = { + "main_pll_c3", + "peri_pll_c1", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const psi_ref_free_mux[] = { + "main_pll_c1", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const usb31_free_mux[] = { + "main_pll_c3", + "peri_pll_c2", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const s2f_user0_free_mux[] = { + "main_pll_c1", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +static const char * const s2f_user1_free_mux[] = { + "main_pll_c1", + "peri_pll_c3", + "osc1", + "cb-intosc-hs-div2-clk", + "f2s-free-clk", +}; + +/* Secondary muxes between free_clk and boot_clk */ +static const char * const core0_mux[] = { + "core0_free_clk", + "boot_clk", +}; + +static const char * const core1_mux[] = { + "core1_free_clk", + "boot_clk", +}; + +static const char * const core2_mux[] = { + "core2_free_clk", + "boot_clk", +}; + +static const char * const core3_mux[] = { + "core3_free_clk", + "boot_clk", +}; + +static const char * const dsu_mux[] = { + "dsu_free_clk", + "boot_clk", +}; + +static const char * const noc_mux[] = { + "noc_free_clk", + "boot_clk", +}; + +static const char * const emac_mux[] = { + "emaca_free_clk", + "emacb_free_clk", + "boot_clk", +}; + +static const char * const s2f_user0_mux[] = { + "s2f_user0_free_clk", + "boot_clk", +}; + +static const char * const s2f_user1_mux[] = { + "s2f_user1_free_clk", + "boot_clk", +}; + +static const char * const psi_mux[] = { + "psi_ref_free_clk", + "boot_clk", +}; + +static const char * const gpio_db_mux[] = { + "gpio_db_free_clk", + "boot_clk", +}; + +static const char * const emac_ptp_mux[] = { + "emac_ptp_free_clk", + "boot_clk", +}; + +static const char * const usb31_mux[] = { + "usb31_free_clk", + "boot_clk", +}; + +static const struct agilex5_pll_clock agilex5_pll_clks[] = { + { + .id = AGILEX5_BOOT_CLK, + .name = "boot_clk", + .parent_names = boot_pll_parents, + .num_parents = ARRAY_SIZE(boot_pll_parents), + .flags = 0, + .offset = 0x0, + }, + { + .id = AGILEX5_MAIN_PLL_CLK, + .name = "main_pll", + .parent_names = main_pll_parents, + .num_parents = ARRAY_SIZE(main_pll_parents), + .flags = 0, + .offset = 0x48, + }, + { + .id = AGILEX5_PERIPH_PLL_CLK, + .name = "periph_pll", + .parent_names = periph_pll_parents, + .num_parents = ARRAY_SIZE(periph_pll_parents), + .flags = 0, + .offset = 0x9C, + }, +}; + +/* Main PLL C0, C1, C2, C3 and Peri PLL C0, C1, C2, C3. With ping-pong counter. */ +static const struct stratix10_perip_c_clock agilex5_main_perip_c_clks[] = { + { AGILEX5_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, + 0x5C }, + { AGILEX5_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, + 0x60 }, + { AGILEX5_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, + 0x64 }, + { AGILEX5_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, + 0x68 }, + { AGILEX5_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, + 0xB0 }, + { AGILEX5_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, + 0xB4 }, + { AGILEX5_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, + 0xB8 }, + { AGILEX5_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, + 0xBC }, +}; + +/* Non-SW clock-gated enabled clocks */ +static const struct agilex5_perip_cnt_clock agilex5_main_perip_cnt_clks[] = { + { AGILEX5_CORE0_FREE_CLK, "core0_free_clk", core0_free_mux, + ARRAY_SIZE(core0_free_mux), 0, 0x0100, 0, 0, 0}, + { AGILEX5_CORE1_FREE_CLK, "core1_free_clk", core1_free_mux, + ARRAY_SIZE(core1_free_mux), 0, 0x0104, 0, 0, 0}, + { AGILEX5_CORE2_FREE_CLK, "core2_free_clk", core2_free_mux, + ARRAY_SIZE(core2_free_mux), 0, 0x010C, 0, 0, 0}, + { AGILEX5_CORE3_FREE_CLK, "core3_free_clk", core3_free_mux, + ARRAY_SIZE(core3_free_mux), 0, 0x0110, 0, 0, 0}, + { AGILEX5_DSU_FREE_CLK, "dsu_free_clk", dsu_free_mux, + ARRAY_SIZE(dsu_free_mux), 0, 0xfc, 0, 0, 0}, + { AGILEX5_NOC_FREE_CLK, "noc_free_clk", noc_free_mux, + ARRAY_SIZE(noc_free_mux), 0, 0x40, 0, 0, 0 }, + { AGILEX5_EMAC_A_FREE_CLK, "emaca_free_clk", emaca_free_mux, + ARRAY_SIZE(emaca_free_mux), 0, 0xD4, 0, 0x88, 0 }, + { AGILEX5_EMAC_B_FREE_CLK, "emacb_free_clk", emacb_free_mux, + ARRAY_SIZE(emacb_free_mux), 0, 0xD8, 0, 0x88, 1 }, + { AGILEX5_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", emac_ptp_free_mux, + ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2 }, + { AGILEX5_GPIO_DB_FREE_CLK, "gpio_db_free_clk", gpio_db_free_mux, + ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3 }, + { AGILEX5_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", s2f_user0_free_mux, + ARRAY_SIZE(s2f_user0_free_mux), 0, 0xE8, 0, 0x30, 2 }, + { AGILEX5_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", s2f_user1_free_mux, + ARRAY_SIZE(s2f_user1_free_mux), 0, 0xEC, 0, 0x88, 5 }, + { AGILEX5_PSI_REF_FREE_CLK, "psi_ref_free_clk", psi_ref_free_mux, + ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6 }, + { AGILEX5_USB31_FREE_CLK, "usb31_free_clk", usb31_free_mux, + ARRAY_SIZE(usb31_free_mux), 0, 0xF8, 0, 0x88, 7}, +}; + +static const char * const cs_pdbg_parents[] = { "cs_at_clk" }; +static const char * const usb31_bus_clk_early_parents[] = { "l4_main_clk" }; +static const char * const l4_mp_clk_parent[] = { "l4_mp_clk" }; +static const char * const l4_sp_clk_parent[] = { "l4_sp_clk" }; +static const char * const dfi_clk_parent[] = { "dfi_clk" }; + +/* SW Clock gate enabled clocks */ +static const struct agilex5_gate_clock agilex5_gate_clks[] = { + { AGILEX5_CORE0_CLK, "core0_clk", core0_mux, + ARRAY_SIZE(core0_mux), 0, 0x24, 8, 0, 0, 0, 0x30, 5, 0 }, + { AGILEX5_CORE1_CLK, "core1_clk", core1_mux, + ARRAY_SIZE(core1_mux), 0, 0x24, 9, 0, 0, 0, 0x30, 5, 0 }, + { AGILEX5_CORE2_CLK, "core2_clk", core2_mux, + ARRAY_SIZE(core2_mux), 0, 0x24, 10, 0, 0, 0, 0x30, 6, 0 }, + { AGILEX5_CORE3_CLK, "core3_clk", core3_mux, + ARRAY_SIZE(core3_mux), 0, 0x24, 11, 0, 0, 0, 0x30, 7, 0 }, + { AGILEX5_MPU_CLK, "dsu_clk", dsu_mux, ARRAY_SIZE(dsu_mux), 0, 0, 0, + 0, 0, 0, 0x34, 4, 0 }, + { AGILEX5_MPU_PERIPH_CLK, "mpu_periph_clk", dsu_mux, + ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 20, 2, 0x34, 4, 0 }, + { AGILEX5_MPU_CCU_CLK, "mpu_ccu_clk", dsu_mux, + ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 18, 2, 0x34, 4, 0 }, + { AGILEX5_L4_MAIN_CLK, "l4_main_clk", noc_mux, ARRAY_SIZE(noc_mux), + CLK_IS_CRITICAL, 0x24, 1, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_L4_MP_CLK, "l4_mp_clk", noc_mux, ARRAY_SIZE(noc_mux), 0, + 0x24, 2, 0x44, 4, 2, 0x30, 1, 0 }, + { AGILEX5_L4_SYS_FREE_CLK, "l4_sys_free_clk", noc_mux, + ARRAY_SIZE(noc_mux), 0, 0, 0, 0x44, 2, 2, 0x30, 1, 0 }, + { AGILEX5_L4_SP_CLK, "l4_sp_clk", noc_mux, ARRAY_SIZE(noc_mux), + CLK_IS_CRITICAL, 0x24, 3, 0x44, 6, 2, 0x30, 1, 0 }, + + /* Core sight clocks*/ + { AGILEX5_CS_AT_CLK, "cs_at_clk", noc_mux, ARRAY_SIZE(noc_mux), 0, + 0x24, 4, 0x44, 24, 2, 0x30, 1, 0 }, + { AGILEX5_CS_TRACE_CLK, "cs_trace_clk", noc_mux, + ARRAY_SIZE(noc_mux), 0, 0x24, 4, 0x44, 26, 2, 0x30, 1, 0 }, + { AGILEX5_CS_PDBG_CLK, "cs_pdbg_clk", cs_pdbg_parents, 1, 0, 0x24, 4, + 0x44, 28, 1, 0, 0, 0 }, + + /* Main Peripheral PLL1 Begin */ + { AGILEX5_EMAC0_CLK, "emac0_clk", emac_mux, ARRAY_SIZE(emac_mux), + 0, 0x7C, 0, 0, 0, 0, 0x94, 26, 0 }, + { AGILEX5_EMAC1_CLK, "emac1_clk", emac_mux, ARRAY_SIZE(emac_mux), + 0, 0x7C, 1, 0, 0, 0, 0x94, 27, 0 }, + { AGILEX5_EMAC2_CLK, "emac2_clk", emac_mux, ARRAY_SIZE(emac_mux), + 0, 0x7C, 2, 0, 0, 0, 0x94, 28, 0 }, + { AGILEX5_EMAC_PTP_CLK, "emac_ptp_clk", emac_ptp_mux, + ARRAY_SIZE(emac_ptp_mux), 0, 0x7C, 3, 0, 0, 0, 0x88, 2, 0 }, + { AGILEX5_GPIO_DB_CLK, "gpio_db_clk", gpio_db_mux, + ARRAY_SIZE(gpio_db_mux), 0, 0x7C, 4, 0x98, 0, 16, 0x88, 3, 1 }, + /* Main Peripheral PLL1 End */ + + /* Peripheral clocks */ + { AGILEX5_S2F_USER0_CLK, "s2f_user0_clk", s2f_user0_mux, + ARRAY_SIZE(s2f_user0_mux), 0, 0x24, 6, 0, 0, 0, 0x30, 2, 0 }, + { AGILEX5_S2F_USER1_CLK, "s2f_user1_clk", s2f_user1_mux, + ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, 6, 0, 0, 0, 0x88, 5, 0 }, + { AGILEX5_PSI_REF_CLK, "psi_ref_clk", psi_mux, + ARRAY_SIZE(psi_mux), 0, 0x7C, 7, 0, 0, 0, 0x88, 6, 0 }, + { AGILEX5_USB31_SUSPEND_CLK, "usb31_suspend_clk", usb31_mux, + ARRAY_SIZE(usb31_mux), 0, 0x7C, 25, 0, 0, 0, 0x88, 7, 0 }, + { AGILEX5_USB31_BUS_CLK_EARLY, "usb31_bus_clk_early", usb31_bus_clk_early_parents, + 1, 0, 0x7C, 25, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_USB2OTG_HCLK, "usb2otg_hclk", l4_mp_clk_parent, 1, 0, 0x7C, + 8, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPIM_0_CLK, "spim_0_clk", l4_mp_clk_parent, 1, 0, 0x7C, 9, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPIM_1_CLK, "spim_1_clk", l4_mp_clk_parent, 1, 0, 0x7C, 11, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPIS_0_CLK, "spis_0_clk", l4_sp_clk_parent, 1, 0, 0x7C, 12, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPIS_1_CLK, "spis_1_clk", l4_sp_clk_parent, 1, 0, 0x7C, 13, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_DMA_CORE_CLK, "dma_core_clk", l4_mp_clk_parent, 1, 0, 0x7C, + 14, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_DMA_HS_CLK, "dma_hs_clk", l4_mp_clk_parent, 1, 0, 0x7C, 14, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I3C_0_CORE_CLK, "i3c_0_core_clk", l4_mp_clk_parent, 1, 0, + 0x7C, 18, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I3C_1_CORE_CLK, "i3c_1_core_clk", l4_mp_clk_parent, 1, 0, + 0x7C, 19, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_0_PCLK, "i2c_0_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 15, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_1_PCLK, "i2c_1_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 16, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_EMAC0_PCLK, "i2c_emac0_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 17, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_EMAC1_PCLK, "i2c_emac1_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 22, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_I2C_EMAC2_PCLK, "i2c_emac2_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 27, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_UART_0_PCLK, "uart_0_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 20, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_UART_1_PCLK, "uart_1_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 21, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPTIMER_0_PCLK, "sptimer_0_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 23, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SPTIMER_1_PCLK, "sptimer_1_pclk", l4_sp_clk_parent, 1, 0, + 0x7C, 24, 0, 0, 0, 0, 0, 0 }, + + /*NAND, SD/MMC and SoftPHY overall clocking*/ + { AGILEX5_DFI_CLK, "dfi_clk", l4_mp_clk_parent, 1, 0, 0, 0, 0x44, 16, + 2, 0, 0, 0 }, + { AGILEX5_NAND_NF_CLK, "nand_nf_clk", dfi_clk_parent, 1, 0, 0x7C, 10, + 0, 0, 0, 0, 0, 0 }, + { AGILEX5_NAND_BCH_CLK, "nand_bch_clk", l4_mp_clk_parent, 1, 0, 0x7C, + 10, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SDMMC_SDPHY_REG_CLK, "sdmmc_sdphy_reg_clk", l4_mp_clk_parent, + 1, 0, 0x7C, 5, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SDMCLK, "sdmclk", dfi_clk_parent, 1, 0, 0x7C, 5, 0, 0, 0, + 0, 0, 0 }, + { AGILEX5_SOFTPHY_REG_PCLK, "softphy_reg_pclk", l4_mp_clk_parent, 1, 0, + 0x7C, 26, 0, 0, 0, 0, 0, 0 }, + { AGILEX5_SOFTPHY_PHY_CLK, "softphy_phy_clk", l4_mp_clk_parent, 1, 0, + 0x7C, 26, 0x44, 16, 2, 0, 0, 0 }, + { AGILEX5_SOFTPHY_CTRL_CLK, "softphy_ctrl_clk", dfi_clk_parent, 1, 0, + 0x7C, 26, 0, 0, 0, 0, 0, 0 }, +}; + +static int +agilex5_clk_register_c_perip(const struct stratix10_perip_c_clock *clks, + int nums, struct stratix10_clock_data *data) +{ + struct clk_hw *hw_clk; + void __iomem *base = data->base; + int i; + + for (i = 0; i < nums; i++) { + hw_clk = s10_register_periph(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + continue; + } + data->clk_data.hws[clks[i].id] = hw_clk; + } + return 0; +} + +static int +agilex5_clk_register_cnt_perip(const struct agilex5_perip_cnt_clock *clks, + int nums, struct stratix10_clock_data *data) +{ + struct clk_hw *hw_clk; + void __iomem *base = data->base; + int i; + + for (i = 0; i < nums; i++) { + hw_clk = agilex5_register_cnt_periph(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + continue; + } + data->clk_data.hws[clks[i].id] = hw_clk; + } + + return 0; +} + +static int agilex5_clk_register_gate(const struct agilex5_gate_clock *clks, + int nums, + struct stratix10_clock_data *data) +{ + struct clk_hw *hw_clk; + void __iomem *base = data->base; + int i; + + for (i = 0; i < nums; i++) { + hw_clk = agilex5_register_gate(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + continue; + } + data->clk_data.hws[clks[i].id] = hw_clk; + } + + return 0; +} + +static int agilex5_clk_register_pll(const struct agilex5_pll_clock *clks, + int nums, struct stratix10_clock_data *data) +{ + struct clk_hw *hw_clk; + void __iomem *base = data->base; + int i; + + for (i = 0; i < nums; i++) { + hw_clk = agilex5_register_pll(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + continue; + } + data->clk_data.hws[clks[i].id] = hw_clk; + } + + return 0; +} + +static int agilex5_clkmgr_init(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct stratix10_clock_data *clk_data; + void __iomem *base; + int i, num_clks; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + num_clks = AGILEX5_NUM_CLKS; + + clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws, + num_clks), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->base = base; + clk_data->clk_data.num = num_clks; + + for (i = 0; i < num_clks; i++) + clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT); + + agilex5_clk_register_pll(agilex5_pll_clks, ARRAY_SIZE(agilex5_pll_clks), + clk_data); + + /* mainPLL C0, C1, C2, C3 and periph PLL C0, C1, C2, C3*/ + agilex5_clk_register_c_perip(agilex5_main_perip_c_clks, + ARRAY_SIZE(agilex5_main_perip_c_clks), + clk_data); + + agilex5_clk_register_cnt_perip(agilex5_main_perip_cnt_clks, + ARRAY_SIZE(agilex5_main_perip_cnt_clks), + clk_data); + + agilex5_clk_register_gate(agilex5_gate_clks, + ARRAY_SIZE(agilex5_gate_clks), clk_data); + + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data); + return 0; +} + +static int agilex5_clkmgr_probe(struct platform_device *pdev) +{ + int (*probe_func)(struct platform_device *init_func); + + probe_func = of_device_get_match_data(&pdev->dev); + if (!probe_func) + return -ENODEV; + return probe_func(pdev); +} + +static const struct of_device_id agilex5_clkmgr_match_table[] = { + { .compatible = "intel,agilex5-clkmgr", .data = agilex5_clkmgr_init }, + {} +}; + +static struct platform_driver agilex5_clkmgr_driver = { + .probe = agilex5_clkmgr_probe, + .driver = { + .name = "agilex5-clkmgr", + .suppress_bind_attrs = true, + .of_match_table = agilex5_clkmgr_match_table, + }, +}; + +static int __init agilex5_clk_init(void) +{ + return platform_driver_register(&agilex5_clkmgr_driver); +} +core_initcall(agilex5_clk_init); diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c index 3930d922efb4..dce3ef137bf3 100644 --- a/drivers/clk/socfpga/clk-gate-s10.c +++ b/drivers/clk/socfpga/clk-gate-s10.c @@ -239,3 +239,56 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi } return hw_clk; } + +struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, void __iomem *regbase) +{ + struct clk_hw *hw_clk; + struct socfpga_gate_clk *socfpga_clk; + struct clk_init_data init; + int ret; + + socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + if (!socfpga_clk) + return NULL; + + socfpga_clk->hw.reg = regbase + clks->gate_reg; + socfpga_clk->hw.bit_idx = clks->gate_idx; + + gateclk_ops.enable = clk_gate_ops.enable; + gateclk_ops.disable = clk_gate_ops.disable; + + socfpga_clk->fixed_div = clks->fixed_div; + + if (clks->div_reg) + socfpga_clk->div_reg = regbase + clks->div_reg; + else + socfpga_clk->div_reg = NULL; + + socfpga_clk->width = clks->div_width; + socfpga_clk->shift = clks->div_offset; + + if (clks->bypass_reg) + socfpga_clk->bypass_reg = regbase + clks->bypass_reg; + else + socfpga_clk->bypass_reg = NULL; + socfpga_clk->bypass_shift = clks->bypass_shift; + + if (streq(clks->name, "cs_pdbg_clk")) + init.ops = &dbgclk_ops; + else + init.ops = &agilex_gateclk_ops; + + init.name = clks->name; + init.flags = clks->flags; + init.num_parents = clks->num_parents; + init.parent_names = clks->parent_names; + socfpga_clk->hw.hw.init = &init; + hw_clk = &socfpga_clk->hw.hw; + + ret = clk_hw_register(NULL, &socfpga_clk->hw.hw); + if (ret) { + kfree(socfpga_clk); + return ERR_PTR(ret); + } + return hw_clk; +} diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c index f5c1ca42b668..f12ca43ffe7c 100644 --- a/drivers/clk/socfpga/clk-periph-s10.c +++ b/drivers/clk/socfpga/clk-periph-s10.c @@ -214,3 +214,44 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c } return hw_clk; } + +struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks, + void __iomem *regbase) +{ + struct clk_hw *hw_clk; + struct socfpga_periph_clk *periph_clk; + struct clk_init_data init; + const char *name = clks->name; + int ret; + + periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); + if (WARN_ON(!periph_clk)) + return NULL; + + if (clks->offset) + periph_clk->hw.reg = regbase + clks->offset; + else + periph_clk->hw.reg = NULL; + + if (clks->bypass_reg) + periph_clk->bypass_reg = regbase + clks->bypass_reg; + else + periph_clk->bypass_reg = NULL; + periph_clk->bypass_shift = clks->bypass_shift; + periph_clk->fixed_div = clks->fixed_divider; + + init.name = name; + init.ops = &peri_cnt_clk_ops; + init.flags = clks->flags; + init.num_parents = clks->num_parents; + init.parent_names = clks->parent_names; + periph_clk->hw.hw.init = &init; + hw_clk = &periph_clk->hw.hw; + + ret = clk_hw_register(NULL, hw_clk); + if (ret) { + kfree(periph_clk); + return ERR_PTR(ret); + } + return hw_clk; +} diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c index a88c212bda12..1be92827cd93 100644 --- a/drivers/clk/socfpga/clk-pll-s10.c +++ b/drivers/clk/socfpga/clk-pll-s10.c @@ -304,3 +304,39 @@ struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks, } return hw_clk; } + +struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks, + void __iomem *reg) +{ + struct clk_hw *hw_clk; + struct socfpga_pll *pll_clk; + struct clk_init_data init; + const char *name = clks->name; + int ret; + + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + if (WARN_ON(!pll_clk)) + return NULL; + + pll_clk->hw.reg = reg + clks->offset; + + if (streq(name, SOCFPGA_BOOT_CLK)) + init.ops = &clk_boot_ops; + else + init.ops = &agilex_clk_pll_ops; + + init.name = name; + init.flags = clks->flags; + init.num_parents = clks->num_parents; + init.parent_names = clks->parent_names; + pll_clk->hw.hw.init = &init; + pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER; + hw_clk = &pll_clk->hw.hw; + + ret = clk_hw_register(NULL, hw_clk); + if (ret) { + kfree(pll_clk); + return ERR_PTR(ret); + } + return hw_clk; +} diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h index 83fe4eb3133c..d1fe4578b3e0 100644 --- a/drivers/clk/socfpga/stratix10-clk.h +++ b/drivers/clk/socfpga/stratix10-clk.h @@ -73,12 +73,55 @@ struct stratix10_gate_clock { u8 fixed_div; }; +struct agilex5_pll_clock { + unsigned int id; + const char *name; + const char * const *parent_names; + u8 num_parents; + unsigned long flags; + unsigned long offset; +}; + +struct agilex5_perip_cnt_clock { + unsigned int id; + const char *name; + const char * const *parent_names; + u8 num_parents; + unsigned long flags; + unsigned long offset; + u8 fixed_divider; + unsigned long bypass_reg; + unsigned long bypass_shift; +}; + +struct agilex5_gate_clock { + unsigned int id; + const char *name; + const char * const *parent_names; + u8 num_parents; + unsigned long flags; + unsigned long gate_reg; + u8 gate_idx; + unsigned long div_reg; + u8 div_offset; + u8 div_width; + unsigned long bypass_reg; + u8 bypass_shift; + u8 fixed_div; +}; + struct clk_hw *s10_register_pll(const struct stratix10_pll_clock *clks, void __iomem *reg); struct clk_hw *agilex_register_pll(const struct stratix10_pll_clock *clks, void __iomem *reg); struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks, void __iomem *reg); +struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks, + void __iomem *reg); +struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks, + void __iomem *regbase); +struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, + void __iomem *regbase); struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks, void __iomem *reg); struct clk_hw *n5x_register_periph(const struct n5x_perip_c_clock *clks, From 934dcccf3ffc7568fdeb363842bb9fc36e1be608 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 14 Oct 2025 11:53:48 +0100 Subject: [PATCH 047/117] clk: renesas: cpg-mssr: Add read-back and delay handling for RZ/T2H MSTP On the RZ/T2H SoC, a specific sequence is required when releasing a module from the module stop state (i.e. when clearing the corresponding bit in the MSTPCRm register to '0'). After writing to the MSTPCRm register, a read-back of the same register must be performed, followed by at least seven dummy reads of any register within the IP block that is being released. To avoid mapping device registers for this purpose, a short delay is introduced after the read-back to ensure proper hardware stabilization before the module becomes accessible. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251014105348.93705-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 0ffe6ee8f165..66c20698927c 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -308,10 +308,21 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); - if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A || - priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) + if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A) return 0; + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + /* + * For the RZ/T2H case, it is necessary to perform a read-back after + * accessing the MSTPCRm register and to dummy-read any register of + * the IP at least seven times. Instead of memory-mapping the IP + * register, we simply add a delay after the read operation. + */ + cpg_rzt2h_mstp_read(hw, priv->control_regs[reg]); + udelay(10); + return 0; + } + error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], value, !(value & bitmask), 0, 10); if (error) From 919bf298dc9fe2cee5abfacb281fb201cda65a44 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Mon, 20 Oct 2025 14:31:05 +0000 Subject: [PATCH 048/117] clk: renesas: r9a09g057: Add clock and reset entries for TSU Add module clock and reset entries for the TSU0 and TSU1 blocks on the Renesas RZ/V2H (R9A09G057) SoC. Signed-off-by: Ovidiu Panait Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251020143107.13974-2-ovidiu.panait.rb@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g057-cpg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index c9c117c6782c..4684af31177e 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -387,6 +387,10 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_ace_clk", CLK_PLLDTY_ACPU_DIV2, 15, 2, 7, 18, BUS_MSTOP(3, BIT(4))), + DEF_MOD("tsu_0_pclk", CLK_QEXTAL, 16, 9, 8, 9, + BUS_MSTOP(5, BIT(2))), + DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10, + BUS_MSTOP(2, BIT(15))), }; static const struct rzv2h_reset r9a09g057_resets[] __initconst = { @@ -459,6 +463,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */ DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */ + DEF_RST(15, 7, 7, 8), /* TSU_0_PRESETN */ + DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */ }; const struct rzv2h_cpg_info r9a09g057_cpg_info __initconst = { From a7231aaf4a10ce8793a347e78988539e778cbdf9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 21 Oct 2025 10:03:56 +0200 Subject: [PATCH 049/117] clk: renesas: cpg-mssr: Spelling s/offets/offsets/ Fix a misspelling of "offsets". Signed-off-by: Geert Uytterhoeven Link: https://patch.msgid.link/47bf5186c3a234f6a6e53d8fdc81fafd2e981534.1761033805.git.geert+renesas@glider.be --- drivers/clk/renesas/renesas-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 66c20698927c..7f9b7aa39790 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -43,7 +43,7 @@ #define RZT2H_RESET_REG_READ_COUNT 7 /* - * Module Standby and Software Reset register offets. + * Module Standby and Software Reset register offsets. * * If the registers exist, these are valid for SH-Mobile, R-Mobile, * R-Car Gen2, R-Car Gen3, and RZ/G1. From 7a03ef9f8223434f19e19a37acc32dcb581ab475 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Tue, 21 Oct 2025 08:07:00 +0000 Subject: [PATCH 050/117] clk: renesas: r9a09g057: Add clock and reset entries for RTC Add module clock and reset entries for the RTC module on the Renesas RZ/V2H (R9A09G057) SoC. Signed-off-by: Ovidiu Panait Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251021080705.18116-2-ovidiu.panait.rb@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g057-cpg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index 4684af31177e..dce5755d85ec 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -241,6 +241,8 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rtc_0_clk_rtc", CLK_PLLCM33_DIV16, 5, 3, 2, 19, + BUS_MSTOP(3, BIT(11) | BIT(12))), DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20, BUS_MSTOP(11, BIT(0))), DEF_MOD("rspi_0_pclk_sfr", CLK_PLLCLN_DIV8, 5, 5, 2, 21, @@ -415,6 +417,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(7, 9, 3, 10), /* RTC_0_RST_RTC */ + DEF_RST(7, 10, 3, 11), /* RTC_0_RST_RTC_V */ DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */ DEF_RST(7, 12, 3, 13), /* RSPI_0_TRESETN */ DEF_RST(7, 13, 3, 14), /* RSPI_1_PRESETN */ From 36a23904b4def05bfbb589af9fab5bc06144d241 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 15 Oct 2025 20:26:05 +0100 Subject: [PATCH 051/117] clk: renesas: rzv2h: Add instance field to struct pll Add a two-bit "instance" member to struct pll and extend the PLL_PACK() macro to accept an instance parameter. Initialize all existing PLL definitions with instance 0 to preserve legacy behavior. This change enables support for SoCs with multiple PLL instances (for example, RZ/G3E we have two PLL DSIs). Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251015192611.241920-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzv2h-cpg.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h index 840eed25aeda..e2053049c299 100644 --- a/drivers/clk/renesas/rzv2h-cpg.h +++ b/drivers/clk/renesas/rzv2h-cpg.h @@ -16,20 +16,23 @@ * * @offset: STBY register offset * @has_clkn: Flag to indicate if CLK1/2 are accessible or not + * @instance: PLL instance number */ struct pll { unsigned int offset:9; unsigned int has_clkn:1; + unsigned int instance:2; }; -#define PLL_PACK(_offset, _has_clkn) \ +#define PLL_PACK(_offset, _has_clkn, _instance) \ ((struct pll){ \ .offset = _offset, \ - .has_clkn = _has_clkn \ + .has_clkn = _has_clkn, \ + .instance = _instance \ }) -#define PLLCA55 PLL_PACK(0x60, 1) -#define PLLGPU PLL_PACK(0x120, 1) +#define PLLCA55 PLL_PACK(0x60, 1, 0) +#define PLLGPU PLL_PACK(0x120, 1, 0) /** * struct ddiv - Structure for dynamic switching divider From a8943f7f0a736e211faa400fa9df1af8dd945347 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 15 Oct 2025 20:26:06 +0100 Subject: [PATCH 052/117] clk: renesas: rzv2h: Use GENMASK for PLL fields Replace the older FIELD_GET-wrapping helper macros with plain GENMASK definitions for the PLL CLK1/CLK2 field masks (CPG_PLL_CLK1_KDIV, CPG_PLL_CLK1_MDIV, CPG_PLL_CLK1_PDIV and CPG_PLL_CLK2_SDIV). Update rzv2h_cpg_pll_clk_recalc_rate() to explicitly extract those fields with FIELD_GET and cast the KDIV extraction to s16 to ensure proper sign extension when computing the PLL output rate. Co-developed-by: Fabrizio Castro Signed-off-by: Fabrizio Castro Signed-off-by: Lad Prabhakar Acked-by: Tomi Valkeinen Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251015192611.241920-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzv2h-cpg.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 2197d1d2453a..6abac15d3475 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -49,11 +49,11 @@ #define CPG_PLL_STBY_RESETB BIT(0) #define CPG_PLL_STBY_RESETB_WEN BIT(16) #define CPG_PLL_CLK1(x) ((x) + 0x004) -#define CPG_PLL_CLK1_KDIV(x) ((s16)FIELD_GET(GENMASK(31, 16), (x))) -#define CPG_PLL_CLK1_MDIV(x) FIELD_GET(GENMASK(15, 6), (x)) -#define CPG_PLL_CLK1_PDIV(x) FIELD_GET(GENMASK(5, 0), (x)) +#define CPG_PLL_CLK1_KDIV GENMASK(31, 16) +#define CPG_PLL_CLK1_MDIV GENMASK(15, 6) +#define CPG_PLL_CLK1_PDIV GENMASK(5, 0) #define CPG_PLL_CLK2(x) ((x) + 0x008) -#define CPG_PLL_CLK2_SDIV(x) FIELD_GET(GENMASK(2, 0), (x)) +#define CPG_PLL_CLK2_SDIV GENMASK(2, 0) #define CPG_PLL_MON(x) ((x) + 0x010) #define CPG_PLL_MON_RESETB BIT(0) #define CPG_PLL_MON_LOCK BIT(4) @@ -231,10 +231,11 @@ static unsigned long rzv2h_cpg_pll_clk_recalc_rate(struct clk_hw *hw, clk1 = readl(priv->base + CPG_PLL_CLK1(pll.offset)); clk2 = readl(priv->base + CPG_PLL_CLK2(pll.offset)); - rate = mul_u64_u32_shr(parent_rate, (CPG_PLL_CLK1_MDIV(clk1) << 16) + - CPG_PLL_CLK1_KDIV(clk1), 16 + CPG_PLL_CLK2_SDIV(clk2)); + rate = mul_u64_u32_shr(parent_rate, (FIELD_GET(CPG_PLL_CLK1_MDIV, clk1) << 16) + + (s16)FIELD_GET(CPG_PLL_CLK1_KDIV, clk1), + 16 + FIELD_GET(CPG_PLL_CLK2_SDIV, clk2)); - return DIV_ROUND_CLOSEST_ULL(rate, CPG_PLL_CLK1_PDIV(clk1)); + return DIV_ROUND_CLOSEST_ULL(rate, FIELD_GET(CPG_PLL_CLK1_PDIV, clk1)); } static const struct clk_ops rzv2h_cpg_pll_ops = { From f864e4b721e386be132cc973eadefe5d52cdfd94 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 15 Oct 2025 20:26:07 +0100 Subject: [PATCH 053/117] clk: renesas: rzv2h: Add support for DSI clocks Add support for PLLDSI and its post-dividers in the RZ/V2H CPG driver and export helper APIs for use by the DSI driver. Introduce per-PLL-DSI state in the CPG private structure and provide a set of helper functions that find valid PLL parameter combinations for a requested frequency. The new helpers are rzv2h_get_pll_pars(), rzv2h_get_pll_div_pars(), rzv2h_get_pll_divs_pars() and rzv2h_get_pll_dtable_pars() and they are exported in the "RZV2H_CPG" namespace for use by other consumers (notably the DSI driver). These helpers perform iterative searches over PLL parameters (M, K, P, S) and optional post-dividers and return the best match (or an exact match when possible). Move PLL/CLK related limits and parameter types into the shared include (include/linux/clk/renesas.h) by adding struct rzv2h_pll_limits, struct rzv2h_pll_pars and struct rzv2h_pll_div_pars plus the RZV2H_CPG_PLL_DSI_LIMITS() helper macro to define DSI PLL limits. This change centralises the PLLDSI algorithms so the CPG and DSI drivers compute PLL parameters consistently and allows the DSI driver to accurately request rates and program its PLL. Co-developed-by: Fabrizio Castro Signed-off-by: Fabrizio Castro Signed-off-by: Lad Prabhakar Acked-by: Tomi Valkeinen Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251015192611.241920-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzv2h-cpg.c | 497 ++++++++++++++++++++++++++++++++ drivers/clk/renesas/rzv2h-cpg.h | 19 +- include/linux/clk/renesas.h | 145 ++++++++++ 3 files changed, 659 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 6abac15d3475..182437800329 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -14,9 +14,14 @@ #include #include #include +#include #include #include #include +#include +#include +#include +#include #include #include #include @@ -26,6 +31,7 @@ #include #include #include +#include #include @@ -47,7 +53,9 @@ #define CPG_PLL_STBY(x) ((x)) #define CPG_PLL_STBY_RESETB BIT(0) +#define CPG_PLL_STBY_SSC_EN BIT(2) #define CPG_PLL_STBY_RESETB_WEN BIT(16) +#define CPG_PLL_STBY_SSC_EN_WEN BIT(18) #define CPG_PLL_CLK1(x) ((x) + 0x004) #define CPG_PLL_CLK1_KDIV GENMASK(31, 16) #define CPG_PLL_CLK1_MDIV GENMASK(15, 6) @@ -65,6 +73,22 @@ #define CPG_CLKSTATUS0 (0x700) +/* On RZ/G3E SoC we have two DSI PLLs */ +#define MAX_CPG_DSI_PLL 2 + +/** + * struct rzv2h_pll_dsi_info - PLL DSI information, holds the limits and parameters + * + * @pll_dsi_limits: PLL DSI parameters limits + * @pll_dsi_parameters: Calculated PLL DSI parameters + * @req_pll_dsi_rate: Requested PLL DSI rate + */ +struct rzv2h_pll_dsi_info { + const struct rzv2h_pll_limits *pll_dsi_limits; + struct rzv2h_pll_div_pars pll_dsi_parameters; + unsigned long req_pll_dsi_rate; +}; + /** * struct rzv2h_cpg_priv - Clock Pulse Generator Private Data * @@ -80,6 +104,7 @@ * @ff_mod_status_ops: Fixed Factor Module Status Clock operations * @mstop_count: Array of mstop values * @rcdev: Reset controller entity + * @pll_dsi_info: Array of PLL DSI information, holds the limits and parameters */ struct rzv2h_cpg_priv { struct device *dev; @@ -98,6 +123,8 @@ struct rzv2h_cpg_priv { atomic_t *mstop_count; struct reset_controller_dev rcdev; + + struct rzv2h_pll_dsi_info pll_dsi_info[MAX_CPG_DSI_PLL]; }; #define rcdev_to_priv(x) container_of(x, struct rzv2h_cpg_priv, rcdev) @@ -168,6 +195,460 @@ struct rzv2h_ff_mod_status_clk { #define to_rzv2h_ff_mod_status_clk(_hw) \ container_of(_hw, struct rzv2h_ff_mod_status_clk, fix.hw) +/** + * struct rzv2h_plldsi_div_clk - PLL DSI DDIV clock + * + * @dtable: divider table + * @priv: CPG private data + * @hw: divider clk + * @ddiv: divider configuration + */ +struct rzv2h_plldsi_div_clk { + const struct clk_div_table *dtable; + struct rzv2h_cpg_priv *priv; + struct clk_hw hw; + struct ddiv ddiv; +}; + +#define to_plldsi_div_clk(_hw) \ + container_of(_hw, struct rzv2h_plldsi_div_clk, hw) + +#define RZ_V2H_OSC_CLK_IN_MEGA (24 * MEGA) +#define RZV2H_MAX_DIV_TABLES (16) + +/** + * rzv2h_get_pll_pars - Finds the best combination of PLL parameters + * for a given frequency. + * + * @limits: Pointer to the structure containing the limits for the PLL parameters + * @pars: Pointer to the structure where the best calculated PLL parameters values + * will be stored + * @freq_millihz: Target output frequency in millihertz + * + * This function calculates the best set of PLL parameters (M, K, P, S) to achieve + * the desired frequency. + * There is no direct formula to calculate the PLL parameters, as it's an open + * system of equations, therefore this function uses an iterative approach to + * determine the best solution. The best solution is one that minimizes the error + * (desired frequency - actual frequency). + * + * Return: true if a valid set of parameters values is found, false otherwise. + */ +bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, u64 freq_millihz) +{ + u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI); + u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI); + struct rzv2h_pll_pars p, best; + + if (freq_millihz > fout_max_millihz || + freq_millihz < fout_min_millihz) + return false; + + /* Initialize best error to maximum possible value */ + best.error_millihz = S64_MAX; + + for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) { + u32 fref = RZ_V2H_OSC_CLK_IN_MEGA / p.p; + u16 divider; + + for (divider = 1 << limits->s.min, p.s = limits->s.min; + p.s <= limits->s.max; p.s++, divider <<= 1) { + for (p.m = limits->m.min; p.m <= limits->m.max; p.m++) { + u64 output_m, output_k_range; + s64 pll_k, output_k; + u64 fvco, output; + + /* + * The frequency generated by the PLL + divider + * is calculated as follows: + * + * With: + * Freq = Ffout = Ffvco / 2^(pll_s) + * Ffvco = (pll_m + (pll_k / 65536)) * Ffref + * Ffref = 24MHz / pll_p + * + * Freq can also be rewritten as: + * Freq = Ffvco / 2^(pll_s) + * = ((pll_m + (pll_k / 65536)) * Ffref) / 2^(pll_s) + * = (pll_m * Ffref) / 2^(pll_s) + ((pll_k / 65536) * Ffref) / 2^(pll_s) + * = output_m + output_k + * + * Every parameter has been determined at this + * point, but pll_k. + * + * Considering that: + * limits->k.min <= pll_k <= limits->k.max + * Then: + * -0.5 <= (pll_k / 65536) < 0.5 + * Therefore: + * -Ffref / (2 * 2^(pll_s)) <= output_k < Ffref / (2 * 2^(pll_s)) + */ + + /* Compute output M component (in mHz) */ + output_m = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(p.m, fref) * MILLI, + divider); + /* Compute range for output K (in mHz) */ + output_k_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fref, MILLI), + 2 * divider); + /* + * No point in continuing if we can't achieve + * the desired frequency + */ + if (freq_millihz < (output_m - output_k_range) || + freq_millihz >= (output_m + output_k_range)) { + continue; + } + + /* + * Compute the K component + * + * Since: + * Freq = output_m + output_k + * Then: + * output_k = Freq - output_m + * = ((pll_k / 65536) * Ffref) / 2^(pll_s) + * Therefore: + * pll_k = (output_k * 65536 * 2^(pll_s)) / Ffref + */ + output_k = freq_millihz - output_m; + pll_k = div_s64(output_k * 65536ULL * divider, + fref); + pll_k = DIV_S64_ROUND_CLOSEST(pll_k, MILLI); + + /* Validate K value within allowed limits */ + if (pll_k < limits->k.min || + pll_k > limits->k.max) + continue; + + p.k = pll_k; + + /* Compute (Ffvco * 65536) */ + fvco = mul_u32_u32(p.m * 65536 + p.k, fref); + if (fvco < mul_u32_u32(limits->fvco.min, 65536) || + fvco > mul_u32_u32(limits->fvco.max, 65536)) + continue; + + /* PLL_M component of (output * 65536 * PLL_P) */ + output = mul_u32_u32(p.m * 65536, RZ_V2H_OSC_CLK_IN_MEGA); + /* PLL_K component of (output * 65536 * PLL_P) */ + output += p.k * RZ_V2H_OSC_CLK_IN_MEGA; + /* Make it in mHz */ + output *= MILLI; + output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider); + + /* Check output frequency against limits */ + if (output < fout_min_millihz || + output > fout_max_millihz) + continue; + + p.error_millihz = freq_millihz - output; + p.freq_millihz = output; + + /* If an exact match is found, return immediately */ + if (p.error_millihz == 0) { + *pars = p; + return true; + } + + /* Update best match if error is smaller */ + if (abs(best.error_millihz) > abs(p.error_millihz)) + best = p; + } + } + } + + /* If no valid parameters were found, return false */ + if (best.error_millihz == S64_MAX) + return false; + + *pars = best; + return true; +} +EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_pars, "RZV2H_CPG"); + +/* + * rzv2h_get_pll_divs_pars - Finds the best combination of PLL parameters + * and divider value for a given frequency. + * + * @limits: Pointer to the structure containing the limits for the PLL parameters + * @pars: Pointer to the structure where the best calculated PLL parameters and + * divider values will be stored + * @table: Pointer to the array of valid divider values + * @table_size: Size of the divider values array + * @freq_millihz: Target output frequency in millihertz + * + * This function calculates the best set of PLL parameters (M, K, P, S) and divider + * value to achieve the desired frequency. See rzv2h_get_pll_pars() for more details + * on how the PLL parameters are calculated. + * + * freq_millihz is the desired frequency generated by the PLL followed by a + * a gear. + */ +bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, u64 freq_millihz) +{ + struct rzv2h_pll_div_pars p, best; + + best.div.error_millihz = S64_MAX; + p.div.error_millihz = S64_MAX; + for (unsigned int i = 0; i < table_size; i++) { + if (!rzv2h_get_pll_pars(limits, &p.pll, freq_millihz * table[i])) + continue; + + p.div.divider_value = table[i]; + p.div.freq_millihz = DIV_U64_ROUND_CLOSEST(p.pll.freq_millihz, table[i]); + p.div.error_millihz = freq_millihz - p.div.freq_millihz; + + if (p.div.error_millihz == 0) { + *pars = p; + return true; + } + + if (abs(best.div.error_millihz) > abs(p.div.error_millihz)) + best = p; + } + + if (best.div.error_millihz == S64_MAX) + return false; + + *pars = best; + return true; +} +EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_divs_pars, "RZV2H_CPG"); + +static unsigned long rzv2h_cpg_plldsi_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw); + struct rzv2h_cpg_priv *priv = dsi_div->priv; + struct ddiv ddiv = dsi_div->ddiv; + u32 div; + + div = readl(priv->base + ddiv.offset); + div >>= ddiv.shift; + div &= clk_div_mask(ddiv.width); + div = dsi_div->dtable[div].div; + + return DIV_ROUND_CLOSEST_ULL(parent_rate, div); +} + +static int rzv2h_cpg_plldsi_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw); + struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw)); + struct rzv2h_cpg_priv *priv = dsi_div->priv; + u8 table[RZV2H_MAX_DIV_TABLES] = { 0 }; + struct rzv2h_pll_div_pars *dsi_params; + struct rzv2h_pll_dsi_info *dsi_info; + const struct clk_div_table *div; + unsigned int i = 0; + u64 rate_millihz; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + dsi_params = &dsi_info->pll_dsi_parameters; + + rate_millihz = mul_u32_u32(req->rate, MILLI); + if (rate_millihz == dsi_params->div.error_millihz + dsi_params->div.freq_millihz) + goto exit_determine_rate; + + for (div = dsi_div->dtable; div->div; div++) { + if (i >= RZV2H_MAX_DIV_TABLES) + return -EINVAL; + table[i++] = div->div; + } + + if (!rzv2h_get_pll_divs_pars(dsi_info->pll_dsi_limits, dsi_params, table, i, + rate_millihz)) { + dev_err(priv->dev, "failed to determine rate for req->rate: %lu\n", + req->rate); + return -EINVAL; + } + +exit_determine_rate: + req->rate = DIV_ROUND_CLOSEST_ULL(dsi_params->div.freq_millihz, MILLI); + req->best_parent_rate = req->rate * dsi_params->div.divider_value; + dsi_info->req_pll_dsi_rate = req->best_parent_rate; + + return 0; +} + +static int rzv2h_cpg_plldsi_div_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw); + struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw)); + struct rzv2h_cpg_priv *priv = dsi_div->priv; + struct rzv2h_pll_div_pars *dsi_params; + struct rzv2h_pll_dsi_info *dsi_info; + struct ddiv ddiv = dsi_div->ddiv; + const struct clk_div_table *clkt; + bool divider_found = false; + u32 val, shift; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + dsi_params = &dsi_info->pll_dsi_parameters; + + for (clkt = dsi_div->dtable; clkt->div; clkt++) { + if (clkt->div == dsi_params->div.divider_value) { + divider_found = true; + break; + } + } + + if (!divider_found) + return -EINVAL; + + shift = ddiv.shift; + val = readl(priv->base + ddiv.offset) | DDIV_DIVCTL_WEN(shift); + val &= ~(clk_div_mask(ddiv.width) << shift); + val |= clkt->val << shift; + writel(val, priv->base + ddiv.offset); + + return 0; +} + +static const struct clk_ops rzv2h_cpg_plldsi_div_ops = { + .recalc_rate = rzv2h_cpg_plldsi_div_recalc_rate, + .determine_rate = rzv2h_cpg_plldsi_div_determine_rate, + .set_rate = rzv2h_cpg_plldsi_div_set_rate, +}; + +static struct clk * __init +rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core, + struct rzv2h_cpg_priv *priv) +{ + struct rzv2h_plldsi_div_clk *clk_hw_data; + struct clk **clks = priv->clks; + struct clk_init_data init; + const struct clk *parent; + const char *parent_name; + struct clk_hw *clk_hw; + int ret; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); + if (!clk_hw_data) + return ERR_PTR(-ENOMEM); + + clk_hw_data->priv = priv; + clk_hw_data->ddiv = core->cfg.ddiv; + clk_hw_data->dtable = core->dtable; + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &rzv2h_cpg_plldsi_div_ops; + init.flags = core->flag; + init.parent_names = &parent_name; + init.num_parents = 1; + + clk_hw = &clk_hw_data->hw; + clk_hw->init = &init; + + ret = devm_clk_hw_register(priv->dev, clk_hw); + if (ret) + return ERR_PTR(ret); + + return clk_hw->clk; +} + +static int rzv2h_cpg_plldsi_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzv2h_cpg_priv *priv = pll_clk->priv; + struct rzv2h_pll_dsi_info *dsi_info; + u64 rate_millihz; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + /* check if the divider has already invoked the algorithm */ + if (req->rate == dsi_info->req_pll_dsi_rate) + return 0; + + /* If the req->rate doesn't match we do the calculation assuming there is no divider */ + rate_millihz = mul_u32_u32(req->rate, MILLI); + if (!rzv2h_get_pll_pars(dsi_info->pll_dsi_limits, + &dsi_info->pll_dsi_parameters.pll, rate_millihz)) { + dev_err(priv->dev, + "failed to determine rate for req->rate: %lu\n", + req->rate); + return -EINVAL; + } + + req->rate = DIV_ROUND_CLOSEST_ULL(dsi_info->pll_dsi_parameters.pll.freq_millihz, MILLI); + dsi_info->req_pll_dsi_rate = req->rate; + + return 0; +} + +static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk, + struct rzv2h_pll_pars *params, + bool ssc_disable) +{ + struct rzv2h_cpg_priv *priv = pll_clk->priv; + u16 offset = pll_clk->pll.offset; + u32 val; + int ret; + + /* Put PLL into standby mode */ + writel(CPG_PLL_STBY_RESETB_WEN, priv->base + CPG_PLL_STBY(offset)); + ret = readl_poll_timeout_atomic(priv->base + CPG_PLL_MON(offset), + val, !(val & CPG_PLL_MON_LOCK), + 100, 2000); + if (ret) { + dev_err(priv->dev, "Failed to put PLLDSI into standby mode"); + return ret; + } + + /* Output clock setting 1 */ + writel(FIELD_PREP(CPG_PLL_CLK1_KDIV, (u16)params->k) | + FIELD_PREP(CPG_PLL_CLK1_MDIV, params->m) | + FIELD_PREP(CPG_PLL_CLK1_PDIV, params->p), + priv->base + CPG_PLL_CLK1(offset)); + + /* Output clock setting 2 */ + val = readl(priv->base + CPG_PLL_CLK2(offset)); + writel((val & ~CPG_PLL_CLK2_SDIV) | FIELD_PREP(CPG_PLL_CLK2_SDIV, params->s), + priv->base + CPG_PLL_CLK2(offset)); + + /* Put PLL to normal mode */ + if (ssc_disable) + val = CPG_PLL_STBY_SSC_EN_WEN; + else + val = CPG_PLL_STBY_SSC_EN_WEN | CPG_PLL_STBY_SSC_EN; + writel(val | CPG_PLL_STBY_RESETB_WEN | CPG_PLL_STBY_RESETB, + priv->base + CPG_PLL_STBY(offset)); + + /* PLL normal mode transition, output clock stability check */ + ret = readl_poll_timeout_atomic(priv->base + CPG_PLL_MON(offset), + val, (val & CPG_PLL_MON_LOCK), + 100, 2000); + if (ret) { + dev_err(priv->dev, "Failed to put PLLDSI into normal mode"); + return ret; + } + + return 0; +} + +static int rzv2h_cpg_plldsi_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzv2h_pll_dsi_info *dsi_info; + struct rzv2h_cpg_priv *priv = pll_clk->priv; + + dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance]; + + return rzv2h_cpg_pll_set_rate(pll_clk, &dsi_info->pll_dsi_parameters.pll, true); +} + static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw) { struct pll_clk *pll_clk = to_pll(hw); @@ -238,6 +719,12 @@ static unsigned long rzv2h_cpg_pll_clk_recalc_rate(struct clk_hw *hw, return DIV_ROUND_CLOSEST_ULL(rate, FIELD_GET(CPG_PLL_CLK1_PDIV, clk1)); } +static const struct clk_ops rzv2h_cpg_plldsi_ops = { + .recalc_rate = rzv2h_cpg_pll_clk_recalc_rate, + .determine_rate = rzv2h_cpg_plldsi_determine_rate, + .set_rate = rzv2h_cpg_plldsi_set_rate, +}; + static const struct clk_ops rzv2h_cpg_pll_ops = { .is_enabled = rzv2h_cpg_pll_clk_is_enabled, .enable = rzv2h_cpg_pll_clk_enable, @@ -264,6 +751,10 @@ rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core, if (!pll_clk) return ERR_PTR(-ENOMEM); + if (core->type == CLK_TYPE_PLLDSI) + priv->pll_dsi_info[core->cfg.pll.instance].pll_dsi_limits = + core->cfg.pll.limits; + parent_name = __clk_get_name(parent); init.name = core->name; init.ops = ops; @@ -588,6 +1079,12 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core, case CLK_TYPE_SMUX: clk = rzv2h_cpg_mux_clk_register(core, priv); break; + case CLK_TYPE_PLLDSI: + clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_plldsi_ops); + break; + case CLK_TYPE_PLLDSI_DIV: + clk = rzv2h_cpg_plldsi_div_clk_register(core, priv); + break; default: goto fail; } diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h index e2053049c299..637803bc1e89 100644 --- a/drivers/clk/renesas/rzv2h-cpg.h +++ b/drivers/clk/renesas/rzv2h-cpg.h @@ -22,15 +22,20 @@ struct pll { unsigned int offset:9; unsigned int has_clkn:1; unsigned int instance:2; + const struct rzv2h_pll_limits *limits; }; -#define PLL_PACK(_offset, _has_clkn, _instance) \ +#define PLL_PACK_LIMITS(_offset, _has_clkn, _instance, _limits) \ ((struct pll){ \ .offset = _offset, \ .has_clkn = _has_clkn, \ - .instance = _instance \ + .instance = _instance, \ + .limits = _limits \ }) +#define PLL_PACK(_offset, _has_clkn, _instance) \ + PLL_PACK_LIMITS(_offset, _has_clkn, _instance, NULL) + #define PLLCA55 PLL_PACK(0x60, 1, 0) #define PLLGPU PLL_PACK(0x120, 1, 0) @@ -191,6 +196,8 @@ enum clk_types { CLK_TYPE_PLL, CLK_TYPE_DDIV, /* Dynamic Switching Divider */ CLK_TYPE_SMUX, /* Static Mux */ + CLK_TYPE_PLLDSI, /* PLLDSI */ + CLK_TYPE_PLLDSI_DIV, /* PLLDSI divider */ }; #define DEF_TYPE(_name, _id, _type...) \ @@ -221,6 +228,14 @@ enum clk_types { .num_parents = ARRAY_SIZE(_parent_names), \ .flag = CLK_SET_RATE_PARENT, \ .mux_flags = CLK_MUX_HIWORD_MASK) +#define DEF_PLLDSI(_name, _id, _parent, _pll_packed) \ + DEF_TYPE(_name, _id, CLK_TYPE_PLLDSI, .parent = _parent, .cfg.pll = _pll_packed) +#define DEF_PLLDSI_DIV(_name, _id, _parent, _ddiv_packed, _dtable) \ + DEF_TYPE(_name, _id, CLK_TYPE_PLLDSI_DIV, \ + .cfg.ddiv = _ddiv_packed, \ + .dtable = _dtable, \ + .parent = _parent, \ + .flag = CLK_SET_RATE_PARENT) /** * struct rzv2h_mod_clk - Module Clocks definitions diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h index 0ebbe2f0b45e..69d8159deee3 100644 --- a/include/linux/clk/renesas.h +++ b/include/linux/clk/renesas.h @@ -10,7 +10,9 @@ #ifndef __LINUX_CLK_RENESAS_H_ #define __LINUX_CLK_RENESAS_H_ +#include #include +#include struct device; struct device_node; @@ -32,4 +34,147 @@ void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev); #define cpg_mssr_attach_dev NULL #define cpg_mssr_detach_dev NULL #endif + +/** + * struct rzv2h_pll_limits - PLL parameter constraints + * + * This structure defines the minimum and maximum allowed values for + * various parameters used to configure a PLL. These limits ensure + * the PLL operates within valid and stable ranges. + * + * @fout: Output frequency range (in MHz) + * @fout.min: Minimum allowed output frequency + * @fout.max: Maximum allowed output frequency + * + * @fvco: PLL oscillation frequency range (in MHz) + * @fvco.min: Minimum allowed VCO frequency + * @fvco.max: Maximum allowed VCO frequency + * + * @m: Main-divider range + * @m.min: Minimum main-divider value + * @m.max: Maximum main-divider value + * + * @p: Pre-divider range + * @p.min: Minimum pre-divider value + * @p.max: Maximum pre-divider value + * + * @s: Divider range + * @s.min: Minimum divider value + * @s.max: Maximum divider value + * + * @k: Delta-sigma modulator range (signed) + * @k.min: Minimum delta-sigma value + * @k.max: Maximum delta-sigma value + */ +struct rzv2h_pll_limits { + struct { + u32 min; + u32 max; + } fout; + + struct { + u32 min; + u32 max; + } fvco; + + struct { + u16 min; + u16 max; + } m; + + struct { + u8 min; + u8 max; + } p; + + struct { + u8 min; + u8 max; + } s; + + struct { + s16 min; + s16 max; + } k; +}; + +/** + * struct rzv2h_pll_pars - PLL configuration parameters + * + * This structure contains the configuration parameters for the + * Phase-Locked Loop (PLL), used to achieve a specific output frequency. + * + * @m: Main divider value + * @p: Pre-divider value + * @s: Output divider value + * @k: Delta-sigma modulation value + * @freq_millihz: Calculated PLL output frequency in millihertz + * @error_millihz: Frequency error from target in millihertz (signed) + */ +struct rzv2h_pll_pars { + u16 m; + u8 p; + u8 s; + s16 k; + u64 freq_millihz; + s64 error_millihz; +}; + +/** + * struct rzv2h_pll_div_pars - PLL parameters with post-divider + * + * This structure is used for PLLs that include an additional post-divider + * stage after the main PLL block. It contains both the PLL configuration + * parameters and the resulting frequency/error values after the divider. + * + * @pll: Main PLL configuration parameters (see struct rzv2h_pll_pars) + * + * @div: Post-divider configuration and result + * @div.divider_value: Divider applied to the PLL output + * @div.freq_millihz: Output frequency after divider in millihertz + * @div.error_millihz: Frequency error from target in millihertz (signed) + */ +struct rzv2h_pll_div_pars { + struct rzv2h_pll_pars pll; + struct { + u8 divider_value; + u64 freq_millihz; + s64 error_millihz; + } div; +}; + +#define RZV2H_CPG_PLL_DSI_LIMITS(name) \ + static const struct rzv2h_pll_limits (name) = { \ + .fout = { .min = 25 * MEGA, .max = 375 * MEGA }, \ + .fvco = { .min = 1600 * MEGA, .max = 3200 * MEGA }, \ + .m = { .min = 64, .max = 533 }, \ + .p = { .min = 1, .max = 4 }, \ + .s = { .min = 0, .max = 6 }, \ + .k = { .min = -32768, .max = 32767 }, \ + } \ + +#ifdef CONFIG_CLK_RZV2H +bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, u64 freq_millihz); + +bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, u64 freq_millihz); +#else +static inline bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, + u64 freq_millihz) +{ + return false; +} + +static inline bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, + u64 freq_millihz) +{ + return false; +} +#endif + #endif From 66a470abe950fd7ebb0cfd909581fb9573f8b629 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 15 Oct 2025 20:26:08 +0100 Subject: [PATCH 054/117] clk: renesas: r9a09g057: Add clock and reset entries for DSI and LCDC Add clock and reset entries for the DSI and LCDC peripherals. Co-developed-by: Fabrizio Castro Signed-off-by: Fabrizio Castro Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251015192611.241920-5-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g057-cpg.c | 62 +++++++++++++++++++++++++++++ drivers/clk/renesas/rzv2h-cpg.h | 3 ++ 2 files changed, 65 insertions(+) diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index dce5755d85ec..c9f6d91884c3 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -30,6 +31,7 @@ enum clk_ids { CLK_PLLCA55, CLK_PLLVDO, CLK_PLLETH, + CLK_PLLDSI, CLK_PLLGPU, /* Internal Core Clocks */ @@ -64,6 +66,9 @@ enum clk_ids { CLK_SMUX2_GBE0_RXCLK, CLK_SMUX2_GBE1_TXCLK, CLK_SMUX2_GBE1_RXCLK, + CLK_CDIV4_PLLETH_LPCLK, + CLK_PLLETH_LPCLK_GEAR, + CLK_PLLDSI_GEAR, CLK_PLLGPU_GEAR, /* Module Clocks */ @@ -92,6 +97,26 @@ static const struct clk_div_table dtable_2_16[] = { {0, 0}, }; +static const struct clk_div_table dtable_2_32[] = { + {0, 2}, + {1, 4}, + {2, 6}, + {3, 8}, + {4, 10}, + {5, 12}, + {6, 14}, + {7, 16}, + {8, 18}, + {9, 20}, + {10, 22}, + {11, 24}, + {12, 26}, + {13, 28}, + {14, 30}, + {15, 32}, + {0, 0}, +}; + static const struct clk_div_table dtable_2_64[] = { {0, 2}, {1, 4}, @@ -108,6 +133,17 @@ static const struct clk_div_table dtable_2_100[] = { {0, 0}, }; +static const struct clk_div_table dtable_16_128[] = { + {0, 16}, + {1, 32}, + {2, 64}, + {3, 128}, + {0, 0}, +}; + +RZV2H_CPG_PLL_DSI_LIMITS(rzv2h_cpg_pll_dsi_limits); +#define PLLDSI PLL_PACK_LIMITS(0xc0, 1, 0, &rzv2h_cpg_pll_dsi_limits) + /* Mux clock tables */ static const char * const smux2_gbe0_rxclk[] = { ".plleth_gbe0", "et0_rxclk" }; static const char * const smux2_gbe0_txclk[] = { ".plleth_gbe0", "et0_txclk" }; @@ -129,6 +165,7 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55), DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2), DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3), + DEF_PLLDSI(".plldsi", CLK_PLLDSI, CLK_QEXTAL, PLLDSI), DEF_PLL(".pllgpu", CLK_PLLGPU, CLK_QEXTAL, PLLGPU), /* Internal Core Clocks */ @@ -170,6 +207,12 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_SMUX(".smux2_gbe0_rxclk", CLK_SMUX2_GBE0_RXCLK, SSEL0_SELCTL3, smux2_gbe0_rxclk), DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk), DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk), + DEF_FIXED(".cdiv4_plleth_lpclk", CLK_CDIV4_PLLETH_LPCLK, CLK_PLLETH, 1, 4), + DEF_CSDIV(".plleth_lpclk_gear", CLK_PLLETH_LPCLK_GEAR, CLK_CDIV4_PLLETH_LPCLK, + CSDIV0_DIVCTL2, dtable_16_128), + + DEF_PLLDSI_DIV(".plldsi_gear", CLK_PLLDSI_GEAR, CLK_PLLDSI, + CSDIV1_DIVCTL2, dtable_2_32), DEF_DDIV(".pllgpu_gear", CLK_PLLGPU_GEAR, CLK_PLLGPU, CDDIV3_DIVCTL1, dtable_2_64), @@ -383,6 +426,22 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(9, BIT(9))), DEF_MOD("isp_0_isp_sclk", CLK_PLLVDO_ISP, 14, 5, 7, 5, BUS_MSTOP(9, BIT(9))), + DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_vclk1", CLK_PLLDSI_GEAR, 14, 10, 7, 10, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_lpclk", CLK_PLLETH_LPCLK_GEAR, 14, 11, 7, 11, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_pllref_clk", CLK_QEXTAL, 14, 12, 7, 12, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("lcdc_0_clk_a", CLK_PLLDTY_ACPU_DIV2, 14, 13, 7, 13, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), + DEF_MOD("lcdc_0_clk_p", CLK_PLLDTY_DIV16, 14, 14, 7, 14, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), + DEF_MOD("lcdc_0_clk_d", CLK_PLLDSI_GEAR, 14, 15, 7, 15, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), DEF_MOD("gpu_0_clk", CLK_PLLGPU_GEAR, 15, 0, 7, 16, BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17, @@ -464,6 +523,9 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(13, 2, 6, 3), /* ISP_0_REG_ARESETN */ DEF_RST(13, 3, 6, 4), /* ISP_0_ISP_SRESETN */ DEF_RST(13, 4, 6, 5), /* ISP_0_PRESETN */ + DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */ + DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */ + DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */ DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */ DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */ diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h index f7b4e4785d0f..dc957bdaf5e9 100644 --- a/drivers/clk/renesas/rzv2h-cpg.h +++ b/drivers/clk/renesas/rzv2h-cpg.h @@ -127,6 +127,7 @@ struct fixed_mod_conf { #define CPG_CDDIV3 (0x40C) #define CPG_CDDIV4 (0x410) #define CPG_CSDIV0 (0x500) +#define CPG_CSDIV1 (0x504) #define CDDIV0_DIVCTL1 DDIV_PACK(CPG_CDDIV0, 4, 3, 1) #define CDDIV0_DIVCTL2 DDIV_PACK(CPG_CDDIV0, 8, 3, 2) @@ -144,7 +145,9 @@ struct fixed_mod_conf { #define CSDIV0_DIVCTL0 DDIV_PACK(CPG_CSDIV0, 0, 2, CSDIV_NO_MON) #define CSDIV0_DIVCTL1 DDIV_PACK(CPG_CSDIV0, 4, 2, CSDIV_NO_MON) +#define CSDIV0_DIVCTL2 DDIV_PACK(CPG_CSDIV0, 8, 2, CSDIV_NO_MON) #define CSDIV0_DIVCTL3 DDIV_PACK_NO_RMW(CPG_CSDIV0, 12, 2, CSDIV_NO_MON) +#define CSDIV1_DIVCTL2 DDIV_PACK(CPG_CSDIV1, 8, 4, CSDIV_NO_MON) #define SSEL0_SELCTL2 SMUX_PACK(CPG_SSEL0, 8, 1) #define SSEL0_SELCTL3 SMUX_PACK(CPG_SSEL0, 12, 1) From 79276fb06d2f7769613abeeed65d69013137cefb Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 23 Oct 2025 11:19:15 +0300 Subject: [PATCH 055/117] clk: renesas: r9a09g077: Add TSU module clock The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have a TSU peripheral which is controlled by a module clock. The TSU module clock is enabled in register MSTPCRD (0x30c), at bit 7, resulting in a (0x30c - 0x300) / 4 * 100 + 7 = 307 index. Add it to the list of module clocks. Signed-off-by: Cosmin Tanislav Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251023081925.2412325-2-cosmin-gabriel.tanislav.xa@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index 4ec6c4ddc5f5..8b7e84a4c307 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -191,6 +191,7 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("adc0", 206, R9A09G077_CLK_PCLKH), DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH), DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM), + DEF_MOD("tsu", 307, R9A09G077_CLK_PCLKL), DEF_MOD("gmac0", 400, R9A09G077_CLK_PCLKM), DEF_MOD("ethsw", 401, R9A09G077_CLK_PCLKM), DEF_MOD("ethss", 403, R9A09G077_CLK_PCLKM), From d64522b54b26229ee074137135dbbcba72a4600b Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 23 Oct 2025 22:07:22 +0100 Subject: [PATCH 056/117] clk: renesas: r9a09g056: Add clocks and resets for DSI and LCDC modules Add clock and reset definitions required to support the DSI and LCDC hardware blocks on the RZ/V2N SoC. This includes new core clocks, clock dividers, module clocks, and reset entries, as well as PLL and divider configurations specific to these peripherals. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251023210724.666476-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 64 +++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 55f056359dd7..70b73d410135 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -29,6 +30,7 @@ enum clk_ids { CLK_PLLDTY, CLK_PLLCA55, CLK_PLLETH, + CLK_PLLDSI, CLK_PLLGPU, /* Internal Core Clocks */ @@ -47,6 +49,7 @@ enum clk_ids { CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_DIV8, + CLK_PLLDTY_DIV16, CLK_PLLETH_DIV_250_FIX, CLK_PLLETH_DIV_125_FIX, CLK_CSDIV_PLLETH_GBE0, @@ -55,6 +58,9 @@ enum clk_ids { CLK_SMUX2_GBE0_RXCLK, CLK_SMUX2_GBE1_TXCLK, CLK_SMUX2_GBE1_RXCLK, + CLK_CDIV4_PLLETH_LPCLK, + CLK_PLLETH_LPCLK_GEAR, + CLK_PLLDSI_GEAR, CLK_PLLGPU_GEAR, /* Module Clocks */ @@ -77,6 +83,26 @@ static const struct clk_div_table dtable_2_16[] = { {0, 0}, }; +static const struct clk_div_table dtable_2_32[] = { + {0, 2}, + {1, 4}, + {2, 6}, + {3, 8}, + {4, 10}, + {5, 12}, + {6, 14}, + {7, 16}, + {8, 18}, + {9, 20}, + {10, 22}, + {11, 24}, + {12, 26}, + {13, 28}, + {14, 30}, + {15, 32}, + {0, 0}, +}; + static const struct clk_div_table dtable_2_64[] = { {0, 2}, {1, 4}, @@ -93,6 +119,17 @@ static const struct clk_div_table dtable_2_100[] = { {0, 0}, }; +static const struct clk_div_table dtable_16_128[] = { + {0, 16}, + {1, 32}, + {2, 64}, + {3, 128}, + {0, 0}, +}; + +RZV2H_CPG_PLL_DSI_LIMITS(rzv2n_cpg_pll_dsi_limits); +#define PLLDSI PLL_PACK_LIMITS(0xc0, 1, 0, &rzv2n_cpg_pll_dsi_limits) + /* Mux clock tables */ static const char * const smux2_gbe0_rxclk[] = { ".plleth_gbe0", "et0_rxclk" }; static const char * const smux2_gbe0_txclk[] = { ".plleth_gbe0", "et0_txclk" }; @@ -113,6 +150,7 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".plldty", CLK_PLLDTY, CLK_QEXTAL, 200, 3), DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55), DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3), + DEF_PLLDSI(".plldsi", CLK_PLLDSI, CLK_QEXTAL, PLLDSI), DEF_PLL(".pllgpu", CLK_PLLGPU, CLK_QEXTAL, PLLGPU), /* Internal Core Clocks */ @@ -134,6 +172,7 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), DEF_FIXED(".plldty_acpu_div4", CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_ACPU, 1, 4), DEF_FIXED(".plldty_div8", CLK_PLLDTY_DIV8, CLK_PLLDTY, 1, 8), + DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16), DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4), DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2), @@ -145,6 +184,12 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_SMUX(".smux2_gbe0_rxclk", CLK_SMUX2_GBE0_RXCLK, SSEL0_SELCTL3, smux2_gbe0_rxclk), DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk), DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk), + DEF_FIXED(".cdiv4_plleth_lpclk", CLK_CDIV4_PLLETH_LPCLK, CLK_PLLETH, 1, 4), + DEF_CSDIV(".plleth_lpclk_gear", CLK_PLLETH_LPCLK_GEAR, CLK_CDIV4_PLLETH_LPCLK, + CSDIV0_DIVCTL2, dtable_16_128), + + DEF_PLLDSI_DIV(".plldsi_gear", CLK_PLLDSI_GEAR, CLK_PLLDSI, + CSDIV1_DIVCTL2, dtable_2_32), DEF_DDIV(".pllgpu_gear", CLK_PLLGPU_GEAR, CLK_PLLGPU, CDDIV3_DIVCTL1, dtable_2_64), @@ -289,6 +334,22 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(8, BIT(6))), DEF_MOD("gbeth_1_aclk_i", CLK_PLLDTY_DIV8, 12, 3, 6, 3, BUS_MSTOP(8, BIT(6))), + DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_vclk1", CLK_PLLDSI_GEAR, 14, 10, 7, 10, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_lpclk", CLK_PLLETH_LPCLK_GEAR, 14, 11, 7, 11, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("dsi_0_pllref_clk", CLK_QEXTAL, 14, 12, 7, 12, + BUS_MSTOP(9, BIT(14) | BIT(15))), + DEF_MOD("lcdc_0_clk_a", CLK_PLLDTY_ACPU_DIV2, 14, 13, 7, 13, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), + DEF_MOD("lcdc_0_clk_p", CLK_PLLDTY_DIV16, 14, 14, 7, 14, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), + DEF_MOD("lcdc_0_clk_d", CLK_PLLDSI_GEAR, 14, 15, 7, 15, + BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))), DEF_MOD("gpu_0_clk", CLK_PLLGPU_GEAR, 15, 0, 7, 16, BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17, @@ -335,6 +396,9 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */ DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */ DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */ + DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */ + DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */ + DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */ DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */ DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */ From 861df8792c69d903fbb705a0d314bfdd5546d72b Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 23 Oct 2025 22:07:23 +0100 Subject: [PATCH 057/117] clk: renesas: r9a09g056: Add support for PLLVDO, CRU clocks, and resets Add support for the PLLVDO clock and its related CRU clocks and reset entries in the R9A09G056 CPG driver. Introduce `CLK_PLLVDO` and associated clocks like `CLK_PLLVDO_CRU0` and `CLK_PLLVDO_CRU1`, along with their corresponding dividers. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251023210724.666476-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 70b73d410135..9c536f7706ff 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -29,6 +29,7 @@ enum clk_ids { CLK_PLLCLN, CLK_PLLDTY, CLK_PLLCA55, + CLK_PLLVDO, CLK_PLLETH, CLK_PLLDSI, CLK_PLLGPU, @@ -50,6 +51,8 @@ enum clk_ids { CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_DIV8, CLK_PLLDTY_DIV16, + CLK_PLLVDO_CRU0, + CLK_PLLVDO_CRU1, CLK_PLLETH_DIV_250_FIX, CLK_PLLETH_DIV_125_FIX, CLK_CSDIV_PLLETH_GBE0, @@ -75,6 +78,12 @@ static const struct clk_div_table dtable_1_8[] = { {0, 0}, }; +static const struct clk_div_table dtable_2_4[] = { + {0, 2}, + {1, 4}, + {0, 0}, +}; + static const struct clk_div_table dtable_2_16[] = { {0, 2}, {1, 4}, @@ -149,6 +158,7 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".pllcln", CLK_PLLCLN, CLK_QEXTAL, 200, 3), DEF_FIXED(".plldty", CLK_PLLDTY, CLK_QEXTAL, 200, 3), DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55), + DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2), DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3), DEF_PLLDSI(".plldsi", CLK_PLLDSI, CLK_QEXTAL, PLLDSI), DEF_PLL(".pllgpu", CLK_PLLGPU, CLK_QEXTAL, PLLGPU), @@ -174,6 +184,9 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".plldty_div8", CLK_PLLDTY_DIV8, CLK_PLLDTY, 1, 8), DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16), + DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4), + DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4), + DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4), DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2), DEF_CSDIV(".plleth_gbe0", CLK_CSDIV_PLLETH_GBE0, @@ -334,6 +347,18 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(8, BIT(6))), DEF_MOD("gbeth_1_aclk_i", CLK_PLLDTY_DIV8, 12, 3, 6, 3, BUS_MSTOP(8, BIT(6))), + DEF_MOD("cru_0_aclk", CLK_PLLDTY_ACPU_DIV2, 13, 2, 6, 18, + BUS_MSTOP(9, BIT(4))), + DEF_MOD_NO_PM("cru_0_vclk", CLK_PLLVDO_CRU0, 13, 3, 6, 19, + BUS_MSTOP(9, BIT(4))), + DEF_MOD("cru_0_pclk", CLK_PLLDTY_DIV16, 13, 4, 6, 20, + BUS_MSTOP(9, BIT(4))), + DEF_MOD("cru_1_aclk", CLK_PLLDTY_ACPU_DIV2, 13, 5, 6, 21, + BUS_MSTOP(9, BIT(5))), + DEF_MOD_NO_PM("cru_1_vclk", CLK_PLLVDO_CRU1, 13, 6, 6, 22, + BUS_MSTOP(9, BIT(5))), + DEF_MOD("cru_1_pclk", CLK_PLLDTY_DIV16, 13, 7, 6, 23, + BUS_MSTOP(9, BIT(5))), DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8, BUS_MSTOP(9, BIT(14) | BIT(15))), DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9, @@ -396,6 +421,12 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */ DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */ DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */ + DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */ + DEF_RST(12, 6, 5, 23), /* CRU_0_ARESETN */ + DEF_RST(12, 7, 5, 24), /* CRU_0_S_RESETN */ + DEF_RST(12, 8, 5, 25), /* CRU_1_PRESETN */ + DEF_RST(12, 9, 5, 26), /* CRU_1_ARESETN */ + DEF_RST(12, 10, 5, 27), /* CRU_1_S_RESETN */ DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */ DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */ DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */ From 07525a693a5ff6592668a0fd647153e4b4933cae Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 23 Oct 2025 22:07:24 +0100 Subject: [PATCH 058/117] clk: renesas: r9a09g056: Add clock and reset entries for ISP Add entries detailing the clocks and resets for the ISP in the RZ/V2N SoC. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251023210724.666476-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 9c536f7706ff..e4a6dfd2bec9 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -53,6 +53,7 @@ enum clk_ids { CLK_PLLDTY_DIV16, CLK_PLLVDO_CRU0, CLK_PLLVDO_CRU1, + CLK_PLLVDO_ISP, CLK_PLLETH_DIV_250_FIX, CLK_PLLETH_DIV_125_FIX, CLK_CSDIV_PLLETH_GBE0, @@ -186,6 +187,7 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4), DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4), + DEF_DDIV(".pllvdo_isp", CLK_PLLVDO_ISP, CLK_PLLVDO, CDDIV2_DIVCTL3, dtable_2_64), DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4), DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2), @@ -359,6 +361,14 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(9, BIT(5))), DEF_MOD("cru_1_pclk", CLK_PLLDTY_DIV16, 13, 7, 6, 23, BUS_MSTOP(9, BIT(5))), + DEF_MOD("isp_0_reg_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 2, 7, 2, + BUS_MSTOP(9, BIT(8))), + DEF_MOD("isp_0_pclk", CLK_PLLDTY_DIV16, 14, 3, 7, 3, + BUS_MSTOP(9, BIT(8))), + DEF_MOD("isp_0_vin_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 4, 7, 4, + BUS_MSTOP(9, BIT(9))), + DEF_MOD("isp_0_isp_sclk", CLK_PLLVDO_ISP, 14, 5, 7, 5, + BUS_MSTOP(9, BIT(9))), DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8, BUS_MSTOP(9, BIT(14) | BIT(15))), DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9, @@ -427,6 +437,10 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(12, 8, 5, 25), /* CRU_1_PRESETN */ DEF_RST(12, 9, 5, 26), /* CRU_1_ARESETN */ DEF_RST(12, 10, 5, 27), /* CRU_1_S_RESETN */ + DEF_RST(13, 1, 6, 2), /* ISP_0_VIN_ARESETN */ + DEF_RST(13, 2, 6, 3), /* ISP_0_REG_ARESETN */ + DEF_RST(13, 3, 6, 4), /* ISP_0_ISP_SRESETN */ + DEF_RST(13, 4, 6, 5), /* ISP_0_PRESETN */ DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */ DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */ DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */ From 0820c9373369c83de5202871d02682d583a91a9c Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 29 Oct 2025 15:07:54 +0530 Subject: [PATCH 059/117] clk: qcom: gcc-qcs615: Update the SDCC clock to use shared_floor_ops Fix "gcc_sdcc2_apps_clk_src: rcg didn't update its configuration" during boot. This happens due to the floor_ops tries to update the rcg configuration even if the clock is not enabled. The shared_floor_ops ensures that the RCG is safely parked and the new parent configuration is cached in the parked_cfg when the clock is off. Ensure to use the ops for the other SDCC clock instances as well. Fixes: 39d6dcf67fe9 ("clk: qcom: gcc: Add support for QCS615 GCC clocks") Reviewed-by: Abel Vesa Signed-off-by: Taniya Das Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251029-sdcc_rcg2_shared_ops-v3-1-ecf47d9601d1@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-qcs615.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/gcc-qcs615.c b/drivers/clk/qcom/gcc-qcs615.c index 9695446bc2a3..5b3b8dd4f114 100644 --- a/drivers/clk/qcom/gcc-qcs615.c +++ b/drivers/clk/qcom/gcc-qcs615.c @@ -784,7 +784,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -806,7 +806,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .name = "gcc_sdcc1_ice_core_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -830,7 +830,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From a4aa1ceb89f5c0d27a55671d88699cf5eae7331b Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 31 Oct 2025 15:32:25 +0530 Subject: [PATCH 060/117] clk: qcom: tcsrcc-glymur: Update register offsets for clock refs Update the register offsets for all the clock ref branches to match the new address mapping in the TCSR subsystem. Fixes: 2c1d6ce4f3da ("clk: qcom: Add TCSR clock driver for Glymur SoC") Signed-off-by: Taniya Das Reviewed-by: Abel Vesa Tested-by: Jagadeesh Kona Link: https://lore.kernel.org/r/20251031-tcsrcc_glymur-v1-1-0efb031f0ac5@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/tcsrcc-glymur.c | 54 ++++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/clk/qcom/tcsrcc-glymur.c b/drivers/clk/qcom/tcsrcc-glymur.c index c1f8b6d10b7f..215bc2ac548d 100644 --- a/drivers/clk/qcom/tcsrcc-glymur.c +++ b/drivers/clk/qcom/tcsrcc-glymur.c @@ -28,10 +28,10 @@ enum { }; static struct clk_branch tcsr_edp_clkref_en = { - .halt_reg = 0x1c, + .halt_reg = 0x60, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x1c, + .enable_reg = 0x60, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_edp_clkref_en", @@ -45,10 +45,10 @@ static struct clk_branch tcsr_edp_clkref_en = { }; static struct clk_branch tcsr_pcie_1_clkref_en = { - .halt_reg = 0x4, + .halt_reg = 0x48, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x4, + .enable_reg = 0x48, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_pcie_1_clkref_en", @@ -62,10 +62,10 @@ static struct clk_branch tcsr_pcie_1_clkref_en = { }; static struct clk_branch tcsr_pcie_2_clkref_en = { - .halt_reg = 0x8, + .halt_reg = 0x4c, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x8, + .enable_reg = 0x4c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_pcie_2_clkref_en", @@ -79,10 +79,10 @@ static struct clk_branch tcsr_pcie_2_clkref_en = { }; static struct clk_branch tcsr_pcie_3_clkref_en = { - .halt_reg = 0x10, + .halt_reg = 0x54, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x10, + .enable_reg = 0x54, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_pcie_3_clkref_en", @@ -96,10 +96,10 @@ static struct clk_branch tcsr_pcie_3_clkref_en = { }; static struct clk_branch tcsr_pcie_4_clkref_en = { - .halt_reg = 0x14, + .halt_reg = 0x58, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x14, + .enable_reg = 0x58, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_pcie_4_clkref_en", @@ -113,10 +113,10 @@ static struct clk_branch tcsr_pcie_4_clkref_en = { }; static struct clk_branch tcsr_usb2_1_clkref_en = { - .halt_reg = 0x28, + .halt_reg = 0x6c, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x28, + .enable_reg = 0x6c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb2_1_clkref_en", @@ -130,10 +130,10 @@ static struct clk_branch tcsr_usb2_1_clkref_en = { }; static struct clk_branch tcsr_usb2_2_clkref_en = { - .halt_reg = 0x2c, + .halt_reg = 0x70, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x2c, + .enable_reg = 0x70, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb2_2_clkref_en", @@ -147,10 +147,10 @@ static struct clk_branch tcsr_usb2_2_clkref_en = { }; static struct clk_branch tcsr_usb2_3_clkref_en = { - .halt_reg = 0x30, + .halt_reg = 0x74, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x30, + .enable_reg = 0x74, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb2_3_clkref_en", @@ -164,10 +164,10 @@ static struct clk_branch tcsr_usb2_3_clkref_en = { }; static struct clk_branch tcsr_usb2_4_clkref_en = { - .halt_reg = 0x44, + .halt_reg = 0x88, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x44, + .enable_reg = 0x88, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb2_4_clkref_en", @@ -181,10 +181,10 @@ static struct clk_branch tcsr_usb2_4_clkref_en = { }; static struct clk_branch tcsr_usb3_0_clkref_en = { - .halt_reg = 0x20, + .halt_reg = 0x64, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x20, + .enable_reg = 0x64, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb3_0_clkref_en", @@ -198,10 +198,10 @@ static struct clk_branch tcsr_usb3_0_clkref_en = { }; static struct clk_branch tcsr_usb3_1_clkref_en = { - .halt_reg = 0x24, + .halt_reg = 0x68, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x24, + .enable_reg = 0x68, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb3_1_clkref_en", @@ -215,10 +215,10 @@ static struct clk_branch tcsr_usb3_1_clkref_en = { }; static struct clk_branch tcsr_usb4_1_clkref_en = { - .halt_reg = 0x0, + .halt_reg = 0x44, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x44, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb4_1_clkref_en", @@ -232,10 +232,10 @@ static struct clk_branch tcsr_usb4_1_clkref_en = { }; static struct clk_branch tcsr_usb4_2_clkref_en = { - .halt_reg = 0x18, + .halt_reg = 0x5c, .halt_check = BRANCH_HALT_DELAY, .clkr = { - .enable_reg = 0x18, + .enable_reg = 0x5c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_usb4_2_clkref_en", @@ -268,7 +268,7 @@ static const struct regmap_config tcsr_cc_glymur_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x44, + .max_register = 0x94, .fast_io = true, }; From eb43534ee4bbfdd0fc134ee245a773555480937b Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 29 Oct 2025 16:11:18 +0000 Subject: [PATCH 061/117] dt-bindings: clk: microchip: mpfs: remove first reg region The first reg region in this binding is not exclusively for clocks, as evidenced by the dual role of this device as a reset controller at present. The first region is however better described by a simple-mfd syscon, but this would have require a significant re-write of the devicetree for the platform, so the easy way out was chosen when reset support was first introduced. The region doesn't just contain clock and reset registers, it also contains pinctrl and interrupt controller functionality, so drop the region from the clock binding so that it can be described instead by a simple-mfd syscon rather than propagate this incorrect description of the hardware to the new pic64gx SoC. Acked-by: Rob Herring (Arm) Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20251029-unwatched-family-e47cb29ea815@spud Signed-off-by: Claudiu Beznea --- .../bindings/clock/microchip,mpfs-clkcfg.yaml | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml index e4e1c31267d2..ee4f31596d97 100644 --- a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml +++ b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml @@ -22,16 +22,23 @@ properties: const: microchip,mpfs-clkcfg reg: - items: - - description: | - clock config registers: - These registers contain enable, reset & divider tables for the, cpu, - axi, ahb and rtc/mtimer reference clocks as well as enable and reset - for the peripheral clocks. - - description: | - mss pll dri registers: - Block of registers responsible for dynamic reconfiguration of the mss - pll + oneOf: + - items: + - description: | + clock config registers: + These registers contain enable, reset & divider tables for the, cpu, + axi, ahb and rtc/mtimer reference clocks as well as enable and reset + for the peripheral clocks. + - description: | + mss pll dri registers: + Block of registers responsible for dynamic reconfiguration of the mss + pll + deprecated: true + - items: + - description: | + mss pll dri registers: + Block of registers responsible for dynamic reconfiguration of the mss + pll clocks: maxItems: 1 @@ -69,11 +76,12 @@ examples: - | #include soc { - #address-cells = <2>; - #size-cells = <2>; - clkcfg: clock-controller@20002000 { + #address-cells = <1>; + #size-cells = <1>; + + clkcfg: clock-controller@3E001000 { compatible = "microchip,mpfs-clkcfg"; - reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; + reg = <0x3E001000 0x1000>; clocks = <&ref>; #clock-cells = <1>; }; From c6f2dddfa7f9579eeab67690def4be8094b4336d Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 29 Oct 2025 16:11:19 +0000 Subject: [PATCH 062/117] clk: microchip: mpfs: use regmap for clocks Convert the PolarFire SoC clock driver to use regmaps instead of iomem addresses as a preparatory work for supporting the new binding for this device that will only provide the second of the two register regions, and will require the use of syscon regmap to access the "cfg" and "periph" clocks currently supported by the driver. This is effectively a revert of commit 4da2404bb003 ("clk: microchip: mpfs: convert cfg_clk to clk_divider") and commit d815569783e6 ("clk: microchip: mpfs: convert periph_clk to clk_gate") as it resurrects the ops structures removed in those commits, with the readl()s and writel()s replaced by regmap_read()s and regmap_writes()s. Signed-off-by: Conor Dooley Reviewed-by: Claudiu Beznea Link: https://lore.kernel.org/r/20251029-surfboard-refocus-ca9b135ab123@spud Signed-off-by: Claudiu Beznea --- drivers/clk/microchip/Kconfig | 2 + drivers/clk/microchip/clk-mpfs.c | 227 +++++++++++++++++++++++++------ 2 files changed, 186 insertions(+), 43 deletions(-) diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig index 0724ce65898f..1b9e43eb5497 100644 --- a/drivers/clk/microchip/Kconfig +++ b/drivers/clk/microchip/Kconfig @@ -7,6 +7,8 @@ config MCHP_CLK_MPFS bool "Clk driver for PolarFire SoC" depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST default ARCH_MICROCHIP_POLARFIRE + depends on MFD_SYSCON select AUXILIARY_BUS + select REGMAP_MMIO help Supports Clock Configuration for PolarFire SoC diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c index c22632a7439c..484893e68b67 100644 --- a/drivers/clk/microchip/clk-mpfs.c +++ b/drivers/clk/microchip/clk-mpfs.c @@ -4,10 +4,13 @@ * * Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved. */ +#include #include #include +#include #include #include +#include #include #include @@ -30,6 +33,14 @@ #define MSSPLL_POSTDIV_WIDTH 0x07u #define MSSPLL_FIXED_DIV 4u +static const struct regmap_config mpfs_clk_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .val_format_endian = REGMAP_ENDIAN_LITTLE, + .max_register = REG_SUBBLK_CLOCK_CR, +}; + /* * This clock ID is defined here, rather than the binding headers, as it is an * internal clock only, and therefore has no consumers in other peripheral @@ -39,6 +50,7 @@ struct mpfs_clock_data { struct device *dev; + struct regmap *regmap; void __iomem *base; void __iomem *msspll_base; struct clk_hw_onecell_data hw_data; @@ -67,21 +79,39 @@ struct mpfs_msspll_out_hw_clock { #define to_mpfs_msspll_out_clk(_hw) container_of(_hw, struct mpfs_msspll_out_hw_clock, hw) +struct mpfs_cfg_clock { + struct regmap *map; + const struct clk_div_table *table; + u8 map_offset; + u8 shift; + u8 width; + u8 flags; +}; + struct mpfs_cfg_hw_clock { - struct clk_divider cfg; - struct clk_init_data init; + struct clk_hw hw; + struct mpfs_cfg_clock cfg; unsigned int id; - u32 reg_offset; +}; + +#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw) + +struct mpfs_periph_clock { + struct regmap *map; + u8 map_offset; + u8 shift; }; struct mpfs_periph_hw_clock { - struct clk_gate periph; + struct clk_hw hw; + struct mpfs_periph_clock periph; unsigned int id; }; +#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw) + /* - * mpfs_clk_lock prevents anything else from writing to the - * mpfs clk block while a software locked register is being written. + * Protects MSSPLL outputs, since there's two to a register */ static DEFINE_SPINLOCK(mpfs_clk_lock); @@ -219,16 +249,61 @@ static int mpfs_clk_register_msspll_outs(struct device *dev, /* * "CFG" clocks */ +static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + u32 val; -#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \ - .id = _id, \ - .cfg.shift = _shift, \ - .cfg.width = _width, \ - .cfg.table = _table, \ - .reg_offset = _offset, \ - .cfg.flags = _flags, \ - .cfg.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0), \ - .cfg.lock = &mpfs_clk_lock, \ + regmap_read(cfg->map, cfg->map_offset, &val); + val >>= cfg->shift; + val &= clk_div_mask(cfg->width); + + return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width); +} + +static int mpfs_cfg_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + + return divider_determine_rate(hw, req, cfg->table, cfg->width, 0); +} + +static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + int divider_setting; + u32 val; + u32 mask; + + divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0); + + if (divider_setting < 0) + return divider_setting; + + mask = clk_div_mask(cfg->width) << cfg->shift; + val = divider_setting << cfg->shift; + regmap_update_bits(cfg->map, cfg->map_offset, val, mask); + + return 0; +} + +static const struct clk_ops mpfs_clk_cfg_ops = { + .recalc_rate = mpfs_cfg_clk_recalc_rate, + .determine_rate = mpfs_cfg_clk_determine_rate, + .set_rate = mpfs_cfg_clk_set_rate, +}; + +#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \ + .id = _id, \ + .cfg.shift = _shift, \ + .cfg.width = _width, \ + .cfg.table = _table, \ + .cfg.map_offset = _offset, \ + .cfg.flags = _flags, \ + .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \ } #define CLK_CPU_OFFSET 0u @@ -248,10 +323,10 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = { .cfg.shift = 0, .cfg.width = 12, .cfg.table = mpfs_div_rtcref_table, - .reg_offset = REG_RTC_CLOCK_CR, + .cfg.map_offset = REG_RTC_CLOCK_CR, .cfg.flags = CLK_DIVIDER_ONE_BASED, - .cfg.hw.init = - CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &clk_divider_ops, 0), + .hw.init = + CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0), } }; @@ -264,14 +339,14 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock * for (i = 0; i < num_clks; i++) { struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i]; - cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset; - ret = devm_clk_hw_register(dev, &cfg_hw->cfg.hw); + cfg_hw->cfg.map = data->regmap; + ret = devm_clk_hw_register(dev, &cfg_hw->hw); if (ret) return dev_err_probe(dev, ret, "failed to register clock id: %d\n", cfg_hw->id); id = cfg_hw->id; - data->hw_data.hws[id] = &cfg_hw->cfg.hw; + data->hw_data.hws[id] = &cfg_hw->hw; } return 0; @@ -281,15 +356,50 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock * * peripheral clocks - devices connected to axi or ahb buses. */ -#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \ - .id = _id, \ - .periph.bit_idx = _shift, \ - .periph.hw.init = CLK_HW_INIT_HW(_name, _parent, &clk_gate_ops, \ - _flags), \ - .periph.lock = &mpfs_clk_lock, \ +static int mpfs_periph_clk_enable(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + + regmap_update_bits(periph->map, periph->map_offset, + BIT(periph->shift), BIT(periph->shift)); + + return 0; } -#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].cfg.hw) +static void mpfs_periph_clk_disable(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + + regmap_update_bits(periph->map, periph->map_offset, BIT(periph->shift), 0); +} + +static int mpfs_periph_clk_is_enabled(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + u32 val; + + regmap_read(periph->map, periph->map_offset, &val); + + return !!(val & BIT(periph->shift)); +} + +static const struct clk_ops mpfs_periph_clk_ops = { + .enable = mpfs_periph_clk_enable, + .disable = mpfs_periph_clk_disable, + .is_enabled = mpfs_periph_clk_is_enabled, +}; + +#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \ + .id = _id, \ + .periph.map_offset = REG_SUBBLK_CLOCK_CR, \ + .periph.shift = _shift, \ + .hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, _flags), \ +} + +#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].hw) /* * Critical clocks: @@ -346,19 +456,55 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c for (i = 0; i < num_clks; i++) { struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i]; - periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR; - ret = devm_clk_hw_register(dev, &periph_hw->periph.hw); + periph_hw->periph.map = data->regmap; + ret = devm_clk_hw_register(dev, &periph_hw->hw); if (ret) return dev_err_probe(dev, ret, "failed to register clock id: %d\n", periph_hw->id); id = periph_hws[i].id; - data->hw_data.hws[id] = &periph_hw->periph.hw; + data->hw_data.hws[id] = &periph_hw->hw; } return 0; } +static inline int mpfs_clk_syscon_probe(struct mpfs_clock_data *clk_data, + struct platform_device *pdev) +{ + clk_data->regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-mss-top-sysreg"); + if (IS_ERR(clk_data->regmap)) + return PTR_ERR(clk_data->regmap); + + clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_data->msspll_base)) + return PTR_ERR(clk_data->msspll_base); + + return 0; +} + +static inline int mpfs_clk_old_format_probe(struct mpfs_clock_data *clk_data, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + dev_warn(&pdev->dev, "falling back to old devicetree format"); + + clk_data->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_data->base)) + return PTR_ERR(clk_data->base); + + clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(clk_data->msspll_base)) + return PTR_ERR(clk_data->msspll_base); + + clk_data->regmap = devm_regmap_init_mmio(dev, clk_data->base, &mpfs_clk_regmap_config); + if (IS_ERR(clk_data->regmap)) + return PTR_ERR(clk_data->regmap); + + return mpfs_reset_controller_register(dev, clk_data->base + REG_SUBBLK_RESET_CR); +} + static int mpfs_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -374,13 +520,12 @@ static int mpfs_clk_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - clk_data->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(clk_data->base)) - return PTR_ERR(clk_data->base); - - clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(clk_data->msspll_base)) - return PTR_ERR(clk_data->msspll_base); + ret = mpfs_clk_syscon_probe(clk_data, pdev); + if (ret) { + ret = mpfs_clk_old_format_probe(clk_data, pdev); + if (ret) + return ret; + } clk_data->hw_data.num = num_clks; clk_data->dev = dev; @@ -406,11 +551,7 @@ static int mpfs_clk_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data); - if (ret) - return ret; - - return mpfs_reset_controller_register(dev, clk_data->base + REG_SUBBLK_RESET_CR); + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data); } static const struct of_device_id mpfs_clk_of_match_table[] = { From 15c320b286a128131193ad270d7aac23bba4c219 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Thu, 30 Oct 2025 16:39:04 +0530 Subject: [PATCH 063/117] dt-bindings: clock: qcom-rpmhcc: Add RPMHCC for Kaanapali Update the documentation for RPMH clock controller for Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20251030-gcc_kaanapali-v2-v2-1-a774a587af6f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index 78fa05726685..3f5f1336262e 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -18,6 +18,7 @@ properties: compatible: enum: - qcom,glymur-rpmh-clk + - qcom,kaanapali-rpmh-clk - qcom,milos-rpmh-clk - qcom,qcs615-rpmh-clk - qcom,qdu1000-rpmh-clk From 395e0e794f9a485d9a5d6af062f096b97beecc11 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Thu, 30 Oct 2025 16:39:05 +0530 Subject: [PATCH 064/117] dt-bindings: clock: qcom: Document the Kaanapali TCSR Clock Controller Add bindings documentation for TCSR Clock Controller for Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20251030-gcc_kaanapali-v2-v2-2-a774a587af6f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml index 2c992b3437f2..784fef830681 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml @@ -25,6 +25,7 @@ properties: items: - enum: - qcom,glymur-tcsr + - qcom,kaanapali-tcsr - qcom,milos-tcsr - qcom,sar2130p-tcsr - qcom,sm8550-tcsr From 342d2a607450f256105781d29aa6300921c6152e Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Thu, 30 Oct 2025 16:39:06 +0530 Subject: [PATCH 065/117] dt-bindings: clock: qcom: Add Kaanapali Global clock controller Add device tree bindings for the global clock controller on Qualcomm Kaanapali platform. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20251030-gcc_kaanapali-v2-v2-3-a774a587af6f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8750-gcc.yaml | 8 +- .../dt-bindings/clock/qcom,kaanapali-gcc.h | 241 ++++++++++++++++++ 2 files changed, 247 insertions(+), 2 deletions(-) create mode 100644 include/dt-bindings/clock/qcom,kaanapali-gcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml index aab7039fd28d..0114d347b26f 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml @@ -13,11 +13,15 @@ description: | Qualcomm global clock control module provides the clocks, resets and power domains on SM8750 - See also: include/dt-bindings/clock/qcom,sm8750-gcc.h + See also: + include/dt-bindings/clock/qcom,kaanapali-gcc.h + include/dt-bindings/clock/qcom,sm8750-gcc.h properties: compatible: - const: qcom,sm8750-gcc + enum: + - qcom,kaanapali-gcc + - qcom,sm8750-gcc clocks: items: diff --git a/include/dt-bindings/clock/qcom,kaanapali-gcc.h b/include/dt-bindings/clock/qcom,kaanapali-gcc.h new file mode 100644 index 000000000000..890e48709f09 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-gcc.h @@ -0,0 +1,241 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_GCC_KAANAPALI_H + +/* GCC clocks */ +#define GCC_AGGRE_NOC_PCIE_AXI_CLK 0 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 1 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK 2 +#define GCC_BOOT_ROM_AHB_CLK 3 +#define GCC_CAM_BIST_MCLK_AHB_CLK 4 +#define GCC_CAMERA_AHB_CLK 5 +#define GCC_CAMERA_HF_AXI_CLK 6 +#define GCC_CAMERA_SF_AXI_CLK 7 +#define GCC_CAMERA_XO_CLK 8 +#define GCC_CFG_NOC_PCIE_ANOC_AHB_CLK 9 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 10 +#define GCC_CNOC_PCIE_SF_AXI_CLK 11 +#define GCC_DDRSS_PCIE_SF_QTB_CLK 12 +#define GCC_QMIP_CAMERA_CMD_AHB_CLK 13 +#define GCC_DISP_HF_AXI_CLK 14 +#define GCC_DISP_SF_AXI_CLK 15 +#define GCC_EVA_AHB_CLK 16 +#define GCC_EVA_AXI0_CLK 17 +#define GCC_EVA_AXI0C_CLK 18 +#define GCC_EVA_XO_CLK 19 +#define GCC_GP1_CLK 20 +#define GCC_GP1_CLK_SRC 21 +#define GCC_GP2_CLK 22 +#define GCC_GP2_CLK_SRC 23 +#define GCC_GP3_CLK 24 +#define GCC_GP3_CLK_SRC 25 +#define GCC_GPLL0 26 +#define GCC_GPLL0_OUT_EVEN 27 +#define GCC_GPLL1 28 +#define GCC_GPLL4 29 +#define GCC_GPLL7 30 +#define GCC_GPLL9 31 +#define GCC_GPU_CFG_AHB_CLK 32 +#define GCC_GPU_GEMNOC_GFX_CLK 33 +#define GCC_GPU_GPLL0_CLK_SRC 34 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 35 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 36 +#define GCC_QMIP_GPU_AHB_CLK 37 +#define GCC_PCIE_0_AUX_CLK 38 +#define GCC_PCIE_0_AUX_CLK_SRC 39 +#define GCC_PCIE_0_CFG_AHB_CLK 40 +#define GCC_PCIE_0_MSTR_AXI_CLK 41 +#define GCC_PCIE_0_PHY_AUX_CLK 42 +#define GCC_PCIE_0_PHY_AUX_CLK_SRC 43 +#define GCC_PCIE_0_PHY_RCHNG_CLK 44 +#define GCC_PCIE_0_PHY_RCHNG_CLK_SRC 45 +#define GCC_PCIE_0_PIPE_CLK 46 +#define GCC_PCIE_0_PIPE_CLK_SRC 47 +#define GCC_PCIE_0_SLV_AXI_CLK 48 +#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 49 +#define GCC_PCIE_RSCC_CFG_AHB_CLK 50 +#define GCC_PCIE_RSCC_XO_CLK 51 +#define GCC_PDM2_CLK 52 +#define GCC_PDM2_CLK_SRC 53 +#define GCC_PDM_AHB_CLK 54 +#define GCC_PDM_XO4_CLK 55 +#define GCC_QUPV3_I2C_CORE_CLK 56 +#define GCC_QUPV3_I2C_S0_CLK 57 +#define GCC_QUPV3_I2C_S0_CLK_SRC 58 +#define GCC_QUPV3_I2C_S1_CLK 59 +#define GCC_QUPV3_I2C_S1_CLK_SRC 60 +#define GCC_QUPV3_I2C_S2_CLK 61 +#define GCC_QUPV3_I2C_S2_CLK_SRC 62 +#define GCC_QUPV3_I2C_S3_CLK 63 +#define GCC_QUPV3_I2C_S3_CLK_SRC 64 +#define GCC_QUPV3_I2C_S4_CLK 65 +#define GCC_QUPV3_I2C_S4_CLK_SRC 66 +#define GCC_QUPV3_I2C_S_AHB_CLK 67 +#define GCC_QUPV3_WRAP1_CORE_2X_CLK 68 +#define GCC_QUPV3_WRAP1_CORE_CLK 69 +#define GCC_QUPV3_WRAP1_QSPI_REF_CLK 70 +#define GCC_QUPV3_WRAP1_QSPI_REF_CLK_SRC 71 +#define GCC_QUPV3_WRAP1_S0_CLK 72 +#define GCC_QUPV3_WRAP1_S0_CLK_SRC 73 +#define GCC_QUPV3_WRAP1_S1_CLK 74 +#define GCC_QUPV3_WRAP1_S1_CLK_SRC 75 +#define GCC_QUPV3_WRAP1_S2_CLK 76 +#define GCC_QUPV3_WRAP1_S2_CLK_SRC 77 +#define GCC_QUPV3_WRAP1_S3_CLK 78 +#define GCC_QUPV3_WRAP1_S3_CLK_SRC 79 +#define GCC_QUPV3_WRAP1_S4_CLK 80 +#define GCC_QUPV3_WRAP1_S4_CLK_SRC 81 +#define GCC_QUPV3_WRAP1_S5_CLK 82 +#define GCC_QUPV3_WRAP1_S5_CLK_SRC 83 +#define GCC_QUPV3_WRAP1_S6_CLK 84 +#define GCC_QUPV3_WRAP1_S6_CLK_SRC 85 +#define GCC_QUPV3_WRAP1_S7_CLK 86 +#define GCC_QUPV3_WRAP1_S7_CLK_SRC 87 +#define GCC_QUPV3_WRAP2_CORE_2X_CLK 88 +#define GCC_QUPV3_WRAP2_CORE_CLK 89 +#define GCC_QUPV3_WRAP2_S0_CLK 90 +#define GCC_QUPV3_WRAP2_S0_CLK_SRC 91 +#define GCC_QUPV3_WRAP2_S1_CLK 92 +#define GCC_QUPV3_WRAP2_S1_CLK_SRC 93 +#define GCC_QUPV3_WRAP2_S2_CLK 94 +#define GCC_QUPV3_WRAP2_S2_CLK_SRC 95 +#define GCC_QUPV3_WRAP2_S3_CLK 96 +#define GCC_QUPV3_WRAP2_S3_CLK_SRC 97 +#define GCC_QUPV3_WRAP2_S4_CLK 98 +#define GCC_QUPV3_WRAP2_S4_CLK_SRC 99 +#define GCC_QUPV3_WRAP3_CORE_2X_CLK 100 +#define GCC_QUPV3_WRAP3_CORE_CLK 101 +#define GCC_QUPV3_WRAP3_IBI_CTRL_0_CLK_SRC 102 +#define GCC_QUPV3_WRAP3_IBI_CTRL_1_CLK 103 +#define GCC_QUPV3_WRAP3_IBI_CTRL_2_CLK 104 +#define GCC_QUPV3_WRAP3_S0_CLK 105 +#define GCC_QUPV3_WRAP3_S0_CLK_SRC 106 +#define GCC_QUPV3_WRAP3_S1_CLK 107 +#define GCC_QUPV3_WRAP3_S1_CLK_SRC 108 +#define GCC_QUPV3_WRAP3_S2_CLK 109 +#define GCC_QUPV3_WRAP3_S2_CLK_SRC 110 +#define GCC_QUPV3_WRAP3_S3_CLK 111 +#define GCC_QUPV3_WRAP3_S3_CLK_SRC 112 +#define GCC_QUPV3_WRAP3_S4_CLK 113 +#define GCC_QUPV3_WRAP3_S4_CLK_SRC 114 +#define GCC_QUPV3_WRAP3_S5_CLK 115 +#define GCC_QUPV3_WRAP3_S5_CLK_SRC 116 +#define GCC_QUPV3_WRAP4_CORE_2X_CLK 117 +#define GCC_QUPV3_WRAP4_CORE_CLK 118 +#define GCC_QUPV3_WRAP4_S0_CLK 119 +#define GCC_QUPV3_WRAP4_S0_CLK_SRC 120 +#define GCC_QUPV3_WRAP4_S1_CLK 121 +#define GCC_QUPV3_WRAP4_S1_CLK_SRC 122 +#define GCC_QUPV3_WRAP4_S2_CLK 123 +#define GCC_QUPV3_WRAP4_S2_CLK_SRC 124 +#define GCC_QUPV3_WRAP4_S3_CLK 125 +#define GCC_QUPV3_WRAP4_S3_CLK_SRC 126 +#define GCC_QUPV3_WRAP4_S4_CLK 127 +#define GCC_QUPV3_WRAP4_S4_CLK_SRC 128 +#define GCC_QUPV3_WRAP_1_M_AXI_CLK 129 +#define GCC_QUPV3_WRAP_1_S_AHB_CLK 130 +#define GCC_QUPV3_WRAP_2_M_AHB_CLK 131 +#define GCC_QUPV3_WRAP_2_S_AHB_CLK 132 +#define GCC_QUPV3_WRAP_3_IBI_1_AHB_CLK 133 +#define GCC_QUPV3_WRAP_3_IBI_2_AHB_CLK 134 +#define GCC_QUPV3_WRAP_3_M_AHB_CLK 135 +#define GCC_QUPV3_WRAP_3_S_AHB_CLK 136 +#define GCC_QUPV3_WRAP_4_M_AHB_CLK 137 +#define GCC_QUPV3_WRAP_4_S_AHB_CLK 138 +#define GCC_SDCC2_AHB_CLK 139 +#define GCC_SDCC2_APPS_CLK 140 +#define GCC_SDCC2_APPS_CLK_SRC 141 +#define GCC_SDCC4_AHB_CLK 142 +#define GCC_SDCC4_APPS_CLK 143 +#define GCC_SDCC4_APPS_CLK_SRC 144 +#define GCC_UFS_PHY_AHB_CLK 145 +#define GCC_UFS_PHY_AXI_CLK 146 +#define GCC_UFS_PHY_AXI_CLK_SRC 147 +#define GCC_UFS_PHY_ICE_CORE_CLK 148 +#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 149 +#define GCC_UFS_PHY_PHY_AUX_CLK 150 +#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 151 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 152 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC 153 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK 154 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC 155 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 156 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC 157 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK 158 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 159 +#define GCC_USB30_PRIM_MASTER_CLK 160 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 161 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 162 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 163 +#define GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC 164 +#define GCC_USB30_PRIM_SLEEP_CLK 165 +#define GCC_USB3_PRIM_PHY_AUX_CLK 166 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 167 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 168 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 169 +#define GCC_USB3_PRIM_PHY_PIPE_CLK_SRC 170 +#define GCC_VIDEO_AHB_CLK 171 +#define GCC_VIDEO_AXI0_CLK 172 +#define GCC_VIDEO_AXI1_CLK 173 +#define GCC_VIDEO_XO_CLK 174 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 175 +#define GCC_QMIP_CAMERA_RT_AHB_CLK 176 +#define GCC_QMIP_DISP_DCP_SF_AHB_CLK 177 +#define GCC_QMIP_PCIE_AHB_CLK 178 +#define GCC_QMIP_VIDEO_CV_CPU_AHB_CLK 179 +#define GCC_QMIP_VIDEO_CVP_AHB_CLK 180 +#define GCC_QMIP_VIDEO_V_CPU_AHB_CLK 181 +#define GCC_DISP_AHB_CLK 182 + +/* GCC power domains */ +#define GCC_PCIE_0_GDSC 0 +#define GCC_PCIE_0_PHY_GDSC 1 +#define GCC_UFS_MEM_PHY_GDSC 2 +#define GCC_UFS_PHY_GDSC 3 +#define GCC_USB30_PRIM_GDSC 4 +#define GCC_USB3_PHY_GDSC 5 + +/* GCC resets */ +#define GCC_CAMERA_BCR 0 +#define GCC_DISPLAY_BCR 1 +#define GCC_EVA_AXI0_CLK_ARES 2 +#define GCC_EVA_AXI0C_CLK_ARES 3 +#define GCC_EVA_BCR 4 +#define GCC_GPU_BCR 5 +#define GCC_PCIE_0_BCR 6 +#define GCC_PCIE_0_LINK_DOWN_BCR 7 +#define GCC_PCIE_0_NOCSR_COM_PHY_BCR 8 +#define GCC_PCIE_0_PHY_BCR 9 +#define GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR 10 +#define GCC_PCIE_PHY_BCR 11 +#define GCC_PCIE_PHY_CFG_AHB_BCR 12 +#define GCC_PCIE_PHY_COM_BCR 13 +#define GCC_PCIE_RSCC_BCR 14 +#define GCC_PDM_BCR 15 +#define GCC_QUPV3_WRAPPER_1_BCR 16 +#define GCC_QUPV3_WRAPPER_2_BCR 17 +#define GCC_QUPV3_WRAPPER_3_BCR 18 +#define GCC_QUPV3_WRAPPER_4_BCR 19 +#define GCC_QUPV3_WRAPPER_I2C_BCR 20 +#define GCC_QUSB2PHY_PRIM_BCR 21 +#define GCC_QUSB2PHY_SEC_BCR 22 +#define GCC_SDCC2_BCR 23 +#define GCC_SDCC4_BCR 24 +#define GCC_UFS_PHY_BCR 25 +#define GCC_USB30_PRIM_BCR 26 +#define GCC_USB3_DP_PHY_PRIM_BCR 27 +#define GCC_USB3_DP_PHY_SEC_BCR 28 +#define GCC_USB3_PHY_PRIM_BCR 29 +#define GCC_USB3_PHY_SEC_BCR 30 +#define GCC_USB3PHY_PHY_PRIM_BCR 31 +#define GCC_USB3PHY_PHY_SEC_BCR 32 +#define GCC_VIDEO_AXI0_CLK_ARES 33 +#define GCC_VIDEO_AXI1_CLK_ARES 34 +#define GCC_VIDEO_BCR 35 +#define GCC_VIDEO_XO_CLK_ARES 36 + +#endif From 2a42e3210d4331dddfb04b020050bd774cf99659 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 4 Nov 2025 00:40:31 +0100 Subject: [PATCH 066/117] clk: rockchip: rk3568: Drop CLK_NR_CLKS usage In order to get rid of CLK_NR_CLKS and be able to drop it from the bindings, use rockchip_clk_find_max_clk_id helper to find the highest clock id. Reviewed-by: Sebastian Reichel Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20251103234032.413563-2-heiko@sntech.de --- drivers/clk/rockchip/clk-rk3568.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c index 97d279399ae8..74eabf9b2ae2 100644 --- a/drivers/clk/rockchip/clk-rk3568.c +++ b/drivers/clk/rockchip/clk-rk3568.c @@ -1652,6 +1652,7 @@ CLK_OF_DECLARE(rk3568_cru_pmu, "rockchip,rk3568-pmucru", rk3568_pmu_clk_init); static void __init rk3568_clk_init(struct device_node *np) { struct rockchip_clk_provider *ctx; + unsigned long clk_nr_clks; void __iomem *reg_base; reg_base = of_iomap(np, 0); @@ -1660,7 +1661,9 @@ static void __init rk3568_clk_init(struct device_node *np) return; } - ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + clk_nr_clks = rockchip_clk_find_max_clk_id(rk3568_clk_branches, + ARRAY_SIZE(rk3568_clk_branches)) + 1; + ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); iounmap(reg_base); From ca38f0f65eefd79889b409c89c6932d7e2fe0993 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 4 Nov 2025 00:40:32 +0100 Subject: [PATCH 067/117] dt-bindings: clock: rk3568: Drop CLK_NR_CLKS define CLK_NR_CLKS has always only be used on the driver side to calculate array sizes should never have been part of the clock-binding. Let's drop it, since the kernel code no longer uses it either and nothing else has ever used it. Acked-by: Conor Dooley Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20251103234032.413563-3-heiko@sntech.de --- include/dt-bindings/clock/rk3568-cru.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/dt-bindings/clock/rk3568-cru.h b/include/dt-bindings/clock/rk3568-cru.h index 18bb8d41d741..1e0aef8a645d 100644 --- a/include/dt-bindings/clock/rk3568-cru.h +++ b/include/dt-bindings/clock/rk3568-cru.h @@ -483,8 +483,6 @@ #define PCLK_CORE_PVTM 450 -#define CLK_NR_CLKS (PCLK_CORE_PVTM + 1) - /* scmi-clocks indices */ #define SCMI_CLK_CPU 0 From bab55c25f2ebed2608e053183146893b63d6f078 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 24 Sep 2025 22:27:15 +0200 Subject: [PATCH 068/117] clk: lan966x: remove unused dt-bindings include In preparation for LAN969x support, all instances referring to defines in the LAN966x specific header were dropped, so its safe to drop its inclusion in the driver. Signed-off-by: Robert Marko Reviewed-by: Daniel Machon Link: https://lore.kernel.org/r/20250924202810.1641883-1-robert.marko@sartura.hr Signed-off-by: Claudiu Beznea --- drivers/clk/clk-lan966x.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/clk-lan966x.c b/drivers/clk/clk-lan966x.c index 16e0405fe28b..3c7a48c616bb 100644 --- a/drivers/clk/clk-lan966x.c +++ b/drivers/clk/clk-lan966x.c @@ -16,8 +16,6 @@ #include #include -#include - #define GCK_ENA BIT(0) #define GCK_SRC_SEL GENMASK(9, 8) #define GCK_PRESCALER GENMASK(23, 16) From 566ed24a0a79e23b37cc883a49d515916a245cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Thu, 6 Nov 2025 22:16:02 +0100 Subject: [PATCH 069/117] clk: renesas: rcar-gen4: Add support for clock dividers in FRQCRB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FRQCRB register on R-Car V3U, V4H and V4M do in addition to the already supported KICK bit contain settings for the frequency division ratios for the clocks ZTR, ZT, ZS and ZG. It is however not possible to use the latter when registering a Z clock with the DEF_GEN4_Z() macro. This change adds support for that by extending the existing practice of treating the bit field offsets at multiples of 32 to map to a different register. With this new mapping in palace bit offsets 0 - 31 map to FRQCRC0 bit offsets 32 - 63 map to FRQCRC1 bit offsets 64 - 95 map to FRQCRB The change also adds an error condition to return an error if an unknown offset is used. The KICK bit defined in FRQCRB and already supported covers all three registers and no addition to how it is handled are needed. Signed-off-by: Niklas Söderlund Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251106211604.2766465-3-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rcar-gen4-cpg.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c index fb9a876aaba5..215ef8e1a115 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.c +++ b/drivers/clk/renesas/rcar-gen4-cpg.c @@ -257,7 +257,7 @@ static struct clk * __init cpg_pll_clk_register(const char *name, } /* - * Z0 Clock & Z1 Clock + * Z0, Z1 and ZG Clock */ #define CPG_FRQCRB 0x00000804 #define CPG_FRQCRB_KICK BIT(31) @@ -389,9 +389,14 @@ static struct clk * __init cpg_z_clk_register(const char *name, if (offset < 32) { zclk->reg = reg + CPG_FRQCRC0; - } else { + } else if (offset < 64) { zclk->reg = reg + CPG_FRQCRC1; offset -= 32; + } else if (offset < 96) { + zclk->reg = reg + CPG_FRQCRB; + offset -= 64; + } else { + return ERR_PTR(-EINVAL); } zclk->kick_reg = reg + CPG_FRQCRB; zclk->hw.init = &init; From f8ea1a2760296831a45a57748ae0587751b6688f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Thu, 6 Nov 2025 22:16:03 +0100 Subject: [PATCH 070/117] clk: renesas: r8a779a0: Add ZG Core clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe the ZG Core clock needed to operate the PowerVR GPU. Signed-off-by: Niklas Söderlund Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251106211604.2766465-4-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a779a0-cpg-mssr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index 1be7b9592aa6..449611432059 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -26,7 +26,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R8A779A0_CLK_OSC, + LAST_DT_CORE_CLK = R8A779A0_CLK_ZG, /* External Input Clocks */ CLK_EXTAL, @@ -39,6 +39,7 @@ enum clk_ids { CLK_PLL21, CLK_PLL30, CLK_PLL31, + CLK_PLL4, CLK_PLL5, CLK_PLL1_DIV2, CLK_PLL20_DIV2, @@ -65,6 +66,7 @@ enum clk_ids { #define CPG_PLL21CR 0x0838 /* PLL21 Control Register */ #define CPG_PLL30CR 0x083c /* PLL30 Control Register */ #define CPG_PLL31CR 0x0840 /* PLL31 Control Register */ +#define CPG_PLL4CR 0x0844 /* PLL4 Control Register */ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { /* External Clock Inputs */ @@ -79,6 +81,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_PLL(".pll21", CLK_PLL21, CPG_PLL21CR), DEF_PLL(".pll30", CLK_PLL30, CPG_PLL30CR), DEF_PLL(".pll31", CLK_PLL31, CPG_PLL31CR), + DEF_PLL(".pll4", CLK_PLL4, CPG_PLL4CR), DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), DEF_FIXED(".pll20_div2", CLK_PLL20_DIV2, CLK_PLL20, 2, 1), @@ -98,6 +101,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { /* Core Clock Outputs */ DEF_GEN4_Z("z0", R8A779A0_CLK_Z0, CLK_TYPE_GEN4_Z, CLK_PLL20, 2, 0), DEF_GEN4_Z("z1", R8A779A0_CLK_Z1, CLK_TYPE_GEN4_Z, CLK_PLL21, 2, 8), + DEF_GEN4_Z("zg", R8A779A0_CLK_ZG, CLK_TYPE_GEN4_Z, CLK_PLL4, 2, 88), DEF_FIXED("zx", R8A779A0_CLK_ZX, CLK_PLL20_DIV2, 2, 1), DEF_FIXED("s1d1", R8A779A0_CLK_S1D1, CLK_S1, 1, 1), DEF_FIXED("s1d2", R8A779A0_CLK_S1D2, CLK_S1, 2, 1), From 79d022dcad375c6ba95e78e9035c8a0630164300 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 6 Nov 2025 18:06:08 +0100 Subject: [PATCH 071/117] clk: sprd: sc9860: Simplify with of_device_get_match_data() Driver's probe function matches against driver's of_device_id table, where each entry has non-NULL match data, so of_match_node() can be simplified with of_device_get_match_data(). Signed-off-by: Krzysztof Kozlowski [sboyd@kernel.org: Use device_get_match_data() instead, drop printk noise] Signed-off-by: Stephen Boyd --- drivers/clk/sprd/sc9860-clk.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clk/sprd/sc9860-clk.c b/drivers/clk/sprd/sc9860-clk.c index cc5ed2dd8267..d7fe924fbe97 100644 --- a/drivers/clk/sprd/sc9860-clk.c +++ b/drivers/clk/sprd/sc9860-clk.c @@ -2021,17 +2021,13 @@ MODULE_DEVICE_TABLE(of, sprd_sc9860_clk_ids); static int sc9860_clk_probe(struct platform_device *pdev) { - const struct of_device_id *match; const struct sprd_clk_desc *desc; int ret; - match = of_match_node(sprd_sc9860_clk_ids, pdev->dev.of_node); - if (!match) { - pr_err("%s: of_match_node() failed", __func__); + desc = device_get_match_data(&pdev->dev); + if (!desc) return -ENODEV; - } - desc = match->data; ret = sprd_clk_regmap_init(pdev, desc); if (ret) return ret; From 25b47635f8729e9536d2652774bd509532eaa522 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Fri, 1 Aug 2025 15:21:53 +0800 Subject: [PATCH 072/117] clk: imx: Add some delay before deassert the reset Some of the PCCs on i.MX8ULP have a sw_rst bit to control the peripheral reset through SW method. For peripherals like GPU that need sync reset, some delay is necessary befere & after release the reset to make sure the HW is reset into a known status. So add some delay before & after release reset. Signed-off-by: Jacky Bai Reviewed-by: Peng Fan Link: https://lore.kernel.org/r/20250801072153.1974428-1-ping.bai@nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-composite-7ulp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/clk/imx/clk-composite-7ulp.c b/drivers/clk/imx/clk-composite-7ulp.c index 8ed2e0ad2769..37d2fc197be6 100644 --- a/drivers/clk/imx/clk-composite-7ulp.c +++ b/drivers/clk/imx/clk-composite-7ulp.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,9 @@ static int pcc_gate_enable(struct clk_hw *hw) if (ret) return ret; + /* Make sure the IP's clock is ready before release reset */ + udelay(1); + spin_lock_irqsave(gate->lock, flags); /* * release the sw reset for peripherals associated with @@ -47,6 +51,15 @@ static int pcc_gate_enable(struct clk_hw *hw) spin_unlock_irqrestore(gate->lock, flags); + /* + * Read back the register to make sure the previous write has been + * done in the target HW register. For IP like GPU, after deassert + * the reset, need to wait for a while to make sure the sync reset + * is done + */ + readl(gate->reg); + udelay(1); + return 0; } From 9d97a2fe48ae77976baff441edd5b30ea4e179c0 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 24 Oct 2025 09:45:51 +0800 Subject: [PATCH 073/117] clk: imx: imx8mp-audiomix: use devm_auxiliary_device_create() to simple code Use helper function devm_auxiliary_device_create() to remove some boilerplate code. Reviewed-by: Abel Vesa Reviewed-by: Frank Li Signed-off-by: Peng Fan Reviewed-by: Shengjiu Wang Link: https://lore.kernel.org/r/20251024-auxiliary-v2-1-a353dc9e6b1a@nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mp-audiomix.c | 39 +++------------------------ 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mp-audiomix.c b/drivers/clk/imx/clk-imx8mp-audiomix.c index 775f62dddb11..131702f2c9ec 100644 --- a/drivers/clk/imx/clk-imx8mp-audiomix.c +++ b/drivers/clk/imx/clk-imx8mp-audiomix.c @@ -230,50 +230,19 @@ struct clk_imx8mp_audiomix_priv { #if IS_ENABLED(CONFIG_RESET_CONTROLLER) -static void clk_imx8mp_audiomix_reset_unregister_adev(void *_adev) -{ - struct auxiliary_device *adev = _adev; - - auxiliary_device_delete(adev); - auxiliary_device_uninit(adev); -} - -static void clk_imx8mp_audiomix_reset_adev_release(struct device *dev) -{ - struct auxiliary_device *adev = to_auxiliary_dev(dev); - - kfree(adev); -} - static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev, struct clk_imx8mp_audiomix_priv *priv) { - struct auxiliary_device *adev __free(kfree) = NULL; - int ret; + struct auxiliary_device *adev; if (!of_property_present(dev->of_node, "#reset-cells")) return 0; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = devm_auxiliary_device_create(dev, "reset", NULL); if (!adev) - return -ENOMEM; + return -ENODEV; - adev->name = "reset"; - adev->dev.parent = dev; - adev->dev.release = clk_imx8mp_audiomix_reset_adev_release; - - ret = auxiliary_device_init(adev); - if (ret) - return ret; - - ret = auxiliary_device_add(adev); - if (ret) { - auxiliary_device_uninit(adev); - return ret; - } - - return devm_add_action_or_reset(dev, clk_imx8mp_audiomix_reset_unregister_adev, - no_free_ptr(adev)); + return 0; } #else /* !CONFIG_RESET_CONTROLLER */ From 3b521bf8c51246466e2c337f1f2b60acfdfe82d6 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 4 Nov 2025 04:02:55 -0800 Subject: [PATCH 074/117] dt-bindings: clock: document 8ULP's SIM LPAV Add documentation for i.MX8ULP's SIM LPAV module. Reviewed-by: Krzysztof Kozlowski Reviewed-by: Daniel Baluta Signed-off-by: Laurentiu Mihalcea Link: https://lore.kernel.org/r/20251104120301.913-3-laurentiumihalcea111@gmail.com Signed-off-by: Abel Vesa --- .../bindings/clock/fsl,imx8ulp-sim-lpav.yaml | 72 +++++++++++++++++++ include/dt-bindings/clock/imx8ulp-clock.h | 5 ++ .../dt-bindings/reset/fsl,imx8ulp-sim-lpav.h | 16 +++++ 3 files changed, 93 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/fsl,imx8ulp-sim-lpav.yaml create mode 100644 include/dt-bindings/reset/fsl,imx8ulp-sim-lpav.h diff --git a/Documentation/devicetree/bindings/clock/fsl,imx8ulp-sim-lpav.yaml b/Documentation/devicetree/bindings/clock/fsl,imx8ulp-sim-lpav.yaml new file mode 100644 index 000000000000..662e07528d76 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/fsl,imx8ulp-sim-lpav.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/fsl,imx8ulp-sim-lpav.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP i.MX8ULP LPAV System Integration Module (SIM) + +maintainers: + - Laurentiu Mihalcea + +description: + The i.MX8ULP LPAV subsystem contains a block control module known as + SIM LPAV, which offers functionalities such as clock gating or reset + line assertion/de-assertion. + +properties: + compatible: + const: fsl,imx8ulp-sim-lpav + + reg: + maxItems: 1 + + clocks: + maxItems: 3 + + clock-names: + items: + - const: bus + - const: core + - const: plat + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + mux-controller: + $ref: /schemas/mux/reg-mux.yaml# + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - mux-controller + +additionalProperties: false + +examples: + - | + #include + + clock-controller@2da50000 { + compatible = "fsl,imx8ulp-sim-lpav"; + reg = <0x2da50000 0x10000>; + clocks = <&cgc2 IMX8ULP_CLK_LPAV_BUS_DIV>, + <&cgc2 IMX8ULP_CLK_HIFI_DIVCORE>, + <&cgc2 IMX8ULP_CLK_HIFI_DIVPLAT>; + clock-names = "bus", "core", "plat"; + #clock-cells = <1>; + #reset-cells = <1>; + + mux-controller { + compatible = "reg-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x8 0x00000200>; + }; + }; diff --git a/include/dt-bindings/clock/imx8ulp-clock.h b/include/dt-bindings/clock/imx8ulp-clock.h index 827404fadf5c..c62d84d093a9 100644 --- a/include/dt-bindings/clock/imx8ulp-clock.h +++ b/include/dt-bindings/clock/imx8ulp-clock.h @@ -255,4 +255,9 @@ #define IMX8ULP_CLK_PCC5_END 56 +/* LPAV SIM */ +#define IMX8ULP_CLK_SIM_LPAV_HIFI_CORE 0 +#define IMX8ULP_CLK_SIM_LPAV_HIFI_PBCLK 1 +#define IMX8ULP_CLK_SIM_LPAV_HIFI_PLAT 2 + #endif diff --git a/include/dt-bindings/reset/fsl,imx8ulp-sim-lpav.h b/include/dt-bindings/reset/fsl,imx8ulp-sim-lpav.h new file mode 100644 index 000000000000..adf95bb26d21 --- /dev/null +++ b/include/dt-bindings/reset/fsl,imx8ulp-sim-lpav.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright 2025 NXP + */ + +#ifndef DT_BINDING_RESET_IMX8ULP_SIM_LPAV_H +#define DT_BINDING_RESET_IMX8ULP_SIM_LPAV_H + +#define IMX8ULP_SIM_LPAV_HIFI4_DSP_DBG_RST 0 +#define IMX8ULP_SIM_LPAV_HIFI4_DSP_RST 1 +#define IMX8ULP_SIM_LPAV_HIFI4_DSP_STALL 2 +#define IMX8ULP_SIM_LPAV_DSI_RST_BYTE_N 3 +#define IMX8ULP_SIM_LPAV_DSI_RST_ESC_N 4 +#define IMX8ULP_SIM_LPAV_DSI_RST_DPI_N 5 + +#endif /* DT_BINDING_RESET_IMX8ULP_SIM_LPAV_H */ From fdc1dc7dd53b95805d3943ed36785c1ec812915e Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 4 Nov 2025 04:02:56 -0800 Subject: [PATCH 075/117] clk: imx: add driver for imx8ulp's sim lpav The i.MX8ULP System Integration Module (SIM) LPAV module is a block control module found inside the LPAV subsystem, which offers some clock gating options and reset line assertion/de-assertion capabilities. Therefore, the clock gate management is supported by registering the module's driver as a clock provider, while the reset capabilities are managed via the auxiliary device API to allow the DT node to act as a reset and clock provider. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Daniel Baluta Reviewed-by: Peng Fan Link: https://lore.kernel.org/r/20251104120301.913-4-laurentiumihalcea111@gmail.com Signed-off-by: Abel Vesa --- drivers/clk/imx/Kconfig | 1 + drivers/clk/imx/Makefile | 1 + drivers/clk/imx/clk-imx8ulp-sim-lpav.c | 156 +++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 drivers/clk/imx/clk-imx8ulp-sim-lpav.c diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index 6ff6d934848a..b292e7ca5c24 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -105,6 +105,7 @@ config CLK_IMX8ULP tristate "IMX8ULP CCM Clock Driver" depends on ARCH_MXC || COMPILE_TEST select MXC_CLK + select AUXILIARY_BUS help Build the driver for i.MX8ULP CCM Clock Driver diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 03f2b2a1ab63..208b46873a18 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -41,6 +41,7 @@ clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o clk-imx-acm-$(CONFIG_CLK_IMX8QXP) = clk-imx8-acm.o obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o +obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp-sim-lpav.o obj-$(CONFIG_CLK_IMX1) += clk-imx1.o obj-$(CONFIG_CLK_IMX25) += clk-imx25.o diff --git a/drivers/clk/imx/clk-imx8ulp-sim-lpav.c b/drivers/clk/imx/clk-imx8ulp-sim-lpav.c new file mode 100644 index 000000000000..990c95b89b75 --- /dev/null +++ b/drivers/clk/imx/clk-imx8ulp-sim-lpav.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2025 NXP + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYSCTRL0 0x8 + +#define IMX8ULP_HIFI_CLK_GATE(gname, cname, pname, bidx) \ + { \ + .name = gname "_cg", \ + .id = IMX8ULP_CLK_SIM_LPAV_HIFI_##cname, \ + .parent = { .fw_name = pname }, \ + .bit = bidx, \ + } + +struct clk_imx8ulp_sim_lpav_data { + spinlock_t lock; /* shared by MUX, clock gate and reset */ + unsigned long flags; /* for spinlock usage */ + struct clk_hw_onecell_data clk_data; /* keep last */ +}; + +struct clk_imx8ulp_sim_lpav_gate { + const char *name; + int id; + const struct clk_parent_data parent; + u8 bit; +}; + +static struct clk_imx8ulp_sim_lpav_gate gates[] = { + IMX8ULP_HIFI_CLK_GATE("hifi_core", CORE, "core", 17), + IMX8ULP_HIFI_CLK_GATE("hifi_pbclk", PBCLK, "bus", 18), + IMX8ULP_HIFI_CLK_GATE("hifi_plat", PLAT, "plat", 19) +}; + +static void clk_imx8ulp_sim_lpav_lock(void *arg) __acquires(&data->lock) +{ + struct clk_imx8ulp_sim_lpav_data *data = dev_get_drvdata(arg); + + spin_lock_irqsave(&data->lock, data->flags); +} + +static void clk_imx8ulp_sim_lpav_unlock(void *arg) __releases(&data->lock) +{ + struct clk_imx8ulp_sim_lpav_data *data = dev_get_drvdata(arg); + + spin_unlock_irqrestore(&data->lock, data->flags); +} + +static int clk_imx8ulp_sim_lpav_probe(struct platform_device *pdev) +{ + const struct regmap_config regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .lock = clk_imx8ulp_sim_lpav_lock, + .unlock = clk_imx8ulp_sim_lpav_unlock, + .lock_arg = &pdev->dev, + }; + struct clk_imx8ulp_sim_lpav_data *data; + struct auxiliary_device *adev; + struct regmap *regmap; + void __iomem *base; + struct clk_hw *hw; + int i, ret; + + data = devm_kzalloc(&pdev->dev, + struct_size(data, clk_data.hws, ARRAY_SIZE(gates)), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, data); + + /* + * this lock is used directly by the clock gate and indirectly + * by the reset and mux controller via the regmap API + */ + spin_lock_init(&data->lock); + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return dev_err_probe(&pdev->dev, PTR_ERR(base), + "failed to ioremap base\n"); + /* + * although the clock gate doesn't use the regmap API to modify the + * registers, we still need the regmap because of the reset auxiliary + * driver and the MUX drivers, which use the parent device's regmap + */ + regmap = devm_regmap_init_mmio(&pdev->dev, base, ®map_config); + if (IS_ERR(regmap)) + return dev_err_probe(&pdev->dev, PTR_ERR(regmap), + "failed to initialize regmap\n"); + + data->clk_data.num = ARRAY_SIZE(gates); + + for (i = 0; i < ARRAY_SIZE(gates); i++) { + hw = devm_clk_hw_register_gate_parent_data(&pdev->dev, + gates[i].name, + &gates[i].parent, + CLK_SET_RATE_PARENT, + base + SYSCTRL0, + gates[i].bit, + 0x0, &data->lock); + if (IS_ERR(hw)) + return dev_err_probe(&pdev->dev, PTR_ERR(hw), + "failed to register %s gate\n", + gates[i].name); + + data->clk_data.hws[i] = hw; + } + + adev = devm_auxiliary_device_create(&pdev->dev, "reset", NULL); + if (!adev) + return dev_err_probe(&pdev->dev, -ENODEV, + "failed to register aux reset\n"); + + ret = devm_of_clk_add_hw_provider(&pdev->dev, + of_clk_hw_onecell_get, + &data->clk_data); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to register clk hw provider\n"); + + /* used to probe MUX child device */ + return devm_of_platform_populate(&pdev->dev); +} + +static const struct of_device_id clk_imx8ulp_sim_lpav_of_match[] = { + { .compatible = "fsl,imx8ulp-sim-lpav" }, + { } +}; +MODULE_DEVICE_TABLE(of, clk_imx8ulp_sim_lpav_of_match); + +static struct platform_driver clk_imx8ulp_sim_lpav_driver = { + .probe = clk_imx8ulp_sim_lpav_probe, + .driver = { + .name = "clk-imx8ulp-sim-lpav", + .of_match_table = clk_imx8ulp_sim_lpav_of_match, + }, +}; +module_platform_driver(clk_imx8ulp_sim_lpav_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("i.MX8ULP LPAV System Integration Module (SIM) clock driver"); +MODULE_AUTHOR("Laurentiu Mihalcea "); From 781f60e45bdfe351aad692ac0fa89e36f8bf4a36 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Mon, 10 Nov 2025 11:23:50 +0000 Subject: [PATCH 076/117] reset: mpfs: add non-auxiliary bus probing While the auxiliary bus was a nice bandaid, and meant that re-writing the representation of the clock regions in devicetree was not required, it has run its course. The "mss_top_sysreg" region that contains the clock and reset regions, also contains pinctrl and an interrupt controller, so the time has come rewrite the devicetree and probe the reset controller from an mfd devicetree node, rather than implement those drivers using the auxiliary bus. Wanting to avoid propagating this naive/incorrect description of the hardware to the new pic64gx SoC is a major motivating factor here. Reviewed-by: Philipp Zabel Acked-by: Philipp Zabel Signed-off-by: Conor Dooley --- drivers/clk/microchip/clk-mpfs.c | 4 +- drivers/reset/Kconfig | 1 + drivers/reset/reset-mpfs.c | 91 +++++++++++++++++++------------- include/soc/microchip/mpfs.h | 3 +- 4 files changed, 60 insertions(+), 39 deletions(-) diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c index 484893e68b67..ee58304913ef 100644 --- a/drivers/clk/microchip/clk-mpfs.c +++ b/drivers/clk/microchip/clk-mpfs.c @@ -38,7 +38,7 @@ static const struct regmap_config mpfs_clk_regmap_config = { .reg_stride = 4, .val_bits = 32, .val_format_endian = REGMAP_ENDIAN_LITTLE, - .max_register = REG_SUBBLK_CLOCK_CR, + .max_register = REG_SUBBLK_RESET_CR, }; /* @@ -502,7 +502,7 @@ static inline int mpfs_clk_old_format_probe(struct mpfs_clock_data *clk_data, if (IS_ERR(clk_data->regmap)) return PTR_ERR(clk_data->regmap); - return mpfs_reset_controller_register(dev, clk_data->base + REG_SUBBLK_RESET_CR); + return mpfs_reset_controller_register(dev, clk_data->regmap); } static int mpfs_clk_probe(struct platform_device *pdev) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 78b7078478d4..0ec4b7cd08d6 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -200,6 +200,7 @@ config RESET_PISTACHIO config RESET_POLARFIRE_SOC bool "Microchip PolarFire SoC (MPFS) Reset Driver" depends on MCHP_CLK_MPFS + depends on MFD_SYSCON select AUXILIARY_BUS default MCHP_CLK_MPFS help diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c index f6fa10e03ea8..8ffcc54ee6f6 100644 --- a/drivers/reset/reset-mpfs.c +++ b/drivers/reset/reset-mpfs.c @@ -9,11 +9,13 @@ #include #include #include +#include #include #include #include -#include +#include #include +#include #include #include @@ -27,11 +29,10 @@ #define MPFS_SLEEP_MIN_US 100 #define MPFS_SLEEP_MAX_US 200 -/* block concurrent access to the soft reset register */ -static DEFINE_SPINLOCK(mpfs_reset_lock); +#define REG_SUBBLK_RESET_CR 0x88u struct mpfs_reset { - void __iomem *base; + struct regmap *regmap; struct reset_controller_dev rcdev; }; @@ -46,41 +47,25 @@ static inline struct mpfs_reset *to_mpfs_reset(struct reset_controller_dev *rcde static int mpfs_assert(struct reset_controller_dev *rcdev, unsigned long id) { struct mpfs_reset *rst = to_mpfs_reset(rcdev); - unsigned long flags; - u32 reg; - spin_lock_irqsave(&mpfs_reset_lock, flags); + return regmap_set_bits(rst->regmap, REG_SUBBLK_RESET_CR, BIT(id)); - reg = readl(rst->base); - reg |= BIT(id); - writel(reg, rst->base); - - spin_unlock_irqrestore(&mpfs_reset_lock, flags); - - return 0; } static int mpfs_deassert(struct reset_controller_dev *rcdev, unsigned long id) { struct mpfs_reset *rst = to_mpfs_reset(rcdev); - unsigned long flags; - u32 reg; - spin_lock_irqsave(&mpfs_reset_lock, flags); + return regmap_clear_bits(rst->regmap, REG_SUBBLK_RESET_CR, BIT(id)); - reg = readl(rst->base); - reg &= ~BIT(id); - writel(reg, rst->base); - - spin_unlock_irqrestore(&mpfs_reset_lock, flags); - - return 0; } static int mpfs_status(struct reset_controller_dev *rcdev, unsigned long id) { struct mpfs_reset *rst = to_mpfs_reset(rcdev); - u32 reg = readl(rst->base); + u32 reg; + + regmap_read(rst->regmap, REG_SUBBLK_RESET_CR, ®); /* * It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit @@ -130,23 +115,58 @@ static int mpfs_reset_xlate(struct reset_controller_dev *rcdev, return index - MPFS_PERIPH_OFFSET; } -static int mpfs_reset_probe(struct auxiliary_device *adev, - const struct auxiliary_device_id *id) +static int mpfs_reset_mfd_probe(struct platform_device *pdev) { - struct device *dev = &adev->dev; struct reset_controller_dev *rcdev; + struct device *dev = &pdev->dev; struct mpfs_reset *rst; rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL); if (!rst) return -ENOMEM; - rst->base = (void __iomem *)adev->dev.platform_data; + rcdev = &rst->rcdev; + rcdev->dev = dev; + rcdev->ops = &mpfs_reset_ops; + + rcdev->of_node = pdev->dev.parent->of_node; + rcdev->of_reset_n_cells = 1; + rcdev->of_xlate = mpfs_reset_xlate; + rcdev->nr_resets = MPFS_NUM_RESETS; + + rst->regmap = device_node_to_regmap(pdev->dev.parent->of_node); + if (IS_ERR(rst->regmap)) + return dev_err_probe(dev, PTR_ERR(rst->regmap), + "Failed to find syscon regmap\n"); + + return devm_reset_controller_register(dev, rcdev); +} + +static struct platform_driver mpfs_reset_mfd_driver = { + .probe = mpfs_reset_mfd_probe, + .driver = { + .name = "mpfs-reset", + }, +}; +module_platform_driver(mpfs_reset_mfd_driver); + +static int mpfs_reset_adev_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct reset_controller_dev *rcdev; + struct device *dev = &adev->dev; + struct mpfs_reset *rst; + + rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL); + if (!rst) + return -ENOMEM; + + rst->regmap = (struct regmap *)adev->dev.platform_data; rcdev = &rst->rcdev; rcdev->dev = dev; - rcdev->dev->parent = dev->parent; rcdev->ops = &mpfs_reset_ops; + rcdev->of_node = dev->parent->of_node; rcdev->of_reset_n_cells = 1; rcdev->of_xlate = mpfs_reset_xlate; @@ -155,12 +175,11 @@ static int mpfs_reset_probe(struct auxiliary_device *adev, return devm_reset_controller_register(dev, rcdev); } -int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base) +int mpfs_reset_controller_register(struct device *clk_dev, struct regmap *map) { struct auxiliary_device *adev; - adev = devm_auxiliary_device_create(clk_dev, "reset-mpfs", - (__force void *)base); + adev = devm_auxiliary_device_create(clk_dev, "reset-mpfs", (void *)map); if (!adev) return -ENODEV; @@ -176,12 +195,12 @@ static const struct auxiliary_device_id mpfs_reset_ids[] = { }; MODULE_DEVICE_TABLE(auxiliary, mpfs_reset_ids); -static struct auxiliary_driver mpfs_reset_driver = { - .probe = mpfs_reset_probe, +static struct auxiliary_driver mpfs_reset_aux_driver = { + .probe = mpfs_reset_adev_probe, .id_table = mpfs_reset_ids, }; -module_auxiliary_driver(mpfs_reset_driver); +module_auxiliary_driver(mpfs_reset_aux_driver); MODULE_DESCRIPTION("Microchip PolarFire SoC Reset Driver"); MODULE_AUTHOR("Conor Dooley "); diff --git a/include/soc/microchip/mpfs.h b/include/soc/microchip/mpfs.h index 0bd67e10b704..ec04c98a8b63 100644 --- a/include/soc/microchip/mpfs.h +++ b/include/soc/microchip/mpfs.h @@ -14,6 +14,7 @@ #include #include +#include struct mpfs_sys_controller; @@ -44,7 +45,7 @@ struct mtd_info *mpfs_sys_controller_get_flash(struct mpfs_sys_controller *mpfs_ #if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) #if IS_ENABLED(CONFIG_RESET_POLARFIRE_SOC) -int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base); +int mpfs_reset_controller_register(struct device *clk_dev, struct regmap *map); #else static inline int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base) { return 0; } #endif /* if IS_ENABLED(CONFIG_RESET_POLARFIRE_SOC) */ From a40efd0741f228023a87bf65b1cebe683e92172b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Thu, 6 Nov 2025 22:16:04 +0100 Subject: [PATCH 077/117] clk: renesas: r8a779a0: Add 3DGE module clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe the 3DGE module clock needed to operate the PowerVR GPU. Signed-off-by: Niklas Söderlund Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251106211604.2766465-5-niklas.soderlund+renesas@ragnatech.se 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 449611432059..d67dff05d9f4 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -142,6 +142,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { }; static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { + DEF_MOD("3dge", 0, R8A779A0_CLK_ZG), DEF_MOD("isp0", 16, R8A779A0_CLK_S1D1), DEF_MOD("isp1", 17, R8A779A0_CLK_S1D1), DEF_MOD("isp2", 18, R8A779A0_CLK_S1D1), From 145dfd70b9c70e5bc03494a7ce8fa3748ac01af3 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 28 Oct 2025 16:51:23 +0000 Subject: [PATCH 078/117] clk: renesas: r9a09g077: Propagate rate changes to parent clocks Add the CLK_SET_RATE_PARENT flag to divider clock registration so that rate changes can propagate to parent clocks when needed. This allows the CPG divider clocks to request rate adjustments from their parent, ensuring correct frequency scaling and improved flexibility in clock rate selection. Fixes: 065fe720eec6e ("clk: renesas: Add support for R9A09G077 SoC") Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251028165127.991351-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index 8b7e84a4c307..1cb33c12234e 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -221,7 +221,7 @@ r9a09g077_cpg_div_clk_register(struct device *dev, if (core->dtable) clk_hw = clk_hw_register_divider_table(dev, core->name, - parent_name, 0, + parent_name, CLK_SET_RATE_PARENT, addr, GET_SHIFT(core->conf), GET_WIDTH(core->conf), @@ -230,7 +230,7 @@ r9a09g077_cpg_div_clk_register(struct device *dev, &pub->rmw_lock); else clk_hw = clk_hw_register_divider(dev, core->name, - parent_name, 0, + parent_name, CLK_SET_RATE_PARENT, addr, GET_SHIFT(core->conf), GET_WIDTH(core->conf), From 3b32a07584a8fc940129cfd384e180bdd758b8ed Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 28 Oct 2025 16:51:24 +0000 Subject: [PATCH 079/117] clk: renesas: r9a09g077: Remove stray blank line Remove an unnecessary blank line at the end of r9a09g077_cpg_div_clk_register() to tidy up the code. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251028165127.991351-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index 1cb33c12234e..666fc16b9a81 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -240,7 +240,6 @@ r9a09g077_cpg_div_clk_register(struct device *dev, return ERR_CAST(clk_hw); return clk_hw->clk; - } static struct clk * __init From 7a9d0318da5d1d148021d9c9762cefecb552c54f Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 28 Oct 2025 16:51:25 +0000 Subject: [PATCH 080/117] clk: renesas: r9a09g077: Use devm_ helpers for divider clock registration Convert the divider clock registration in the R9A09G077 CPG driver to use device-managed (devm_) helper functions. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251028165127.991351-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 30 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index 666fc16b9a81..b46167d42084 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -220,21 +220,23 @@ r9a09g077_cpg_div_clk_register(struct device *dev, parent_name = __clk_get_name(parent); if (core->dtable) - clk_hw = clk_hw_register_divider_table(dev, core->name, - parent_name, CLK_SET_RATE_PARENT, - addr, - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->flag, - core->dtable, - &pub->rmw_lock); + clk_hw = devm_clk_hw_register_divider_table(dev, core->name, + parent_name, + CLK_SET_RATE_PARENT, + addr, + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, + core->dtable, + &pub->rmw_lock); else - clk_hw = clk_hw_register_divider(dev, core->name, - parent_name, CLK_SET_RATE_PARENT, - addr, - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->flag, &pub->rmw_lock); + clk_hw = devm_clk_hw_register_divider(dev, core->name, + parent_name, + CLK_SET_RATE_PARENT, + addr, + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, &pub->rmw_lock); if (IS_ERR(clk_hw)) return ERR_CAST(clk_hw); From f8def051bbcf8677f64701e9699bf6d11e2780cd Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Thu, 30 Oct 2025 14:16:03 +0800 Subject: [PATCH 081/117] clk: renesas: r9a06g032: Fix memory leak in error path The current code uses of_iomap() to map registers but never calls iounmap() on any error path after the mapping. This causes a memory leak when probe fails after successful ioremap, for example when of_clk_add_provider() or r9a06g032_add_clk_domain() fails. Replace of_iomap() with devm_of_iomap() to automatically unmap the region on probe failure. Update the error check accordingly to use IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") Signed-off-by: Haotian Zhang Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index dcda19318b2a..0f5c91b5dfa9 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -1333,9 +1333,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) if (IS_ERR(mclk)) return PTR_ERR(mclk); - clocks->reg = of_iomap(np, 0); - if (WARN_ON(!clocks->reg)) - return -ENOMEM; + clocks->reg = devm_of_iomap(dev, np, 0, NULL); + if (IS_ERR(clocks->reg)) + return PTR_ERR(clocks->reg); r9a06g032_init_h2mode(clocks); From dc937f12e6c3488713de1262e37a30307ee9feac Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 13 Nov 2025 17:15:25 +0100 Subject: [PATCH 082/117] clk: qcom: apss-ipq5424: remove unused 'apss_clk' structure The locally defined 'apss_clk' structure is not used in the code, so remove that. Compile tested only. Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/r/20251113-ipq5424-remove-apss_clk-v1-1-e942e720cf99@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/apss-ipq5424.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/clk/qcom/apss-ipq5424.c b/drivers/clk/qcom/apss-ipq5424.c index 4c67f722e009..2d622c1fe5d0 100644 --- a/drivers/clk/qcom/apss-ipq5424.c +++ b/drivers/clk/qcom/apss-ipq5424.c @@ -35,13 +35,6 @@ enum { P_L3_PLL, }; -struct apss_clk { - struct notifier_block cpu_clk_notifier; - struct clk_hw *hw; - struct device *dev; - struct clk *l3_clk; -}; - static const struct alpha_pll_config apss_pll_config = { .l = 0x3b, .config_ctl_val = 0x08200920, From 4145fc363eb23a1caf14f7ebf6830ab32bcaa50e Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 13 Nov 2025 17:42:52 +0100 Subject: [PATCH 083/117] clk: qcom: use different Kconfig prompts for APSS IPQ5424/6018 drivers Both the IPQ_APSS_5424 and IPQ_APSS_6018 symbols are using the same prompt which complicates to see that which option corresponds to which driver. Add a prefix to both prompts to make it easier to differentiate the two options. While at it, also fix a typo in the help text of the IPQ_APSS_5424 symbol. Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/r/20251113-clk-qcom-apss-ipq-prompt-v1-1-b62cf2142609@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 4a78099e706c..550a9d82a6b3 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -215,16 +215,16 @@ config IPQ_APSS_PLL devices. config IPQ_APSS_5424 - tristate "IPQ APSS Clock Controller" + tristate "IPQ5424 APSS Clock Controller" select IPQ_APSS_PLL default y if IPQ_GCC_5424 help - Support for APSS Clock controller on Qualcom IPQ5424 platform. + Support for APSS Clock controller on Qualcomm IPQ5424 platform. Say Y if you want to support CPU frequency scaling on ipq based devices. config IPQ_APSS_6018 - tristate "IPQ APSS Clock Controller" + tristate "IPQ6018 APSS Clock Controller" select IPQ_APSS_PLL depends on QCOM_APCS_IPC || COMPILE_TEST depends on QCOM_SMEM From 280b7cdddc3d96c4887fdb31b6766e4db1b2f2a3 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sat, 1 Nov 2025 05:00:31 +0000 Subject: [PATCH 084/117] dt-bindings: clock: renesas,r9a09g057-cpg: Add USB3.0 core clocks Add definitions for USB3.0 core clocks in the R9A09G057 CPG DT bindings header file. Signed-off-by: Lad Prabhakar Acked-by: Krzysztof Kozlowski Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251101050034.738807-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/renesas,r9a09g057-cpg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/dt-bindings/clock/renesas,r9a09g057-cpg.h b/include/dt-bindings/clock/renesas,r9a09g057-cpg.h index 5346a898ab60..f91d7f72922a 100644 --- a/include/dt-bindings/clock/renesas,r9a09g057-cpg.h +++ b/include/dt-bindings/clock/renesas,r9a09g057-cpg.h @@ -22,5 +22,9 @@ #define R9A09G057_GBETH_0_CLK_PTP_REF_I 11 #define R9A09G057_GBETH_1_CLK_PTP_REF_I 12 #define R9A09G057_SPI_CLK_SPI 13 +#define R9A09G057_USB3_0_REF_ALT_CLK_P 14 +#define R9A09G057_USB3_0_CLKCORE 15 +#define R9A09G057_USB3_1_REF_ALT_CLK_P 16 +#define R9A09G057_USB3_1_CLKCORE 17 #endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G057_CPG_H__ */ From a95ce05cd0cc8b53f1559390c4e690bb8f79562f Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sat, 1 Nov 2025 05:00:32 +0000 Subject: [PATCH 085/117] dt-bindings: clock: renesas,r9a09g056-cpg: Add USB3.0 core clocks Add definitions for USB3.0 core clocks in the R9A09G056 CPG DT bindings header file. Signed-off-by: Lad Prabhakar Acked-by: Krzysztof Kozlowski Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251101050034.738807-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/renesas,r9a09g056-cpg.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/clock/renesas,r9a09g056-cpg.h b/include/dt-bindings/clock/renesas,r9a09g056-cpg.h index a9af5af9e3a1..234dcf4f0f91 100644 --- a/include/dt-bindings/clock/renesas,r9a09g056-cpg.h +++ b/include/dt-bindings/clock/renesas,r9a09g056-cpg.h @@ -21,5 +21,7 @@ #define R9A09G056_GBETH_0_CLK_PTP_REF_I 10 #define R9A09G056_GBETH_1_CLK_PTP_REF_I 11 #define R9A09G056_SPI_CLK_SPI 12 +#define R9A09G056_USB3_0_REF_ALT_CLK_P 13 +#define R9A09G056_USB3_0_CLKCORE 14 #endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G056_CPG_H__ */ From c6b63d54c6f8d81e72c8b9b8e8d1cb5ada03c5dd Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 27 Oct 2025 15:45:48 +0000 Subject: [PATCH 086/117] clk: renesas: r9a09g047: Add RSCI clocks/resets Add RSCI clock and reset entries. Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251027154615.115759-2-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g047-cpg.c | 126 ++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/drivers/clk/renesas/r9a09g047-cpg.c b/drivers/clk/renesas/r9a09g047-cpg.c index 68f8b08bd16f..1e9896742a06 100644 --- a/drivers/clk/renesas/r9a09g047-cpg.c +++ b/drivers/clk/renesas/r9a09g047-cpg.c @@ -44,6 +44,9 @@ enum clk_ids { CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, CLK_PLLCLN_DIV20, + CLK_PLLCLN_DIV64, + CLK_PLLCLN_DIV256, + CLK_PLLCLN_DIV1024, CLK_PLLDTY_ACPU, CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, @@ -142,6 +145,9 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20), + DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64), + DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256), + DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024), DEF_DDIV(".plldty_acpu", CLK_PLLDTY_ACPU, CLK_PLLDTY, CDDIV0_DIVCTL2, dtable_2_64), DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), @@ -218,6 +224,106 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rsci0_pclk", CLK_PLLCLN_DIV16, 5, 13, 2, 29, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_tclk", CLK_PLLCLN_DIV16, 5, 14, 2, 30, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps3_n", CLK_PLLCLN_DIV1024, 5, 15, 2, 31, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 0, 3, 0, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 1, 3, 1, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci1_pclk", CLK_PLLCLN_DIV16, 6, 2, 3, 2, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_tclk", CLK_PLLCLN_DIV16, 6, 3, 3, 3, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 4, 3, 4, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 5, 3, 5, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 6, 3, 6, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci2_pclk", CLK_PLLCLN_DIV16, 6, 7, 3, 7, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_tclk", CLK_PLLCLN_DIV16, 6, 8, 3, 8, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 9, 3, 9, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 10, 3, 10, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 11, 3, 11, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci3_pclk", CLK_PLLCLN_DIV16, 6, 12, 3, 12, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_tclk", CLK_PLLCLN_DIV16, 6, 13, 3, 13, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 14, 3, 14, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 15, 3, 15, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 0, 3, 16, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci4_pclk", CLK_PLLCLN_DIV16, 7, 1, 3, 17, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_tclk", CLK_PLLCLN_DIV16, 7, 2, 3, 18, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 3, 3, 19, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 4, 3, 20, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 5, 3, 21, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci5_pclk", CLK_PLLCLN_DIV16, 7, 6, 3, 22, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_tclk", CLK_PLLCLN_DIV16, 7, 7, 3, 23, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 8, 3, 24, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 9, 3, 25, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 10, 3, 26, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci6_pclk", CLK_PLLCLN_DIV16, 7, 11, 3, 27, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_tclk", CLK_PLLCLN_DIV16, 7, 12, 3, 28, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 13, 3, 29, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 14, 3, 30, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 15, 3, 31, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci7_pclk", CLK_PLLCLN_DIV16, 8, 0, 4, 0, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_tclk", CLK_PLLCLN_DIV16, 8, 1, 4, 1, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 2, 4, 2, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 3, 4, 3, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 4, 4, 4, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci8_pclk", CLK_PLLCLN_DIV16, 8, 5, 4, 5, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_tclk", CLK_PLLCLN_DIV16, 8, 6, 4, 6, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 7, 4, 7, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 8, 4, 8, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 9, 4, 9, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci9_pclk", CLK_PLLCLN_DIV16, 8, 10, 4, 10, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_tclk", CLK_PLLCLN_DIV16, 8, 11, 4, 11, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 12, 4, 12, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 13, 4, 13, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 14, 4, 14, + BUS_MSTOP(11, BIT(12))), DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15, BUS_MSTOP(3, BIT(14))), DEF_MOD("i3c_0_pclkrw", CLK_PLLCLN_DIV16, 9, 0, 4, 16, @@ -351,6 +457,26 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(8, 1, 3, 18), /* RSCI0_PRESETN */ + DEF_RST(8, 2, 3, 19), /* RSCI0_TRESETN */ + DEF_RST(8, 3, 3, 20), /* RSCI1_PRESETN */ + DEF_RST(8, 4, 3, 21), /* RSCI1_TRESETN */ + DEF_RST(8, 5, 3, 22), /* RSCI2_PRESETN */ + DEF_RST(8, 6, 3, 23), /* RSCI2_TRESETN */ + DEF_RST(8, 7, 3, 24), /* RSCI3_PRESETN */ + DEF_RST(8, 8, 3, 25), /* RSCI3_TRESETN */ + DEF_RST(8, 9, 3, 26), /* RSCI4_PRESETN */ + DEF_RST(8, 10, 3, 27), /* RSCI4_TRESETN */ + DEF_RST(8, 11, 3, 28), /* RSCI5_PRESETN */ + DEF_RST(8, 12, 3, 29), /* RSCI5_TRESETN */ + DEF_RST(8, 13, 3, 30), /* RSCI6_PRESETN */ + DEF_RST(8, 14, 3, 31), /* RSCI6_TRESETN */ + DEF_RST(8, 15, 4, 0), /* RSCI7_PRESETN */ + DEF_RST(9, 0, 4, 1), /* RSCI7_TRESETN */ + DEF_RST(9, 1, 4, 2), /* RSCI8_PRESETN */ + DEF_RST(9, 2, 4, 3), /* RSCI8_TRESETN */ + DEF_RST(9, 3, 4, 4), /* RSCI9_PRESETN */ + DEF_RST(9, 4, 4, 5), /* RSCI9_TRESETN */ DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */ DEF_RST(9, 6, 4, 7), /* I3C_0_PRESETN */ DEF_RST(9, 7, 4, 8), /* I3C_0_TRESETN */ From 4ecc8ccde5b488eb7284c1e674f274850eb039a6 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sat, 1 Nov 2025 05:00:33 +0000 Subject: [PATCH 087/117] clk: renesas: r9a09g057: Add USB3.0 clocks/resets Add USB3.0 clock and reset entries. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251101050034.738807-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g057-cpg.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index c9f6d91884c3..400d9e94f2e9 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -17,7 +17,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G057_SPI_CLK_SPI, + LAST_DT_CORE_CLK = R9A09G057_USB3_1_CLKCORE, /* External Input Clocks */ CLK_AUDIO_EXTAL, @@ -235,6 +235,10 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { CLK_PLLETH_DIV_125_FIX, 1, 1), DEF_FIXED_MOD_STATUS("spi_clk_spi", R9A09G057_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2, FIXED_MOD_CONF_XSPI), + DEF_FIXED("usb3_0_ref_alt_clk_p", R9A09G057_USB3_0_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_0_core_clk", R9A09G057_USB3_0_CLKCORE, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_1_ref_alt_clk_p", R9A09G057_USB3_1_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_1_core_clk", R9A09G057_USB3_1_CLKCORE, CLK_QEXTAL, 1, 1), }; static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { @@ -360,6 +364,14 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(8, BIT(4))), DEF_MOD("sdhi_2_aclk", CLK_PLLDTY_ACPU_DIV4, 10, 14, 5, 14, BUS_MSTOP(8, BIT(4))), + DEF_MOD("usb3_0_aclk", CLK_PLLDTY_DIV8, 10, 15, 5, 15, + BUS_MSTOP(7, BIT(12))), + DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16, + BUS_MSTOP(7, BIT(14))), + DEF_MOD("usb3_1_aclk", CLK_PLLDTY_DIV8, 11, 1, 5, 17, + BUS_MSTOP(7, BIT(13))), + DEF_MOD("usb3_1_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 2, 5, 18, + BUS_MSTOP(7, BIT(15))), DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19, BUS_MSTOP(7, BIT(7))), DEF_MOD("usb2_0_u2h1_hclk", CLK_PLLDTY_DIV8, 11, 4, 5, 20, @@ -501,6 +513,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */ DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */ + DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */ + DEF_RST(10, 11, 4, 28), /* USB3_1_ARESETN */ DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */ DEF_RST(10, 13, 4, 30), /* USB2_0_U2H1_HRESETN */ DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */ From 7efa3a6d96348bfbe02e330219b05ec922958fab Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sat, 1 Nov 2025 05:00:34 +0000 Subject: [PATCH 088/117] clk: renesas: r9a09g056: Add USB3.0 clocks/resets Add USB3.0 clock and reset entries. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251101050034.738807-5-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index e4a6dfd2bec9..f48a082e65d7 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -17,7 +17,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G056_SPI_CLK_SPI, + LAST_DT_CORE_CLK = R9A09G056_USB3_0_CLKCORE, /* External Input Clocks */ CLK_AUDIO_EXTAL, @@ -226,6 +226,8 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { CLK_PLLETH_DIV_125_FIX, 1, 1), DEF_FIXED_MOD_STATUS("spi_clk_spi", R9A09G056_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2, FIXED_MOD_CONF_XSPI), + DEF_FIXED("usb3_0_ref_alt_clk_p", R9A09G056_USB3_0_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_0_core_clk", R9A09G056_USB3_0_CLKCORE, CLK_QEXTAL, 1, 1), }; static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { @@ -319,6 +321,10 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(8, BIT(4))), DEF_MOD("sdhi_2_aclk", CLK_PLLDTY_ACPU_DIV4, 10, 14, 5, 14, BUS_MSTOP(8, BIT(4))), + DEF_MOD("usb3_0_aclk", CLK_PLLDTY_DIV8, 10, 15, 5, 15, + BUS_MSTOP(7, BIT(12))), + DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16, + BUS_MSTOP(7, BIT(14))), DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19, BUS_MSTOP(7, BIT(7))), DEF_MOD("usb2_0_u2p_exr_cpuclk", CLK_PLLDTY_ACPU_DIV4, 11, 5, 5, 21, @@ -426,6 +432,7 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */ DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */ + DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */ DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */ DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */ DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */ From 5fb2f67341bd4b7c482f2bbda6b78244a51c3923 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Wed, 5 Nov 2025 12:41:38 +0200 Subject: [PATCH 089/117] clk: renesas: r9a09g077: Add SPI module clocks The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have four SPI peripherals, each with their own clock divider, which divides PLL4 by either 24, 25, 30 or 32, similar to the SCI peripheral. The dividers feed into the usual module clocks. Add them all. Signed-off-by: Cosmin Tanislav Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251105104151.1489281-2-cosmin-gabriel.tanislav.xa@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index b46167d42084..fb6cc94d08a1 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -46,8 +46,12 @@ #define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1) #define DIVCA55C3 CONF_PACK(SCKCR2, 11, 1) #define DIVCA55S CONF_PACK(SCKCR2, 12, 1) +#define DIVSPI3ASYNC CONF_PACK(SCKCR2, 16, 2) #define DIVSCI5ASYNC CONF_PACK(SCKCR2, 18, 2) +#define DIVSPI0ASYNC CONF_PACK(SCKCR3, 0, 2) +#define DIVSPI1ASYNC CONF_PACK(SCKCR3, 2, 2) +#define DIVSPI2ASYNC CONF_PACK(SCKCR3, 4, 2) #define DIVSCI0ASYNC CONF_PACK(SCKCR3, 6, 2) #define DIVSCI1ASYNC CONF_PACK(SCKCR3, 8, 2) #define DIVSCI2ASYNC CONF_PACK(SCKCR3, 10, 2) @@ -56,7 +60,6 @@ #define SEL_PLL CONF_PACK(SCKCR, 22, 1) - enum rzt2h_clk_types { CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */ CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */ @@ -94,6 +97,10 @@ enum clk_ids { CLK_SCI3ASYNC, CLK_SCI4ASYNC, CLK_SCI5ASYNC, + CLK_SPI0ASYNC, + CLK_SPI1ASYNC, + CLK_SPI2ASYNC, + CLK_SPI3ASYNC, /* Module Clocks */ MOD_CLK_BASE, @@ -154,6 +161,15 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_DIV(".sci5async", CLK_SCI5ASYNC, CLK_PLL4D1, DIVSCI5ASYNC, dtable_24_25_30_32), + DEF_DIV(".spi0async", CLK_SPI0ASYNC, CLK_PLL4D1, DIVSPI0ASYNC, + dtable_24_25_30_32), + DEF_DIV(".spi1async", CLK_SPI1ASYNC, CLK_PLL4D1, DIVSPI1ASYNC, + dtable_24_25_30_32), + DEF_DIV(".spi2async", CLK_SPI2ASYNC, CLK_PLL4D1, DIVSPI2ASYNC, + dtable_24_25_30_32), + DEF_DIV(".spi3async", CLK_SPI3ASYNC, CLK_PLL4D1, DIVSPI3ASYNC, + dtable_24_25_30_32), + /* Core output clk */ DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0, dtable_1_2), @@ -188,6 +204,9 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("sci4fck", 12, CLK_SCI4ASYNC), DEF_MOD("iic0", 100, R9A09G077_CLK_PCLKL), DEF_MOD("iic1", 101, R9A09G077_CLK_PCLKL), + DEF_MOD("spi0", 104, CLK_SPI0ASYNC), + DEF_MOD("spi1", 105, CLK_SPI1ASYNC), + DEF_MOD("spi2", 106, CLK_SPI2ASYNC), DEF_MOD("adc0", 206, R9A09G077_CLK_PCLKH), DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH), DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM), @@ -200,6 +219,7 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("gmac2", 417, R9A09G077_CLK_PCLKAM), DEF_MOD("sci5fck", 600, CLK_SCI5ASYNC), DEF_MOD("iic2", 601, R9A09G077_CLK_PCLKL), + DEF_MOD("spi3", 602, CLK_SPI3ASYNC), DEF_MOD("sdhi0", 1212, R9A09G077_CLK_PCLKAM), DEF_MOD("sdhi1", 1213, R9A09G077_CLK_PCLKAM), }; From fa3542e822c99196a27f030e87eab5458072613a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Barna=C5=9B?= Date: Tue, 28 Oct 2025 16:16:42 +0000 Subject: [PATCH 090/117] clk: keystone: Fix discarded const qualifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add const qualifiers to the pointers returned from 'container_of' macro to prevent breaking the const promise on const struct pointers from parameters. Once you have a mutable container structure pointer, you can change structure fields through it, which violates the const guarantee. Signed-off-by: Adrian BarnaÅ› Reviewed-by: Nishanth Menon Signed-off-by: Stephen Boyd --- drivers/clk/keystone/sci-clk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index a4b42811de55..9d5071223f4c 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -496,8 +496,8 @@ static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider) static int _cmp_sci_clk_list(void *priv, const struct list_head *a, const struct list_head *b) { - struct sci_clk *ca = container_of(a, struct sci_clk, node); - struct sci_clk *cb = container_of(b, struct sci_clk, node); + const struct sci_clk *ca = container_of(a, struct sci_clk, node); + const struct sci_clk *cb = container_of(b, struct sci_clk, node); return _cmp_sci_clk(ca, &cb); } From 2e12d91cbf3d0105fc58d07b8a0548ebd7bb619b Mon Sep 17 00:00:00 2001 From: Encrow Thorne Date: Tue, 11 Nov 2025 23:50:09 +0800 Subject: [PATCH 091/117] clk: spacemit: fix comment typo Fix incorrect comment to match the filename. Reviewd-by: Troy Mitchell Signed-off-by: Encrow Thorne Reviewed-by: Yixun Lan Signed-off-by: Stephen Boyd --- drivers/clk/spacemit/ccu_mix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/spacemit/ccu_mix.h b/drivers/clk/spacemit/ccu_mix.h index 54d40cd39b27..c406508e3504 100644 --- a/drivers/clk/spacemit/ccu_mix.h +++ b/drivers/clk/spacemit/ccu_mix.h @@ -220,4 +220,4 @@ extern const struct clk_ops spacemit_ccu_div_gate_ops; extern const struct clk_ops spacemit_ccu_mux_gate_ops; extern const struct clk_ops spacemit_ccu_mux_div_ops; extern const struct clk_ops spacemit_ccu_mux_div_gate_ops; -#endif /* _CCU_DIV_H_ */ +#endif /* _CCU_MIX_H_ */ From 947643509279a605a09959a06d332bf027e8be57 Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Mon, 10 Nov 2025 06:56:43 +0300 Subject: [PATCH 092/117] dt-bindings: clock: airoha: Add reset support to EN7523 clock binding Introduce reset capability to EN7523 device-tree clock binding documentation. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Rob Herring (Arm) Signed-off-by: Stephen Boyd --- .../bindings/clock/airoha,en7523-scu.yaml | 3 +- .../dt-bindings/reset/airoha,en7523-reset.h | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 include/dt-bindings/reset/airoha,en7523-reset.h diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml index fe2c5c1baf43..a8471367175b 100644 --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml @@ -64,8 +64,6 @@ allOf: reg: minItems: 2 - '#reset-cells': false - - if: properties: compatible: @@ -85,6 +83,7 @@ examples: reg = <0x1fa20000 0x400>, <0x1fb00000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; - | diff --git a/include/dt-bindings/reset/airoha,en7523-reset.h b/include/dt-bindings/reset/airoha,en7523-reset.h new file mode 100644 index 000000000000..211e8a23a21c --- /dev/null +++ b/include/dt-bindings/reset/airoha,en7523-reset.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 iopsys Software Solutions AB. + * Copyright (C) 2025 Genexis AB. + * + * Author: Mikhail Kshevetskiy + * + * based on + * include/dt-bindings/reset/airoha,en7581-reset.h + * by Lorenzo Bianconi + */ + +#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_ +#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_ + +/* RST_CTRL2 */ +#define EN7523_XPON_PHY_RST 0 +#define EN7523_XSI_MAC_RST 1 +#define EN7523_XSI_PHY_RST 2 +#define EN7523_NPU_RST 3 +#define EN7523_I2S_RST 4 +#define EN7523_TRNG_RST 5 +#define EN7523_TRNG_MSTART_RST 6 +#define EN7523_DUAL_HSI0_RST 7 +#define EN7523_DUAL_HSI1_RST 8 +#define EN7523_HSI_RST 9 +#define EN7523_DUAL_HSI0_MAC_RST 10 +#define EN7523_DUAL_HSI1_MAC_RST 11 +#define EN7523_HSI_MAC_RST 12 +#define EN7523_WDMA_RST 13 +#define EN7523_WOE0_RST 14 +#define EN7523_WOE1_RST 15 +#define EN7523_HSDMA_RST 16 +#define EN7523_I2C2RBUS_RST 17 +#define EN7523_TDMA_RST 18 +/* RST_CTRL1 */ +#define EN7523_PCM1_ZSI_ISI_RST 19 +#define EN7523_FE_PDMA_RST 20 +#define EN7523_FE_QDMA_RST 21 +#define EN7523_PCM_SPIWP_RST 22 +#define EN7523_CRYPTO_RST 23 +#define EN7523_TIMER_RST 24 +#define EN7523_PCM1_RST 25 +#define EN7523_UART_RST 26 +#define EN7523_GPIO_RST 27 +#define EN7523_GDMA_RST 28 +#define EN7523_I2C_MASTER_RST 29 +#define EN7523_PCM2_ZSI_ISI_RST 30 +#define EN7523_SFC_RST 31 +#define EN7523_UART2_RST 32 +#define EN7523_GDMP_RST 33 +#define EN7523_FE_RST 34 +#define EN7523_USB_HOST_P0_RST 35 +#define EN7523_GSW_RST 36 +#define EN7523_SFC2_PCM_RST 37 +#define EN7523_PCIE0_RST 38 +#define EN7523_PCIE1_RST 39 +#define EN7523_PCIE_HB_RST 40 +#define EN7523_XPON_MAC_RST 41 + +#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_ */ From 1c0608d860db973ad09b5a9ccb19b76ae07622a3 Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Mon, 10 Nov 2025 06:56:44 +0300 Subject: [PATCH 093/117] clk: en7523: Add reset-controller support for EN7523 SoC Introduce reset API support to EN7523 clock driver. EN7523 uses the same reset logic as EN7581, so just reuse existing code. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Philipp Zabel Signed-off-by: Stephen Boyd --- drivers/clk/clk-en7523.c | 64 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 15bbdeb60b8e..08cc8e5acf43 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #define RST_NR_PER_BANK 32 @@ -299,6 +300,53 @@ static const u16 en7581_rst_ofs[] = { REG_RST_CTRL1, }; +static const u16 en7523_rst_map[] = { + /* RST_CTRL2 */ + [EN7523_XPON_PHY_RST] = 0, + [EN7523_XSI_MAC_RST] = 7, + [EN7523_XSI_PHY_RST] = 8, + [EN7523_NPU_RST] = 9, + [EN7523_I2S_RST] = 10, + [EN7523_TRNG_RST] = 11, + [EN7523_TRNG_MSTART_RST] = 12, + [EN7523_DUAL_HSI0_RST] = 13, + [EN7523_DUAL_HSI1_RST] = 14, + [EN7523_HSI_RST] = 15, + [EN7523_DUAL_HSI0_MAC_RST] = 16, + [EN7523_DUAL_HSI1_MAC_RST] = 17, + [EN7523_HSI_MAC_RST] = 18, + [EN7523_WDMA_RST] = 19, + [EN7523_WOE0_RST] = 20, + [EN7523_WOE1_RST] = 21, + [EN7523_HSDMA_RST] = 22, + [EN7523_I2C2RBUS_RST] = 23, + [EN7523_TDMA_RST] = 24, + /* RST_CTRL1 */ + [EN7523_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0, + [EN7523_FE_PDMA_RST] = RST_NR_PER_BANK + 1, + [EN7523_FE_QDMA_RST] = RST_NR_PER_BANK + 2, + [EN7523_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4, + [EN7523_CRYPTO_RST] = RST_NR_PER_BANK + 6, + [EN7523_TIMER_RST] = RST_NR_PER_BANK + 8, + [EN7523_PCM1_RST] = RST_NR_PER_BANK + 11, + [EN7523_UART_RST] = RST_NR_PER_BANK + 12, + [EN7523_GPIO_RST] = RST_NR_PER_BANK + 13, + [EN7523_GDMA_RST] = RST_NR_PER_BANK + 14, + [EN7523_I2C_MASTER_RST] = RST_NR_PER_BANK + 16, + [EN7523_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17, + [EN7523_SFC_RST] = RST_NR_PER_BANK + 18, + [EN7523_UART2_RST] = RST_NR_PER_BANK + 19, + [EN7523_GDMP_RST] = RST_NR_PER_BANK + 20, + [EN7523_FE_RST] = RST_NR_PER_BANK + 21, + [EN7523_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22, + [EN7523_GSW_RST] = RST_NR_PER_BANK + 23, + [EN7523_SFC2_PCM_RST] = RST_NR_PER_BANK + 25, + [EN7523_PCIE0_RST] = RST_NR_PER_BANK + 26, + [EN7523_PCIE1_RST] = RST_NR_PER_BANK + 27, + [EN7523_PCIE_HB_RST] = RST_NR_PER_BANK + 29, + [EN7523_XPON_MAC_RST] = RST_NR_PER_BANK + 31, +}; + static const u16 en7581_rst_map[] = { /* RST_CTRL2 */ [EN7581_XPON_PHY_RST] = 0, @@ -357,6 +405,9 @@ static const u16 en7581_rst_map[] = { [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, }; +static int en7581_reset_register(struct device *dev, void __iomem *base, + const u16 *rst_map, int nr_resets); + static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) { if (!desc->base_bits) @@ -552,7 +603,8 @@ static int en7523_clk_hw_init(struct platform_device *pdev, en7523_register_clocks(&pdev->dev, clk_data, base, np_base); - return 0; + return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map, + ARRAY_SIZE(en7523_rst_map)); } static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, @@ -652,7 +704,8 @@ static const struct reset_control_ops en7581_reset_ops = { .status = en7523_reset_status, }; -static int en7581_reset_register(struct device *dev, void __iomem *base) +static int en7581_reset_register(struct device *dev, void __iomem *base, + const u16 *rst_map, int nr_resets) { struct en_rst_data *rst_data; @@ -661,10 +714,10 @@ static int en7581_reset_register(struct device *dev, void __iomem *base) return -ENOMEM; rst_data->bank_ofs = en7581_rst_ofs; - rst_data->idx_map = en7581_rst_map; + rst_data->idx_map = rst_map; rst_data->base = base; - rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map); + rst_data->rcdev.nr_resets = nr_resets; rst_data->rcdev.of_xlate = en7523_reset_xlate; rst_data->rcdev.ops = &en7581_reset_ops; rst_data->rcdev.of_node = dev->of_node; @@ -698,7 +751,8 @@ static int en7581_clk_hw_init(struct platform_device *pdev, val = readl(base + REG_NP_SCU_PCIC); writel(val | 3, base + REG_NP_SCU_PCIC); - return en7581_reset_register(&pdev->dev, base); + return en7581_reset_register(&pdev->dev, base, en7581_rst_map, + ARRAY_SIZE(en7581_rst_map)); } static int en7523_clk_probe(struct platform_device *pdev) From c57210bc15371caa06a5d4040e7d8aaeed4cb661 Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Sun, 16 Nov 2025 04:12:33 +0300 Subject: [PATCH 094/117] dt-bindings: clock: mmcc-sdm660: Add missing MDSS reset Add definition for display subsystem reset control, so display driver can reset display controller properly, clearing any configuration left there by bootloader. Since 6.17 after PM domains rework it became necessary for display to function. Fixes: 0e789b491ba0 ("pmdomain: core: Leave powered-on genpds on until sync_state") Cc: stable@vger.kernel.org # 6.17 Signed-off-by: Alexey Minnekhanov Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251116-sdm660-mdss-reset-v2-1-6219bec0a97f@postmarketos.org Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,mmcc-sdm660.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/qcom,mmcc-sdm660.h b/include/dt-bindings/clock/qcom,mmcc-sdm660.h index f9dbc21cb5c7..ee2a89dae72d 100644 --- a/include/dt-bindings/clock/qcom,mmcc-sdm660.h +++ b/include/dt-bindings/clock/qcom,mmcc-sdm660.h @@ -157,6 +157,7 @@ #define BIMC_SMMU_GDSC 7 #define CAMSS_MICRO_BCR 0 +#define MDSS_BCR 1 #endif From 0a0ea5541d30c0fbb3dac975bd1983f299cd6948 Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Sun, 16 Nov 2025 04:12:34 +0300 Subject: [PATCH 095/117] clk: qcom: mmcc-sdm660: Add missing MDSS reset Add offset for display subsystem reset in multimedia clock controller block, which is necessary to reset display when there is some configuration in display controller left by previous stock (Android) bootloader to provide continuous splash functionaluty. Before 6.17 power domains were turned off for long enough to clear registers, now this is not the case and a proper reset is needed to have functioning display. Fixes: 0e789b491ba0 ("pmdomain: core: Leave powered-on genpds on until sync_state") Cc: stable@vger.kernel.org # 6.17 Signed-off-by: Alexey Minnekhanov Reviewed-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251116-sdm660-mdss-reset-v2-2-6219bec0a97f@postmarketos.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/mmcc-sdm660.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index b723c536dfb6..dbd3f561dc6d 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -2781,6 +2781,7 @@ static struct gdsc *mmcc_sdm660_gdscs[] = { }; static const struct qcom_reset_map mmcc_660_resets[] = { + [MDSS_BCR] = { 0x2300 }, [CAMSS_MICRO_BCR] = { 0x3490 }, }; From 165d0b6dd248b939fb0d31a00687e6ef672b3b3c Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 18 Nov 2025 12:47:05 +0530 Subject: [PATCH 096/117] clk: qcom: clk_mem_branch: add enable mask and invert flags Introduce mem_enable_mask and mem_enable_invert in clk_mem_branch to describe memory gating implementations that use a separate mask and/or inverted enable logic. This documents hardware behavior in data instead of code and will be used by upcoming platform descriptions. Signed-off-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251118-sm8750-videocc-v2-v4-1-049882a70c9f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-branch.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h index 292756435f53..6bc2ba2b5350 100644 --- a/drivers/clk/qcom/clk-branch.h +++ b/drivers/clk/qcom/clk-branch.h @@ -44,6 +44,8 @@ struct clk_branch { * @mem_enable_reg: branch clock memory gating register * @mem_ack_reg: branch clock memory ack register * @mem_enable_ack_mask: branch clock memory enable and ack field in @mem_ack_reg + * @mem_enable_mask: branch clock memory enable mask + * @mem_enable_invert: branch clock memory enable and disable has invert logic * @branch: branch clock gating handle * * Clock which can gate its memories. @@ -52,6 +54,8 @@ struct clk_mem_branch { u32 mem_enable_reg; u32 mem_ack_reg; u32 mem_enable_ack_mask; + u32 mem_enable_mask; + bool mem_enable_invert; struct clk_branch branch; }; From 53a18958349a627ae5d6b1ea708289b6cf3d8b9d Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 18 Nov 2025 12:47:06 +0530 Subject: [PATCH 097/117] clk: qcom: ecpricc-qdu100: Add mem_enable_mask to the clock memory branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ECPRI clock controller’s mem_ops clocks used the mem_enable_ack_mask directly for both setting and polling. Add the newly introduced 'mem_enable_mask' to the memory control branch clocks of ECPRI clock controller to align to the new mem_ops handling. Signed-off-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251118-sm8750-videocc-v2-v4-2-049882a70c9f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/ecpricc-qdu1000.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/clk/qcom/ecpricc-qdu1000.c b/drivers/clk/qcom/ecpricc-qdu1000.c index dbc11260479b..c2a16616ed64 100644 --- a/drivers/clk/qcom/ecpricc-qdu1000.c +++ b/drivers/clk/qcom/ecpricc-qdu1000.c @@ -920,6 +920,7 @@ static struct clk_branch ecpri_cc_eth_100g_c2c1_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_0_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x80b4, @@ -943,6 +944,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_1_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x80bc, @@ -966,6 +968,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_c2c_hm_macsec_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(4), .mem_enable_ack_mask = BIT(4), .branch = { .halt_reg = 0x80ac, @@ -989,6 +992,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_hm_macsec_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_0_clk = { .mem_enable_reg = 0x8414, .mem_ack_reg = 0x8428, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x80d8, @@ -1012,6 +1016,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_1_clk = { .mem_enable_reg = 0x8414, .mem_ack_reg = 0x8428, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x80e0, @@ -1053,6 +1058,7 @@ static struct clk_branch ecpri_cc_eth_100g_dbg_c2c_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_0_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x800c, @@ -1076,6 +1082,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_1_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x8014, @@ -1099,6 +1106,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_2_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(2), .mem_enable_ack_mask = BIT(2), .branch = { .halt_reg = 0x801c, @@ -1122,6 +1130,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_2_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_3_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(3), .mem_enable_ack_mask = BIT(3), .branch = { .halt_reg = 0x8024, @@ -1163,6 +1172,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_0_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_0_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x8044, @@ -1186,6 +1196,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_1_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x804c, @@ -1209,6 +1220,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_2_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(2), .mem_enable_ack_mask = BIT(2), .branch = { .halt_reg = 0x8054, @@ -1232,6 +1244,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_2_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_3_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(3), .mem_enable_ack_mask = BIT(3), .branch = { .halt_reg = 0x805c, @@ -1273,6 +1286,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_1_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_0_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(0), .mem_enable_ack_mask = BIT(0), .branch = { .halt_reg = 0x807c, @@ -1296,6 +1310,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_1_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(1), .mem_enable_ack_mask = BIT(1), .branch = { .halt_reg = 0x8084, @@ -1319,6 +1334,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_2_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(2), .mem_enable_ack_mask = BIT(2), .branch = { .halt_reg = 0x808c, @@ -1342,6 +1358,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_2_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_3_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(3), .mem_enable_ack_mask = BIT(3), .branch = { .halt_reg = 0x8094, @@ -1383,6 +1400,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_2_udp_fifo_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_0_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(4), .mem_enable_ack_mask = BIT(4), .branch = { .halt_reg = 0x8004, @@ -1406,6 +1424,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_0_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_1_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(4), .mem_enable_ack_mask = BIT(4), .branch = { .halt_reg = 0x803c, @@ -1429,6 +1448,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_1_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_2_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(4), .mem_enable_ack_mask = BIT(4), .branch = { .halt_reg = 0x8074, @@ -1452,6 +1472,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_2_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_c2c_hm_ref_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x80c4, @@ -1475,6 +1496,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_c2c_hm_ref_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_dbg_c2c_hm_ref_clk = { .mem_enable_reg = 0x8414, .mem_ack_reg = 0x8428, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x80e8, @@ -1498,6 +1520,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_dbg_c2c_hm_ref_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh0_hm_ref_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x802c, @@ -1521,6 +1544,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh0_hm_ref_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh1_hm_ref_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841c, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x8064, @@ -1544,6 +1568,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh1_hm_ref_clk = { static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh2_hm_ref_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(5), .mem_enable_ack_mask = BIT(5), .branch = { .halt_reg = 0x809c, @@ -1603,6 +1628,7 @@ static struct clk_branch ecpri_cc_eth_dbg_noc_axi_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_0_ock_sram_clk = { .mem_enable_reg = 0x8404, .mem_ack_reg = 0x8418, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd140, @@ -1621,6 +1647,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_0_ock_sram_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_1_ock_sram_clk = { .mem_enable_reg = 0x8408, .mem_ack_reg = 0x841C, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd148, @@ -1639,6 +1666,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_1_ock_sram_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_2_ock_sram_clk = { .mem_enable_reg = 0x840c, .mem_ack_reg = 0x8420, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd150, @@ -1657,6 +1685,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_2_ock_sram_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_3_ock_sram_clk = { .mem_enable_reg = 0x8410, .mem_ack_reg = 0x8424, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd158, @@ -1675,6 +1704,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_3_ock_sram_clk = { static struct clk_mem_branch ecpri_cc_eth_phy_4_ock_sram_clk = { .mem_enable_reg = 0x8414, .mem_ack_reg = 0x8428, + .mem_enable_mask = BIT(6), .mem_enable_ack_mask = BIT(6), .branch = { .halt_reg = 0xd160, From aa788d3b475652a3ebaca32ca714f02f8ece3393 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 18 Nov 2025 12:47:07 +0530 Subject: [PATCH 098/117] clk: qcom: branch: Extend invert logic for branch2 mem clocks Some clock branches require inverted logic for memory gating, where disabling the memory involves setting a bit and enabling it involves clearing the same bit. This behavior differs from the standard approach memory branch clocks ops where enabling typically sets the bit. The mem_enable_invert to allow conditional handling of these sequences of the inverted control logic for memory operations required on those memory clock branches. Signed-off-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251118-sm8750-videocc-v2-v4-3-049882a70c9f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-branch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index 0f10090d4ae6..444e7d8648d4 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -142,8 +142,8 @@ static int clk_branch2_mem_enable(struct clk_hw *hw) u32 val; int ret; - regmap_update_bits(branch.clkr.regmap, mem_br->mem_enable_reg, - mem_br->mem_enable_ack_mask, mem_br->mem_enable_ack_mask); + regmap_assign_bits(branch.clkr.regmap, mem_br->mem_enable_reg, + mem_br->mem_enable_mask, !mem_br->mem_enable_invert); ret = regmap_read_poll_timeout(branch.clkr.regmap, mem_br->mem_ack_reg, val, val & mem_br->mem_enable_ack_mask, 0, 200); @@ -159,8 +159,8 @@ static void clk_branch2_mem_disable(struct clk_hw *hw) { struct clk_mem_branch *mem_br = to_clk_mem_branch(hw); - regmap_update_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg, - mem_br->mem_enable_ack_mask, 0); + regmap_assign_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg, + mem_br->mem_enable_mask, mem_br->mem_enable_invert); return clk_branch2_disable(hw); } From b190eaea57803da00a4318ba12359625337be9e8 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 18 Nov 2025 12:47:08 +0530 Subject: [PATCH 099/117] dt-bindings: clock: qcom: Add SM8750 video clock controller Add compatible string for SM8750 video clock controller and the bindings for SM8750 Qualcomm SoC. Signed-off-by: Taniya Das Reviewed-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20251118-sm8750-videocc-v2-v4-4-049882a70c9f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8450-videocc.yaml | 5 ++- .../dt-bindings/clock/qcom,sm8750-videocc.h | 40 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/clock/qcom,sm8750-videocc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index fcd2727dae46..b31bd8335529 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Video Clock & Reset Controller on SM8450 maintainers: - - Taniya Das + - Taniya Das - Jagadeesh Kona description: | @@ -17,6 +17,7 @@ description: | See also: include/dt-bindings/clock/qcom,sm8450-videocc.h include/dt-bindings/clock/qcom,sm8650-videocc.h + include/dt-bindings/clock/qcom,sm8750-videocc.h properties: compatible: @@ -25,6 +26,7 @@ properties: - qcom,sm8475-videocc - qcom,sm8550-videocc - qcom,sm8650-videocc + - qcom,sm8750-videocc - qcom,x1e80100-videocc clocks: @@ -61,6 +63,7 @@ allOf: enum: - qcom,sm8450-videocc - qcom,sm8550-videocc + - qcom,sm8750-videocc then: required: - required-opps diff --git a/include/dt-bindings/clock/qcom,sm8750-videocc.h b/include/dt-bindings/clock/qcom,sm8750-videocc.h new file mode 100644 index 000000000000..f3bfa2ba5160 --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-videocc.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SM8750_H + +/* VIDEO_CC clocks */ +#define VIDEO_CC_AHB_CLK 0 +#define VIDEO_CC_AHB_CLK_SRC 1 +#define VIDEO_CC_MVS0_CLK 2 +#define VIDEO_CC_MVS0_CLK_SRC 3 +#define VIDEO_CC_MVS0_DIV_CLK_SRC 4 +#define VIDEO_CC_MVS0_FREERUN_CLK 5 +#define VIDEO_CC_MVS0_SHIFT_CLK 6 +#define VIDEO_CC_MVS0C_CLK 7 +#define VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC 8 +#define VIDEO_CC_MVS0C_FREERUN_CLK 9 +#define VIDEO_CC_MVS0C_SHIFT_CLK 10 +#define VIDEO_CC_PLL0 11 +#define VIDEO_CC_SLEEP_CLK 12 +#define VIDEO_CC_SLEEP_CLK_SRC 13 +#define VIDEO_CC_XO_CLK 14 +#define VIDEO_CC_XO_CLK_SRC 15 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_MVS0_GDSC 0 +#define VIDEO_CC_MVS0C_GDSC 1 + +/* VIDEO_CC resets */ +#define VIDEO_CC_INTERFACE_BCR 0 +#define VIDEO_CC_MVS0_BCR 1 +#define VIDEO_CC_MVS0C_CLK_ARES 2 +#define VIDEO_CC_MVS0C_BCR 3 +#define VIDEO_CC_MVS0_FREERUN_CLK_ARES 4 +#define VIDEO_CC_MVS0C_FREERUN_CLK_ARES 5 +#define VIDEO_CC_XO_CLK_ARES 6 + +#endif From a160860529b55c54dbd54137f86c818a53d07655 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 18 Nov 2025 12:47:09 +0530 Subject: [PATCH 100/117] clk: qcom: videocc-sm8750: Add video clock controller driver for SM8750 Add support for the video clock controller for video clients to be able to request for videocc clocks on SM8750 platform. Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Reviewed-by: Dmitry Baryshkov Reviewed-by: Imran Shaik Link: https://lore.kernel.org/r/20251118-sm8750-videocc-v2-v4-5-049882a70c9f@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 11 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-sm8750.c | 463 ++++++++++++++++++++++++++++++ 3 files changed, 475 insertions(+) create mode 100644 drivers/clk/qcom/videocc-sm8750.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 550a9d82a6b3..a284ba040b78 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1531,6 +1531,17 @@ config SM_VIDEOCC_8550 Say Y if you want to support video devices and functionality such as video encode/decode. +config SM_VIDEOCC_8750 + tristate "SM8750 Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_8750 + select QCOM_GDSC + help + Support for the video clock controller on Qualcomm Technologies, Inc. + SM8750 devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on SPMI || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 5a0fd1d843c8..0ac8a9055a43 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -185,6 +185,7 @@ obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o obj-$(CONFIG_SM_VIDEOCC_8350) += videocc-sm8350.o obj-$(CONFIG_SM_VIDEOCC_8450) += videocc-sm8450.o obj-$(CONFIG_SM_VIDEOCC_8550) += videocc-sm8550.o +obj-$(CONFIG_SM_VIDEOCC_8750) += videocc-sm8750.o obj-$(CONFIG_SM_VIDEOCC_MILOS) += videocc-milos.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o diff --git a/drivers/clk/qcom/videocc-sm8750.c b/drivers/clk/qcom/videocc-sm8750.c new file mode 100644 index 000000000000..0acf3104d702 --- /dev/null +++ b/drivers/clk/qcom/videocc-sm8750.c @@ -0,0 +1,463 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_SLEEP_CLK, + P_VIDEO_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco taycan_elu_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x25, + .alpha = 0x8000, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_cc_pll0_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2_ao[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_ahb_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_ahb_clk_src", + .parent_data = video_cc_parent_data_0_ao, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { + F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1710000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1890000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_sleep_clk_src = { + .cmd_rcgr = 0x80e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_sleep_clk_src", + .parent_data = video_cc_parent_data_2_ao, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x80bc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_0_ao, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs0_div_clk_src = { + .reg = 0x809c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = { + .reg = 0x8060, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_div2_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x807c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_mem_branch video_cc_mvs0_freerun_clk = { + .mem_enable_reg = 0x8090, + .mem_ack_reg = 0x8090, + .mem_enable_mask = BIT(3), + .mem_enable_ack_mask = GENMASK(11, 10), + .mem_enable_invert = true, + .branch = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_mem_ops, + }, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x80d8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80d8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_freerun_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x80dc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80dc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x8034, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_gdsc = { + .gdscr = 0x8068, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs0c_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct clk_regmap *video_cc_sm8750_clocks[] = { + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, + [VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, + [VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, + [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_sm8750_gdscs[] = { + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map video_cc_sm8750_resets[] = { + [VIDEO_CC_INTERFACE_BCR] = { 0x80a0 }, + [VIDEO_CC_MVS0_BCR] = { 0x8064 }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x804c, 2 }, + [VIDEO_CC_MVS0C_BCR] = { 0x8030 }, + [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x808c, 2 }, + [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x805c, 2 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x80d4, 2 }, +}; + +static const struct regmap_config video_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9f4c, + .fast_io = true, +}; + +static struct clk_alpha_pll *video_cc_sm8750_plls[] = { + &video_cc_pll0, +}; + +static u32 video_cc_sm8750_critical_cbcrs[] = { + 0x80a4, /* VIDEO_CC_AHB_CLK */ + 0x80f8, /* VIDEO_CC_SLEEP_CLK */ + 0x80d4, /* VIDEO_CC_XO_CLK */ +}; + +static void clk_sm8750_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Update DLY_ACCU_RED_SHIFTER_DONE to 0xF for mvs0, mvs0c */ + regmap_update_bits(regmap, 0x8074, GENMASK(25, 21), GENMASK(25, 21)); + regmap_update_bits(regmap, 0x8040, GENMASK(25, 21), GENMASK(25, 21)); + + regmap_update_bits(regmap, 0x9f24, BIT(0), BIT(0)); +} + +static struct qcom_cc_driver_data video_cc_sm8750_driver_data = { + .alpha_plls = video_cc_sm8750_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_sm8750_plls), + .clk_cbcrs = video_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_sm8750_critical_cbcrs), + .clk_regs_configure = clk_sm8750_regs_configure, +}; + +static struct qcom_cc_desc video_cc_sm8750_desc = { + .config = &video_cc_sm8750_regmap_config, + .clks = video_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(video_cc_sm8750_clocks), + .resets = video_cc_sm8750_resets, + .num_resets = ARRAY_SIZE(video_cc_sm8750_resets), + .gdscs = video_cc_sm8750_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_sm8750_gdscs), + .use_rpm = true, + .driver_data = &video_cc_sm8750_driver_data, +}; + +static const struct of_device_id video_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_sm8750_match_table); + +static int video_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_sm8750_desc); +} + +static struct platform_driver video_cc_sm8750_driver = { + .probe = video_cc_sm8750_probe, + .driver = { + .name = "video_cc-sm8750", + .of_match_table = video_cc_sm8750_match_table, + }, +}; + +static int __init video_cc_sm8750_init(void) +{ + return platform_driver_register(&video_cc_sm8750_driver); +} +subsys_initcall(video_cc_sm8750_init); + +static void __exit video_cc_sm8750_exit(void) +{ + platform_driver_unregister(&video_cc_sm8750_driver); +} +module_exit(video_cc_sm8750_exit); + +MODULE_DESCRIPTION("QTI VIDEO_CC SM8750 Driver"); +MODULE_LICENSE("GPL"); From c84b824d3a8f14bedec8108cb8061da761180f49 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Tue, 18 Nov 2025 18:33:11 +0100 Subject: [PATCH 101/117] dt-bindings: clock: qcom: x1e80100-dispcc: Add USB4 router link resets The router link clock branches also feature some reset logic, which is required to properly power sequence the hardware for DP tunneling over USB4. Describe these missing resets. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251118-topic-usb4_x1e_dispcc-v1-1-14c68d842c71@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,x1e80100-dispcc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/dt-bindings/clock/qcom,x1e80100-dispcc.h b/include/dt-bindings/clock/qcom,x1e80100-dispcc.h index d4a83e4fd0d1..49b3a9e5ce4a 100644 --- a/include/dt-bindings/clock/qcom,x1e80100-dispcc.h +++ b/include/dt-bindings/clock/qcom,x1e80100-dispcc.h @@ -90,6 +90,9 @@ #define DISP_CC_MDSS_CORE_BCR 0 #define DISP_CC_MDSS_CORE_INT2_BCR 1 #define DISP_CC_MDSS_RSCC_BCR 2 +#define DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK_ARES 3 +#define DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK_ARES 4 +#define DISP_CC_MDSS_DPTX2_USB_ROUTER_LINK_INTF_CLK_ARES 5 /* DISP_CC GDSCR */ #define MDSS_GDSC 0 From 3664282f3345fdfa6a154feb6ed6c3217a8b3b0d Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Tue, 18 Nov 2025 18:33:12 +0100 Subject: [PATCH 102/117] clk: qcom: x1e80100-dispcc: Add USB4 router link resets The router link clock branches also feature some reset logic, which is required to properly power sequence the hardware for DP tunneling over USB4. Describe these missing resets. Signed-off-by: Konrad Dybcio Reviewed-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251118-topic-usb4_x1e_dispcc-v1-2-14c68d842c71@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-x1e80100.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/dispcc-x1e80100.c b/drivers/clk/qcom/dispcc-x1e80100.c index 40069eba41f2..aa7fd43969f9 100644 --- a/drivers/clk/qcom/dispcc-x1e80100.c +++ b/drivers/clk/qcom/dispcc-x1e80100.c @@ -1618,6 +1618,9 @@ static struct clk_regmap *disp_cc_x1e80100_clocks[] = { static const struct qcom_reset_map disp_cc_x1e80100_resets[] = { [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8044, .bit = 2 }, + [DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8068, .bit = 2 }, + [DISP_CC_MDSS_DPTX2_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8088, .bit = 2 }, [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, }; From 826eaa8f5bac6e919cf7c0b4161b2d783fdc45b3 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Tue, 11 Nov 2025 10:57:34 +0800 Subject: [PATCH 103/117] clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll() The current path will have an independent PLL(LPLL\BPLL) exclusively for the CPU to use. As follows: |-\ --lpll--| \ |mux|--[gate]--[div]--clk_core-- --gpll--| / |-/ The new chip does not have a dedicated PLL for the cpu; it is distributed nearby from the common PLL. If there are special frequency requirements that require the use of pvtpll, explanations will be submitted later. The clock path of new soc CPU simplified as follows: --gpll--|--\ | \ | \ | \ --v0pll--| mux |--[gate]--[div]--clk_core-- | / | / --v1pll--| / |--/ Signed-off-by: Elaine Zhang Link: https://patch.msgid.link/20251111025738.869847-2-zhangqing@rock-chips.com Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-cpu.c | 165 +++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.c | 24 +++++ drivers/clk/rockchip/clk.h | 15 +++ 3 files changed, 204 insertions(+) diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index dcc9dcb597ae..6e91a3041a03 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -396,3 +396,168 @@ free_cpuclk: kfree(cpuclk); return ERR_PTR(ret); } + +static int rockchip_cpuclk_multi_pll_pre_rate_change(struct rockchip_cpuclk *cpuclk, + struct clk_notifier_data *ndata) +{ + unsigned long new_rate = roundup(ndata->new_rate, 1000); + const struct rockchip_cpuclk_rate_table *rate; + unsigned long flags; + + rate = rockchip_get_cpuclk_settings(cpuclk, new_rate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for cpuclk\n", + __func__, new_rate); + return -EINVAL; + } + + if (new_rate > ndata->old_rate) { + spin_lock_irqsave(cpuclk->lock, flags); + rockchip_cpuclk_set_dividers(cpuclk, rate); + spin_unlock_irqrestore(cpuclk->lock, flags); + } + + return 0; +} + +static int rockchip_cpuclk_multi_pll_post_rate_change(struct rockchip_cpuclk *cpuclk, + struct clk_notifier_data *ndata) +{ + unsigned long new_rate = roundup(ndata->new_rate, 1000); + const struct rockchip_cpuclk_rate_table *rate; + unsigned long flags; + + rate = rockchip_get_cpuclk_settings(cpuclk, new_rate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for cpuclk\n", + __func__, new_rate); + return -EINVAL; + } + + if (new_rate < ndata->old_rate) { + spin_lock_irqsave(cpuclk->lock, flags); + rockchip_cpuclk_set_dividers(cpuclk, rate); + spin_unlock_irqrestore(cpuclk->lock, flags); + } + + return 0; +} + +static int rockchip_cpuclk_multi_pll_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_nb(nb); + int ret = 0; + + pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n", + __func__, event, ndata->old_rate, ndata->new_rate); + if (event == PRE_RATE_CHANGE) + ret = rockchip_cpuclk_multi_pll_pre_rate_change(cpuclk, ndata); + else if (event == POST_RATE_CHANGE) + ret = rockchip_cpuclk_multi_pll_post_rate_change(cpuclk, ndata); + + return notifier_from_errno(ret); +} + +struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name, + const char *const *parent_names, + u8 num_parents, void __iomem *base, + int muxdiv_offset, u8 mux_shift, + u8 mux_width, u8 mux_flags, + int div_offset, u8 div_shift, + u8 div_width, u8 div_flags, + unsigned long flags, spinlock_t *lock, + const struct rockchip_cpuclk_rate_table *rates, + int nrates) +{ + struct rockchip_cpuclk *cpuclk; + struct clk_hw *hw; + struct clk_mux *mux = NULL; + struct clk_divider *div = NULL; + const struct clk_ops *mux_ops = NULL, *div_ops = NULL; + int ret; + + if (num_parents > 1) { + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + mux->reg = base + muxdiv_offset; + mux->shift = mux_shift; + mux->mask = BIT(mux_width) - 1; + mux->flags = mux_flags; + mux->lock = lock; + mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops + : &clk_mux_ops; + } + + if (div_width > 0) { + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) { + ret = -ENOMEM; + goto free_mux; + } + + div->flags = div_flags; + if (div_offset) + div->reg = base + div_offset; + else + div->reg = base + muxdiv_offset; + div->shift = div_shift; + div->width = div_width; + div->lock = lock; + div_ops = (div_flags & CLK_DIVIDER_READ_ONLY) + ? &clk_divider_ro_ops + : &clk_divider_ops; + } + + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, + mux ? &mux->hw : NULL, mux_ops, + div ? &div->hw : NULL, div_ops, + NULL, NULL, flags); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto free_div; + } + + cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); + if (!cpuclk) { + ret = -ENOMEM; + goto unregister_clk; + } + + cpuclk->reg_base = base; + cpuclk->lock = lock; + cpuclk->clk_nb.notifier_call = rockchip_cpuclk_multi_pll_notifier_cb; + ret = clk_notifier_register(hw->clk, &cpuclk->clk_nb); + if (ret) { + pr_err("%s: failed to register clock notifier for %s\n", + __func__, name); + goto free_cpuclk; + } + + if (nrates > 0) { + cpuclk->rate_count = nrates; + cpuclk->rate_table = kmemdup(rates, + sizeof(*rates) * nrates, + GFP_KERNEL); + if (!cpuclk->rate_table) { + ret = -ENOMEM; + goto free_cpuclk; + } + } + + return hw->clk; + +free_cpuclk: + kfree(cpuclk); +unregister_clk: + clk_hw_unregister_composite(hw); +free_div: + kfree(div); +free_mux: + kfree(mux); + + return ERR_PTR(ret); +} diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 19caf26c991b..2601df3b1066 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -722,6 +722,30 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, } EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk); +void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *list, + const struct rockchip_cpuclk_rate_table *rates, + int nrates) +{ + struct clk *clk; + + clk = rockchip_clk_register_cpuclk_multi_pll(list->name, list->parent_names, + list->num_parents, ctx->reg_base, + list->muxdiv_offset, list->mux_shift, + list->mux_width, list->mux_flags, + list->div_offset, list->div_shift, + list->div_width, list->div_flags, + list->flags, &ctx->lock, rates, nrates); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s: %ld\n", + __func__, list->name, PTR_ERR(clk)); + return; + } + + rockchip_clk_set_lookup(ctx, clk, list->id); +} +EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk_multi_pll); + void rockchip_clk_protect_critical(const char *const clocks[], int nclocks) { diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 7c5e74c7a2e2..23653a942403 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -622,6 +622,17 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, const struct rockchip_cpuclk_rate_table *rates, int nrates, void __iomem *reg_base, spinlock_t *lock); +struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name, + const char *const *parent_names, + u8 num_parents, void __iomem *base, + int muxdiv_offset, u8 mux_shift, + u8 mux_width, u8 mux_flags, + int div_offset, u8 div_shift, + u8 div_width, u8 div_flags, + unsigned long flags, spinlock_t *lock, + const struct rockchip_cpuclk_rate_table *rates, + int nrates); + struct clk *rockchip_clk_register_mmc(const char *name, const char *const *parent_names, u8 num_parents, void __iomem *reg, @@ -1208,6 +1219,10 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, const struct rockchip_cpuclk_reg_data *reg_data, const struct rockchip_cpuclk_rate_table *rates, int nrates); +void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *list, + const struct rockchip_cpuclk_rate_table *rates, + int nrates); void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, unsigned int reg, void (*cb)(void)); From d0d9a9629f505ac70e1ffd172e092ff71f5d989a Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Tue, 11 Nov 2025 10:57:35 +0800 Subject: [PATCH 104/117] dt-bindings: clock, reset: Add support for rv1126b Add clock and reset ID defines for rv1126b. Also add documentation for the rv1126b CRU core. Signed-off-by: Elaine Zhang Acked-by: Conor Dooley Link: https://patch.msgid.link/20251111025738.869847-3-zhangqing@rock-chips.com Signed-off-by: Heiko Stuebner --- .../bindings/clock/rockchip,rv1126b-cru.yaml | 52 +++ .../dt-bindings/clock/rockchip,rv1126b-cru.h | 392 +++++++++++++++++ .../dt-bindings/reset/rockchip,rv1126b-cru.h | 405 ++++++++++++++++++ 3 files changed, 849 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml create mode 100644 include/dt-bindings/clock/rockchip,rv1126b-cru.h create mode 100644 include/dt-bindings/reset/rockchip,rv1126b-cru.h diff --git a/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml new file mode 100644 index 000000000000..04b0a5c51e4e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/rockchip,rv1126b-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RV1126B Clock and Reset Unit + +maintainers: + - Elaine Zhang + - Heiko Stuebner + +description: + The rv1126b clock controller generates the clock and also implements a + reset controller for SoC peripherals. + +properties: + compatible: + enum: + - rockchip,rv1126b-cru + + reg: + maxItems: 1 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + + clocks: + maxItems: 1 + + clock-names: + const: xin24m + +required: + - compatible + - reg + - "#clock-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + clock-controller@20000000 { + compatible = "rockchip,rv1126b-cru"; + reg = <0x20000000 0xc0000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/include/dt-bindings/clock/rockchip,rv1126b-cru.h b/include/dt-bindings/clock/rockchip,rv1126b-cru.h new file mode 100644 index 000000000000..721d50a1419f --- /dev/null +++ b/include/dt-bindings/clock/rockchip,rv1126b-cru.h @@ -0,0 +1,392 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + * Author: Elaine Zhang + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1126B_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RV1126B_H + +/* pll clocks */ +#define PLL_GPLL 0 +#define PLL_CPLL 1 +#define PLL_AUPLL 2 +#define ARMCLK 3 +#define SCLK_DDR 4 + +/* clk (clocks) */ +#define CLK_CPLL_DIV20 5 +#define CLK_CPLL_DIV10 6 +#define CLK_CPLL_DIV8 7 +#define CLK_GPLL_DIV8 8 +#define CLK_GPLL_DIV6 9 +#define CLK_GPLL_DIV4 10 +#define CLK_CPLL_DIV3 11 +#define CLK_GPLL_DIV3 12 +#define CLK_CPLL_DIV2 13 +#define CLK_GPLL_DIV2 14 +#define CLK_CM_FRAC0 15 +#define CLK_CM_FRAC1 16 +#define CLK_CM_FRAC2 17 +#define CLK_UART_FRAC0 18 +#define CLK_UART_FRAC1 19 +#define CLK_AUDIO_FRAC0 20 +#define CLK_AUDIO_FRAC1 21 +#define CLK_AUDIO_INT0 22 +#define CLK_AUDIO_INT1 23 +#define SCLK_UART0_SRC 24 +#define SCLK_UART1 25 +#define SCLK_UART2 26 +#define SCLK_UART3 27 +#define SCLK_UART4 28 +#define SCLK_UART5 29 +#define SCLK_UART6 30 +#define SCLK_UART7 31 +#define MCLK_SAI0 32 +#define MCLK_SAI1 33 +#define MCLK_SAI2 34 +#define MCLK_PDM 35 +#define CLKOUT_PDM 36 +#define MCLK_ASRC0 37 +#define MCLK_ASRC1 38 +#define MCLK_ASRC2 39 +#define MCLK_ASRC3 40 +#define CLK_ASRC0 41 +#define CLK_ASRC1 42 +#define CLK_CORE_PLL 43 +#define CLK_NPU_PLL 44 +#define CLK_VEPU_PLL 45 +#define CLK_ISP_PLL 46 +#define CLK_AISP_PLL 47 +#define CLK_SARADC0_SRC 48 +#define CLK_SARADC1_SRC 49 +#define CLK_SARADC2_SRC 50 +#define HCLK_NPU_ROOT 51 +#define PCLK_NPU_ROOT 52 +#define ACLK_VEPU_ROOT 53 +#define HCLK_VEPU_ROOT 54 +#define PCLK_VEPU_ROOT 55 +#define CLK_CORE_RGA_SRC 56 +#define ACLK_GMAC_ROOT 57 +#define ACLK_VI_ROOT 58 +#define HCLK_VI_ROOT 59 +#define PCLK_VI_ROOT 60 +#define DCLK_VICAP_ROOT 61 +#define CLK_SYS_DSMC_ROOT 62 +#define ACLK_VDO_ROOT 63 +#define ACLK_RKVDEC_ROOT 64 +#define HCLK_VDO_ROOT 65 +#define PCLK_VDO_ROOT 66 +#define DCLK_OOC_SRC 67 +#define DCLK_VOP 68 +#define DCLK_DECOM_SRC 69 +#define PCLK_DDR_ROOT 70 +#define ACLK_SYSMEM_SRC 71 +#define ACLK_TOP_ROOT 72 +#define ACLK_BUS_ROOT 73 +#define HCLK_BUS_ROOT 74 +#define PCLK_BUS_ROOT 75 +#define CCLK_SDMMC0 76 +#define CCLK_SDMMC1 77 +#define CCLK_EMMC 78 +#define SCLK_2X_FSPI0 79 +#define CLK_GMAC_PTP_REF_SRC 80 +#define CLK_GMAC_125M 81 +#define CLK_TIMER_ROOT 82 +#define TCLK_WDT_NS_SRC 83 +#define TCLK_WDT_S_SRC 84 +#define TCLK_WDT_HPMCU 85 +#define CLK_CAN0 86 +#define CLK_CAN1 87 +#define PCLK_PERI_ROOT 88 +#define ACLK_PERI_ROOT 89 +#define CLK_I2C_BUS_SRC 90 +#define CLK_SPI0 91 +#define CLK_SPI1 92 +#define BUSCLK_PMU_SRC 93 +#define CLK_PWM0 94 +#define CLK_PWM2 95 +#define CLK_PWM3 96 +#define CLK_PKA_RKCE_SRC 97 +#define ACLK_RKCE_SRC 98 +#define ACLK_VCP_ROOT 99 +#define HCLK_VCP_ROOT 100 +#define PCLK_VCP_ROOT 101 +#define CLK_CORE_FEC_SRC 102 +#define CLK_CORE_AVSP_SRC 103 +#define CLK_50M_GMAC_IOBUF_VI 104 +#define PCLK_TOP_ROOT 105 +#define CLK_MIPI0_OUT2IO 106 +#define CLK_MIPI1_OUT2IO 107 +#define CLK_MIPI2_OUT2IO 108 +#define CLK_MIPI3_OUT2IO 109 +#define CLK_CIF_OUT2IO 110 +#define CLK_MAC_OUT2IO 111 +#define MCLK_SAI0_OUT2IO 112 +#define MCLK_SAI1_OUT2IO 113 +#define MCLK_SAI2_OUT2IO 114 +#define CLK_CM_FRAC0_SRC 115 +#define CLK_CM_FRAC1_SRC 116 +#define CLK_CM_FRAC2_SRC 117 +#define CLK_UART_FRAC0_SRC 118 +#define CLK_UART_FRAC1_SRC 119 +#define CLK_AUDIO_FRAC0_SRC 120 +#define CLK_AUDIO_FRAC1_SRC 121 +#define ACLK_NPU_ROOT 122 +#define HCLK_RKNN 123 +#define ACLK_RKNN 124 +#define PCLK_GPIO3 125 +#define DBCLK_GPIO3 126 +#define PCLK_IOC_VCCIO3 127 +#define PCLK_SARADC0 128 +#define CLK_SARADC0 129 +#define HCLK_SDMMC1 130 +#define HCLK_VEPU 131 +#define ACLK_VEPU 132 +#define CLK_CORE_VEPU 133 +#define HCLK_FEC 134 +#define ACLK_FEC 135 +#define CLK_CORE_FEC 136 +#define HCLK_AVSP 137 +#define ACLK_AVSP 138 +#define BUSCLK_PMU1_ROOT 139 +#define HCLK_AISP 140 +#define ACLK_AISP 141 +#define CLK_CORE_AISP 142 +#define CLK_CORE_ISP_ROOT 143 +#define PCLK_DSMC 144 +#define ACLK_DSMC 145 +#define HCLK_CAN0 146 +#define HCLK_CAN1 147 +#define PCLK_GPIO2 148 +#define DBCLK_GPIO2 149 +#define PCLK_GPIO4 150 +#define DBCLK_GPIO4 151 +#define PCLK_GPIO5 152 +#define DBCLK_GPIO5 153 +#define PCLK_GPIO6 154 +#define DBCLK_GPIO6 155 +#define PCLK_GPIO7 156 +#define DBCLK_GPIO7 157 +#define PCLK_IOC_VCCIO2 158 +#define PCLK_IOC_VCCIO4 159 +#define PCLK_IOC_VCCIO5 160 +#define PCLK_IOC_VCCIO6 161 +#define PCLK_IOC_VCCIO7 162 +#define HCLK_ISP 163 +#define ACLK_ISP 164 +#define CLK_CORE_ISP 165 +#define HCLK_VICAP 166 +#define ACLK_VICAP 167 +#define DCLK_VICAP 168 +#define ISP0CLK_VICAP 169 +#define HCLK_VPSS 170 +#define ACLK_VPSS 171 +#define CLK_CORE_VPSS 172 +#define PCLK_CSI2HOST0 173 +#define DCLK_CSI2HOST0 174 +#define PCLK_CSI2HOST1 175 +#define DCLK_CSI2HOST1 176 +#define PCLK_CSI2HOST2 177 +#define DCLK_CSI2HOST2 178 +#define PCLK_CSI2HOST3 179 +#define DCLK_CSI2HOST3 180 +#define HCLK_SDMMC0 181 +#define ACLK_GMAC 182 +#define PCLK_GMAC 183 +#define CLK_GMAC_PTP_REF 184 +#define PCLK_CSIPHY0 185 +#define PCLK_CSIPHY1 186 +#define PCLK_MACPHY 187 +#define PCLK_SARADC1 188 +#define CLK_SARADC1 189 +#define PCLK_SARADC2 190 +#define CLK_SARADC2 191 +#define ACLK_RKVDEC 192 +#define HCLK_RKVDEC 193 +#define CLK_HEVC_CA_RKVDEC 194 +#define ACLK_VOP 195 +#define HCLK_VOP 196 +#define HCLK_RKJPEG 197 +#define ACLK_RKJPEG 198 +#define ACLK_RKMMU_DECOM 199 +#define HCLK_RKMMU_DECOM 200 +#define DCLK_DECOM 201 +#define ACLK_DECOM 202 +#define PCLK_DECOM 203 +#define PCLK_MIPI_DSI 204 +#define PCLK_DSIPHY 205 +#define ACLK_OOC 206 +#define ACLK_SYSMEM 207 +#define PCLK_DDRC 208 +#define PCLK_DDRMON 209 +#define CLK_TIMER_DDRMON 210 +#define PCLK_DFICTRL 211 +#define PCLK_DDRPHY 212 +#define PCLK_DMA2DDR 213 +#define CLK_RCOSC_SRC 214 +#define BUSCLK_PMU_MUX 215 +#define BUSCLK_PMU_ROOT 216 +#define PCLK_PMU 217 +#define CLK_XIN_RC_DIV 218 +#define CLK_32K 219 +#define PCLK_PMU_GPIO0 220 +#define DBCLK_PMU_GPIO0 221 +#define PCLK_PMU_HP_TIMER 222 +#define CLK_PMU_HP_TIMER 223 +#define CLK_PMU_32K_HP_TIMER 224 +#define PCLK_PWM1 225 +#define CLK_PWM1 226 +#define CLK_OSC_PWM1 227 +#define CLK_RC_PWM1 228 +#define CLK_FREQ_PWM1 229 +#define CLK_COUNTER_PWM1 230 +#define PCLK_I2C2 231 +#define CLK_I2C2 232 +#define PCLK_UART0 233 +#define SCLK_UART0 234 +#define PCLK_RCOSC_CTRL 235 +#define CLK_OSC_RCOSC_CTRL 236 +#define CLK_REF_RCOSC_CTRL 237 +#define PCLK_IOC_PMUIO0 238 +#define CLK_REFOUT 239 +#define CLK_PREROLL 240 +#define CLK_PREROLL_32K 241 +#define HCLK_PMU_SRAM 242 +#define PCLK_WDT_LPMCU 243 +#define TCLK_WDT_LPMCU 244 +#define CLK_LPMCU 245 +#define CLK_LPMCU_RTC 246 +#define PCLK_LPMCU_MAILBOX 247 +#define HCLK_OOC 248 +#define PCLK_SPI2AHB 249 +#define HCLK_SPI2AHB 250 +#define HCLK_FSPI1 251 +#define HCLK_XIP_FSPI1 252 +#define SCLK_1X_FSPI1 253 +#define PCLK_IOC_PMUIO1 254 +#define PCLK_AUDIO_ADC_PMU 255 +#define MCLK_AUDIO_ADC_PMU 256 +#define MCLK_AUDIO_ADC_DIV4_PMU 257 +#define MCLK_LPSAI 258 +#define ACLK_GIC400 259 +#define PCLK_WDT_NS 260 +#define TCLK_WDT_NS 261 +#define PCLK_WDT_HPMCU 262 +#define HCLK_CACHE 263 +#define PCLK_HPMCU_MAILBOX 264 +#define PCLK_HPMCU_INTMUX 265 +#define CLK_HPMCU 266 +#define CLK_HPMCU_RTC 267 +#define PCLK_RKDMA 268 +#define ACLK_RKDMA 269 +#define PCLK_DCF 270 +#define ACLK_DCF 271 +#define HCLK_RGA 272 +#define ACLK_RGA 273 +#define CLK_CORE_RGA 274 +#define PCLK_TIMER 275 +#define CLK_TIMER0 276 +#define CLK_TIMER1 277 +#define CLK_TIMER2 278 +#define CLK_TIMER3 279 +#define CLK_TIMER4 280 +#define CLK_TIMER5 281 +#define PCLK_I2C0 282 +#define CLK_I2C0 283 +#define PCLK_I2C1 284 +#define CLK_I2C1 285 +#define PCLK_I2C3 286 +#define CLK_I2C3 287 +#define PCLK_I2C4 288 +#define CLK_I2C4 289 +#define PCLK_I2C5 290 +#define CLK_I2C5 291 +#define PCLK_SPI0 292 +#define PCLK_SPI1 293 +#define PCLK_PWM0 294 +#define CLK_OSC_PWM0 295 +#define CLK_RC_PWM0 296 +#define PCLK_PWM2 297 +#define CLK_OSC_PWM2 298 +#define CLK_RC_PWM2 299 +#define PCLK_PWM3 300 +#define CLK_OSC_PWM3 301 +#define CLK_RC_PWM3 302 +#define PCLK_UART1 303 +#define PCLK_UART2 304 +#define PCLK_UART3 305 +#define PCLK_UART4 306 +#define PCLK_UART5 307 +#define PCLK_UART6 308 +#define PCLK_UART7 309 +#define PCLK_TSADC 310 +#define CLK_TSADC 311 +#define HCLK_SAI0 312 +#define HCLK_SAI1 313 +#define HCLK_SAI2 314 +#define HCLK_RKDSM 315 +#define MCLK_RKDSM 316 +#define HCLK_PDM 317 +#define HCLK_ASRC0 318 +#define HCLK_ASRC1 319 +#define PCLK_AUDIO_ADC_BUS 320 +#define MCLK_AUDIO_ADC_BUS 321 +#define MCLK_AUDIO_ADC_DIV4_BUS 322 +#define PCLK_RKCE 323 +#define HCLK_NS_RKCE 324 +#define PCLK_OTPC_NS 325 +#define CLK_SBPI_OTPC_NS 326 +#define CLK_USER_OTPC_NS 327 +#define CLK_OTPC_ARB 328 +#define PCLK_OTP_MASK 329 +#define CLK_TSADC_PHYCTRL 330 +#define LRCK_SRC_ASRC0 331 +#define LRCK_DST_ASRC0 332 +#define LRCK_SRC_ASRC1 333 +#define LRCK_DST_ASRC1 334 +#define PCLK_KEY_READER 335 +#define ACLK_NSRKCE 336 +#define CLK_PKA_NSRKCE 337 +#define PCLK_RTC_ROOT 338 +#define PCLK_GPIO1 339 +#define DBCLK_GPIO1 340 +#define PCLK_IOC_VCCIO1 341 +#define ACLK_USB3OTG 342 +#define CLK_REF_USB3OTG 343 +#define CLK_SUSPEND_USB3OTG 344 +#define HCLK_USB2HOST 345 +#define HCLK_ARB_USB2HOST 346 +#define PCLK_RTC_TEST 347 +#define HCLK_EMMC 348 +#define HCLK_FSPI0 349 +#define HCLK_XIP_FSPI0 350 +#define PCLK_PIPEPHY 351 +#define PCLK_USB2PHY 352 +#define CLK_REF_PIPEPHY_CPLL_SRC 353 +#define CLK_REF_PIPEPHY 354 +#define HCLK_VPSL 355 +#define ACLK_VPSL 356 +#define CLK_CORE_VPSL 357 +#define CLK_MACPHY 358 +#define HCLK_RKRNG_NS 359 +#define HCLK_RKRNG_S_NS 360 +#define CLK_AISP_PLL_SRC 361 + +/* secure clks */ +#define CLK_USER_OTPC_S 362 +#define CLK_SBPI_OTPC_S 363 +#define PCLK_OTPC_S 364 +#define PCLK_KEY_READER_S 365 +#define HCLK_KL_RKCE_S 366 +#define HCLK_RKCE_S 367 +#define PCLK_WDT_S 368 +#define TCLK_WDT_S 369 +#define CLK_STIMER0 370 +#define CLK_STIMER1 371 +#define PLK_STIMER 372 +#define HCLK_RKRNG_S 373 +#define CLK_PKA_RKCE_S 374 +#define ACLK_RKCE_S 375 + +#endif diff --git a/include/dt-bindings/reset/rockchip,rv1126b-cru.h b/include/dt-bindings/reset/rockchip,rv1126b-cru.h new file mode 100644 index 000000000000..a7712db319d0 --- /dev/null +++ b/include/dt-bindings/reset/rockchip,rv1126b-cru.h @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + * Author: Elaine Zhang + */ + +#ifndef _DT_BINDINGS_RESET_ROCKCHIP_RV1126B_H +#define _DT_BINDINGS_RESET_ROCKCHIP_RV1126B_H + +/* ==========================list all of reset fields id=========================== */ +/* TOPCRU-->SOFTRST_CON00 */ + +/* TOPCRU-->SOFTRST_CON15 */ +#define SRST_P_CRU 0 +#define SRST_P_CRU_BIU 1 + +/* BUSCRU-->SOFTRST_CON00 */ +#define SRST_A_TOP_BIU 2 +#define SRST_A_RKCE_BIU 3 +#define SRST_A_BUS_BIU 4 +#define SRST_H_BUS_BIU 5 +#define SRST_P_BUS_BIU 6 +#define SRST_P_CRU_BUS 7 +#define SRST_P_SYS_GRF 8 +#define SRST_H_BOOTROM 9 +#define SRST_A_GIC400 10 +#define SRST_A_SPINLOCK 11 +#define SRST_P_WDT_NS 12 +#define SRST_T_WDT_NS 13 + +/* BUSCRU-->SOFTRST_CON01 */ +#define SRST_P_WDT_HPMCU 14 +#define SRST_T_WDT_HPMCU 15 +#define SRST_H_CACHE 16 +#define SRST_P_HPMCU_MAILBOX 17 +#define SRST_P_HPMCU_INTMUX 18 +#define SRST_HPMCU_FULL_CLUSTER 19 +#define SRST_HPMCU_PWUP 20 +#define SRST_HPMCU_ONLY_CORE 21 +#define SRST_T_HPMCU_JTAG 22 +#define SRST_P_RKDMA 23 +#define SRST_A_RKDMA 24 + +/* BUSCRU-->SOFTRST_CON02 */ +#define SRST_P_DCF 25 +#define SRST_A_DCF 26 +#define SRST_H_RGA 27 +#define SRST_A_RGA 28 +#define SRST_CORE_RGA 29 +#define SRST_P_TIMER 30 +#define SRST_TIMER0 31 +#define SRST_TIMER1 32 +#define SRST_TIMER2 33 +#define SRST_TIMER3 34 +#define SRST_TIMER4 35 +#define SRST_TIMER5 36 +#define SRST_A_RKCE 37 +#define SRST_PKA_RKCE 38 +#define SRST_H_RKRNG_S 39 +#define SRST_H_RKRNG_NS 40 + +/* BUSCRU-->SOFTRST_CON03 */ +#define SRST_P_I2C0 41 +#define SRST_I2C0 42 +#define SRST_P_I2C1 43 +#define SRST_I2C1 44 +#define SRST_P_I2C3 45 +#define SRST_I2C3 46 +#define SRST_P_I2C4 47 +#define SRST_I2C4 48 +#define SRST_P_I2C5 49 +#define SRST_I2C5 50 +#define SRST_P_SPI0 51 +#define SRST_SPI0 52 +#define SRST_P_SPI1 53 +#define SRST_SPI1 54 + +/* BUSCRU-->SOFTRST_CON04 */ +#define SRST_P_PWM0 55 +#define SRST_PWM0 56 +#define SRST_P_PWM2 57 +#define SRST_PWM2 58 +#define SRST_P_PWM3 59 +#define SRST_PWM3 60 + +/* BUSCRU-->SOFTRST_CON05 */ +#define SRST_P_UART1 61 +#define SRST_S_UART1 62 +#define SRST_P_UART2 63 +#define SRST_S_UART2 64 +#define SRST_P_UART3 65 +#define SRST_S_UART3 66 +#define SRST_P_UART4 67 +#define SRST_S_UART4 68 +#define SRST_P_UART5 69 +#define SRST_S_UART5 70 +#define SRST_P_UART6 71 +#define SRST_S_UART6 72 +#define SRST_P_UART7 73 +#define SRST_S_UART7 74 + +/* BUSCRU-->SOFTRST_CON06 */ +#define SRST_P_TSADC 75 +#define SRST_TSADC 76 +#define SRST_H_SAI0 77 +#define SRST_M_SAI0 78 +#define SRST_H_SAI1 79 +#define SRST_M_SAI1 80 +#define SRST_H_SAI2 81 +#define SRST_M_SAI2 82 +#define SRST_H_RKDSM 83 +#define SRST_M_RKDSM 84 +#define SRST_H_PDM 85 +#define SRST_M_PDM 86 +#define SRST_PDM 87 + +/* BUSCRU-->SOFTRST_CON07 */ +#define SRST_H_ASRC0 88 +#define SRST_ASRC0 89 +#define SRST_H_ASRC1 90 +#define SRST_ASRC1 91 +#define SRST_P_AUDIO_ADC_BUS 92 +#define SRST_M_AUDIO_ADC_BUS 93 +#define SRST_P_RKCE 94 +#define SRST_H_NS_RKCE 95 +#define SRST_P_OTPC_NS 96 +#define SRST_SBPI_OTPC_NS 97 +#define SRST_USER_OTPC_NS 98 +#define SRST_OTPC_ARB 99 +#define SRST_P_OTP_MASK 100 + +/* PERICRU-->SOFTRST_CON00 */ +#define SRST_A_PERI_BIU 101 +#define SRST_P_PERI_BIU 102 +#define SRST_P_RTC_BIU 103 +#define SRST_P_CRU_PERI 104 +#define SRST_P_PERI_GRF 105 +#define SRST_P_GPIO1 106 +#define SRST_DB_GPIO1 107 +#define SRST_P_IOC_VCCIO1 108 +#define SRST_A_USB3OTG 109 +#define SRST_H_USB2HOST 110 +#define SRST_H_ARB_USB2HOST 111 +#define SRST_P_RTC_TEST 112 + +/* PERICRU-->SOFTRST_CON01 */ +#define SRST_H_EMMC 113 +#define SRST_H_FSPI0 114 +#define SRST_H_XIP_FSPI0 115 +#define SRST_S_2X_FSPI0 116 +#define SRST_UTMI_USB2HOST 117 +#define SRST_REF_PIPEPHY 118 +#define SRST_P_PIPEPHY 119 +#define SRST_P_PIPEPHY_GRF 120 +#define SRST_P_USB2PHY 121 +#define SRST_POR_USB2PHY 122 +#define SRST_OTG_USB2PHY 123 +#define SRST_HOST_USB2PHY 124 + +/* CORECRU-->SOFTRST_CON00 */ +#define SRST_REF_PVTPLL_CORE 125 +#define SRST_NCOREPORESET0 126 +#define SRST_NCORESET0 127 +#define SRST_NCOREPORESET1 128 +#define SRST_NCORESET1 129 +#define SRST_NCOREPORESET2 130 +#define SRST_NCORESET2 131 +#define SRST_NCOREPORESET3 132 +#define SRST_NCORESET3 133 +#define SRST_NDBGRESET 134 +#define SRST_NL2RESET 135 + +/* CORECRU-->SOFTRST_CON01 */ +#define SRST_A_CORE_BIU 136 +#define SRST_P_CORE_BIU 137 +#define SRST_H_CORE_BIU 138 +#define SRST_P_DBG 139 +#define SRST_POT_DBG 140 +#define SRST_NT_DBG 141 +#define SRST_P_CORE_PVTPLL 142 +#define SRST_P_CRU_CORE 143 +#define SRST_P_CORE_GRF 144 +#define SRST_P_DFT2APB 145 + +/* PMUCRU-->SOFTRST_CON00 */ +#define SRST_H_PMU_BIU 146 +#define SRST_P_PMU_GPIO0 147 +#define SRST_DB_PMU_GPIO0 148 +#define SRST_P_PMU_HP_TIMER 149 +#define SRST_PMU_HP_TIMER 150 +#define SRST_PMU_32K_HP_TIMER 151 + +/* PMUCRU-->SOFTRST_CON01 */ +#define SRST_P_PWM1 152 +#define SRST_PWM1 153 +#define SRST_P_I2C2 154 +#define SRST_I2C2 155 +#define SRST_P_UART0 156 +#define SRST_S_UART0 157 + +/* PMUCRU-->SOFTRST_CON02 */ +#define SRST_P_RCOSC_CTRL 158 +#define SRST_REF_RCOSC_CTRL 159 +#define SRST_P_IOC_PMUIO0 160 +#define SRST_P_CRU_PMU 161 +#define SRST_P_PMU_GRF 162 +#define SRST_PREROLL 163 +#define SRST_PREROLL_32K 164 +#define SRST_H_PMU_SRAM 165 + +/* PMUCRU-->SOFTRST_CON03 */ +#define SRST_P_WDT_LPMCU 166 +#define SRST_T_WDT_LPMCU 167 +#define SRST_LPMCU_FULL_CLUSTER 168 +#define SRST_LPMCU_PWUP 169 +#define SRST_LPMCU_ONLY_CORE 170 +#define SRST_T_LPMCU_JTAG 171 +#define SRST_P_LPMCU_MAILBOX 172 + +/* PMU1CRU-->SOFTRST_CON00 */ +#define SRST_P_SPI2AHB 173 +#define SRST_H_SPI2AHB 174 +#define SRST_H_FSPI1 175 +#define SRST_H_XIP_FSPI1 176 +#define SRST_S_1X_FSPI1 177 +#define SRST_P_IOC_PMUIO1 178 +#define SRST_P_CRU_PMU1 179 +#define SRST_P_AUDIO_ADC_PMU 180 +#define SRST_M_AUDIO_ADC_PMU 181 +#define SRST_H_PMU1_BIU 182 + +/* PMU1CRU-->SOFTRST_CON01 */ +#define SRST_P_LPDMA 183 +#define SRST_A_LPDMA 184 +#define SRST_H_LPSAI 185 +#define SRST_M_LPSAI 186 +#define SRST_P_AOA_TDD 187 +#define SRST_P_AOA_FE 188 +#define SRST_P_AOA_AAD 189 +#define SRST_P_AOA_APB 190 +#define SRST_P_AOA_SRAM 191 + +/* DDRCRU-->SOFTRST_CON00 */ +#define SRST_P_DDR_BIU 192 +#define SRST_P_DDRC 193 +#define SRST_P_DDRMON 194 +#define SRST_TIMER_DDRMON 195 +#define SRST_P_DFICTRL 196 +#define SRST_P_DDR_GRF 197 +#define SRST_P_CRU_DDR 198 +#define SRST_P_DDRPHY 199 +#define SRST_P_DMA2DDR 200 + +/* SUBDDRCRU-->SOFTRST_CON00 */ +#define SRST_A_SYSMEM_BIU 201 +#define SRST_A_SYSMEM 202 +#define SRST_A_DDR_BIU 203 +#define SRST_A_DDRSCH0_CPU 204 +#define SRST_A_DDRSCH1_NPU 205 +#define SRST_A_DDRSCH2_POE 206 +#define SRST_A_DDRSCH3_VI 207 +#define SRST_CORE_DDRC 208 +#define SRST_DDRMON 209 +#define SRST_DFICTRL 210 +#define SRST_RS 211 +#define SRST_A_DMA2DDR 212 +#define SRST_DDRPHY 213 + +/* VICRU-->SOFTRST_CON00 */ +#define SRST_REF_PVTPLL_ISP 214 +#define SRST_A_GMAC_BIU 215 +#define SRST_A_VI_BIU 216 +#define SRST_H_VI_BIU 217 +#define SRST_P_VI_BIU 218 +#define SRST_P_CRU_VI 219 +#define SRST_P_VI_GRF 220 +#define SRST_P_VI_PVTPLL 221 +#define SRST_P_DSMC 222 +#define SRST_A_DSMC 223 +#define SRST_H_CAN0 224 +#define SRST_CAN0 225 +#define SRST_H_CAN1 226 +#define SRST_CAN1 227 + +/* VICRU-->SOFTRST_CON01 */ +#define SRST_P_GPIO2 228 +#define SRST_DB_GPIO2 229 +#define SRST_P_GPIO4 230 +#define SRST_DB_GPIO4 231 +#define SRST_P_GPIO5 232 +#define SRST_DB_GPIO5 233 +#define SRST_P_GPIO6 234 +#define SRST_DB_GPIO6 235 +#define SRST_P_GPIO7 236 +#define SRST_DB_GPIO7 237 +#define SRST_P_IOC_VCCIO2 238 +#define SRST_P_IOC_VCCIO4 239 +#define SRST_P_IOC_VCCIO5 240 +#define SRST_P_IOC_VCCIO6 241 +#define SRST_P_IOC_VCCIO7 242 + +/* VICRU-->SOFTRST_CON02 */ +#define SRST_CORE_ISP 243 +#define SRST_H_VICAP 244 +#define SRST_A_VICAP 245 +#define SRST_D_VICAP 246 +#define SRST_ISP0_VICAP 247 +#define SRST_CORE_VPSS 248 +#define SRST_CORE_VPSL 249 +#define SRST_P_CSI2HOST0 250 +#define SRST_P_CSI2HOST1 251 +#define SRST_P_CSI2HOST2 252 +#define SRST_P_CSI2HOST3 253 +#define SRST_H_SDMMC0 254 +#define SRST_A_GMAC 255 +#define SRST_P_CSIPHY0 256 +#define SRST_P_CSIPHY1 257 + +/* VICRU-->SOFTRST_CON03 */ +#define SRST_P_MACPHY 258 +#define SRST_MACPHY 259 +#define SRST_P_SARADC1 260 +#define SRST_SARADC1 261 +#define SRST_P_SARADC2 262 +#define SRST_SARADC2 263 + +/* VEPUCRU-->SOFTRST_CON00 */ +#define SRST_REF_PVTPLL_VEPU 264 +#define SRST_A_VEPU_BIU 265 +#define SRST_H_VEPU_BIU 266 +#define SRST_P_VEPU_BIU 267 +#define SRST_P_CRU_VEPU 268 +#define SRST_P_VEPU_GRF 269 +#define SRST_P_GPIO3 270 +#define SRST_DB_GPIO3 271 +#define SRST_P_IOC_VCCIO3 272 +#define SRST_P_SARADC0 273 +#define SRST_SARADC0 274 +#define SRST_H_SDMMC1 275 + +/* VEPUCRU-->SOFTRST_CON01 */ +#define SRST_P_VEPU_PVTPLL 276 +#define SRST_H_VEPU 277 +#define SRST_A_VEPU 278 +#define SRST_CORE_VEPU 279 + +/* NPUCRU-->SOFTRST_CON00 */ +#define SRST_REF_PVTPLL_NPU 280 +#define SRST_A_NPU_BIU 281 +#define SRST_H_NPU_BIU 282 +#define SRST_P_NPU_BIU 283 +#define SRST_P_CRU_NPU 284 +#define SRST_P_NPU_GRF 285 +#define SRST_P_NPU_PVTPLL 286 +#define SRST_H_RKNN 287 +#define SRST_A_RKNN 288 + +/* VDOCRU-->SOFTRST_CON00 */ +#define SRST_A_RKVDEC_BIU 289 +#define SRST_A_VDO_BIU 290 +#define SRST_H_VDO_BIU 291 +#define SRST_P_VDO_BIU 292 +#define SRST_P_CRU_VDO 293 +#define SRST_P_VDO_GRF 294 +#define SRST_A_RKVDEC 295 +#define SRST_H_RKVDEC 296 +#define SRST_HEVC_CA_RKVDEC 297 +#define SRST_A_VOP 298 +#define SRST_H_VOP 299 +#define SRST_D_VOP 300 +#define SRST_A_OOC 301 +#define SRST_H_OOC 302 +#define SRST_D_OOC 303 + +/* VDOCRU-->SOFTRST_CON01 */ +#define SRST_H_RKJPEG 304 +#define SRST_A_RKJPEG 305 +#define SRST_A_RKMMU_DECOM 306 +#define SRST_H_RKMMU_DECOM 307 +#define SRST_D_DECOM 308 +#define SRST_A_DECOM 309 +#define SRST_P_DECOM 310 +#define SRST_P_MIPI_DSI 311 +#define SRST_P_DSIPHY 312 + +/* VCPCRU-->SOFTRST_CON00 */ +#define SRST_REF_PVTPLL_VCP 313 +#define SRST_A_VCP_BIU 314 +#define SRST_H_VCP_BIU 315 +#define SRST_P_VCP_BIU 316 +#define SRST_P_CRU_VCP 317 +#define SRST_P_VCP_GRF 318 +#define SRST_P_VCP_PVTPLL 319 +#define SRST_A_AISP_BIU 320 +#define SRST_H_AISP_BIU 321 +#define SRST_CORE_AISP 322 + +/* VCPCRU-->SOFTRST_CON01 */ +#define SRST_H_FEC 323 +#define SRST_A_FEC 324 +#define SRST_CORE_FEC 325 +#define SRST_H_AVSP 326 +#define SRST_A_AVSP 327 + +#endif From 652c108cc44cd961b58b2998ff429f11ee60c9fd Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Tue, 11 Nov 2025 10:57:36 +0800 Subject: [PATCH 105/117] clk: rockchip: Add clock controller for the RV1126B Add the clock and reset tree definitions for the new rv1126b SoC. Signed-off-by: Elaine Zhang Link: https://patch.msgid.link/20251111025738.869847-4-zhangqing@rock-chips.com Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/Kconfig | 7 + drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk-rv1126b.c | 1117 ++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 68 ++ drivers/clk/rockchip/rst-rv1126b.c | 443 +++++++++++ 5 files changed, 1636 insertions(+) create mode 100644 drivers/clk/rockchip/clk-rv1126b.c create mode 100644 drivers/clk/rockchip/rst-rv1126b.c diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig index febb7944f34b..e1ea0a098ca9 100644 --- a/drivers/clk/rockchip/Kconfig +++ b/drivers/clk/rockchip/Kconfig @@ -30,6 +30,13 @@ config CLK_RV1126 help Build the driver for RV1126 Clock Driver. +config CLK_RV1126B + bool "Rockchip RV1126B clock controller support" + depends on ARM64 || COMPILE_TEST + default y + help + Build the driver for RV1126B Clock Driver. + config CLK_RK3036 bool "Rockchip RK3036 clock controller support" depends on ARM || COMPILE_TEST diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index c281a9738d9f..82b4b29ad036 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -20,6 +20,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-$(CONFIG_CLK_PX30) += clk-px30.o obj-$(CONFIG_CLK_RV110X) += clk-rv1108.o obj-$(CONFIG_CLK_RV1126) += clk-rv1126.o +obj-$(CONFIG_CLK_RV1126B) += clk-rv1126b.o rst-rv1126b.o obj-$(CONFIG_CLK_RK3036) += clk-rk3036.o obj-$(CONFIG_CLK_RK312X) += clk-rk3128.o obj-$(CONFIG_CLK_RK3188) += clk-rk3188.o diff --git a/drivers/clk/rockchip/clk-rv1126b.c b/drivers/clk/rockchip/clk-rv1126b.c new file mode 100644 index 000000000000..3e27bfc14854 --- /dev/null +++ b/drivers/clk/rockchip/clk-rv1126b.c @@ -0,0 +1,1117 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + * Author: Elaine Zhang + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define RV1126B_FRAC_MAX_PRATE 1200000000 + +#define PVTPLL_SRC_SEL_PVTPLL (BIT(0) | BIT(16)) + +enum rv1126b_plls { + gpll, cpll, aupll, dpll +}; + +static struct rockchip_pll_rate_table rv1126b_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137), + RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355), + RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127), + RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185), + { /* sentinel */ }, +}; + +#define RV1126B_DIV_ACLK_CORE_MASK 0x1f +#define RV1126B_DIV_ACLK_CORE_SHIFT 0 +#define RV1126B_DIV_PCLK_CORE_MASK 0x1f +#define RV1126B_DIV_PCLK_CORE_SHIFT 8 +#define RV1126B_CORE_SEL_MASK 0x1 +#define RV1126B_CORE_SEL_SHIFT 1 + +#define RV1126B_CLKSEL0(_aclk_core) \ +{ \ + .reg = RV1126B_CORECLKSEL_CON(2), \ + .val = HIWORD_UPDATE(_aclk_core - 1, RV1126B_DIV_ACLK_CORE_MASK, \ + RV1126B_DIV_ACLK_CORE_SHIFT), \ +} + +#define RV1126B_CLKSEL1(_pclk_dbg) \ +{ \ + .reg = RV1126B_CORECLKSEL_CON(2), \ + .val = HIWORD_UPDATE(_pclk_dbg - 1, RV1126B_DIV_PCLK_CORE_MASK, \ + RV1126B_DIV_PCLK_CORE_SHIFT), \ +} + +#define RV1126B_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \ +{ \ + .prate = _prate, \ + .divs = { \ + RV1126B_CLKSEL0(_aclk_core), \ + RV1126B_CLKSEL1(_pclk_dbg), \ + }, \ +} + +static struct rockchip_cpuclk_rate_table rv1126b_cpuclk_rates[] __initdata = { + RV1126B_CPUCLK_RATE(1608000000, 4, 10), + RV1126B_CPUCLK_RATE(1512000000, 4, 10), + RV1126B_CPUCLK_RATE(1416000000, 4, 10), + RV1126B_CPUCLK_RATE(1296000000, 3, 10), + RV1126B_CPUCLK_RATE(1200000000, 3, 10), + RV1126B_CPUCLK_RATE(1188000000, 3, 8), + RV1126B_CPUCLK_RATE(1104000000, 2, 8), + RV1126B_CPUCLK_RATE(1008000000, 2, 8), + RV1126B_CPUCLK_RATE(816000000, 2, 6), + RV1126B_CPUCLK_RATE(600000000, 2, 4), + RV1126B_CPUCLK_RATE(594000000, 2, 4), + RV1126B_CPUCLK_RATE(408000000, 1, 3), + RV1126B_CPUCLK_RATE(396000000, 1, 3), +}; + +PNAME(mux_pll_p) = { "xin24m" }; +PNAME(mux_gpll_cpll_p) = { "gpll", "cpll" }; +PNAME(mux_gpll_aupll_p) = { "gpll", "aupll" }; +PNAME(mux_gpll_aupll_cpll_p) = { "gpll", "aupll", "cpll" }; +PNAME(mux_gpll_cpll_24m_p) = { "gpll", "cpll", "xin24m" }; +PNAME(mux_cpll_24m_p) = { "cpll", "xin24m" }; +PNAME(mux_24m_gpll_aupll_cpll_p) = { "xin24m", "gpll", "aupll", "cpll" }; +PNAME(mux_24m_gpll_cpll_p) = { "xin24m", "gpll", "cpll" }; +PNAME(mux_24m_gpll_aupll_p) = { "xin24m", "gpll", "aupll" }; +PNAME(mux_sclk_uart_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_uart_frac0", "clk_uart_frac1" }; +PNAME(mclk_sai0_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_audio_frac0", "clk_audio_frac1", + "clk_audio_int0", "clk_audio_int1", + "mclk_sai0_from_io" }; +PNAME(mclk_sai1_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_audio_frac0", "clk_audio_frac1", + "clk_audio_int0", "clk_audio_int1", + "mclk_sai1_from_io" }; +PNAME(mclk_sai2_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_audio_frac0", "clk_audio_frac1", + "clk_audio_int0", "clk_audio_int1", + "mclk_sai2_from_io" }; +PNAME(mux_sai_src_p) = { "xin24m", "clk_cm_frac0", "clk_cm_frac1", + "clk_cm_frac2", "clk_audio_frac0", "clk_audio_frac1", + "clk_audio_int0", "clk_audio_int1", "mclk_sai0_from_io", + "mclk_sai1_from_io", "mclk_sai2_from_io"}; +PNAME(mux_100m_24m_p) = { "clk_cpll_div10", "xin24m" }; +PNAME(mux_200m_24m_p) = { "clk_gpll_div6", "xin24m" }; +PNAME(mux_500m_400m_200m_p) = { "clk_cpll_div2", "clk_gpll_div3", "clk_gpll_div6" }; +PNAME(mux_300m_200m_p) = { "clk_gpll_div4", "clk_gpll_div6" }; +PNAME(mux_500m_400m_300m_p) = { "clk_cpll_div2", "clk_gpll_div3", "clk_gpll_div4" }; +PNAME(mux_333m_200m_p) = { "clk_cpll_div3", "clk_gpll_div6" }; +PNAME(mux_600m_400m_200m_p) = { "clk_gpll_div2", "clk_gpll_div3", "clk_gpll_div6" }; +PNAME(mux_400m_300m_200m_p) = { "clk_gpll_div3", "clk_gpll_div4", "clk_gpll_div6" }; +PNAME(mux_200m_100m_p) = { "clk_gpll_div6", "clk_cpll_div10" }; +PNAME(mux_200m_100m_50m_24m_p) = { "clk_gpll_div6", "clk_cpll_div10", "clk_cpll_div20", + "xin24m" }; +PNAME(mux_600m_24m_p) = { "clk_gpll_div2", "xin24m" }; +PNAME(mux_armclk_p) = { "clk_core_pll", "clk_core_pvtpll" }; +PNAME(aclk_npu_root_p) = { "clk_npu_pll", "clk_npu_pvtpll" }; +PNAME(clk_saradc0_p) = { "clk_saradc0_src", "clk_saradc0_rcosc_io" }; +PNAME(clk_core_vepu_p) = { "clk_vepu_pll", "clk_vepu_pvtpll" }; +PNAME(clk_core_fec_p) = { "clk_core_fec_src", "clk_vcp_pvtpll" }; +PNAME(clk_core_aisp_p) = { "clk_aisp_pll", "clk_vcp_pvtpll" }; +PNAME(clk_core_isp_root_p) = { "clk_isp_pll", "clk_isp_pvtpll" }; +PNAME(clk_gmac_ptp_ref_p) = { "clk_gmac_ptp_ref_src", "clk_gmac_ptp_from_io" }; +PNAME(clk_saradc1_p) = { "clk_saradc1_src", "clk_saradc1_rcosc_io" }; +PNAME(clk_saradc2_p) = { "clk_saradc2_src", "clk_saradc2_rcosc_io" }; +PNAME(clk_rcosc_src_p) = { "xin24m", "clk_rcosc", "clk_rcosc_div2", + "clk_rcosc_div3", "clk_rcosc_div4" }; +PNAME(busclk_pmu_mux_p) = { "clk_cpll_div10", "clk_rcosc_src" }; +PNAME(clk_xin_rc_div_p) = { "xin24m", "clk_rcosc_src" }; +PNAME(clk_32k_p) = { "clk_xin_rc_div", "clk_32k_rtc", "clk_32k_io" }; +PNAME(mux_24m_32k_p) = { "xin24m", "clk_32k" }; +PNAME(mux_24m_rcosc_buspmu_p) = { "xin24m", "clk_rcosc_src", "busclk_pmu_src" }; +PNAME(mux_24m_rcosc_buspmu_32k_p) = { "xin24m", "clk_rcosc_src", "busclk_pmu_src", + "clk_32k" }; +PNAME(sclk_uart0_p) = { "sclk_uart0_src", "xin24m", "clk_rcosc_src" }; +PNAME(clk_osc_rcosc_ctrl_p) = { "clk_rcosc_src", "clk_testout_out" }; +PNAME(lrck_src_asrc_p) = { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", + "fs_inter_from_sai0", "fs_inter_from_sai1", + "fs_inter_from_sai2", "clkout_pdm"}; +PNAME(clk_ref_pipephy_p) = { "clk_ref_pipephy_cpll_src", "xin24m" }; +PNAME(clk_timer0_parents_p) = { "clk_timer_root", "mclk_sai0_from_io", + "sclk_sai0_from_io" }; +PNAME(clk_timer1_parents_p) = { "clk_timer_root", "mclk_sai1_from_io", + "sclk_sai1_from_io" }; +PNAME(clk_timer2_parents_p) = { "clk_timer_root", "mclk_sai2_from_io", + "sclk_sai2_from_io" }; +PNAME(clk_timer3_parents_p) = { "clk_timer_root", "mclk_asrc0", "mclk_asrc1" }; +PNAME(clk_timer4_parents_p) = { "clk_timer_root", "mclk_asrc2", "mclk_asrc3" }; +PNAME(clk_macphy_p) = { "xin24m", "clk_cpll_div20" }; +PNAME(clk_cpll_div10_p) = { "gpll", "clk_aisp_pll_src" }; + +static struct rockchip_pll_clock rv1126b_pll_clks[] __initdata = { + [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p, + CLK_IS_CRITICAL, RV1126B_PLL_CON(8), + RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates), + [aupll] = PLL(pll_rk3328, PLL_AUPLL, "aupll", mux_pll_p, + CLK_IS_CRITICAL, RV1126B_PLL_CON(0), + RV1126B_MODE_CON, 0, 10, 0, rv1126b_pll_rates), + [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p, + CLK_IS_CRITICAL, RV1126B_PERIPLL_CON(0), + RV1126B_MODE_CON, 4, 10, 0, rv1126b_pll_rates), + [dpll] = PLL(pll_rk3328, 0, "dpll", mux_pll_p, + CLK_IS_CRITICAL, RV1126B_SUBDDRPLL_CON(0), + RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates), +}; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_clk_branch rv1126b_rcdiv_pmu_fracmux __initdata = + MUX(CLK_32K, "clk_32k", clk_32k_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + RV1126B_PMUCLKSEL_CON(2), 1, 2, MFLAGS); + +static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = { + + FACTOR(0, "clk_rcosc_div2", "clk_rcosc", 0, 1, 2), + FACTOR(0, "clk_rcosc_div3", "clk_rcosc", 0, 1, 3), + FACTOR(0, "clk_rcosc_div4", "clk_rcosc", 0, 1, 4), + + /* Clock Definition */ + COMPOSITE_NODIV(CLK_AISP_PLL_SRC, "clk_aisp_pll_src", mux_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(62), 4, 2, MFLAGS, + RV1126B_CLKGATE_CON(5), 4, GFLAGS), + DIV(CLK_AISP_PLL, "clk_aisp_pll", "clk_aisp_pll_src", 0, + RV1126B_CLKSEL_CON(62), 0, 3, DFLAGS), + + COMPOSITE(CLK_CPLL_DIV10, "clk_cpll_div10", clk_cpll_div10_p, 0, + RV1126B_CLKSEL_CON(1), 15, 1, MFLAGS, 5, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NOMUX(CLK_CPLL_DIV20, "clk_cpll_div20", "cpll", 0, + RV1126B_CLKSEL_CON(1), 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NOMUX(CLK_CPLL_DIV8, "clk_cpll_div8", "cpll", 0, + RV1126B_CLKSEL_CON(1), 10, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV8, "clk_gpll_div8", "gpll", 0, + RV1126B_CLKSEL_CON(2), 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV6, "clk_gpll_div6", "gpll", 0, + RV1126B_CLKSEL_CON(2), 5, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV4, "clk_gpll_div4", "gpll", 0, + RV1126B_CLKSEL_CON(2), 10, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE_NOMUX(CLK_CPLL_DIV3, "clk_cpll_div3", "cpll", 0, + RV1126B_CLKSEL_CON(3), 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 6, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV3, "clk_gpll_div3", "gpll", 0, + RV1126B_CLKSEL_CON(3), 5, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 7, GFLAGS), + COMPOSITE_NOMUX(CLK_CPLL_DIV2, "clk_cpll_div2", "cpll", 0, + RV1126B_CLKSEL_CON(3), 10, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV2, "clk_gpll_div2", "gpll", 0, + RV1126B_CLKSEL_CON(4), 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(0), 9, GFLAGS), + MUX(CLK_CM_FRAC0_SRC, "clk_cm_frac0_src", mux_24m_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 0, 2, MFLAGS), + COMPOSITE_FRAC(CLK_CM_FRAC0, "clk_cm_frac0", "clk_cm_frac0_src", 0, + RV1126B_CLKSEL_CON(25), 0, + RV1126B_CLKGATE_CON(1), 0, GFLAGS), + MUX(CLK_CM_FRAC1_SRC, "clk_cm_frac1_src", mux_24m_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 2, 2, MFLAGS), + COMPOSITE_FRAC(CLK_CM_FRAC1, "clk_cm_frac1", "clk_cm_frac1_src", 0, + RV1126B_CLKSEL_CON(26), 0, + RV1126B_CLKGATE_CON(1), 1, GFLAGS), + MUX(CLK_CM_FRAC2_SRC, "clk_cm_frac2_src", mux_24m_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 4, 2, MFLAGS), + COMPOSITE_FRAC(CLK_CM_FRAC2, "clk_cm_frac2", "clk_cm_frac2_src", 0, + RV1126B_CLKSEL_CON(27), 0, + RV1126B_CLKGATE_CON(1), 2, GFLAGS), + MUX(CLK_UART_FRAC0_SRC, "clk_uart_frac0_src", mux_24m_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 6, 2, MFLAGS), + COMPOSITE_FRAC(CLK_UART_FRAC0, "clk_uart_frac0", "clk_uart_frac0_src", 0, + RV1126B_CLKSEL_CON(28), 0, + RV1126B_CLKGATE_CON(1), 3, GFLAGS), + MUX(CLK_UART_FRAC1_SRC, "clk_uart_frac1_src", mux_24m_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(10), 8, 2, MFLAGS), + COMPOSITE_FRAC(CLK_UART_FRAC1, "clk_uart_frac1", "clk_uart_frac1_src", 0, + RV1126B_CLKSEL_CON(29), 0, + RV1126B_CLKGATE_CON(1), 4, GFLAGS), + MUX(CLK_AUDIO_FRAC0_SRC, "clk_audio_frac0_src", mux_24m_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(10), 10, 2, MFLAGS), + COMPOSITE_FRAC(CLK_AUDIO_FRAC0, "clk_audio_frac0", "clk_audio_frac0_src", 0, + RV1126B_CLKSEL_CON(30), 0, + RV1126B_CLKGATE_CON(1), 5, GFLAGS), + MUX(CLK_AUDIO_FRAC1_SRC, "clk_audio_frac1_src", mux_24m_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(10), 12, 2, MFLAGS), + COMPOSITE_FRAC(CLK_AUDIO_FRAC1, "clk_audio_frac1", "clk_audio_frac1_src", 0, + RV1126B_CLKSEL_CON(31), 0, + RV1126B_CLKGATE_CON(1), 6, GFLAGS), + COMPOSITE(CLK_AUDIO_INT0, "clk_audio_int0", mux_24m_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 7, GFLAGS), + COMPOSITE(CLK_AUDIO_INT1, "clk_audio_int1", mux_24m_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 8, GFLAGS), + COMPOSITE(SCLK_UART0_SRC, "sclk_uart0_src", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(12), 5, 3, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 9, GFLAGS), + COMPOSITE(SCLK_UART1, "sclk_uart1", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(12), 13, 3, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 10, GFLAGS), + COMPOSITE(SCLK_UART2, "sclk_uart2", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(13), 5, 3, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 11, GFLAGS), + COMPOSITE(SCLK_UART3, "sclk_uart3", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(13), 13, 3, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 12, GFLAGS), + COMPOSITE(SCLK_UART4, "sclk_uart4", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(14), 5, 3, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 13, GFLAGS), + COMPOSITE(SCLK_UART5, "sclk_uart5", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(14), 13, 3, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(1), 14, GFLAGS), + COMPOSITE(SCLK_UART6, "sclk_uart6", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(15), 5, 3, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 0, GFLAGS), + COMPOSITE(SCLK_UART7, "sclk_uart7", mux_sclk_uart_src_p, 0, + RV1126B_CLKSEL_CON(15), 13, 3, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 1, GFLAGS), + COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai0_src_p, 0, + RV1126B_CLKSEL_CON(16), 8, 4, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(2), 2, GFLAGS), + COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai1_src_p, 0, + RV1126B_CLKSEL_CON(17), 8, 4, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(2), 3, GFLAGS), + COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai2_src_p, 0, + RV1126B_CLKSEL_CON(18), 8, 4, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(2), 4, GFLAGS), + COMPOSITE(MCLK_PDM, "mclk_pdm", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(19), 6, 4, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 5, GFLAGS), + COMPOSITE_NOGATE(0, "clkout_pdm_src", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(20), 8, 4, MFLAGS, 0, 8, DFLAGS), + GATE(CLKOUT_PDM, "clkout_pdm", "clkout_pdm_src", 0, + RV1126B_CLKGATE_CON(2), 6, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(16), 12, 4, MFLAGS, + RV1126B_CLKGATE_CON(2), 7, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(17), 12, 4, MFLAGS, + RV1126B_CLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(18), 12, 4, MFLAGS, + RV1126B_CLKGATE_CON(2), 9, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mux_sai_src_p, 0, + RV1126B_CLKSEL_CON(19), 12, 4, MFLAGS, + RV1126B_CLKGATE_CON(2), 10, GFLAGS), + COMPOSITE(CLK_ASRC0, "clk_asrc0", mux_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(21), 6, 1, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 11, GFLAGS), + COMPOSITE(CLK_ASRC1, "clk_asrc1", mux_gpll_aupll_p, 0, + RV1126B_CLKSEL_CON(21), 14, 1, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(2), 12, GFLAGS), + COMPOSITE_NOMUX(CLK_CORE_PLL, "clk_core_pll", "gpll", CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(60), 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 0, GFLAGS), + COMPOSITE_NOMUX(CLK_NPU_PLL, "clk_npu_pll", "gpll", CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(60), 6, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 1, GFLAGS), + COMPOSITE(CLK_VEPU_PLL, "clk_vepu_pll", mux_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(61), 4, 2, MFLAGS, 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 2, GFLAGS), + COMPOSITE(CLK_ISP_PLL, "clk_isp_pll", mux_gpll_aupll_cpll_p, 0, + RV1126B_CLKSEL_CON(61), 10, 2, MFLAGS, 6, 4, DFLAGS, + RV1126B_CLKGATE_CON(5), 3, GFLAGS), + COMPOSITE(CLK_SARADC0_SRC, "clk_saradc0_src", mux_200m_24m_p, 0, + RV1126B_CLKSEL_CON(63), 12, 1, MFLAGS, 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 6, GFLAGS), + COMPOSITE(CLK_SARADC1_SRC, "clk_saradc1_src", mux_200m_24m_p, 0, + RV1126B_CLKSEL_CON(63), 13, 1, MFLAGS, 4, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 7, GFLAGS), + COMPOSITE(CLK_SARADC2_SRC, "clk_saradc2_src", mux_200m_24m_p, 0, + RV1126B_CLKSEL_CON(63), 14, 1, MFLAGS, 8, 3, DFLAGS, + RV1126B_CLKGATE_CON(5), 8, GFLAGS), + GATE(HCLK_RKNN, "hclk_rknn", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(5), 10, GFLAGS), + GATE(PCLK_NPU_ROOT, "pclk_npu_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(5), 11, GFLAGS), + COMPOSITE_NODIV(ACLK_VEPU_ROOT, "aclk_vepu_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(40), 0, 2, MFLAGS, + RV1126B_CLKGATE_CON(5), 12, GFLAGS), + GATE(HCLK_VEPU_ROOT, "hclk_vepu_root", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(5), 13, GFLAGS), + GATE(PCLK_VEPU_ROOT, "pclk_vepu_root", "clk_cpll_div10", 0, + RV1126B_CLKGATE_CON(5), 14, GFLAGS), + COMPOSITE(CLK_CORE_RGA_SRC, "clk_core_rga_src", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(40), 5, 1, MFLAGS, 2, 3, DFLAGS, + RV1126B_CLKGATE_CON(6), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_GMAC_ROOT, "aclk_gmac_root", mux_300m_200m_p, 0, + RV1126B_CLKSEL_CON(40), 6, 1, MFLAGS, + RV1126B_CLKGATE_CON(6), 1, GFLAGS), + COMPOSITE_NODIV(ACLK_VI_ROOT, "aclk_vi_root", mux_500m_400m_300m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(40), 7, 2, MFLAGS, + RV1126B_CLKGATE_CON(6), 2, GFLAGS), + GATE(HCLK_VI_ROOT, "hclk_vi_root", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(6), 3, GFLAGS), + GATE(PCLK_VI_ROOT, "pclk_vi_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(6), 4, GFLAGS), + COMPOSITE_NODIV(DCLK_VICAP_ROOT, "dclk_vicap_root", mux_333m_200m_p, 0, + RV1126B_CLKSEL_CON(42), 5, 1, MFLAGS, + RV1126B_CLKGATE_CON(6), 5, GFLAGS), + COMPOSITE(CLK_SYS_DSMC_ROOT, "clk_sys_dsmc_root", mux_24m_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(40), 14, 2, MFLAGS, 9, 5, DFLAGS, + RV1126B_CLKGATE_CON(6), 6, GFLAGS), + COMPOSITE(ACLK_VDO_ROOT, "aclk_vdo_root", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(42), 4, 1, MFLAGS, 0, 4, DFLAGS, + RV1126B_CLKGATE_CON(6), 7, GFLAGS), + COMPOSITE(ACLK_RKVDEC_ROOT, "aclk_rkvdec_root", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(42), 10, 1, MFLAGS, 6, 4, DFLAGS, + RV1126B_CLKGATE_CON(6), 8, GFLAGS), + GATE(HCLK_VDO_ROOT, "hclk_vdo_root", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(6), 9, GFLAGS), + GATE(PCLK_VDO_ROOT, "pclk_vdo_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(6), 10, GFLAGS), + COMPOSITE(DCLK_VOP, "dclk_vop", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(43), 8, 1, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(6), 12, GFLAGS), + COMPOSITE(DCLK_OOC_SRC, "dclk_ooc_src", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(62), 7, 1, MFLAGS, 8, 8, DFLAGS, + RV1126B_CLKGATE_CON(6), 13, GFLAGS), + GATE(DCLK_DECOM_SRC, "dclk_decom_src", "clk_gpll_div3", 0, + RV1126B_CLKGATE_CON(6), 14, GFLAGS), + GATE(PCLK_DDR_ROOT, "pclk_ddr_root", "clk_cpll_div10", 0, + RV1126B_CLKGATE_CON(7), 0, GFLAGS), + COMPOSITE(ACLK_SYSMEM, "aclk_sysmem", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(44), 3, 1, MFLAGS, 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(7), 1, GFLAGS), + COMPOSITE_NODIV(ACLK_TOP_ROOT, "aclk_top_root", mux_600m_400m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(44), 6, 2, MFLAGS, + RV1126B_CLKGATE_CON(7), 3, GFLAGS), + COMPOSITE_NODIV(ACLK_BUS_ROOT, "aclk_bus_root", mux_400m_300m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(44), 8, 2, MFLAGS, + RV1126B_CLKGATE_CON(7), 4, GFLAGS), + COMPOSITE_NODIV(HCLK_BUS_ROOT, "hclk_bus_root", mux_200m_100m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(44), 10, 1, MFLAGS, + RV1126B_CLKGATE_CON(7), 5, GFLAGS), + GATE(PCLK_BUS_ROOT, "pclk_bus_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(7), 6, GFLAGS), + COMPOSITE(CCLK_SDMMC0, "cclk_sdmmc0", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(45), 8, 2, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(7), 7, GFLAGS), + COMPOSITE(CCLK_SDMMC1, "cclk_sdmmc1", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(46), 8, 2, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(7), 8, GFLAGS), + COMPOSITE(CCLK_EMMC, "cclk_emmc", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(47), 8, 2, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(7), 9, GFLAGS), + COMPOSITE(SCLK_2X_FSPI0, "sclk_2x_fspi0", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(48), 8, 2, MFLAGS, 0, 8, DFLAGS, + RV1126B_CLKGATE_CON(7), 10, GFLAGS), + COMPOSITE(CLK_GMAC_PTP_REF_SRC, "clk_gmac_ptp_ref_src", mux_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(45), 10, 1, MFLAGS, 11, 5, DFLAGS, + RV1126B_CLKGATE_CON(7), 11, GFLAGS), + GATE(CLK_GMAC_125M, "clk_gmac_125m", "clk_cpll_div8", 0, + RV1126B_CLKGATE_CON(7), 12, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER_ROOT, "clk_timer_root", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(46), 11, 1, MFLAGS, + RV1126B_CLKGATE_CON(7), 13, GFLAGS), + COMPOSITE_NODIV(TCLK_WDT_NS_SRC, "tclk_wdt_ns_src", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(46), 12, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 0, GFLAGS), + COMPOSITE_NODIV(TCLK_WDT_S_SRC, "tclk_wdt_s_src", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(46), 13, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 1, GFLAGS), + COMPOSITE_NODIV(TCLK_WDT_HPMCU, "tclk_wdt_hpmcu", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(46), 14, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 2, GFLAGS), + COMPOSITE(CLK_CAN0, "clk_can0", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(8), 4, GFLAGS), + COMPOSITE(CLK_CAN1, "clk_can1", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(49), 14, 2, MFLAGS, 8, 5, DFLAGS, + RV1126B_CLKGATE_CON(8), 5, GFLAGS), + COMPOSITE_NODIV(PCLK_PERI_ROOT, "pclk_peri_root", mux_100m_24m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(47), 12, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 6, GFLAGS), + COMPOSITE_NODIV(ACLK_PERI_ROOT, "aclk_peri_root", mux_200m_24m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(47), 13, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 7, GFLAGS), + COMPOSITE_NODIV(CLK_I2C_BUS_SRC, "clk_i2c_bus_src", mux_200m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 1, 1, MFLAGS, + RV1126B_CLKGATE_CON(8), 9, GFLAGS), + COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 2, 2, MFLAGS, + RV1126B_CLKGATE_CON(8), 10, GFLAGS), + COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 4, 2, MFLAGS, + RV1126B_CLKGATE_CON(8), 11, GFLAGS), + GATE(BUSCLK_PMU_SRC, "busclk_pmu_src", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(8), 12, GFLAGS), + COMPOSITE_NODIV(CLK_PWM0, "clk_pwm0", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 8, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 0, GFLAGS), + COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 10, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 2, GFLAGS), + COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", mux_100m_24m_p, 0, + RV1126B_CLKSEL_CON(50), 11, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 3, GFLAGS), + COMPOSITE_NODIV(CLK_PKA_RKCE_SRC, "clk_pka_rkce_src", mux_300m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(50), 12, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 4, GFLAGS), + COMPOSITE_NODIV(ACLK_RKCE_SRC, "aclk_rkce_src", mux_200m_24m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(50), 13, 1, MFLAGS, + RV1126B_CLKGATE_CON(9), 5, GFLAGS), + COMPOSITE_NODIV(ACLK_VCP_ROOT, "aclk_vcp_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL, + RV1126B_CLKSEL_CON(48), 12, 2, MFLAGS, + RV1126B_CLKGATE_CON(9), 6, GFLAGS), + GATE(HCLK_VCP_ROOT, "hclk_vcp_root", "clk_gpll_div8", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(9), 7, GFLAGS), + GATE(PCLK_VCP_ROOT, "pclk_vcp_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(9), 8, GFLAGS), + COMPOSITE(CLK_CORE_FEC_SRC, "clk_core_fec_src", mux_gpll_cpll_p, 0, + RV1126B_CLKSEL_CON(51), 3, 1, MFLAGS, 0, 3, DFLAGS, + RV1126B_CLKGATE_CON(9), 9, GFLAGS), + GATE(CLK_50M_GMAC_IOBUF_VI, "clk_50m_gmac_iobuf_vi", "clk_cpll_div20", 0, + RV1126B_CLKGATE_CON(9), 11, GFLAGS), + GATE(PCLK_TOP_ROOT, "pclk_top_root", "clk_cpll_div10", CLK_IS_CRITICAL, + RV1126B_CLKGATE_CON(15), 0, GFLAGS), + COMPOSITE(CLK_MIPI0_OUT2IO, "clk_mipi0_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(67), 11, 1, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 3, GFLAGS), + COMPOSITE(CLK_MIPI1_OUT2IO, "clk_mipi1_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(67), 12, 1, MFLAGS, 6, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 4, GFLAGS), + COMPOSITE(CLK_MIPI2_OUT2IO, "clk_mipi2_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(68), 11, 1, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 5, GFLAGS), + COMPOSITE(CLK_MIPI3_OUT2IO, "clk_mipi3_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(68), 12, 1, MFLAGS, 6, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 6, GFLAGS), + COMPOSITE(CLK_CIF_OUT2IO, "clk_cif_out2io", mux_600m_24m_p, 0, + RV1126B_CLKSEL_CON(69), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1126B_CLKGATE_CON(15), 7, GFLAGS), + COMPOSITE(CLK_MAC_OUT2IO, "clk_mac_out2io", mux_gpll_cpll_24m_p, 0, + RV1126B_CLKSEL_CON(69), 6, 2, MFLAGS, 8, 7, DFLAGS, + RV1126B_CLKGATE_CON(15), 8, GFLAGS), + COMPOSITE_NOMUX(MCLK_SAI0_OUT2IO, "mclk_sai0_out2io", "mclk_sai0", CLK_SET_RATE_PARENT, + RV1126B_CLKSEL_CON(70), 0, 4, DFLAGS, + RV1126B_CLKGATE_CON(15), 9, GFLAGS), + COMPOSITE_NOMUX(MCLK_SAI1_OUT2IO, "mclk_sai1_out2io", "mclk_sai1", CLK_SET_RATE_PARENT, + RV1126B_CLKSEL_CON(70), 5, 4, DFLAGS, + RV1126B_CLKGATE_CON(15), 10, GFLAGS), + COMPOSITE_NOMUX(MCLK_SAI2_OUT2IO, "mclk_sai2_out2io", "mclk_sai2", CLK_SET_RATE_PARENT, + RV1126B_CLKSEL_CON(70), 10, 4, DFLAGS, + RV1126B_CLKGATE_CON(15), 11, GFLAGS), + + /* pd _npu */ + MUX(ACLK_RKNN, "aclk_rknn", aclk_npu_root_p, CLK_SET_RATE_PARENT, + RV1126B_NPUCLKSEL_CON(0), 1, 1, MFLAGS), + + /* pd_vepu */ + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(0), 7, GFLAGS), + GATE(DBCLK_GPIO3, "dbclk_gpio3", "xin24m", 0, + RV1126B_VEPUCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_IOC_VCCIO3, "pclk_ioc_vccio3", "pclk_vepu_root", CLK_IS_CRITICAL, + RV1126B_VEPUCLKGATE_CON(0), 9, GFLAGS), + GATE(PCLK_SARADC0, "pclk_saradc0", "pclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(0), 10, GFLAGS), + MUX(CLK_SARADC0, "clk_saradc0", clk_saradc0_p, CLK_SET_RATE_PARENT, + RV1126B_VEPUCLKSEL_CON(0), 2, 1, MFLAGS), + GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(0), 12, GFLAGS), + GATE(HCLK_VEPU, "hclk_vepu", "hclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(1), 1, GFLAGS), + GATE(ACLK_VEPU, "aclk_vepu", "aclk_vepu_root", 0, + RV1126B_VEPUCLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_VEPU, "clk_core_vepu", clk_core_vepu_p, CLK_SET_RATE_PARENT, + RV1126B_VEPUCLKSEL_CON(0), 1, 1, MFLAGS, + RV1126B_VEPUCLKGATE_CON(1), 3, GFLAGS), + + /* pd_vcp */ + GATE(HCLK_FEC, "hclk_fec", "hclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(1), 0, GFLAGS), + GATE(ACLK_FEC, "aclk_fec", "aclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(1), 1, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_FEC, "clk_core_fec", clk_core_fec_p, CLK_SET_RATE_PARENT, + RV1126B_VCPCLKSEL_CON(0), 13, 1, MFLAGS, + RV1126B_VCPCLKGATE_CON(1), 2, GFLAGS), + GATE(HCLK_AVSP, "hclk_avsp", "hclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(1), 3, GFLAGS), + GATE(ACLK_AVSP, "aclk_avsp", "aclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(1), 4, GFLAGS), + GATE(HCLK_AISP, "hclk_aisp", "hclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(0), 11, GFLAGS), + GATE(ACLK_AISP, "aclk_aisp", "aclk_vcp_root", 0, + RV1126B_VCPCLKGATE_CON(0), 12, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_AISP, "clk_core_aisp", clk_core_aisp_p, CLK_SET_RATE_PARENT, + RV1126B_VCPCLKSEL_CON(0), 15, 1, MFLAGS, + RV1126B_VCPCLKGATE_CON(0), 13, GFLAGS), + + /* pd_vi */ + MUX(CLK_CORE_ISP_ROOT, "clk_core_isp_root", clk_core_isp_root_p, CLK_SET_RATE_PARENT, + RV1126B_VICLKSEL_CON(0), 1, 1, MFLAGS), + GATE(PCLK_DSMC, "pclk_dsmc", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(0), 8, GFLAGS), + GATE(ACLK_DSMC, "aclk_dsmc", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(0), 9, GFLAGS), + GATE(HCLK_CAN0, "hclk_can0", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(0), 10, GFLAGS), + GATE(HCLK_CAN1, "hclk_can1", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(0), 11, GFLAGS), + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 0, GFLAGS), + GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 1, GFLAGS), + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 2, GFLAGS), + GATE(DBCLK_GPIO4, "dbclk_gpio4", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 4, GFLAGS), + GATE(DBCLK_GPIO5, "dbclk_gpio5", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 5, GFLAGS), + GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 6, GFLAGS), + GATE(DBCLK_GPIO6, "dbclk_gpio6", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 7, GFLAGS), + GATE(PCLK_GPIO7, "pclk_gpio7", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(1), 8, GFLAGS), + GATE(DBCLK_GPIO7, "dbclk_gpio7", "xin24m", 0, + RV1126B_VICLKGATE_CON(1), 9, GFLAGS), + GATE(PCLK_IOC_VCCIO2, "pclk_ioc_vccio2", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 10, GFLAGS), + GATE(PCLK_IOC_VCCIO4, "pclk_ioc_vccio4", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 11, GFLAGS), + GATE(PCLK_IOC_VCCIO5, "pclk_ioc_vccio5", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 12, GFLAGS), + GATE(PCLK_IOC_VCCIO6, "pclk_ioc_vccio6", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 13, GFLAGS), + GATE(PCLK_IOC_VCCIO7, "pclk_ioc_vccio7", "pclk_vi_root", CLK_IS_CRITICAL, + RV1126B_VICLKGATE_CON(1), 14, GFLAGS), + GATE(HCLK_ISP, "hclk_isp", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 0, GFLAGS), + GATE(ACLK_ISP, "aclk_isp", "aclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 1, GFLAGS), + GATE(CLK_CORE_ISP, "clk_core_isp", "clk_core_isp_root", 0, + RV1126B_VICLKGATE_CON(2), 2, GFLAGS), + GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 3, GFLAGS), + GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 4, GFLAGS), + GATE(DCLK_VICAP, "dclk_vicap", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(2), 5, GFLAGS), + GATE(ISP0CLK_VICAP, "isp0clk_vicap", "clk_core_isp_root", 0, + RV1126B_VICLKGATE_CON(2), 6, GFLAGS), + GATE(HCLK_VPSS, "hclk_vpss", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 7, GFLAGS), + GATE(ACLK_VPSS, "aclk_vpss", "aclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 8, GFLAGS), + GATE(CLK_CORE_VPSS, "clk_core_vpss", "clk_core_isp_root", 0, + RV1126B_VICLKGATE_CON(2), 9, GFLAGS), + GATE(HCLK_VPSL, "hclk_vpsl", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 10, GFLAGS), + GATE(ACLK_VPSL, "aclk_vpsl", "aclk_vi_root", 0, + RV1126B_VICLKGATE_CON(2), 11, GFLAGS), + GATE(CLK_CORE_VPSL, "clk_core_vpsl", "clk_core_isp_root", 0, + RV1126B_VICLKGATE_CON(2), 12, GFLAGS), + GATE(PCLK_CSI2HOST0, "pclk_csi2host0", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 0, GFLAGS), + GATE(DCLK_CSI2HOST0, "dclk_csi2host0", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(3), 1, GFLAGS), + GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 2, GFLAGS), + GATE(DCLK_CSI2HOST1, "dclk_csi2host1", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(3), 3, GFLAGS), + GATE(PCLK_CSI2HOST2, "pclk_csi2host2", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 4, GFLAGS), + GATE(DCLK_CSI2HOST2, "dclk_csi2host2", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(3), 5, GFLAGS), + GATE(PCLK_CSI2HOST3, "pclk_csi2host3", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 6, GFLAGS), + GATE(DCLK_CSI2HOST3, "dclk_csi2host3", "dclk_vicap_root", 0, + RV1126B_VICLKGATE_CON(3), 7, GFLAGS), + GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 8, GFLAGS), + GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_root", 0, + RV1126B_VICLKGATE_CON(3), 9, GFLAGS), + GATE(PCLK_GMAC, "pclk_gmac", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 10, GFLAGS), + MUX(CLK_GMAC_PTP_REF, "clk_gmac_ptp_ref", clk_gmac_ptp_ref_p, CLK_SET_RATE_PARENT, + RV1126B_VICLKSEL_CON(0), 14, 1, MFLAGS), + GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 11, GFLAGS), + GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 12, GFLAGS), + GATE(PCLK_MACPHY, "pclk_macphy", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(3), 13, GFLAGS), + GATE(PCLK_SARADC1, "pclk_saradc1", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(4), 0, GFLAGS), + MUX(CLK_SARADC1, "clk_saradc1", clk_saradc1_p, CLK_SET_RATE_PARENT, + RV1126B_VICLKSEL_CON(0), 2, 1, MFLAGS), + GATE(PCLK_SARADC2, "pclk_saradc2", "pclk_vi_root", 0, + RV1126B_VICLKGATE_CON(4), 2, GFLAGS), + MUX(CLK_SARADC2, "clk_saradc2", clk_saradc2_p, CLK_SET_RATE_PARENT, + RV1126B_VICLKSEL_CON(0), 3, 1, MFLAGS), + COMPOSITE_NODIV(CLK_MACPHY, "clk_macphy", clk_macphy_p, 0, + RV1126B_VICLKSEL_CON(1), 1, 1, MFLAGS, + RV1126B_VICLKGATE_CON(0), 12, GFLAGS), + + /* pd_vdo */ + GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_root", 0, + RV1126B_VDOCLKGATE_CON(0), 7, GFLAGS), + GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 8, GFLAGS), + GATE(CLK_HEVC_CA_RKVDEC, "clk_hevc_ca_rkvdec", "aclk_rkvdec_root", 0, + RV1126B_VDOCLKGATE_CON(0), 9, GFLAGS), + GATE(ACLK_VOP, "aclk_vop", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 10, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 11, GFLAGS), + GATE(ACLK_OOC, "aclk_ooc", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 13, GFLAGS), + GATE(HCLK_OOC, "hclk_ooc", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(0), 14, GFLAGS), + GATE(HCLK_RKJPEG, "hclk_rkjpeg", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 3, GFLAGS), + GATE(ACLK_RKJPEG, "aclk_rkjpeg", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 4, GFLAGS), + GATE(ACLK_RKMMU_DECOM, "aclk_rkmmu_decom", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 5, GFLAGS), + GATE(HCLK_RKMMU_DECOM, "hclk_rkmmu_decom", "hclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 6, GFLAGS), + GATE(DCLK_DECOM, "dclk_decom", "dclk_decom_src", 0, + RV1126B_VDOCLKGATE_CON(1), 8, GFLAGS), + GATE(ACLK_DECOM, "aclk_decom", "aclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 9, GFLAGS), + GATE(PCLK_DECOM, "pclk_decom", "pclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 10, GFLAGS), + GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 12, GFLAGS), + GATE(PCLK_DSIPHY, "pclk_dsiphy", "pclk_vdo_root", 0, + RV1126B_VDOCLKGATE_CON(1), 13, GFLAGS), + + /* pd_ddr */ + GATE(PCLK_DDRC, "pclk_ddrc", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 2, GFLAGS), + GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 3, GFLAGS), + GATE(CLK_TIMER_DDRMON, "clk_timer_ddrmon", "xin24m", 0, + RV1126B_DDRCLKGATE_CON(0), 4, GFLAGS), + GATE(PCLK_DFICTRL, "pclk_dfictrl", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 5, GFLAGS), + GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1126B_DDRCLKGATE_CON(0), 9, GFLAGS), + + /* pd_pmu*/ + COMPOSITE_NODIV(CLK_RCOSC_SRC, "clk_rcosc_src", clk_rcosc_src_p, 0, + RV1126B_PMUCLKSEL_CON(1), 0, 3, MFLAGS, + RV1126B_PMUCLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NOGATE(BUSCLK_PMU_MUX, "busclk_pmu_mux", busclk_pmu_mux_p, 0, + RV1126B_PMUCLKSEL_CON(1), 3, 1, MFLAGS, 4, 2, DFLAGS), + GATE(BUSCLK_PMU_ROOT, "busclk_pmu_root", "busclk_pmu_mux", 0, + RV1126B_PMUCLKGATE_CON(0), 1, GFLAGS), + GATE(BUSCLK_PMU1_ROOT, "busclk_pmu1_root", "busclk_pmu_mux", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(3), 11, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(0), 6, GFLAGS), + MUX(0, "xin_rc_src", clk_xin_rc_div_p, 0, + RV1126B_PMUCLKSEL_CON(2), 0, 1, MFLAGS), + COMPOSITE_FRACMUX_NOGATE(CLK_XIN_RC_DIV, "clk_xin_rc_div", "xin_rc_src", CLK_SET_RATE_PARENT, + RV1126B_PMUCLKSEL_CON(8), 0, + &rv1126b_rcdiv_pmu_fracmux), + GATE(PCLK_PMU_GPIO0, "pclk_pmu_gpio0", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(0), 7, GFLAGS), + COMPOSITE_NODIV(DBCLK_PMU_GPIO0, "dbclk_pmu_gpio0", mux_24m_32k_p, 0, + RV1126B_PMUCLKSEL_CON(2), 4, 1, MFLAGS, + RV1126B_PMUCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(0), 10, GFLAGS), + COMPOSITE(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", mux_cpll_24m_p, CLK_IS_CRITICAL, + RV1126B_PMUCLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS, + RV1126B_PMUCLKGATE_CON(0), 11, GFLAGS), + GATE(CLK_PMU_32K_HP_TIMER, "clk_pmu_32k_hp_timer", "clk_32k", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(0), 13, GFLAGS), + GATE(PCLK_PWM1, "pclk_pwm1", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(1), 0, GFLAGS), + COMPOSITE(CLK_PWM1, "clk_pwm1", mux_24m_rcosc_buspmu_p, 0, + RV1126B_PMUCLKSEL_CON(2), 8, 2, MFLAGS, 6, 2, DFLAGS, + RV1126B_PMUCLKGATE_CON(1), 1, GFLAGS), + GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0, + RV1126B_PMUCLKGATE_CON(1), 2, GFLAGS), + GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_32k", 0, + RV1126B_PMUCLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_I2C2, "pclk_i2c2", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(1), 6, GFLAGS), + COMPOSITE(CLK_I2C2, "clk_i2c2", mux_24m_rcosc_buspmu_p, 0, + RV1126B_PMUCLKSEL_CON(2), 14, 2, MFLAGS, 12, 2, DFLAGS, + RV1126B_PMUCLKGATE_CON(1), 7, GFLAGS), + GATE(PCLK_UART0, "pclk_uart0", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(1), 8, GFLAGS), + COMPOSITE_NODIV(SCLK_UART0, "sclk_uart0", sclk_uart0_p, CLK_SET_RATE_PARENT, + RV1126B_PMUCLKSEL_CON(3), 0, 2, MFLAGS, + RV1126B_PMUCLKGATE_CON(1), 11, GFLAGS), + GATE(PCLK_RCOSC_CTRL, "pclk_rcosc_ctrl", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(2), 0, GFLAGS), + COMPOSITE_NODIV(CLK_OSC_RCOSC_CTRL, "clk_osc_rcosc_ctrl", clk_osc_rcosc_ctrl_p, CLK_IS_CRITICAL, + RV1126B_PMUCLKSEL_CON(3), 2, 1, MFLAGS, + RV1126B_PMUCLKGATE_CON(2), 1, GFLAGS), + GATE(CLK_REF_RCOSC_CTRL, "clk_ref_rcosc_ctrl", "xin24m", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(2), 2, GFLAGS), + GATE(PCLK_IOC_PMUIO0, "pclk_ioc_pmuio0", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(2), 3, GFLAGS), + GATE(CLK_REFOUT, "clk_refout", "xin24m", 0, + RV1126B_PMUCLKGATE_CON(2), 6, GFLAGS), + GATE(CLK_PREROLL, "clk_preroll", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(2), 7, GFLAGS), + GATE(CLK_PREROLL_32K, "clk_preroll_32k", "clk_32k", 0, + RV1126B_PMUCLKGATE_CON(2), 8, GFLAGS), + GATE(HCLK_PMU_SRAM, "hclk_pmu_sram", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMUCLKGATE_CON(2), 9, GFLAGS), + GATE(PCLK_WDT_LPMCU, "pclk_wdt_lpmcu", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(3), 0, GFLAGS), + COMPOSITE_NODIV(TCLK_WDT_LPMCU, "tclk_wdt_lpmcu", mux_24m_rcosc_buspmu_32k_p, 0, + RV1126B_PMUCLKSEL_CON(3), 6, 2, MFLAGS, + RV1126B_PMUCLKGATE_CON(3), 1, GFLAGS), + GATE(CLK_LPMCU, "clk_lpmcu", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(3), 2, GFLAGS), + GATE(CLK_LPMCU_RTC, "clk_lpmcu_rtc", "xin24m", 0, + RV1126B_PMUCLKGATE_CON(3), 3, GFLAGS), + GATE(PCLK_LPMCU_MAILBOX, "pclk_lpmcu_mailbox", "busclk_pmu_root", 0, + RV1126B_PMUCLKGATE_CON(3), 4, GFLAGS), + + /* pd_pmu1 */ + GATE(PCLK_SPI2AHB, "pclk_spi2ahb", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 0, GFLAGS), + GATE(HCLK_SPI2AHB, "hclk_spi2ahb", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 1, GFLAGS), + GATE(HCLK_FSPI1, "hclk_fspi1", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 2, GFLAGS), + GATE(HCLK_XIP_FSPI1, "hclk_xip_fspi1", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE(SCLK_1X_FSPI1, "sclk_1x_fspi1", mux_24m_rcosc_buspmu_p, 0, + RV1126B_PMU1CLKSEL_CON(0), 0, 2, MFLAGS, 2, 3, DFLAGS, + RV1126B_PMU1CLKGATE_CON(0), 4, GFLAGS), + GATE(PCLK_IOC_PMUIO1, "pclk_ioc_pmuio1", "busclk_pmu_root", CLK_IS_CRITICAL, + RV1126B_PMU1CLKGATE_CON(0), 5, GFLAGS), + GATE(PCLK_AUDIO_ADC_PMU, "pclk_audio_adc_pmu", "busclk_pmu_root", 0, + RV1126B_PMU1CLKGATE_CON(0), 8, GFLAGS), + + COMPOSITE(MCLK_LPSAI, "mclk_lpsai", mux_24m_rcosc_buspmu_p, 0, + RV1126B_PMU1CLKSEL_CON(0), 6, 2, MFLAGS, 8, 5, DFLAGS, + RV1126B_PMU1CLKGATE_CON(1), 3, GFLAGS), + GATE(MCLK_AUDIO_ADC_PMU, "mclk_audio_adc_pmu", "mclk_lpsai", CLK_IS_CRITICAL, + RV1126B_PMU1CLKGATE_CON(0), 9, GFLAGS), + FACTOR(MCLK_AUDIO_ADC_DIV4_PMU, "mclk_audio_adc_div4_pmu", "mclk_audio_adc_pmu", 0, 1, 4), + + /* pd_bus */ + GATE(ACLK_GIC400, "aclk_gic400", "hclk_bus_root", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(0), 10, GFLAGS), + GATE(TCLK_WDT_NS, "tclk_wdt_ns", "tclk_wdt_ns_src", 0, + RV1126B_BUSCLKGATE_CON(0), 11, GFLAGS), + GATE(PCLK_WDT_HPMCU, "pclk_wdt_hpmcu", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 0, GFLAGS), + GATE(HCLK_CACHE, "hclk_cache", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 2, GFLAGS), + GATE(PCLK_HPMCU_MAILBOX, "pclk_hpmcu_mailbox", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_HPMCU_INTMUX, "pclk_hpmcu_intmux", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 4, GFLAGS), + GATE(CLK_HPMCU, "clk_hpmcu", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 5, GFLAGS), + GATE(CLK_HPMCU_RTC, "clk_hpmcu_rtc", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(1), 10, GFLAGS), + GATE(PCLK_RKDMA, "pclk_rkdma", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 11, GFLAGS), + GATE(ACLK_RKDMA, "aclk_rkdma", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(1), 12, GFLAGS), + GATE(PCLK_DCF, "pclk_dcf", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 0, GFLAGS), + GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 1, GFLAGS), + GATE(HCLK_RGA, "hclk_rga", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 2, GFLAGS), + GATE(ACLK_RGA, "aclk_rga", "aclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 3, GFLAGS), + GATE(CLK_CORE_RGA, "clk_core_rga", "clk_core_rga_src", 0, + RV1126B_BUSCLKGATE_CON(2), 4, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 5, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0, "clk_timer0", clk_timer0_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 0, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 6, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER1, "clk_timer1", clk_timer1_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 2, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 7, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER2, "clk_timer2", clk_timer2_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 4, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER3, "clk_timer3", clk_timer3_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 6, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 9, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER4, "clk_timer4", clk_timer4_parents_p, 0, + RV1126B_BUSCLKSEL_CON(2), 8, 2, MFLAGS, + RV1126B_BUSCLKGATE_CON(2), 10, GFLAGS), + GATE(HCLK_RKRNG_S_NS, "hclk_rkrng_s_ns", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 14, GFLAGS), + GATE(HCLK_RKRNG_NS, "hclk_rkrng_ns", "hclk_rkrng_s_ns", 0, + RV1126B_BUSCLKGATE_CON(2), 15, GFLAGS), + GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(2), 11, GFLAGS), + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 0, GFLAGS), + GATE(CLK_I2C0, "clk_i2c0", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 1, GFLAGS), + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 2, GFLAGS), + GATE(CLK_I2C1, "clk_i2c1", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 3, GFLAGS), + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 4, GFLAGS), + GATE(CLK_I2C3, "clk_i2c3", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 5, GFLAGS), + GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 6, GFLAGS), + GATE(CLK_I2C4, "clk_i2c4", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 7, GFLAGS), + GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 8, GFLAGS), + GATE(CLK_I2C5, "clk_i2c5", "clk_i2c_bus_src", 0, + RV1126B_BUSCLKGATE_CON(3), 9, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 10, GFLAGS), + GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(3), 12, GFLAGS), + GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 0, GFLAGS), + GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 1, GFLAGS), + GATE(CLK_RC_PWM0, "clk_rc_pwm0", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 2, GFLAGS), + GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 3, GFLAGS), + GATE(CLK_OSC_PWM2, "clk_osc_pwm2", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 4, GFLAGS), + GATE(CLK_RC_PWM2, "clk_rc_pwm2", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 5, GFLAGS), + GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 6, GFLAGS), + GATE(CLK_OSC_PWM3, "clk_osc_pwm3", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 7, GFLAGS), + GATE(CLK_RC_PWM3, "clk_rc_pwm3", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(4), 8, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 9, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 10, GFLAGS), + GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 11, GFLAGS), + GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 12, GFLAGS), + GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 13, GFLAGS), + GATE(PCLK_UART6, "pclk_uart6", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 14, GFLAGS), + GATE(PCLK_UART7, "pclk_uart7", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(4), 15, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_root", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(5), 0, GFLAGS), + GATE(CLK_TSADC, "clk_tsadc", "xin24m", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(5), 1, GFLAGS), + GATE(HCLK_SAI0, "hclk_sai0", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 2, GFLAGS), + GATE(HCLK_SAI1, "hclk_sai1", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 4, GFLAGS), + GATE(HCLK_SAI2, "hclk_sai2", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 6, GFLAGS), + GATE(HCLK_RKDSM, "hclk_rkdsm", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 8, GFLAGS), + GATE(MCLK_RKDSM, "mclk_rkdsm", "mclk_sai2", 0, + RV1126B_BUSCLKGATE_CON(5), 9, GFLAGS), + GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 10, GFLAGS), + GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 11, GFLAGS), + GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 12, GFLAGS), + GATE(PCLK_AUDIO_ADC_BUS, "pclk_audio_adc_bus", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(5), 13, GFLAGS), + GATE(MCLK_AUDIO_ADC_BUS, "mclk_audio_adc_bus", "mclk_sai2", 0, + RV1126B_BUSCLKGATE_CON(5), 14, GFLAGS), + FACTOR(MCLK_AUDIO_ADC_DIV4_BUS, "mclk_audio_adc_div4_bus", "mclk_audio_adc_bus", 0, 1, 4), + GATE(PCLK_RKCE, "pclk_rkce", "pclk_bus_root", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(6), 0, GFLAGS), + GATE(HCLK_NS_RKCE, "hclk_ns_rkce", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(6), 1, GFLAGS), + GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(6), 2, GFLAGS), + GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m", 0, + RV1126B_BUSCLKGATE_CON(6), 3, GFLAGS), + COMPOSITE_NOMUX(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "xin24m", 0, + RV1126B_BUSCLKSEL_CON(2), 12, 3, DFLAGS, + RV1126B_BUSCLKGATE_CON(6), 4, GFLAGS), + GATE(PCLK_OTP_MASK, "pclk_otp_mask", "pclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(6), 6, GFLAGS), + GATE(CLK_TSADC_PHYCTRL, "clk_tsadc_phyctrl", "xin24m", CLK_IS_CRITICAL, + RV1126B_BUSCLKGATE_CON(6), 8, GFLAGS), + MUX(LRCK_SRC_ASRC0, "lrck_src_asrc0", lrck_src_asrc_p, 0, + RV1126B_BUSCLKSEL_CON(3), 0, 3, MFLAGS), + MUX(LRCK_DST_ASRC0, "lrck_dst_asrc0", lrck_src_asrc_p, 0, + RV1126B_BUSCLKSEL_CON(3), 4, 3, MFLAGS), + MUX(LRCK_SRC_ASRC1, "lrck_src_asrc1", lrck_src_asrc_p, 0, + RV1126B_BUSCLKSEL_CON(3), 8, 3, MFLAGS), + MUX(LRCK_DST_ASRC1, "lrck_dst_asrc1", lrck_src_asrc_p, 0, + RV1126B_BUSCLKSEL_CON(3), 12, 3, MFLAGS), + GATE(ACLK_NSRKCE, "aclk_nsrkce", "aclk_rkce_src", 0, + RV1126B_BUSCLKGATE_CON(2), 12, GFLAGS), + GATE(CLK_PKA_NSRKCE, "clk_pka_nsrkce", "clk_pka_rkce_src", 0, + RV1126B_BUSCLKGATE_CON(2), 13, GFLAGS), + + /* pd_peri */ + DIV(PCLK_RTC_ROOT, "pclk_rtc_root", "pclk_peri_root", 0, + RV1126B_PERICLKSEL_CON(0), 0, 2, DFLAGS), + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(0), 5, GFLAGS), + GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0, + RV1126B_PERICLKGATE_CON(0), 6, GFLAGS), + GATE(PCLK_IOC_VCCIO1, "pclk_ioc_vccio1", "pclk_peri_root", CLK_IS_CRITICAL, + RV1126B_PERICLKGATE_CON(0), 7, GFLAGS), + GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(0), 8, GFLAGS), + GATE(CLK_REF_USB3OTG, "clk_ref_usb3otg", "xin24m", 0, + RV1126B_PERICLKGATE_CON(0), 9, GFLAGS), + GATE(CLK_SUSPEND_USB3OTG, "clk_suspend_usb3otg", "xin24m", 0, + RV1126B_PERICLKGATE_CON(0), 10, GFLAGS), + GATE(HCLK_USB2HOST, "hclk_usb2host", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(0), 11, GFLAGS), + GATE(HCLK_ARB_USB2HOST, "hclk_arb_usb2host", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(0), 12, GFLAGS), + GATE(PCLK_RTC_TEST, "pclk_rtc_test", "pclk_rtc_root", 0, + RV1126B_PERICLKGATE_CON(0), 13, GFLAGS), + GATE(HCLK_EMMC, "hclk_emmc", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 0, GFLAGS), + GATE(HCLK_FSPI0, "hclk_fspi0", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 1, GFLAGS), + GATE(HCLK_XIP_FSPI0, "hclk_xip_fspi0", "aclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 2, GFLAGS), + GATE(PCLK_PIPEPHY, "pclk_pipephy", "pclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 8, GFLAGS), + GATE(PCLK_USB2PHY, "pclk_usb2phy", "pclk_peri_root", 0, + RV1126B_PERICLKGATE_CON(1), 10, GFLAGS), + COMPOSITE_NOMUX(CLK_REF_PIPEPHY_CPLL_SRC, "clk_ref_pipephy_cpll_src", "cpll", 0, + RV1126B_PERICLKSEL_CON(1), 0, 6, DFLAGS, + RV1126B_PERICLKGATE_CON(1), 14, GFLAGS), + MUX(CLK_REF_PIPEPHY, "clk_ref_pipephy", clk_ref_pipephy_p, 0, + RV1126B_PERICLKSEL_CON(1), 12, 1, MFLAGS), +}; + +static struct rockchip_clk_branch rv1126b_armclk __initdata = + MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + RV1126B_CORECLKSEL_CON(0), 1, 1, MFLAGS); + +static void __init rv1126b_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + void __iomem *reg_base; + unsigned long clk_nr_clks; + + clk_nr_clks = rockchip_clk_find_max_clk_id(rv1126b_clk_branches, + ARRAY_SIZE(rv1126b_clk_branches)) + 1; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + + ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); + return; + } + + rockchip_clk_register_plls(ctx, rv1126b_pll_clks, + ARRAY_SIZE(rv1126b_pll_clks), + 0); + + rockchip_clk_register_branches(ctx, rv1126b_clk_branches, + ARRAY_SIZE(rv1126b_clk_branches)); + + rockchip_clk_register_armclk_multi_pll(ctx, &rv1126b_armclk, + rv1126b_cpuclk_rates, + ARRAY_SIZE(rv1126b_cpuclk_rates)); + + rv1126b_rst_init(np, reg_base); + + rockchip_register_restart_notifier(ctx, RV1126B_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); + + /* pvtpll src init */ + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_CORECLKSEL_CON(0)); + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_NPUCLKSEL_CON(0)); + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VICLKSEL_CON(0)); + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VEPUCLKSEL_CON(0)); + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VCPCLKSEL_CON(0)); +} + +CLK_OF_DECLARE(rv1126b_cru, "rockchip,rv1126b-cru", rv1126b_clk_init); + +struct clk_rv1126b_inits { + void (*inits)(struct device_node *np); +}; + +static const struct clk_rv1126b_inits clk_rv1126b_init = { + .inits = rv1126b_clk_init, +}; + +static const struct of_device_id clk_rv1126b_match_table[] = { + { + .compatible = "rockchip,rv1126b-cru", + .data = &clk_rv1126b_init, + }, + { } +}; + +static int clk_rv1126b_probe(struct platform_device *pdev) +{ + const struct clk_rv1126b_inits *init_data; + struct device *dev = &pdev->dev; + + init_data = device_get_match_data(dev); + if (!init_data) + return -EINVAL; + + if (init_data->inits) + init_data->inits(dev->of_node); + + return 0; +} + +static struct platform_driver clk_rv1126b_driver = { + .probe = clk_rv1126b_probe, + .driver = { + .name = "clk-rv1126b", + .of_match_table = clk_rv1126b_match_table, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver_probe(clk_rv1126b_driver, clk_rv1126b_probe); diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 23653a942403..87f09320b942 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -99,6 +99,73 @@ struct clk; #define RV1126_EMMC_CON0 0x450 #define RV1126_EMMC_CON1 0x454 +#define RV1126B_TOPCRU_BASE 0x0 +#define RV1126B_BUSCRU_BASE 0x10000 +#define RV1126B_PERICRU_BASE 0x20000 +#define RV1126B_CORECRU_BASE 0x30000 +#define RV1126B_PMUCRU_BASE 0x40000 +#define RV1126B_PMU1CRU_BASE 0x50000 +#define RV1126B_DDRCRU_BASE 0x60000 +#define RV1126B_SUBDDRCRU_BASE 0x68000 +#define RV1126B_VICRU_BASE 0x70000 +#define RV1126B_VEPUCRU_BASE 0x80000 +#define RV1126B_NPUCRU_BASE 0x90000 +#define RV1126B_VDOCRU_BASE 0xA0000 +#define RV1126B_VCPCRU_BASE 0xB0000 + +#define RV1126B_PLL_CON(x) ((x) * 0x4 + RV1126B_TOPCRU_BASE) +#define RV1126B_MODE_CON (0x280 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_TOPCRU_BASE) +#define RV1126B_SOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_TOPCRU_BASE) +#define RV1126B_GLB_SRST_FST (0xc08 + RV1126B_TOPCRU_BASE) +#define RV1126B_GLB_SRST_SND (0xc0c + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_CM_FRAC0_DIV_H (0xcc0 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_CM_FRAC1_DIV_H (0xcc4 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_CM_FRAC2_DIV_H (0xcc8 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_UART_FRAC0_DIV_H (0xccc + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_UART_FRAC1_DIV_H (0xcd0 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_AUDIO_FRAC0_DIV_H (0xcd4 + RV1126B_TOPCRU_BASE) +#define RV1126B_CLK_AUDIO_FRAC1_DIV_H (0xcd8 + RV1126B_TOPCRU_BASE) +#define RV1126B_BUSCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_BUSCRU_BASE) +#define RV1126B_BUSCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_BUSCRU_BASE) +#define RV1126B_BUSSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_BUSCRU_BASE) +#define RV1126B_PERIPLL_CON(x) ((x) * 0x4 + RV1126B_PERICRU_BASE) +#define RV1126B_PERICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PERICRU_BASE) +#define RV1126B_PERICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PERICRU_BASE) +#define RV1126B_PERISOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PERICRU_BASE) +#define RV1126B_CORECLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_CORECRU_BASE) +#define RV1126B_CORECLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_CORECRU_BASE) +#define RV1126B_CORESOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_CORECRU_BASE) +#define RV1126B_PMUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PMUCRU_BASE) +#define RV1126B_PMUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PMUCRU_BASE) +#define RV1126B_PMUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PMUCRU_BASE) +#define RV1126B_PMU1CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PMU1CRU_BASE) +#define RV1126B_PMU1CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PMU1CRU_BASE) +#define RV1126B_PMU1SOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PMU1CRU_BASE) +#define RV1126B_DDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_DDRCRU_BASE) +#define RV1126B_DDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_DDRCRU_BASE) +#define RV1126B_DDRSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_DDRCRU_BASE) +#define RV1126B_SUBDDRPLL_CON(x) ((x) * 0x4 + RV1126B_SUBDDRCRU_BASE) +#define RV1126B_SUBDDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_SUBDDRCRU_BASE) +#define RV1126B_SUBDDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_SUBDDRCRU_BASE) +#define RV1126B_SUBDDRSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_SUBDDRCRU_BASE) +#define RV1126B_VICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VICRU_BASE) +#define RV1126B_VICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VICRU_BASE) +#define RV1126B_VISOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VICRU_BASE) +#define RV1126B_VEPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VEPUCRU_BASE) +#define RV1126B_VEPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VEPUCRU_BASE) +#define RV1126B_VEPUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VEPUCRU_BASE) +#define RV1126B_NPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_NPUCRU_BASE) +#define RV1126B_NPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_NPUCRU_BASE) +#define RV1126B_NPUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_NPUCRU_BASE) +#define RV1126B_VDOCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VDOCRU_BASE) +#define RV1126B_VDOCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VDOCRU_BASE) +#define RV1126B_VDOSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VDOCRU_BASE) +#define RV1126B_VCPCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VCPCRU_BASE) +#define RV1126B_VCPCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VCPCRU_BASE) +#define RV1126B_VCPSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VCPCRU_BASE) + #define RK2928_PLL_CON(x) ((x) * 0x4) #define RK2928_MODE_CON 0x40 #define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44) @@ -1261,6 +1328,7 @@ static inline void rockchip_register_softrst(struct device_node *np, return rockchip_register_softrst_lut(np, NULL, num_regs, base, flags); } +void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base); void rk3528_rst_init(struct device_node *np, void __iomem *reg_base); void rk3562_rst_init(struct device_node *np, void __iomem *reg_base); void rk3576_rst_init(struct device_node *np, void __iomem *reg_base); diff --git a/drivers/clk/rockchip/rst-rv1126b.c b/drivers/clk/rockchip/rst-rv1126b.c new file mode 100644 index 000000000000..c75b0d885ca2 --- /dev/null +++ b/drivers/clk/rockchip/rst-rv1126b.c @@ -0,0 +1,443 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + * Author: Elaine Zhang + */ + +#include +#include +#include +#include "clk.h" + +/* 0x20000000 + 0x0A00 */ +#define TOPCRU_RESET_OFFSET(id, reg, bit) [id] = (0x0 * 4 + reg * 16 + bit) +/* 0x20010000 + 0x0A00 */ +#define BUSCRU_RESET_OFFSET(id, reg, bit) [id] = (0x10000 * 4 + reg * 16 + bit) +/* 0x20020000 + 0x0A00 */ +#define PERICRU_RESET_OFFSET(id, reg, bit) [id] = (0x20000 * 4 + reg * 16 + bit) +/* 0x20030000 + 0x0A00 */ +#define CORECRU_RESET_OFFSET(id, reg, bit) [id] = (0x30000 * 4 + reg * 16 + bit) +/* 0x20040000 + 0x0A00 */ +#define PMUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x40000 * 4 + reg * 16 + bit) +/* 0x20050000 + 0x0A00 */ +#define PMU1CRU_RESET_OFFSET(id, reg, bit) [id] = (0x50000 * 4 + reg * 16 + bit) +/* 0x20060000 + 0x0A00 */ +#define DDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x60000 * 4 + reg * 16 + bit) +/* 0x20068000 + 0x0A00 */ +#define SUBDDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x68000 * 4 + reg * 16 + bit) +/* 0x20070000 + 0x0A00 */ +#define VICRU_RESET_OFFSET(id, reg, bit) [id] = (0x70000 * 4 + reg * 16 + bit) +/* 0x20080000 + 0x0A00 */ +#define VEPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x80000 * 4 + reg * 16 + bit) +/* 0x20090000 + 0x0A00 */ +#define NPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x90000 * 4 + reg * 16 + bit) +/* 0x200A0000 + 0x0A00 */ +#define VDOCRU_RESET_OFFSET(id, reg, bit) [id] = (0xA0000 * 4 + reg * 16 + bit) +/* 0x200B0000 + 0x0A00 */ +#define VCPCRU_RESET_OFFSET(id, reg, bit) [id] = (0xB0000 * 4 + reg * 16 + bit) + +/* =================mapping table for reset ID to register offset================== */ +static const int rv1126b_register_offset[] = { + /* TOPCRU-->SOFTRST_CON00 */ + + /* TOPCRU-->SOFTRST_CON15 */ + TOPCRU_RESET_OFFSET(SRST_P_CRU, 15, 1), + TOPCRU_RESET_OFFSET(SRST_P_CRU_BIU, 15, 2), + + /* BUSCRU-->SOFTRST_CON00 */ + BUSCRU_RESET_OFFSET(SRST_A_TOP_BIU, 0, 0), + BUSCRU_RESET_OFFSET(SRST_A_RKCE_BIU, 0, 1), + BUSCRU_RESET_OFFSET(SRST_A_BUS_BIU, 0, 2), + BUSCRU_RESET_OFFSET(SRST_H_BUS_BIU, 0, 3), + BUSCRU_RESET_OFFSET(SRST_P_BUS_BIU, 0, 4), + BUSCRU_RESET_OFFSET(SRST_P_CRU_BUS, 0, 5), + BUSCRU_RESET_OFFSET(SRST_P_SYS_GRF, 0, 6), + BUSCRU_RESET_OFFSET(SRST_H_BOOTROM, 0, 7), + BUSCRU_RESET_OFFSET(SRST_A_GIC400, 0, 8), + BUSCRU_RESET_OFFSET(SRST_A_SPINLOCK, 0, 9), + BUSCRU_RESET_OFFSET(SRST_P_WDT_NS, 0, 10), + BUSCRU_RESET_OFFSET(SRST_T_WDT_NS, 0, 11), + + /* BUSCRU-->SOFTRST_CON01 */ + BUSCRU_RESET_OFFSET(SRST_P_WDT_HPMCU, 1, 0), + BUSCRU_RESET_OFFSET(SRST_T_WDT_HPMCU, 1, 1), + BUSCRU_RESET_OFFSET(SRST_H_CACHE, 1, 2), + BUSCRU_RESET_OFFSET(SRST_P_HPMCU_MAILBOX, 1, 3), + BUSCRU_RESET_OFFSET(SRST_P_HPMCU_INTMUX, 1, 4), + BUSCRU_RESET_OFFSET(SRST_HPMCU_FULL_CLUSTER, 1, 5), + BUSCRU_RESET_OFFSET(SRST_HPMCU_PWUP, 1, 6), + BUSCRU_RESET_OFFSET(SRST_HPMCU_ONLY_CORE, 1, 7), + BUSCRU_RESET_OFFSET(SRST_T_HPMCU_JTAG, 1, 8), + BUSCRU_RESET_OFFSET(SRST_P_RKDMA, 1, 11), + BUSCRU_RESET_OFFSET(SRST_A_RKDMA, 1, 12), + + /* BUSCRU-->SOFTRST_CON02 */ + BUSCRU_RESET_OFFSET(SRST_P_DCF, 2, 0), + BUSCRU_RESET_OFFSET(SRST_A_DCF, 2, 1), + BUSCRU_RESET_OFFSET(SRST_H_RGA, 2, 2), + BUSCRU_RESET_OFFSET(SRST_A_RGA, 2, 3), + BUSCRU_RESET_OFFSET(SRST_CORE_RGA, 2, 4), + BUSCRU_RESET_OFFSET(SRST_P_TIMER, 2, 5), + BUSCRU_RESET_OFFSET(SRST_TIMER0, 2, 6), + BUSCRU_RESET_OFFSET(SRST_TIMER1, 2, 7), + BUSCRU_RESET_OFFSET(SRST_TIMER2, 2, 8), + BUSCRU_RESET_OFFSET(SRST_TIMER3, 2, 9), + BUSCRU_RESET_OFFSET(SRST_TIMER4, 2, 10), + BUSCRU_RESET_OFFSET(SRST_TIMER5, 2, 11), + BUSCRU_RESET_OFFSET(SRST_A_RKCE, 2, 12), + BUSCRU_RESET_OFFSET(SRST_PKA_RKCE, 2, 13), + BUSCRU_RESET_OFFSET(SRST_H_RKRNG_S, 2, 14), + BUSCRU_RESET_OFFSET(SRST_H_RKRNG_NS, 2, 15), + + /* BUSCRU-->SOFTRST_CON03 */ + BUSCRU_RESET_OFFSET(SRST_P_I2C0, 3, 0), + BUSCRU_RESET_OFFSET(SRST_I2C0, 3, 1), + BUSCRU_RESET_OFFSET(SRST_P_I2C1, 3, 2), + BUSCRU_RESET_OFFSET(SRST_I2C1, 3, 3), + BUSCRU_RESET_OFFSET(SRST_P_I2C3, 3, 4), + BUSCRU_RESET_OFFSET(SRST_I2C3, 3, 5), + BUSCRU_RESET_OFFSET(SRST_P_I2C4, 3, 6), + BUSCRU_RESET_OFFSET(SRST_I2C4, 3, 7), + BUSCRU_RESET_OFFSET(SRST_P_I2C5, 3, 8), + BUSCRU_RESET_OFFSET(SRST_I2C5, 3, 9), + BUSCRU_RESET_OFFSET(SRST_P_SPI0, 3, 10), + BUSCRU_RESET_OFFSET(SRST_SPI0, 3, 11), + BUSCRU_RESET_OFFSET(SRST_P_SPI1, 3, 12), + BUSCRU_RESET_OFFSET(SRST_SPI1, 3, 13), + + /* BUSCRU-->SOFTRST_CON04 */ + BUSCRU_RESET_OFFSET(SRST_P_PWM0, 4, 0), + BUSCRU_RESET_OFFSET(SRST_PWM0, 4, 1), + BUSCRU_RESET_OFFSET(SRST_P_PWM2, 4, 4), + BUSCRU_RESET_OFFSET(SRST_PWM2, 4, 5), + BUSCRU_RESET_OFFSET(SRST_P_PWM3, 4, 8), + BUSCRU_RESET_OFFSET(SRST_PWM3, 4, 9), + + /* BUSCRU-->SOFTRST_CON05 */ + BUSCRU_RESET_OFFSET(SRST_P_UART1, 5, 0), + BUSCRU_RESET_OFFSET(SRST_S_UART1, 5, 1), + BUSCRU_RESET_OFFSET(SRST_P_UART2, 5, 2), + BUSCRU_RESET_OFFSET(SRST_S_UART2, 5, 3), + BUSCRU_RESET_OFFSET(SRST_P_UART3, 5, 4), + BUSCRU_RESET_OFFSET(SRST_S_UART3, 5, 5), + BUSCRU_RESET_OFFSET(SRST_P_UART4, 5, 6), + BUSCRU_RESET_OFFSET(SRST_S_UART4, 5, 7), + BUSCRU_RESET_OFFSET(SRST_P_UART5, 5, 8), + BUSCRU_RESET_OFFSET(SRST_S_UART5, 5, 9), + BUSCRU_RESET_OFFSET(SRST_P_UART6, 5, 10), + BUSCRU_RESET_OFFSET(SRST_S_UART6, 5, 11), + BUSCRU_RESET_OFFSET(SRST_P_UART7, 5, 12), + BUSCRU_RESET_OFFSET(SRST_S_UART7, 5, 13), + + /* BUSCRU-->SOFTRST_CON06 */ + BUSCRU_RESET_OFFSET(SRST_P_TSADC, 6, 0), + BUSCRU_RESET_OFFSET(SRST_TSADC, 6, 1), + BUSCRU_RESET_OFFSET(SRST_H_SAI0, 6, 2), + BUSCRU_RESET_OFFSET(SRST_M_SAI0, 6, 3), + BUSCRU_RESET_OFFSET(SRST_H_SAI1, 6, 4), + BUSCRU_RESET_OFFSET(SRST_M_SAI1, 6, 5), + BUSCRU_RESET_OFFSET(SRST_H_SAI2, 6, 6), + BUSCRU_RESET_OFFSET(SRST_M_SAI2, 6, 7), + BUSCRU_RESET_OFFSET(SRST_H_RKDSM, 6, 8), + BUSCRU_RESET_OFFSET(SRST_M_RKDSM, 6, 9), + BUSCRU_RESET_OFFSET(SRST_H_PDM, 6, 10), + BUSCRU_RESET_OFFSET(SRST_M_PDM, 6, 11), + BUSCRU_RESET_OFFSET(SRST_PDM, 6, 12), + + /* BUSCRU-->SOFTRST_CON07 */ + BUSCRU_RESET_OFFSET(SRST_H_ASRC0, 7, 0), + BUSCRU_RESET_OFFSET(SRST_ASRC0, 7, 1), + BUSCRU_RESET_OFFSET(SRST_H_ASRC1, 7, 2), + BUSCRU_RESET_OFFSET(SRST_ASRC1, 7, 3), + BUSCRU_RESET_OFFSET(SRST_P_AUDIO_ADC_BUS, 7, 4), + BUSCRU_RESET_OFFSET(SRST_M_AUDIO_ADC_BUS, 7, 5), + BUSCRU_RESET_OFFSET(SRST_P_RKCE, 7, 6), + BUSCRU_RESET_OFFSET(SRST_H_NS_RKCE, 7, 7), + BUSCRU_RESET_OFFSET(SRST_P_OTPC_NS, 7, 8), + BUSCRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 7, 9), + BUSCRU_RESET_OFFSET(SRST_USER_OTPC_NS, 7, 10), + BUSCRU_RESET_OFFSET(SRST_OTPC_ARB, 7, 11), + BUSCRU_RESET_OFFSET(SRST_P_OTP_MASK, 7, 12), + + /* PERICRU-->SOFTRST_CON00 */ + PERICRU_RESET_OFFSET(SRST_A_PERI_BIU, 0, 0), + PERICRU_RESET_OFFSET(SRST_P_PERI_BIU, 0, 1), + PERICRU_RESET_OFFSET(SRST_P_RTC_BIU, 0, 2), + PERICRU_RESET_OFFSET(SRST_P_CRU_PERI, 0, 3), + PERICRU_RESET_OFFSET(SRST_P_PERI_GRF, 0, 4), + PERICRU_RESET_OFFSET(SRST_P_GPIO1, 0, 5), + PERICRU_RESET_OFFSET(SRST_DB_GPIO1, 0, 6), + PERICRU_RESET_OFFSET(SRST_P_IOC_VCCIO1, 0, 7), + PERICRU_RESET_OFFSET(SRST_A_USB3OTG, 0, 8), + PERICRU_RESET_OFFSET(SRST_H_USB2HOST, 0, 11), + PERICRU_RESET_OFFSET(SRST_H_ARB_USB2HOST, 0, 12), + PERICRU_RESET_OFFSET(SRST_P_RTC_TEST, 0, 13), + + /* PERICRU-->SOFTRST_CON01 */ + PERICRU_RESET_OFFSET(SRST_H_EMMC, 1, 0), + PERICRU_RESET_OFFSET(SRST_H_FSPI0, 1, 1), + PERICRU_RESET_OFFSET(SRST_H_XIP_FSPI0, 1, 2), + PERICRU_RESET_OFFSET(SRST_S_2X_FSPI0, 1, 3), + PERICRU_RESET_OFFSET(SRST_UTMI_USB2HOST, 1, 5), + PERICRU_RESET_OFFSET(SRST_REF_PIPEPHY, 1, 7), + PERICRU_RESET_OFFSET(SRST_P_PIPEPHY, 1, 8), + PERICRU_RESET_OFFSET(SRST_P_PIPEPHY_GRF, 1, 9), + PERICRU_RESET_OFFSET(SRST_P_USB2PHY, 1, 10), + PERICRU_RESET_OFFSET(SRST_POR_USB2PHY, 1, 11), + PERICRU_RESET_OFFSET(SRST_OTG_USB2PHY, 1, 12), + PERICRU_RESET_OFFSET(SRST_HOST_USB2PHY, 1, 13), + + /* CORECRU-->SOFTRST_CON00 */ + CORECRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 0, 0), + CORECRU_RESET_OFFSET(SRST_NCOREPORESET0, 0, 1), + CORECRU_RESET_OFFSET(SRST_NCORESET0, 0, 2), + CORECRU_RESET_OFFSET(SRST_NCOREPORESET1, 0, 3), + CORECRU_RESET_OFFSET(SRST_NCORESET1, 0, 4), + CORECRU_RESET_OFFSET(SRST_NCOREPORESET2, 0, 5), + CORECRU_RESET_OFFSET(SRST_NCORESET2, 0, 6), + CORECRU_RESET_OFFSET(SRST_NCOREPORESET3, 0, 7), + CORECRU_RESET_OFFSET(SRST_NCORESET3, 0, 8), + CORECRU_RESET_OFFSET(SRST_NDBGRESET, 0, 9), + CORECRU_RESET_OFFSET(SRST_NL2RESET, 0, 10), + + /* CORECRU-->SOFTRST_CON01 */ + CORECRU_RESET_OFFSET(SRST_A_CORE_BIU, 1, 0), + CORECRU_RESET_OFFSET(SRST_P_CORE_BIU, 1, 1), + CORECRU_RESET_OFFSET(SRST_H_CORE_BIU, 1, 2), + CORECRU_RESET_OFFSET(SRST_P_DBG, 1, 3), + CORECRU_RESET_OFFSET(SRST_POT_DBG, 1, 4), + CORECRU_RESET_OFFSET(SRST_NT_DBG, 1, 5), + CORECRU_RESET_OFFSET(SRST_P_CORE_PVTPLL, 1, 6), + CORECRU_RESET_OFFSET(SRST_P_CRU_CORE, 1, 7), + CORECRU_RESET_OFFSET(SRST_P_CORE_GRF, 1, 8), + CORECRU_RESET_OFFSET(SRST_P_DFT2APB, 1, 10), + + /* PMUCRU-->SOFTRST_CON00 */ + PMUCRU_RESET_OFFSET(SRST_H_PMU_BIU, 0, 0), + PMUCRU_RESET_OFFSET(SRST_P_PMU_GPIO0, 0, 7), + PMUCRU_RESET_OFFSET(SRST_DB_PMU_GPIO0, 0, 8), + PMUCRU_RESET_OFFSET(SRST_P_PMU_HP_TIMER, 0, 10), + PMUCRU_RESET_OFFSET(SRST_PMU_HP_TIMER, 0, 11), + PMUCRU_RESET_OFFSET(SRST_PMU_32K_HP_TIMER, 0, 12), + + /* PMUCRU-->SOFTRST_CON01 */ + PMUCRU_RESET_OFFSET(SRST_P_PWM1, 1, 0), + PMUCRU_RESET_OFFSET(SRST_PWM1, 1, 1), + PMUCRU_RESET_OFFSET(SRST_P_I2C2, 1, 2), + PMUCRU_RESET_OFFSET(SRST_I2C2, 1, 3), + PMUCRU_RESET_OFFSET(SRST_P_UART0, 1, 4), + PMUCRU_RESET_OFFSET(SRST_S_UART0, 1, 5), + + /* PMUCRU-->SOFTRST_CON02 */ + PMUCRU_RESET_OFFSET(SRST_P_RCOSC_CTRL, 2, 0), + PMUCRU_RESET_OFFSET(SRST_REF_RCOSC_CTRL, 2, 2), + PMUCRU_RESET_OFFSET(SRST_P_IOC_PMUIO0, 2, 3), + PMUCRU_RESET_OFFSET(SRST_P_CRU_PMU, 2, 4), + PMUCRU_RESET_OFFSET(SRST_P_PMU_GRF, 2, 5), + PMUCRU_RESET_OFFSET(SRST_PREROLL, 2, 7), + PMUCRU_RESET_OFFSET(SRST_PREROLL_32K, 2, 8), + PMUCRU_RESET_OFFSET(SRST_H_PMU_SRAM, 2, 9), + + /* PMUCRU-->SOFTRST_CON03 */ + PMUCRU_RESET_OFFSET(SRST_P_WDT_LPMCU, 3, 0), + PMUCRU_RESET_OFFSET(SRST_T_WDT_LPMCU, 3, 1), + PMUCRU_RESET_OFFSET(SRST_LPMCU_FULL_CLUSTER, 3, 2), + PMUCRU_RESET_OFFSET(SRST_LPMCU_PWUP, 3, 3), + PMUCRU_RESET_OFFSET(SRST_LPMCU_ONLY_CORE, 3, 4), + PMUCRU_RESET_OFFSET(SRST_T_LPMCU_JTAG, 3, 5), + PMUCRU_RESET_OFFSET(SRST_P_LPMCU_MAILBOX, 3, 6), + + /* PMU1CRU-->SOFTRST_CON00 */ + PMU1CRU_RESET_OFFSET(SRST_P_SPI2AHB, 0, 0), + PMU1CRU_RESET_OFFSET(SRST_H_SPI2AHB, 0, 1), + PMU1CRU_RESET_OFFSET(SRST_H_FSPI1, 0, 2), + PMU1CRU_RESET_OFFSET(SRST_H_XIP_FSPI1, 0, 3), + PMU1CRU_RESET_OFFSET(SRST_S_1X_FSPI1, 0, 4), + PMU1CRU_RESET_OFFSET(SRST_P_IOC_PMUIO1, 0, 5), + PMU1CRU_RESET_OFFSET(SRST_P_CRU_PMU1, 0, 6), + PMU1CRU_RESET_OFFSET(SRST_P_AUDIO_ADC_PMU, 0, 7), + PMU1CRU_RESET_OFFSET(SRST_M_AUDIO_ADC_PMU, 0, 8), + PMU1CRU_RESET_OFFSET(SRST_H_PMU1_BIU, 0, 9), + + /* PMU1CRU-->SOFTRST_CON01 */ + PMU1CRU_RESET_OFFSET(SRST_P_LPDMA, 1, 0), + PMU1CRU_RESET_OFFSET(SRST_A_LPDMA, 1, 1), + PMU1CRU_RESET_OFFSET(SRST_H_LPSAI, 1, 2), + PMU1CRU_RESET_OFFSET(SRST_M_LPSAI, 1, 3), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_TDD, 1, 4), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_FE, 1, 5), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_AAD, 1, 6), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_APB, 1, 7), + PMU1CRU_RESET_OFFSET(SRST_P_AOA_SRAM, 1, 8), + + /* DDRCRU-->SOFTRST_CON00 */ + DDRCRU_RESET_OFFSET(SRST_P_DDR_BIU, 0, 1), + DDRCRU_RESET_OFFSET(SRST_P_DDRC, 0, 2), + DDRCRU_RESET_OFFSET(SRST_P_DDRMON, 0, 3), + DDRCRU_RESET_OFFSET(SRST_TIMER_DDRMON, 0, 4), + DDRCRU_RESET_OFFSET(SRST_P_DFICTRL, 0, 5), + DDRCRU_RESET_OFFSET(SRST_P_DDR_GRF, 0, 6), + DDRCRU_RESET_OFFSET(SRST_P_CRU_DDR, 0, 7), + DDRCRU_RESET_OFFSET(SRST_P_DDRPHY, 0, 8), + DDRCRU_RESET_OFFSET(SRST_P_DMA2DDR, 0, 9), + + /* SUBDDRCRU-->SOFTRST_CON00 */ + SUBDDRCRU_RESET_OFFSET(SRST_A_SYSMEM_BIU, 0, 0), + SUBDDRCRU_RESET_OFFSET(SRST_A_SYSMEM, 0, 1), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDR_BIU, 0, 2), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH0_CPU, 0, 3), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH1_NPU, 0, 4), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH2_POE, 0, 5), + SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH3_VI, 0, 6), + SUBDDRCRU_RESET_OFFSET(SRST_CORE_DDRC, 0, 7), + SUBDDRCRU_RESET_OFFSET(SRST_DDRMON, 0, 8), + SUBDDRCRU_RESET_OFFSET(SRST_DFICTRL, 0, 9), + SUBDDRCRU_RESET_OFFSET(SRST_RS, 0, 11), + SUBDDRCRU_RESET_OFFSET(SRST_A_DMA2DDR, 0, 12), + SUBDDRCRU_RESET_OFFSET(SRST_DDRPHY, 0, 13), + + /* VICRU-->SOFTRST_CON00 */ + VICRU_RESET_OFFSET(SRST_REF_PVTPLL_ISP, 0, 0), + VICRU_RESET_OFFSET(SRST_A_GMAC_BIU, 0, 1), + VICRU_RESET_OFFSET(SRST_A_VI_BIU, 0, 2), + VICRU_RESET_OFFSET(SRST_H_VI_BIU, 0, 3), + VICRU_RESET_OFFSET(SRST_P_VI_BIU, 0, 4), + VICRU_RESET_OFFSET(SRST_P_CRU_VI, 0, 5), + VICRU_RESET_OFFSET(SRST_P_VI_GRF, 0, 6), + VICRU_RESET_OFFSET(SRST_P_VI_PVTPLL, 0, 7), + VICRU_RESET_OFFSET(SRST_P_DSMC, 0, 8), + VICRU_RESET_OFFSET(SRST_A_DSMC, 0, 9), + VICRU_RESET_OFFSET(SRST_H_CAN0, 0, 10), + VICRU_RESET_OFFSET(SRST_CAN0, 0, 11), + VICRU_RESET_OFFSET(SRST_H_CAN1, 0, 12), + VICRU_RESET_OFFSET(SRST_CAN1, 0, 13), + + /* VICRU-->SOFTRST_CON01 */ + VICRU_RESET_OFFSET(SRST_P_GPIO2, 1, 0), + VICRU_RESET_OFFSET(SRST_DB_GPIO2, 1, 1), + VICRU_RESET_OFFSET(SRST_P_GPIO4, 1, 2), + VICRU_RESET_OFFSET(SRST_DB_GPIO4, 1, 3), + VICRU_RESET_OFFSET(SRST_P_GPIO5, 1, 4), + VICRU_RESET_OFFSET(SRST_DB_GPIO5, 1, 5), + VICRU_RESET_OFFSET(SRST_P_GPIO6, 1, 6), + VICRU_RESET_OFFSET(SRST_DB_GPIO6, 1, 7), + VICRU_RESET_OFFSET(SRST_P_GPIO7, 1, 8), + VICRU_RESET_OFFSET(SRST_DB_GPIO7, 1, 9), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO2, 1, 10), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO4, 1, 11), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO5, 1, 12), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO6, 1, 13), + VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO7, 1, 14), + + /* VICRU-->SOFTRST_CON02 */ + VICRU_RESET_OFFSET(SRST_CORE_ISP, 2, 0), + VICRU_RESET_OFFSET(SRST_H_VICAP, 2, 1), + VICRU_RESET_OFFSET(SRST_A_VICAP, 2, 2), + VICRU_RESET_OFFSET(SRST_D_VICAP, 2, 3), + VICRU_RESET_OFFSET(SRST_ISP0_VICAP, 2, 4), + VICRU_RESET_OFFSET(SRST_CORE_VPSS, 2, 5), + VICRU_RESET_OFFSET(SRST_CORE_VPSL, 2, 6), + VICRU_RESET_OFFSET(SRST_P_CSI2HOST0, 2, 7), + VICRU_RESET_OFFSET(SRST_P_CSI2HOST1, 2, 8), + VICRU_RESET_OFFSET(SRST_P_CSI2HOST2, 2, 9), + VICRU_RESET_OFFSET(SRST_P_CSI2HOST3, 2, 10), + VICRU_RESET_OFFSET(SRST_H_SDMMC0, 2, 11), + VICRU_RESET_OFFSET(SRST_A_GMAC, 2, 12), + VICRU_RESET_OFFSET(SRST_P_CSIPHY0, 2, 13), + VICRU_RESET_OFFSET(SRST_P_CSIPHY1, 2, 14), + + /* VICRU-->SOFTRST_CON03 */ + VICRU_RESET_OFFSET(SRST_P_MACPHY, 3, 0), + VICRU_RESET_OFFSET(SRST_MACPHY, 3, 1), + VICRU_RESET_OFFSET(SRST_P_SARADC1, 3, 2), + VICRU_RESET_OFFSET(SRST_SARADC1, 3, 3), + VICRU_RESET_OFFSET(SRST_P_SARADC2, 3, 5), + VICRU_RESET_OFFSET(SRST_SARADC2, 3, 6), + + /* VEPUCRU-->SOFTRST_CON00 */ + VEPUCRU_RESET_OFFSET(SRST_REF_PVTPLL_VEPU, 0, 0), + VEPUCRU_RESET_OFFSET(SRST_A_VEPU_BIU, 0, 1), + VEPUCRU_RESET_OFFSET(SRST_H_VEPU_BIU, 0, 2), + VEPUCRU_RESET_OFFSET(SRST_P_VEPU_BIU, 0, 3), + VEPUCRU_RESET_OFFSET(SRST_P_CRU_VEPU, 0, 4), + VEPUCRU_RESET_OFFSET(SRST_P_VEPU_GRF, 0, 5), + VEPUCRU_RESET_OFFSET(SRST_P_GPIO3, 0, 7), + VEPUCRU_RESET_OFFSET(SRST_DB_GPIO3, 0, 8), + VEPUCRU_RESET_OFFSET(SRST_P_IOC_VCCIO3, 0, 9), + VEPUCRU_RESET_OFFSET(SRST_P_SARADC0, 0, 10), + VEPUCRU_RESET_OFFSET(SRST_SARADC0, 0, 11), + VEPUCRU_RESET_OFFSET(SRST_H_SDMMC1, 0, 13), + + /* VEPUCRU-->SOFTRST_CON01 */ + VEPUCRU_RESET_OFFSET(SRST_P_VEPU_PVTPLL, 1, 0), + VEPUCRU_RESET_OFFSET(SRST_H_VEPU, 1, 1), + VEPUCRU_RESET_OFFSET(SRST_A_VEPU, 1, 2), + VEPUCRU_RESET_OFFSET(SRST_CORE_VEPU, 1, 3), + + /* NPUCRU-->SOFTRST_CON00 */ + NPUCRU_RESET_OFFSET(SRST_REF_PVTPLL_NPU, 0, 0), + NPUCRU_RESET_OFFSET(SRST_A_NPU_BIU, 0, 2), + NPUCRU_RESET_OFFSET(SRST_H_NPU_BIU, 0, 3), + NPUCRU_RESET_OFFSET(SRST_P_NPU_BIU, 0, 4), + NPUCRU_RESET_OFFSET(SRST_P_CRU_NPU, 0, 5), + NPUCRU_RESET_OFFSET(SRST_P_NPU_GRF, 0, 6), + NPUCRU_RESET_OFFSET(SRST_P_NPU_PVTPLL, 0, 8), + NPUCRU_RESET_OFFSET(SRST_H_RKNN, 0, 9), + NPUCRU_RESET_OFFSET(SRST_A_RKNN, 0, 10), + + /* VDOCRU-->SOFTRST_CON00 */ + VDOCRU_RESET_OFFSET(SRST_A_RKVDEC_BIU, 0, 0), + VDOCRU_RESET_OFFSET(SRST_A_VDO_BIU, 0, 1), + VDOCRU_RESET_OFFSET(SRST_H_VDO_BIU, 0, 3), + VDOCRU_RESET_OFFSET(SRST_P_VDO_BIU, 0, 4), + VDOCRU_RESET_OFFSET(SRST_P_CRU_VDO, 0, 5), + VDOCRU_RESET_OFFSET(SRST_P_VDO_GRF, 0, 6), + VDOCRU_RESET_OFFSET(SRST_A_RKVDEC, 0, 7), + VDOCRU_RESET_OFFSET(SRST_H_RKVDEC, 0, 8), + VDOCRU_RESET_OFFSET(SRST_HEVC_CA_RKVDEC, 0, 9), + VDOCRU_RESET_OFFSET(SRST_A_VOP, 0, 10), + VDOCRU_RESET_OFFSET(SRST_H_VOP, 0, 11), + VDOCRU_RESET_OFFSET(SRST_D_VOP, 0, 12), + VDOCRU_RESET_OFFSET(SRST_A_OOC, 0, 13), + VDOCRU_RESET_OFFSET(SRST_H_OOC, 0, 14), + VDOCRU_RESET_OFFSET(SRST_D_OOC, 0, 15), + + /* VDOCRU-->SOFTRST_CON01 */ + VDOCRU_RESET_OFFSET(SRST_H_RKJPEG, 1, 3), + VDOCRU_RESET_OFFSET(SRST_A_RKJPEG, 1, 4), + VDOCRU_RESET_OFFSET(SRST_A_RKMMU_DECOM, 1, 5), + VDOCRU_RESET_OFFSET(SRST_H_RKMMU_DECOM, 1, 6), + VDOCRU_RESET_OFFSET(SRST_D_DECOM, 1, 8), + VDOCRU_RESET_OFFSET(SRST_A_DECOM, 1, 9), + VDOCRU_RESET_OFFSET(SRST_P_DECOM, 1, 10), + VDOCRU_RESET_OFFSET(SRST_P_MIPI_DSI, 1, 12), + VDOCRU_RESET_OFFSET(SRST_P_DSIPHY, 1, 13), + + /* VCPCRU-->SOFTRST_CON00 */ + VCPCRU_RESET_OFFSET(SRST_REF_PVTPLL_VCP, 0, 0), + VCPCRU_RESET_OFFSET(SRST_A_VCP_BIU, 0, 1), + VCPCRU_RESET_OFFSET(SRST_H_VCP_BIU, 0, 2), + VCPCRU_RESET_OFFSET(SRST_P_VCP_BIU, 0, 3), + VCPCRU_RESET_OFFSET(SRST_P_CRU_VCP, 0, 4), + VCPCRU_RESET_OFFSET(SRST_P_VCP_GRF, 0, 5), + VCPCRU_RESET_OFFSET(SRST_P_VCP_PVTPLL, 0, 7), + VCPCRU_RESET_OFFSET(SRST_A_AISP_BIU, 0, 8), + VCPCRU_RESET_OFFSET(SRST_H_AISP_BIU, 0, 9), + VCPCRU_RESET_OFFSET(SRST_CORE_AISP, 0, 13), + + /* VCPCRU-->SOFTRST_CON01 */ + VCPCRU_RESET_OFFSET(SRST_H_FEC, 1, 0), + VCPCRU_RESET_OFFSET(SRST_A_FEC, 1, 1), + VCPCRU_RESET_OFFSET(SRST_CORE_FEC, 1, 2), + VCPCRU_RESET_OFFSET(SRST_H_AVSP, 1, 3), + VCPCRU_RESET_OFFSET(SRST_A_AVSP, 1, 4), +}; + +void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base) +{ + rockchip_register_softrst_lut(np, + rv1126b_register_offset, + ARRAY_SIZE(rv1126b_register_offset), + reg_base + RV1126B_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); +} From 67e41dbc268a521a61acca25b6cbc70592488b19 Mon Sep 17 00:00:00 2001 From: Yuji Ishikawa Date: Fri, 14 Nov 2025 15:53:57 +0900 Subject: [PATCH 106/117] clk: visconti: Do not define number of clocks in bindings Remove use of TMPV770X_NR_CLK. Instead, define number of clocks inside the driver directory. The same for TMPV770X_NR_RESET and TMPV770X_NR_PLL. Signed-off-by: Yuji Ishikawa Signed-off-by: Stephen Boyd --- drivers/clk/visconti/clkc-tmpv770x.c | 8 ++++++-- drivers/clk/visconti/pll-tmpv770x.c | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/clk/visconti/clkc-tmpv770x.c b/drivers/clk/visconti/clkc-tmpv770x.c index 6c753b2cb558..94a736da6fea 100644 --- a/drivers/clk/visconti/clkc-tmpv770x.c +++ b/drivers/clk/visconti/clkc-tmpv770x.c @@ -17,6 +17,10 @@ #include "clkc.h" #include "reset.h" +/* Must be equal to the last clock/reset ID increased by one */ +#define CLKS_NR (TMPV770X_CLK_BUSLCK + 1) +#define RESETS_NR (TMPV770X_RESET_SBUSCLK + 1) + static DEFINE_SPINLOCK(tmpv770x_clk_lock); static DEFINE_SPINLOCK(tmpv770x_rst_lock); @@ -234,12 +238,12 @@ static int visconti_clk_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); - ctx = visconti_init_clk(dev, regmap, TMPV770X_NR_CLK); + ctx = visconti_init_clk(dev, regmap, CLKS_NR); if (IS_ERR(ctx)) return PTR_ERR(ctx); ret = visconti_register_reset_controller(dev, regmap, clk_reset_data, - TMPV770X_NR_RESET, + RESETS_NR, &visconti_reset_ops, &tmpv770x_rst_lock); if (ret) { diff --git a/drivers/clk/visconti/pll-tmpv770x.c b/drivers/clk/visconti/pll-tmpv770x.c index 8360ccf88867..a2208c5fc12e 100644 --- a/drivers/clk/visconti/pll-tmpv770x.c +++ b/drivers/clk/visconti/pll-tmpv770x.c @@ -16,6 +16,9 @@ #include "pll.h" +/* Must be equal to the last pll ID increased by one */ +#define PLLS_NR (TMPV770X_PLL_PIIMGERPLL + 1) + static DEFINE_SPINLOCK(tmpv770x_pll_lock); static const struct visconti_pll_rate_table pipll0_rates[] __initconst = { @@ -66,7 +69,7 @@ static void __init tmpv770x_setup_plls(struct device_node *np) if (!reg_base) return; - ctx = visconti_init_pll(np, reg_base, TMPV770X_NR_PLL); + ctx = visconti_init_pll(np, reg_base, PLLS_NR); if (IS_ERR(ctx)) { iounmap(reg_base); return; From d10f26a7abbd3dd5d59bac1acdca117385b54ea9 Mon Sep 17 00:00:00 2001 From: Yuji Ishikawa Date: Fri, 14 Nov 2025 15:53:58 +0900 Subject: [PATCH 107/117] dt-bindings: clock: tmpv770x: Remove definition of number of clocks Remove the definitions of number of clocks from bindings because they prevent adding new clocks. Since the previous patch removed all refereces within the driver, they can now be deleted. The same for resets and plls. Signed-off-by: Yuji Ishikawa Acked-by: Conor Dooley Signed-off-by: Stephen Boyd --- include/dt-bindings/clock/toshiba,tmpv770x.h | 3 --- include/dt-bindings/reset/toshiba,tmpv770x.h | 1 - 2 files changed, 4 deletions(-) diff --git a/include/dt-bindings/clock/toshiba,tmpv770x.h b/include/dt-bindings/clock/toshiba,tmpv770x.h index 5fce713001fd..89189c4f6a52 100644 --- a/include/dt-bindings/clock/toshiba,tmpv770x.h +++ b/include/dt-bindings/clock/toshiba,tmpv770x.h @@ -11,7 +11,6 @@ #define TMPV770X_PLL_PIDDRCPLL 4 #define TMPV770X_PLL_PIVOIFPLL 5 #define TMPV770X_PLL_PIIMGERPLL 6 -#define TMPV770X_NR_PLL 7 /* Clocks */ #define TMPV770X_CLK_PIPLL1_DIV1 0 @@ -141,7 +140,6 @@ #define TMPV770X_CLK_PIREFCLK 124 #define TMPV770X_CLK_SBUS 125 #define TMPV770X_CLK_BUSLCK 126 -#define TMPV770X_NR_CLK 127 /* Reset */ #define TMPV770X_RESET_PIETHER_2P5M 0 @@ -176,6 +174,5 @@ #define TMPV770X_RESET_PIPCMIF 29 #define TMPV770X_RESET_PICKMON 30 #define TMPV770X_RESET_SBUSCLK 31 -#define TMPV770X_NR_RESET 32 #endif /*_DT_BINDINGS_CLOCK_TOSHIBA_TMPV770X_H_ */ diff --git a/include/dt-bindings/reset/toshiba,tmpv770x.h b/include/dt-bindings/reset/toshiba,tmpv770x.h index c1007acb1941..bedfe253fa36 100644 --- a/include/dt-bindings/reset/toshiba,tmpv770x.h +++ b/include/dt-bindings/reset/toshiba,tmpv770x.h @@ -36,6 +36,5 @@ #define TMPV770X_RESET_PIPCMIF 29 #define TMPV770X_RESET_PICKMON 30 #define TMPV770X_RESET_SBUSCLK 31 -#define TMPV770X_NR_RESET 32 #endif /*_DT_BINDINGS_RESET_TOSHIBA_TMPV770X_H_ */ From beeff790c5679b3eacc8ee7021f775f447f47603 Mon Sep 17 00:00:00 2001 From: Yuji Ishikawa Date: Fri, 14 Nov 2025 16:05:11 +0900 Subject: [PATCH 108/117] dt-bindings: clock: tmpv770x: Add VIIF clocks Add clock and reset identifiers for the Video Input Interface. These identifiers support two instances: VIIF0 and VIIF1. Signed-off-by: Yuji Ishikawa Acked-by: Conor Dooley Signed-off-by: Stephen Boyd --- include/dt-bindings/clock/toshiba,tmpv770x.h | 11 +++++++++++ include/dt-bindings/reset/toshiba,tmpv770x.h | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/include/dt-bindings/clock/toshiba,tmpv770x.h b/include/dt-bindings/clock/toshiba,tmpv770x.h index 89189c4f6a52..a36c89266686 100644 --- a/include/dt-bindings/clock/toshiba,tmpv770x.h +++ b/include/dt-bindings/clock/toshiba,tmpv770x.h @@ -140,6 +140,9 @@ #define TMPV770X_CLK_PIREFCLK 124 #define TMPV770X_CLK_SBUS 125 #define TMPV770X_CLK_BUSLCK 126 +#define TMPV770X_CLK_VIIFBS1_L2ISP 127 +#define TMPV770X_CLK_VIIFBS1_L1ISP 128 +#define TMPV770X_CLK_VIIFBS1_PROC 129 /* Reset */ #define TMPV770X_RESET_PIETHER_2P5M 0 @@ -174,5 +177,13 @@ #define TMPV770X_RESET_PIPCMIF 29 #define TMPV770X_RESET_PICKMON 30 #define TMPV770X_RESET_SBUSCLK 31 +#define TMPV770X_RESET_VIIFBS0 32 +#define TMPV770X_RESET_VIIFBS0_APB 33 +#define TMPV770X_RESET_VIIFBS0_L2ISP 34 +#define TMPV770X_RESET_VIIFBS0_L1ISP 35 +#define TMPV770X_RESET_VIIFBS1 36 +#define TMPV770X_RESET_VIIFBS1_APB 37 +#define TMPV770X_RESET_VIIFBS1_L2ISP 38 +#define TMPV770X_RESET_VIIFBS1_L1ISP 39 #endif /*_DT_BINDINGS_CLOCK_TOSHIBA_TMPV770X_H_ */ diff --git a/include/dt-bindings/reset/toshiba,tmpv770x.h b/include/dt-bindings/reset/toshiba,tmpv770x.h index bedfe253fa36..9452bef31425 100644 --- a/include/dt-bindings/reset/toshiba,tmpv770x.h +++ b/include/dt-bindings/reset/toshiba,tmpv770x.h @@ -36,5 +36,13 @@ #define TMPV770X_RESET_PIPCMIF 29 #define TMPV770X_RESET_PICKMON 30 #define TMPV770X_RESET_SBUSCLK 31 +#define TMPV770X_RESET_VIIFBS0 32 +#define TMPV770X_RESET_VIIFBS0_APB 33 +#define TMPV770X_RESET_VIIFBS0_L2ISP 34 +#define TMPV770X_RESET_VIIFBS0_L1ISP 35 +#define TMPV770X_RESET_VIIFBS1 36 +#define TMPV770X_RESET_VIIFBS1_APB 37 +#define TMPV770X_RESET_VIIFBS1_L2ISP 38 +#define TMPV770X_RESET_VIIFBS1_L1ISP 39 #endif /*_DT_BINDINGS_RESET_TOSHIBA_TMPV770X_H_ */ From b65e179b986a4812ed38486050a438ce57a873b9 Mon Sep 17 00:00:00 2001 From: Yuji Ishikawa Date: Fri, 14 Nov 2025 16:05:12 +0900 Subject: [PATCH 109/117] clk: visconti: Add VIIF clocks Add the control sequence of register bits to handle the clocks and the resets of Video Input Interface. Signed-off-by: Yuji Ishikawa Signed-off-by: Stephen Boyd --- drivers/clk/visconti/clkc-tmpv770x.c | 75 +++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/clk/visconti/clkc-tmpv770x.c b/drivers/clk/visconti/clkc-tmpv770x.c index 94a736da6fea..1e2e8d6437fe 100644 --- a/drivers/clk/visconti/clkc-tmpv770x.c +++ b/drivers/clk/visconti/clkc-tmpv770x.c @@ -18,8 +18,8 @@ #include "reset.h" /* Must be equal to the last clock/reset ID increased by one */ -#define CLKS_NR (TMPV770X_CLK_BUSLCK + 1) -#define RESETS_NR (TMPV770X_RESET_SBUSCLK + 1) +#define CLKS_NR (TMPV770X_CLK_VIIFBS1_PROC + 1) +#define RESETS_NR (TMPV770X_RESET_VIIFBS1_L1ISP + 1) static DEFINE_SPINLOCK(tmpv770x_clk_lock); static DEFINE_SPINLOCK(tmpv770x_rst_lock); @@ -32,6 +32,10 @@ static const struct clk_parent_data pietherplls_parent_data[] = { { .fw_name = "pietherpll", .name = "pietherpll", }, }; +static const struct clk_parent_data pidnnplls_parent_data[] = { + { .fw_name = "pidnnpll", .name = "pidnnpll", }, +}; + static const struct visconti_fixed_clk fixed_clk_tables[] = { /* PLL1 */ /* PICMPT0/1, PITSC, PIUWDT, PISWDT, PISBUS, PIPMU, PIGPMU, PITMU */ @@ -68,6 +72,41 @@ static const struct visconti_clk_gate_table pietherpll_clk_gate_tables[] = { TMPV770X_RESET_PIETHER_125M, }, }; +static const struct visconti_clk_gate_table pidnnpll_clk_gate_tables[] = { + { TMPV770X_CLK_VIIFBS0, "viifbs0", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 1, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS0_PROC, "viifbs0_proc", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 18, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS0_L1ISP, "viifbs0_l1isp", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 17, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS0_L2ISP, "viifbs0_l2isp", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 16, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS1, "viifbs1", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 5, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS1_PROC, "viifbs1_proc", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 22, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS1_L1ISP, "viifbs1_l1isp", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 21, 1, + NO_RESET, }, + { TMPV770X_CLK_VIIFBS1_L2ISP, "viifbs1_l2isp", + pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data), + 0, 0x58, 0x158, 20, 1, + NO_RESET, }, +}; + static const struct visconti_clk_gate_table clk_gate_tables[] = { { TMPV770X_CLK_HOX, "hox", clks_parent_data, ARRAY_SIZE(clks_parent_data), @@ -189,6 +228,22 @@ static const struct visconti_clk_gate_table clk_gate_tables[] = { clks_parent_data, ARRAY_SIZE(clks_parent_data), 0, 0x14, 0x114, 0, 4, TMPV770X_RESET_SBUSCLK, }, + { TMPV770X_CLK_VIIF0_CFGCLK, "csi2rx0cfg", + clks_parent_data, ARRAY_SIZE(clks_parent_data), + 0, 0x58, 0x158, 0, 24, + NO_RESET, }, + { TMPV770X_CLK_VIIF0_APBCLK, "csi2rx0apb", + clks_parent_data, ARRAY_SIZE(clks_parent_data), + 0, 0x58, 0x158, 2, 4, + NO_RESET, }, + { TMPV770X_CLK_VIIF1_CFGCLK, "csi2rx1cfg", + clks_parent_data, ARRAY_SIZE(clks_parent_data), + 0, 0x58, 0x158, 4, 24, + NO_RESET, }, + { TMPV770X_CLK_VIIF1_APBCLK, "csi2rx1apb", + clks_parent_data, ARRAY_SIZE(clks_parent_data), + 0, 0x58, 0x158, 6, 4, + NO_RESET, }, }; static const struct visconti_reset_data clk_reset_data[] = { @@ -224,6 +279,14 @@ static const struct visconti_reset_data clk_reset_data[] = { [TMPV770X_RESET_PIPCMIF] = { 0x464, 0x564, 0, }, [TMPV770X_RESET_PICKMON] = { 0x410, 0x510, 8, }, [TMPV770X_RESET_SBUSCLK] = { 0x414, 0x514, 0, }, + [TMPV770X_RESET_VIIFBS0] = { 0x458, 0x558, 0, }, + [TMPV770X_RESET_VIIFBS0_APB] = { 0x458, 0x558, 1, }, + [TMPV770X_RESET_VIIFBS0_L2ISP] = { 0x458, 0x558, 16, }, + [TMPV770X_RESET_VIIFBS0_L1ISP] = { 0x458, 0x558, 17, }, + [TMPV770X_RESET_VIIFBS1] = { 0x458, 0x558, 4, }, + [TMPV770X_RESET_VIIFBS1_APB] = { 0x458, 0x558, 5, }, + [TMPV770X_RESET_VIIFBS1_L2ISP] = { 0x458, 0x558, 20, }, + [TMPV770X_RESET_VIIFBS1_L1ISP] = { 0x458, 0x558, 21, }, }; static int visconti_clk_probe(struct platform_device *pdev) @@ -276,6 +339,14 @@ static int visconti_clk_probe(struct platform_device *pdev) return ret; } + ret = visconti_clk_register_gates(ctx, pidnnpll_clk_gate_tables, + ARRAY_SIZE(pidnnpll_clk_gate_tables), + clk_reset_data, &tmpv770x_clk_lock); + if (ret) { + dev_err(dev, "Failed to register pidnnpll clock gate: %d\n", ret); + return ret; + } + return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &ctx->clk_data); } From 23b2d2fb136959fd0a8e309c70be83d9b8841c7e Mon Sep 17 00:00:00 2001 From: Charles Mirabile Date: Mon, 17 Nov 2025 14:03:29 -0500 Subject: [PATCH 110/117] clk: spacemit: Set clk_hw_onecell_data::num before using flex array When booting with KASAN enabled the following splat is encountered during probe of the k1 clock driver: UBSAN: array-index-out-of-bounds in drivers/clk/spacemit/ccu-k1.c:1044:16 index 0 is out of range for type 'clk_hw *[*]' CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc5+ #1 PREEMPT(lazy) Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10spacemit 10/01/2022 Call Trace: [] dump_backtrace+0x28/0x38 [] show_stack+0x3a/0x50 [] dump_stack_lvl+0x5a/0x80 [] dump_stack+0x18/0x20 [] ubsan_epilogue+0x10/0x48 [] __ubsan_handle_out_of_bounds+0xa6/0xa8 [] k1_ccu_probe+0x37e/0x420 [] platform_probe+0x56/0x98 [] really_probe+0x9e/0x350 [] __driver_probe_device+0x80/0x138 [] driver_probe_device+0x3a/0xd0 [] __driver_attach+0xac/0x1b8 [] bus_for_each_dev+0x6c/0xc8 [] driver_attach+0x26/0x38 [] bus_add_driver+0x13e/0x268 [] driver_register+0x52/0x100 [] __platform_driver_register+0x28/0x38 [] k1_ccu_driver_init+0x22/0x38 [] do_one_initcall+0x62/0x2a0 [] do_initcalls+0x170/0x1a8 [] kernel_init_freeable+0x16a/0x1e0 [] kernel_init+0x2c/0x180 [] ret_from_fork_kernel+0x16/0x1d8 [] ret_from_fork_kernel_asm+0x16/0x18 ---[ end trace ]--- This is bogus and is simply a result of KASAN consulting the `.num` member of the struct for bounds information (as it should due to `__counted_by`) and finding 0 set by kzalloc() because it has not been initialized before the loop that fills in the array. The easy fix is to just move the line that sets `num` to before the loop that fills the array so that KASAN has the information it needs to accurately conclude that the access is valid. Fixes: 1b72c59db0add ("clk: spacemit: Add clock support for SpacemiT K1 SoC") Tested-by: Yanko Kaneti Signed-off-by: Charles Mirabile Reviewed-by: Alex Elder Reviewed-by: Troy Mitchell Reviewed-by: Yixun Lan Signed-off-by: Stephen Boyd --- drivers/clk/spacemit/ccu-k1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c index f5a9fe6ba185..4761bc1e3b6e 100644 --- a/drivers/clk/spacemit/ccu-k1.c +++ b/drivers/clk/spacemit/ccu-k1.c @@ -1018,6 +1018,8 @@ static int spacemit_ccu_register(struct device *dev, if (!clk_data) return -ENOMEM; + clk_data->num = data->num; + for (i = 0; i < data->num; i++) { struct clk_hw *hw = data->hws[i]; struct ccu_common *common; @@ -1044,8 +1046,6 @@ static int spacemit_ccu_register(struct device *dev, clk_data->hws[i] = hw; } - clk_data->num = data->num; - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); if (ret) dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); From 1749001151d11b5296754a99f0e845cd2d904a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Barna=C5=9B?= Date: Tue, 28 Oct 2025 15:20:11 +0000 Subject: [PATCH 111/117] clk: actions: Fix discarding const qualifier by 'container_of' macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove const qualifier from functions parameter because it was discarded when container_of was called. Received pointer had mutable access to it through received container. Signed-off-by: Adrian BarnaÅ› Signed-off-by: Stephen Boyd --- drivers/clk/actions/owl-common.h | 2 +- drivers/clk/actions/owl-composite.h | 2 +- drivers/clk/actions/owl-divider.h | 2 +- drivers/clk/actions/owl-factor.h | 2 +- drivers/clk/actions/owl-gate.h | 2 +- drivers/clk/actions/owl-mux.h | 2 +- drivers/clk/actions/owl-pll.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/clk/actions/owl-common.h b/drivers/clk/actions/owl-common.h index 8fb65f3e82d7..5768a2e0f6a0 100644 --- a/drivers/clk/actions/owl-common.h +++ b/drivers/clk/actions/owl-common.h @@ -32,7 +32,7 @@ struct owl_clk_desc { }; static inline struct owl_clk_common * - hw_to_owl_clk_common(const struct clk_hw *hw) + hw_to_owl_clk_common(struct clk_hw *hw) { return container_of(hw, struct owl_clk_common, hw); } diff --git a/drivers/clk/actions/owl-composite.h b/drivers/clk/actions/owl-composite.h index bca38bf8f218..6d7c6f0c47c8 100644 --- a/drivers/clk/actions/owl-composite.h +++ b/drivers/clk/actions/owl-composite.h @@ -108,7 +108,7 @@ struct owl_composite { }, \ } -static inline struct owl_composite *hw_to_owl_comp(const struct clk_hw *hw) +static inline struct owl_composite *hw_to_owl_comp(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-divider.h b/drivers/clk/actions/owl-divider.h index 083be6d80954..d76f58782c52 100644 --- a/drivers/clk/actions/owl-divider.h +++ b/drivers/clk/actions/owl-divider.h @@ -49,7 +49,7 @@ struct owl_divider { }, \ } -static inline struct owl_divider *hw_to_owl_divider(const struct clk_hw *hw) +static inline struct owl_divider *hw_to_owl_divider(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-factor.h b/drivers/clk/actions/owl-factor.h index 04b89cbfdccb..24c704d40925 100644 --- a/drivers/clk/actions/owl-factor.h +++ b/drivers/clk/actions/owl-factor.h @@ -57,7 +57,7 @@ struct owl_factor { #define div_mask(d) ((1 << ((d)->width)) - 1) -static inline struct owl_factor *hw_to_owl_factor(const struct clk_hw *hw) +static inline struct owl_factor *hw_to_owl_factor(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-gate.h b/drivers/clk/actions/owl-gate.h index c2f161c93fda..ac458d4385ee 100644 --- a/drivers/clk/actions/owl-gate.h +++ b/drivers/clk/actions/owl-gate.h @@ -56,7 +56,7 @@ struct owl_gate { }, \ } \ -static inline struct owl_gate *hw_to_owl_gate(const struct clk_hw *hw) +static inline struct owl_gate *hw_to_owl_gate(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-mux.h b/drivers/clk/actions/owl-mux.h index 53b9ab665294..dc0ecc2d5e10 100644 --- a/drivers/clk/actions/owl-mux.h +++ b/drivers/clk/actions/owl-mux.h @@ -44,7 +44,7 @@ struct owl_mux { }, \ } -static inline struct owl_mux *hw_to_owl_mux(const struct clk_hw *hw) +static inline struct owl_mux *hw_to_owl_mux(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); diff --git a/drivers/clk/actions/owl-pll.h b/drivers/clk/actions/owl-pll.h index 78e5fc360b03..58e19f1ade43 100644 --- a/drivers/clk/actions/owl-pll.h +++ b/drivers/clk/actions/owl-pll.h @@ -98,7 +98,7 @@ struct owl_pll { #define mul_mask(m) ((1 << ((m)->width)) - 1) -static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw) +static inline struct owl_pll *hw_to_owl_pll(struct clk_hw *hw) { struct owl_clk_common *common = hw_to_owl_clk_common(hw); From 84898f8e9cea06f8178fc5ca53f068180f7bfba0 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Fri, 21 Nov 2025 15:53:49 +0800 Subject: [PATCH 112/117] dt-bindings: clock: rockchip: Add RK3506 clock and reset unit Add device tree bindings for clock and reset unit on RK3506 SoC. Add clock and reset IDs for RK3506 SoC. Signed-off-by: Finley Xiao Signed-off-by: Elaine Zhang Reviewed-by: Conor Dooley Link: https://patch.msgid.link/20251121075350.2564860-2-zhangqing@rock-chips.com Signed-off-by: Heiko Stuebner --- .../bindings/clock/rockchip,rk3506-cru.yaml | 55 ++++ .../dt-bindings/clock/rockchip,rk3506-cru.h | 285 ++++++++++++++++++ .../dt-bindings/reset/rockchip,rk3506-cru.h | 211 +++++++++++++ 3 files changed, 551 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml new file mode 100644 index 000000000000..ca940475336c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RK3506 Clock and Reset Unit (CRU) + +maintainers: + - Finley Xiao + - Heiko Stuebner + +description: + The RK3506 CRU generates the clock and also implements reset for SoC + peripherals. + +properties: + compatible: + const: rockchip,rk3506-cru + + reg: + maxItems: 1 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + + clocks: + maxItems: 1 + + clock-names: + const: xin + +required: + - compatible + - reg + - "#clock-cells" + - "#reset-cells" + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + clock-controller@ff9a0000 { + compatible = "rockchip,rk3506-cru"; + reg = <0xff9a0000 0x20000>; + #clock-cells = <1>; + #reset-cells = <1>; + clocks = <&xin24m>; + clock-names = "xin"; + }; diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h new file mode 100644 index 000000000000..71d7dda23cc9 --- /dev/null +++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h @@ -0,0 +1,285 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd. + * Author: Finley Xiao + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H + +/* cru plls */ +#define PLL_GPLL 0 +#define PLL_V0PLL 1 +#define PLL_V1PLL 2 + +/* cru-clocks indices */ +#define ARMCLK 3 +#define CLK_DDR 4 +#define XIN24M_GATE 5 +#define CLK_GPLL_GATE 6 +#define CLK_V0PLL_GATE 7 +#define CLK_V1PLL_GATE 8 +#define CLK_GPLL_DIV 9 +#define CLK_GPLL_DIV_100M 10 +#define CLK_V0PLL_DIV 11 +#define CLK_V1PLL_DIV 12 +#define CLK_INT_VOICE_MATRIX0 13 +#define CLK_INT_VOICE_MATRIX1 14 +#define CLK_INT_VOICE_MATRIX2 15 +#define CLK_FRAC_UART_MATRIX0_MUX 16 +#define CLK_FRAC_UART_MATRIX1_MUX 17 +#define CLK_FRAC_VOICE_MATRIX0_MUX 18 +#define CLK_FRAC_VOICE_MATRIX1_MUX 19 +#define CLK_FRAC_COMMON_MATRIX0_MUX 20 +#define CLK_FRAC_COMMON_MATRIX1_MUX 21 +#define CLK_FRAC_COMMON_MATRIX2_MUX 22 +#define CLK_FRAC_UART_MATRIX0 23 +#define CLK_FRAC_UART_MATRIX1 24 +#define CLK_FRAC_VOICE_MATRIX0 25 +#define CLK_FRAC_VOICE_MATRIX1 26 +#define CLK_FRAC_COMMON_MATRIX0 27 +#define CLK_FRAC_COMMON_MATRIX1 28 +#define CLK_FRAC_COMMON_MATRIX2 29 +#define CLK_REF_USBPHY_TOP 30 +#define CLK_REF_DPHY_TOP 31 +#define ACLK_CORE_ROOT 32 +#define PCLK_CORE_ROOT 33 +#define PCLK_DBG 34 +#define PCLK_CORE_GRF 35 +#define PCLK_CORE_CRU 36 +#define CLK_CORE_EMA_DETECT 37 +#define CLK_REF_PVTPLL_CORE 38 +#define PCLK_GPIO1 39 +#define DBCLK_GPIO1 40 +#define ACLK_CORE_PERI_ROOT 41 +#define HCLK_CORE_PERI_ROOT 42 +#define PCLK_CORE_PERI_ROOT 43 +#define CLK_DSMC 44 +#define ACLK_DSMC 45 +#define PCLK_DSMC 46 +#define CLK_FLEXBUS_TX 47 +#define CLK_FLEXBUS_RX 48 +#define ACLK_FLEXBUS 49 +#define HCLK_FLEXBUS 50 +#define ACLK_DSMC_SLV 51 +#define HCLK_DSMC_SLV 52 +#define ACLK_BUS_ROOT 53 +#define HCLK_BUS_ROOT 54 +#define PCLK_BUS_ROOT 55 +#define ACLK_SYSRAM 56 +#define HCLK_SYSRAM 57 +#define ACLK_DMAC0 58 +#define ACLK_DMAC1 59 +#define HCLK_M0 60 +#define PCLK_BUS_GRF 61 +#define PCLK_TIMER 62 +#define CLK_TIMER0_CH0 63 +#define CLK_TIMER0_CH1 64 +#define CLK_TIMER0_CH2 65 +#define CLK_TIMER0_CH3 66 +#define CLK_TIMER0_CH4 67 +#define CLK_TIMER0_CH5 68 +#define PCLK_WDT0 69 +#define TCLK_WDT0 70 +#define PCLK_WDT1 71 +#define TCLK_WDT1 72 +#define PCLK_MAILBOX 73 +#define PCLK_INTMUX 74 +#define PCLK_SPINLOCK 75 +#define PCLK_DDRC 76 +#define HCLK_DDRPHY 77 +#define PCLK_DDRMON 78 +#define CLK_DDRMON_OSC 79 +#define PCLK_STDBY 80 +#define HCLK_USBOTG0 81 +#define HCLK_USBOTG0_PMU 82 +#define CLK_USBOTG0_ADP 83 +#define HCLK_USBOTG1 84 +#define HCLK_USBOTG1_PMU 85 +#define CLK_USBOTG1_ADP 86 +#define PCLK_USBPHY 87 +#define ACLK_DMA2DDR 88 +#define PCLK_DMA2DDR 89 +#define STCLK_M0 90 +#define CLK_DDRPHY 91 +#define CLK_DDRC_SRC 92 +#define ACLK_DDRC_0 93 +#define ACLK_DDRC_1 94 +#define CLK_DDRC 95 +#define CLK_DDRMON 96 +#define HCLK_LSPERI_ROOT 97 +#define PCLK_LSPERI_ROOT 98 +#define PCLK_UART0 99 +#define PCLK_UART1 100 +#define PCLK_UART2 101 +#define PCLK_UART3 102 +#define PCLK_UART4 103 +#define SCLK_UART0 104 +#define SCLK_UART1 105 +#define SCLK_UART2 106 +#define SCLK_UART3 107 +#define SCLK_UART4 108 +#define PCLK_I2C0 109 +#define CLK_I2C0 110 +#define PCLK_I2C1 111 +#define CLK_I2C1 112 +#define PCLK_I2C2 113 +#define CLK_I2C2 114 +#define PCLK_PWM1 115 +#define CLK_PWM1 116 +#define CLK_OSC_PWM1 117 +#define CLK_RC_PWM1 118 +#define CLK_FREQ_PWM1 119 +#define CLK_COUNTER_PWM1 120 +#define PCLK_SPI0 121 +#define CLK_SPI0 122 +#define PCLK_SPI1 123 +#define CLK_SPI1 124 +#define PCLK_GPIO2 125 +#define DBCLK_GPIO2 126 +#define PCLK_GPIO3 127 +#define DBCLK_GPIO3 128 +#define PCLK_GPIO4 129 +#define DBCLK_GPIO4 130 +#define HCLK_CAN0 131 +#define CLK_CAN0 132 +#define HCLK_CAN1 133 +#define CLK_CAN1 134 +#define HCLK_PDM 135 +#define MCLK_PDM 136 +#define CLKOUT_PDM 137 +#define MCLK_SPDIFTX 138 +#define HCLK_SPDIFTX 139 +#define HCLK_SPDIFRX 140 +#define MCLK_SPDIFRX 141 +#define MCLK_SAI0 142 +#define HCLK_SAI0 143 +#define MCLK_OUT_SAI0 144 +#define MCLK_SAI1 145 +#define HCLK_SAI1 146 +#define MCLK_OUT_SAI1 147 +#define HCLK_ASRC0 148 +#define CLK_ASRC0 149 +#define HCLK_ASRC1 150 +#define CLK_ASRC1 151 +#define PCLK_CRU 152 +#define PCLK_PMU_ROOT 153 +#define MCLK_ASRC0 154 +#define MCLK_ASRC1 155 +#define MCLK_ASRC2 156 +#define MCLK_ASRC3 157 +#define LRCK_ASRC0_SRC 158 +#define LRCK_ASRC0_DST 159 +#define LRCK_ASRC1_SRC 160 +#define LRCK_ASRC1_DST 161 +#define ACLK_HSPERI_ROOT 162 +#define HCLK_HSPERI_ROOT 163 +#define PCLK_HSPERI_ROOT 164 +#define CCLK_SRC_SDMMC 165 +#define HCLK_SDMMC 166 +#define HCLK_FSPI 167 +#define SCLK_FSPI 168 +#define PCLK_SPI2 169 +#define ACLK_MAC0 170 +#define ACLK_MAC1 171 +#define PCLK_MAC0 172 +#define PCLK_MAC1 173 +#define CLK_MAC_ROOT 174 +#define CLK_MAC0 175 +#define CLK_MAC1 176 +#define MCLK_SAI2 177 +#define HCLK_SAI2 178 +#define MCLK_OUT_SAI2 179 +#define MCLK_SAI3_SRC 180 +#define HCLK_SAI3 181 +#define MCLK_SAI3 182 +#define MCLK_OUT_SAI3 183 +#define MCLK_SAI4_SRC 184 +#define HCLK_SAI4 185 +#define MCLK_SAI4 186 +#define HCLK_DSM 187 +#define MCLK_DSM 188 +#define PCLK_AUDIO_ADC 189 +#define MCLK_AUDIO_ADC 190 +#define MCLK_AUDIO_ADC_DIV4 191 +#define PCLK_SARADC 192 +#define CLK_SARADC 193 +#define PCLK_OTPC_NS 194 +#define CLK_SBPI_OTPC_NS 195 +#define CLK_USER_OTPC_NS 196 +#define PCLK_UART5 197 +#define SCLK_UART5 198 +#define PCLK_GPIO234_IOC 199 +#define CLK_MAC_PTP_ROOT 200 +#define CLK_MAC0_PTP 201 +#define CLK_MAC1_PTP 202 +#define CLK_SPI2 203 +#define ACLK_VIO_ROOT 204 +#define HCLK_VIO_ROOT 205 +#define PCLK_VIO_ROOT 206 +#define HCLK_RGA 207 +#define ACLK_RGA 208 +#define CLK_CORE_RGA 209 +#define ACLK_VOP 210 +#define HCLK_VOP 211 +#define DCLK_VOP 212 +#define PCLK_DPHY 213 +#define PCLK_DSI_HOST 214 +#define PCLK_TSADC 215 +#define CLK_TSADC 216 +#define CLK_TSADC_TSEN 217 +#define PCLK_GPIO1_IOC 218 +#define PCLK_OTPC_S 219 +#define CLK_SBPI_OTPC_S 220 +#define CLK_USER_OTPC_S 221 +#define PCLK_OTP_MASK 222 +#define PCLK_KEYREADER 223 +#define HCLK_BOOTROM 224 +#define PCLK_DDR_SERVICE 225 +#define HCLK_CRYPTO_S 226 +#define HCLK_KEYLAD 227 +#define CLK_CORE_CRYPTO 228 +#define CLK_PKA_CRYPTO 229 +#define CLK_CORE_CRYPTO_S 230 +#define CLK_PKA_CRYPTO_S 231 +#define ACLK_CRYPTO_S 232 +#define HCLK_RNG_S 233 +#define CLK_CORE_CRYPTO_NS 234 +#define CLK_PKA_CRYPTO_NS 235 +#define ACLK_CRYPTO_NS 236 +#define HCLK_CRYPTO_NS 237 +#define HCLK_RNG 238 +#define CLK_PMU 239 +#define PCLK_PMU 240 +#define CLK_PMU_32K 241 +#define PCLK_PMU_CRU 242 +#define PCLK_PMU_GRF 243 +#define PCLK_GPIO0_IOC 244 +#define PCLK_GPIO0 245 +#define DBCLK_GPIO0 246 +#define PCLK_GPIO1_SHADOW 247 +#define DBCLK_GPIO1_SHADOW 248 +#define PCLK_PMU_HP_TIMER 249 +#define CLK_PMU_HP_TIMER 250 +#define CLK_PMU_HP_TIMER_32K 251 +#define PCLK_PWM0 252 +#define CLK_PWM0 253 +#define CLK_OSC_PWM0 254 +#define CLK_RC_PWM0 255 +#define CLK_MAC_OUT 256 +#define CLK_REF_OUT0 257 +#define CLK_REF_OUT1 258 +#define CLK_32K_FRAC 259 +#define CLK_32K_RC 260 +#define CLK_32K 261 +#define CLK_32K_PMU 262 +#define PCLK_TOUCH_KEY 263 +#define CLK_TOUCH_KEY 264 +#define CLK_REF_PHY_PLL 265 +#define CLK_REF_PHY_PMU_MUX 266 +#define CLK_WIFI_OUT 267 +#define CLK_V0PLL_REF 268 +#define CLK_V1PLL_REF 269 +#define CLK_32K_FRAC_MUX 270 + +#endif diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h new file mode 100644 index 000000000000..31c0d4aa410f --- /dev/null +++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h @@ -0,0 +1,211 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd. + * Author: Finley Xiao + */ + +#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H +#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H + +/* CRU-->SOFTRST_CON00 */ +#define SRST_NCOREPORESET0_AC 0 +#define SRST_NCOREPORESET1_AC 1 +#define SRST_NCOREPORESET2_AC 2 +#define SRST_NCORESET0_AC 3 +#define SRST_NCORESET1_AC 4 +#define SRST_NCORESET2_AC 5 +#define SRST_NL2RESET_AC 6 +#define SRST_A_CORE_BIU_AC 7 +#define SRST_H_M0_AC 8 + +/* CRU-->SOFTRST_CON02 */ +#define SRST_NDBGRESET 9 +#define SRST_P_CORE_BIU 10 +#define SRST_PMU 11 + +/* CRU-->SOFTRST_CON03 */ +#define SRST_P_DBG 12 +#define SRST_POT_DBG 13 +#define SRST_P_CORE_GRF 14 +#define SRST_CORE_EMA_DETECT 15 +#define SRST_REF_PVTPLL_CORE 16 +#define SRST_P_GPIO1 17 +#define SRST_DB_GPIO1 18 + +/* CRU-->SOFTRST_CON04 */ +#define SRST_A_CORE_PERI_BIU 19 +#define SRST_A_DSMC 20 +#define SRST_P_DSMC 21 +#define SRST_FLEXBUS 22 +#define SRST_A_FLEXBUS 23 +#define SRST_H_FLEXBUS 24 +#define SRST_A_DSMC_SLV 25 +#define SRST_H_DSMC_SLV 26 +#define SRST_DSMC_SLV 27 + +/* CRU-->SOFTRST_CON05 */ +#define SRST_A_BUS_BIU 28 +#define SRST_H_BUS_BIU 29 +#define SRST_P_BUS_BIU 30 +#define SRST_A_SYSRAM 31 +#define SRST_H_SYSRAM 32 +#define SRST_A_DMAC0 33 +#define SRST_A_DMAC1 34 +#define SRST_H_M0 35 +#define SRST_M0_JTAG 36 +#define SRST_H_CRYPTO 37 + +/* CRU-->SOFTRST_CON06 */ +#define SRST_H_RNG 38 +#define SRST_P_BUS_GRF 39 +#define SRST_P_TIMER0 40 +#define SRST_TIMER0_CH0 41 +#define SRST_TIMER0_CH1 42 +#define SRST_TIMER0_CH2 43 +#define SRST_TIMER0_CH3 44 +#define SRST_TIMER0_CH4 45 +#define SRST_TIMER0_CH5 46 +#define SRST_P_WDT0 47 +#define SRST_T_WDT0 48 +#define SRST_P_WDT1 49 +#define SRST_T_WDT1 50 +#define SRST_P_MAILBOX 51 +#define SRST_P_INTMUX 52 +#define SRST_P_SPINLOCK 53 + +/* CRU-->SOFTRST_CON07 */ +#define SRST_P_DDRC 54 +#define SRST_H_DDRPHY 55 +#define SRST_P_DDRMON 56 +#define SRST_DDRMON_OSC 57 +#define SRST_P_DDR_LPC 58 +#define SRST_H_USBOTG0 59 +#define SRST_USBOTG0_ADP 60 +#define SRST_H_USBOTG1 61 +#define SRST_USBOTG1_ADP 62 +#define SRST_P_USBPHY 63 +#define SRST_USBPHY_POR 64 +#define SRST_USBPHY_OTG0 65 +#define SRST_USBPHY_OTG1 66 + +/* CRU-->SOFTRST_CON08 */ +#define SRST_A_DMA2DDR 67 +#define SRST_P_DMA2DDR 68 + +/* CRU-->SOFTRST_CON09 */ +#define SRST_USBOTG0_UTMI 69 +#define SRST_USBOTG1_UTMI 70 + +/* CRU-->SOFTRST_CON10 */ +#define SRST_A_DDRC_0 71 +#define SRST_A_DDRC_1 72 +#define SRST_A_DDR_BIU 73 +#define SRST_DDRC 74 +#define SRST_DDRMON 75 + +/* CRU-->SOFTRST_CON11 */ +#define SRST_H_LSPERI_BIU 76 +#define SRST_P_UART0 77 +#define SRST_P_UART1 78 +#define SRST_P_UART2 79 +#define SRST_P_UART3 80 +#define SRST_P_UART4 81 +#define SRST_UART0 82 +#define SRST_UART1 83 +#define SRST_UART2 84 +#define SRST_UART3 85 +#define SRST_UART4 86 +#define SRST_P_I2C0 87 +#define SRST_I2C0 88 + +/* CRU-->SOFTRST_CON12 */ +#define SRST_P_I2C1 89 +#define SRST_I2C1 90 +#define SRST_P_I2C2 91 +#define SRST_I2C2 92 +#define SRST_P_PWM1 93 +#define SRST_PWM1 94 +#define SRST_P_SPI0 95 +#define SRST_SPI0 96 +#define SRST_P_SPI1 97 +#define SRST_SPI1 98 +#define SRST_P_GPIO2 99 +#define SRST_DB_GPIO2 100 + +/* CRU-->SOFTRST_CON13 */ +#define SRST_P_GPIO3 101 +#define SRST_DB_GPIO3 102 +#define SRST_P_GPIO4 103 +#define SRST_DB_GPIO4 104 +#define SRST_H_CAN0 105 +#define SRST_CAN0 106 +#define SRST_H_CAN1 107 +#define SRST_CAN1 108 +#define SRST_H_PDM 109 +#define SRST_M_PDM 110 +#define SRST_PDM 111 +#define SRST_SPDIFTX 112 +#define SRST_H_SPDIFTX 113 +#define SRST_H_SPDIFRX 114 +#define SRST_SPDIFRX 115 +#define SRST_M_SAI0 116 + +/* CRU-->SOFTRST_CON14 */ +#define SRST_H_SAI0 117 +#define SRST_M_SAI1 118 +#define SRST_H_SAI1 119 +#define SRST_H_ASRC0 120 +#define SRST_ASRC0 121 +#define SRST_H_ASRC1 122 +#define SRST_ASRC1 123 + +/* CRU-->SOFTRST_CON17 */ +#define SRST_H_HSPERI_BIU 124 +#define SRST_H_SDMMC 125 +#define SRST_H_FSPI 126 +#define SRST_S_FSPI 127 +#define SRST_P_SPI2 128 +#define SRST_A_MAC0 129 +#define SRST_A_MAC1 130 + +/* CRU-->SOFTRST_CON18 */ +#define SRST_M_SAI2 131 +#define SRST_H_SAI2 132 +#define SRST_H_SAI3 133 +#define SRST_M_SAI3 134 +#define SRST_H_SAI4 135 +#define SRST_M_SAI4 136 +#define SRST_H_DSM 137 +#define SRST_M_DSM 138 +#define SRST_P_AUDIO_ADC 139 +#define SRST_M_AUDIO_ADC 140 + +/* CRU-->SOFTRST_CON19 */ +#define SRST_P_SARADC 141 +#define SRST_SARADC 142 +#define SRST_SARADC_PHY 143 +#define SRST_P_OTPC_NS 144 +#define SRST_SBPI_OTPC_NS 145 +#define SRST_USER_OTPC_NS 146 +#define SRST_P_UART5 147 +#define SRST_UART5 148 +#define SRST_P_GPIO234_IOC 149 + +/* CRU-->SOFTRST_CON21 */ +#define SRST_A_VIO_BIU 150 +#define SRST_H_VIO_BIU 151 +#define SRST_H_RGA 152 +#define SRST_A_RGA 153 +#define SRST_CORE_RGA 154 +#define SRST_A_VOP 155 +#define SRST_H_VOP 156 +#define SRST_VOP 157 +#define SRST_P_DPHY 158 +#define SRST_P_DSI_HOST 159 +#define SRST_P_TSADC 160 +#define SRST_TSADC 161 + +/* CRU-->SOFTRST_CON22 */ +#define SRST_P_GPIO1_IOC 162 + +#endif From 18191dd750e6c9e17fabefd09ff418dd587bcdb9 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Fri, 21 Nov 2025 15:53:50 +0800 Subject: [PATCH 113/117] clk: rockchip: Add clock and reset driver for RK3506 Add the clock and reset tree definitions for the new RK3506 SoC. Signed-off-by: Finley Xiao Signed-off-by: Elaine Zhang Link: https://patch.msgid.link/20251121075350.2564860-3-zhangqing@rock-chips.com Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/Kconfig | 7 + drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk-rk3506.c | 869 ++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 13 + drivers/clk/rockchip/rst-rk3506.c | 226 ++++++++ 5 files changed, 1116 insertions(+) create mode 100644 drivers/clk/rockchip/clk-rk3506.c create mode 100644 drivers/clk/rockchip/rst-rk3506.c diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig index e1ea0a098ca9..5cf1e0fd6fb3 100644 --- a/drivers/clk/rockchip/Kconfig +++ b/drivers/clk/rockchip/Kconfig @@ -100,6 +100,13 @@ config CLK_RK3399 help Build the driver for RK3399 Clock Driver. +config CLK_RK3506 + bool "Rockchip RK3506 clock controller support" + depends on ARM || COMPILE_TEST + default y + help + Build the driver for RK3506 Clock Driver. + config CLK_RK3528 bool "Rockchip RK3528 clock controller support" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 82b4b29ad036..4d8cbb2044c7 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308) += clk-rk3308.o obj-$(CONFIG_CLK_RK3328) += clk-rk3328.o obj-$(CONFIG_CLK_RK3368) += clk-rk3368.o obj-$(CONFIG_CLK_RK3399) += clk-rk3399.o +obj-$(CONFIG_CLK_RK3506) += clk-rk3506.o rst-rk3506.o obj-$(CONFIG_CLK_RK3528) += clk-rk3528.o rst-rk3528.o obj-$(CONFIG_CLK_RK3562) += clk-rk3562.o rst-rk3562.o obj-$(CONFIG_CLK_RK3568) += clk-rk3568.o diff --git a/drivers/clk/rockchip/clk-rk3506.c b/drivers/clk/rockchip/clk-rk3506.c new file mode 100644 index 000000000000..dd59bd60382e --- /dev/null +++ b/drivers/clk/rockchip/clk-rk3506.c @@ -0,0 +1,869 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd. + * Author: Finley Xiao + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define PVTPLL_SRC_SEL_PVTPLL (BIT(7) | BIT(23)) + +enum rk3506_plls { + gpll, v0pll, v1pll, +}; + +/* + * [FRAC PLL]: GPLL, V0PLL, V1PLL + * - VCO Frequency: 950MHz to 3800MHZ + * - Output Frequency: 19MHz to 3800MHZ + * - refdiv: 1 to 63 (Int Mode), 1 to 2 (Frac Mode) + * - fbdiv: 16 to 3800 (Int Mode), 20 to 380 (Frac Mode) + * - post1div: 1 to 7 + * - post2div: 1 to 7 + */ +static struct rockchip_pll_rate_table rk3506_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0), + RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0), + RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0), + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), + RK3036_PLL_RATE(1350000000, 4, 225, 1, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 3, 125, 1, 1, 1, 0), + RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355), + RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127), + RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0), + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185), + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0), + RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0), + RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), + RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(96000000, 1, 48, 6, 2, 1, 0), + { /* sentinel */ }, +}; + +#define RK3506_DIV_ACLK_CORE_MASK 0xf +#define RK3506_DIV_ACLK_CORE_SHIFT 9 +#define RK3506_DIV_PCLK_CORE_MASK 0xf +#define RK3506_DIV_PCLK_CORE_SHIFT 0 + +#define RK3506_CLKSEL15(_aclk_core_div) \ +{ \ + .reg = RK3506_CLKSEL_CON(15), \ + .val = HIWORD_UPDATE(_aclk_core_div, RK3506_DIV_ACLK_CORE_MASK, \ + RK3506_DIV_ACLK_CORE_SHIFT), \ +} + +#define RK3506_CLKSEL16(_pclk_core_div) \ +{ \ + .reg = RK3506_CLKSEL_CON(16), \ + .val = HIWORD_UPDATE(_pclk_core_div, RK3506_DIV_PCLK_CORE_MASK, \ + RK3506_DIV_PCLK_CORE_SHIFT), \ +} + +/* SIGN-OFF: aclk_core: 500M, pclk_core: 125M, */ +#define RK3506_CPUCLK_RATE(_prate, _aclk_core_div, _pclk_core_div) \ +{ \ + .prate = _prate, \ + .divs = { \ + RK3506_CLKSEL15(_aclk_core_div), \ + RK3506_CLKSEL16(_pclk_core_div), \ + }, \ +} + +static struct rockchip_cpuclk_rate_table rk3506_cpuclk_rates[] __initdata = { + RK3506_CPUCLK_RATE(1608000000, 3, 12), + RK3506_CPUCLK_RATE(1512000000, 3, 12), + RK3506_CPUCLK_RATE(1416000000, 2, 11), + RK3506_CPUCLK_RATE(1296000000, 2, 10), + RK3506_CPUCLK_RATE(1200000000, 2, 9), + RK3506_CPUCLK_RATE(1179648000, 2, 9), + RK3506_CPUCLK_RATE(1008000000, 1, 7), + RK3506_CPUCLK_RATE(903168000, 1, 7), + RK3506_CPUCLK_RATE(800000000, 1, 6), + RK3506_CPUCLK_RATE(750000000, 1, 5), + RK3506_CPUCLK_RATE(589824000, 1, 4), + RK3506_CPUCLK_RATE(400000000, 1, 3), + RK3506_CPUCLK_RATE(200000000, 1, 1), +}; + +PNAME(mux_pll_p) = { "xin24m" }; +PNAME(gpll_v0pll_v1pll_parents_p) = { "gpll", "v0pll", "v1pll" }; +PNAME(gpll_v0pll_v1pll_g_parents_p) = { "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(gpll_v0pll_v1pll_div_parents_p) = { "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" }; +PNAME(xin24m_gpll_v0pll_v1pll_g_parents_p) = { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(xin24m_g_gpll_v0pll_v1pll_g_parents_p) = { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(xin24m_g_gpll_v0pll_v1pll_div_parents_p) = { "xin24m_gate", "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" }; +PNAME(xin24m_400k_32k_parents_p) = { "xin24m", "clk_rc", "clk_32k" }; +PNAME(clk_frac_uart_matrix0_mux_parents_p) = { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(clk_timer0_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai0_mclk_in", "sai0_sclk_in" }; +PNAME(clk_timer1_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai1_mclk_in", "sai1_sclk_in" }; +PNAME(clk_timer2_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai2_mclk_in", "sai2_sclk_in" }; +PNAME(clk_timer3_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai3_mclk_in", "sai3_sclk_in" }; +PNAME(clk_timer4_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc0" }; +PNAME(clk_timer5_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc1" }; +PNAME(sclk_uart_parents_p) = { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_frac_uart_matrix0", "clk_frac_uart_matrix1", + "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" }; +PNAME(clk_mac_ptp_root_parents_p) = { "gpll", "v0pll", "v1pll" }; +PNAME(clk_pwm_parents_p) = { "clk_rc", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "sai0_sclk_in", "sai1_sclk_in", + "sai2_sclk_in", "sai3_sclk_in", "mclk_asrc0", "mclk_asrc1" }; +PNAME(clk_can_parents_p) = { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1", + "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" }; +PNAME(clk_pdm_parents_p) = { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2", + "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1", + "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "clk_gpll_div" }; +PNAME(mclk_sai_asrc_parents_p) = { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2", + "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1", + "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in" }; +PNAME(lrck_asrc_parents_p) = { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm", + "sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" }; +PNAME(cclk_src_sdmmc_parents_p) = { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" }; +PNAME(dclk_vop_parents_p) = { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk", + "dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" }; +PNAME(dbclk_gpio0_parents_p) = { "xin24m", "clk_rc", "clk_32k_pmu" }; +PNAME(clk_pmu_hp_timer_parents_p) = { "xin24m", "gpll_div_100m", "clk_core_pvtpll" }; +PNAME(clk_ref_out_parents_p) = { "xin24m", "gpll", "v0pll", "v1pll" }; +PNAME(clk_32k_frac_parents_p) = { "xin24m", "v0pll", "v1pll", "clk_rc" }; +PNAME(clk_32k_parents_p) = { "xin32k", "clk_32k_rc", "clk_32k_frac" }; +PNAME(clk_ref_phy_pmu_mux_parents_p) = { "xin24m", "clk_ref_phy_pll" }; +PNAME(clk_vpll_ref_parents_p) = { "xin24m", "clk_pll_ref_io" }; +PNAME(mux_armclk_p) = { "armclk_pll", "clk_core_pvtpll" }; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_pll_clock rk3506_pll_clks[] __initdata = { + [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p, + CLK_IS_CRITICAL, RK3506_PLL_CON(0), + RK3506_MODE_CON, 0, 2, 0, rk3506_pll_rates), + [v0pll] = PLL(pll_rk3328, PLL_V0PLL, "v0pll", mux_pll_p, + CLK_IS_CRITICAL, RK3506_PLL_CON(8), + RK3506_MODE_CON, 2, 0, 0, rk3506_pll_rates), + [v1pll] = PLL(pll_rk3328, PLL_V1PLL, "v1pll", mux_pll_p, + CLK_IS_CRITICAL, RK3506_PLL_CON(16), + RK3506_MODE_CON, 4, 1, 0, rk3506_pll_rates), +}; + +static struct rockchip_clk_branch rk3506_armclk __initdata = + MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + RK3506_CLKSEL_CON(15), 8, 1, MFLAGS); + +static struct rockchip_clk_branch rk3506_clk_branches[] __initdata = { + /* + * CRU Clock-Architecture + */ + /* top */ + GATE(XIN24M_GATE, "xin24m_gate", "xin24m", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(0), 1, GFLAGS), + GATE(CLK_GPLL_GATE, "clk_gpll_gate", "gpll", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(0), 2, GFLAGS), + GATE(CLK_V0PLL_GATE, "clk_v0pll_gate", "v0pll", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(0), 3, GFLAGS), + GATE(CLK_V1PLL_GATE, "clk_v1pll_gate", "v1pll", 0, + RK3506_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV, "clk_gpll_div", "clk_gpll_gate", CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(0), 6, 4, DFLAGS, + RK3506_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE_NOMUX(CLK_GPLL_DIV_100M, "clk_gpll_div_100m", "clk_gpll_div", 0, + RK3506_CLKSEL_CON(0), 10, 4, DFLAGS, + RK3506_CLKGATE_CON(0), 6, GFLAGS), + COMPOSITE_NOMUX(CLK_V0PLL_DIV, "clk_v0pll_div", "clk_v0pll_gate", CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(1), 0, 4, DFLAGS, + RK3506_CLKGATE_CON(0), 7, GFLAGS), + COMPOSITE_NOMUX(CLK_V1PLL_DIV, "clk_v1pll_div", "clk_v1pll_gate", 0, + RK3506_CLKSEL_CON(1), 4, 4, DFLAGS, + RK3506_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX0, "clk_int_voice_matrix0", "clk_v0pll_gate", 0, + RK3506_CLKSEL_CON(1), 8, 5, DFLAGS, + RK3506_CLKGATE_CON(0), 9, GFLAGS), + COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX1, "clk_int_voice_matrix1", "clk_v1pll_gate", 0, + RK3506_CLKSEL_CON(2), 0, 5, DFLAGS, + RK3506_CLKGATE_CON(0), 10, GFLAGS), + COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX2, "clk_int_voice_matrix2", "clk_v0pll_gate", 0, + RK3506_CLKSEL_CON(2), 5, 5, DFLAGS, + RK3506_CLKGATE_CON(0), 11, GFLAGS), + MUX(CLK_FRAC_UART_MATRIX0_MUX, "clk_frac_uart_matrix0_mux", clk_frac_uart_matrix0_mux_parents_p, 0, + RK3506_CLKSEL_CON(3), 9, 2, MFLAGS), + MUX(CLK_FRAC_UART_MATRIX1_MUX, "clk_frac_uart_matrix1_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(3), 11, 2, MFLAGS), + MUX(CLK_FRAC_VOICE_MATRIX0_MUX, "clk_frac_voice_matrix0_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(3), 13, 2, MFLAGS), + MUX(CLK_FRAC_VOICE_MATRIX1_MUX, "clk_frac_voice_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(4), 0, 2, MFLAGS), + MUX(CLK_FRAC_COMMON_MATRIX0_MUX, "clk_frac_common_matrix0_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(4), 2, 2, MFLAGS), + MUX(CLK_FRAC_COMMON_MATRIX1_MUX, "clk_frac_common_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(4), 4, 2, MFLAGS), + MUX(CLK_FRAC_COMMON_MATRIX2_MUX, "clk_frac_common_matrix2_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(4), 6, 2, MFLAGS), + COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX0, "clk_frac_uart_matrix0", "clk_frac_uart_matrix0_mux", 0, + RK3506_CLKSEL_CON(5), 0, + RK3506_CLKGATE_CON(0), 13, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX1, "clk_frac_uart_matrix1", "clk_frac_uart_matrix1_mux", 0, + RK3506_CLKSEL_CON(6), 0, + RK3506_CLKGATE_CON(0), 14, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX0, "clk_frac_voice_matrix0", "clk_frac_voice_matrix0_mux", 0, + RK3506_CLKSEL_CON(7), 0, + RK3506_CLKGATE_CON(0), 15, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX1, "clk_frac_voice_matrix1", "clk_frac_voice_matrix1_mux", 0, + RK3506_CLKSEL_CON(9), 0, + RK3506_CLKGATE_CON(1), 0, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX0, "clk_frac_common_matrix0", "clk_frac_common_matrix0_mux", 0, + RK3506_CLKSEL_CON(11), 0, + RK3506_CLKGATE_CON(1), 1, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX1, "clk_frac_common_matrix1", "clk_frac_common_matrix1_mux", 0, + RK3506_CLKSEL_CON(12), 0, + RK3506_CLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX2, "clk_frac_common_matrix2", "clk_frac_common_matrix2_mux", 0, + RK3506_CLKSEL_CON(13), 0, + RK3506_CLKGATE_CON(1), 3, GFLAGS), + GATE(CLK_REF_USBPHY_TOP, "clk_ref_usbphy_top", "xin24m", 0, + RK3506_CLKGATE_CON(1), 4, GFLAGS), + GATE(CLK_REF_DPHY_TOP, "clk_ref_dphy_top", "xin24m", 0, + RK3506_CLKGATE_CON(1), 5, GFLAGS), + + /* core */ + COMPOSITE_NOGATE(0, "armclk_pll", gpll_v0pll_v1pll_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS), + COMPOSITE_NOMUX(ACLK_CORE_ROOT, "aclk_core_root", "armclk", CLK_IGNORE_UNUSED, + RK3506_CLKSEL_CON(15), 9, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3506_CLKGATE_CON(2), 11, GFLAGS), + COMPOSITE_NOMUX(PCLK_CORE_ROOT, "pclk_core_root", "armclk", CLK_IGNORE_UNUSED, + RK3506_CLKSEL_CON(16), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3506_CLKGATE_CON(2), 12, GFLAGS), + GATE(PCLK_DBG, "pclk_dbg", "pclk_core_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(3), 1, GFLAGS), + GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_core_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(3), 4, GFLAGS), + GATE(PCLK_CORE_CRU, "pclk_core_cru", "pclk_core_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(3), 5, GFLAGS), + GATE(CLK_CORE_EMA_DETECT, "clk_core_ema_detect", "xin24m_gate", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(3), 6, GFLAGS), + GATE(PCLK_GPIO1, "pclk_gpio1", "aclk_core_root", 0, + RK3506_CLKGATE_CON(3), 8, GFLAGS), + GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m_gate", 0, + RK3506_CLKGATE_CON(3), 9, GFLAGS), + + /* core peri */ + COMPOSITE(ACLK_CORE_PERI_ROOT, "aclk_core_peri_root", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(18), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(4), 0, GFLAGS), + GATE(HCLK_CORE_PERI_ROOT, "hclk_core_peri_root", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 1, GFLAGS), + GATE(PCLK_CORE_PERI_ROOT, "pclk_core_peri_root", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 2, GFLAGS), + COMPOSITE(CLK_DSMC, "clk_dsmc", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(18), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(4), 4, GFLAGS), + GATE(ACLK_DSMC, "aclk_dsmc", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 5, GFLAGS), + GATE(PCLK_DSMC, "pclk_dsmc", "pclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 6, GFLAGS), + COMPOSITE(CLK_FLEXBUS_TX, "clk_flexbus_tx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(19), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(4), 7, GFLAGS), + COMPOSITE(CLK_FLEXBUS_RX, "clk_flexbus_rx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(19), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(4), 8, GFLAGS), + GATE(ACLK_FLEXBUS, "aclk_flexbus", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 9, GFLAGS), + GATE(HCLK_FLEXBUS, "hclk_flexbus", "hclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 10, GFLAGS), + GATE(ACLK_DSMC_SLV, "aclk_dsmc_slv", "aclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 11, GFLAGS), + GATE(HCLK_DSMC_SLV, "hclk_dsmc_slv", "hclk_core_peri_root", 0, + RK3506_CLKGATE_CON(4), 12, GFLAGS), + + /* bus */ + COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(21), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(5), 0, GFLAGS), + COMPOSITE(HCLK_BUS_ROOT, "hclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(21), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(5), 1, GFLAGS), + COMPOSITE(PCLK_BUS_ROOT, "pclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(5), 2, GFLAGS), + GATE(ACLK_SYSRAM, "aclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(5), 6, GFLAGS), + GATE(HCLK_SYSRAM, "hclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(5), 7, GFLAGS), + GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 8, GFLAGS), + GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 9, GFLAGS), + GATE(HCLK_M0, "hclk_m0", "aclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 10, GFLAGS), + GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 14, GFLAGS), + GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(5), 15, GFLAGS), + GATE(HCLK_RNG, "hclk_rng", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 0, GFLAGS), + GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(6), 1, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 2, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH0, "clk_timer0_ch0", clk_timer0_parents_p, 0, + RK3506_CLKSEL_CON(22), 7, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 3, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH1, "clk_timer0_ch1", clk_timer1_parents_p, 0, + RK3506_CLKSEL_CON(22), 10, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 4, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH2, "clk_timer0_ch2", clk_timer2_parents_p, 0, + RK3506_CLKSEL_CON(22), 13, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 5, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH3, "clk_timer0_ch3", clk_timer3_parents_p, 0, + RK3506_CLKSEL_CON(23), 0, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 6, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH4, "clk_timer0_ch4", clk_timer4_parents_p, 0, + RK3506_CLKSEL_CON(23), 3, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 7, GFLAGS), + COMPOSITE_NODIV(CLK_TIMER0_CH5, "clk_timer0_ch5", clk_timer5_parents_p, 0, + RK3506_CLKSEL_CON(23), 6, 3, MFLAGS, + RK3506_CLKGATE_CON(6), 8, GFLAGS), + GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 9, GFLAGS), + GATE(TCLK_WDT0, "tclk_wdt0", "xin24m_gate", 0, + RK3506_CLKGATE_CON(6), 10, GFLAGS), + GATE(PCLK_WDT1, "pclk_wdt1", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 11, GFLAGS), + GATE(TCLK_WDT1, "tclk_wdt1", "xin24m_gate", 0, + RK3506_CLKGATE_CON(6), 12, GFLAGS), + GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 13, GFLAGS), + GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 14, GFLAGS), + GATE(PCLK_SPINLOCK, "pclk_spinlock", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(6), 15, GFLAGS), + GATE(PCLK_DDRC, "pclk_ddrc", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 0, GFLAGS), + GATE(HCLK_DDRPHY, "hclk_ddrphy", "hclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 1, GFLAGS), + GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 2, GFLAGS), + GATE(CLK_DDRMON_OSC, "clk_ddrmon_osc", "xin24m_gate", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 3, GFLAGS), + GATE(PCLK_STDBY, "pclk_stdby", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(7), 4, GFLAGS), + GATE(HCLK_USBOTG0, "hclk_usbotg0", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 5, GFLAGS), + GATE(HCLK_USBOTG0_PMU, "hclk_usbotg0_pmu", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 6, GFLAGS), + GATE(CLK_USBOTG0_ADP, "clk_usbotg0_adp", "clk_32k", 0, + RK3506_CLKGATE_CON(7), 7, GFLAGS), + GATE(HCLK_USBOTG1, "hclk_usbotg1", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 8, GFLAGS), + GATE(HCLK_USBOTG1_PMU, "hclk_usbotg1_pmu", "hclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 9, GFLAGS), + GATE(CLK_USBOTG1_ADP, "clk_usbotg1_adp", "clk_32k", 0, + RK3506_CLKGATE_CON(7), 10, GFLAGS), + GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_bus_root", 0, + RK3506_CLKGATE_CON(7), 11, GFLAGS), + GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(8), 0, GFLAGS), + GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(8), 1, GFLAGS), + COMPOSITE_NOMUX(STCLK_M0, "stclk_m0", "xin24m_gate", 0, + RK3506_CLKSEL_CON(23), 9, 6, DFLAGS, + RK3506_CLKGATE_CON(8), 2, GFLAGS), + COMPOSITE(CLK_DDRPHY, "clk_ddrphy", gpll_v0pll_v1pll_parents_p, CLK_IGNORE_UNUSED, + RK3506_PMU_CLKSEL_CON(4), 4, 2, MFLAGS, 0, 4, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 10, GFLAGS), + FACTOR(CLK_DDRC_SRC, "clk_ddrc_src", "clk_ddrphy", 0, 1, 4), + GATE(ACLK_DDRC_0, "aclk_ddrc_0", "clk_ddrc_src", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(10), 0, GFLAGS), + GATE(ACLK_DDRC_1, "aclk_ddrc_1", "clk_ddrc_src", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(10), 1, GFLAGS), + GATE(CLK_DDRC, "clk_ddrc", "clk_ddrc_src", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(10), 3, GFLAGS), + GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IGNORE_UNUSED, + RK3506_CLKGATE_CON(10), 4, GFLAGS), + + /* ls peri */ + COMPOSITE(HCLK_LSPERI_ROOT, "hclk_lsperi_root", gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(29), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 0, GFLAGS), + GATE(PCLK_LSPERI_ROOT, "pclk_lsperi_root", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 1, GFLAGS), + GATE(PCLK_UART0, "pclk_uart0", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 4, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 5, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 6, GFLAGS), + GATE(PCLK_UART3, "pclk_uart3", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 7, GFLAGS), + GATE(PCLK_UART4, "pclk_uart4", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 8, GFLAGS), + COMPOSITE(SCLK_UART0, "sclk_uart0", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(29), 12, 3, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 9, GFLAGS), + COMPOSITE(SCLK_UART1, "sclk_uart1", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(30), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 10, GFLAGS), + COMPOSITE(SCLK_UART2, "sclk_uart2", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(30), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 11, GFLAGS), + COMPOSITE(SCLK_UART3, "sclk_uart3", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 12, GFLAGS), + COMPOSITE(SCLK_UART4, "sclk_uart4", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK3506_CLKGATE_CON(11), 13, GFLAGS), + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(11), 14, GFLAGS), + COMPOSITE(CLK_I2C0, "clk_i2c0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(32), 4, 2, MFLAGS, 0, 4, DFLAGS, + RK3506_CLKGATE_CON(11), 15, GFLAGS), + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 0, GFLAGS), + COMPOSITE(CLK_I2C1, "clk_i2c1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(32), 10, 2, MFLAGS, 6, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 1, GFLAGS), + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 2, GFLAGS), + COMPOSITE(CLK_I2C2, "clk_i2c2", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(33), 4, 2, MFLAGS, 0, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 3, GFLAGS), + GATE(PCLK_PWM1, "pclk_pwm1", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 4, GFLAGS), + COMPOSITE(CLK_PWM1, "clk_pwm1", gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(33), 10, 2, MFLAGS, 6, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 5, GFLAGS), + GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0, + RK3506_CLKGATE_CON(12), 6, GFLAGS), + GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_rc", 0, + RK3506_CLKGATE_CON(12), 7, GFLAGS), + COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_pwm_parents_p, 0, + RK3506_CLKSEL_CON(33), 12, 4, MFLAGS, + RK3506_CLKGATE_CON(12), 8, GFLAGS), + COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_pwm_parents_p, 0, + RK3506_CLKSEL_CON(34), 0, 4, MFLAGS, + RK3506_CLKGATE_CON(12), 9, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 10, GFLAGS), + COMPOSITE(CLK_SPI0, "clk_spi0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(34), 8, 2, MFLAGS, 4, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 11, GFLAGS), + GATE(PCLK_SPI1, "pclk_spi1", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 12, GFLAGS), + COMPOSITE(CLK_SPI1, "clk_spi1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(34), 14, 2, MFLAGS, 10, 4, DFLAGS, + RK3506_CLKGATE_CON(12), 13, GFLAGS), + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(12), 14, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", xin24m_400k_32k_parents_p, 0, + RK3506_CLKSEL_CON(35), 0, 2, MFLAGS, + RK3506_CLKGATE_CON(12), 15, GFLAGS), + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 0, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", xin24m_400k_32k_parents_p, 0, + RK3506_CLKSEL_CON(35), 2, 2, MFLAGS, + RK3506_CLKGATE_CON(13), 1, GFLAGS), + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 2, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", xin24m_400k_32k_parents_p, 0, + RK3506_CLKSEL_CON(35), 4, 2, MFLAGS, + RK3506_CLKGATE_CON(13), 3, GFLAGS), + GATE(HCLK_CAN0, "hclk_can0", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 4, GFLAGS), + COMPOSITE(CLK_CAN0, "clk_can0", clk_can_parents_p, 0, + RK3506_CLKSEL_CON(35), 11, 3, MFLAGS, 6, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 5, GFLAGS), + GATE(HCLK_CAN1, "hclk_can1", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 6, GFLAGS), + COMPOSITE(CLK_CAN1, "clk_can1", clk_can_parents_p, 0, + RK3506_CLKSEL_CON(36), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 7, GFLAGS), + GATE(HCLK_PDM, "hclk_pdm", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 8, GFLAGS), + COMPOSITE(MCLK_PDM, "mclk_pdm", clk_pdm_parents_p, 0, + RK3506_CLKSEL_CON(37), 5, 4, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 9, GFLAGS), + COMPOSITE(CLKOUT_PDM, "clkout_pdm", clk_pdm_parents_p, 0, + RK3506_CLKSEL_CON(38), 10, 4, MFLAGS, 0, 10, DFLAGS, + RK3506_CLKGATE_CON(13), 10, GFLAGS), + COMPOSITE(MCLK_SPDIFTX, "mclk_spdiftx", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(39), 5, 4, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 11, GFLAGS), + GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 12, GFLAGS), + GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(13), 13, GFLAGS), + COMPOSITE(MCLK_SPDIFRX, "mclk_spdifrx", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(39), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3506_CLKGATE_CON(13), 14, GFLAGS), + COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(40), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(13), 15, GFLAGS), + GATE(HCLK_SAI0, "hclk_sai0", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(14), 0, GFLAGS), + GATE(MCLK_OUT_SAI0, "mclk_out_sai0", "mclk_sai0", 0, + RK3506_CLKGATE_CON(14), 1, GFLAGS), + COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(41), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(14), 2, GFLAGS), + GATE(HCLK_SAI1, "hclk_sai1", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(14), 3, GFLAGS), + GATE(MCLK_OUT_SAI1, "mclk_out_sai1", "mclk_sai1", 0, + RK3506_CLKGATE_CON(14), 4, GFLAGS), + GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(14), 5, GFLAGS), + COMPOSITE(CLK_ASRC0, "clk_asrc0", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(42), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(14), 6, GFLAGS), + GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_lsperi_root", 0, + RK3506_CLKGATE_CON(14), 7, GFLAGS), + COMPOSITE(CLK_ASRC1, "clk_asrc1", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(42), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(14), 8, GFLAGS), + GATE(PCLK_CRU, "pclk_cru", "pclk_lsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(14), 9, GFLAGS), + GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "pclk_lsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(14), 10, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(46), 0, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 0, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(46), 4, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 1, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(46), 8, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 2, GFLAGS), + COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(46), 12, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 3, GFLAGS), + COMPOSITE_NODIV(LRCK_ASRC0_SRC, "lrck_asrc0_src", lrck_asrc_parents_p, 0, + RK3506_CLKSEL_CON(47), 0, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 4, GFLAGS), + COMPOSITE_NODIV(LRCK_ASRC0_DST, "lrck_asrc0_dst", lrck_asrc_parents_p, 0, + RK3506_CLKSEL_CON(47), 4, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 5, GFLAGS), + COMPOSITE_NODIV(LRCK_ASRC1_SRC, "lrck_asrc1_src", lrck_asrc_parents_p, 0, + RK3506_CLKSEL_CON(47), 8, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 6, GFLAGS), + COMPOSITE_NODIV(LRCK_ASRC1_DST, "lrck_asrc1_dst", lrck_asrc_parents_p, 0, + RK3506_CLKSEL_CON(47), 12, 4, MFLAGS, + RK3506_CLKGATE_CON(16), 7, GFLAGS), + + /* hs peri */ + COMPOSITE(ACLK_HSPERI_ROOT, "aclk_hsperi_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL, + RK3506_CLKSEL_CON(49), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(17), 0, GFLAGS), + GATE(HCLK_HSPERI_ROOT, "hclk_hsperi_root", "aclk_hsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(17), 1, GFLAGS), + GATE(PCLK_HSPERI_ROOT, "pclk_hsperi_root", "hclk_hsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(17), 2, GFLAGS), + COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", cclk_src_sdmmc_parents_p, 0, + RK3506_CLKSEL_CON(49), 13, 2, MFLAGS, 7, 6, DFLAGS, + RK3506_CLKGATE_CON(17), 6, GFLAGS), + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 7, GFLAGS), + GATE(HCLK_FSPI, "hclk_fspi", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 8, GFLAGS), + COMPOSITE(SCLK_FSPI, "sclk_fspi", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(50), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(17), 9, GFLAGS), + GATE(PCLK_SPI2, "pclk_spi2", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 10, GFLAGS), + GATE(ACLK_MAC0, "aclk_mac0", "aclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 11, GFLAGS), + GATE(ACLK_MAC1, "aclk_mac1", "aclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 12, GFLAGS), + GATE(PCLK_MAC0, "pclk_mac0", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 13, GFLAGS), + GATE(PCLK_MAC1, "pclk_mac1", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(17), 14, GFLAGS), + COMPOSITE_NOMUX(CLK_MAC_ROOT, "clk_mac_root", "gpll", 0, + RK3506_CLKSEL_CON(50), 7, 5, DFLAGS, + RK3506_CLKGATE_CON(17), 15, GFLAGS), + GATE(CLK_MAC0, "clk_mac0", "clk_mac_root", 0, + RK3506_CLKGATE_CON(18), 0, GFLAGS), + GATE(CLK_MAC1, "clk_mac1", "clk_mac_root", 0, + RK3506_CLKGATE_CON(18), 1, GFLAGS), + COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(51), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(18), 2, GFLAGS), + GATE(HCLK_SAI2, "hclk_sai2", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 3, GFLAGS), + GATE(MCLK_OUT_SAI2, "mclk_out_sai2", "mclk_sai2", 0, + RK3506_CLKGATE_CON(18), 4, GFLAGS), + COMPOSITE(MCLK_SAI3_SRC, "mclk_sai3_src", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(52), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(18), 5, GFLAGS), + GATE(HCLK_SAI3, "hclk_sai3", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 6, GFLAGS), + GATE(MCLK_SAI3, "mclk_sai3", "mclk_sai3_src", 0, + RK3506_CLKGATE_CON(18), 7, GFLAGS), + GATE(MCLK_OUT_SAI3, "mclk_out_sai3", "mclk_sai3_src", 0, + RK3506_CLKGATE_CON(18), 8, GFLAGS), + COMPOSITE(MCLK_SAI4_SRC, "mclk_sai4_src", mclk_sai_asrc_parents_p, 0, + RK3506_CLKSEL_CON(53), 8, 4, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(18), 9, GFLAGS), + GATE(HCLK_SAI4, "hclk_sai4", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 10, GFLAGS), + GATE(MCLK_SAI4, "mclk_sai4", "mclk_sai4_src", 0, + RK3506_CLKGATE_CON(18), 11, GFLAGS), + GATE(HCLK_DSM, "hclk_dsm", "hclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 12, GFLAGS), + GATE(MCLK_DSM, "mclk_dsm", "mclk_sai3_src", 0, + RK3506_CLKGATE_CON(18), 13, GFLAGS), + GATE(PCLK_AUDIO_ADC, "pclk_audio_adc", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(18), 14, GFLAGS), + GATE(MCLK_AUDIO_ADC, "mclk_audio_adc", "mclk_sai4_src", 0, + RK3506_CLKGATE_CON(18), 15, GFLAGS), + FACTOR(MCLK_AUDIO_ADC_DIV4, "mclk_audio_adc_div4", "mclk_audio_adc", 0, 1, 4), + GATE(PCLK_SARADC, "pclk_saradc", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(19), 0, GFLAGS), + COMPOSITE(CLK_SARADC, "clk_saradc", xin24m_400k_32k_parents_p, 0, + RK3506_CLKSEL_CON(54), 4, 2, MFLAGS, 0, 4, DFLAGS, + RK3506_CLKGATE_CON(19), 1, GFLAGS), + GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(19), 3, GFLAGS), + GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m_gate", 0, + RK3506_CLKGATE_CON(19), 4, GFLAGS), + FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2), + GATE(PCLK_UART5, "pclk_uart5", "pclk_hsperi_root", 0, + RK3506_CLKGATE_CON(19), 6, GFLAGS), + COMPOSITE(SCLK_UART5, "sclk_uart5", sclk_uart_parents_p, 0, + RK3506_CLKSEL_CON(54), 11, 3, MFLAGS, 6, 5, DFLAGS, + RK3506_CLKGATE_CON(19), 7, GFLAGS), + GATE(PCLK_GPIO234_IOC, "pclk_gpio234_ioc", "pclk_hsperi_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(19), 8, GFLAGS), + COMPOSITE(CLK_MAC_PTP_ROOT, "clk_mac_ptp_root", clk_mac_ptp_root_parents_p, 0, + RK3506_CLKSEL_CON(55), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(19), 9, GFLAGS), + GATE(CLK_MAC0_PTP, "clk_mac0_ptp", "clk_mac_ptp_root", 0, + RK3506_CLKGATE_CON(19), 10, GFLAGS), + GATE(CLK_MAC1_PTP, "clk_mac1_ptp", "clk_mac_ptp_root", 0, + RK3506_CLKGATE_CON(19), 11, GFLAGS), + COMPOSITE(ACLK_VIO_ROOT, "aclk_vio_root", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(58), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(21), 0, GFLAGS), + COMPOSITE(HCLK_VIO_ROOT, "hclk_vio_root", gpll_v0pll_v1pll_div_parents_p, 0, + RK3506_CLKSEL_CON(58), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3506_CLKGATE_CON(21), 1, GFLAGS), + GATE(PCLK_VIO_ROOT, "pclk_vio_root", "hclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 2, GFLAGS), + GATE(HCLK_RGA, "hclk_rga", "hclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 6, GFLAGS), + GATE(ACLK_RGA, "aclk_rga", "aclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 7, GFLAGS), + COMPOSITE(CLK_CORE_RGA, "clk_core_rga", gpll_v0pll_v1pll_g_parents_p, 0, + RK3506_CLKSEL_CON(59), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3506_CLKGATE_CON(21), 8, GFLAGS), + GATE(ACLK_VOP, "aclk_vop", "aclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 9, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 10, GFLAGS), + COMPOSITE(DCLK_VOP, "dclk_vop", dclk_vop_parents_p, 0, + RK3506_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3506_CLKGATE_CON(21), 11, GFLAGS), + GATE(PCLK_DPHY, "pclk_dphy", "pclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 12, GFLAGS), + GATE(PCLK_DSI_HOST, "pclk_dsi_host", "pclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 13, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vio_root", 0, + RK3506_CLKGATE_CON(21), 14, GFLAGS), + COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m_gate", 0, + RK3506_CLKSEL_CON(61), 0, 8, DFLAGS, + RK3506_CLKGATE_CON(21), 15, GFLAGS), + COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m_gate", 0, + RK3506_CLKSEL_CON(61), 8, 3, DFLAGS, + RK3506_CLKGATE_CON(22), 0, GFLAGS), + GATE(PCLK_GPIO1_IOC, "pclk_gpio1_ioc", "pclk_vio_root", CLK_IS_CRITICAL, + RK3506_CLKGATE_CON(22), 1, GFLAGS), + + /* pmu */ + GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 1, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 2, GFLAGS), + GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 4, GFLAGS), + GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 5, GFLAGS), + GATE(PCLK_GPIO0_IOC, "pclk_gpio0_ioc", "pclk_pmu_root", CLK_IS_CRITICAL, + RK3506_PMU_CLKGATE_CON(0), 7, GFLAGS), + GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0, + RK3506_PMU_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", dbclk_gpio0_parents_p, 0, + RK3506_PMU_CLKSEL_CON(0), 0, 2, MFLAGS, + RK3506_PMU_CLKGATE_CON(0), 9, GFLAGS), + GATE(PCLK_GPIO1_SHADOW, "pclk_gpio1_shadow", "pclk_pmu_root", 0, + RK3506_PMU_CLKGATE_CON(0), 10, GFLAGS), + COMPOSITE_NODIV(DBCLK_GPIO1_SHADOW, "dbclk_gpio1_shadow", dbclk_gpio0_parents_p, 0, + RK3506_PMU_CLKSEL_CON(0), 2, 2, MFLAGS, + RK3506_PMU_CLKGATE_CON(0), 11, GFLAGS), + GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 12, GFLAGS), + MUX(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", clk_pmu_hp_timer_parents_p, CLK_IGNORE_UNUSED, + RK3506_PMU_CLKSEL_CON(0), 4, 2, MFLAGS), + GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pmu_root", 0, + RK3506_PMU_CLKGATE_CON(0), 15, GFLAGS), + COMPOSITE_NOMUX(CLK_PWM0, "clk_pwm0", "clk_gpll_div_100m", 0, + RK3506_PMU_CLKSEL_CON(0), 6, 4, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 0, GFLAGS), + GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0, + RK3506_PMU_CLKGATE_CON(1), 1, GFLAGS), + GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_rc", 0, + RK3506_PMU_CLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_NOMUX(CLK_MAC_OUT, "clk_mac_out", "gpll", 0, + RK3506_PMU_CLKSEL_CON(0), 10, 6, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 3, GFLAGS), + COMPOSITE(CLK_REF_OUT0, "clk_ref_out0", clk_ref_out_parents_p, 0, + RK3506_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 4, GFLAGS), + COMPOSITE(CLK_REF_OUT1, "clk_ref_out1", clk_ref_out_parents_p, 0, + RK3506_PMU_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 5, GFLAGS), + MUX(CLK_32K_FRAC_MUX, "clk_32k_frac_mux", clk_32k_frac_parents_p, 0, + RK3506_PMU_CLKSEL_CON(3), 0, 2, MFLAGS), + COMPOSITE_FRAC(CLK_32K_FRAC, "clk_32k_frac", "clk_32k_frac_mux", 0, + RK3506_PMU_CLKSEL_CON(2), 0, + RK3506_PMU_CLKGATE_CON(1), 6, GFLAGS), + COMPOSITE_NOMUX(CLK_32K_RC, "clk_32k_rc", "clk_rc", CLK_IS_CRITICAL, + RK3506_PMU_CLKSEL_CON(3), 2, 5, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 7, GFLAGS), + COMPOSITE_NODIV(CLK_32K, "clk_32k", clk_32k_parents_p, CLK_IS_CRITICAL, + RK3506_PMU_CLKSEL_CON(3), 7, 2, MFLAGS, + RK3506_PMU_CLKGATE_CON(1), 8, GFLAGS), + COMPOSITE_NODIV(CLK_32K_PMU, "clk_32k_pmu", clk_32k_parents_p, CLK_IS_CRITICAL, + RK3506_PMU_CLKSEL_CON(3), 9, 2, MFLAGS, + RK3506_PMU_CLKGATE_CON(1), 9, GFLAGS), + GATE(CLK_PMU_32K, "clk_pmu_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 3, GFLAGS), + GATE(CLK_PMU_HP_TIMER_32K, "clk_pmu_hp_timer_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(0), 14, GFLAGS), + GATE(PCLK_TOUCH_KEY, "pclk_touch_key", "pclk_pmu_root", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(1), 12, GFLAGS), + GATE(CLK_TOUCH_KEY, "clk_touch_key", "xin24m", CLK_IGNORE_UNUSED, + RK3506_PMU_CLKGATE_CON(1), 13, GFLAGS), + COMPOSITE(CLK_REF_PHY_PLL, "clk_ref_phy_pll", gpll_v0pll_v1pll_parents_p, 0, + RK3506_PMU_CLKSEL_CON(4), 13, 2, MFLAGS, 6, 7, DFLAGS, + RK3506_PMU_CLKGATE_CON(1), 14, GFLAGS), + MUX(CLK_REF_PHY_PMU_MUX, "clk_ref_phy_pmu_mux", clk_ref_phy_pmu_mux_parents_p, 0, + RK3506_PMU_CLKSEL_CON(4), 15, 1, MFLAGS), + GATE(CLK_WIFI_OUT, "clk_wifi_out", "xin24m", 0, + RK3506_PMU_CLKGATE_CON(2), 0, GFLAGS), + MUX(CLK_V0PLL_REF, "clk_v0pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED, + RK3506_PMU_CLKSEL_CON(6), 0, 1, MFLAGS), + MUX(CLK_V1PLL_REF, "clk_v1pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED, + RK3506_PMU_CLKSEL_CON(6), 1, 1, MFLAGS), + + /* secure ns */ + GATE(CLK_CORE_CRYPTO_NS, "clk_core_crypto_ns", "clk_core_crypto", 0, + RK3506_CLKGATE_CON(5), 12, GFLAGS), + GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto", 0, + RK3506_CLKGATE_CON(5), 13, GFLAGS), + + /* io */ + GATE(CLK_SPI2, "clk_spi2", "clk_spi2_io", 0, + RK3506_CLKGATE_CON(20), 0, GFLAGS), +}; + +static void __init rk3506_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + unsigned long clk_nr_clks; + void __iomem *reg_base; + + clk_nr_clks = rockchip_clk_find_max_clk_id(rk3506_clk_branches, + ARRAY_SIZE(rk3506_clk_branches)) + 1; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + + ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); + return; + } + + rockchip_clk_register_plls(ctx, rk3506_pll_clks, + ARRAY_SIZE(rk3506_pll_clks), + 0); + + rockchip_clk_register_armclk_multi_pll(ctx, &rk3506_armclk, + rk3506_cpuclk_rates, + ARRAY_SIZE(rk3506_cpuclk_rates)); + + rockchip_clk_register_branches(ctx, rk3506_clk_branches, + ARRAY_SIZE(rk3506_clk_branches)); + + rk3506_rst_init(np, reg_base); + + rockchip_register_restart_notifier(ctx, RK3506_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); + + /* pvtpll src init */ + writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RK3506_CLKSEL_CON(15)); +} + +CLK_OF_DECLARE(rk3506_cru, "rockchip,rk3506-cru", rk3506_clk_init); + +struct clk_rk3506_inits { + void (*inits)(struct device_node *np); +}; + +static const struct clk_rk3506_inits clk_rk3506_cru_init = { + .inits = rk3506_clk_init, +}; + +static const struct of_device_id clk_rk3506_match_table[] = { + { + .compatible = "rockchip,rk3506-cru", + .data = &clk_rk3506_cru_init, + }, + { } +}; + +static int clk_rk3506_probe(struct platform_device *pdev) +{ + const struct clk_rk3506_inits *init_data; + struct device *dev = &pdev->dev; + + init_data = device_get_match_data(dev); + if (!init_data) + return -EINVAL; + + if (init_data->inits) + init_data->inits(dev->of_node); + + return 0; +} + +static struct platform_driver clk_rk3506_driver = { + .probe = clk_rk3506_probe, + .driver = { + .name = "clk-rk3506", + .of_match_table = clk_rk3506_match_table, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver_probe(clk_rk3506_driver, clk_rk3506_probe); diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 87f09320b942..b2fff1d13a4a 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -275,6 +275,18 @@ struct clk; #define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100) #define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110) +#define RK3506_PMU_CRU_BASE 0x10000 +#define RK3506_PLL_CON(x) ((x) * 0x4 + RK3506_PMU_CRU_BASE) +#define RK3506_CLKSEL_CON(x) ((x) * 0x4 + 0x300) +#define RK3506_CLKGATE_CON(x) ((x) * 0x4 + 0x800) +#define RK3506_SOFTRST_CON(x) ((x) * 0x4 + 0xa00) +#define RK3506_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3506_PMU_CRU_BASE) +#define RK3506_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3506_PMU_CRU_BASE) +#define RK3506_MODE_CON 0x280 +#define RK3506_GLB_CNT_TH 0xc00 +#define RK3506_GLB_SRST_FST 0xc08 +#define RK3506_GLB_SRST_SND 0xc0c + #define RK3528_PMU_CRU_BASE 0x10000 #define RK3528_PCIE_CRU_BASE 0x20000 #define RK3528_DDRPHY_CRU_BASE 0x28000 @@ -1329,6 +1341,7 @@ static inline void rockchip_register_softrst(struct device_node *np, } void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base); +void rk3506_rst_init(struct device_node *np, void __iomem *reg_base); void rk3528_rst_init(struct device_node *np, void __iomem *reg_base); void rk3562_rst_init(struct device_node *np, void __iomem *reg_base); void rk3576_rst_init(struct device_node *np, void __iomem *reg_base); diff --git a/drivers/clk/rockchip/rst-rk3506.c b/drivers/clk/rockchip/rst-rk3506.c new file mode 100644 index 000000000000..c3abde60f3c6 --- /dev/null +++ b/drivers/clk/rockchip/rst-rk3506.c @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + * Author: Finley Xiao + */ + +#include +#include +#include +#include "clk.h" + +/* 0xFF9A0000 + 0x0A00 */ +#define RK3506_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit) + +/* mapping table for reset ID to register offset */ +static const int rk3506_register_offset[] = { + /* CRU-->SOFTRST_CON00 */ + RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET0_AC, 0, 0), + RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET1_AC, 0, 1), + RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET2_AC, 0, 2), + RK3506_CRU_RESET_OFFSET(SRST_NCORESET0_AC, 0, 4), + RK3506_CRU_RESET_OFFSET(SRST_NCORESET1_AC, 0, 5), + RK3506_CRU_RESET_OFFSET(SRST_NCORESET2_AC, 0, 6), + RK3506_CRU_RESET_OFFSET(SRST_NL2RESET_AC, 0, 8), + RK3506_CRU_RESET_OFFSET(SRST_A_CORE_BIU_AC, 0, 9), + RK3506_CRU_RESET_OFFSET(SRST_H_M0_AC, 0, 10), + + /* CRU-->SOFTRST_CON02 */ + RK3506_CRU_RESET_OFFSET(SRST_NDBGRESET, 2, 10), + RK3506_CRU_RESET_OFFSET(SRST_P_CORE_BIU, 2, 14), + RK3506_CRU_RESET_OFFSET(SRST_PMU, 2, 15), + + /* CRU-->SOFTRST_CON03 */ + RK3506_CRU_RESET_OFFSET(SRST_P_DBG, 3, 1), + RK3506_CRU_RESET_OFFSET(SRST_POT_DBG, 3, 2), + RK3506_CRU_RESET_OFFSET(SRST_P_CORE_GRF, 3, 4), + RK3506_CRU_RESET_OFFSET(SRST_CORE_EMA_DETECT, 3, 6), + RK3506_CRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 3, 7), + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1, 3, 8), + RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO1, 3, 9), + + /* CRU-->SOFTRST_CON04 */ + RK3506_CRU_RESET_OFFSET(SRST_A_CORE_PERI_BIU, 4, 3), + RK3506_CRU_RESET_OFFSET(SRST_A_DSMC, 4, 5), + RK3506_CRU_RESET_OFFSET(SRST_P_DSMC, 4, 6), + RK3506_CRU_RESET_OFFSET(SRST_FLEXBUS, 4, 7), + RK3506_CRU_RESET_OFFSET(SRST_A_FLEXBUS, 4, 9), + RK3506_CRU_RESET_OFFSET(SRST_H_FLEXBUS, 4, 10), + RK3506_CRU_RESET_OFFSET(SRST_A_DSMC_SLV, 4, 11), + RK3506_CRU_RESET_OFFSET(SRST_H_DSMC_SLV, 4, 12), + RK3506_CRU_RESET_OFFSET(SRST_DSMC_SLV, 4, 13), + + /* CRU-->SOFTRST_CON05 */ + RK3506_CRU_RESET_OFFSET(SRST_A_BUS_BIU, 5, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_BUS_BIU, 5, 4), + RK3506_CRU_RESET_OFFSET(SRST_P_BUS_BIU, 5, 5), + RK3506_CRU_RESET_OFFSET(SRST_A_SYSRAM, 5, 6), + RK3506_CRU_RESET_OFFSET(SRST_H_SYSRAM, 5, 7), + RK3506_CRU_RESET_OFFSET(SRST_A_DMAC0, 5, 8), + RK3506_CRU_RESET_OFFSET(SRST_A_DMAC1, 5, 9), + RK3506_CRU_RESET_OFFSET(SRST_H_M0, 5, 10), + RK3506_CRU_RESET_OFFSET(SRST_M0_JTAG, 5, 11), + RK3506_CRU_RESET_OFFSET(SRST_H_CRYPTO, 5, 15), + + /* CRU-->SOFTRST_CON06 */ + RK3506_CRU_RESET_OFFSET(SRST_H_RNG, 6, 0), + RK3506_CRU_RESET_OFFSET(SRST_P_BUS_GRF, 6, 1), + RK3506_CRU_RESET_OFFSET(SRST_P_TIMER0, 6, 2), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH0, 6, 3), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH1, 6, 4), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH2, 6, 5), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH3, 6, 6), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH4, 6, 7), + RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH5, 6, 8), + RK3506_CRU_RESET_OFFSET(SRST_P_WDT0, 6, 9), + RK3506_CRU_RESET_OFFSET(SRST_T_WDT0, 6, 10), + RK3506_CRU_RESET_OFFSET(SRST_P_WDT1, 6, 11), + RK3506_CRU_RESET_OFFSET(SRST_T_WDT1, 6, 12), + RK3506_CRU_RESET_OFFSET(SRST_P_MAILBOX, 6, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_INTMUX, 6, 14), + RK3506_CRU_RESET_OFFSET(SRST_P_SPINLOCK, 6, 15), + + /* CRU-->SOFTRST_CON07 */ + RK3506_CRU_RESET_OFFSET(SRST_P_DDRC, 7, 0), + RK3506_CRU_RESET_OFFSET(SRST_H_DDRPHY, 7, 1), + RK3506_CRU_RESET_OFFSET(SRST_P_DDRMON, 7, 2), + RK3506_CRU_RESET_OFFSET(SRST_DDRMON_OSC, 7, 3), + RK3506_CRU_RESET_OFFSET(SRST_P_DDR_LPC, 7, 4), + RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG0, 7, 5), + RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_ADP, 7, 7), + RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG1, 7, 8), + RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_ADP, 7, 10), + RK3506_CRU_RESET_OFFSET(SRST_P_USBPHY, 7, 11), + RK3506_CRU_RESET_OFFSET(SRST_USBPHY_POR, 7, 12), + RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG0, 7, 13), + RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG1, 7, 14), + + /* CRU-->SOFTRST_CON08 */ + RK3506_CRU_RESET_OFFSET(SRST_A_DMA2DDR, 8, 0), + RK3506_CRU_RESET_OFFSET(SRST_P_DMA2DDR, 8, 1), + + /* CRU-->SOFTRST_CON09 */ + RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_UTMI, 9, 0), + RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_UTMI, 9, 1), + + /* CRU-->SOFTRST_CON10 */ + RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_0, 10, 0), + RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_1, 10, 1), + RK3506_CRU_RESET_OFFSET(SRST_A_DDR_BIU, 10, 2), + RK3506_CRU_RESET_OFFSET(SRST_DDRC, 10, 3), + RK3506_CRU_RESET_OFFSET(SRST_DDRMON, 10, 4), + + /* CRU-->SOFTRST_CON11 */ + RK3506_CRU_RESET_OFFSET(SRST_H_LSPERI_BIU, 11, 2), + RK3506_CRU_RESET_OFFSET(SRST_P_UART0, 11, 4), + RK3506_CRU_RESET_OFFSET(SRST_P_UART1, 11, 5), + RK3506_CRU_RESET_OFFSET(SRST_P_UART2, 11, 6), + RK3506_CRU_RESET_OFFSET(SRST_P_UART3, 11, 7), + RK3506_CRU_RESET_OFFSET(SRST_P_UART4, 11, 8), + RK3506_CRU_RESET_OFFSET(SRST_UART0, 11, 9), + RK3506_CRU_RESET_OFFSET(SRST_UART1, 11, 10), + RK3506_CRU_RESET_OFFSET(SRST_UART2, 11, 11), + RK3506_CRU_RESET_OFFSET(SRST_UART3, 11, 12), + RK3506_CRU_RESET_OFFSET(SRST_UART4, 11, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_I2C0, 11, 14), + RK3506_CRU_RESET_OFFSET(SRST_I2C0, 11, 15), + + /* CRU-->SOFTRST_CON12 */ + RK3506_CRU_RESET_OFFSET(SRST_P_I2C1, 12, 0), + RK3506_CRU_RESET_OFFSET(SRST_I2C1, 12, 1), + RK3506_CRU_RESET_OFFSET(SRST_P_I2C2, 12, 2), + RK3506_CRU_RESET_OFFSET(SRST_I2C2, 12, 3), + RK3506_CRU_RESET_OFFSET(SRST_P_PWM1, 12, 4), + RK3506_CRU_RESET_OFFSET(SRST_PWM1, 12, 5), + RK3506_CRU_RESET_OFFSET(SRST_P_SPI0, 12, 10), + RK3506_CRU_RESET_OFFSET(SRST_SPI0, 12, 11), + RK3506_CRU_RESET_OFFSET(SRST_P_SPI1, 12, 12), + RK3506_CRU_RESET_OFFSET(SRST_SPI1, 12, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO2, 12, 14), + RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO2, 12, 15), + + /* CRU-->SOFTRST_CON13 */ + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO3, 13, 0), + RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO3, 13, 1), + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO4, 13, 2), + RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO4, 13, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_CAN0, 13, 4), + RK3506_CRU_RESET_OFFSET(SRST_CAN0, 13, 5), + RK3506_CRU_RESET_OFFSET(SRST_H_CAN1, 13, 6), + RK3506_CRU_RESET_OFFSET(SRST_CAN1, 13, 7), + RK3506_CRU_RESET_OFFSET(SRST_H_PDM, 13, 8), + RK3506_CRU_RESET_OFFSET(SRST_M_PDM, 13, 9), + RK3506_CRU_RESET_OFFSET(SRST_PDM, 13, 10), + RK3506_CRU_RESET_OFFSET(SRST_SPDIFTX, 13, 11), + RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFTX, 13, 12), + RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFRX, 13, 13), + RK3506_CRU_RESET_OFFSET(SRST_SPDIFRX, 13, 14), + RK3506_CRU_RESET_OFFSET(SRST_M_SAI0, 13, 15), + + /* CRU-->SOFTRST_CON14 */ + RK3506_CRU_RESET_OFFSET(SRST_H_SAI0, 14, 0), + RK3506_CRU_RESET_OFFSET(SRST_M_SAI1, 14, 2), + RK3506_CRU_RESET_OFFSET(SRST_H_SAI1, 14, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_ASRC0, 14, 5), + RK3506_CRU_RESET_OFFSET(SRST_ASRC0, 14, 6), + RK3506_CRU_RESET_OFFSET(SRST_H_ASRC1, 14, 7), + RK3506_CRU_RESET_OFFSET(SRST_ASRC1, 14, 8), + + /* CRU-->SOFTRST_CON17 */ + RK3506_CRU_RESET_OFFSET(SRST_H_HSPERI_BIU, 17, 4), + RK3506_CRU_RESET_OFFSET(SRST_H_SDMMC, 17, 7), + RK3506_CRU_RESET_OFFSET(SRST_H_FSPI, 17, 8), + RK3506_CRU_RESET_OFFSET(SRST_S_FSPI, 17, 9), + RK3506_CRU_RESET_OFFSET(SRST_P_SPI2, 17, 10), + RK3506_CRU_RESET_OFFSET(SRST_A_MAC0, 17, 11), + RK3506_CRU_RESET_OFFSET(SRST_A_MAC1, 17, 12), + + /* CRU-->SOFTRST_CON18 */ + RK3506_CRU_RESET_OFFSET(SRST_M_SAI2, 18, 2), + RK3506_CRU_RESET_OFFSET(SRST_H_SAI2, 18, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_SAI3, 18, 6), + RK3506_CRU_RESET_OFFSET(SRST_M_SAI3, 18, 7), + RK3506_CRU_RESET_OFFSET(SRST_H_SAI4, 18, 10), + RK3506_CRU_RESET_OFFSET(SRST_M_SAI4, 18, 11), + RK3506_CRU_RESET_OFFSET(SRST_H_DSM, 18, 12), + RK3506_CRU_RESET_OFFSET(SRST_M_DSM, 18, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_AUDIO_ADC, 18, 14), + RK3506_CRU_RESET_OFFSET(SRST_M_AUDIO_ADC, 18, 15), + + /* CRU-->SOFTRST_CON19 */ + RK3506_CRU_RESET_OFFSET(SRST_P_SARADC, 19, 0), + RK3506_CRU_RESET_OFFSET(SRST_SARADC, 19, 1), + RK3506_CRU_RESET_OFFSET(SRST_SARADC_PHY, 19, 2), + RK3506_CRU_RESET_OFFSET(SRST_P_OTPC_NS, 19, 3), + RK3506_CRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 19, 4), + RK3506_CRU_RESET_OFFSET(SRST_USER_OTPC_NS, 19, 5), + RK3506_CRU_RESET_OFFSET(SRST_P_UART5, 19, 6), + RK3506_CRU_RESET_OFFSET(SRST_UART5, 19, 7), + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO234_IOC, 19, 8), + + /* CRU-->SOFTRST_CON21 */ + RK3506_CRU_RESET_OFFSET(SRST_A_VIO_BIU, 21, 3), + RK3506_CRU_RESET_OFFSET(SRST_H_VIO_BIU, 21, 4), + RK3506_CRU_RESET_OFFSET(SRST_H_RGA, 21, 6), + RK3506_CRU_RESET_OFFSET(SRST_A_RGA, 21, 7), + RK3506_CRU_RESET_OFFSET(SRST_CORE_RGA, 21, 8), + RK3506_CRU_RESET_OFFSET(SRST_A_VOP, 21, 9), + RK3506_CRU_RESET_OFFSET(SRST_H_VOP, 21, 10), + RK3506_CRU_RESET_OFFSET(SRST_VOP, 21, 11), + RK3506_CRU_RESET_OFFSET(SRST_P_DPHY, 21, 12), + RK3506_CRU_RESET_OFFSET(SRST_P_DSI_HOST, 21, 13), + RK3506_CRU_RESET_OFFSET(SRST_P_TSADC, 21, 14), + RK3506_CRU_RESET_OFFSET(SRST_TSADC, 21, 15), + + /* CRU-->SOFTRST_CON22 */ + RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1_IOC, 22, 1), +}; + +void rk3506_rst_init(struct device_node *np, void __iomem *reg_base) +{ + rockchip_register_softrst_lut(np, + rk3506_register_offset, + ARRAY_SIZE(rk3506_register_offset), + reg_base + RK3506_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); +} From cf33f0b7df13685234ccea7be7bfe316b60db4db Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 24 Nov 2025 12:11:06 -0700 Subject: [PATCH 114/117] clk: samsung: exynos-clkout: Assign .num before accessing .hws Commit f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with __counted_by") annotated the hws member of 'struct clk_hw_onecell_data' with __counted_by, which informs the bounds sanitizer (UBSAN_BOUNDS) about the number of elements in .hws[], so that it can warn when .hws[] is accessed out of bounds. As noted in that change, the __counted_by member must be initialized with the number of elements before the first array access happens, otherwise there will be a warning from each access prior to the initialization because the number of elements is zero. This occurs in exynos_clkout_probe() due to .num being assigned after .hws[] has been accessed: UBSAN: array-index-out-of-bounds in drivers/clk/samsung/clk-exynos-clkout.c:178:18 index 0 is out of range for type 'clk_hw *[*]' Move the .num initialization to before the first access of .hws[], clearing up the warning. Cc: stable@vger.kernel.org Fixes: f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with __counted_by") Reported-by: Jochen Sprickerhof Closes: https://lore.kernel.org/aSIYDN5eyKFKoXKL@eldamar.lan/ Tested-by: Jochen Sprickerhof Signed-off-by: Nathan Chancellor Reviewed-by: Kees Cook Reviewed-by: Sam Protsenko Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- drivers/clk/samsung/clk-exynos-clkout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c index 5f1a4f5e2e59..5b21025338bd 100644 --- a/drivers/clk/samsung/clk-exynos-clkout.c +++ b/drivers/clk/samsung/clk-exynos-clkout.c @@ -175,6 +175,7 @@ static int exynos_clkout_probe(struct platform_device *pdev) clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT; clkout->mux.lock = &clkout->slock; + clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout", parent_names, parent_count, &clkout->mux.hw, &clk_mux_ops, NULL, NULL, &clkout->gate.hw, @@ -185,7 +186,6 @@ static int exynos_clkout_probe(struct platform_device *pdev) goto err_unmap; } - clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; ret = of_clk_add_hw_provider(clkout->np, of_clk_hw_onecell_get, &clkout->data); if (ret) goto err_clk_unreg; From 1413717ad0c6d3887192b0119ad6420dbf0c26ae Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sun, 30 Nov 2025 12:02:31 -0800 Subject: [PATCH 115/117] clk: qcom: Mark camcc_sm7150_hws static This isn't used outside this file. Mark it static. Fixes: 9f0532da4226 ("clk: qcom: Add Camera Clock Controller driver for SM7150") Signed-off-by: Stephen Boyd --- drivers/clk/qcom/camcc-sm7150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c index 8b06af8d1509..ee963ed341c3 100644 --- a/drivers/clk/qcom/camcc-sm7150.c +++ b/drivers/clk/qcom/camcc-sm7150.c @@ -1895,7 +1895,7 @@ static struct gdsc camcc_titan_top_gdsc = { .pwrsts = PWRSTS_OFF_ON, }; -struct clk_hw *camcc_sm7150_hws[] = { +static struct clk_hw *camcc_sm7150_hws[] = { [CAMCC_PLL0_OUT_EVEN] = &camcc_pll0_out_even.hw, [CAMCC_PLL0_OUT_ODD] = &camcc_pll0_out_odd.hw, [CAMCC_PLL1_OUT_EVEN] = &camcc_pll1_out_even.hw, From 9c75986a298f121ed2c6599b05e51d9a34e77068 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 27 Nov 2025 14:42:43 +0100 Subject: [PATCH 116/117] clk: keystone: syscon-clk: fix regmap leak on probe failure The mmio regmap allocated during probe is never freed. Switch to using the device managed allocator so that the regmap is released on probe failures (e.g. probe deferral) and on driver unbind. Fixes: a250cd4c1901 ("clk: keystone: syscon-clk: Do not use syscon helper to build regmap") Cc: stable@vger.kernel.org # 6.15 Cc: Andrew Davis Signed-off-by: Johan Hovold Signed-off-by: Stephen Boyd --- drivers/clk/keystone/syscon-clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c index c509929da854..ecf180a7949c 100644 --- a/drivers/clk/keystone/syscon-clk.c +++ b/drivers/clk/keystone/syscon-clk.c @@ -129,7 +129,7 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - regmap = regmap_init_mmio(dev, base, &ti_syscon_regmap_cfg); + regmap = devm_regmap_init_mmio(dev, base, &ti_syscon_regmap_cfg); if (IS_ERR(regmap)) return dev_err_probe(dev, PTR_ERR(regmap), "failed to get regmap\n"); From b276445e98fe28609688fb85b89a81b803910e63 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 27 Nov 2025 14:53:25 +0100 Subject: [PATCH 117/117] clk: keystone: fix compile testing Some keystone clock drivers can be selected when COMPILE_TEST is enabled but since commit b745c0794e2f ("clk: keystone: Add sci-clk driver support") they are never actually built. Enable compile testing by allowing the build system to process the keystone drivers. Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") Signed-off-by: Johan Hovold Signed-off-by: Stephen Boyd --- drivers/clk/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index b74a1767ca27..61ec08404442 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -125,8 +125,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-y += imgtec/ obj-y += imx/ obj-y += ingenic/ -obj-$(CONFIG_ARCH_K3) += keystone/ -obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ +obj-y += keystone/ obj-y += mediatek/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-y += microchip/