1
2
3
4
5
6#include <linux/kernel.h>
7#include <linux/export.h>
8#include <linux/clk-provider.h>
9#include <linux/regmap.h>
10#include <linux/delay.h>
11
12#include "clk-alpha-pll.h"
13#include "common.h"
14
15#define PLL_MODE(p) ((p)->offset + 0x0)
16# define PLL_OUTCTRL BIT(0)
17# define PLL_BYPASSNL BIT(1)
18# define PLL_RESET_N BIT(2)
19# define PLL_OFFLINE_REQ BIT(7)
20# define PLL_LOCK_COUNT_SHIFT 8
21# define PLL_LOCK_COUNT_MASK 0x3f
22# define PLL_BIAS_COUNT_SHIFT 14
23# define PLL_BIAS_COUNT_MASK 0x3f
24# define PLL_VOTE_FSM_ENA BIT(20)
25# define PLL_FSM_ENA BIT(20)
26# define PLL_VOTE_FSM_RESET BIT(21)
27# define PLL_UPDATE BIT(22)
28# define PLL_UPDATE_BYPASS BIT(23)
29# define PLL_OFFLINE_ACK BIT(28)
30# define ALPHA_PLL_ACK_LATCH BIT(29)
31# define PLL_ACTIVE_FLAG BIT(30)
32# define PLL_LOCK_DET BIT(31)
33
34#define PLL_L_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_L_VAL])
35#define PLL_CAL_L_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_CAL_L_VAL])
36#define PLL_ALPHA_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL])
37#define PLL_ALPHA_VAL_U(p) ((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL_U])
38
39#define PLL_USER_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL])
40# define PLL_POST_DIV_SHIFT 8
41# define PLL_POST_DIV_MASK(p) GENMASK((p)->width, 0)
42# define PLL_ALPHA_EN BIT(24)
43# define PLL_ALPHA_MODE BIT(25)
44# define PLL_VCO_SHIFT 20
45# define PLL_VCO_MASK 0x3
46
47#define PLL_USER_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U])
48#define PLL_USER_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U1])
49
50#define PLL_CONFIG_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL])
51#define PLL_CONFIG_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U])
52#define PLL_CONFIG_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1])
53#define PLL_TEST_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL])
54#define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])
55#define PLL_TEST_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1])
56#define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS])
57#define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE])
58#define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC])
59
60const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
61 [CLK_ALPHA_PLL_TYPE_DEFAULT] = {
62 [PLL_OFF_L_VAL] = 0x04,
63 [PLL_OFF_ALPHA_VAL] = 0x08,
64 [PLL_OFF_ALPHA_VAL_U] = 0x0c,
65 [PLL_OFF_USER_CTL] = 0x10,
66 [PLL_OFF_USER_CTL_U] = 0x14,
67 [PLL_OFF_CONFIG_CTL] = 0x18,
68 [PLL_OFF_TEST_CTL] = 0x1c,
69 [PLL_OFF_TEST_CTL_U] = 0x20,
70 [PLL_OFF_STATUS] = 0x24,
71 },
72 [CLK_ALPHA_PLL_TYPE_HUAYRA] = {
73 [PLL_OFF_L_VAL] = 0x04,
74 [PLL_OFF_ALPHA_VAL] = 0x08,
75 [PLL_OFF_USER_CTL] = 0x10,
76 [PLL_OFF_CONFIG_CTL] = 0x14,
77 [PLL_OFF_CONFIG_CTL_U] = 0x18,
78 [PLL_OFF_TEST_CTL] = 0x1c,
79 [PLL_OFF_TEST_CTL_U] = 0x20,
80 [PLL_OFF_STATUS] = 0x24,
81 },
82 [CLK_ALPHA_PLL_TYPE_BRAMMO] = {
83 [PLL_OFF_L_VAL] = 0x04,
84 [PLL_OFF_ALPHA_VAL] = 0x08,
85 [PLL_OFF_ALPHA_VAL_U] = 0x0c,
86 [PLL_OFF_USER_CTL] = 0x10,
87 [PLL_OFF_CONFIG_CTL] = 0x18,
88 [PLL_OFF_TEST_CTL] = 0x1c,
89 [PLL_OFF_STATUS] = 0x24,
90 },
91 [CLK_ALPHA_PLL_TYPE_FABIA] = {
92 [PLL_OFF_L_VAL] = 0x04,
93 [PLL_OFF_USER_CTL] = 0x0c,
94 [PLL_OFF_USER_CTL_U] = 0x10,
95 [PLL_OFF_CONFIG_CTL] = 0x14,
96 [PLL_OFF_CONFIG_CTL_U] = 0x18,
97 [PLL_OFF_TEST_CTL] = 0x1c,
98 [PLL_OFF_TEST_CTL_U] = 0x20,
99 [PLL_OFF_STATUS] = 0x24,
100 [PLL_OFF_OPMODE] = 0x2c,
101 [PLL_OFF_FRAC] = 0x38,
102 },
103 [CLK_ALPHA_PLL_TYPE_TRION] = {
104 [PLL_OFF_L_VAL] = 0x04,
105 [PLL_OFF_CAL_L_VAL] = 0x08,
106 [PLL_OFF_USER_CTL] = 0x0c,
107 [PLL_OFF_USER_CTL_U] = 0x10,
108 [PLL_OFF_USER_CTL_U1] = 0x14,
109 [PLL_OFF_CONFIG_CTL] = 0x18,
110 [PLL_OFF_CONFIG_CTL_U] = 0x1c,
111 [PLL_OFF_CONFIG_CTL_U1] = 0x20,
112 [PLL_OFF_TEST_CTL] = 0x24,
113 [PLL_OFF_TEST_CTL_U] = 0x28,
114 [PLL_OFF_TEST_CTL_U1] = 0x2c,
115 [PLL_OFF_STATUS] = 0x30,
116 [PLL_OFF_OPMODE] = 0x38,
117 [PLL_OFF_ALPHA_VAL] = 0x40,
118 },
119 [CLK_ALPHA_PLL_TYPE_AGERA] = {
120 [PLL_OFF_L_VAL] = 0x04,
121 [PLL_OFF_ALPHA_VAL] = 0x08,
122 [PLL_OFF_USER_CTL] = 0x0c,
123 [PLL_OFF_CONFIG_CTL] = 0x10,
124 [PLL_OFF_CONFIG_CTL_U] = 0x14,
125 [PLL_OFF_TEST_CTL] = 0x18,
126 [PLL_OFF_TEST_CTL_U] = 0x1c,
127 [PLL_OFF_STATUS] = 0x2c,
128 },
129 [CLK_ALPHA_PLL_TYPE_ZONDA] = {
130 [PLL_OFF_L_VAL] = 0x04,
131 [PLL_OFF_ALPHA_VAL] = 0x08,
132 [PLL_OFF_USER_CTL] = 0x0c,
133 [PLL_OFF_CONFIG_CTL] = 0x10,
134 [PLL_OFF_CONFIG_CTL_U] = 0x14,
135 [PLL_OFF_CONFIG_CTL_U1] = 0x18,
136 [PLL_OFF_TEST_CTL] = 0x1c,
137 [PLL_OFF_TEST_CTL_U] = 0x20,
138 [PLL_OFF_TEST_CTL_U1] = 0x24,
139 [PLL_OFF_OPMODE] = 0x28,
140 [PLL_OFF_STATUS] = 0x38,
141 },
142};
143EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
144
145
146
147
148#define ALPHA_REG_BITWIDTH 40
149#define ALPHA_REG_16BIT_WIDTH 16
150#define ALPHA_BITWIDTH 32U
151#define ALPHA_SHIFT(w) min(w, ALPHA_BITWIDTH)
152
153#define PLL_HUAYRA_M_WIDTH 8
154#define PLL_HUAYRA_M_SHIFT 8
155#define PLL_HUAYRA_M_MASK 0xff
156#define PLL_HUAYRA_N_SHIFT 0
157#define PLL_HUAYRA_N_MASK 0xff
158#define PLL_HUAYRA_ALPHA_WIDTH 16
159
160#define PLL_STANDBY 0x0
161#define PLL_RUN 0x1
162#define PLL_OUT_MASK 0x7
163#define PLL_RATE_MARGIN 500
164
165
166#define TRION_PLL_CAL_VAL 0x44
167#define TRION_PCAL_DONE BIT(26)
168
169
170#define LUCID_PCAL_DONE BIT(27)
171
172
173#define LUCID_5LPE_PCAL_DONE BIT(11)
174#define LUCID_5LPE_ALPHA_PLL_ACK_LATCH BIT(13)
175#define LUCID_5LPE_PLL_LATCH_INPUT BIT(14)
176#define LUCID_5LPE_ENABLE_VOTE_RUN BIT(21)
177
178
179#define ZONDA_PLL_OUT_MASK 0xf
180#define ZONDA_STAY_IN_CFA BIT(16)
181#define ZONDA_PLL_FREQ_LOCK_DET BIT(29)
182
183#define pll_alpha_width(p) \
184 ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \
185 ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH)
186
187#define pll_has_64bit_config(p) ((PLL_CONFIG_CTL_U(p) - PLL_CONFIG_CTL(p)) == 4)
188
189#define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \
190 struct clk_alpha_pll, clkr)
191
192#define to_clk_alpha_pll_postdiv(_hw) container_of(to_clk_regmap(_hw), \
193 struct clk_alpha_pll_postdiv, clkr)
194
195static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
196 const char *action)
197{
198 u32 val;
199 int count;
200 int ret;
201 const char *name = clk_hw_get_name(&pll->clkr.hw);
202
203 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
204 if (ret)
205 return ret;
206
207 for (count = 100; count > 0; count--) {
208 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
209 if (ret)
210 return ret;
211 if (inverse && !(val & mask))
212 return 0;
213 else if ((val & mask) == mask)
214 return 0;
215
216 udelay(1);
217 }
218
219 WARN(1, "%s failed to %s!\n", name, action);
220 return -ETIMEDOUT;
221}
222
223#define wait_for_pll_enable_active(pll) \
224 wait_for_pll(pll, PLL_ACTIVE_FLAG, 0, "enable")
225
226#define wait_for_pll_enable_lock(pll) \
227 wait_for_pll(pll, PLL_LOCK_DET, 0, "enable")
228
229#define wait_for_zonda_pll_freq_lock(pll) \
230 wait_for_pll(pll, ZONDA_PLL_FREQ_LOCK_DET, 0, "freq enable")
231
232#define wait_for_pll_disable(pll) \
233 wait_for_pll(pll, PLL_ACTIVE_FLAG, 1, "disable")
234
235#define wait_for_pll_offline(pll) \
236 wait_for_pll(pll, PLL_OFFLINE_ACK, 0, "offline")
237
238#define wait_for_pll_update(pll) \
239 wait_for_pll(pll, PLL_UPDATE, 1, "update")
240
241#define wait_for_pll_update_ack_set(pll) \
242 wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 0, "update_ack_set")
243
244#define wait_for_pll_update_ack_clear(pll) \
245 wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 1, "update_ack_clear")
246
247static void clk_alpha_pll_write_config(struct regmap *regmap, unsigned int reg,
248 unsigned int val)
249{
250 if (val)
251 regmap_write(regmap, reg, val);
252}
253
254void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
255 const struct alpha_pll_config *config)
256{
257 u32 val, mask;
258
259 regmap_write(regmap, PLL_L_VAL(pll), config->l);
260 regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha);
261 regmap_write(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
262
263 if (pll_has_64bit_config(pll))
264 regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
265 config->config_ctl_hi_val);
266
267 if (pll_alpha_width(pll) > 32)
268 regmap_write(regmap, PLL_ALPHA_VAL_U(pll), config->alpha_hi);
269
270 val = config->main_output_mask;
271 val |= config->aux_output_mask;
272 val |= config->aux2_output_mask;
273 val |= config->early_output_mask;
274 val |= config->pre_div_val;
275 val |= config->post_div_val;
276 val |= config->vco_val;
277 val |= config->alpha_en_mask;
278 val |= config->alpha_mode_mask;
279
280 mask = config->main_output_mask;
281 mask |= config->aux_output_mask;
282 mask |= config->aux2_output_mask;
283 mask |= config->early_output_mask;
284 mask |= config->pre_div_mask;
285 mask |= config->post_div_mask;
286 mask |= config->vco_mask;
287
288 regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);
289
290 if (pll->flags & SUPPORTS_FSM_MODE)
291 qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
292}
293EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
294
295static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
296{
297 int ret;
298 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
299 u32 val;
300
301 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
302 if (ret)
303 return ret;
304
305 val |= PLL_FSM_ENA;
306
307 if (pll->flags & SUPPORTS_OFFLINE_REQ)
308 val &= ~PLL_OFFLINE_REQ;
309
310 ret = regmap_write(pll->clkr.regmap, PLL_MODE(pll), val);
311 if (ret)
312 return ret;
313
314
315 mb();
316
317 return wait_for_pll_enable_active(pll);
318}
319
320static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
321{
322 int ret;
323 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
324 u32 val;
325
326 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
327 if (ret)
328 return;
329
330 if (pll->flags & SUPPORTS_OFFLINE_REQ) {
331 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
332 PLL_OFFLINE_REQ, PLL_OFFLINE_REQ);
333 if (ret)
334 return;
335
336 ret = wait_for_pll_offline(pll);
337 if (ret)
338 return;
339 }
340
341
342 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
343 PLL_FSM_ENA, 0);
344 if (ret)
345 return;
346
347 wait_for_pll_disable(pll);
348}
349
350static int pll_is_enabled(struct clk_hw *hw, u32 mask)
351{
352 int ret;
353 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
354 u32 val;
355
356 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
357 if (ret)
358 return ret;
359
360 return !!(val & mask);
361}
362
363static int clk_alpha_pll_hwfsm_is_enabled(struct clk_hw *hw)
364{
365 return pll_is_enabled(hw, PLL_ACTIVE_FLAG);
366}
367
368static int clk_alpha_pll_is_enabled(struct clk_hw *hw)
369{
370 return pll_is_enabled(hw, PLL_LOCK_DET);
371}
372
373static int clk_alpha_pll_enable(struct clk_hw *hw)
374{
375 int ret;
376 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
377 u32 val, mask;
378
379 mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
380 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
381 if (ret)
382 return ret;
383
384
385 if (val & PLL_VOTE_FSM_ENA) {
386 ret = clk_enable_regmap(hw);
387 if (ret)
388 return ret;
389 return wait_for_pll_enable_active(pll);
390 }
391
392
393 if ((val & mask) == mask)
394 return 0;
395
396 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
397 PLL_BYPASSNL, PLL_BYPASSNL);
398 if (ret)
399 return ret;
400
401
402
403
404
405 mb();
406 udelay(5);
407
408 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
409 PLL_RESET_N, PLL_RESET_N);
410 if (ret)
411 return ret;
412
413 ret = wait_for_pll_enable_lock(pll);
414 if (ret)
415 return ret;
416
417 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
418 PLL_OUTCTRL, PLL_OUTCTRL);
419
420
421 mb();
422 return ret;
423}
424
425static void clk_alpha_pll_disable(struct clk_hw *hw)
426{
427 int ret;
428 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
429 u32 val, mask;
430
431 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
432 if (ret)
433 return;
434
435
436 if (val & PLL_VOTE_FSM_ENA) {
437 clk_disable_regmap(hw);
438 return;
439 }
440
441 mask = PLL_OUTCTRL;
442 regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), mask, 0);
443
444
445 mb();
446 udelay(1);
447
448 mask = PLL_RESET_N | PLL_BYPASSNL;
449 regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), mask, 0);
450}
451
452static unsigned long
453alpha_pll_calc_rate(u64 prate, u32 l, u32 a, u32 alpha_width)
454{
455 return (prate * l) + ((prate * a) >> ALPHA_SHIFT(alpha_width));
456}
457
458static unsigned long
459alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a,
460 u32 alpha_width)
461{
462 u64 remainder;
463 u64 quotient;
464
465 quotient = rate;
466 remainder = do_div(quotient, prate);
467 *l = quotient;
468
469 if (!remainder) {
470 *a = 0;
471 return rate;
472 }
473
474
475 quotient = remainder << ALPHA_SHIFT(alpha_width);
476
477 remainder = do_div(quotient, prate);
478
479 if (remainder)
480 quotient++;
481
482 *a = quotient;
483 return alpha_pll_calc_rate(prate, *l, *a, alpha_width);
484}
485
486static const struct pll_vco *
487alpha_pll_find_vco(const struct clk_alpha_pll *pll, unsigned long rate)
488{
489 const struct pll_vco *v = pll->vco_table;
490 const struct pll_vco *end = v + pll->num_vco;
491
492 for (; v < end; v++)
493 if (rate >= v->min_freq && rate <= v->max_freq)
494 return v;
495
496 return NULL;
497}
498
499static unsigned long
500clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
501{
502 u32 l, low, high, ctl;
503 u64 a = 0, prate = parent_rate;
504 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
505 u32 alpha_width = pll_alpha_width(pll);
506
507 regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);
508
509 regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
510 if (ctl & PLL_ALPHA_EN) {
511 regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low);
512 if (alpha_width > 32) {
513 regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),
514 &high);
515 a = (u64)high << 32 | low;
516 } else {
517 a = low & GENMASK(alpha_width - 1, 0);
518 }
519
520 if (alpha_width > ALPHA_BITWIDTH)
521 a >>= alpha_width - ALPHA_BITWIDTH;
522 }
523
524 return alpha_pll_calc_rate(prate, l, a, alpha_width);
525}
526
527
528static int __clk_alpha_pll_update_latch(struct clk_alpha_pll *pll)
529{
530 int ret;
531 u32 mode;
532
533 regmap_read(pll->clkr.regmap, PLL_MODE(pll), &mode);
534
535
536 regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_UPDATE,
537 PLL_UPDATE);
538
539
540 udelay(1);
541
542
543
544
545
546
547
548
549 if (mode & PLL_UPDATE_BYPASS) {
550 ret = wait_for_pll_update_ack_set(pll);
551 if (ret)
552 return ret;
553
554 regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_UPDATE, 0);
555 } else {
556 ret = wait_for_pll_update(pll);
557 if (ret)
558 return ret;
559 }
560
561 ret = wait_for_pll_update_ack_clear(pll);
562 if (ret)
563 return ret;
564
565
566 udelay(10);
567
568 return 0;
569}
570
571static int clk_alpha_pll_update_latch(struct clk_alpha_pll *pll,
572 int (*is_enabled)(struct clk_hw *))
573{
574 if (!is_enabled(&pll->clkr.hw) ||
575 !(pll->flags & SUPPORTS_DYNAMIC_UPDATE))
576 return 0;
577
578 return __clk_alpha_pll_update_latch(pll);
579}
580
581static int __clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
582 unsigned long prate,
583 int (*is_enabled)(struct clk_hw *))
584{
585 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
586 const struct pll_vco *vco;
587 u32 l, alpha_width = pll_alpha_width(pll);
588 u64 a;
589
590 rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
591 vco = alpha_pll_find_vco(pll, rate);
592 if (pll->vco_table && !vco) {
593 pr_err("%s: alpha pll not in a valid vco range\n",
594 clk_hw_get_name(hw));
595 return -EINVAL;
596 }
597
598 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
599
600 if (alpha_width > ALPHA_BITWIDTH)
601 a <<= alpha_width - ALPHA_BITWIDTH;
602
603 if (alpha_width > 32)
604 regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> 32);
605
606 regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
607
608 if (vco) {
609 regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
610 PLL_VCO_MASK << PLL_VCO_SHIFT,
611 vco->val << PLL_VCO_SHIFT);
612 }
613
614 regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
615 PLL_ALPHA_EN, PLL_ALPHA_EN);
616
617 return clk_alpha_pll_update_latch(pll, is_enabled);
618}
619
620static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
621 unsigned long prate)
622{
623 return __clk_alpha_pll_set_rate(hw, rate, prate,
624 clk_alpha_pll_is_enabled);
625}
626
627static int clk_alpha_pll_hwfsm_set_rate(struct clk_hw *hw, unsigned long rate,
628 unsigned long prate)
629{
630 return __clk_alpha_pll_set_rate(hw, rate, prate,
631 clk_alpha_pll_hwfsm_is_enabled);
632}
633
634static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
635 unsigned long *prate)
636{
637 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
638 u32 l, alpha_width = pll_alpha_width(pll);
639 u64 a;
640 unsigned long min_freq, max_freq;
641
642 rate = alpha_pll_round_rate(rate, *prate, &l, &a, alpha_width);
643 if (!pll->vco_table || alpha_pll_find_vco(pll, rate))
644 return rate;
645
646 min_freq = pll->vco_table[0].min_freq;
647 max_freq = pll->vco_table[pll->num_vco - 1].max_freq;
648
649 return clamp(rate, min_freq, max_freq);
650}
651
652static unsigned long
653alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
654{
655
656
657
658
659 if (a >= BIT(PLL_HUAYRA_ALPHA_WIDTH - 1))
660 l -= 1;
661
662 return (prate * l) + (prate * a >> PLL_HUAYRA_ALPHA_WIDTH);
663}
664
665static unsigned long
666alpha_huayra_pll_round_rate(unsigned long rate, unsigned long prate,
667 u32 *l, u32 *a)
668{
669 u64 remainder;
670 u64 quotient;
671
672 quotient = rate;
673 remainder = do_div(quotient, prate);
674 *l = quotient;
675
676 if (!remainder) {
677 *a = 0;
678 return rate;
679 }
680
681 quotient = remainder << PLL_HUAYRA_ALPHA_WIDTH;
682 remainder = do_div(quotient, prate);
683
684 if (remainder)
685 quotient++;
686
687
688
689
690
691
692 if (quotient >= BIT(PLL_HUAYRA_ALPHA_WIDTH - 1))
693 *l += 1;
694
695 *a = quotient;
696 return alpha_huayra_pll_calc_rate(prate, *l, *a);
697}
698
699static unsigned long
700alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
701{
702 u64 rate = parent_rate, tmp;
703 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
704 u32 l, alpha = 0, ctl, alpha_m, alpha_n;
705
706 regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);
707 regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
708
709 if (ctl & PLL_ALPHA_EN) {
710 regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &alpha);
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728 if (!(ctl & PLL_ALPHA_MODE))
729 return alpha_huayra_pll_calc_rate(rate, l, alpha);
730
731 alpha_m = alpha >> PLL_HUAYRA_M_SHIFT & PLL_HUAYRA_M_MASK;
732 alpha_n = alpha >> PLL_HUAYRA_N_SHIFT & PLL_HUAYRA_N_MASK;
733
734 rate *= l;
735 tmp = parent_rate;
736 if (alpha_m >= BIT(PLL_HUAYRA_M_WIDTH - 1)) {
737 alpha_m = BIT(PLL_HUAYRA_M_WIDTH) - alpha_m;
738 tmp *= alpha_m;
739 do_div(tmp, alpha_n);
740 rate -= tmp;
741 } else {
742 tmp *= alpha_m;
743 do_div(tmp, alpha_n);
744 rate += tmp;
745 }
746
747 return rate;
748 }
749
750 return alpha_huayra_pll_calc_rate(rate, l, alpha);
751}
752
753static int alpha_pll_huayra_set_rate(struct clk_hw *hw, unsigned long rate,
754 unsigned long prate)
755{
756 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
757 u32 l, a, ctl, cur_alpha = 0;
758
759 rate = alpha_huayra_pll_round_rate(rate, prate, &l, &a);
760
761 regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
762
763 if (ctl & PLL_ALPHA_EN)
764 regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &cur_alpha);
765
766
767
768
769
770 if (clk_alpha_pll_is_enabled(hw)) {
771 if (cur_alpha != a) {
772 pr_err("%s: clock needs to be gated\n",
773 clk_hw_get_name(hw));
774 return -EBUSY;
775 }
776
777 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
778
779 mb();
780 return wait_for_pll_enable_lock(pll);
781 }
782
783 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
784 regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
785
786 if (a == 0)
787 regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
788 PLL_ALPHA_EN, 0x0);
789 else
790 regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
791 PLL_ALPHA_EN | PLL_ALPHA_MODE, PLL_ALPHA_EN);
792
793 return 0;
794}
795
796static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate,
797 unsigned long *prate)
798{
799 u32 l, a;
800
801 return alpha_huayra_pll_round_rate(rate, *prate, &l, &a);
802}
803
804static int trion_pll_is_enabled(struct clk_alpha_pll *pll,
805 struct regmap *regmap)
806{
807 u32 mode_val, opmode_val;
808 int ret;
809
810 ret = regmap_read(regmap, PLL_MODE(pll), &mode_val);
811 ret |= regmap_read(regmap, PLL_OPMODE(pll), &opmode_val);
812 if (ret)
813 return 0;
814
815 return ((opmode_val & PLL_RUN) && (mode_val & PLL_OUTCTRL));
816}
817
818static int clk_trion_pll_is_enabled(struct clk_hw *hw)
819{
820 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
821
822 return trion_pll_is_enabled(pll, pll->clkr.regmap);
823}
824
825static int clk_trion_pll_enable(struct clk_hw *hw)
826{
827 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
828 struct regmap *regmap = pll->clkr.regmap;
829 u32 val;
830 int ret;
831
832 ret = regmap_read(regmap, PLL_MODE(pll), &val);
833 if (ret)
834 return ret;
835
836
837 if (val & PLL_VOTE_FSM_ENA) {
838 ret = clk_enable_regmap(hw);
839 if (ret)
840 return ret;
841 return wait_for_pll_enable_active(pll);
842 }
843
844
845 regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);
846
847 ret = wait_for_pll_enable_lock(pll);
848 if (ret)
849 return ret;
850
851
852 ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),
853 PLL_OUT_MASK, PLL_OUT_MASK);
854 if (ret)
855 return ret;
856
857
858 return regmap_update_bits(regmap, PLL_MODE(pll),
859 PLL_OUTCTRL, PLL_OUTCTRL);
860}
861
862static void clk_trion_pll_disable(struct clk_hw *hw)
863{
864 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
865 struct regmap *regmap = pll->clkr.regmap;
866 u32 val;
867 int ret;
868
869 ret = regmap_read(regmap, PLL_MODE(pll), &val);
870 if (ret)
871 return;
872
873
874 if (val & PLL_VOTE_FSM_ENA) {
875 clk_disable_regmap(hw);
876 return;
877 }
878
879
880 ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
881 if (ret)
882 return;
883
884
885 ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),
886 PLL_OUT_MASK, 0);
887 if (ret)
888 return;
889
890
891 regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
892 regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
893}
894
895static unsigned long
896clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
897{
898 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
899 u32 l, frac, alpha_width = pll_alpha_width(pll);
900
901 regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);
902 regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac);
903
904 return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width);
905}
906
907const struct clk_ops clk_alpha_pll_fixed_ops = {
908 .enable = clk_alpha_pll_enable,
909 .disable = clk_alpha_pll_disable,
910 .is_enabled = clk_alpha_pll_is_enabled,
911 .recalc_rate = clk_alpha_pll_recalc_rate,
912};
913EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_ops);
914
915const struct clk_ops clk_alpha_pll_ops = {
916 .enable = clk_alpha_pll_enable,
917 .disable = clk_alpha_pll_disable,
918 .is_enabled = clk_alpha_pll_is_enabled,
919 .recalc_rate = clk_alpha_pll_recalc_rate,
920 .round_rate = clk_alpha_pll_round_rate,
921 .set_rate = clk_alpha_pll_set_rate,
922};
923EXPORT_SYMBOL_GPL(clk_alpha_pll_ops);
924
925const struct clk_ops clk_alpha_pll_huayra_ops = {
926 .enable = clk_alpha_pll_enable,
927 .disable = clk_alpha_pll_disable,
928 .is_enabled = clk_alpha_pll_is_enabled,
929 .recalc_rate = alpha_pll_huayra_recalc_rate,
930 .round_rate = alpha_pll_huayra_round_rate,
931 .set_rate = alpha_pll_huayra_set_rate,
932};
933EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops);
934
935const struct clk_ops clk_alpha_pll_hwfsm_ops = {
936 .enable = clk_alpha_pll_hwfsm_enable,
937 .disable = clk_alpha_pll_hwfsm_disable,
938 .is_enabled = clk_alpha_pll_hwfsm_is_enabled,
939 .recalc_rate = clk_alpha_pll_recalc_rate,
940 .round_rate = clk_alpha_pll_round_rate,
941 .set_rate = clk_alpha_pll_hwfsm_set_rate,
942};
943EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
944
945const struct clk_ops clk_alpha_pll_fixed_trion_ops = {
946 .enable = clk_trion_pll_enable,
947 .disable = clk_trion_pll_disable,
948 .is_enabled = clk_trion_pll_is_enabled,
949 .recalc_rate = clk_trion_pll_recalc_rate,
950 .round_rate = clk_alpha_pll_round_rate,
951};
952EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_trion_ops);
953
954static unsigned long
955clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
956{
957 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
958 u32 ctl;
959
960 regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
961
962 ctl >>= PLL_POST_DIV_SHIFT;
963 ctl &= PLL_POST_DIV_MASK(pll);
964
965 return parent_rate >> fls(ctl);
966}
967
968static const struct clk_div_table clk_alpha_div_table[] = {
969 { 0x0, 1 },
970 { 0x1, 2 },
971 { 0x3, 4 },
972 { 0x7, 8 },
973 { 0xf, 16 },
974 { }
975};
976
977static const struct clk_div_table clk_alpha_2bit_div_table[] = {
978 { 0x0, 1 },
979 { 0x1, 2 },
980 { 0x3, 4 },
981 { }
982};
983
984static long
985clk_alpha_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,
986 unsigned long *prate)
987{
988 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
989 const struct clk_div_table *table;
990
991 if (pll->width == 2)
992 table = clk_alpha_2bit_div_table;
993 else
994 table = clk_alpha_div_table;
995
996 return divider_round_rate(hw, rate, prate, table,
997 pll->width, CLK_DIVIDER_POWER_OF_TWO);
998}
999
1000static long
1001clk_alpha_pll_postdiv_round_ro_rate(struct clk_hw *hw, unsigned long rate,
1002 unsigned long *prate)
1003{
1004 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1005 u32 ctl, div;
1006
1007 regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
1008
1009 ctl >>= PLL_POST_DIV_SHIFT;
1010 ctl &= BIT(pll->width) - 1;
1011 div = 1 << fls(ctl);
1012
1013 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)
1014 *prate = clk_hw_round_rate(clk_hw_get_parent(hw), div * rate);
1015
1016 return DIV_ROUND_UP_ULL((u64)*prate, div);
1017}
1018
1019static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
1020 unsigned long parent_rate)
1021{
1022 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1023 int div;
1024
1025
1026 div = DIV_ROUND_UP_ULL(parent_rate, rate) - 1;
1027
1028 return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
1029 PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,
1030 div << PLL_POST_DIV_SHIFT);
1031}
1032
1033const struct clk_ops clk_alpha_pll_postdiv_ops = {
1034 .recalc_rate = clk_alpha_pll_postdiv_recalc_rate,
1035 .round_rate = clk_alpha_pll_postdiv_round_rate,
1036 .set_rate = clk_alpha_pll_postdiv_set_rate,
1037};
1038EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops);
1039
1040const struct clk_ops clk_alpha_pll_postdiv_ro_ops = {
1041 .round_rate = clk_alpha_pll_postdiv_round_ro_rate,
1042 .recalc_rate = clk_alpha_pll_postdiv_recalc_rate,
1043};
1044EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ro_ops);
1045
1046void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
1047 const struct alpha_pll_config *config)
1048{
1049 u32 val, mask;
1050
1051 clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
1052 clk_alpha_pll_write_config(regmap, PLL_FRAC(pll), config->alpha);
1053 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
1054 config->config_ctl_val);
1055 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
1056 config->config_ctl_hi_val);
1057 clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
1058 config->user_ctl_val);
1059 clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),
1060 config->user_ctl_hi_val);
1061 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
1062 config->test_ctl_val);
1063 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
1064 config->test_ctl_hi_val);
1065
1066 if (config->post_div_mask) {
1067 mask = config->post_div_mask;
1068 val = config->post_div_val;
1069 regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);
1070 }
1071
1072 regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS,
1073 PLL_UPDATE_BYPASS);
1074
1075 regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
1076}
1077EXPORT_SYMBOL_GPL(clk_fabia_pll_configure);
1078
1079static int alpha_pll_fabia_enable(struct clk_hw *hw)
1080{
1081 int ret;
1082 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1083 u32 val, opmode_val;
1084 struct regmap *regmap = pll->clkr.regmap;
1085
1086 ret = regmap_read(regmap, PLL_MODE(pll), &val);
1087 if (ret)
1088 return ret;
1089
1090
1091 if (val & PLL_VOTE_FSM_ENA) {
1092 ret = clk_enable_regmap(hw);
1093 if (ret)
1094 return ret;
1095 return wait_for_pll_enable_active(pll);
1096 }
1097
1098 ret = regmap_read(regmap, PLL_OPMODE(pll), &opmode_val);
1099 if (ret)
1100 return ret;
1101
1102
1103 if ((opmode_val & PLL_RUN) && (val & PLL_OUTCTRL))
1104 return 0;
1105
1106 ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
1107 if (ret)
1108 return ret;
1109
1110 ret = regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
1111 if (ret)
1112 return ret;
1113
1114 ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N,
1115 PLL_RESET_N);
1116 if (ret)
1117 return ret;
1118
1119 ret = regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);
1120 if (ret)
1121 return ret;
1122
1123 ret = wait_for_pll_enable_lock(pll);
1124 if (ret)
1125 return ret;
1126
1127 ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),
1128 PLL_OUT_MASK, PLL_OUT_MASK);
1129 if (ret)
1130 return ret;
1131
1132 return regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL,
1133 PLL_OUTCTRL);
1134}
1135
1136static void alpha_pll_fabia_disable(struct clk_hw *hw)
1137{
1138 int ret;
1139 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1140 u32 val;
1141 struct regmap *regmap = pll->clkr.regmap;
1142
1143 ret = regmap_read(regmap, PLL_MODE(pll), &val);
1144 if (ret)
1145 return;
1146
1147
1148 if (val & PLL_FSM_ENA) {
1149 clk_disable_regmap(hw);
1150 return;
1151 }
1152
1153 ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
1154 if (ret)
1155 return;
1156
1157
1158 ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0);
1159 if (ret)
1160 return;
1161
1162
1163 regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
1164}
1165
1166static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw,
1167 unsigned long parent_rate)
1168{
1169 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1170 u32 l, frac, alpha_width = pll_alpha_width(pll);
1171
1172 regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);
1173 regmap_read(pll->clkr.regmap, PLL_FRAC(pll), &frac);
1174
1175 return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width);
1176}
1177
1178
1179
1180
1181
1182static int alpha_pll_check_rate_margin(struct clk_hw *hw,
1183 unsigned long rrate, unsigned long rate)
1184{
1185 unsigned long rate_margin = rate + PLL_RATE_MARGIN;
1186
1187 if (rrate > rate_margin || rrate < rate) {
1188 pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n",
1189 clk_hw_get_name(hw), rrate, rate, rate_margin);
1190 return -EINVAL;
1191 }
1192
1193 return 0;
1194}
1195
1196static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate,
1197 unsigned long prate)
1198{
1199 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1200 u32 l, alpha_width = pll_alpha_width(pll);
1201 unsigned long rrate;
1202 int ret;
1203 u64 a;
1204
1205 rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
1206
1207 ret = alpha_pll_check_rate_margin(hw, rrate, rate);
1208 if (ret < 0)
1209 return ret;
1210
1211 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
1212 regmap_write(pll->clkr.regmap, PLL_FRAC(pll), a);
1213
1214 return __clk_alpha_pll_update_latch(pll);
1215}
1216
1217static int alpha_pll_fabia_prepare(struct clk_hw *hw)
1218{
1219 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1220 const struct pll_vco *vco;
1221 struct clk_hw *parent_hw;
1222 unsigned long cal_freq, rrate;
1223 u32 cal_l, val, alpha_width = pll_alpha_width(pll);
1224 const char *name = clk_hw_get_name(hw);
1225 u64 a;
1226 int ret;
1227
1228
1229 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
1230 if (ret)
1231 return ret;
1232
1233
1234 if (val & PLL_RESET_N)
1235 return 0;
1236
1237 vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));
1238 if (!vco) {
1239 pr_err("%s: alpha pll not in a valid vco range\n", name);
1240 return -EINVAL;
1241 }
1242
1243 cal_freq = DIV_ROUND_CLOSEST((pll->vco_table[0].min_freq +
1244 pll->vco_table[0].max_freq) * 54, 100);
1245
1246 parent_hw = clk_hw_get_parent(hw);
1247 if (!parent_hw)
1248 return -EINVAL;
1249
1250 rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw),
1251 &cal_l, &a, alpha_width);
1252
1253 ret = alpha_pll_check_rate_margin(hw, rrate, cal_freq);
1254 if (ret < 0)
1255 return ret;
1256
1257
1258 regmap_write(pll->clkr.regmap, PLL_CAL_L_VAL(pll), cal_l);
1259
1260
1261 ret = clk_alpha_pll_enable(hw);
1262 if (ret) {
1263 pr_err("%s: alpha pll calibration failed\n", name);
1264 return ret;
1265 }
1266
1267 clk_alpha_pll_disable(hw);
1268
1269 return 0;
1270}
1271
1272const struct clk_ops clk_alpha_pll_fabia_ops = {
1273 .prepare = alpha_pll_fabia_prepare,
1274 .enable = alpha_pll_fabia_enable,
1275 .disable = alpha_pll_fabia_disable,
1276 .is_enabled = clk_alpha_pll_is_enabled,
1277 .set_rate = alpha_pll_fabia_set_rate,
1278 .recalc_rate = alpha_pll_fabia_recalc_rate,
1279 .round_rate = clk_alpha_pll_round_rate,
1280};
1281EXPORT_SYMBOL_GPL(clk_alpha_pll_fabia_ops);
1282
1283const struct clk_ops clk_alpha_pll_fixed_fabia_ops = {
1284 .enable = alpha_pll_fabia_enable,
1285 .disable = alpha_pll_fabia_disable,
1286 .is_enabled = clk_alpha_pll_is_enabled,
1287 .recalc_rate = alpha_pll_fabia_recalc_rate,
1288 .round_rate = clk_alpha_pll_round_rate,
1289};
1290EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_fabia_ops);
1291
1292static unsigned long clk_alpha_pll_postdiv_fabia_recalc_rate(struct clk_hw *hw,
1293 unsigned long parent_rate)
1294{
1295 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1296 u32 i, div = 1, val;
1297 int ret;
1298
1299 ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
1300 if (ret)
1301 return ret;
1302
1303 val >>= pll->post_div_shift;
1304 val &= BIT(pll->width) - 1;
1305
1306 for (i = 0; i < pll->num_post_div; i++) {
1307 if (pll->post_div_table[i].val == val) {
1308 div = pll->post_div_table[i].div;
1309 break;
1310 }
1311 }
1312
1313 return (parent_rate / div);
1314}
1315
1316static unsigned long
1317clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
1318{
1319 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1320 struct regmap *regmap = pll->clkr.regmap;
1321 u32 i, div = 1, val;
1322
1323 regmap_read(regmap, PLL_USER_CTL(pll), &val);
1324
1325 val >>= pll->post_div_shift;
1326 val &= PLL_POST_DIV_MASK(pll);
1327
1328 for (i = 0; i < pll->num_post_div; i++) {
1329 if (pll->post_div_table[i].val == val) {
1330 div = pll->post_div_table[i].div;
1331 break;
1332 }
1333 }
1334
1335 return (parent_rate / div);
1336}
1337
1338static long
1339clk_trion_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,
1340 unsigned long *prate)
1341{
1342 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1343
1344 return divider_round_rate(hw, rate, prate, pll->post_div_table,
1345 pll->width, CLK_DIVIDER_ROUND_CLOSEST);
1346};
1347
1348static int
1349clk_trion_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
1350 unsigned long parent_rate)
1351{
1352 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1353 struct regmap *regmap = pll->clkr.regmap;
1354 int i, val = 0, div;
1355
1356 div = DIV_ROUND_UP_ULL(parent_rate, rate);
1357 for (i = 0; i < pll->num_post_div; i++) {
1358 if (pll->post_div_table[i].div == div) {
1359 val = pll->post_div_table[i].val;
1360 break;
1361 }
1362 }
1363
1364 return regmap_update_bits(regmap, PLL_USER_CTL(pll),
1365 PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,
1366 val << PLL_POST_DIV_SHIFT);
1367}
1368
1369const struct clk_ops clk_alpha_pll_postdiv_trion_ops = {
1370 .recalc_rate = clk_trion_pll_postdiv_recalc_rate,
1371 .round_rate = clk_trion_pll_postdiv_round_rate,
1372 .set_rate = clk_trion_pll_postdiv_set_rate,
1373};
1374EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_trion_ops);
1375
1376static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw,
1377 unsigned long rate, unsigned long *prate)
1378{
1379 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1380
1381 return divider_round_rate(hw, rate, prate, pll->post_div_table,
1382 pll->width, CLK_DIVIDER_ROUND_CLOSEST);
1383}
1384
1385static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw,
1386 unsigned long rate, unsigned long parent_rate)
1387{
1388 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1389 int i, val = 0, div, ret;
1390
1391
1392
1393
1394
1395 ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
1396 if (ret)
1397 return ret;
1398
1399 if (val & PLL_VOTE_FSM_ENA)
1400 return 0;
1401
1402 div = DIV_ROUND_UP_ULL(parent_rate, rate);
1403 for (i = 0; i < pll->num_post_div; i++) {
1404 if (pll->post_div_table[i].div == div) {
1405 val = pll->post_div_table[i].val;
1406 break;
1407 }
1408 }
1409
1410 return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
1411 (BIT(pll->width) - 1) << pll->post_div_shift,
1412 val << pll->post_div_shift);
1413}
1414
1415const struct clk_ops clk_alpha_pll_postdiv_fabia_ops = {
1416 .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
1417 .round_rate = clk_alpha_pll_postdiv_fabia_round_rate,
1418 .set_rate = clk_alpha_pll_postdiv_fabia_set_rate,
1419};
1420EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops);
1421
1422
1423
1424
1425
1426
1427
1428
1429void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
1430 const struct alpha_pll_config *config)
1431{
1432 clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
1433 regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
1434 clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
1435 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
1436 config->config_ctl_val);
1437 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
1438 config->config_ctl_hi_val);
1439 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll),
1440 config->config_ctl_hi1_val);
1441 clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
1442 config->user_ctl_val);
1443 clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),
1444 config->user_ctl_hi_val);
1445 clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll),
1446 config->user_ctl_hi1_val);
1447 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
1448 config->test_ctl_val);
1449 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
1450 config->test_ctl_hi_val);
1451 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll),
1452 config->test_ctl_hi1_val);
1453
1454 regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS,
1455 PLL_UPDATE_BYPASS);
1456
1457
1458 regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
1459
1460
1461 regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
1462
1463
1464 regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
1465}
1466EXPORT_SYMBOL_GPL(clk_trion_pll_configure);
1467
1468
1469
1470
1471
1472static int __alpha_pll_trion_prepare(struct clk_hw *hw, u32 pcal_done)
1473{
1474 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1475 u32 val;
1476 int ret;
1477
1478
1479 regmap_read(pll->clkr.regmap, PLL_STATUS(pll), &val);
1480 if (val & pcal_done)
1481 return 0;
1482
1483
1484 ret = clk_trion_pll_enable(hw);
1485 if (!ret)
1486 clk_trion_pll_disable(hw);
1487
1488 return ret;
1489}
1490
1491static int alpha_pll_trion_prepare(struct clk_hw *hw)
1492{
1493 return __alpha_pll_trion_prepare(hw, TRION_PCAL_DONE);
1494}
1495
1496static int alpha_pll_lucid_prepare(struct clk_hw *hw)
1497{
1498 return __alpha_pll_trion_prepare(hw, LUCID_PCAL_DONE);
1499}
1500
1501static int __alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
1502 unsigned long prate, u32 latch_bit, u32 latch_ack)
1503{
1504 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1505 unsigned long rrate;
1506 u32 val, l, alpha_width = pll_alpha_width(pll);
1507 u64 a;
1508 int ret;
1509
1510 rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
1511
1512 ret = alpha_pll_check_rate_margin(hw, rrate, rate);
1513 if (ret < 0)
1514 return ret;
1515
1516 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
1517 regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
1518
1519
1520 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), latch_bit, latch_bit);
1521 if (ret)
1522 return ret;
1523
1524
1525 udelay(1);
1526 regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
1527 if (!(val & latch_ack)) {
1528 pr_err("Lucid PLL latch failed. Output may be unstable!\n");
1529 return -EINVAL;
1530 }
1531
1532
1533 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), latch_bit, 0);
1534 if (ret)
1535 return ret;
1536
1537 if (clk_hw_is_enabled(hw)) {
1538 ret = wait_for_pll_enable_lock(pll);
1539 if (ret)
1540 return ret;
1541 }
1542
1543
1544 udelay(100);
1545 return 0;
1546}
1547
1548static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
1549 unsigned long prate)
1550{
1551 return __alpha_pll_trion_set_rate(hw, rate, prate, PLL_UPDATE, ALPHA_PLL_ACK_LATCH);
1552}
1553
1554const struct clk_ops clk_alpha_pll_trion_ops = {
1555 .prepare = alpha_pll_trion_prepare,
1556 .enable = clk_trion_pll_enable,
1557 .disable = clk_trion_pll_disable,
1558 .is_enabled = clk_trion_pll_is_enabled,
1559 .recalc_rate = clk_trion_pll_recalc_rate,
1560 .round_rate = clk_alpha_pll_round_rate,
1561 .set_rate = alpha_pll_trion_set_rate,
1562};
1563EXPORT_SYMBOL_GPL(clk_alpha_pll_trion_ops);
1564
1565const struct clk_ops clk_alpha_pll_lucid_ops = {
1566 .prepare = alpha_pll_lucid_prepare,
1567 .enable = clk_trion_pll_enable,
1568 .disable = clk_trion_pll_disable,
1569 .is_enabled = clk_trion_pll_is_enabled,
1570 .recalc_rate = clk_trion_pll_recalc_rate,
1571 .round_rate = clk_alpha_pll_round_rate,
1572 .set_rate = alpha_pll_trion_set_rate,
1573};
1574EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops);
1575
1576const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = {
1577 .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
1578 .round_rate = clk_alpha_pll_postdiv_fabia_round_rate,
1579 .set_rate = clk_alpha_pll_postdiv_fabia_set_rate,
1580};
1581EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops);
1582
1583void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
1584 const struct alpha_pll_config *config)
1585{
1586 clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
1587 clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
1588 clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
1589 config->user_ctl_val);
1590 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
1591 config->config_ctl_val);
1592 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
1593 config->config_ctl_hi_val);
1594 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
1595 config->test_ctl_val);
1596 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
1597 config->test_ctl_hi_val);
1598}
1599EXPORT_SYMBOL_GPL(clk_agera_pll_configure);
1600
1601static int clk_alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate,
1602 unsigned long prate)
1603{
1604 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1605 u32 l, alpha_width = pll_alpha_width(pll);
1606 int ret;
1607 unsigned long rrate;
1608 u64 a;
1609
1610 rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
1611 ret = alpha_pll_check_rate_margin(hw, rrate, rate);
1612 if (ret < 0)
1613 return ret;
1614
1615
1616 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
1617 regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
1618
1619 if (clk_hw_is_enabled(hw))
1620 return wait_for_pll_enable_lock(pll);
1621
1622 return 0;
1623}
1624
1625const struct clk_ops clk_alpha_pll_agera_ops = {
1626 .enable = clk_alpha_pll_enable,
1627 .disable = clk_alpha_pll_disable,
1628 .is_enabled = clk_alpha_pll_is_enabled,
1629 .recalc_rate = alpha_pll_fabia_recalc_rate,
1630 .round_rate = clk_alpha_pll_round_rate,
1631 .set_rate = clk_alpha_pll_agera_set_rate,
1632};
1633EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops);
1634
1635static int alpha_pll_lucid_5lpe_enable(struct clk_hw *hw)
1636{
1637 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1638 u32 val;
1639 int ret;
1640
1641 ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
1642 if (ret)
1643 return ret;
1644
1645
1646 if (val & LUCID_5LPE_ENABLE_VOTE_RUN) {
1647 ret = clk_enable_regmap(hw);
1648 if (ret)
1649 return ret;
1650 return wait_for_pll_enable_lock(pll);
1651 }
1652
1653
1654 ret = trion_pll_is_enabled(pll, pll->clkr.regmap);
1655 if (ret < 0)
1656 return ret;
1657
1658 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
1659 if (ret)
1660 return ret;
1661
1662 regmap_write(pll->clkr.regmap, PLL_OPMODE(pll), PLL_RUN);
1663
1664 ret = wait_for_pll_enable_lock(pll);
1665 if (ret)
1666 return ret;
1667
1668
1669 ret = regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, PLL_OUT_MASK);
1670 if (ret)
1671 return ret;
1672
1673
1674 return regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
1675}
1676
1677static void alpha_pll_lucid_5lpe_disable(struct clk_hw *hw)
1678{
1679 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1680 u32 val;
1681 int ret;
1682
1683 ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
1684 if (ret)
1685 return;
1686
1687
1688 if (val & LUCID_5LPE_ENABLE_VOTE_RUN) {
1689 clk_disable_regmap(hw);
1690 return;
1691 }
1692
1693
1694 ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
1695 if (ret)
1696 return;
1697
1698
1699 ret = regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0);
1700 if (ret)
1701 return;
1702
1703
1704 regmap_write(pll->clkr.regmap, PLL_OPMODE(pll), PLL_STANDBY);
1705}
1706
1707
1708
1709
1710
1711static int alpha_pll_lucid_5lpe_prepare(struct clk_hw *hw)
1712{
1713 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1714 struct clk_hw *p;
1715 u32 val = 0;
1716 int ret;
1717
1718
1719 regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
1720 if (val & LUCID_5LPE_PCAL_DONE)
1721 return 0;
1722
1723 p = clk_hw_get_parent(hw);
1724 if (!p)
1725 return -EINVAL;
1726
1727 ret = alpha_pll_lucid_5lpe_enable(hw);
1728 if (ret)
1729 return ret;
1730
1731 alpha_pll_lucid_5lpe_disable(hw);
1732
1733 return 0;
1734}
1735
1736static int alpha_pll_lucid_5lpe_set_rate(struct clk_hw *hw, unsigned long rate,
1737 unsigned long prate)
1738{
1739 return __alpha_pll_trion_set_rate(hw, rate, prate,
1740 LUCID_5LPE_PLL_LATCH_INPUT,
1741 LUCID_5LPE_ALPHA_PLL_ACK_LATCH);
1742}
1743
1744static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
1745 unsigned long parent_rate)
1746{
1747 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1748 int i, val = 0, div, ret;
1749 u32 mask;
1750
1751
1752
1753
1754
1755 ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
1756 if (ret)
1757 return ret;
1758
1759 if (val & LUCID_5LPE_ENABLE_VOTE_RUN)
1760 return 0;
1761
1762 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
1763 for (i = 0; i < pll->num_post_div; i++) {
1764 if (pll->post_div_table[i].div == div) {
1765 val = pll->post_div_table[i].val;
1766 break;
1767 }
1768 }
1769
1770 mask = GENMASK(pll->width + pll->post_div_shift - 1, pll->post_div_shift);
1771 return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
1772 mask, val << pll->post_div_shift);
1773}
1774
1775const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = {
1776 .prepare = alpha_pll_lucid_5lpe_prepare,
1777 .enable = alpha_pll_lucid_5lpe_enable,
1778 .disable = alpha_pll_lucid_5lpe_disable,
1779 .is_enabled = clk_trion_pll_is_enabled,
1780 .recalc_rate = clk_trion_pll_recalc_rate,
1781 .round_rate = clk_alpha_pll_round_rate,
1782 .set_rate = alpha_pll_lucid_5lpe_set_rate,
1783};
1784EXPORT_SYMBOL(clk_alpha_pll_lucid_5lpe_ops);
1785
1786const struct clk_ops clk_alpha_pll_fixed_lucid_5lpe_ops = {
1787 .enable = alpha_pll_lucid_5lpe_enable,
1788 .disable = alpha_pll_lucid_5lpe_disable,
1789 .is_enabled = clk_trion_pll_is_enabled,
1790 .recalc_rate = clk_trion_pll_recalc_rate,
1791 .round_rate = clk_alpha_pll_round_rate,
1792};
1793EXPORT_SYMBOL(clk_alpha_pll_fixed_lucid_5lpe_ops);
1794
1795const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops = {
1796 .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
1797 .round_rate = clk_alpha_pll_postdiv_fabia_round_rate,
1798 .set_rate = clk_lucid_5lpe_pll_postdiv_set_rate,
1799};
1800EXPORT_SYMBOL(clk_alpha_pll_postdiv_lucid_5lpe_ops);
1801
1802void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
1803 const struct alpha_pll_config *config)
1804{
1805 clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
1806 clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
1807 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
1808 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
1809 clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
1810 clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
1811 clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val);
1812 clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll), config->user_ctl_hi1_val);
1813 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
1814 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
1815 clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
1816
1817 regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, 0);
1818
1819
1820 regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
1821
1822
1823 regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
1824
1825
1826 regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
1827}
1828EXPORT_SYMBOL_GPL(clk_zonda_pll_configure);
1829
1830static int clk_zonda_pll_enable(struct clk_hw *hw)
1831{
1832 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1833 struct regmap *regmap = pll->clkr.regmap;
1834 u32 val;
1835 int ret;
1836
1837 regmap_read(regmap, PLL_MODE(pll), &val);
1838
1839
1840 if (val & PLL_VOTE_FSM_ENA) {
1841 ret = clk_enable_regmap(hw);
1842 if (ret)
1843 return ret;
1844 return wait_for_pll_enable_active(pll);
1845 }
1846
1847
1848 regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);
1849
1850
1851
1852
1853
1854 udelay(1);
1855
1856 regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
1857
1858
1859 regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);
1860
1861 regmap_read(regmap, PLL_TEST_CTL(pll), &val);
1862
1863
1864 if (val & ZONDA_STAY_IN_CFA)
1865 ret = wait_for_zonda_pll_freq_lock(pll);
1866 else
1867 ret = wait_for_pll_enable_lock(pll);
1868 if (ret)
1869 return ret;
1870
1871
1872 regmap_update_bits(regmap, PLL_USER_CTL(pll), ZONDA_PLL_OUT_MASK, ZONDA_PLL_OUT_MASK);
1873
1874
1875 regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
1876
1877 return 0;
1878}
1879
1880static void clk_zonda_pll_disable(struct clk_hw *hw)
1881{
1882 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1883 struct regmap *regmap = pll->clkr.regmap;
1884 u32 val;
1885
1886 regmap_read(regmap, PLL_MODE(pll), &val);
1887
1888
1889 if (val & PLL_VOTE_FSM_ENA) {
1890 clk_disable_regmap(hw);
1891 return;
1892 }
1893
1894
1895 regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
1896
1897
1898 regmap_update_bits(regmap, PLL_USER_CTL(pll), ZONDA_PLL_OUT_MASK, 0);
1899
1900
1901 regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N | PLL_BYPASSNL, 0);
1902
1903
1904 regmap_write(regmap, PLL_OPMODE(pll), 0x0);
1905}
1906
1907static int clk_zonda_pll_set_rate(struct clk_hw *hw, unsigned long rate,
1908 unsigned long prate)
1909{
1910 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1911 unsigned long rrate;
1912 u32 test_ctl_val;
1913 u32 l, alpha_width = pll_alpha_width(pll);
1914 u64 a;
1915 int ret;
1916
1917 rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
1918
1919 ret = alpha_pll_check_rate_margin(hw, rrate, rate);
1920 if (ret < 0)
1921 return ret;
1922
1923 regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
1924 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
1925
1926
1927 udelay(5);
1928
1929
1930 regmap_read(pll->clkr.regmap, PLL_TEST_CTL(pll), &test_ctl_val);
1931
1932
1933 if (test_ctl_val & ZONDA_STAY_IN_CFA)
1934 ret = wait_for_zonda_pll_freq_lock(pll);
1935 else
1936 ret = wait_for_pll_enable_lock(pll);
1937 if (ret)
1938 return ret;
1939
1940
1941 udelay(100);
1942 return 0;
1943}
1944
1945const struct clk_ops clk_alpha_pll_zonda_ops = {
1946 .enable = clk_zonda_pll_enable,
1947 .disable = clk_zonda_pll_disable,
1948 .is_enabled = clk_trion_pll_is_enabled,
1949 .recalc_rate = clk_trion_pll_recalc_rate,
1950 .round_rate = clk_alpha_pll_round_rate,
1951 .set_rate = clk_zonda_pll_set_rate,
1952};
1953EXPORT_SYMBOL(clk_alpha_pll_zonda_ops);
1954