1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 #include <linux/kernel.h>
5 #include <linux/export.h>
6 #include <linux/regmap.h>
7 #include <linux/delay.h>
9 #include <linux/clk-provider.h>
10 #include <linux/spinlock.h>
12 #include "clk-regmap.h"
13 #include "clk-hfpll.h"
15 #define PLL_OUTCTRL BIT(0)
16 #define PLL_BYPASSNL BIT(1)
17 #define PLL_RESET_N BIT(2)
19 /* Initialize a HFPLL at a given rate and enable it. */
20 static void __clk_hfpll_init_once(struct clk_hw
*hw
)
22 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
23 struct hfpll_data
const *hd
= h
->d
;
24 struct regmap
*regmap
= h
->clkr
.regmap
;
26 if (likely(h
->init_done
))
29 /* Configure PLL parameters for integer mode. */
31 regmap_write(regmap
, hd
->config_reg
, hd
->config_val
);
32 regmap_write(regmap
, hd
->m_reg
, 0);
33 regmap_write(regmap
, hd
->n_reg
, 1);
36 u32 regval
= hd
->user_val
;
39 rate
= clk_hw_get_rate(hw
);
41 /* Pick the right VCO. */
42 if (hd
->user_vco_mask
&& rate
> hd
->low_vco_max_rate
)
43 regval
|= hd
->user_vco_mask
;
44 regmap_write(regmap
, hd
->user_reg
, regval
);
47 /* Write L_VAL from conf if it exist */
49 regmap_write(regmap
, hd
->l_reg
, hd
->l_val
);
52 regmap_write(regmap
, hd
->droop_reg
, hd
->droop_val
);
57 static void __clk_hfpll_enable(struct clk_hw
*hw
)
59 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
60 struct hfpll_data
const *hd
= h
->d
;
61 struct regmap
*regmap
= h
->clkr
.regmap
;
64 __clk_hfpll_init_once(hw
);
66 /* Disable PLL bypass mode. */
67 regmap_update_bits(regmap
, hd
->mode_reg
, PLL_BYPASSNL
, PLL_BYPASSNL
);
70 * H/W requires a 5us delay between disabling the bypass and
71 * de-asserting the reset. Delay 10us just to be safe.
75 /* De-assert active-low PLL reset. */
76 regmap_update_bits(regmap
, hd
->mode_reg
, PLL_RESET_N
, PLL_RESET_N
);
78 /* Wait for PLL to lock. */
81 * Busy wait. Should never timeout, we add a timeout to
82 * prevent any sort of stall.
84 regmap_read_poll_timeout(regmap
, hd
->status_reg
, val
,
85 !(val
& BIT(hd
->lock_bit
)), 0,
90 /* Enable PLL output. */
91 regmap_update_bits(regmap
, hd
->mode_reg
, PLL_OUTCTRL
, PLL_OUTCTRL
);
94 /* Enable an already-configured HFPLL. */
95 static int clk_hfpll_enable(struct clk_hw
*hw
)
98 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
99 struct hfpll_data
const *hd
= h
->d
;
100 struct regmap
*regmap
= h
->clkr
.regmap
;
103 spin_lock_irqsave(&h
->lock
, flags
);
104 regmap_read(regmap
, hd
->mode_reg
, &mode
);
105 if (!(mode
& (PLL_BYPASSNL
| PLL_RESET_N
| PLL_OUTCTRL
)))
106 __clk_hfpll_enable(hw
);
107 spin_unlock_irqrestore(&h
->lock
, flags
);
112 static void __clk_hfpll_disable(struct clk_hfpll
*h
)
114 struct hfpll_data
const *hd
= h
->d
;
115 struct regmap
*regmap
= h
->clkr
.regmap
;
118 * Disable the PLL output, disable test mode, enable the bypass mode,
119 * and assert the reset.
121 regmap_update_bits(regmap
, hd
->mode_reg
,
122 PLL_BYPASSNL
| PLL_RESET_N
| PLL_OUTCTRL
, 0);
125 static void clk_hfpll_disable(struct clk_hw
*hw
)
127 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
130 spin_lock_irqsave(&h
->lock
, flags
);
131 __clk_hfpll_disable(h
);
132 spin_unlock_irqrestore(&h
->lock
, flags
);
135 static int clk_hfpll_determine_rate(struct clk_hw
*hw
, struct clk_rate_request
*req
)
137 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
138 struct hfpll_data
const *hd
= h
->d
;
141 req
->rate
= clamp(req
->rate
, hd
->min_rate
, hd
->max_rate
);
143 rrate
= DIV_ROUND_UP(req
->rate
, req
->best_parent_rate
) * req
->best_parent_rate
;
144 if (rrate
> hd
->max_rate
)
145 rrate
-= req
->best_parent_rate
;
152 * For optimization reasons, assumes no downstream clocks are actively using
155 static int clk_hfpll_set_rate(struct clk_hw
*hw
, unsigned long rate
,
156 unsigned long parent_rate
)
158 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
159 struct hfpll_data
const *hd
= h
->d
;
160 struct regmap
*regmap
= h
->clkr
.regmap
;
165 l_val
= rate
/ parent_rate
;
167 spin_lock_irqsave(&h
->lock
, flags
);
169 enabled
= __clk_is_enabled(hw
->clk
);
171 __clk_hfpll_disable(h
);
173 /* Pick the right VCO. */
174 if (hd
->user_reg
&& hd
->user_vco_mask
) {
175 regmap_read(regmap
, hd
->user_reg
, &val
);
176 if (rate
<= hd
->low_vco_max_rate
)
177 val
&= ~hd
->user_vco_mask
;
179 val
|= hd
->user_vco_mask
;
180 regmap_write(regmap
, hd
->user_reg
, val
);
183 regmap_write(regmap
, hd
->l_reg
, l_val
);
186 __clk_hfpll_enable(hw
);
188 spin_unlock_irqrestore(&h
->lock
, flags
);
193 static unsigned long clk_hfpll_recalc_rate(struct clk_hw
*hw
,
194 unsigned long parent_rate
)
196 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
197 struct hfpll_data
const *hd
= h
->d
;
198 struct regmap
*regmap
= h
->clkr
.regmap
;
201 regmap_read(regmap
, hd
->l_reg
, &l_val
);
203 return l_val
* parent_rate
;
206 static int clk_hfpll_init(struct clk_hw
*hw
)
208 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
209 struct hfpll_data
const *hd
= h
->d
;
210 struct regmap
*regmap
= h
->clkr
.regmap
;
213 regmap_read(regmap
, hd
->mode_reg
, &mode
);
214 if (mode
!= (PLL_BYPASSNL
| PLL_RESET_N
| PLL_OUTCTRL
)) {
215 __clk_hfpll_init_once(hw
);
219 if (hd
->status_reg
) {
220 regmap_read(regmap
, hd
->status_reg
, &status
);
221 if (!(status
& BIT(hd
->lock_bit
))) {
222 WARN(1, "HFPLL %s is ON, but not locked!\n",
223 __clk_get_name(hw
->clk
));
224 clk_hfpll_disable(hw
);
225 __clk_hfpll_init_once(hw
);
232 static int hfpll_is_enabled(struct clk_hw
*hw
)
234 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
235 struct hfpll_data
const *hd
= h
->d
;
236 struct regmap
*regmap
= h
->clkr
.regmap
;
239 regmap_read(regmap
, hd
->mode_reg
, &mode
);
241 return mode
== (PLL_BYPASSNL
| PLL_RESET_N
| PLL_OUTCTRL
);
244 const struct clk_ops clk_ops_hfpll
= {
245 .enable
= clk_hfpll_enable
,
246 .disable
= clk_hfpll_disable
,
247 .is_enabled
= hfpll_is_enabled
,
248 .determine_rate
= clk_hfpll_determine_rate
,
249 .set_rate
= clk_hfpll_set_rate
,
250 .recalc_rate
= clk_hfpll_recalc_rate
,
251 .init
= clk_hfpll_init
,
253 EXPORT_SYMBOL_GPL(clk_ops_hfpll
);