From d84bf9d6308e2606b60bb5b4577f8b9ac295cf0b Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Wed, 26 Oct 2022 20:43:41 +0100 Subject: clk: ingenic: Make PLL clock enable_bit and stable_bit optional When the enable bit is undefined, the clock is assumed to be always on and enable/disable is a no-op. When the stable bit is undefined, the PLL stable check is a no-op. Signed-off-by: Aidan MacDonald Link: https://lore.kernel.org/r/20221026194345.243007-3-aidanmacdonald.0x0@gmail.com Reviewed-by: Paul Cercueil Signed-off-by: Stephen Boyd --- drivers/clk/ingenic/cgu.c | 14 +++++++++++++- drivers/clk/ingenic/cgu.h | 10 ++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 0324576f5e62..75524c606a90 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -189,6 +189,9 @@ static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu, { u32 ctl; + if (pll_info->stable_bit < 0) + return 0; + return readl_poll_timeout(cgu->base + pll_info->reg, ctl, ctl & BIT(pll_info->stable_bit), 0, 100 * USEC_PER_MSEC); @@ -230,7 +233,7 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate, writel(ctl, cgu->base + pll_info->reg); /* If the PLL is enabled, verify that it's stable */ - if (ctl & BIT(pll_info->enable_bit)) + if (pll_info->enable_bit >= 0 && (ctl & BIT(pll_info->enable_bit))) ret = ingenic_pll_check_stable(cgu, pll_info); spin_unlock_irqrestore(&cgu->lock, flags); @@ -248,6 +251,9 @@ static int ingenic_pll_enable(struct clk_hw *hw) int ret; u32 ctl; + if (pll_info->enable_bit < 0) + return 0; + spin_lock_irqsave(&cgu->lock, flags); if (pll_info->bypass_bit >= 0) { ctl = readl(cgu->base + pll_info->bypass_reg); @@ -278,6 +284,9 @@ static void ingenic_pll_disable(struct clk_hw *hw) unsigned long flags; u32 ctl; + if (pll_info->enable_bit < 0) + return; + spin_lock_irqsave(&cgu->lock, flags); ctl = readl(cgu->base + pll_info->reg); @@ -295,6 +304,9 @@ static int ingenic_pll_is_enabled(struct clk_hw *hw) const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll; u32 ctl; + if (pll_info->enable_bit < 0) + return true; + ctl = readl(cgu->base + pll_info->reg); return !!(ctl & BIT(pll_info->enable_bit)); diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h index 567142b584bb..a5e44ca7f969 100644 --- a/drivers/clk/ingenic/cgu.h +++ b/drivers/clk/ingenic/cgu.h @@ -42,8 +42,10 @@ * @bypass_reg: the offset of the bypass control register within the CGU * @bypass_bit: the index of the bypass bit in the PLL control register, or * -1 if there is no bypass bit - * @enable_bit: the index of the enable bit in the PLL control register - * @stable_bit: the index of the stable bit in the PLL control register + * @enable_bit: the index of the enable bit in the PLL control register, or + * -1 if there is no enable bit (ie, the PLL is always on) + * @stable_bit: the index of the stable bit in the PLL control register, or + * -1 if there is no stable bit */ struct ingenic_cgu_pll_info { unsigned reg; @@ -54,8 +56,8 @@ struct ingenic_cgu_pll_info { u8 od_shift, od_bits, od_max; unsigned bypass_reg; s8 bypass_bit; - u8 enable_bit; - u8 stable_bit; + s8 enable_bit; + s8 stable_bit; void (*calc_m_n_od)(const struct ingenic_cgu_pll_info *pll_info, unsigned long rate, unsigned long parent_rate, unsigned int *m, unsigned int *n, unsigned int *od); -- cgit v1.2.3