On 24/02/2024 21:20, Sam Protsenko wrote: > Some ARM64 Exynos chips are capable to control PLL clocks automatically. > For those chips, whether the PLL is controlled automatically or manually > is chosen in PLL_CON1 register with next bits: > > [28] ENABLE_AUTOMATIC_CLKGATING > [1] MANUAL_PLL_CTRL > [0] AUTO_PLL_CTRL > > The bl2 bootloader sets 0x10000001 value for some PLL_CON1 registers, > which means any attempt to control those PLLs manually (e.g. > disabling/enabling those PLLs or changing MUX parent clocks) would lead > to PLL lock timeout with error message like this: > > Could not lock PLL ... > > At the moment, all Samsung clock drivers implement manual clock control. > So in order to make it possible to control PLLs, corresponding PLL_CON1 > registers should be set to 0x2 first. > > Some older ARM64 chips don't implement the automatic clock control > though. It also might be desirable to configure some PLLs for manual > control, while keeping the default configuration for the rest. So it'd > convenient to choose this PLL mode for each CMU separately. Introduce > .manual_plls field to CMU structure to choose the PLL control mode. > Because it'll be initialized with "false" in all existing CMU > structures by default, it won't affect any existing clock drivers, > allowing for this feature to be enabled gradually when it's needed with > no change for the rest of users. In case .manual_plls is set, set > PLL_CON1 registers to manual control, akin to what's already done for > gate clocks in exynos_arm64_init_clocks(). Of course, PLL_CON1 registers > should be added to corresponding struct samsung_cmu_info::clk_regs array > to make sure they get initialized. > > No functional change. This patch adds a feature, but doesn't enable it > for any users. > > Signed-off-by: Sam Protsenko <semen.protsenko@xxxxxxxxxx> > --- > Changes in v3: > - none > > Changes in v2: > - none > > drivers/clk/samsung/clk-exynos-arm64.c | 44 +++++++++++++++++--------- > drivers/clk/samsung/clk.h | 4 +++ > 2 files changed, 33 insertions(+), 15 deletions(-) > > diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c > index 6fb7194df7ab..55490209b9a9 100644 > --- a/drivers/clk/samsung/clk-exynos-arm64.c > +++ b/drivers/clk/samsung/clk-exynos-arm64.c > @@ -25,6 +25,19 @@ > #define GATE_OFF_START 0x2000 > #define GATE_OFF_END 0x2fff > > +/* PLL CON register offsets range */ > +#define PLL_CON_START 0x100 > +#define PLL_CON_END 0x600 > + > +/* PLL register bits */ > +#define PLL_CON1_MANUAL BIT(1) > + > +/* Helper macros to check for particular clock regiter by its offset */ > +#define IS_GATE_REG(o) ((o) >= GATE_OFF_START && (o) <= GATE_OFF_END) > +#define IS_PLL_CONx_REG(o) ((o) >= PLL_CON_START && (o) <= PLL_CON_END) > +#define IS_PLL_CON1_REG(o) \ > + (IS_PLL_CONx_REG(o) && ((o) & 0xf) == 0x4 && !((o) & 0x10)) These should be static functions, because it leads to trickier code. See also checkpatch warning. Best regards, Krzysztof