[PATCH 2/3] clk: stm32mp1: don't disable a PLL while its P/Q/R outputs are enabled
From: Gabriel Fernandez
Date: Tue Oct 20 2026 - 05:50:44 EST
The clock framework only accounts for the users that enabled a PLL
output through it. An output that is already enabled in hardware, for
instance by an earlier boot stage, and not (yet) claimed by its consumer
is unknown to the framework. If another output of the same PLL is then
enabled and disabled by Linux, the PLL enable count drops to zero and
pll_disable() unconditionally clears PLLON, which silently cuts the
clock of the output that is still running.
Don't clear PLLON while at least one of the DIVPEN, DIVQEN or DIVREN
bits is set. The PLL is then switched off by a later disable, once all
its outputs are off.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@xxxxxxxxxxx>
---
drivers/clk/stm32/clk-stm32mp1.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/stm32/clk-stm32mp1.c b/drivers/clk/stm32/clk-stm32mp1.c
index 8f7bb2c31809..077dd3342911 100644
--- a/drivers/clk/stm32/clk-stm32mp1.c
+++ b/drivers/clk/stm32/clk-stm32mp1.c
@@ -755,6 +755,7 @@ struct stm32_pll_obj {
#define PLL_ON BIT(0)
#define PLL_RDY BIT(1)
+#define PLL_DIV_PQR_EN GENMASK(6, 4)
#define DIVN_MASK 0x1FF
#define DIVM_MASK 0x3F
#define DIVM_SHIFT 16
@@ -820,8 +821,12 @@ static void pll_disable(struct clk_hw *hw)
spin_lock_irqsave(clk_elem->lock, flags);
reg = readl_relaxed(clk_elem->reg);
- reg &= ~PLL_ON;
- writel_relaxed(reg, clk_elem->reg);
+
+ /* Keep the PLL on as long as one of its P/Q/R outputs is enabled */
+ if (!(reg & PLL_DIV_PQR_EN)) {
+ reg &= ~PLL_ON;
+ writel_relaxed(reg, clk_elem->reg);
+ }
spin_unlock_irqrestore(clk_elem->lock, flags);
}
--
2.43.0