blob: b775bd55faab98db3c1a7b6093b5e9ff402a5050 [file] [log] [blame]
Tero Kristo81744b72021-06-11 11:45:13 +03001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Texas Instruments K3 SoC PLL clock driver
4 *
Nishanth Menoneaa39c62023-11-01 15:56:03 -05005 * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
Tero Kristo81744b72021-06-11 11:45:13 +03006 * Tero Kristo <t-kristo@ti.com>
7 */
8
Tero Kristo81744b72021-06-11 11:45:13 +03009#include <asm/io.h>
10#include <dm.h>
11#include <div64.h>
12#include <errno.h>
13#include <clk-uclass.h>
14#include <linux/clk-provider.h>
15#include "k3-clk.h"
16#include <linux/rational.h>
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053017#include <linux/delay.h>
Tero Kristo81744b72021-06-11 11:45:13 +030018
19/* 16FFT register offsets */
20#define PLL_16FFT_CFG 0x08
21#define PLL_KICK0 0x10
22#define PLL_KICK1 0x14
23#define PLL_16FFT_CTRL 0x20
24#define PLL_16FFT_STAT 0x24
25#define PLL_16FFT_FREQ_CTRL0 0x30
26#define PLL_16FFT_FREQ_CTRL1 0x34
27#define PLL_16FFT_DIV_CTRL 0x38
Vishal Mahaveera5135b82023-10-23 08:35:46 -050028#define PLL_16FFT_CAL_CTRL 0x60
29#define PLL_16FFT_CAL_STAT 0x64
30
31/* CAL STAT register bits */
32#define PLL_16FFT_CAL_STAT_CAL_LOCK BIT(31)
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053033#define PLL_16FFT_CAL_STAT_CAL_LOCK_TIMEOUT (4350U * 100U)
Vishal Mahaveera5135b82023-10-23 08:35:46 -050034
35/* CFG register bits */
36#define PLL_16FFT_CFG_PLL_TYPE_SHIFT (0)
37#define PLL_16FFT_CFG_PLL_TYPE_MASK (0x3 << 0)
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053038#define PLL_16FFT_CFG_PLL_TYPE_FRAC2 0
Vishal Mahaveera5135b82023-10-23 08:35:46 -050039#define PLL_16FFT_CFG_PLL_TYPE_FRACF 1
40
41/* CAL CTRL register bits */
42#define PLL_16FFT_CAL_CTRL_CAL_EN BIT(31)
43#define PLL_16FFT_CAL_CTRL_FAST_CAL BIT(20)
44#define PLL_16FFT_CAL_CTRL_CAL_BYP BIT(15)
45#define PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT 16
46#define PLL_16FFT_CAL_CTRL_CAL_CNT_MASK (0x7 << 16)
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053047#define PLL_16FFT_CAL_CTRL_CAL_IN_MASK (0xFFFU)
Tero Kristo81744b72021-06-11 11:45:13 +030048
49/* CTRL register bits */
50#define PLL_16FFT_CTRL_BYPASS_EN BIT(31)
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053051#define PLL_16FFT_CTRL_BYP_ON_LOCKLOSS BIT(16)
Tero Kristo81744b72021-06-11 11:45:13 +030052#define PLL_16FFT_CTRL_PLL_EN BIT(15)
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053053#define PLL_16FFT_CTRL_INTL_BYP_EN BIT(8)
54#define PLL_16FFT_CTRL_CLK_4PH_EN BIT(5)
55#define PLL_16FFT_CTRL_CLK_POSTDIV_EN BIT(4)
Tero Kristo81744b72021-06-11 11:45:13 +030056#define PLL_16FFT_CTRL_DSM_EN BIT(1)
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053057#define PLL_16FFT_CTRL_DAC_EN BIT(0)
Tero Kristo81744b72021-06-11 11:45:13 +030058
59/* STAT register bits */
60#define PLL_16FFT_STAT_LOCK BIT(0)
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053061#define PLL_16FFT_STAT_LOCK_TIMEOUT (150U * 100U)
Tero Kristo81744b72021-06-11 11:45:13 +030062
63/* FREQ_CTRL0 bits */
64#define PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK 0xfff
65
66/* DIV CTRL register bits */
67#define PLL_16FFT_DIV_CTRL_REF_DIV_MASK 0x3f
68
Vishal Mahaveera5135b82023-10-23 08:35:46 -050069/* HSDIV register bits*/
Tero Kristo81744b72021-06-11 11:45:13 +030070#define PLL_16FFT_HSDIV_CTRL_CLKOUT_EN BIT(15)
71
Vishal Mahaveera5135b82023-10-23 08:35:46 -050072/* FREQ_CTRL1 bits */
73#define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS 24
74#define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK 0xffffff
Vishal Mahaveera5135b82023-10-23 08:35:46 -050075
Tero Kristo81744b72021-06-11 11:45:13 +030076/* KICK register magic values */
77#define PLL_KICK0_VALUE 0x68ef3490
78#define PLL_KICK1_VALUE 0xd172bc5a
79
80/**
81 * struct ti_pll_clk - TI PLL clock data info structure
82 * @clk: core clock structure
83 * @reg: memory address of the PLL controller
84 */
85struct ti_pll_clk {
86 struct clk clk;
Manorit Chawdhry65caba52024-11-21 17:32:52 +053087 void __iomem *base;
Tero Kristo81744b72021-06-11 11:45:13 +030088};
89
90#define to_clk_pll(_clk) container_of(_clk, struct ti_pll_clk, clk)
91
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053092static int ti_pll_clk_disable(struct clk *clk)
Tero Kristo81744b72021-06-11 11:45:13 +030093{
94 struct ti_pll_clk *pll = to_clk_pll(clk);
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +053095 u32 ctrl;
96
97 ctrl = readl(pll->base + PLL_16FFT_CTRL);
98
99 if ((ctrl & PLL_16FFT_CTRL_PLL_EN)) {
100 ctrl &= ~PLL_16FFT_CTRL_PLL_EN;
101 writel(ctrl, pll->base + PLL_16FFT_CTRL);
102
103 /* wait 1us */
104 udelay(1);
105 }
106
107 return 0;
108}
109
110static int ti_pll_clk_enable(struct clk *clk)
111{
112 struct ti_pll_clk *pll = to_clk_pll(clk);
113 u32 ctrl;
114
115 ctrl = readl(pll->base + PLL_16FFT_CTRL);
116 ctrl |= PLL_16FFT_CTRL_PLL_EN;
117 writel(ctrl, pll->base + PLL_16FFT_CTRL);
118
119 /* Wait 1us */
120 udelay(1);
121
122 return 0;
123}
124
125static bool clk_pll_16fft_check_lock(const struct ti_pll_clk *pll)
126{
Tero Kristo81744b72021-06-11 11:45:13 +0300127 u32 stat;
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530128
129 stat = readl(pll->base + PLL_16FFT_STAT);
130 return (stat & PLL_16FFT_STAT_LOCK);
131}
132
133static bool clk_pll_16fft_check_cal_lock(const struct ti_pll_clk *pll)
134{
135 u32 stat;
136
137 stat = readl(pll->base + PLL_16FFT_CAL_STAT);
138 return (stat & PLL_16FFT_CAL_STAT_CAL_LOCK);
139}
140
141static void clk_pll_16fft_cal_int(const struct ti_pll_clk *pll)
142{
143 u32 cal;
144
145 cal = readl(pll->base + PLL_16FFT_CAL_CTRL);
146
147 /* Enable fast cal mode */
148 cal |= PLL_16FFT_CAL_CTRL_FAST_CAL;
149
150 /* Disable calibration bypass */
151 cal &= ~PLL_16FFT_CAL_CTRL_CAL_BYP;
152
153 /* Set CALCNT to 2 */
154 cal &= ~PLL_16FFT_CAL_CTRL_CAL_CNT_MASK;
155 cal |= 2 << PLL_16FFT_CAL_CTRL_CAL_CNT_SHIFT;
156
157 /* Set CAL_IN to 0 */
158 cal &= ~PLL_16FFT_CAL_CTRL_CAL_IN_MASK;
159
160 /* Note this register does not readback the written value. */
161 writel(cal, pll->base + PLL_16FFT_CAL_CTRL);
162
163 /* Wait 1us before enabling the CAL_EN field */
164 udelay(1);
165
166 cal = readl(pll->base + PLL_16FFT_CAL_CTRL);
167
168 /* Enable calibration for FRACF */
169 cal |= PLL_16FFT_CAL_CTRL_CAL_EN;
170
171 /* Note this register does not readback the written value. */
172 writel(cal, pll->base + PLL_16FFT_CAL_CTRL);
173}
174
175static void clk_pll_16fft_disable_cal(const struct ti_pll_clk *pll)
176{
177 u32 cal, stat;
178
179 cal = readl(pll->base + PLL_16FFT_CAL_CTRL);
180 cal &= ~PLL_16FFT_CAL_CTRL_CAL_EN;
181 /* Note this register does not readback the written value. */
182 writel(cal, pll->base + PLL_16FFT_CAL_CTRL);
183 do {
184 stat = readl(pll->base + PLL_16FFT_CAL_STAT);
185 } while (stat & PLL_16FFT_CAL_STAT_CAL_LOCK);
186}
187
188static int ti_pll_wait_for_lock(struct clk *clk)
189{
190 struct ti_pll_clk *pll = to_clk_pll(clk);
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500191 u32 cfg;
192 u32 cal;
193 u32 freq_ctrl1;
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530194 unsigned int i;
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500195 u32 pllfm;
196 u32 pll_type;
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530197 u32 cal_en = 0;
198 bool success;
Tero Kristo81744b72021-06-11 11:45:13 +0300199
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530200 /*
201 * Minimum VCO input freq is 5MHz, and the longest a lock should
202 * be consider to be timed out after 750 cycles. Be conservative
203 * and assume each loop takes 10 cycles and we run at a
204 * max of 1GHz. That gives 15000 loop cycles. We may end up waiting
205 * longer than necessary for timeout, but that should be ok.
206 */
207 success = false;
208 for (i = 0; i < PLL_16FFT_STAT_LOCK_TIMEOUT; i++) {
209 if (clk_pll_16fft_check_lock(pll)) {
210 success = true;
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500211 break;
212 }
Tero Kristo81744b72021-06-11 11:45:13 +0300213 }
214
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530215 /* Disable calibration in the fractional mode of the FRACF PLL based on data
216 * from silicon and simulation data.
217 */
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530218 freq_ctrl1 = readl(pll->base + PLL_16FFT_FREQ_CTRL1);
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500219 pllfm = freq_ctrl1 & PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK;
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530220
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530221 cfg = readl(pll->base + PLL_16FFT_CFG);
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500222 pll_type = (cfg & PLL_16FFT_CFG_PLL_TYPE_MASK) >> PLL_16FFT_CFG_PLL_TYPE_SHIFT;
Tero Kristo81744b72021-06-11 11:45:13 +0300223
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530224 if (success && pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF) {
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530225 cal = readl(pll->base + PLL_16FFT_CAL_CTRL);
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530226 cal_en = (cal & PLL_16FFT_CAL_CTRL_CAL_EN);
227 }
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500228
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530229 if (success && pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF &&
230 pllfm == 0 && cal_en == 1) {
231 /*
232 * Wait for calibration lock.
233 *
234 * Lock should occur within:
235 *
236 * 170 * 2^(5+CALCNT) / PFD
237 * 21760 / PFD
238 *
239 * CALCNT = 2, PFD = 5-50MHz. This gives a range of 0.435mS to
240 * 4.35mS depending on PFD frequency.
241 *
242 * Be conservative and assume each loop takes 10 cycles and we run at a
243 * max of 1GHz. That gives 435000 loop cycles. We may end up waiting
244 * longer than necessary for timeout, but that should be ok.
245 *
246 * The recommend timeout for CALLOCK to go high is 4.35 ms
247 */
248 success = false;
249 for (i = 0; i < PLL_16FFT_CAL_STAT_CAL_LOCK_TIMEOUT; i++) {
250 if (clk_pll_16fft_check_cal_lock(pll)) {
251 success = true;
252 break;
253 }
254 }
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500255
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530256 /* In case of cal lock failure, operate without calibration */
257 if (!success) {
258 debug("Failure for calibration, falling back without calibration\n");
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500259
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530260 /* Disable PLL */
261 ti_pll_clk_disable(clk);
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500262
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530263 /* Disable Calibration */
264 clk_pll_16fft_disable_cal(pll);
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500265
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530266 /* Enable PLL */
267 ti_pll_clk_enable(clk);
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500268
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530269 /* Wait for PLL Lock */
270 for (i = 0; i < PLL_16FFT_STAT_LOCK_TIMEOUT; i++) {
271 if (clk_pll_16fft_check_lock(pll)) {
272 success = true;
273 break;
274 }
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500275 }
276 }
277 }
278
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530279 if (!success) {
Vishal Mahaveera5135b82023-10-23 08:35:46 -0500280 printf("%s: pll (%s) failed to lock\n", __func__,
281 clk->dev->name);
282 return -EBUSY;
283 } else {
284 return 0;
285 }
Tero Kristo81744b72021-06-11 11:45:13 +0300286}
287
288static ulong ti_pll_clk_get_rate(struct clk *clk)
289{
290 struct ti_pll_clk *pll = to_clk_pll(clk);
291 u64 current_freq;
292 u64 parent_freq = clk_get_parent_rate(clk);
293 u32 pllm;
294 u32 plld;
295 u32 pllfm;
296 u32 ctrl;
297
298 /* Check if we are in bypass */
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530299 ctrl = readl(pll->base + PLL_16FFT_CTRL);
Tero Kristo81744b72021-06-11 11:45:13 +0300300 if (ctrl & PLL_16FFT_CTRL_BYPASS_EN)
301 return parent_freq;
302
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530303 pllm = readl(pll->base + PLL_16FFT_FREQ_CTRL0);
304 pllfm = readl(pll->base + PLL_16FFT_FREQ_CTRL1);
Tero Kristo81744b72021-06-11 11:45:13 +0300305
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530306 plld = readl(pll->base + PLL_16FFT_DIV_CTRL) &
Tero Kristo81744b72021-06-11 11:45:13 +0300307 PLL_16FFT_DIV_CTRL_REF_DIV_MASK;
308
309 current_freq = parent_freq * pllm / plld;
310
311 if (pllfm) {
312 u64 tmp;
313
314 tmp = parent_freq * pllfm;
315 do_div(tmp, plld);
316 tmp >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS;
317 current_freq += tmp;
318 }
319
320 return current_freq;
321}
322
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530323static bool ti_pll_clk_is_bypass(struct ti_pll_clk *pll)
324{
325 u32 ctrl;
326 bool ret;
327
328 ctrl = readl(pll->base + PLL_16FFT_CTRL);
329 ret = (ctrl & PLL_16FFT_CTRL_BYPASS_EN) != 0;
330
331 return ret;
332}
333
334static void ti_pll_clk_bypass(struct ti_pll_clk *pll, bool bypass)
335{
336 u32 ctrl;
337
338 ctrl = readl(pll->base + PLL_16FFT_CTRL);
339 if (bypass)
340 ctrl |= PLL_16FFT_CTRL_BYPASS_EN;
341 else
342 ctrl &= ~PLL_16FFT_CTRL_BYPASS_EN;
343
344 writel(ctrl, pll->base + PLL_16FFT_CTRL);
345}
346
Tero Kristo81744b72021-06-11 11:45:13 +0300347static ulong ti_pll_clk_set_rate(struct clk *clk, ulong rate)
348{
349 struct ti_pll_clk *pll = to_clk_pll(clk);
350 u64 current_freq;
351 u64 parent_freq = clk_get_parent_rate(clk);
352 int ret;
353 u32 ctrl;
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530354 u32 cfg;
355 u32 pll_type;
Tero Kristo81744b72021-06-11 11:45:13 +0300356 unsigned long pllm;
357 u32 pllfm = 0;
358 unsigned long plld;
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530359 u32 freq_ctrl0;
360 u32 freq_ctrl1;
Dave Gerlach6bc722e2021-09-07 17:16:57 -0500361 u32 div_ctrl;
Tero Kristo81744b72021-06-11 11:45:13 +0300362 u32 rem;
363 int shift;
364
365 debug("%s(clk=%p, rate=%u)\n", __func__, clk, (u32)rate);
366
367 if (ti_pll_clk_get_rate(clk) == rate)
368 return rate;
369
370 if (rate != parent_freq)
371 /*
372 * Attempt with higher max multiplier value first to give
373 * some space for fractional divider to kick in.
374 */
375 for (shift = 8; shift >= 0; shift -= 8) {
376 rational_best_approximation(rate, parent_freq,
377 ((PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK + 1) << shift) - 1,
378 PLL_16FFT_DIV_CTRL_REF_DIV_MASK, &pllm, &plld);
379 if (pllm / plld <= PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK)
380 break;
381 }
382
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530383 if (!ti_pll_clk_is_bypass(pll)) {
384 /* Put the PLL into bypass */
385 ti_pll_clk_bypass(pll, true);
386 }
387
388 /* Disable the PLL */
389 ti_pll_clk_disable(clk);
Tero Kristo81744b72021-06-11 11:45:13 +0300390
391 if (rate == parent_freq) {
392 debug("%s: put %s to bypass\n", __func__, clk->dev->name);
393 return rate;
394 }
395
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530396 cfg = readl(pll->base + PLL_16FFT_CFG);
397 pll_type = (cfg & PLL_16FFT_CFG_PLL_TYPE_MASK) >> PLL_16FFT_CFG_PLL_TYPE_SHIFT;
398
Tero Kristo81744b72021-06-11 11:45:13 +0300399 debug("%s: pre-frac-calc: rate=%u, parent_freq=%u, plld=%u, pllm=%u\n",
400 __func__, (u32)rate, (u32)parent_freq, (u32)plld, (u32)pllm);
401
402 /* Check if we need fractional config */
403 if (plld > 1) {
404 pllfm = pllm % plld;
405 pllfm <<= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS;
406 rem = pllfm % plld;
407 pllfm /= plld;
408 if (rem)
409 pllfm++;
410 pllm /= plld;
411 plld = 1;
412 }
413
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530414 /* Program the new rate */
415 freq_ctrl0 = readl(pll->base + PLL_16FFT_FREQ_CTRL0);
416 freq_ctrl1 = readl(pll->base + PLL_16FFT_FREQ_CTRL1);
417 div_ctrl = readl(pll->base + PLL_16FFT_DIV_CTRL);
Tero Kristo81744b72021-06-11 11:45:13 +0300418
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530419 freq_ctrl0 &= ~PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK;
420 freq_ctrl0 |= pllm;
421
422 freq_ctrl1 &= ~PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_MASK;
423 freq_ctrl1 |= pllfm;
Dave Gerlach6bc722e2021-09-07 17:16:57 -0500424
425 /*
426 * div_ctrl register contains other divider values, so rmw
427 * only plld and leave existing values alone
428 */
Dave Gerlach6bc722e2021-09-07 17:16:57 -0500429 div_ctrl &= ~PLL_16FFT_DIV_CTRL_REF_DIV_MASK;
430 div_ctrl |= plld;
Tero Kristo81744b72021-06-11 11:45:13 +0300431
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530432 /* Make sure we have fractional support if required */
433 ctrl = readl(pll->base + PLL_16FFT_CTRL);
434
435 /* Don't use internal bypass,it is not glitch free. Always prefer glitchless bypass */
436 ctrl &= ~(PLL_16FFT_CTRL_INTL_BYP_EN | PLL_16FFT_CTRL_CLK_4PH_EN);
437
438 /* Always enable output if PLL, Always bypass if we lose lock */
439 ctrl |= (PLL_16FFT_CTRL_CLK_POSTDIV_EN | PLL_16FFT_CTRL_BYP_ON_LOCKLOSS);
440
441 /* Enable fractional support if required */
442 if (pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF) {
443 if (pllfm != 0)
444 ctrl |= (PLL_16FFT_CTRL_DSM_EN | PLL_16FFT_CTRL_DAC_EN);
445 else
446 ctrl &= ~(PLL_16FFT_CTRL_DSM_EN | PLL_16FFT_CTRL_DAC_EN);
447 }
448
449 /* Enable Fractional by default for PLL_16FFT_CFG_PLL_TYPE_FRAC2 */
450 if (pll_type == PLL_16FFT_CFG_PLL_TYPE_FRAC2)
451 ctrl |= (PLL_16FFT_CTRL_DSM_EN | PLL_16FFT_CTRL_DAC_EN);
452
453 writel(freq_ctrl0, pll->base + PLL_16FFT_FREQ_CTRL0);
454 writel(freq_ctrl1, pll->base + PLL_16FFT_FREQ_CTRL1);
455 writel(div_ctrl, pll->base + PLL_16FFT_DIV_CTRL);
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530456 writel(ctrl, pll->base + PLL_16FFT_CTRL);
Tero Kristo81744b72021-06-11 11:45:13 +0300457
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530458 /* Configure PLL calibration*/
459 if (pll_type == PLL_16FFT_CFG_PLL_TYPE_FRACF) {
460 if (pllfm != 0) {
461 /* Disable Calibration in Fractional mode */
462 clk_pll_16fft_disable_cal(pll);
463 } else {
464 /* Enable Calibration in Integer mode */
465 clk_pll_16fft_cal_int(pll);
466 }
467 }
468
469 /*
470 * Wait at least 1 ref cycle before enabling PLL.
471 * Minimum VCO input frequency is 5MHz, therefore maximum
472 * wait time for 1 ref clock is 0.2us.
473 */
474 udelay(1);
475 ti_pll_clk_enable(clk);
476
Tero Kristo81744b72021-06-11 11:45:13 +0300477 ret = ti_pll_wait_for_lock(clk);
478 if (ret)
479 return ret;
480
Manorit Chawdhry02fb7bf2024-11-21 17:32:53 +0530481 ti_pll_clk_bypass(pll, false);
482
Tero Kristo81744b72021-06-11 11:45:13 +0300483 debug("%s: pllm=%u, plld=%u, pllfm=%u, parent_freq=%u\n",
484 __func__, (u32)pllm, (u32)plld, (u32)pllfm, (u32)parent_freq);
485
486 current_freq = parent_freq * pllm / plld;
487
488 if (pllfm) {
489 u64 tmp;
490
491 tmp = parent_freq * pllfm;
492 do_div(tmp, plld);
493 tmp >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS;
494 current_freq += tmp;
495 }
496
497 return current_freq;
498}
499
Tero Kristo81744b72021-06-11 11:45:13 +0300500
Tero Kristo81744b72021-06-11 11:45:13 +0300501
502static const struct clk_ops ti_pll_clk_ops = {
503 .get_rate = ti_pll_clk_get_rate,
504 .set_rate = ti_pll_clk_set_rate,
505 .enable = ti_pll_clk_enable,
506 .disable = ti_pll_clk_disable,
507};
508
509struct clk *clk_register_ti_pll(const char *name, const char *parent_name,
510 void __iomem *reg)
511{
512 struct ti_pll_clk *pll;
513 int ret;
514 int i;
515 u32 cfg, ctrl, hsdiv_presence_bit, hsdiv_ctrl_offs;
516
517 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
518 if (!pll)
519 return ERR_PTR(-ENOMEM);
520
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530521 pll->base = reg;
Tero Kristo81744b72021-06-11 11:45:13 +0300522
523 ret = clk_register(&pll->clk, "ti-pll-clk", name, parent_name);
524 if (ret) {
525 printf("%s: failed to register: %d\n", __func__, ret);
526 kfree(pll);
527 return ERR_PTR(ret);
528 }
529
530 /* Unlock the PLL registers */
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530531 writel(PLL_KICK0_VALUE, pll->base + PLL_KICK0);
532 writel(PLL_KICK1_VALUE, pll->base + PLL_KICK1);
Tero Kristo81744b72021-06-11 11:45:13 +0300533
534 /* Enable all HSDIV outputs */
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530535 cfg = readl(pll->base + PLL_16FFT_CFG);
Tero Kristo81744b72021-06-11 11:45:13 +0300536 for (i = 0; i < 16; i++) {
537 hsdiv_presence_bit = BIT(16 + i);
538 hsdiv_ctrl_offs = 0x80 + (i * 4);
539 /* Enable HSDIV output if present */
540 if ((hsdiv_presence_bit & cfg) != 0UL) {
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530541 ctrl = readl(pll->base + hsdiv_ctrl_offs);
Tero Kristo81744b72021-06-11 11:45:13 +0300542 ctrl |= PLL_16FFT_HSDIV_CTRL_CLKOUT_EN;
Manorit Chawdhry65caba52024-11-21 17:32:52 +0530543 writel(ctrl, pll->base + hsdiv_ctrl_offs);
Tero Kristo81744b72021-06-11 11:45:13 +0300544 }
545 }
546
547 return &pll->clk;
548}
549
550U_BOOT_DRIVER(ti_pll_clk) = {
551 .name = "ti-pll-clk",
552 .id = UCLASS_CLK,
553 .ops = &ti_pll_clk_ops,
554 .flags = DM_FLAG_PRE_RELOC,
555};