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
);
48 regmap_write(regmap
, hd
->droop_reg
, hd
->droop_val
);
53 static void __clk_hfpll_enable(struct clk_hw
*hw
)
55 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
56 struct hfpll_data
const *hd
= h
->d
;
57 struct regmap
*regmap
= h
->clkr
.regmap
;
60 __clk_hfpll_init_once(hw
);
62 /* Disable PLL bypass mode. */
63 regmap_update_bits(regmap
, hd
->mode_reg
, PLL_BYPASSNL
, PLL_BYPASSNL
);
66 * H/W requires a 5us delay between disabling the bypass and
67 * de-asserting the reset. Delay 10us just to be safe.
71 /* De-assert active-low PLL reset. */
72 regmap_update_bits(regmap
, hd
->mode_reg
, PLL_RESET_N
, PLL_RESET_N
);
74 /* Wait for PLL to lock. */
77 regmap_read(regmap
, hd
->status_reg
, &val
);
78 } while (!(val
& BIT(hd
->lock_bit
)));
83 /* Enable PLL output. */
84 regmap_update_bits(regmap
, hd
->mode_reg
, PLL_OUTCTRL
, PLL_OUTCTRL
);
87 /* Enable an already-configured HFPLL. */
88 static int clk_hfpll_enable(struct clk_hw
*hw
)
91 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
92 struct hfpll_data
const *hd
= h
->d
;
93 struct regmap
*regmap
= h
->clkr
.regmap
;
96 spin_lock_irqsave(&h
->lock
, flags
);
97 regmap_read(regmap
, hd
->mode_reg
, &mode
);
98 if (!(mode
& (PLL_BYPASSNL
| PLL_RESET_N
| PLL_OUTCTRL
)))
99 __clk_hfpll_enable(hw
);
100 spin_unlock_irqrestore(&h
->lock
, flags
);
105 static void __clk_hfpll_disable(struct clk_hfpll
*h
)
107 struct hfpll_data
const *hd
= h
->d
;
108 struct regmap
*regmap
= h
->clkr
.regmap
;
111 * Disable the PLL output, disable test mode, enable the bypass mode,
112 * and assert the reset.
114 regmap_update_bits(regmap
, hd
->mode_reg
,
115 PLL_BYPASSNL
| PLL_RESET_N
| PLL_OUTCTRL
, 0);
118 static void clk_hfpll_disable(struct clk_hw
*hw
)
120 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
123 spin_lock_irqsave(&h
->lock
, flags
);
124 __clk_hfpll_disable(h
);
125 spin_unlock_irqrestore(&h
->lock
, flags
);
128 static long clk_hfpll_round_rate(struct clk_hw
*hw
, unsigned long rate
,
129 unsigned long *parent_rate
)
131 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
132 struct hfpll_data
const *hd
= h
->d
;
135 rate
= clamp(rate
, hd
->min_rate
, hd
->max_rate
);
137 rrate
= DIV_ROUND_UP(rate
, *parent_rate
) * *parent_rate
;
138 if (rrate
> hd
->max_rate
)
139 rrate
-= *parent_rate
;
145 * For optimization reasons, assumes no downstream clocks are actively using
148 static int clk_hfpll_set_rate(struct clk_hw
*hw
, unsigned long rate
,
149 unsigned long parent_rate
)
151 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
152 struct hfpll_data
const *hd
= h
->d
;
153 struct regmap
*regmap
= h
->clkr
.regmap
;
158 l_val
= rate
/ parent_rate
;
160 spin_lock_irqsave(&h
->lock
, flags
);
162 enabled
= __clk_is_enabled(hw
->clk
);
164 __clk_hfpll_disable(h
);
166 /* Pick the right VCO. */
167 if (hd
->user_reg
&& hd
->user_vco_mask
) {
168 regmap_read(regmap
, hd
->user_reg
, &val
);
169 if (rate
<= hd
->low_vco_max_rate
)
170 val
&= ~hd
->user_vco_mask
;
172 val
|= hd
->user_vco_mask
;
173 regmap_write(regmap
, hd
->user_reg
, val
);
176 regmap_write(regmap
, hd
->l_reg
, l_val
);
179 __clk_hfpll_enable(hw
);
181 spin_unlock_irqrestore(&h
->lock
, flags
);
186 static unsigned long clk_hfpll_recalc_rate(struct clk_hw
*hw
,
187 unsigned long parent_rate
)
189 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
190 struct hfpll_data
const *hd
= h
->d
;
191 struct regmap
*regmap
= h
->clkr
.regmap
;
194 regmap_read(regmap
, hd
->l_reg
, &l_val
);
196 return l_val
* parent_rate
;
199 static int clk_hfpll_init(struct clk_hw
*hw
)
201 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
202 struct hfpll_data
const *hd
= h
->d
;
203 struct regmap
*regmap
= h
->clkr
.regmap
;
206 regmap_read(regmap
, hd
->mode_reg
, &mode
);
207 if (mode
!= (PLL_BYPASSNL
| PLL_RESET_N
| PLL_OUTCTRL
)) {
208 __clk_hfpll_init_once(hw
);
212 if (hd
->status_reg
) {
213 regmap_read(regmap
, hd
->status_reg
, &status
);
214 if (!(status
& BIT(hd
->lock_bit
))) {
215 WARN(1, "HFPLL %s is ON, but not locked!\n",
216 __clk_get_name(hw
->clk
));
217 clk_hfpll_disable(hw
);
218 __clk_hfpll_init_once(hw
);
225 static int hfpll_is_enabled(struct clk_hw
*hw
)
227 struct clk_hfpll
*h
= to_clk_hfpll(hw
);
228 struct hfpll_data
const *hd
= h
->d
;
229 struct regmap
*regmap
= h
->clkr
.regmap
;
232 regmap_read(regmap
, hd
->mode_reg
, &mode
);
234 return mode
== (PLL_BYPASSNL
| PLL_RESET_N
| PLL_OUTCTRL
);
237 const struct clk_ops clk_ops_hfpll
= {
238 .enable
= clk_hfpll_enable
,
239 .disable
= clk_hfpll_disable
,
240 .is_enabled
= hfpll_is_enabled
,
241 .round_rate
= clk_hfpll_round_rate
,
242 .set_rate
= clk_hfpll_set_rate
,
243 .recalc_rate
= clk_hfpll_recalc_rate
,
244 .init
= clk_hfpll_init
,
246 EXPORT_SYMBOL_GPL(clk_ops_hfpll
);