blob: 514c0ad356c73a1f0e11416130421e14b8332deb [file] [log] [blame]
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -08001/*
Deepak Katragadda043f8542017-02-22 11:21:31 -08002 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -08003 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Deepak Katragadda9abd7942017-06-13 14:20:09 -070014#define pr_fmt(fmt) "clk: %s: " fmt, __func__
15
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -080016#include <linux/kernel.h>
17#include <linux/export.h>
18#include <linux/clk-provider.h>
19#include <linux/regmap.h>
20#include <linux/delay.h>
21
22#include "clk-alpha-pll.h"
23
24#define PLL_MODE 0x00
Amit Nischal82b6461b2017-06-19 15:47:36 +053025#define PLL_STANDBY 0x0
26#define PLL_RUN 0x1
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -080027# define PLL_OUTCTRL BIT(0)
28# define PLL_BYPASSNL BIT(1)
29# define PLL_RESET_N BIT(2)
30# define PLL_LOCK_COUNT_SHIFT 8
31# define PLL_LOCK_COUNT_MASK 0x3f
32# define PLL_BIAS_COUNT_SHIFT 14
33# define PLL_BIAS_COUNT_MASK 0x3f
34# define PLL_VOTE_FSM_ENA BIT(20)
35# define PLL_VOTE_FSM_RESET BIT(21)
36# define PLL_ACTIVE_FLAG BIT(30)
37# define PLL_LOCK_DET BIT(31)
38
39#define PLL_L_VAL 0x04
40#define PLL_ALPHA_VAL 0x08
41#define PLL_ALPHA_VAL_U 0x0c
42
43#define PLL_USER_CTL 0x10
44# define PLL_POST_DIV_SHIFT 8
45# define PLL_POST_DIV_MASK 0xf
46# define PLL_ALPHA_EN BIT(24)
47# define PLL_VCO_SHIFT 20
48# define PLL_VCO_MASK 0x3
49
50#define PLL_USER_CTL_U 0x14
51
52#define PLL_CONFIG_CTL 0x18
53#define PLL_TEST_CTL 0x1c
54#define PLL_TEST_CTL_U 0x20
55#define PLL_STATUS 0x24
Amit Nischal82b6461b2017-06-19 15:47:36 +053056#define PLL_UPDATE BIT(22)
57#define PLL_ACK_LATCH BIT(29)
58#define PLL_CALIBRATION_MASK (0x7<<3)
59#define PLL_CALIBRATION_CONTROL 2
60#define PLL_HW_UPDATE_LOGIC_BYPASS BIT(23)
61#define ALPHA_16_BIT_PLL_RATE_MARGIN 500
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -080062
63/*
64 * Even though 40 bits are present, use only 32 for ease of calculation.
65 */
66#define ALPHA_REG_BITWIDTH 40
67#define ALPHA_BITWIDTH 32
Amit Nischal82b6461b2017-06-19 15:47:36 +053068#define SUPPORTS_16BIT_ALPHA 16
Deepak Katragadda2b803212016-06-29 16:35:22 -070069
70#define FABIA_USER_CTL_LO 0xc
71#define FABIA_USER_CTL_HI 0x10
Deepak Katragadda2b803212016-06-29 16:35:22 -070072#define FABIA_FRAC_VAL 0x38
73#define FABIA_OPMODE 0x2c
Deepak Katragadda2b803212016-06-29 16:35:22 -070074#define FABIA_PLL_OUT_MASK 0x7
Deepak Katragadda2b803212016-06-29 16:35:22 -070075#define FABIA_PLL_ACK_LATCH BIT(29)
76#define FABIA_PLL_UPDATE BIT(22)
Amit Nischal82b6461b2017-06-19 15:47:36 +053077
78#define TRION_PLL_CAL_VAL 0x44
79#define TRION_PLL_CAL_L_VAL 0x8
80#define TRION_PLL_USER_CTL 0xc
81#define TRION_PLL_USER_CTL_U 0x10
82#define TRION_PLL_USER_CTL_U1 0x14
83#define TRION_PLL_CONFIG_CTL_U 0x1c
84#define TRION_PLL_CONFIG_CTL_U1 0x20
85#define TRION_PLL_OPMODE 0x38
86#define TRION_PLL_ALPHA_VAL 0x40
87
88#define TRION_PLL_OUT_MASK 0x7
89#define TRION_PLL_ENABLE_STATE_READ BIT(4)
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -080090
91#define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \
92 struct clk_alpha_pll, clkr)
93
94#define to_clk_alpha_pll_postdiv(_hw) container_of(to_clk_regmap(_hw), \
95 struct clk_alpha_pll_postdiv, clkr)
96
Rajendra Nayake512fb22016-04-18 11:40:43 +053097static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
98 const char *action)
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -080099{
Rajendra Nayake512fb22016-04-18 11:40:43 +0530100 u32 val, off;
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800101 int count;
102 int ret;
103 const char *name = clk_hw_get_name(&pll->clkr.hw);
104
105 off = pll->offset;
106 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
107 if (ret)
108 return ret;
109
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800110 for (count = 100; count > 0; count--) {
111 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
112 if (ret)
113 return ret;
Rajendra Nayake512fb22016-04-18 11:40:43 +0530114 if (inverse && (val & mask))
115 return 0;
116 else if ((val & mask) == mask)
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800117 return 0;
118
119 udelay(1);
120 }
121
Deepak Katragadda9abd7942017-06-13 14:20:09 -0700122 WARN(1, "clk: %s failed to %s!\n", name, action);
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800123 return -ETIMEDOUT;
124}
125
Rajendra Nayake512fb22016-04-18 11:40:43 +0530126static int wait_for_pll_enable(struct clk_alpha_pll *pll, u32 mask)
127{
128 return wait_for_pll(pll, mask, 0, "enable");
129}
130
131static int wait_for_pll_disable(struct clk_alpha_pll *pll, u32 mask)
132{
133 return wait_for_pll(pll, mask, 1, "disable");
134}
135
136static int wait_for_pll_offline(struct clk_alpha_pll *pll, u32 mask)
137{
138 return wait_for_pll(pll, mask, 0, "offline");
139}
140
Amit Nischal82b6461b2017-06-19 15:47:36 +0530141static int wait_for_pll_latch_ack(struct clk_alpha_pll *pll, u32 mask)
142{
143 return wait_for_pll(pll, mask, 0, "latch_ack");
144}
Rajendra Nayake512fb22016-04-18 11:40:43 +0530145
146/* alpha pll with hwfsm support */
147
148#define PLL_OFFLINE_REQ BIT(7)
149#define PLL_FSM_ENA BIT(20)
150#define PLL_OFFLINE_ACK BIT(28)
151#define PLL_ACTIVE_FLAG BIT(30)
152
153void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
154 const struct pll_config *config)
155{
156 u32 val, mask;
157
158 regmap_write(regmap, pll->offset + PLL_CONFIG_CTL,
159 config->config_ctl_val);
160
161 val = config->main_output_mask;
162 val |= config->aux_output_mask;
163 val |= config->aux2_output_mask;
164 val |= config->early_output_mask;
165 val |= config->post_div_val;
166
167 mask = config->main_output_mask;
168 mask |= config->aux_output_mask;
169 mask |= config->aux2_output_mask;
170 mask |= config->early_output_mask;
171 mask |= config->post_div_mask;
172
173 regmap_update_bits(regmap, pll->offset + PLL_USER_CTL, mask, val);
174}
175
176static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
177{
178 int ret;
179 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
180 u32 val, off;
181
182 off = pll->offset;
183 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
184 if (ret)
185 return ret;
186 /* Enable HW FSM mode, clear OFFLINE request */
187 val |= PLL_FSM_ENA;
188 val &= ~PLL_OFFLINE_REQ;
189 ret = regmap_write(pll->clkr.regmap, off + PLL_MODE, val);
190 if (ret)
191 return ret;
192
193 /* Make sure enable request goes through before waiting for update */
194 mb();
195
196 ret = wait_for_pll_enable(pll, PLL_ACTIVE_FLAG);
197 if (ret)
198 return ret;
199
200 return 0;
201}
202
203static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
204{
205 int ret;
206 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
207 u32 val, off;
208
209 off = pll->offset;
210 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
211 if (ret)
212 return;
213 /* Request PLL_OFFLINE and wait for ack */
214 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
215 PLL_OFFLINE_REQ, PLL_OFFLINE_REQ);
216 if (ret)
217 return;
218 ret = wait_for_pll_offline(pll, PLL_OFFLINE_ACK);
219 if (ret)
220 return;
221
222 /* Disable hwfsm */
223 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
224 PLL_FSM_ENA, 0);
225 if (ret)
226 return;
227 wait_for_pll_disable(pll, PLL_ACTIVE_FLAG);
228}
229
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800230static int clk_alpha_pll_enable(struct clk_hw *hw)
231{
232 int ret;
233 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
234 u32 val, mask, off;
235
236 off = pll->offset;
237
238 mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
239 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
240 if (ret)
241 return ret;
242
243 /* If in FSM mode, just vote for it */
244 if (val & PLL_VOTE_FSM_ENA) {
245 ret = clk_enable_regmap(hw);
246 if (ret)
247 return ret;
Rajendra Nayake512fb22016-04-18 11:40:43 +0530248 return wait_for_pll_enable(pll, PLL_ACTIVE_FLAG);
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800249 }
250
251 /* Skip if already enabled */
252 if ((val & mask) == mask)
253 return 0;
254
255 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
256 PLL_BYPASSNL, PLL_BYPASSNL);
257 if (ret)
258 return ret;
259
260 /*
261 * H/W requires a 5us delay between disabling the bypass and
262 * de-asserting the reset.
263 */
264 mb();
265 udelay(5);
266
267 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
268 PLL_RESET_N, PLL_RESET_N);
269 if (ret)
270 return ret;
271
Rajendra Nayake512fb22016-04-18 11:40:43 +0530272 ret = wait_for_pll_enable(pll, PLL_LOCK_DET);
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800273 if (ret)
274 return ret;
275
276 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
277 PLL_OUTCTRL, PLL_OUTCTRL);
278
279 /* Ensure that the write above goes through before returning. */
280 mb();
281 return ret;
282}
283
284static void clk_alpha_pll_disable(struct clk_hw *hw)
285{
286 int ret;
287 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
288 u32 val, mask, off;
289
290 off = pll->offset;
291
292 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
293 if (ret)
294 return;
295
296 /* If in FSM mode, just unvote it */
297 if (val & PLL_VOTE_FSM_ENA) {
298 clk_disable_regmap(hw);
299 return;
300 }
301
302 mask = PLL_OUTCTRL;
303 regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, mask, 0);
304
305 /* Delay of 2 output clock ticks required until output is disabled */
306 mb();
307 udelay(1);
308
309 mask = PLL_RESET_N | PLL_BYPASSNL;
310 regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, mask, 0);
311}
312
Deepak Katragadda2b803212016-06-29 16:35:22 -0700313static unsigned long alpha_pll_calc_rate(const struct clk_alpha_pll *pll,
314 u64 prate, u32 l, u32 a)
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800315{
Deepak Katragadda2b803212016-06-29 16:35:22 -0700316 int alpha_bw = ALPHA_BITWIDTH;
317
Amit Nischal82b6461b2017-06-19 15:47:36 +0530318 if (pll->type == FABIA_PLL || pll->type == TRION_PLL)
319 alpha_bw = SUPPORTS_16BIT_ALPHA;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700320
321 return (prate * l) + ((prate * a) >> alpha_bw);
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800322}
323
324static unsigned long
Deepak Katragadda2b803212016-06-29 16:35:22 -0700325alpha_pll_round_rate(const struct clk_alpha_pll *pll, unsigned long rate,
326 unsigned long prate, u32 *l, u64 *a)
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800327{
328 u64 remainder;
329 u64 quotient;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700330 int alpha_bw = ALPHA_BITWIDTH;
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800331
Deepak Katragaddab0823d02017-04-21 15:17:19 -0700332 /*
333 * The PLLs parent rate is zero probably since the parent hasn't
334 * registered yet. Return early with the requested rate.
335 */
336 if (!prate) {
337 pr_debug("PLLs parent rate hasn't been initialized.\n");
338 return rate;
339 }
340
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800341 quotient = rate;
342 remainder = do_div(quotient, prate);
343 *l = quotient;
344
345 if (!remainder) {
346 *a = 0;
347 return rate;
348 }
349
Amit Nischal82b6461b2017-06-19 15:47:36 +0530350 /* Some PLLs only have 16 bits to program the fractional divider */
351 if (pll->type == FABIA_PLL || pll->type == TRION_PLL)
352 alpha_bw = SUPPORTS_16BIT_ALPHA;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700353
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800354 /* Upper ALPHA_BITWIDTH bits of Alpha */
Deepak Katragadda2b803212016-06-29 16:35:22 -0700355 quotient = remainder << alpha_bw;
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800356 remainder = do_div(quotient, prate);
357
358 if (remainder)
359 quotient++;
360
361 *a = quotient;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700362 return alpha_pll_calc_rate(pll, prate, *l, *a);
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800363}
364
365static const struct pll_vco *
366alpha_pll_find_vco(const struct clk_alpha_pll *pll, unsigned long rate)
367{
368 const struct pll_vco *v = pll->vco_table;
369 const struct pll_vco *end = v + pll->num_vco;
370
371 for (; v < end; v++)
372 if (rate >= v->min_freq && rate <= v->max_freq)
373 return v;
374
375 return NULL;
376}
377
378static unsigned long
379clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
380{
381 u32 l, low, high, ctl;
382 u64 a = 0, prate = parent_rate;
383 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
384 u32 off = pll->offset;
385
386 regmap_read(pll->clkr.regmap, off + PLL_L_VAL, &l);
387
388 regmap_read(pll->clkr.regmap, off + PLL_USER_CTL, &ctl);
389 if (ctl & PLL_ALPHA_EN) {
390 regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL, &low);
391 regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, &high);
392 a = (u64)high << 32 | low;
393 a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
394 }
395
Deepak Katragadda2b803212016-06-29 16:35:22 -0700396 return alpha_pll_calc_rate(pll, prate, l, a);
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800397}
398
399static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
400 unsigned long prate)
401{
402 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
403 const struct pll_vco *vco;
Bruce Levy9f40ff52017-12-07 17:54:58 -0800404 u32 l = 0, off = pll->offset;
405 u64 a = 0;
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800406
Deepak Katragadda2b803212016-06-29 16:35:22 -0700407 rate = alpha_pll_round_rate(pll, rate, prate, &l, &a);
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800408 vco = alpha_pll_find_vco(pll, rate);
409 if (!vco) {
410 pr_err("alpha pll not in a valid vco range\n");
411 return -EINVAL;
412 }
413
414 a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
415
416 regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
417 regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL, a);
418 regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, a >> 32);
419
420 regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
421 PLL_VCO_MASK << PLL_VCO_SHIFT,
422 vco->val << PLL_VCO_SHIFT);
423
424 regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, PLL_ALPHA_EN,
425 PLL_ALPHA_EN);
426
427 return 0;
428}
429
430static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
431 unsigned long *prate)
432{
433 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
434 u32 l;
435 u64 a;
436 unsigned long min_freq, max_freq;
437
Deepak Katragadda2b803212016-06-29 16:35:22 -0700438 rate = alpha_pll_round_rate(pll, rate, *prate, &l, &a);
Amit Nischal82b6461b2017-06-19 15:47:36 +0530439 if (pll->type == FABIA_PLL || pll->type == TRION_PLL ||
440 alpha_pll_find_vco(pll, rate))
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800441 return rate;
442
443 min_freq = pll->vco_table[0].min_freq;
444 max_freq = pll->vco_table[pll->num_vco - 1].max_freq;
445
446 return clamp(rate, min_freq, max_freq);
447}
448
Taniya Das4b006ad2016-11-07 10:01:38 +0530449static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
450{
451 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
452 int size, i, val;
453
454 static struct clk_register_data data[] = {
455 {"PLL_MODE", 0x0},
456 {"PLL_L_VAL", 0x4},
457 {"PLL_ALPHA_VAL", 0x8},
458 {"PLL_ALPHA_VAL_U", 0xC},
459 {"PLL_USER_CTL", 0x10},
460 {"PLL_CONFIG_CTL", 0x18},
461 };
462
463 static struct clk_register_data data1[] = {
464 {"APSS_PLL_VOTE", 0x0},
465 };
466
467 size = ARRAY_SIZE(data);
468
469 for (i = 0; i < size; i++) {
470 regmap_read(pll->clkr.regmap, pll->offset + data[i].offset,
471 &val);
472 seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
473 }
474
475 regmap_read(pll->clkr.regmap, pll->offset + data[0].offset, &val);
476
477 if (val & PLL_FSM_ENA) {
478 regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
479 data1[0].offset, &val);
480 seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
481 }
482}
483
Deepak Katragaddadcd7ed82017-09-12 16:50:56 -0700484static int clk_fabia_pll_latch_input(struct clk_alpha_pll *pll,
485 struct regmap *regmap)
486{
487 u32 regval;
488 int ret = 0;
489
490 /* Latch the PLL input */
491 ret = regmap_update_bits(regmap, pll->offset + PLL_MODE,
492 FABIA_PLL_UPDATE, FABIA_PLL_UPDATE);
493 if (ret)
494 return ret;
495
496 /* Wait for 2 reference cycles before checking the ACK bit. */
497 udelay(1);
498 regmap_read(regmap, pll->offset + PLL_MODE, &regval);
499 if (!(regval & FABIA_PLL_ACK_LATCH)) {
500 WARN(1, "clk: PLL latch failed. Output may be unstable!\n");
501 return -EINVAL;
502 }
503
504 /* Return the latch input to 0 */
505 ret = regmap_update_bits(regmap, pll->offset + PLL_MODE,
506 FABIA_PLL_UPDATE, 0);
507 if (ret)
508 return ret;
509
510 /* Wait for PLL output to stabilize */
511 udelay(100);
512 return ret;
513}
514
Deepak Katragadda2b803212016-06-29 16:35:22 -0700515void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
516 const struct pll_config *config)
517{
518 u32 val, mask;
519
Deepak Katragadda491a92a2017-05-23 10:02:26 -0700520 if (config->l)
Deepak Katragadda2b803212016-06-29 16:35:22 -0700521 regmap_write(regmap, pll->offset + PLL_L_VAL,
522 config->l);
Deepak Katragadda2b803212016-06-29 16:35:22 -0700523
524 if (config->frac)
525 regmap_write(regmap, pll->offset + FABIA_FRAC_VAL,
526 config->frac);
Deepak Katragaddadcd7ed82017-09-12 16:50:56 -0700527
Deepak Katragadda2b803212016-06-29 16:35:22 -0700528 if (config->config_ctl_val)
529 regmap_write(regmap, pll->offset + PLL_CONFIG_CTL,
530 config->config_ctl_val);
531
532 if (config->post_div_mask) {
533 mask = config->post_div_mask;
534 val = config->post_div_val;
535 regmap_update_bits(regmap, pll->offset + FABIA_USER_CTL_LO,
536 mask, val);
537 }
538
Deepak Katragaddadcd7ed82017-09-12 16:50:56 -0700539 /*
540 * If the PLL has already been initialized, it would now be in a STANDBY
541 * state. Any new updates to the PLL frequency will require setting the
542 * PLL_UPDATE bit.
543 */
544 if (pll->inited)
545 clk_fabia_pll_latch_input(pll, regmap);
546
Deepak Katragadda2b803212016-06-29 16:35:22 -0700547 regmap_update_bits(regmap, pll->offset + PLL_MODE,
Amit Nischal82b6461b2017-06-19 15:47:36 +0530548 PLL_HW_UPDATE_LOGIC_BYPASS,
549 PLL_HW_UPDATE_LOGIC_BYPASS);
Deepak Katragadda2b803212016-06-29 16:35:22 -0700550
551 regmap_update_bits(regmap, pll->offset + PLL_MODE,
552 PLL_RESET_N, PLL_RESET_N);
553
554 pll->inited = true;
555}
556
Deepak Katragadda2b803212016-06-29 16:35:22 -0700557static int clk_fabia_pll_enable(struct clk_hw *hw)
558{
559 int ret;
560 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
561 u32 val, off = pll->offset;
562
563 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
564 if (ret)
565 return ret;
566
567 /* If in FSM mode, just vote for it */
568 if (val & PLL_VOTE_FSM_ENA) {
569 ret = clk_enable_regmap(hw);
570 if (ret)
571 return ret;
572 return wait_for_pll_enable(pll, PLL_ACTIVE_FLAG);
573 }
574
575 if (unlikely(!pll->inited))
576 clk_fabia_pll_configure(pll, pll->clkr.regmap, pll->config);
577
578 /* Disable PLL output */
579 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
580 PLL_OUTCTRL, 0);
581 if (ret)
582 return ret;
583
584 /* Set operation mode to STANDBY */
Amit Nischal82b6461b2017-06-19 15:47:36 +0530585 regmap_write(pll->clkr.regmap, off + FABIA_OPMODE, PLL_STANDBY);
Deepak Katragadda2b803212016-06-29 16:35:22 -0700586
587 /* PLL should be in STANDBY mode before continuing */
588 mb();
589
590 /* Bring PLL out of reset */
591 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
592 PLL_RESET_N, PLL_RESET_N);
593 if (ret)
594 return ret;
595
596 /* Set operation mode to RUN */
Amit Nischal82b6461b2017-06-19 15:47:36 +0530597 regmap_write(pll->clkr.regmap, off + FABIA_OPMODE, PLL_RUN);
Deepak Katragadda2b803212016-06-29 16:35:22 -0700598
599 ret = wait_for_pll_enable(pll, PLL_LOCK_DET);
600 if (ret)
601 return ret;
602
603 /* Enable the main PLL output */
604 ret = regmap_update_bits(pll->clkr.regmap, off + FABIA_USER_CTL_LO,
605 FABIA_PLL_OUT_MASK, FABIA_PLL_OUT_MASK);
606 if (ret)
607 return ret;
608
609 /* Enable PLL outputs */
610 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
611 PLL_OUTCTRL, PLL_OUTCTRL);
612 if (ret)
613 return ret;
614
615 /* Ensure that the write above goes through before returning. */
616 mb();
617 return ret;
618}
619
620static void clk_fabia_pll_disable(struct clk_hw *hw)
621{
622 int ret;
623 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
624 u32 val, off = pll->offset;
625
626 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
627 if (ret)
628 return;
629
630 /* If in FSM mode, just unvote it */
631 if (val & PLL_VOTE_FSM_ENA) {
632 clk_disable_regmap(hw);
633 return;
634 }
635
636 /* Disable PLL outputs */
637 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
638 PLL_OUTCTRL, 0);
639 if (ret)
640 return;
641
642 /* Disable the main PLL output */
643 ret = regmap_update_bits(pll->clkr.regmap, off + FABIA_USER_CTL_LO,
644 FABIA_PLL_OUT_MASK, 0);
645 if (ret)
646 return;
647
648 /* Place the PLL mode in STANDBY */
Amit Nischal82b6461b2017-06-19 15:47:36 +0530649 regmap_write(pll->clkr.regmap, off + FABIA_OPMODE, PLL_STANDBY);
Deepak Katragadda2b803212016-06-29 16:35:22 -0700650}
651
652static unsigned long
653clk_fabia_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
654{
655 u32 l, frac;
656 u64 prate = parent_rate;
657 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
658 u32 off = pll->offset;
659
660 regmap_read(pll->clkr.regmap, off + PLL_L_VAL, &l);
661 regmap_read(pll->clkr.regmap, off + FABIA_FRAC_VAL, &frac);
662
663 return alpha_pll_calc_rate(pll, prate, l, frac);
664}
665
666static int clk_fabia_pll_set_rate(struct clk_hw *hw, unsigned long rate,
667 unsigned long prate)
668{
669 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
670 unsigned long rrate;
Bruce Levy9f40ff52017-12-07 17:54:58 -0800671 u32 regval = 0, l = 0, off = pll->offset;
672 u64 a = 0;
673 int ret = 0;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700674
675 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &regval);
676 if (ret)
677 return ret;
678
679 rrate = alpha_pll_round_rate(pll, rate, prate, &l, &a);
680 /*
681 * Due to limited number of bits for fractional rate programming, the
682 * rounded up rate could be marginally higher than the requested rate.
683 */
Amit Nischal82b6461b2017-06-19 15:47:36 +0530684 if (rrate > (rate + ALPHA_16_BIT_PLL_RATE_MARGIN) || rrate < rate) {
Deepak Katragadda2b803212016-06-29 16:35:22 -0700685 pr_err("Call set rate on the PLL with rounded rates!\n");
686 return -EINVAL;
687 }
688
689 regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
Deepak Katragadda2b803212016-06-29 16:35:22 -0700690 regmap_write(pll->clkr.regmap, off + FABIA_FRAC_VAL, a);
691
Deepak Katragaddadcd7ed82017-09-12 16:50:56 -0700692 ret = clk_fabia_pll_latch_input(pll, pll->clkr.regmap);
693 return ret;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700694}
695
Taniya Das4b006ad2016-11-07 10:01:38 +0530696static void clk_fabia_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
697{
698 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
699 int size, i, val;
700
701 static struct clk_register_data data[] = {
702 {"PLL_MODE", 0x0},
703 {"PLL_L_VAL", 0x4},
704 {"PLL_FRAC_VAL", 0x38},
705 {"PLL_USER_CTL", 0xc},
706 {"PLL_CONFIG_CTL", 0x14},
707 {"PLL_OPMODE", 0x2c},
708 };
709
710 static struct clk_register_data data1[] = {
711 {"APSS_PLL_VOTE", 0x0},
712 };
713
714 size = ARRAY_SIZE(data);
715
716 for (i = 0; i < size; i++) {
717 regmap_read(pll->clkr.regmap, pll->offset + data[i].offset,
718 &val);
719 seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
720 }
721
722 regmap_read(pll->clkr.regmap, pll->offset + data[0].offset, &val);
723
724 if (val & PLL_FSM_ENA) {
725 regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
726 data1[0].offset, &val);
727 seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
728 }
729}
730
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800731const struct clk_ops clk_alpha_pll_ops = {
732 .enable = clk_alpha_pll_enable,
733 .disable = clk_alpha_pll_disable,
734 .recalc_rate = clk_alpha_pll_recalc_rate,
735 .round_rate = clk_alpha_pll_round_rate,
736 .set_rate = clk_alpha_pll_set_rate,
Taniya Das4b006ad2016-11-07 10:01:38 +0530737 .list_registers = clk_alpha_pll_list_registers,
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800738};
739EXPORT_SYMBOL_GPL(clk_alpha_pll_ops);
740
Rajendra Nayake512fb22016-04-18 11:40:43 +0530741const struct clk_ops clk_alpha_pll_hwfsm_ops = {
742 .enable = clk_alpha_pll_hwfsm_enable,
743 .disable = clk_alpha_pll_hwfsm_disable,
744 .recalc_rate = clk_alpha_pll_recalc_rate,
745 .round_rate = clk_alpha_pll_round_rate,
746 .set_rate = clk_alpha_pll_set_rate,
Taniya Das4b006ad2016-11-07 10:01:38 +0530747 .list_registers = clk_alpha_pll_list_registers,
Rajendra Nayake512fb22016-04-18 11:40:43 +0530748};
749EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
750
Deepak Katragadda2b803212016-06-29 16:35:22 -0700751const struct clk_ops clk_fabia_pll_ops = {
752 .enable = clk_fabia_pll_enable,
753 .disable = clk_fabia_pll_disable,
754 .recalc_rate = clk_fabia_pll_recalc_rate,
755 .round_rate = clk_alpha_pll_round_rate,
756 .set_rate = clk_fabia_pll_set_rate,
Taniya Das4b006ad2016-11-07 10:01:38 +0530757 .list_registers = clk_fabia_pll_list_registers,
Deepak Katragadda2b803212016-06-29 16:35:22 -0700758};
759EXPORT_SYMBOL_GPL(clk_fabia_pll_ops);
760
761const struct clk_ops clk_fabia_fixed_pll_ops = {
762 .enable = clk_fabia_pll_enable,
763 .disable = clk_fabia_pll_disable,
764 .recalc_rate = clk_fabia_pll_recalc_rate,
Deepak Katragadda24c04712016-11-28 14:27:05 -0800765 .round_rate = clk_alpha_pll_round_rate,
Taniya Das4b006ad2016-11-07 10:01:38 +0530766 .list_registers = clk_fabia_pll_list_registers,
Deepak Katragadda2b803212016-06-29 16:35:22 -0700767};
768EXPORT_SYMBOL_GPL(clk_fabia_fixed_pll_ops);
769
Stephen Boyd8ff1f4c2015-11-30 17:31:39 -0800770static unsigned long
771clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
772{
773 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
774 u32 ctl;
775
776 regmap_read(pll->clkr.regmap, pll->offset + PLL_USER_CTL, &ctl);
777
778 ctl >>= PLL_POST_DIV_SHIFT;
779 ctl &= PLL_POST_DIV_MASK;
780
781 return parent_rate >> fls(ctl);
782}
783
784static const struct clk_div_table clk_alpha_div_table[] = {
785 { 0x0, 1 },
786 { 0x1, 2 },
787 { 0x3, 4 },
788 { 0x7, 8 },
789 { 0xf, 16 },
790 { }
791};
792
793static long
794clk_alpha_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,
795 unsigned long *prate)
796{
797 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
798
799 return divider_round_rate(hw, rate, prate, clk_alpha_div_table,
800 pll->width, CLK_DIVIDER_POWER_OF_TWO);
801}
802
803static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
804 unsigned long parent_rate)
805{
806 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
807 int div;
808
809 /* 16 -> 0xf, 8 -> 0x7, 4 -> 0x3, 2 -> 0x1, 1 -> 0x0 */
810 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
811
812 return regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL,
813 PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT,
814 div << PLL_POST_DIV_SHIFT);
815}
816
817const struct clk_ops clk_alpha_pll_postdiv_ops = {
818 .recalc_rate = clk_alpha_pll_postdiv_recalc_rate,
819 .round_rate = clk_alpha_pll_postdiv_round_rate,
820 .set_rate = clk_alpha_pll_postdiv_set_rate,
821};
822EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops);
Deepak Katragadda2b803212016-06-29 16:35:22 -0700823
Deepak Katragadda582d6022016-11-09 16:17:45 -0800824static unsigned long clk_generic_pll_postdiv_recalc_rate(struct clk_hw *hw,
Deepak Katragadda2b803212016-06-29 16:35:22 -0700825 unsigned long parent_rate)
826{
827 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
828 u32 i, div = 1, val;
829
Deepak Katragadda582d6022016-11-09 16:17:45 -0800830 if (!pll->post_div_table) {
831 pr_err("Missing the post_div_table for the PLL\n");
832 return -EINVAL;
833 }
834
Deepak Katragadda2b803212016-06-29 16:35:22 -0700835 regmap_read(pll->clkr.regmap, pll->offset + FABIA_USER_CTL_LO, &val);
836
Deepak Katragadda2b803212016-06-29 16:35:22 -0700837 val >>= pll->post_div_shift;
838 val &= PLL_POST_DIV_MASK;
839
Deepak Katragadda582d6022016-11-09 16:17:45 -0800840 for (i = 0; i < pll->num_post_div; i++) {
841 if (pll->post_div_table[i].val == val) {
842 div = pll->post_div_table[i].div;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700843 break;
844 }
845 }
846
847 return (parent_rate / div);
848}
849
Deepak Katragadda582d6022016-11-09 16:17:45 -0800850static long clk_generic_pll_postdiv_round_rate(struct clk_hw *hw,
Deepak Katragadda2b803212016-06-29 16:35:22 -0700851 unsigned long rate, unsigned long *prate)
852{
853 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
854
Deepak Katragadda582d6022016-11-09 16:17:45 -0800855 if (!pll->post_div_table)
856 return -EINVAL;
857
858 return divider_round_rate(hw, rate, prate, pll->post_div_table,
Vicky Wallaceefd87da2017-06-05 19:03:25 -0700859 pll->width, CLK_DIVIDER_ROUND_KHZ);
Deepak Katragadda2b803212016-06-29 16:35:22 -0700860}
861
Deepak Katragadda582d6022016-11-09 16:17:45 -0800862static int clk_generic_pll_postdiv_set_rate(struct clk_hw *hw,
Deepak Katragadda2b803212016-06-29 16:35:22 -0700863 unsigned long rate, unsigned long parent_rate)
864{
865 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
Deepak Katragadda043f8542017-02-22 11:21:31 -0800866 int i, val = 0, div, ret;
867
868 /*
869 * If the PLL is in FSM mode, then treat the set_rate callback
870 * as a no-operation.
871 */
872 ret = regmap_read(pll->clkr.regmap, pll->offset + PLL_MODE, &val);
873 if (ret)
874 return ret;
875
876 if (val & PLL_VOTE_FSM_ENA)
877 return 0;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700878
Deepak Katragadda582d6022016-11-09 16:17:45 -0800879 if (!pll->post_div_table) {
880 pr_err("Missing the post_div_table for the PLL\n");
881 return -EINVAL;
882 }
883
Deepak Katragadda2b803212016-06-29 16:35:22 -0700884 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
Deepak Katragadda582d6022016-11-09 16:17:45 -0800885 for (i = 0; i < pll->num_post_div; i++) {
886 if (pll->post_div_table[i].div == div) {
887 val = pll->post_div_table[i].val;
Deepak Katragadda2b803212016-06-29 16:35:22 -0700888 break;
889 }
890 }
891
892 return regmap_update_bits(pll->clkr.regmap,
893 pll->offset + FABIA_USER_CTL_LO,
894 PLL_POST_DIV_MASK << pll->post_div_shift,
895 val << pll->post_div_shift);
896}
897
Deepak Katragadda582d6022016-11-09 16:17:45 -0800898const struct clk_ops clk_generic_pll_postdiv_ops = {
899 .recalc_rate = clk_generic_pll_postdiv_recalc_rate,
900 .round_rate = clk_generic_pll_postdiv_round_rate,
901 .set_rate = clk_generic_pll_postdiv_set_rate,
Deepak Katragadda2b803212016-06-29 16:35:22 -0700902};
Deepak Katragadda582d6022016-11-09 16:17:45 -0800903EXPORT_SYMBOL_GPL(clk_generic_pll_postdiv_ops);
Amit Nischal82b6461b2017-06-19 15:47:36 +0530904
905static int trion_pll_is_enabled(struct clk_alpha_pll *pll,
906 struct regmap *regmap)
907{
908 u32 mode_val, opmode_val, off = pll->offset;
909 int ret;
910
911 ret = regmap_read(regmap, off + PLL_MODE, &mode_val);
912 ret |= regmap_read(regmap, off + TRION_PLL_OPMODE, &opmode_val);
913 if (ret)
914 return 0;
915
916 return ((opmode_val & PLL_RUN) && (mode_val & PLL_OUTCTRL));
917}
918
919int clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
920 const struct pll_config *config)
921{
922 int ret = 0;
923
924 if (trion_pll_is_enabled(pll, regmap)) {
925 pr_debug("PLL is already enabled. Skipping configuration.\n");
926
927 /*
928 * Set the PLL_HW_UPDATE_LOGIC_BYPASS bit to latch the input
929 * before continuing.
930 */
931 regmap_update_bits(regmap, pll->offset + PLL_MODE,
932 PLL_HW_UPDATE_LOGIC_BYPASS,
933 PLL_HW_UPDATE_LOGIC_BYPASS);
934
935 pll->inited = true;
936 return ret;
937 }
938
939 /*
940 * Disable the PLL if it's already been initialized. Not doing so might
941 * lead to the PLL running with the old frequency configuration.
942 */
943 if (pll->inited) {
944 ret = regmap_update_bits(regmap, pll->offset + PLL_MODE,
945 PLL_RESET_N, 0);
946 if (ret)
947 return ret;
948 }
949
950 if (config->l)
951 regmap_write(regmap, pll->offset + PLL_L_VAL,
952 config->l);
953
954 regmap_write(regmap, pll->offset + TRION_PLL_CAL_L_VAL,
955 TRION_PLL_CAL_VAL);
956
957 if (config->frac)
958 regmap_write(regmap, pll->offset + TRION_PLL_ALPHA_VAL,
959 config->frac);
960
961 if (config->config_ctl_val)
962 regmap_write(regmap, pll->offset + PLL_CONFIG_CTL,
963 config->config_ctl_val);
964
965 if (config->config_ctl_hi_val)
966 regmap_write(regmap, pll->offset + TRION_PLL_CONFIG_CTL_U,
967 config->config_ctl_hi_val);
968
969 if (config->config_ctl_hi1_val)
970 regmap_write(regmap, pll->offset + TRION_PLL_CONFIG_CTL_U1,
971 config->config_ctl_hi1_val);
972
973 if (config->post_div_mask)
974 regmap_update_bits(regmap, pll->offset + TRION_PLL_USER_CTL,
975 config->post_div_mask, config->post_div_val);
976
977 /* Disable state read */
978 regmap_update_bits(regmap, pll->offset + TRION_PLL_USER_CTL_U,
979 TRION_PLL_ENABLE_STATE_READ, 0);
980
981 regmap_update_bits(regmap, pll->offset + PLL_MODE,
982 PLL_HW_UPDATE_LOGIC_BYPASS,
983 PLL_HW_UPDATE_LOGIC_BYPASS);
984
985 /* Set calibration control to Automatic */
986 regmap_update_bits(regmap, pll->offset + TRION_PLL_USER_CTL_U,
987 PLL_CALIBRATION_MASK, PLL_CALIBRATION_CONTROL);
988
989 /* Disable PLL output */
990 ret = regmap_update_bits(regmap, pll->offset + PLL_MODE,
991 PLL_OUTCTRL, 0);
992 if (ret)
993 return ret;
994
995 /* Set operation mode to OFF */
996 regmap_write(regmap, pll->offset + TRION_PLL_OPMODE, PLL_STANDBY);
997
998 /* PLL should be in OFF mode before continuing */
999 wmb();
1000
1001 /* Place the PLL in STANDBY mode */
1002 ret = regmap_update_bits(regmap, pll->offset + PLL_MODE,
1003 PLL_RESET_N, PLL_RESET_N);
1004 if (ret)
1005 return ret;
1006
1007 pll->inited = true;
1008
1009 return ret;
1010}
1011
1012static int clk_alpha_pll_latch_l_val(struct clk_alpha_pll *pll)
1013{
1014 int ret;
1015
1016 /* Latch the input to the PLL */
1017 ret = regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_MODE,
1018 PLL_UPDATE, PLL_UPDATE);
1019 if (ret)
1020 return ret;
1021
1022 /* Wait for 2 reference cycle before checking ACK bit */
1023 udelay(1);
1024
1025 ret = wait_for_pll_latch_ack(pll, PLL_ACK_LATCH);
1026 if (ret)
1027 return ret;
1028
1029 /* Return latch input to 0 */
1030 ret = regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_MODE,
1031 PLL_UPDATE, (u32)~PLL_UPDATE);
1032 if (ret)
1033 return ret;
1034
1035 return 0;
1036}
1037
1038static int clk_trion_pll_enable(struct clk_hw *hw)
1039{
1040 int ret = 0;
1041 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1042 u32 val, off = pll->offset;
1043
1044 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
1045 if (ret)
1046 return ret;
1047
1048 /* If in FSM mode, just vote for it */
1049 if (val & PLL_VOTE_FSM_ENA) {
1050 ret = clk_enable_regmap(hw);
1051 if (ret)
1052 return ret;
1053 return wait_for_pll_enable(pll, PLL_ACTIVE_FLAG);
1054 }
1055
1056 if (unlikely(!pll->inited)) {
1057 ret = clk_trion_pll_configure(pll, pll->clkr.regmap,
1058 pll->config);
1059 if (ret) {
1060 pr_err("Failed to configure %s\n", clk_hw_get_name(hw));
1061 return ret;
1062 }
1063 }
1064
1065 /* Skip If PLL is already running */
1066 if (trion_pll_is_enabled(pll, pll->clkr.regmap))
1067 return ret;
1068
1069 /* Set operation mode to RUN */
1070 regmap_write(pll->clkr.regmap, off + TRION_PLL_OPMODE, PLL_RUN);
1071
1072 ret = wait_for_pll_enable(pll, PLL_LOCK_DET);
1073 if (ret)
1074 return ret;
1075
1076 /* Enable PLL main output */
1077 ret = regmap_update_bits(pll->clkr.regmap, off + TRION_PLL_USER_CTL,
1078 TRION_PLL_OUT_MASK, TRION_PLL_OUT_MASK);
1079 if (ret)
1080 return ret;
1081
1082 /* Enable Global PLL outputs */
1083 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
1084 PLL_OUTCTRL, PLL_OUTCTRL);
1085 if (ret)
1086 return ret;
1087
1088 /* Ensure that the write above goes through before returning. */
1089 mb();
1090 return ret;
1091}
1092
1093static void clk_trion_pll_disable(struct clk_hw *hw)
1094{
1095 int ret;
1096 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1097 u32 val, off = pll->offset;
1098
1099 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
1100 if (ret)
1101 return;
1102
1103 /* If in FSM mode, just unvote it */
1104 if (val & PLL_VOTE_FSM_ENA) {
1105 clk_disable_regmap(hw);
1106 return;
1107 }
1108
1109 /* Disable Global PLL outputs */
1110 ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
1111 PLL_OUTCTRL, 0);
1112 if (ret)
1113 return;
1114
1115 /* Disable the main PLL output */
1116 ret = regmap_update_bits(pll->clkr.regmap, off + TRION_PLL_USER_CTL,
1117 TRION_PLL_OUT_MASK, 0);
1118 if (ret)
1119 return;
1120
1121 /* Place the PLL into STANDBY mode */
1122 regmap_write(pll->clkr.regmap, off + TRION_PLL_OPMODE, PLL_STANDBY);
1123
1124 regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
1125 PLL_RESET_N, PLL_RESET_N);
1126}
1127
1128static unsigned long
1129clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
1130{
1131 u32 l, frac = 0;
1132 u64 prate = parent_rate;
1133 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1134 u32 off = pll->offset;
1135
1136 regmap_read(pll->clkr.regmap, off + PLL_L_VAL, &l);
1137 regmap_read(pll->clkr.regmap, off + TRION_PLL_ALPHA_VAL, &frac);
1138
1139 return alpha_pll_calc_rate(pll, prate, l, frac);
1140}
1141
1142static int clk_trion_pll_set_rate(struct clk_hw *hw, unsigned long rate,
1143 unsigned long prate)
1144{
1145 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1146 unsigned long rrate;
1147 bool is_enabled;
1148 int ret;
Bruce Levy9f40ff52017-12-07 17:54:58 -08001149 u32 l = 0, val = 0, off = pll->offset;
1150 u64 a = 0;
Amit Nischal82b6461b2017-06-19 15:47:36 +05301151
1152 rrate = alpha_pll_round_rate(pll, rate, prate, &l, &a);
1153 /*
1154 * Due to limited number of bits for fractional rate programming, the
1155 * rounded up rate could be marginally higher than the requested rate.
1156 */
1157 if (rrate > (rate + ALPHA_16_BIT_PLL_RATE_MARGIN) || rrate < rate) {
1158 pr_err("Trion_pll: Call clk_set_rate with rounded rates!\n");
1159 return -EINVAL;
1160 }
1161
1162 is_enabled = clk_hw_is_enabled(hw);
1163
1164 if (is_enabled)
1165 hw->init->ops->disable(hw);
1166
1167 regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
1168 regmap_write(pll->clkr.regmap, off + TRION_PLL_ALPHA_VAL, a);
1169
1170 ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
1171 if (ret)
1172 return ret;
1173
1174 /*
1175 * If PLL is in Standby or RUN mode then only latch the L value
1176 * Else PLL is in OFF mode and just configure L register - as per
1177 * HPG no need to latch input.
1178 */
1179 if (val & PLL_RESET_N)
1180 clk_alpha_pll_latch_l_val(pll);
1181
1182 if (is_enabled)
1183 hw->init->ops->enable(hw);
1184
1185 /* Wait for PLL output to stabilize */
1186 udelay(100);
1187
1188 return ret;
1189}
1190
1191static int clk_trion_pll_is_enabled(struct clk_hw *hw)
1192{
1193 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1194
1195 return trion_pll_is_enabled(pll, pll->clkr.regmap);
1196}
1197
1198static void clk_trion_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
1199{
1200 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
1201 int size, i, val;
1202
1203 static struct clk_register_data data[] = {
1204 {"PLL_MODE", 0x0},
1205 {"PLL_L_VAL", 0x4},
1206 {"PLL_USER_CTL", 0xc},
1207 {"PLL_USER_CTL_U", 0x10},
1208 {"PLL_USER_CTL_U1", 0x14},
1209 {"PLL_CONFIG_CTL", 0x18},
1210 {"PLL_CONFIG_CTL_U", 0x1c},
1211 {"PLL_CONFIG_CTL_U1", 0x20},
1212 {"PLL_OPMODE", 0x38},
1213 };
1214
1215 static struct clk_register_data data1[] = {
1216 {"APSS_PLL_VOTE", 0x0},
1217 };
1218
1219 size = ARRAY_SIZE(data);
1220
1221 for (i = 0; i < size; i++) {
1222 regmap_read(pll->clkr.regmap, pll->offset + data[i].offset,
1223 &val);
1224 seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
1225 }
1226
1227 regmap_read(pll->clkr.regmap, pll->offset + data[0].offset, &val);
1228
1229 if (val & PLL_VOTE_FSM_ENA) {
1230 regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
1231 data1[0].offset, &val);
1232 seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val);
1233 }
1234}
1235
1236const struct clk_ops clk_trion_pll_ops = {
1237 .enable = clk_trion_pll_enable,
1238 .disable = clk_trion_pll_disable,
1239 .recalc_rate = clk_trion_pll_recalc_rate,
1240 .round_rate = clk_alpha_pll_round_rate,
1241 .set_rate = clk_trion_pll_set_rate,
1242 .is_enabled = clk_trion_pll_is_enabled,
1243 .list_registers = clk_trion_pll_list_registers,
1244};
1245EXPORT_SYMBOL(clk_trion_pll_ops);
1246
1247const struct clk_ops clk_trion_fixed_pll_ops = {
1248 .enable = clk_trion_pll_enable,
1249 .disable = clk_trion_pll_disable,
1250 .recalc_rate = clk_trion_pll_recalc_rate,
1251 .round_rate = clk_alpha_pll_round_rate,
1252 .is_enabled = clk_trion_pll_is_enabled,
1253 .list_registers = clk_trion_pll_list_registers,
1254};
1255EXPORT_SYMBOL(clk_trion_fixed_pll_ops);
1256
1257static unsigned long clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw,
1258 unsigned long parent_rate)
1259{
1260 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1261 u32 i, cal_div = 1, val;
1262
1263 if (!pll->post_div_table) {
1264 pr_err("Missing the post_div_table for the PLL\n");
1265 return -EINVAL;
1266 }
1267
1268 regmap_read(pll->clkr.regmap, pll->offset + TRION_PLL_USER_CTL, &val);
1269
1270 val >>= pll->post_div_shift;
1271 val &= PLL_POST_DIV_MASK;
1272
1273 for (i = 0; i < pll->num_post_div; i++) {
1274 if (pll->post_div_table[i].val == val) {
1275 cal_div = pll->post_div_table[i].div;
1276 break;
1277 }
1278 }
1279
1280 return (parent_rate / cal_div);
1281}
1282
1283static long clk_trion_pll_postdiv_round_rate(struct clk_hw *hw,
1284 unsigned long rate, unsigned long *prate)
1285{
1286 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1287
1288 if (!pll->post_div_table)
1289 return -EINVAL;
1290
1291 return divider_round_rate(hw, rate, prate, pll->post_div_table,
1292 pll->width, CLK_DIVIDER_ROUND_CLOSEST);
1293}
1294
1295static int clk_trion_pll_postdiv_set_rate(struct clk_hw *hw,
1296 unsigned long rate, unsigned long parent_rate)
1297{
1298 struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
1299 int i, val = 0, cal_div, ret;
1300
1301 /*
1302 * If the PLL is in FSM mode, then treat the set_rate callback
1303 * as a no-operation.
1304 */
1305 ret = regmap_read(pll->clkr.regmap, pll->offset + PLL_MODE, &val);
1306 if (ret)
1307 return ret;
1308
1309 if (val & PLL_VOTE_FSM_ENA)
1310 return 0;
1311
1312 if (!pll->post_div_table) {
1313 pr_err("Missing the post_div_table for the PLL\n");
1314 return -EINVAL;
1315 }
1316
1317 cal_div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
1318 for (i = 0; i < pll->num_post_div; i++) {
1319 if (pll->post_div_table[i].div == cal_div) {
1320 val = pll->post_div_table[i].val;
1321 break;
1322 }
1323 }
1324
1325 return regmap_update_bits(pll->clkr.regmap,
1326 pll->offset + TRION_PLL_USER_CTL,
1327 PLL_POST_DIV_MASK << pll->post_div_shift,
1328 val << pll->post_div_shift);
1329}
1330
1331const struct clk_ops clk_trion_pll_postdiv_ops = {
1332 .recalc_rate = clk_trion_pll_postdiv_recalc_rate,
1333 .round_rate = clk_trion_pll_postdiv_round_rate,
1334 .set_rate = clk_trion_pll_postdiv_set_rate,
1335};
1336EXPORT_SYMBOL(clk_trion_pll_postdiv_ops);