^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (c) 2018, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "clk-regmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "clk-hfpll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define PLL_OUTCTRL BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define PLL_BYPASSNL BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define PLL_RESET_N BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Initialize a HFPLL at a given rate and enable it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static void __clk_hfpll_init_once(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct regmap *regmap = h->clkr.regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (likely(h->init_done))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Configure PLL parameters for integer mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (hd->config_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) regmap_write(regmap, hd->config_reg, hd->config_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) regmap_write(regmap, hd->m_reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) regmap_write(regmap, hd->n_reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (hd->user_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u32 regval = hd->user_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) rate = clk_hw_get_rate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Pick the right VCO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (hd->user_vco_mask && rate > hd->low_vco_max_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) regval |= hd->user_vco_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) regmap_write(regmap, hd->user_reg, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (hd->droop_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) regmap_write(regmap, hd->droop_reg, hd->droop_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) h->init_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void __clk_hfpll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct regmap *regmap = h->clkr.regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) __clk_hfpll_init_once(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Disable PLL bypass mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) regmap_update_bits(regmap, hd->mode_reg, PLL_BYPASSNL, PLL_BYPASSNL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * H/W requires a 5us delay between disabling the bypass and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * de-asserting the reset. Delay 10us just to be safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* De-assert active-low PLL reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Wait for PLL to lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (hd->status_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) regmap_read(regmap, hd->status_reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) } while (!(val & BIT(hd->lock_bit)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) udelay(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Enable PLL output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Enable an already-configured HFPLL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int clk_hfpll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct regmap *regmap = h->clkr.regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u32 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) spin_lock_irqsave(&h->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) regmap_read(regmap, hd->mode_reg, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (!(mode & (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) __clk_hfpll_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) spin_unlock_irqrestore(&h->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static void __clk_hfpll_disable(struct clk_hfpll *h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct regmap *regmap = h->clkr.regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * Disable the PLL output, disable test mode, enable the bypass mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * and assert the reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) regmap_update_bits(regmap, hd->mode_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void clk_hfpll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) spin_lock_irqsave(&h->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) __clk_hfpll_disable(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) spin_unlock_irqrestore(&h->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static long clk_hfpll_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned long rrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rate = clamp(rate, hd->min_rate, hd->max_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) rrate = DIV_ROUND_UP(rate, *parent_rate) * *parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (rrate > hd->max_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) rrate -= *parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return rrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * For optimization reasons, assumes no downstream clocks are actively using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct regmap *regmap = h->clkr.regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u32 l_val, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) bool enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) l_val = rate / parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) spin_lock_irqsave(&h->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) enabled = __clk_is_enabled(hw->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) __clk_hfpll_disable(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Pick the right VCO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (hd->user_reg && hd->user_vco_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) regmap_read(regmap, hd->user_reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (rate <= hd->low_vco_max_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) val &= ~hd->user_vco_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) val |= hd->user_vco_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) regmap_write(regmap, hd->user_reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) regmap_write(regmap, hd->l_reg, l_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) __clk_hfpll_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) spin_unlock_irqrestore(&h->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct regmap *regmap = h->clkr.regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u32 l_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) regmap_read(regmap, hd->l_reg, &l_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return l_val * parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int clk_hfpll_init(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct regmap *regmap = h->clkr.regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u32 mode, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) regmap_read(regmap, hd->mode_reg, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) __clk_hfpll_init_once(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (hd->status_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) regmap_read(regmap, hd->status_reg, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!(status & BIT(hd->lock_bit))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) WARN(1, "HFPLL %s is ON, but not locked!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) __clk_get_name(hw->clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) clk_hfpll_disable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) __clk_hfpll_init_once(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int hfpll_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct clk_hfpll *h = to_clk_hfpll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct hfpll_data const *hd = h->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct regmap *regmap = h->clkr.regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u32 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) regmap_read(regmap, hd->mode_reg, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mode &= 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return mode == (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) const struct clk_ops clk_ops_hfpll = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .enable = clk_hfpll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .disable = clk_hfpll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .is_enabled = hfpll_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .round_rate = clk_hfpll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .set_rate = clk_hfpll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .recalc_rate = clk_hfpll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .init = clk_hfpll_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) EXPORT_SYMBOL_GPL(clk_ops_hfpll);