1 /*
2 * Copyright (c) 2025-2026 Texas Instruments Incorporated - https://www.ti.com
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /*
8 * TI 16FFT PLL Driver
9 *
10 * This driver implements support for TI's 16FFT (16-bit Fractional Feedback)
11 * PLL variant, which provides fractional frequency synthesis capabilities.
12 * It supports VCO frequencies from 800 MHz to 3.2 GHz, fractional-N synthesis
13 * with calibration, HSDIV (High-Speed Divider) output control, PLL lock
14 * detection and wait functions, and parent frequency modification.
15 */
16
17 #include <assert.h>
18 #include <cdefs.h>
19 #include <errno.h>
20
21 #include <drivers/delay_timer.h>
22 #include <lib/mmio.h>
23 #include <ti_clk_div.h>
24 #include <ti_clk_mux.h>
25 #include <ti_clk_pll.h>
26 #include <ti_clk_pll_16fft.h>
27 #include <ti_container_of.h>
28
29 /* PLL instance offset - each PLL instance is 0x1000 bytes apart */
30 #define PLL_16FFT_INSTANCE_OFFSET 0x1000UL
31
32 /* Register offsets */
33 #define PLL_16FFT_CFG 0x08UL
34 #define PLL_16FFT_CFG_PLL_TYPE_SHIFT 0UL
35 #define PLL_16FFT_CFG_PLL_TYPE_MASK (0x3UL << 0UL)
36 #define PLL_16FFT_CFG_PLL_TYPE_FRAC2 0UL
37 #define PLL_16FFT_CFG_PLL_TYPE_FRACF 1UL
38
39 #define PLL_16FFT_LOCKKEY0 0x10UL
40 #define PLL_16FFT_LOCKKEY0_VALUE 0x68EF3490UL
41
42 #define PLL_16FFT_LOCKKEY1 0x14UL
43 #define PLL_16FFT_LOCKKEY1_VALUE 0xD172BC5AUL
44
45 #define PLL_16FFT_CTRL 0x20UL
46 #define PLL_16FFT_CTRL_BYPASS_EN BIT(31)
47 #define PLL_16FFT_CTRL_BYP_ON_LOCKLOSS BIT(16)
48 #define PLL_16FFT_CTRL_PLL_EN BIT(15)
49 #define PLL_16FFT_CTRL_INTL_BYP_EN BIT(8)
50 #define PLL_16FFT_CTRL_CLK_4PH_EN BIT(5)
51 #define PLL_16FFT_CTRL_CLK_POSTDIV_EN BIT(4)
52 #define PLL_16FFT_CTRL_DSM_EN BIT(1)
53 #define PLL_16FFT_CTRL_DAC_EN BIT(0)
54
55 #define PLL_16FFT_STAT 0x24UL
56 #define PLL_16FFT_STAT_LOCK BIT(0)
57
58 #define PLL_16FFT_FREQ_CTRL0 0x30UL
59 #define PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_SHIFT 0UL
60 #define PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MSK (0xfffUL << 0UL)
61
62 #define PLL_16FFT_FREQ_CTRL1 0x34UL
63 #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT 0UL
64 #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MSK (0xffffffUL << 0UL)
65 #define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BIT_CNT 24UL
66
67 #define PLL_16FFT_DIV_CTRL 0x38UL
68 #define PLL_16FFT_DIV_CTRL_POST_DIV2_SHIFT 24UL
69 #define PLL_16FFT_DIV_CTRL_POST_DIV2_MASK (0x7UL << 24UL)
70 #define PLL_16FFT_DIV_CTRL_POST_DIV1_SHIFT 16UL
71 #define PLL_16FFT_DIV_CTRL_POST_DIV1_MASK (0x7UL << 16UL)
72 #define PLL_16FFT_DIV_CTRL_REF_DIV_SHIFT 0UL
73 #define PLL_16FFT_DIV_CTRL_REF_DIV_MASK (0x3fUL << 0UL)
74
75 #define PLL_16FFT_CAL_CTRL 0x60UL
76 #define PLL_16FFT_CAL_CTRL_CAL_EN BIT(31)
77 #define PLL_16FFT_CAL_CTRL_FAST_CAL BIT(20)
78 #define PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT 16UL
79 #define PLL_16FFT_CAL_CTRL_CAL_CNT_MASK (0x7UL << 16UL)
80 #define PLL_16FFT_CAL_CTRL_CAL_BYP BIT(15)
81 #define PLL_16FFT_CAL_CTRL_CAL_IN_SHIFT 0U
82 #define PLL_16FFT_CAL_CTRL_CAL_IN_MASK (0xFFFU << 0U)
83
84 #define PLL_16FFT_CAL_STAT 0x64UL
85 #define PLL_16FFT_CAL_STAT_CAL_LOCK BIT(31)
86
87 #define PLL_16FFT_HSDIV_CTRL 0x80UL
88 #define PLL_16FFT_HSDIV_CTRL_CLKOUT_EN BIT(15)
89
90 /* Register accessor functions */
ti_pll_16fft_read(const struct ti_clk_data_pll_16fft * pll,uint32_t reg)91 static inline uint32_t ti_pll_16fft_read(const struct ti_clk_data_pll_16fft *pll,
92 uint32_t reg)
93 {
94 return mmio_read_32(pll->base + (PLL_16FFT_INSTANCE_OFFSET * pll->idx) + reg);
95 }
96
ti_pll_16fft_write(const struct ti_clk_data_pll_16fft * pll,uint32_t reg,uint32_t val)97 static inline void ti_pll_16fft_write(const struct ti_clk_data_pll_16fft *pll,
98 uint32_t reg, uint32_t val)
99 {
100 mmio_write_32((uintptr_t)(pll->base + (PLL_16FFT_INSTANCE_OFFSET * pll->idx) + reg), val);
101 }
102
103 /**
104 * ti_pll_16fft_pllm_valid() - Check if a pllm value is valid for this PLL.
105 * @clock_ptr: unused.
106 * @pllm: The integer multiplier value to validate.
107 * @is_frac: True if fractional mode is in use.
108 *
109 * Return: true if pllm is within the valid range for the given mode, false otherwise.
110 */
ti_pll_16fft_pllm_valid(struct ti_clk * clock_ptr __unused,uint32_t pllm,bool is_frac)111 static bool ti_pll_16fft_pllm_valid(struct ti_clk *clock_ptr __unused, uint32_t pllm,
112 bool is_frac)
113 {
114 if ((is_frac && (pllm >= 20UL) && (pllm <= 320UL)) ||
115 (!is_frac && (pllm >= 16UL) && (pllm <= 640UL))) {
116 return true;
117 }
118 return false;
119 }
120
121 /**
122 * ti_pll_16fft_bin() - Assign a bin preference for a given PLL configuration.
123 * @clock_ptr: unused.
124 * @plld: unused.
125 * @pllm: unused.
126 * @is_frac: True if fractional mode is in use.
127 * @clkod: unused.
128 *
129 * Prefer non-fractional configuration if possible.
130 *
131 * Return: 1 for integer mode (preferred), 0 for fractional mode.
132 */
ti_pll_16fft_bin(struct ti_clk * clock_ptr __unused,uint32_t plld __unused,uint32_t pllm __unused,bool is_frac,uint32_t clkod __unused)133 static int32_t ti_pll_16fft_bin(struct ti_clk *clock_ptr __unused,
134 uint32_t plld __unused,
135 uint32_t pllm __unused, bool is_frac,
136 uint32_t clkod __unused)
137 {
138 return is_frac ? 0 : 1;
139 }
140
141 /**
142 * ti_pll_16fft_vco_fitness() - Return a fitness score for a VCO frequency.
143 * @clock_ptr: unused.
144 * @vco: VCO frequency in Hz.
145 * @is_frac: unused.
146 *
147 * Prefer higher VCO frequencies.
148 *
149 * Return: The VCO frequency itself as the fitness score.
150 */
ti_pll_16fft_vco_fitness(struct ti_clk * clock_ptr __unused,uint32_t vco,bool is_frac __unused)151 static uint32_t ti_pll_16fft_vco_fitness(struct ti_clk *clock_ptr __unused,
152 uint32_t vco, bool is_frac __unused)
153 {
154 return vco;
155 }
156
157 /*
158 * There are two post dividers. Total post divide is postdiv1 * postdiv2.
159 * postdiv1 must always be greater than or equal to postdiv2. Rather than
160 * factor the divider, just keep a small 50 byte lookup table.
161 *
162 * Note that this means that even though that there are 6 bits used for
163 * divider values, there are only 25 divider values (rather than 64).
164 */
165 #define PDV(pd1, pd2) ((uint8_t)((pd1) | ((pd2) << 4UL)))
166 #define PDV_ENTRY(div, pd1)[(div)] = PDV((pd1), (div) / (pd1))
167 static const uint8_t postdiv_mapping[(7U * 7U) + 1U] = {
168 PDV_ENTRY(1U, 1U),
169 PDV_ENTRY(2U, 2U),
170 PDV_ENTRY(3U, 3U),
171 PDV_ENTRY(4U, 4U),
172 PDV_ENTRY(5U, 5U),
173 PDV_ENTRY(6U, 6U),
174 PDV_ENTRY(7U, 7U),
175 PDV_ENTRY(8U, 4U),
176 PDV_ENTRY(9U, 3U),
177 PDV_ENTRY(10U, 5U),
178 PDV_ENTRY(12U, 4U),
179 PDV_ENTRY(14U, 7U),
180 PDV_ENTRY(15U, 5U),
181 PDV_ENTRY(16U, 4U),
182 PDV_ENTRY(18U, 6U),
183 PDV_ENTRY(20U, 5U),
184 PDV_ENTRY(21U, 7U),
185 PDV_ENTRY(24U, 6U),
186 PDV_ENTRY(25U, 5U),
187 PDV_ENTRY(28U, 7U),
188 PDV_ENTRY(30U, 6U),
189 PDV_ENTRY(35U, 7U),
190 PDV_ENTRY(36U, 6U),
191 PDV_ENTRY(42U, 7U),
192 PDV_ENTRY(49U, 7U),
193 };
194
195 /**
196 * ti_pll_16fft_clkod_valid() - Check if a clkod value is valid for this PLL.
197 * @clock_ptr: unused.
198 * @clkod: The output divider value to validate.
199 *
200 * Return: true if clkod has a valid postdiv_mapping entry, false otherwise.
201 */
ti_pll_16fft_clkod_valid(struct ti_clk * clock_ptr __unused,uint32_t clkod)202 static bool ti_pll_16fft_clkod_valid(struct ti_clk *clock_ptr __unused, uint32_t clkod)
203 {
204 return (clkod < ARRAY_SIZE(postdiv_mapping)) && (postdiv_mapping[clkod] != 0U);
205 }
206
207 static const struct ti_pll_data ti_pll_16fft_raw_data = {
208 .plld_max = 1U,
209 .pllm_max = 640U,
210 .pllfm_bits = (uint32_t) PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BIT_CNT,
211 .clkod_max = 1U,
212 .pllm_valid = ti_pll_16fft_pllm_valid,
213 .bin = ti_pll_16fft_bin,
214 .vco_fitness = ti_pll_16fft_vco_fitness,
215 };
216
217 static const struct ti_pll_data ti_pll_16fft_postdiv_data = {
218 .plld_max = 1U,
219 .pllm_max = 640U,
220 .pllfm_bits = (uint32_t) PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BIT_CNT,
221 .clkod_max = 49U,
222 .pllm_valid = ti_pll_16fft_pllm_valid,
223 .clkod_valid = ti_pll_16fft_clkod_valid,
224 .bin = ti_pll_16fft_bin,
225 .vco_fitness = ti_pll_16fft_vco_fitness,
226 };
227
228 static const struct ti_pll_data ti_pll_16fft_hsdiv_data = {
229 .plld_max = 1U,
230 .pllm_max = 640U,
231 .pllfm_bits = (uint32_t) PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BIT_CNT,
232 .clkod_max = 128U,
233 .pllm_valid = ti_pll_16fft_pllm_valid,
234 .bin = ti_pll_16fft_bin,
235 .vco_fitness = ti_pll_16fft_vco_fitness,
236 };
237
238 /**
239 * ti_clk_pll_16fft_cal_option3() - Perform option 3 PLL calibration.
240 * @pll: PLL instance data.
241 *
242 * Implements the option 3 PLL calibration method using FASTCAL mode to obtain
243 * a calibration value for the FRACF PLL type.
244 */
ti_clk_pll_16fft_cal_option3(const struct ti_clk_data_pll_16fft * pll)245 static void ti_clk_pll_16fft_cal_option3(const struct ti_clk_data_pll_16fft *pll)
246 {
247 uint32_t cal;
248
249 cal = ti_pll_16fft_read(pll, PLL_16FFT_CAL_CTRL);
250
251 /* Enable fast cal mode */
252 cal |= PLL_16FFT_CAL_CTRL_FAST_CAL;
253
254 /* Disable calibration bypass */
255 cal &= ~PLL_16FFT_CAL_CTRL_CAL_BYP;
256
257 /* Set CALCNT to 2 */
258 cal &= ~PLL_16FFT_CAL_CTRL_CAL_CNT_MASK;
259 cal |= (uint32_t) 2U << (uint32_t) PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT;
260
261 /* Set CAL_IN to 0 */
262 cal &= ~PLL_16FFT_CAL_CTRL_CAL_IN_MASK;
263
264 /* Note this register does not readback the written value. */
265 ti_pll_16fft_write(pll, PLL_16FFT_CAL_CTRL, cal);
266
267 /* Wait 1us before enabling the CAL_EN field */
268 udelay(1U); /* Wait 1us */
269
270 cal = ti_pll_16fft_read(pll, PLL_16FFT_CAL_CTRL);
271
272 /* Enable calibration for FRACF */
273 cal |= PLL_16FFT_CAL_CTRL_CAL_EN;
274
275 /* Note this register does not readback the written value. */
276 ti_pll_16fft_write(pll, PLL_16FFT_CAL_CTRL, cal);
277 }
278
ti_clk_pll_16fft_disable_cal(const struct ti_clk_data_pll_16fft * pll)279 static void ti_clk_pll_16fft_disable_cal(const struct ti_clk_data_pll_16fft *pll)
280 {
281 uint32_t cal, stat;
282
283 cal = ti_pll_16fft_read(pll, PLL_16FFT_CAL_CTRL);
284 cal &= ~PLL_16FFT_CAL_CTRL_CAL_EN;
285 /* Note this register does not readback the written value. */
286 ti_pll_16fft_write(pll, PLL_16FFT_CAL_CTRL, cal);
287 do {
288 stat = ti_pll_16fft_read(pll, PLL_16FFT_CAL_STAT);
289 } while ((stat & PLL_16FFT_CAL_STAT_CAL_LOCK) != 0U);
290 }
291
292 /**
293 * ti_clk_pll_16fft_check_lock() - Check if the PLL VCO/DCO is locked.
294 * @pll: PLL instance data.
295 *
296 * Return: true if the PLL is locked, false otherwise.
297 */
ti_clk_pll_16fft_check_lock(const struct ti_clk_data_pll_16fft * pll)298 static bool ti_clk_pll_16fft_check_lock(const struct ti_clk_data_pll_16fft *pll)
299 {
300 uint32_t stat;
301
302 stat = ti_pll_16fft_read(pll, PLL_16FFT_STAT);
303 return (stat & PLL_16FFT_STAT_LOCK) != 0U;
304 }
305
ti_clk_pll_16fft_enable_pll(const struct ti_clk_data_pll_16fft * pll)306 static int32_t ti_clk_pll_16fft_enable_pll(const struct ti_clk_data_pll_16fft *pll)
307 {
308 uint32_t ctrl;
309 int32_t err = 0;
310
311 ctrl = ti_pll_16fft_read(pll, PLL_16FFT_CTRL);
312
313 if ((ctrl & PLL_16FFT_CTRL_PLL_EN) == 0U) {
314 ctrl |= PLL_16FFT_CTRL_PLL_EN;
315 ti_pll_16fft_write(pll, PLL_16FFT_CTRL, ctrl);
316 udelay(1U); /* Wait 1us */
317 }
318
319 return err;
320 }
321
ti_clk_pll_16fft_disable_pll(const struct ti_clk_data_pll_16fft * pll)322 static int32_t ti_clk_pll_16fft_disable_pll(const struct ti_clk_data_pll_16fft *pll)
323 {
324 uint32_t ctrl;
325 int32_t err = 0;
326
327 ctrl = ti_pll_16fft_read(pll, PLL_16FFT_CTRL);
328
329 if ((ctrl & PLL_16FFT_CTRL_PLL_EN) != 0U) {
330 ctrl &= (uint32_t)~PLL_16FFT_CTRL_PLL_EN;
331 ti_pll_16fft_write(pll, PLL_16FFT_CTRL, ctrl);
332 udelay(1U); /* Wait 1us */
333 }
334
335 return err;
336 }
337
338 /**
339 * ti_clk_pll_16fft_check_cal_lock() - Check if PLL deskew calibration is complete.
340 * @pll: PLL instance data.
341 *
342 * Return: true if calibration lock is achieved, false otherwise.
343 */
ti_clk_pll_16fft_check_cal_lock(const struct ti_clk_data_pll_16fft * pll)344 static bool ti_clk_pll_16fft_check_cal_lock(const struct ti_clk_data_pll_16fft *pll)
345 {
346 uint32_t stat;
347
348 stat = ti_pll_16fft_read(pll, PLL_16FFT_CAL_STAT);
349 return (stat & PLL_16FFT_CAL_STAT_CAL_LOCK) != 0U;
350 }
351
ti_clk_pll_16fft_wait_for_lock(struct ti_clk * clock_ptr)352 static bool ti_clk_pll_16fft_wait_for_lock(struct ti_clk *clock_ptr)
353 {
354 const struct ti_clk_data_pll_16fft *pll;
355 const struct ti_clk_data_pll *data_pll;
356 uint32_t i;
357 bool success;
358
359 uint32_t freq_ctrl1;
360 uint32_t pllfm;
361 uint32_t pll_type;
362 uint32_t cfg;
363 int32_t err;
364 uint32_t cal, cal_en;
365
366 assert(clock_ptr != NULL);
367
368 data_pll = ti_container_of(clock_ptr->data, const struct ti_clk_data_pll,
369 data);
370 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft, data_pll);
371
372 /*
373 * Minimum VCO input freq is 5MHz, and the longest a lock should
374 * be consider to be timed out after 750 cycles. Be conservative
375 * and assume each loop takes 10 cycles and we run at a
376 * max of 1GHz. That gives 15000 loop cycles. We may end up waiting
377 * longer than necessary for timeout, but that should be ok.
378 */
379 success = false;
380 for (i = 0U; i < (150U * 100U); i++) {
381 if (ti_clk_pll_16fft_check_lock(pll)) {
382 success = true;
383 break;
384 }
385 }
386
387 /* Disable calibration in the fractional mode of the FRACF PLL based on data
388 * from silicon and simulation data.
389 */
390 freq_ctrl1 = ti_pll_16fft_read(pll, PLL_16FFT_FREQ_CTRL1);
391 pllfm = freq_ctrl1 & PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MSK;
392 pllfm >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT;
393
394 cfg = ti_pll_16fft_read(pll, PLL_16FFT_CFG);
395 pll_type = (cfg & PLL_16FFT_CFG_PLL_TYPE_MASK) >> PLL_16FFT_CFG_PLL_TYPE_SHIFT;
396
397 cal = ti_pll_16fft_read(pll, PLL_16FFT_CAL_CTRL);
398 cal_en = (cal & PLL_16FFT_CAL_CTRL_CAL_EN);
399
400 if (!success ||
401 (pll_type != PLL_16FFT_CFG_PLL_TYPE_FRACF) || (pllfm != 0U) ||
402 (cal_en == 0U)) {
403 return success;
404 }
405
406 /*
407 * Wait for calibration lock.
408 *
409 * Lock should occur within:
410 *
411 * 170 * 2^(5+CALCNT) / PFD
412 * 21760 / PFD
413 *
414 * CALCNT = 2, PFD = 5-50MHz. This gives a range of 0.435mS to
415 * 4.35mS depending on PFD frequency.
416 *
417 * Be conservative and assume each loop takes 10 cycles and we run at a
418 * max of 1GHz. That gives 435000 loop cycles. We may end up waiting
419 * longer than necessary for timeout, but that should be ok.
420 *
421 * The recommend timeout for CALLOCK to go high is 4.35 ms
422 */
423 for (i = 0U; i < (4350U * 100U); i++) {
424 if (ti_clk_pll_16fft_check_cal_lock(pll)) {
425 return true;
426 }
427 }
428
429 /* In case of cal lock failure, operate without calibration */
430 /* Disable PLL */
431 err = ti_clk_pll_16fft_disable_pll(pll);
432 if (err != 0) {
433 return false;
434 }
435
436 /* Disable Calibration */
437 ti_clk_pll_16fft_disable_cal(pll);
438
439 /* Enable PLL */
440 err = ti_clk_pll_16fft_enable_pll(pll);
441 if (err != 0) {
442 return false;
443 }
444
445 /* Wait for PLL Lock */
446 success = false;
447 for (i = 0U; i < (150U * 100U); i++) {
448 if (ti_clk_pll_16fft_check_lock(pll)) {
449 success = true;
450 break;
451 }
452 }
453 return success;
454 }
455
456 /**
457 * ti_clk_pll_16fft_is_bypass() - Query the bypass state of the PLL.
458 * @pll: PLL instance data.
459 *
460 * Return: true if the PLL is in bypass mode, false otherwise.
461 */
ti_clk_pll_16fft_is_bypass(const struct ti_clk_data_pll_16fft * pll)462 static bool ti_clk_pll_16fft_is_bypass(const struct ti_clk_data_pll_16fft *pll)
463 {
464 bool ret = false;
465 uint32_t ctrl;
466
467 /* IDLE Bypass */
468 ctrl = ti_pll_16fft_read(pll, PLL_16FFT_CTRL);
469 ret = (ctrl & PLL_16FFT_CTRL_BYPASS_EN) != 0U;
470
471 return ret;
472 }
473
ti_clk_pll_16fft_bypass(struct ti_clk * clock_ptr,bool bypass)474 static int32_t ti_clk_pll_16fft_bypass(struct ti_clk *clock_ptr, bool bypass)
475 {
476 const struct ti_clk_data_pll_16fft *pll;
477 const struct ti_clk_data_pll *data_pll;
478 uint32_t ctrl;
479
480 data_pll = ti_container_of(clock_ptr->data, const struct ti_clk_data_pll,
481 data);
482 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft,
483 data_pll);
484
485 ctrl = ti_pll_16fft_read(pll, PLL_16FFT_CTRL);
486 /* Enable bypass only if its not bypassed already */
487 if (bypass && ((ctrl & PLL_16FFT_CTRL_BYPASS_EN) == 0U)) {
488 ctrl |= PLL_16FFT_CTRL_BYPASS_EN;
489 ti_pll_16fft_write(pll, PLL_16FFT_CTRL, ctrl);
490 } else if ((ctrl & PLL_16FFT_CTRL_BYPASS_EN) == PLL_16FFT_CTRL_BYPASS_EN) {
491 /* Disable bypass only if its bypassed */
492 ctrl &= (uint32_t)~PLL_16FFT_CTRL_BYPASS_EN;
493 ti_pll_16fft_write(pll, PLL_16FFT_CTRL, ctrl);
494 }
495 return 0;
496 }
497
ti_clk_pll_16fft_get_freq_internal(struct ti_clk * clock_ptr,uint32_t clkod)498 static uint32_t ti_clk_pll_16fft_get_freq_internal(struct ti_clk *clock_ptr,
499 uint32_t clkod)
500 {
501 const struct ti_clk_data_pll_16fft *pll;
502 const struct ti_clk_data_pll *data_pll;
503 uint32_t ret = 0U;
504 uint32_t freq_ctrl0;
505 uint32_t freq_ctrl1;
506 uint32_t div_ctrl;
507 uint32_t pllm;
508 uint32_t m_frac_mult;
509 uint32_t plld;
510 uint32_t clkod_plld;
511
512 data_pll = ti_container_of(clock_ptr->data, const struct ti_clk_data_pll,
513 data);
514 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft, data_pll);
515 freq_ctrl0 = ti_pll_16fft_read(pll, PLL_16FFT_FREQ_CTRL0);
516 freq_ctrl1 = ti_pll_16fft_read(pll, PLL_16FFT_FREQ_CTRL1);
517 div_ctrl = ti_pll_16fft_read(pll, PLL_16FFT_DIV_CTRL);
518
519 pllm = (uint32_t)(freq_ctrl0 & PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MSK);
520 pllm >>= PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_SHIFT;
521
522 m_frac_mult = freq_ctrl1 & PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MSK;
523 m_frac_mult >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT;
524
525 plld = div_ctrl & PLL_16FFT_DIV_CTRL_REF_DIV_MASK;
526 plld >>= PLL_16FFT_DIV_CTRL_REF_DIV_SHIFT;
527
528 clkod_plld = clkod * plld;
529
530 if (clkod_plld != 0UL) {
531 uint32_t parent_freq_hz;
532 uint64_t ret64;
533 uint64_t rem;
534
535 /* Calculate non-fractional part */
536 parent_freq_hz = ti_clk_get_parent_freq(clock_ptr);
537 ret64 = ((uint64_t) parent_freq_hz / clkod_plld) * pllm;
538 rem = ((uint64_t) parent_freq_hz % clkod_plld) * pllm;
539 ret64 += rem / (uint64_t) clkod_plld;
540 rem = rem % (uint64_t) clkod_plld;
541
542 if (m_frac_mult != 0UL) {
543 uint64_t fret; /* Fraction return value */
544 uint64_t frem; /* Fraction remainder */
545 const uint32_t mask = (1UL << PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BIT_CNT) -
546 1UL;
547
548 /* Calculate fractional component of frequency */
549 fret = ((uint64_t) parent_freq_hz / clkod_plld) * m_frac_mult;
550 frem = ((uint64_t) parent_freq_hz % clkod_plld) * m_frac_mult;
551 fret += frem / (uint64_t) clkod_plld;
552 frem = frem % (uint64_t) clkod_plld;
553
554 /* Fold back into return/remainder */
555 frem += (fret & (uint64_t) mask) * clkod_plld;
556
557 /* Round the fractional component. Above mid point is rounded up*/
558 fret += (uint32_t) 1U << (PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BIT_CNT - 1U);
559
560 ret64 += fret >> PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BIT_CNT;
561 rem += frem >> PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BIT_CNT;
562
563 ret64 += ((uint64_t) rem) / clkod_plld;
564 }
565
566 ret = (uint32_t) ret64;
567 }
568
569 return ret;
570 }
571
ti_clk_pll_16fft_program_freq(struct ti_clk * pll_clk,struct ti_clk * div_clk,const struct ti_clk_data_pll_16fft * pll,uint32_t plld,uint32_t pllm,uint32_t pllfm,uint32_t clkod)572 static bool ti_clk_pll_16fft_program_freq(struct ti_clk *pll_clk,
573 struct ti_clk *div_clk,
574 const struct ti_clk_data_pll_16fft *pll,
575 uint32_t plld,
576 uint32_t pllm,
577 uint32_t pllfm,
578 uint32_t clkod)
579 {
580 const struct ti_clk_drv_div *drv_div;
581 uint32_t freq_ctrl0;
582 uint32_t freq_ctrl1;
583 uint32_t div_ctrl;
584 uint32_t ctrl;
585 bool ret = true;
586 uint32_t cfg;
587 uint32_t pll_type;
588
589 pll_clk->flags &= (uint8_t) ~TI_CLK_FLAG_CACHED;
590
591 if (!ti_clk_pll_16fft_is_bypass(pll)) {
592 /* Put the PLL into bypass */
593 (void)ti_clk_pll_16fft_bypass(pll_clk, true);
594 }
595
596 /* Disable the PLL */
597 (void)ti_clk_pll_16fft_disable_pll(pll);
598
599 cfg = ti_pll_16fft_read(pll, PLL_16FFT_CFG);
600 pll_type = (cfg & PLL_16FFT_CFG_PLL_TYPE_MASK) >> PLL_16FFT_CFG_PLL_TYPE_SHIFT;
601
602 /* Program the new rate */
603 freq_ctrl0 = ti_pll_16fft_read(pll, PLL_16FFT_FREQ_CTRL0);
604 freq_ctrl1 = ti_pll_16fft_read(pll, PLL_16FFT_FREQ_CTRL1);
605 div_ctrl = ti_pll_16fft_read(pll, PLL_16FFT_DIV_CTRL);
606
607 freq_ctrl0 &= (uint32_t)~PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MSK;
608 freq_ctrl0 |= (uint32_t)(pllm << PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_SHIFT);
609
610 freq_ctrl1 &= (uint32_t)~PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MSK;
611 freq_ctrl1 |= (uint32_t)(pllfm << PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT);
612
613 div_ctrl &= (uint32_t)~PLL_16FFT_DIV_CTRL_REF_DIV_MASK;
614 div_ctrl |= (uint32_t)(plld << PLL_16FFT_DIV_CTRL_REF_DIV_SHIFT);
615
616 /* Make sure we have fractional support if required */
617 ctrl = ti_pll_16fft_read(pll, PLL_16FFT_CTRL);
618
619 /* Don't use internal bypass,it is not glitch free. Always prefer glitchless bypass */
620 ctrl &= (uint32_t)~PLL_16FFT_CTRL_INTL_BYP_EN;
621
622 /* Always enable output if PLL */
623 ctrl |= PLL_16FFT_CTRL_CLK_POSTDIV_EN;
624
625 /* Currently unused by all PLLs */
626 ctrl &= (uint32_t)~PLL_16FFT_CTRL_CLK_4PH_EN;
627
628 /* Always bypass if we lose lock */
629 ctrl |= PLL_16FFT_CTRL_BYP_ON_LOCKLOSS;
630
631 /* Enable fractional support if required */
632 if (pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF) {
633 if (pllfm != 0UL) {
634 ctrl |= PLL_16FFT_CTRL_DSM_EN;
635 ctrl |= PLL_16FFT_CTRL_DAC_EN;
636 } else {
637 ctrl &= (uint32_t)~PLL_16FFT_CTRL_DSM_EN;
638 ctrl &= (uint32_t)~PLL_16FFT_CTRL_DAC_EN;
639 }
640 }
641
642 /* Enable Fractional by default for PLL_16FFT_CFG_PLL_TYPE_FRAC2 */
643 if (pll_type == PLL_16FFT_CFG_PLL_TYPE_FRAC2) {
644 ctrl |= PLL_16FFT_CTRL_DSM_EN;
645 ctrl |= PLL_16FFT_CTRL_DAC_EN;
646 }
647
648 ti_pll_16fft_write(pll, PLL_16FFT_FREQ_CTRL0, freq_ctrl0);
649 ti_pll_16fft_write(pll, PLL_16FFT_FREQ_CTRL1, freq_ctrl1);
650 ti_pll_16fft_write(pll, PLL_16FFT_DIV_CTRL, div_ctrl);
651 ti_pll_16fft_write(pll, PLL_16FFT_CTRL, ctrl);
652
653 /* Program output divider */
654 if (div_clk != NULL) {
655 if (div_clk->drv != NULL) {
656 drv_div = ti_container_of(div_clk->drv,
657 const struct ti_clk_drv_div, drv);
658 } else {
659 drv_div = NULL;
660 }
661 if (drv_div && drv_div->set_div) {
662 ret = drv_div->set_div(div_clk, clkod);
663 }
664 }
665
666 if (ret) {
667 ti_pll_16fft_write(pll, PLL_16FFT_CTRL, ctrl);
668 }
669
670 /* Configure PLL calibration*/
671 if ((pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF) && ret) {
672 if (pllfm != 0UL) {
673 /* Disable Calibration in Fractional mode */
674 ti_clk_pll_16fft_disable_cal(pll);
675 } else {
676 /* Enable Calibration in Integer mode */
677 ti_clk_pll_16fft_cal_option3(pll);
678 }
679 }
680
681 /*
682 * Wait at least 1 ref cycle before enabling PLL.
683 * Minimum VCO input frequency is 5MHz, therefore maximum
684 * wait time for 1 ref clock is 0.2us.
685 */
686 if (ret) {
687 udelay(1U);
688 (void)ti_clk_pll_16fft_enable_pll(pll);
689 }
690
691 if ((pll_clk->ref_count != 0U) && ret) {
692 /* Take the PLL out of bypass */
693 ret = ti_clk_pll_16fft_wait_for_lock(pll_clk);
694 if (ret) {
695 (void)ti_clk_pll_16fft_bypass(pll_clk, false);
696 }
697 }
698
699 return ret;
700 }
701
ti_pll_16fft_set_freq(struct ti_clk * pll_clk,struct ti_clk * div_clk,const struct ti_pll_data * pll_data_t,uint32_t target_hz,uint32_t min_hz,uint32_t max_hz,bool * changed)702 static uint32_t ti_pll_16fft_set_freq(struct ti_clk *pll_clk,
703 struct ti_clk *div_clk,
704 const struct ti_pll_data *pll_data_t,
705 uint32_t target_hz,
706 uint32_t min_hz,
707 uint32_t max_hz,
708 bool *changed)
709 {
710 const struct ti_clk_data_pll_16fft *pll;
711 const struct ti_clk_data_pll *data_pll;
712 uint32_t freq_ctrl0;
713 uint32_t freq_ctrl1;
714 uint32_t div_ctrl;
715 uint32_t prev_pllm;
716 uint32_t prev_pllfm;
717 uint32_t prev_plld;
718 uint32_t prev_clkod;
719 uint32_t pllm = 0U;
720 uint32_t pllfm = 0U;
721 uint32_t plld = 0U;
722 uint32_t clkod = 0U;
723 uint32_t freq;
724 uint32_t parent_freq_hz;
725 bool was_bypass;
726
727 data_pll = ti_container_of(pll_clk->data, const struct ti_clk_data_pll,
728 data);
729 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft,
730 data_pll);
731
732 was_bypass = ti_clk_pll_16fft_is_bypass(pll);
733
734 freq_ctrl0 = ti_pll_16fft_read(pll, PLL_16FFT_FREQ_CTRL0);
735 freq_ctrl1 = ti_pll_16fft_read(pll, PLL_16FFT_FREQ_CTRL1);
736 div_ctrl = ti_pll_16fft_read(pll, PLL_16FFT_DIV_CTRL);
737
738 /* Check current values */
739 prev_pllm = (uint32_t)(freq_ctrl0 & PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MSK);
740 prev_pllm >>= PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_SHIFT;
741
742 prev_pllfm = freq_ctrl1 & PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MSK;
743 prev_pllfm >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_SHIFT;
744
745 prev_plld = div_ctrl & PLL_16FFT_DIV_CTRL_REF_DIV_MASK;
746 prev_plld >>= PLL_16FFT_DIV_CTRL_REF_DIV_SHIFT;
747
748 if (div_clk != NULL) {
749 prev_clkod = ti_clk_get_div(div_clk);
750 } else {
751 prev_clkod = 1U;
752 }
753
754 /* Compute new values */
755 parent_freq_hz = ti_clk_get_parent_freq(pll_clk);
756 freq = ti_pll_calc(pll_clk, pll_data_t, parent_freq_hz,
757 target_hz, min_hz, max_hz,
758 &plld, &pllm, &pllfm, &clkod);
759
760 *changed = true;
761 /* No need to do anything if they haven't changed */
762 if ((plld == prev_plld) && (pllm == prev_pllm) && (clkod == prev_clkod) &&
763 (pllfm == prev_pllfm) && !was_bypass) {
764 *changed = false;
765 }
766
767 if ((freq != 0UL) && *changed) {
768 if (!ti_clk_pll_16fft_program_freq(pll_clk, div_clk, pll,
769 plld, pllm, pllfm, clkod)) {
770 freq = 0U;
771 }
772 }
773
774 return freq;
775 }
776
777 /**
778 * ti_pll_16fft_set_freq_table() - Set frequency using a PLL table entry.
779 * @pll_clk: Parent PLL clock of the div_clk.
780 * @div_clk: HSDIV clock whose frequency is to be changed.
781 * @pll_data_t: PLL driver data describing valid parameter ranges.
782 * @target_hz: Required output frequency in Hz.
783 * @min_hz: Minimum acceptable frequency in Hz.
784 * @max_hz: Maximum acceptable frequency in Hz.
785 * @changed: Set to true if the PLL parameters were changed.
786 *
787 * Check if the desired frequency can be derived from VCO frequencies listed
788 * in the PLL table. If so, program those parameters.
789 *
790 * Return: The actual frequency set if derivable from the PLL table, 0 otherwise.
791 */
ti_pll_16fft_set_freq_table(struct ti_clk * pll_clk,struct ti_clk * div_clk,const struct ti_pll_data * pll_data_t,uint32_t target_hz,uint32_t min_hz,uint32_t max_hz,bool * changed)792 static uint32_t ti_pll_16fft_set_freq_table(struct ti_clk *pll_clk,
793 struct ti_clk *div_clk,
794 const struct ti_pll_data *pll_data_t,
795 uint32_t target_hz,
796 uint32_t min_hz,
797 uint32_t max_hz,
798 bool *changed)
799 {
800 const struct ti_clk_data_pll_16fft *pll;
801 const struct ti_clk_data_pll *data_pll;
802 const struct ti_clk_data_div *data_div;
803 uint32_t div0 = 0U, div1;
804 uint32_t div0_delta = UINT_MAX;
805 uint32_t div1_delta = UINT_MAX;
806 uint32_t div0_hz, div1_hz;
807 uint32_t freq = 0U;
808 uint32_t input;
809 size_t i;
810 uint32_t n;
811 uint32_t rem;
812 uint64_t actual64;
813 uint32_t actual = 0U;
814 uint32_t clkod_plld;
815
816 data_pll = ti_container_of(pll_clk->data, const struct ti_clk_data_pll,
817 data);
818 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft, data_pll);
819 data_div = ti_container_of(div_clk->data, const struct ti_clk_data_div,
820 data);
821
822 input = ti_clk_get_parent_freq(pll_clk);
823
824 n = data_div->max_div;
825
826 for (i = 0; i < data_pll->pll_entries_count; i++) {
827 /*
828 * Determine actual frequency given table entry would produce:
829 *
830 * actual = input * pllm / (plld * clkod)
831 */
832 clkod_plld = (uint32_t)ti_soc_pll_table[data_pll->pll_entries[i]].plld *
833 (uint32_t)ti_soc_pll_table[data_pll->pll_entries[i]].clkod;
834
835 actual64 = ((uint64_t)input * ti_soc_pll_table[data_pll->pll_entries[i]].pllm) /
836 clkod_plld;
837 rem = (uint32_t)(((uint64_t)input *
838 ti_soc_pll_table[data_pll->pll_entries[i]].pllm) %
839 clkod_plld);
840
841 if (ti_soc_pll_table[data_pll->pll_entries[i]].pllfm != 0UL) {
842 uint64_t fret;
843 uint64_t frem;
844 uint32_t stride = 1U;
845 uint32_t pllfm_bits;
846 uint32_t pllfm_range;
847 uint32_t pllfm_mask;
848 uint32_t pllm;
849
850 pllfm_bits = pll_data_t->pllfm_bits;
851 pllfm_range = (uint32_t) (1UL << pllfm_bits);
852 pllfm_mask = pllfm_range - 1U;
853
854 if (pll_data_t->pllm_stride != NULL) {
855 pllm = ti_soc_pll_table[data_pll->pll_entries[i]].pllm;
856 stride = pll_data_t->pllm_stride(pll_clk,
857 pllm);
858 }
859
860 /* Calculate fractional component of frequency */
861 fret = ((uint64_t) input / clkod_plld) *
862 ti_soc_pll_table[data_pll->pll_entries[i]].pllfm;
863 frem = ((uint64_t) input % clkod_plld) *
864 ti_soc_pll_table[data_pll->pll_entries[i]].pllfm;
865 if (frem >= clkod_plld) {
866 fret += ((uint64_t) frem) / clkod_plld;
867 frem = ((uint64_t) frem) % clkod_plld;
868 }
869 fret *= stride;
870 frem *= stride;
871 if (frem >= clkod_plld) {
872 fret += ((uint64_t) frem) / clkod_plld;
873 frem = ((uint64_t) frem) % clkod_plld;
874 }
875 frem += ((uint64_t) (fret & pllfm_mask)) * clkod_plld;
876
877 /* Add fractional part */
878 actual64 += fret >> pllfm_bits;
879 rem += (uint32_t) (frem >> pllfm_bits);
880
881 actual64 += ((uint64_t) rem) / clkod_plld;
882 }
883
884 actual = (uint32_t) actual64;
885
886 /* Calculate 2 best potential dividers for HSDIV */
887 div0 = actual / target_hz;
888
889 /*
890 * Prevent out-of-bounds divider value. Rest of the code in the
891 * function will check if the resulting divider value is within
892 * the allowable min/max range.
893 */
894 if (div0 > (n - 1U)) {
895 div0 = n - 1U;
896 }
897 div1 = div0 + 1U;
898 if (div0 != 0UL) {
899 div0_hz = actual / div0;
900 /* Check for in range */
901 if (div0_hz <= max_hz) {
902 div0_delta = div0_hz - target_hz;
903 }
904 }
905 div1_hz = actual / div1;
906 if (div1_hz >= min_hz) {
907 div1_delta = target_hz - div1_hz;
908 }
909
910 /* Make sure at least one of them is acceptable */
911 if ((div1_delta == UINT_MAX) && ((div0_delta == UINT_MAX))) {
912 *changed = false;
913 freq = 0U;
914 } else {
915 if (div0_delta > div1_delta) {
916 div0 = div1;
917 }
918 *changed = true;
919 freq = actual / div0;
920 break;
921 }
922 }
923
924 if (*changed) {
925 if (!ti_clk_pll_16fft_program_freq(pll_clk, div_clk, pll,
926 ti_soc_pll_table[data_pll->pll_entries[i]].plld,
927 ti_soc_pll_table[data_pll->pll_entries[i]].pllm,
928 ti_soc_pll_table[data_pll->pll_entries[i]].pllfm,
929 div0)) {
930 freq = 0U;
931 }
932 }
933
934 return freq;
935 }
936
937 /**
938 * ti_clk_pll_16fft_set_freq() - Set the 16FFT PLL output frequency.
939 * @clock_ptr: The PLL clock to program.
940 * @target_hz: Target frequency in Hz.
941 * @min_hz: Minimum acceptable frequency in Hz.
942 * @max_hz: Maximum acceptable frequency in Hz.
943 * @changed: Set to true if PLL parameters were changed.
944 *
945 * Glue function called only by pll_init. Sets the frequency of the
946 * foutpostdiv_clk output rather than the DCO directly.
947 *
948 * Return: The actual frequency set, or 0 on failure.
949 */
ti_clk_pll_16fft_set_freq(struct ti_clk * clock_ptr,uint32_t target_hz,uint32_t min_hz,uint32_t max_hz,bool * changed)950 static uint32_t ti_clk_pll_16fft_set_freq(struct ti_clk *clock_ptr,
951 uint32_t target_hz,
952 uint32_t min_hz,
953 uint32_t max_hz,
954 bool *changed)
955 {
956 const struct ti_pll_data *pll_data_t;
957 struct ti_clk *div_clk = NULL;
958 struct ti_clk *sub_clk = NULL;
959 struct ti_clk *pll_clk = NULL;
960 const struct ti_clk_parent *p = NULL;
961 uint32_t ret = 0U;
962 uint32_t i;
963
964 assert(clock_ptr != NULL);
965 assert(changed != NULL);
966
967 /* Find our associated postdiv */
968 for (i = 0U; (div_clk == NULL) && (i < soc_clock_count); i++) {
969 sub_clk = &soc_clocks[i];
970
971 if (sub_clk->drv == &ti_clk_drv_div_pll_16fft_postdiv.drv) {
972 p = ti_clk_mux_get_parent(sub_clk);
973 if (p != NULL) {
974 pll_clk = ti_clk_lookup((ti_clk_idx_t) p->clk);
975 if (pll_clk == clock_ptr) {
976 div_clk = sub_clk;
977 }
978 }
979 }
980 }
981
982 /*
983 * Since this function is only called by pll_init, the frequency
984 * passed in will always be from autogen. Because this PLL type
985 * can have many output dividers, including FOUTPOSTDIV and
986 * the various HSDIV options, the frequency listed by autogen
987 * is a bit ambiguous.
988 *
989 * The current rule to resolve ambiguity is that if a PLL has a
990 * connected FOUTPOSTDIV, the default frequency given is for this
991 * output. If there is no FOUTPOSTDIV, the default frequency given
992 * is for FOUTVCO.
993 */
994
995 if (div_clk != NULL) {
996 /*
997 * This is a clock with FOUTPOSTDIV. Utilize the postdiv
998 * output divider when determining a new frequency.
999 */
1000 pll_data_t = &ti_pll_16fft_postdiv_data;
1001 } else {
1002 /*
1003 * This is a clock without FOUTPOSTDIV. The clock
1004 * output divider must be 1.
1005 */
1006 pll_data_t = &ti_pll_16fft_raw_data;
1007 }
1008
1009 ret = ti_pll_16fft_set_freq(clock_ptr, div_clk, pll_data_t,
1010 target_hz, min_hz, max_hz,
1011 changed);
1012
1013 return ret;
1014 }
1015
1016 /**
1017 * ti_clk_pll_16fft_get_freq() - Return the 16FFT PLL DCO frequency.
1018 * @clock_ptr: The PLL clock instance.
1019 *
1020 * Return: The DCO output frequency in Hz, or 0 if the PLL is disabled or in bypass.
1021 */
ti_clk_pll_16fft_get_freq(struct ti_clk * clock_ptr)1022 static uint32_t ti_clk_pll_16fft_get_freq(struct ti_clk *clock_ptr)
1023 {
1024 uint32_t ret;
1025
1026 assert(clock_ptr != NULL);
1027
1028 /*
1029 * If disabled, return the frequency we would be running at once
1030 * we bring it out of bypass. If enabled and in bypass, return 0.
1031 */
1032 if (clock_ptr->ref_count == 0U) {
1033 ret = 0U;
1034 } else if ((clock_ptr->flags & TI_CLK_FLAG_CACHED) != 0U) {
1035 ret = ti_clk_get_value(clock_ptr->freq_idx);
1036 } else {
1037 const struct ti_clk_data_pll_16fft *pll;
1038 const struct ti_clk_data_pll *data_pll;
1039
1040 data_pll = ti_container_of(clock_ptr->data,
1041 const struct ti_clk_data_pll, data);
1042 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft,
1043 data_pll);
1044
1045 if (!ti_clk_pll_16fft_is_bypass(pll)) {
1046 ret = ti_clk_pll_16fft_get_freq_internal(clock_ptr, 1U);
1047 } else {
1048 ret = 0U;
1049 }
1050 ti_clk_set_value(clock_ptr->freq_idx, ret);
1051 clock_ptr->flags |= TI_CLK_FLAG_CACHED;
1052 }
1053
1054 return ret;
1055 }
1056
ti_clk_pll_16fft_set_state(struct ti_clk * clock_ptr,bool enabled)1057 static bool ti_clk_pll_16fft_set_state(struct ti_clk *clock_ptr, bool enabled)
1058 {
1059 bool ret = true;
1060
1061 if (enabled) {
1062 ret = ti_clk_pll_16fft_wait_for_lock(clock_ptr);
1063 }
1064
1065 clock_ptr->flags &= (uint8_t) ~TI_CLK_FLAG_CACHED;
1066 (void)ti_clk_pll_16fft_bypass(clock_ptr, !enabled);
1067
1068 return ret;
1069 }
1070
1071 /**
1072 * ti_clk_pll_16fft_get_state() - Get the hardware state of the 16FFT PLL.
1073 * @clock_ptr: The PLL clock instance.
1074 *
1075 * Return: TI_CLK_HW_STATE_ENABLED, TI_CLK_HW_STATE_DISABLED, or
1076 * TI_CLK_HW_STATE_TRANSITION depending on lock and bypass status.
1077 */
ti_clk_pll_16fft_get_state(struct ti_clk * clock_ptr)1078 static uint32_t ti_clk_pll_16fft_get_state(struct ti_clk *clock_ptr)
1079 {
1080 struct ti_clk *clock_parent = NULL;
1081 uint32_t ret = TI_CLK_HW_STATE_ENABLED;
1082
1083 if (clock_ptr->ref_count == 0U) {
1084 ret = TI_CLK_HW_STATE_DISABLED;
1085 }
1086
1087 /* PLLs can't function without an enabled parent */
1088 if (ret == TI_CLK_HW_STATE_ENABLED) {
1089 const struct ti_clk_parent *p;
1090
1091 p = ti_clk_mux_get_parent(clock_ptr);
1092 if (p != NULL) {
1093 clock_parent = ti_clk_lookup(p->clk);
1094 }
1095 if (clock_parent != NULL) {
1096 ret = ti_clk_get_state(clock_parent);
1097 } else {
1098 ret = TI_CLK_HW_STATE_DISABLED;
1099 }
1100 }
1101
1102 if (ret == TI_CLK_HW_STATE_ENABLED) {
1103 const struct ti_clk_data_pll_16fft *pll;
1104 const struct ti_clk_data_pll *data_pll;
1105
1106 data_pll = ti_container_of(clock_ptr->data,
1107 const struct ti_clk_data_pll, data);
1108 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft,
1109 data_pll);
1110
1111 if (!ti_clk_pll_16fft_is_bypass(pll) && !ti_clk_pll_16fft_check_lock(pll)) {
1112 ret = TI_CLK_HW_STATE_TRANSITION;
1113 }
1114 }
1115
1116 return ret;
1117 }
1118
ti_clk_pll_16fft_hsdiv_get_pll_root(struct ti_clk * clock_ptr)1119 static struct ti_clk *ti_clk_pll_16fft_hsdiv_get_pll_root(struct ti_clk *clock_ptr)
1120 {
1121 const struct ti_clk_parent *p = NULL;
1122 struct ti_clk *pll_clk = NULL;
1123
1124 /* Get PLL root */
1125 p = ti_clk_mux_get_parent(clock_ptr);
1126 if (p != NULL) {
1127 pll_clk = ti_clk_lookup((ti_clk_idx_t) p->clk);
1128 }
1129
1130 return pll_clk;
1131 }
1132
ti_clk_pll_16fft_postdiv_get_pll_root(struct ti_clk * clock_ptr)1133 static struct ti_clk *ti_clk_pll_16fft_postdiv_get_pll_root(struct ti_clk *clock_ptr)
1134 {
1135 const struct ti_clk_parent *p = NULL;
1136 struct ti_clk *pll_clk = NULL;
1137
1138 /* Get PLL post divider */
1139 p = ti_clk_mux_get_parent(clock_ptr);
1140 if (p != NULL) {
1141 pll_clk = ti_clk_lookup((ti_clk_idx_t) p->clk);
1142 }
1143
1144 /* Verify correct clock tree */
1145 if (pll_clk && (pll_clk->drv == &ti_clk_drv_div_pll_16fft_postdiv.drv)) {
1146 /* Get PLL root */
1147 p = ti_clk_mux_get_parent(pll_clk);
1148 if (p != NULL) {
1149 pll_clk = ti_clk_lookup((ti_clk_idx_t) p->clk);
1150 } else {
1151 pll_clk = NULL;
1152 }
1153 }
1154
1155 return pll_clk;
1156 }
1157
ti_clk_pll_16fft_init_internal(struct ti_clk * clock_ptr)1158 static int32_t ti_clk_pll_16fft_init_internal(struct ti_clk *clock_ptr)
1159 {
1160 const struct ti_clk_data_pll_16fft *pll;
1161 const struct ti_clk_data_pll *data_pll;
1162 uint32_t i;
1163 int32_t ret;
1164 bool skip_hw_init = false;
1165
1166 clock_ptr->flags &= (uint8_t) ~TI_CLK_FLAG_CACHED;
1167
1168 data_pll = ti_container_of(clock_ptr->data, const struct ti_clk_data_pll,
1169 data);
1170 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft, data_pll);
1171
1172 /*
1173 * In order to honor the TI_CLK_DATA_FLAG_NO_HW_REINIT flag when set,
1174 * we must check if the clk is enabled, and if so, skip re-setting
1175 * default frequency if it is available.
1176 */
1177 if (((clock_ptr->data_flags & TI_CLK_DATA_FLAG_NO_HW_REINIT) != 0U) &&
1178 (ti_clk_pll_16fft_check_lock(pll) == true)) {
1179 skip_hw_init = true;
1180 }
1181
1182 if (skip_hw_init == false) {
1183 ret = ti_pll_init(clock_ptr);
1184 if (ret != 0) {
1185 return ret;
1186 }
1187 }
1188
1189 /*
1190 * Find and program hsdiv defaults.
1191 *
1192 * HSDIV defaults must be programmed before programming the
1193 * PLL since their power on default is /1. Most DCO
1194 * frequencies will exceed clock rate maximums of the HSDIV
1195 * outputs.
1196 *
1197 * We walk through the clock tree to find all the clocks
1198 * with the hsdiv driver who have this PLL for a parent.
1199 */
1200 for (i = 0; i < soc_clock_count; i++) {
1201 struct ti_clk *sub_data = &soc_clocks[i];
1202 struct ti_clk *sub_clk = &soc_clocks[i];
1203
1204 if ((sub_data->drv == &ti_clk_drv_div_reg.drv) &&
1205 sub_data->drv->init) {
1206 if (ti_clk_pll_16fft_postdiv_get_pll_root(sub_clk) == clock_ptr) {
1207 (void)sub_data->drv->init(sub_clk);
1208 }
1209 } else if ((sub_data->drv == &ti_clk_drv_div_pll_16fft_hsdiv.drv) &&
1210 sub_data->drv->init) {
1211 if (ti_clk_pll_16fft_hsdiv_get_pll_root(sub_clk) == clock_ptr) {
1212 (void)sub_data->drv->init(sub_clk);
1213 }
1214 } else {
1215 /* Do Nothing */
1216 }
1217 }
1218
1219 /*
1220 * We must always assume we are enabled as we could be operating
1221 * clocks in bypass.
1222 */
1223 clock_ptr->flags |= TI_CLK_FLAG_PWR_UP_EN;
1224
1225 return 0;
1226 }
1227
ti_clk_pll_16fft_init(struct ti_clk * clock_ptr)1228 static int32_t ti_clk_pll_16fft_init(struct ti_clk *clock_ptr)
1229 {
1230 assert(clock_ptr != NULL);
1231
1232 return ti_clk_pll_16fft_init_internal(clock_ptr);
1233 }
1234
1235 const struct ti_clk_drv ti_clk_drv_pll_16fft = {
1236 .init = ti_clk_pll_16fft_init,
1237 .get_freq = ti_clk_pll_16fft_get_freq,
1238 .set_freq = ti_clk_pll_16fft_set_freq,
1239 .get_state = ti_clk_pll_16fft_get_state,
1240 .set_state = ti_clk_pll_16fft_set_state,
1241 };
1242
ti_clk_pll_16fft_postdiv_set_freq(struct ti_clk * clock_ptr,uint32_t target_hz,uint32_t min_hz,uint32_t max_hz,bool * changed)1243 static uint32_t ti_clk_pll_16fft_postdiv_set_freq(struct ti_clk *clock_ptr,
1244 uint32_t target_hz,
1245 uint32_t min_hz,
1246 uint32_t max_hz,
1247 bool *changed)
1248 {
1249 if ((clock_ptr->data_flags & TI_CLK_DATA_FLAG_MODIFY_PARENT_FREQ) != 0U) {
1250 /* Program the whole PLL */
1251 const struct ti_clk_parent *p;
1252 struct ti_clk *pll_clk;
1253
1254 p = ti_clk_mux_get_parent(clock_ptr);
1255 if (p == NULL) {
1256 return 0U;
1257 }
1258
1259 pll_clk = ti_clk_lookup((ti_clk_idx_t) p->clk);
1260 if (pll_clk == NULL) {
1261 return 0U;
1262 }
1263
1264 return ti_pll_16fft_set_freq(pll_clk, clock_ptr,
1265 &ti_pll_16fft_postdiv_data,
1266 target_hz, min_hz,
1267 max_hz,
1268 changed);
1269 }
1270
1271 /* Just program the output divider. */
1272 return ti_clk_div_set_freq(clock_ptr, target_hz, min_hz, max_hz,
1273 changed);
1274 }
1275
ti_clk_pll_16fft_postdiv_valid_div(struct ti_clk * clock_ptr __unused,uint32_t div)1276 static bool ti_clk_pll_16fft_postdiv_valid_div(struct ti_clk *clock_ptr __unused,
1277 uint32_t div)
1278 {
1279 return (div < ARRAY_SIZE(postdiv_mapping)) && (postdiv_mapping[div] != 0U);
1280 }
1281
ti_clk_pll_16fft_postdiv_set_div(struct ti_clk * clock_ptr,uint32_t div)1282 static bool ti_clk_pll_16fft_postdiv_set_div(struct ti_clk *clock_ptr, uint32_t div)
1283 {
1284 const struct ti_clk_parent *p;
1285 struct ti_clk *pll_clk = NULL;
1286
1287 p = ti_clk_mux_get_parent(clock_ptr);
1288 if (p != NULL) {
1289 pll_clk = ti_clk_lookup((ti_clk_idx_t) p->clk);
1290 }
1291
1292 if (pll_clk != NULL) {
1293 const struct ti_clk_data_pll *data_pll;
1294 const struct ti_clk_data_pll_16fft *pll;
1295 uint32_t div_ctrl;
1296 uint32_t post_div1;
1297 uint32_t post_div2;
1298 uint8_t val;
1299
1300 data_pll = ti_container_of(pll_clk->data,
1301 const struct ti_clk_data_pll, data);
1302 pll = ti_container_of(data_pll, const struct ti_clk_data_pll_16fft,
1303 data_pll);
1304
1305 div_ctrl = ti_pll_16fft_read(pll, PLL_16FFT_DIV_CTRL);
1306 div_ctrl &= (uint32_t)~PLL_16FFT_DIV_CTRL_POST_DIV2_MASK;
1307 div_ctrl &= (uint32_t)~PLL_16FFT_DIV_CTRL_POST_DIV1_MASK;
1308
1309 val = postdiv_mapping[div];
1310 post_div1 = (uint32_t) val & 0xFU;
1311 post_div2 = (uint32_t) val >> 4UL;
1312
1313 div_ctrl |= post_div1 << PLL_16FFT_DIV_CTRL_POST_DIV1_SHIFT;
1314 div_ctrl |= post_div2 << PLL_16FFT_DIV_CTRL_POST_DIV2_SHIFT;
1315
1316 ti_pll_16fft_write(pll, PLL_16FFT_DIV_CTRL, div_ctrl);
1317 }
1318
1319 return true;
1320 }
1321
ti_clk_pll_16fft_postdiv_get_div(struct ti_clk * clock_ptr)1322 static uint32_t ti_clk_pll_16fft_postdiv_get_div(struct ti_clk *clock_ptr)
1323 {
1324 const struct ti_clk_parent *p;
1325 struct ti_clk *pll_clk;
1326 const struct ti_clk_data_pll *data_pll;
1327 const struct ti_clk_data_pll_16fft *pll;
1328 uint32_t div_ctrl;
1329 uint32_t post_div1;
1330 uint32_t post_div2;
1331
1332 p = ti_clk_mux_get_parent(clock_ptr);
1333 if (p == NULL) {
1334 return 0U;
1335 }
1336
1337 pll_clk = ti_clk_lookup((ti_clk_idx_t) p->clk);
1338 if (pll_clk == NULL) {
1339 return 0U;
1340 }
1341
1342 data_pll = ti_container_of(pll_clk->data,
1343 const struct ti_clk_data_pll, data);
1344 pll = ti_container_of(data_pll,
1345 const struct ti_clk_data_pll_16fft, data_pll);
1346
1347 div_ctrl = ti_pll_16fft_read(pll, PLL_16FFT_DIV_CTRL);
1348 post_div1 = (uint32_t)(div_ctrl & PLL_16FFT_DIV_CTRL_POST_DIV1_MASK);
1349 post_div1 >>= PLL_16FFT_DIV_CTRL_POST_DIV1_SHIFT;
1350 post_div2 = div_ctrl & PLL_16FFT_DIV_CTRL_POST_DIV2_MASK;
1351 post_div2 >>= PLL_16FFT_DIV_CTRL_POST_DIV2_SHIFT;
1352
1353 return post_div1 * post_div2;
1354 }
1355
1356 const struct ti_clk_drv_div ti_clk_drv_div_pll_16fft_postdiv = {
1357 .drv = {
1358 .init = ti_clk_div_init,
1359 .get_freq = ti_clk_div_get_freq,
1360 .set_freq = ti_clk_pll_16fft_postdiv_set_freq,
1361 },
1362 .valid_div = ti_clk_pll_16fft_postdiv_valid_div,
1363 .set_div = ti_clk_pll_16fft_postdiv_set_div,
1364 .get_div = ti_clk_pll_16fft_postdiv_get_div,
1365 };
1366
ti_clk_pll_16fft_hsdiv_set_freq(struct ti_clk * clock_ptr,uint32_t target_hz,uint32_t min_hz,uint32_t max_hz,bool * changed)1367 static uint32_t ti_clk_pll_16fft_hsdiv_set_freq(struct ti_clk *clock_ptr,
1368 uint32_t target_hz,
1369 uint32_t min_hz,
1370 uint32_t max_hz,
1371 bool *changed)
1372 {
1373 uint32_t ret = 0U;
1374 const struct ti_clk_parent *p;
1375 struct ti_clk *pll_clk = NULL;
1376
1377 if ((clock_ptr->data_flags & TI_CLK_DATA_FLAG_MODIFY_PARENT_FREQ) == 0U) {
1378 /* Just program the output divider. */
1379 return ti_clk_div_set_freq(clock_ptr, target_hz, min_hz, max_hz,
1380 changed);
1381 }
1382
1383 /* Program the whole PLL */
1384 p = ti_clk_mux_get_parent(clock_ptr);
1385 if (p != NULL) {
1386 pll_clk = ti_clk_lookup((ti_clk_idx_t) p->clk);
1387 }
1388
1389 if (pll_clk == NULL) {
1390 return ret;
1391 }
1392
1393 /*
1394 * Before changing the VCO frequency of PLL.
1395 * Check that new target freq can be obtained with current parent
1396 * frequency by changing the divider.
1397 *
1398 * Here both min and max freq is given same as target freq.
1399 * Reason :
1400 * If min and max frequency is given it might set to frequency other
1401 * than target frequency even if target frequency can be obtained by
1402 * changing the PLL vco frequency.
1403 */
1404 ret = ti_clk_div_set_freq_static_parent(clock_ptr,
1405 target_hz,
1406 target_hz,
1407 target_hz,
1408 changed);
1409
1410 if (ret != 0U) {
1411 return ret;
1412 }
1413
1414 /*
1415 * If the requested frequency cannot be achieved by changing the
1416 * hsdiv and clk_modify_parent_frequency is enabled for that hsdiv,
1417 * the VCO frequency of the PLL will be altered to obtain the
1418 * required frequency.However, in this case, the VCO frequency
1419 * can vary between 800MHz to 3.2 GHz for 16fft PLLs, and the
1420 * user has no control over it.
1421 * To tackle this issue, if the required frequency is not
1422 * achievable, one can refer to the PLL table,
1423 * which contains a list of alternate suggested VCO frequency
1424 * values for the corresponding PLL.
1425 *
1426 * If the target frequency cannot be achieved using values
1427 * from the PLL table,then use pll_internal_calc function to
1428 * determine the optimal VCO frequency.
1429 */
1430 ret = ti_pll_16fft_set_freq_table(pll_clk,
1431 clock_ptr,
1432 &ti_pll_16fft_hsdiv_data,
1433 target_hz,
1434 target_hz,
1435 target_hz,
1436 changed);
1437
1438 if (ret != 0U) {
1439 return ret;
1440 }
1441
1442 /*
1443 * First try setting the exact target_hz frequency
1444 * without using the min and max range. We do this
1445 * because some times even when the target frequency
1446 * is achievable, the calculations will result
1447 * in choosing a value other than the target from the
1448 * range provided.
1449 */
1450 ret = ti_pll_16fft_set_freq(pll_clk, clock_ptr,
1451 &ti_pll_16fft_hsdiv_data,
1452 target_hz,
1453 target_hz, target_hz,
1454 changed);
1455 if (ret != 0U) {
1456 return ret;
1457 }
1458
1459 /*
1460 * If the previous step failed in setting the exact
1461 * target_hz, use the min and max range provided.
1462 */
1463 ret = ti_pll_16fft_set_freq(pll_clk,
1464 clock_ptr,
1465 &ti_pll_16fft_hsdiv_data,
1466 target_hz,
1467 min_hz,
1468 max_hz,
1469 changed);
1470
1471 return ret;
1472 }
1473
ti_clk_pll_16fft_hsdiv_init(struct ti_clk * clkp)1474 static int32_t ti_clk_pll_16fft_hsdiv_init(struct ti_clk *clkp)
1475 {
1476 const struct ti_clk_data_div *data_div;
1477 const struct ti_clk_data_div_reg *data_reg;
1478 const struct ti_clk_drv_div *drv_div;
1479 bool skip_hw_init = false;
1480 uint32_t hsdiv_ctrl;
1481
1482 data_div = ti_container_of(clkp->data, const struct ti_clk_data_div,
1483 data);
1484 data_reg = ti_container_of(data_div, const struct ti_clk_data_div_reg,
1485 data_div);
1486 drv_div = ti_container_of(clkp->drv, const struct ti_clk_drv_div, drv);
1487
1488 hsdiv_ctrl = mmio_read_32(data_reg->reg);
1489
1490 if (((clkp->data_flags & TI_CLK_DATA_FLAG_NO_HW_REINIT) != 0U) &&
1491 ((hsdiv_ctrl & PLL_16FFT_HSDIV_CTRL_CLKOUT_EN) != 0U)) {
1492 if (drv_div->get_div != NULL) {
1493 /*
1494 * In order to honor the TI_CLK_DATA_FLAG_NO_HW_REINIT flag when set,
1495 * we must check if the HSDIV is configured. If the HSDIV
1496 * is the default value of 1 then we consider it is not configured.
1497 */
1498 if (drv_div->get_div(clkp) != 1U) {
1499 skip_hw_init = true;
1500 }
1501 }
1502 }
1503
1504 if ((drv_div->get_div != NULL) && ((hsdiv_ctrl & PLL_16FFT_HSDIV_CTRL_CLKOUT_EN) != 0U)) {
1505 if (data_div->default_div > 0U) {
1506 /*
1507 * If the HSDIV value is already configured to the
1508 * expected value, then don't reconfigure.
1509 */
1510 if (drv_div->get_div(clkp) == data_div->default_div) {
1511 skip_hw_init = true;
1512 }
1513 }
1514 }
1515
1516 if (skip_hw_init == false) {
1517 if (data_div->default_div && drv_div->set_div) {
1518 /* Disable HSDIV */
1519 mmio_clrbits_32((uintptr_t)data_reg->reg,
1520 PLL_16FFT_HSDIV_CTRL_CLKOUT_EN);
1521
1522 if (!drv_div->set_div(clkp, data_div->default_div)) {
1523 return -EINVAL;
1524 }
1525
1526 /* Enable HSDIV */
1527 mmio_setbits_32((uintptr_t)data_reg->reg,
1528 PLL_16FFT_HSDIV_CTRL_CLKOUT_EN);
1529 }
1530 }
1531
1532 return 0;
1533 }
1534
1535 const struct ti_clk_drv_div ti_clk_drv_div_pll_16fft_hsdiv = {
1536 .drv = {
1537 .init = ti_clk_pll_16fft_hsdiv_init,
1538 .get_freq = ti_clk_div_get_freq,
1539 .set_freq = ti_clk_pll_16fft_hsdiv_set_freq,
1540 },
1541 .set_div = ti_clk_div_reg_set_div,
1542 .get_div = ti_clk_div_reg_get_div,
1543 };
1544
1545 const struct ti_clk_drv_div ti_clk_drv_div_pll_16fft_postdiv_hsdiv = {
1546 .drv = {
1547 .set_freq = ti_clk_div_set_freq,
1548 .get_freq = ti_clk_div_get_freq,
1549 .init = ti_clk_pll_16fft_hsdiv_init,
1550 },
1551 .set_div = ti_clk_div_reg_set_div,
1552 .get_div = ti_clk_div_reg_get_div,
1553 };
1554