[v4,8/9] clk: sunxi-ng: sun6i-rtc: split main oscillator div and gate.

Message ID 20260706-a733-rtc-v4-8-f330728db3d3@baylibre.com (mailing list archive)
State New
Headers
Series clk: sun6i-rtc: Add support for Allwinner A733 SoC |

Commit Message

Jerome Brunet July 6, 2026, 9:32 a.m. UTC
On the a733 the "osc24M-32k" clock has the same gate bits as the previously
supported SoC but a different divider implementation.

Instead of a fixed 750 divider, the divider is selected based on the
rate of the oscillator. It can be seen as a simple read-only divider.

To easily replace the divider part depending the SoC, split the divider
and gate into two separate clock entities.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 20 +++++++++++---------
 drivers/clk/sunxi-ng/ccu-sun6i-rtc.h |  3 ++-
 2 files changed, 13 insertions(+), 10 deletions(-)
  

Comments

sashiko-bot@kernel.org July 6, 2026, 10:18 a.m. UTC | #1
> On the a733 the "osc24M-32k" clock has the same gate bits as the previously
> supported SoC but a different divider implementation.
> 
> Instead of a fixed 750 divider, the divider is selected based on the
> rate of the oscillator. It can be seen as a simple read-only divider.
> 
> To easily replace the divider part depending the SoC, split the divider
> and gate into two separate clock entities.
> 
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>

Sashiko has reviewed this patch and found no issues. It looks great!
  
Chen-Yu Tsai July 6, 2026, 3:49 p.m. UTC | #2
On Mon, Jul 6, 2026 at 5:32 PM Jerome Brunet <jbrunet@baylibre.com> wrote:
>
> On the a733 the "osc24M-32k" clock has the same gate bits as the previously
> supported SoC but a different divider implementation.
>
> Instead of a fixed 750 divider, the divider is selected based on the
> rate of the oscillator. It can be seen as a simple read-only divider.
>
> To easily replace the divider part depending the SoC, split the divider
> and gate into two separate clock entities.

Actually, an even bigger reason to do this is because the read-only divider
and gate are in different registers, something that our combined clocks
don't support. So they need to be separate clock entities.

I think this should be mentioned. Otherwise,

Reviewed-by: Chen-Yu Tsai <wens@kernel.org>

> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
> ---
>  drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 20 +++++++++++---------
>  drivers/clk/sunxi-ng/ccu-sun6i-rtc.h |  3 ++-
>  2 files changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
> index b24c8b196e66..25dd87e78eb7 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
> @@ -218,17 +218,18 @@ static const struct clk_parent_data osc24M[] = {
>         { .fw_name = "hosc", .name = "osc24M" }
>  };
>
> -static struct ccu_gate osc24M_32k_clk = {
> -       .enable = BIT(16),
> -       .common = {
> -               .reg            = LOSC_OUT_GATING_REG,
> -               .prediv         = 750,
> -               .features       = CCU_FEATURE_ALL_PREDIV,
> -               .hw.init        = CLK_HW_INIT_PARENTS_DATA("osc24M-32k", osc24M,
> -                                                          &ccu_gate_ops, 0),
> -       },
> +static struct clk_fixed_factor osc24M_32k_div_clk = {
> +       .mult = 1,
> +       .div = 750,
> +       .hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k-div",
> +                                           osc24M,
> +                                           &clk_fixed_factor_ops,
> +                                           0),
>  };
>
> +static SUNXI_CCU_GATE_HW(osc24M_32k_clk, "osc24M-32k", &osc24M_32k_div_clk.hw,
> +                        LOSC_OUT_GATING_REG, BIT(16), 0);
> +
>  static const struct clk_hw *rtc_32k_parents[] = {
>         &osc32k_clk.common.hw,
>         &osc24M_32k_clk.common.hw
> @@ -286,6 +287,7 @@ static struct clk_hw_onecell_data sun6i_rtc_ccu_hw_clks = {
>                 [CLK_EXT_OSC32K_GATE]   = &ext_osc32k_gate_clk.common.hw,
>                 [CLK_OSC24M_32K]        = &osc24M_32k_clk.common.hw,
>                 [CLK_RTC_32K]           = &rtc_32k_clk.common.hw,
> +               [CLK_OSC24M_32K_DIV]    = &osc24M_32k_div_clk.hw,
>         },
>  };
>
> diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h
> index 9ae821fc2599..ab7b92b47f59 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h
> +++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h
> @@ -9,7 +9,8 @@
>  #define CLK_EXT_OSC32K_GATE    4
>  #define CLK_OSC24M_32K         5
>  #define CLK_RTC_32K            6
> +#define CLK_OSC24M_32K_DIV     7
>
> -#define CLK_NUMBER             (CLK_RTC_32K + 1)
> +#define CLK_NUMBER             (CLK_OSC24M_32K_DIV + 1)
>
>  #endif /* _CCU_SUN6I_RTC_H */
>
> --
> 2.47.3
>
  

Patch

diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index b24c8b196e66..25dd87e78eb7 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -218,17 +218,18 @@  static const struct clk_parent_data osc24M[] = {
 	{ .fw_name = "hosc", .name = "osc24M" }
 };
 
-static struct ccu_gate osc24M_32k_clk = {
-	.enable	= BIT(16),
-	.common	= {
-		.reg		= LOSC_OUT_GATING_REG,
-		.prediv		= 750,
-		.features	= CCU_FEATURE_ALL_PREDIV,
-		.hw.init	= CLK_HW_INIT_PARENTS_DATA("osc24M-32k", osc24M,
-							   &ccu_gate_ops, 0),
-	},
+static struct clk_fixed_factor osc24M_32k_div_clk = {
+	.mult = 1,
+	.div = 750,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k-div",
+					    osc24M,
+					    &clk_fixed_factor_ops,
+					    0),
 };
 
+static SUNXI_CCU_GATE_HW(osc24M_32k_clk, "osc24M-32k", &osc24M_32k_div_clk.hw,
+			 LOSC_OUT_GATING_REG, BIT(16), 0);
+
 static const struct clk_hw *rtc_32k_parents[] = {
 	&osc32k_clk.common.hw,
 	&osc24M_32k_clk.common.hw
@@ -286,6 +287,7 @@  static struct clk_hw_onecell_data sun6i_rtc_ccu_hw_clks = {
 		[CLK_EXT_OSC32K_GATE]	= &ext_osc32k_gate_clk.common.hw,
 		[CLK_OSC24M_32K]	= &osc24M_32k_clk.common.hw,
 		[CLK_RTC_32K]		= &rtc_32k_clk.common.hw,
+		[CLK_OSC24M_32K_DIV]	= &osc24M_32k_div_clk.hw,
 	},
 };
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h
index 9ae821fc2599..ab7b92b47f59 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h
@@ -9,7 +9,8 @@ 
 #define CLK_EXT_OSC32K_GATE	4
 #define CLK_OSC24M_32K		5
 #define CLK_RTC_32K		6
+#define CLK_OSC24M_32K_DIV	7
 
-#define CLK_NUMBER		(CLK_RTC_32K + 1)
+#define CLK_NUMBER		(CLK_OSC24M_32K_DIV + 1)
 
 #endif /* _CCU_SUN6I_RTC_H */