diff options
author | Manorit Chawdhry | 2024-07-26 04:30:55 -0500 |
---|---|---|
committer | Udit Kumar | 2024-07-26 06:00:12 -0500 |
commit | fda88f8bcea30590528930ff9441c6e958da86f5 (patch) | |
tree | 8433a8576e68a423da8d31ba8af60b2296766438 | |
parent | a99fde602fae9efafeaafd57a7f684557f9cd666 (diff) | |
download | ti-u-boot-fda88f8bcea30590528930ff9441c6e958da86f5.tar.gz ti-u-boot-fda88f8bcea30590528930ff9441c6e958da86f5.tar.xz ti-u-boot-fda88f8bcea30590528930ff9441c6e958da86f5.zip |
clk: ti: clk-k3-pll: Add additional robustness steps to the PLL sequencecicd.scarthgap.202407301155cicd.scarthgap.20240727144310.00.07
Based on the recommendation from HW team make modifications to
the sequence for more robustness.
- Unlock the PLL registers
- Enable external bypass
- Disable the PLL
- Program pllm and pllf
- Program Ref divider
- Enable other PLL controls like DSM_EN, DAC_EN,etc
- Enable calibration if available
- Enable PLL
- Wait for PLL lock and Calibration lock
- Remove external bypass
Re-write the full sequence from scratch as the previous sequence was way
off.
Signed-off-by: Manorit Chawdhry <m-chawdhry@ti.com>
-rw-r--r-- | drivers/clk/ti/clk-k3-pll.c | 333 |
1 files changed, 264 insertions, 69 deletions
diff --git a/drivers/clk/ti/clk-k3-pll.c b/drivers/clk/ti/clk-k3-pll.c index a21d1807bc6..a01d153d14d 100644 --- a/drivers/clk/ti/clk-k3-pll.c +++ b/drivers/clk/ti/clk-k3-pll.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/clk-provider.h> | 15 | #include <linux/clk-provider.h> |
16 | #include "k3-clk.h" | 16 | #include "k3-clk.h" |
17 | #include <linux/rational.h> | 17 | #include <linux/rational.h> |
18 | #include <linux/delay.h> | ||
18 | 19 | ||
19 | /* 16FFT register offsets */ | 20 | /* 16FFT register offsets */ |
20 | #define PLL_16FFT_CFG 0x08 | 21 | #define PLL_16FFT_CFG 0x08 |
@@ -30,10 +31,12 @@ | |||
30 | 31 | ||
31 | /* CAL STAT register bits */ | 32 | /* CAL STAT register bits */ |
32 | #define PLL_16FFT_CAL_STAT_CAL_LOCK BIT(31) | 33 | #define PLL_16FFT_CAL_STAT_CAL_LOCK BIT(31) |
34 | #define PLL_16FFT_CAL_STAT_CAL_LOCK_TIMEOUT (4350U * 100U) | ||
33 | 35 | ||
34 | /* CFG register bits */ | 36 | /* CFG register bits */ |
35 | #define PLL_16FFT_CFG_PLL_TYPE_SHIFT (0) | 37 | #define PLL_16FFT_CFG_PLL_TYPE_SHIFT (0) |
36 | #define PLL_16FFT_CFG_PLL_TYPE_MASK (0x3 << 0) | 38 | #define PLL_16FFT_CFG_PLL_TYPE_MASK (0x3) |
39 | #define PLL_16FFT_CFG_PLL_TYPE_FRAC2 0 | ||
37 | #define PLL_16FFT_CFG_PLL_TYPE_FRACF 1 | 40 | #define PLL_16FFT_CFG_PLL_TYPE_FRACF 1 |
38 | 41 | ||
39 | /* CAL CTRL register bits */ | 42 | /* CAL CTRL register bits */ |
@@ -42,20 +45,27 @@ | |||
42 | #define PLL_16FFT_CAL_CTRL_CAL_BYP BIT(15) | 45 | #define PLL_16FFT_CAL_CTRL_CAL_BYP BIT(15) |
43 | #define PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT 16 | 46 | #define PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT 16 |
44 | #define PLL_16FFT_CAL_CTRL_CAL_CNT_MASK (0x7 << 16) | 47 | #define PLL_16FFT_CAL_CTRL_CAL_CNT_MASK (0x7 << 16) |
48 | #define PLL_16FFT_CAL_CTRL_CAL_IN_MASK (0xFFFU) | ||
45 | 49 | ||
46 | /* CTRL register bits */ | 50 | /* CTRL register bits */ |
47 | #define PLL_16FFT_CTRL_BYPASS_EN BIT(31) | 51 | #define PLL_16FFT_CTRL_BYPASS_EN BIT(31) |
52 | #define PLL_16FFT_CTRL_BYP_ON_LOCKLOSS BIT(16) | ||
48 | #define PLL_16FFT_CTRL_PLL_EN BIT(15) | 53 | #define PLL_16FFT_CTRL_PLL_EN BIT(15) |
54 | #define PLL_16FFT_CTRL_INTL_BYP_EN BIT(8) | ||
55 | #define PLL_16FFT_CTRL_CLK_4PH_EN BIT(5) | ||
56 | #define PLL_16FFT_CTRL_CLK_POSTDIV_EN BIT(4) | ||
49 | #define PLL_16FFT_CTRL_DSM_EN BIT(1) | 57 | #define PLL_16FFT_CTRL_DSM_EN BIT(1) |
58 | #define PLL_16FFT_CTRL_DAC_EN BIT(0) | ||
50 | 59 | ||
51 | /* STAT register bits */ | 60 | /* STAT register bits */ |
52 | #define PLL_16FFT_STAT_LOCK BIT(0) | 61 | #define PLL_16FFT_STAT_LOCK BIT(0) |
62 | #define PLL_16FFT_STAT_LOCK_TIMEOUT (150U * 100U) | ||
53 | 63 | ||
54 | /* FREQ_CTRL0 bits */ | 64 | /* FREQ_CTRL0 bits */ |
55 | #define PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK 0xfff | 65 | #define PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK 0xfff |
56 | 66 | ||
57 | /* DIV CTRL register bits */ | 67 | /* DIV CTRL register bits */ |
58 | #define PLL_16FFT_DIV_CTRL_REF_DIV_MASK 0x3f | 68 | #define PLL_16FFT_DIV_CTRL_REF_DIV_MASK 0x3f |
59 | 69 | ||
60 | /* HSDIV register bits*/ | 70 | /* HSDIV register bits*/ |
61 | #define PLL_16FFT_HSDIV_CTRL_CLKOUT_EN BIT(15) | 71 | #define PLL_16FFT_HSDIV_CTRL_CLKOUT_EN BIT(15) |
@@ -63,7 +73,6 @@ | |||
63 | /* FREQ_CTRL1 bits */ | 73 | /* FREQ_CTRL1 bits */ |
64 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS 24 | 74 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS 24 |
65 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK 0xffffff | 75 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK 0xffffff |
66 | #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT 0 | ||
67 | 76 | ||
68 | /* KICK register magic values */ | 77 | /* KICK register magic values */ |
69 | #define PLL_KICK0_VALUE 0x68ef3490 | 78 | #define PLL_KICK0_VALUE 0x68ef3490 |
@@ -81,63 +90,194 @@ struct ti_pll_clk { | |||
81 | 90 | ||
82 | #define to_clk_pll(_clk) container_of(_clk, struct ti_pll_clk, clk) | 91 | #define to_clk_pll(_clk) container_of(_clk, struct ti_pll_clk, clk) |
83 | 92 | ||
84 | static int ti_pll_wait_for_lock(struct clk *clk) | 93 | static int ti_pll_clk_disable(struct clk *clk) |
85 | { | 94 | { |
86 | struct ti_pll_clk *pll = to_clk_pll(clk); | 95 | struct ti_pll_clk *pll = to_clk_pll(clk); |
96 | u32 ctrl; | ||
97 | |||
98 | ctrl = readl(pll->base + PLL_16FFT_CTRL); | ||
99 | |||
100 | if ((ctrl & PLL_16FFT_CTRL_PLL_EN)) { | ||
101 | ctrl &= ~PLL_16FFT_CTRL_PLL_EN; | ||
102 | writel(ctrl, pll->base + PLL_16FFT_CTRL); | ||
103 | |||
104 | /* wait 1us */ | ||
105 | udelay(1); | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int ti_pll_clk_enable(struct clk *clk) | ||
112 | { | ||
113 | struct ti_pll_clk *pll = to_clk_pll(clk); | ||
114 | u32 ctrl; | ||
115 | |||
116 | ctrl = readl(pll->base + PLL_16FFT_CTRL); | ||
117 | ctrl |= PLL_16FFT_CTRL_PLL_EN; | ||
118 | writel(ctrl, pll->base + PLL_16FFT_CTRL); | ||
119 | |||
120 | /* Wait 1us */ | ||
121 | udelay(1); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static bool clk_pll_16fft_check_lock(const struct ti_pll_clk *pll) | ||
127 | { | ||
87 | u32 stat; | 128 | u32 stat; |
129 | |||
130 | stat = readl(pll->base + PLL_16FFT_STAT); | ||
131 | return (stat & PLL_16FFT_STAT_LOCK); | ||
132 | } | ||
133 | |||
134 | static bool clk_pll_16fft_check_cal_lock(const struct ti_pll_clk *pll) | ||
135 | { | ||
136 | u32 stat; | ||
137 | |||
138 | stat = readl(pll->base + PLL_16FFT_CAL_STAT); | ||
139 | return (stat & PLL_16FFT_CAL_STAT_CAL_LOCK); | ||
140 | } | ||
141 | |||
142 | static void clk_pll_16fft_cal_int(const struct ti_pll_clk *pll) | ||
143 | { | ||
144 | u32 cal; | ||
145 | |||
146 | cal = readl(pll->base + PLL_16FFT_CAL_CTRL); | ||
147 | |||
148 | /* Enable fast cal mode */ | ||
149 | cal |= PLL_16FFT_CAL_CTRL_FAST_CAL; | ||
150 | |||
151 | /* Disable calibration bypass */ | ||
152 | cal &= ~PLL_16FFT_CAL_CTRL_CAL_BYP; | ||
153 | |||
154 | /* Set CALCNT to 2 */ | ||
155 | cal &= ~PLL_16FFT_CAL_CTRL_CAL_CNT_MASK; | ||
156 | cal |= 2 << PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT; | ||
157 | |||
158 | /* Set CAL_IN to 0 */ | ||
159 | cal &= ~PLL_16FFT_CAL_CTRL_CAL_IN_MASK; | ||
160 | |||
161 | /* Note this register does not readback the written value. */ | ||
162 | writel(cal, pll->base + PLL_16FFT_CAL_CTRL); | ||
163 | |||
164 | /* Wait 1us before enabling the CAL_EN field */ | ||
165 | udelay(1); | ||
166 | |||
167 | cal = readl(pll->base + PLL_16FFT_CAL_CTRL); | ||
168 | |||
169 | /* Enable calibration for FRACF */ | ||
170 | cal |= PLL_16FFT_CAL_CTRL_CAL_EN; | ||
171 | |||
172 | /* Note this register does not readback the written value. */ | ||
173 | writel(cal, pll->base + PLL_16FFT_CAL_CTRL); | ||
174 | } | ||
175 | |||
176 | static void clk_pll_16fft_disable_cal(const struct ti_pll_clk *pll) | ||
177 | { | ||
178 | u32 cal, stat; | ||
179 | |||
180 | cal = readl(pll->base + PLL_16FFT_CAL_CTRL); | ||
181 | cal &= ~PLL_16FFT_CAL_CTRL_CAL_EN; | ||
182 | /* Note this register does not readback the written value. */ | ||
183 | writel(cal, pll->base + PLL_16FFT_CAL_CTRL); | ||
184 | do { | ||
185 | stat = readl(pll->base + PLL_16FFT_CAL_STAT); | ||
186 | } while (stat & PLL_16FFT_CAL_STAT_CAL_LOCK); | ||
187 | } | ||
188 | |||
189 | static int ti_pll_wait_for_lock(struct clk *clk) | ||
190 | { | ||
191 | struct ti_pll_clk *pll = to_clk_pll(clk); | ||
88 | u32 cfg; | 192 | u32 cfg; |
89 | u32 cal; | 193 | u32 cal; |
90 | u32 freq_ctrl1; | 194 | u32 freq_ctrl1; |
91 | int i; | 195 | unsigned int i; |
92 | u32 pllfm; | 196 | u32 pllfm; |
93 | u32 pll_type; | 197 | u32 pll_type; |
94 | int success; | 198 | u32 cal_en = 0; |
199 | bool success; | ||
95 | 200 | ||
96 | for (i = 0; i < 100000; i++) { | 201 | /* |
97 | stat = readl(pll->base + PLL_16FFT_STAT); | 202 | * Minimum VCO input freq is 5MHz, and the longest a lock should |
98 | if (stat & PLL_16FFT_STAT_LOCK) { | 203 | * be consider to be timed out after 750 cycles. Be conservative |
99 | success = 1; | 204 | * and assume each loop takes 10 cycles and we run at a |
205 | * max of 1GHz. That gives 15000 loop cycles. We may end up waiting | ||
206 | * longer than necessary for timeout, but that should be ok. | ||
207 | */ | ||
208 | success = false; | ||
209 | for (i = 0; i < PLL_16FFT_STAT_LOCK_TIMEOUT; i++) { | ||
210 | if (clk_pll_16fft_check_lock(pll)) { | ||
211 | success = true; | ||
100 | break; | 212 | break; |
101 | } | 213 | } |
102 | } | 214 | } |
103 | 215 | ||
104 | /* Enable calibration if not in fractional mode of the FRACF PLL */ | 216 | /* Disable calibration in the fractional mode of the FRACF PLL based on data |
217 | * from silicon and simulation data. | ||
218 | */ | ||
105 | freq_ctrl1 = readl(pll->base + PLL_16FFT_FREQ_CTRL1); | 219 | freq_ctrl1 = readl(pll->base + PLL_16FFT_FREQ_CTRL1); |
106 | pllfm = freq_ctrl1 & PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK; | 220 | pllfm = freq_ctrl1 & PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK; |
107 | pllfm >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT; | 221 | |
108 | cfg = readl(pll->base + PLL_16FFT_CFG); | 222 | cfg = readl(pll->base + PLL_16FFT_CFG); |
109 | pll_type = (cfg & PLL_16FFT_CFG_PLL_TYPE_MASK) >> PLL_16FFT_CFG_PLL_TYPE_SHIFT; | 223 | pll_type = (cfg & PLL_16FFT_CFG_PLL_TYPE_MASK) >> PLL_16FFT_CFG_PLL_TYPE_SHIFT; |
110 | 224 | ||
111 | if (success && pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF && pllfm == 0) { | 225 | if (success && pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF) { |
112 | cal = readl(pll->base + PLL_16FFT_CAL_CTRL); | 226 | cal = readl(pll->base + PLL_16FFT_CAL_CTRL); |
227 | cal_en = (cal & PLL_16FFT_CAL_CTRL_CAL_EN); | ||
228 | } | ||
113 | 229 | ||
114 | /* Enable calibration for FRACF */ | 230 | if (success && pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF && |
115 | cal |= PLL_16FFT_CAL_CTRL_CAL_EN; | 231 | pllfm == 0 && cal_en == 1) { |
232 | /* | ||
233 | * Wait for calibration lock. | ||
234 | * | ||
235 | * Lock should occur within: | ||
236 | * | ||
237 | * 170 * 2^(5+CALCNT) / PFD | ||
238 | * 21760 / PFD | ||
239 | * | ||
240 | * CALCNT = 2, PFD = 5-50MHz. This gives a range of 0.435mS to | ||
241 | * 4.35mS depending on PFD frequency. | ||
242 | * | ||
243 | * Be conservative and assume each loop takes 10 cycles and we run at a | ||
244 | * max of 1GHz. That gives 435000 loop cycles. We may end up waiting | ||
245 | * longer than necessary for timeout, but that should be ok. | ||
246 | * | ||
247 | * The recommend timeout for CALLOCK to go high is 4.35 ms | ||
248 | */ | ||
249 | success = false; | ||
250 | for (i = 0; i < PLL_16FFT_CAL_STAT_CAL_LOCK_TIMEOUT; i++) { | ||
251 | if (clk_pll_16fft_check_cal_lock(pll)) { | ||
252 | success = true; | ||
253 | break; | ||
254 | } | ||
255 | } | ||
116 | 256 | ||
117 | /* Enable fast cal mode */ | 257 | /* In case of cal lock failure, operate without calibration */ |
118 | cal |= PLL_16FFT_CAL_CTRL_FAST_CAL; | 258 | if (!success) { |
259 | debug("Failure for calibration, falling back without calibration\n"); | ||
119 | 260 | ||
120 | /* Disable calibration bypass */ | 261 | /* Disable PLL */ |
121 | cal &= ~PLL_16FFT_CAL_CTRL_CAL_BYP; | 262 | ti_pll_clk_disable(clk); |
122 | 263 | ||
123 | /* Set CALCNT to 2 */ | 264 | /* Disable Calibration */ |
124 | cal &= ~PLL_16FFT_CAL_CTRL_CAL_CNT_MASK; | 265 | clk_pll_16fft_disable_cal(pll); |
125 | cal |= 2 << PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT; | ||
126 | 266 | ||
127 | /* Note this register does not readback the written value. */ | 267 | /* Enable PLL */ |
128 | writel(cal, pll->base + PLL_16FFT_CAL_CTRL); | 268 | ti_pll_clk_enable(clk); |
129 | 269 | ||
130 | success = 0; | 270 | /* Wait for PLL Lock */ |
131 | for (i = 0; i < 100000; i++) { | 271 | for (i = 0; i < PLL_16FFT_STAT_LOCK_TIMEOUT; i++) { |
132 | stat = readl(pll->base + PLL_16FFT_CAL_STAT); | 272 | if (clk_pll_16fft_check_lock(pll)) { |
133 | if (stat & PLL_16FFT_CAL_STAT_CAL_LOCK) { | 273 | success = true; |
134 | success = 1; | 274 | break; |
135 | break; | 275 | } |
136 | } | 276 | } |
137 | } | 277 | } |
138 | } | 278 | } |
139 | 279 | ||
140 | if (success == 0) { | 280 | if (!success) { |
141 | printf("%s: pll (%s) failed to lock\n", __func__, | 281 | printf("%s: pll (%s) failed to lock\n", __func__, |
142 | clk->dev->name); | 282 | clk->dev->name); |
143 | return -EBUSY; | 283 | return -EBUSY; |
@@ -181,6 +321,30 @@ static ulong ti_pll_clk_get_rate(struct clk *clk) | |||
181 | return current_freq; | 321 | return current_freq; |
182 | } | 322 | } |
183 | 323 | ||
324 | static bool ti_pll_clk_is_bypass(struct ti_pll_clk *pll) | ||
325 | { | ||
326 | u32 ctrl; | ||
327 | bool ret; | ||
328 | |||
329 | ctrl = readl(pll->base + PLL_16FFT_CTRL); | ||
330 | ret = (ctrl & PLL_16FFT_CTRL_BYPASS_EN) != 0; | ||
331 | |||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | static void ti_pll_clk_bypass(struct ti_pll_clk *pll, bool bypass) | ||
336 | { | ||
337 | u32 ctrl; | ||
338 | |||
339 | ctrl = readl(pll->base + PLL_16FFT_CTRL); | ||
340 | if (bypass) | ||
341 | ctrl |= PLL_16FFT_CTRL_BYPASS_EN; | ||
342 | else | ||
343 | ctrl &= ~PLL_16FFT_CTRL_BYPASS_EN; | ||
344 | |||
345 | writel(ctrl, pll->base + PLL_16FFT_CTRL); | ||
346 | } | ||
347 | |||
184 | static ulong ti_pll_clk_set_rate(struct clk *clk, ulong rate) | 348 | static ulong ti_pll_clk_set_rate(struct clk *clk, ulong rate) |
185 | { | 349 | { |
186 | struct ti_pll_clk *pll = to_clk_pll(clk); | 350 | struct ti_pll_clk *pll = to_clk_pll(clk); |
@@ -188,9 +352,13 @@ static ulong ti_pll_clk_set_rate(struct clk *clk, ulong rate) | |||
188 | u64 parent_freq = clk_get_parent_rate(clk); | 352 | u64 parent_freq = clk_get_parent_rate(clk); |
189 | int ret; | 353 | int ret; |
190 | u32 ctrl; | 354 | u32 ctrl; |
355 | u32 cfg; | ||
356 | u32 pll_type; | ||
191 | unsigned long pllm; | 357 | unsigned long pllm; |
192 | u32 pllfm = 0; | 358 | u32 pllfm = 0; |
193 | unsigned long plld; | 359 | unsigned long plld; |
360 | u32 freq_ctrl0; | ||
361 | u32 freq_ctrl1; | ||
194 | u32 div_ctrl; | 362 | u32 div_ctrl; |
195 | u32 rem; | 363 | u32 rem; |
196 | int shift; | 364 | int shift; |
@@ -213,16 +381,22 @@ static ulong ti_pll_clk_set_rate(struct clk *clk, ulong rate) | |||
213 | break; | 381 | break; |
214 | } | 382 | } |
215 | 383 | ||
216 | /* Put PLL to bypass mode */ | 384 | if (!ti_pll_clk_is_bypass(pll)) { |
217 | ctrl = readl(pll->base + PLL_16FFT_CTRL); | 385 | /* Put the PLL into bypass */ |
218 | ctrl |= PLL_16FFT_CTRL_BYPASS_EN; | 386 | ti_pll_clk_bypass(pll, true); |
219 | writel(ctrl, pll->base + PLL_16FFT_CTRL); | 387 | } |
388 | |||
389 | /* Disable the PLL */ | ||
390 | ti_pll_clk_disable(clk); | ||
220 | 391 | ||
221 | if (rate == parent_freq) { | 392 | if (rate == parent_freq) { |
222 | debug("%s: put %s to bypass\n", __func__, clk->dev->name); | 393 | debug("%s: put %s to bypass\n", __func__, clk->dev->name); |
223 | return rate; | 394 | return rate; |
224 | } | 395 | } |
225 | 396 | ||
397 | cfg = readl(pll->base + PLL_16FFT_CFG); | ||
398 | pll_type = (cfg & PLL_16FFT_CFG_PLL_TYPE_MASK) >> PLL_16FFT_CFG_PLL_TYPE_SHIFT; | ||
399 | |||
226 | debug("%s: pre-frac-calc: rate=%u, parent_freq=%u, plld=%u, pllm=%u\n", | 400 | debug("%s: pre-frac-calc: rate=%u, parent_freq=%u, plld=%u, pllm=%u\n", |
227 | __func__, (u32)rate, (u32)parent_freq, (u32)plld, (u32)pllm); | 401 | __func__, (u32)rate, (u32)parent_freq, (u32)plld, (u32)pllm); |
228 | 402 | ||
@@ -238,31 +412,75 @@ static ulong ti_pll_clk_set_rate(struct clk *clk, ulong rate) | |||
238 | plld = 1; | 412 | plld = 1; |
239 | } | 413 | } |
240 | 414 | ||
241 | if (pllfm) | 415 | /* Program the new rate */ |
242 | ctrl |= PLL_16FFT_CTRL_DSM_EN; | 416 | freq_ctrl0 = readl(pll->base + PLL_16FFT_FREQ_CTRL0); |
243 | else | 417 | freq_ctrl1 = readl(pll->base + PLL_16FFT_FREQ_CTRL1); |
244 | ctrl &= ~PLL_16FFT_CTRL_DSM_EN; | 418 | div_ctrl = readl(pll->base + PLL_16FFT_DIV_CTRL); |
245 | 419 | ||
246 | writel(pllm, pll->base + PLL_16FFT_FREQ_CTRL0); | 420 | freq_ctrl0 &= ~PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK; |
247 | writel(pllfm, pll->base + PLL_16FFT_FREQ_CTRL1); | 421 | freq_ctrl0 |= pllm; |
422 | |||
423 | freq_ctrl1 &= ~PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK; | ||
424 | freq_ctrl1 |= pllfm; | ||
248 | 425 | ||
249 | /* | 426 | /* |
250 | * div_ctrl register contains other divider values, so rmw | 427 | * div_ctrl register contains other divider values, so rmw |
251 | * only plld and leave existing values alone | 428 | * only plld and leave existing values alone |
252 | */ | 429 | */ |
253 | div_ctrl = readl(pll->base + PLL_16FFT_DIV_CTRL); | ||
254 | div_ctrl &= ~PLL_16FFT_DIV_CTRL_REF_DIV_MASK; | 430 | div_ctrl &= ~PLL_16FFT_DIV_CTRL_REF_DIV_MASK; |
255 | div_ctrl |= plld; | 431 | div_ctrl |= plld; |
256 | writel(div_ctrl, pll->base + PLL_16FFT_DIV_CTRL); | ||
257 | 432 | ||
258 | ctrl &= ~PLL_16FFT_CTRL_BYPASS_EN; | 433 | /* Make sure we have fractional support if required */ |
259 | ctrl |= PLL_16FFT_CTRL_PLL_EN; | 434 | ctrl = readl(pll->base + PLL_16FFT_CTRL); |
435 | |||
436 | /* Don't use internal bypass,it is not glitch free. Always prefer glitchless bypass */ | ||
437 | ctrl &= (~PLL_16FFT_CTRL_INTL_BYP_EN & ~PLL_16FFT_CTRL_CLK_4PH_EN); | ||
438 | |||
439 | /* Always enable output if PLL, Always bypass if we lose lock */ | ||
440 | ctrl |= (PLL_16FFT_CTRL_CLK_POSTDIV_EN | PLL_16FFT_CTRL_BYP_ON_LOCKLOSS); | ||
441 | |||
442 | /* Enable fractional support if required */ | ||
443 | if (pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF) { | ||
444 | if (pllfm != 0) | ||
445 | ctrl |= (PLL_16FFT_CTRL_DSM_EN | PLL_16FFT_CTRL_DAC_EN); | ||
446 | else | ||
447 | ctrl &= (~PLL_16FFT_CTRL_DSM_EN & ~PLL_16FFT_CTRL_DAC_EN); | ||
448 | } | ||
449 | |||
450 | /* Enable Fractional by default for PLL_16FFT_CFG_PLL_TYPE_FRAC2 */ | ||
451 | if (pll_type == PLL_16FFT_CFG_PLL_TYPE_FRAC2) | ||
452 | ctrl |= (PLL_16FFT_CTRL_DSM_EN | PLL_16FFT_CTRL_DAC_EN); | ||
453 | |||
454 | writel(freq_ctrl0, pll->base + PLL_16FFT_FREQ_CTRL0); | ||
455 | writel(freq_ctrl1, pll->base + PLL_16FFT_FREQ_CTRL1); | ||
456 | writel(div_ctrl, pll->base + PLL_16FFT_DIV_CTRL); | ||
260 | writel(ctrl, pll->base + PLL_16FFT_CTRL); | 457 | writel(ctrl, pll->base + PLL_16FFT_CTRL); |
261 | 458 | ||
459 | /* Configure PLL calibration*/ | ||
460 | if (pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF) { | ||
461 | if (pllfm != 0) { | ||
462 | /* Disable Calibration in Fractional mode */ | ||
463 | clk_pll_16fft_disable_cal(pll); | ||
464 | } else { | ||
465 | /* Enable Calibration in Integer mode */ | ||
466 | clk_pll_16fft_cal_int(pll); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | /* | ||
471 | * Wait at least 1 ref cycle before enabling PLL. | ||
472 | * Minimum VCO input frequency is 5MHz, therefore maximum | ||
473 | * wait time for 1 ref clock is 0.2us. | ||
474 | */ | ||
475 | udelay(1); | ||
476 | ti_pll_clk_enable(clk); | ||
477 | |||
262 | ret = ti_pll_wait_for_lock(clk); | 478 | ret = ti_pll_wait_for_lock(clk); |
263 | if (ret) | 479 | if (ret) |
264 | return ret; | 480 | return ret; |
265 | 481 | ||
482 | ti_pll_clk_bypass(pll, false); | ||
483 | |||
266 | debug("%s: pllm=%u, plld=%u, pllfm=%u, parent_freq=%u\n", | 484 | debug("%s: pllm=%u, plld=%u, pllfm=%u, parent_freq=%u\n", |
267 | __func__, (u32)pllm, (u32)plld, (u32)pllfm, (u32)parent_freq); | 485 | __func__, (u32)pllm, (u32)plld, (u32)pllfm, (u32)parent_freq); |
268 | 486 | ||
@@ -280,30 +498,7 @@ static ulong ti_pll_clk_set_rate(struct clk *clk, ulong rate) | |||
280 | return current_freq; | 498 | return current_freq; |
281 | } | 499 | } |
282 | 500 | ||
283 | static int ti_pll_clk_enable(struct clk *clk) | ||
284 | { | ||
285 | struct ti_pll_clk *pll = to_clk_pll(clk); | ||
286 | u32 ctrl; | ||
287 | 501 | ||
288 | ctrl = readl(pll->base + PLL_16FFT_CTRL); | ||
289 | ctrl &= ~PLL_16FFT_CTRL_BYPASS_EN; | ||
290 | ctrl |= PLL_16FFT_CTRL_PLL_EN; | ||
291 | writel(ctrl, pll->base + PLL_16FFT_CTRL); | ||
292 | |||
293 | return ti_pll_wait_for_lock(clk); | ||
294 | } | ||
295 | |||
296 | static int ti_pll_clk_disable(struct clk *clk) | ||
297 | { | ||
298 | struct ti_pll_clk *pll = to_clk_pll(clk); | ||
299 | u32 ctrl; | ||
300 | |||
301 | ctrl = readl(pll->base + PLL_16FFT_CTRL); | ||
302 | ctrl |= PLL_16FFT_CTRL_BYPASS_EN; | ||
303 | writel(ctrl, pll->base + PLL_16FFT_CTRL); | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | 502 | ||
308 | static const struct clk_ops ti_pll_clk_ops = { | 503 | static const struct clk_ops ti_pll_clk_ops = { |
309 | .get_rate = ti_pll_clk_get_rate, | 504 | .get_rate = ti_pll_clk_get_rate, |
@@ -343,7 +538,7 @@ struct clk *clk_register_ti_pll(const char *name, const char *parent_name, | |||
343 | hsdiv_presence_bit = BIT(16 + i); | 538 | hsdiv_presence_bit = BIT(16 + i); |
344 | hsdiv_ctrl_offs = 0x80 + (i * 4); | 539 | hsdiv_ctrl_offs = 0x80 + (i * 4); |
345 | /* Enable HSDIV output if present */ | 540 | /* Enable HSDIV output if present */ |
346 | if ((hsdiv_presence_bit & cfg) != 0UL) { | 541 | if ((hsdiv_presence_bit & cfg) != 0) { |
347 | ctrl = readl(pll->base + hsdiv_ctrl_offs); | 542 | ctrl = readl(pll->base + hsdiv_ctrl_offs); |
348 | ctrl |= PLL_16FFT_HSDIV_CTRL_CLKOUT_EN; | 543 | ctrl |= PLL_16FFT_HSDIV_CTRL_CLKOUT_EN; |
349 | writel(ctrl, pll->base + hsdiv_ctrl_offs); | 544 | writel(ctrl, pll->base + hsdiv_ctrl_offs); |