[PATCH v7 5/7] clk: nuvoton: ma35d1: Reparent SYSPLL correctly

From: Miquel Raynal

Date: Fri Oct 02 2026 - 11:02:17 EST


The clock tree is still incorrect. SYSPLL is derived from HXT_GATE, very
much like CAPLL, DDRPLL, VPLL, APLL and EPLL. SYSPLL has a fixed
frequency, but if HXT gets gated, SYSPLL stops running.

Reparent SYSPLL under HXT_GATE to properly define the clock tree
topology. After this change, the frequencies are identical, but the
clock tree looks (again) much closer to the reality.

Since the TRM does not explicitly shows that HIRC and LIRC are
internally sourced from HXT and LXT, respectively, I haven't reparented
them (even though that was tempting). This can be done later anyway.

Side effect: since I am moving to a devm_* clk helper for SYSPLL, I can
reuse this helper to register the other fixed clocks, so they are also
become device managed.

Fixes: 691521a367cf ("clk: nuvoton: Add clock driver for ma35d1 clock controller")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx>
---
drivers/clk/nuvoton/clk-ma35d1.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index 2e6e1c65d01e..0baaa93f1380 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -73,6 +73,8 @@ static const struct clk_parent_data lxtg_parent_data[] = {
{ .fw_name = "lxt", .name = "lxt" },
};

+static struct clk_parent_data syspll_parent_data[] = {};
+
/* Mux parent selection, by index into the controller's clock table */
static const int ca35clk_parent_idx[] = { HXT_GATE, CAPLL, DDRPLL };
static const int sysclk0_parent_idx[] = { EPLL_DIV2, SYSPLL };
@@ -139,9 +141,15 @@ static const struct clk_div_table eadc_div_table[] = {
{13, 28}, {14, 30}, {15, 32}, {0, 0},
};

-static struct clk_hw *ma35d1_clk_fixed(const char *name, int rate)
+static struct clk_hw *ma35d1_clk_fixed_parent_data(struct device *dev, const char *name, int rate,
+ const struct clk_parent_data *parent_data)
{
- return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
+ return devm_clk_hw_register_fixed_rate_parent_data(dev, name, parent_data, 0, rate);
+}
+
+static struct clk_hw *ma35d1_clk_fixed(struct device *dev, const char *name, int rate)
+{
+ return ma35d1_clk_fixed_parent_data(dev, name, rate, NULL);
}

static struct clk_hw *ma35d1_clk_mux(struct device *dev, const char *name,
@@ -275,22 +283,23 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)

/* Old DTs do not describe the low-speed crystal */
if (num_clks == 1)
- hws[LXT] = ma35d1_clk_fixed("lxt", 32768);
+ hws[LXT] = ma35d1_clk_fixed(dev, "lxt", 32768);

hws[HXT_GATE] = ma35d1_clk_gate_parent_data(dev, "hxt_gate", hxtg_parent_data,
clk_base + REG_CLK_PWRCTL, 0);
hws[LXT_GATE] = ma35d1_clk_gate_parent_data(dev, "lxt_gate", lxtg_parent_data,
clk_base + REG_CLK_PWRCTL, 1);
- hws[HIRC] = ma35d1_clk_fixed("hirc", 12000000);
+ hws[HIRC] = ma35d1_clk_fixed(dev, "hirc", 12000000);
hws[HIRC_GATE] = ma35d1_clk_gate(dev, "hirc_gate", "hirc",
clk_base + REG_CLK_PWRCTL, 2);
- hws[LIRC] = ma35d1_clk_fixed("lirc", 32000);
+ hws[LIRC] = ma35d1_clk_fixed(dev, "lirc", 32000);
hws[LIRC_GATE] = ma35d1_clk_gate(dev, "lirc_gate", "lirc",
clk_base + REG_CLK_PWRCTL, 3);

hws[CAPLL] = ma35d1_reg_clk_pll(dev, CAPLL, pllmode[0], "capll",
hws[HXT_GATE], clk_base + REG_CLK_PLL0CTL0);
- hws[SYSPLL] = ma35d1_clk_fixed("syspll", 180000000);
+ syspll_parent_data[0].hw = hws[HXT_GATE];
+ hws[SYSPLL] = ma35d1_clk_fixed_parent_data(dev, "syspll", 180000000, syspll_parent_data);
hws[DDRPLL] = ma35d1_reg_clk_pll(dev, DDRPLL, pllmode[1], "ddrpll",
hws[HXT_GATE], clk_base + REG_CLK_PLL2CTL0);
hws[APLL] = ma35d1_reg_clk_pll(dev, APLL, pllmode[2], "apll",
@@ -331,8 +340,8 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[PCLK3_DIV4096] = ma35d1_clk_fixed_factor(dev, "pclk3_div4096", "pclk3", 1, 4096);
hws[PCLK4_DIV4096] = ma35d1_clk_fixed_factor(dev, "pclk4_div4096", "pclk4", 1, 4096);

- hws[USBPHY0] = ma35d1_clk_fixed("usbphy0", 480000000);
- hws[USBPHY1] = ma35d1_clk_fixed("usbphy1", 480000000);
+ hws[USBPHY0] = ma35d1_clk_fixed(dev, "usbphy0", 480000000);
+ hws[USBPHY1] = ma35d1_clk_fixed(dev, "usbphy1", 480000000);

/* DDR */
hws[DDR0_GATE] = ma35d1_clk_gate(dev, "ddr0_gate", "ddrpll",

--
2.55.0