blob: f9a4f0e2866149504446d6749ff6db0c6dc5fb33 [file] [log] [blame]
Sachin Bhayarecf8460a2018-01-03 18:34:30 +05301/* Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/kernel.h>
16#include <linux/err.h>
17#include <linux/iopoll.h>
18#include <linux/delay.h>
19#include <linux/clk/msm-clock-generic.h>
20
21#include "mdss-pll.h"
22#include "mdss-dsi-pll.h"
23#include "mdss-dsi-pll-8996.h"
24
25#define DSI_PLL_POLL_MAX_READS 15
26#define DSI_PLL_POLL_TIMEOUT_US 1000
27#define MSM8996_DSI_PLL_REVISION_2 2
28
29#define DSI_PHY_SPARE_VAL 0x6a
30#define DSI_PLL_DEFAULT_POSTDIV 1
31
32#define CEIL(x, y) (((x) + ((y)-1)) / (y))
33static void pll_db_commit_8996(struct mdss_pll_resources *pll,
34 struct dsi_pll_db *pdb);
35
36int set_mdss_byte_mux_sel_8996(struct mux_clk *clk, int sel)
37{
38 return 0;
39}
40
41int get_mdss_byte_mux_sel_8996(struct mux_clk *clk)
42{
43 return 0;
44}
45
46int set_mdss_pixel_mux_sel_8996(struct mux_clk *clk, int sel)
47{
48 return 0;
49}
50
51int get_mdss_pixel_mux_sel_8996(struct mux_clk *clk)
52{
53 return 0;
54}
55
56static int mdss_pll_read_stored_trim_codes(
57 struct mdss_pll_resources *dsi_pll_res, s64 vco_clk_rate,
58 int *pll_trim_codes)
59{
60 int i;
61 int rc = 0;
62 bool found = false;
63
64 if (!dsi_pll_res->dfps) {
65 rc = -EINVAL;
66 goto end_read;
67 }
68
69 for (i = 0; i < dsi_pll_res->dfps->panel_dfps.frame_rate_cnt; i++) {
70 struct dfps_codes_info *codes_info =
71 &dsi_pll_res->dfps->codes_dfps[i];
72
73 pr_debug("valid=%d frame_rate=%d, vco_rate=%d, code %d %d\n",
74 codes_info->is_valid, codes_info->frame_rate,
75 codes_info->clk_rate, codes_info->pll_codes.pll_codes_1,
76 codes_info->pll_codes.pll_codes_2);
77
78 if (vco_clk_rate != codes_info->clk_rate &&
79 codes_info->is_valid)
80 continue;
81
82 pll_trim_codes[0] =
83 codes_info->pll_codes.pll_codes_1;
84 pll_trim_codes[1] =
85 codes_info->pll_codes.pll_codes_2;
86 found = true;
87 break;
88 }
89
90 if (!found) {
91 rc = -EINVAL;
92 goto end_read;
93 }
94
95 pr_debug("core_kvco_code=0x%x core_vco_tune=0x%x\n",
96 pll_trim_codes[0], pll_trim_codes[1]);
97
98end_read:
99 return rc;
100}
101
102int post_n1_div_set_div(struct div_clk *clk, int div)
103{
104 struct mdss_pll_resources *pll = clk->priv;
105 struct dsi_pll_db *pdb;
106 struct dsi_pll_output *pout;
107 int rc;
108 u32 n1div = 0;
109
110 rc = mdss_pll_resource_enable(pll, true);
111 if (rc) {
112 pr_err("Failed to enable mdss dsi pll resources\n");
113 return rc;
114 }
115
116 pdb = (struct dsi_pll_db *)pll->priv;
117 pout = &pdb->out;
118
119 /*
120 * vco rate = bit_clk * postdiv * n1div
121 * vco range from 1300 to 2600 Mhz
122 * postdiv = 1
123 * n1div = 1 to 15
124 * n1div = roundup(1300Mhz / bit_clk)
125 * support bit_clk above 86.67Mhz
126 */
127
128 /* this is for vco/bit clock */
129 pout->pll_postdiv = DSI_PLL_DEFAULT_POSTDIV;
130 pout->pll_n1div = div;
131
132 n1div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
133 n1div &= ~0xf;
134 n1div |= (div & 0xf);
135 MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n1div);
136 /* ensure n1 divider is programed */
137 wmb();
138 pr_debug("ndx=%d div=%d postdiv=%x n1div=%x\n",
139 pll->index, div, pout->pll_postdiv, pout->pll_n1div);
140
141 mdss_pll_resource_enable(pll, false);
142
143 return 0;
144}
145
146int post_n1_div_get_div(struct div_clk *clk)
147{
148 u32 div;
149 int rc;
150 struct mdss_pll_resources *pll = clk->priv;
151
152 if (is_gdsc_disabled(pll))
153 return 0;
154
155 rc = mdss_pll_resource_enable(pll, true);
156 if (rc) {
157 pr_err("Failed to enable mdss dsi pll resources\n");
158 return rc;
159 }
160
161 /*
162 * postdiv = 1/2/4/8
163 * n1div = 1 - 15
164 * fot the time being, assume postdiv = 1
165 */
166
167 div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
168 div &= 0xF;
169 pr_debug("n1 div = %d\n", div);
170
171 mdss_pll_resource_enable(pll, false);
172
173 return div;
174}
175
176int n2_div_set_div(struct div_clk *clk, int div)
177{
178 int rc;
179 u32 n2div;
180 struct mdss_pll_resources *pll = clk->priv;
181 struct dsi_pll_db *pdb;
182 struct dsi_pll_output *pout;
183 struct mdss_pll_resources *slave;
184
185 rc = mdss_pll_resource_enable(pll, true);
186 if (rc) {
187 pr_err("Failed to enable mdss dsi pll resources\n");
188 return rc;
189 }
190
191 pdb = (struct dsi_pll_db *)pll->priv;
192 pout = &pdb->out;
193
194 /* this is for pixel_clock */
195 n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
196 n2div &= ~0xf0; /* bits 4 to 7 */
197 n2div |= (div << 4);
198 MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n2div);
199
200 /* commit slave if split display is enabled */
201 slave = pll->slave;
202 if (slave)
203 MDSS_PLL_REG_W(slave->pll_base, DSIPHY_CMN_CLK_CFG0, n2div);
204
205 pout->pll_n2div = div;
206
207 /* set dsiclk_sel=1 so that n2div *= 2 */
208 MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG1, 1);
209 pr_debug("ndx=%d div=%d n2div=%x\n", pll->index, div, n2div);
210
211 mdss_pll_resource_enable(pll, false);
212
213 return rc;
214}
215
216int shadow_n2_div_set_div(struct div_clk *clk, int div)
217{
218 struct mdss_pll_resources *pll = clk->priv;
219 struct dsi_pll_db *pdb;
220 struct dsi_pll_output *pout;
221 u32 data;
222
223 pdb = pll->priv;
224 pout = &pdb->out;
225
226 pout->pll_n2div = div;
227
228 data = (pout->pll_n1div | (pout->pll_n2div << 4));
229 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
230 DSI_DYNAMIC_REFRESH_PLL_CTRL19,
231 DSIPHY_CMN_CLK_CFG0, DSIPHY_CMN_CLK_CFG1,
232 data, 1);
233 return 0;
234}
235
236int n2_div_get_div(struct div_clk *clk)
237{
238 int rc;
239 u32 n2div;
240 struct mdss_pll_resources *pll = clk->priv;
241
242 if (is_gdsc_disabled(pll))
243 return 0;
244
245 rc = mdss_pll_resource_enable(pll, true);
246 if (rc) {
247 pr_err("Failed to enable mdss dsi pll=%d resources\n",
248 pll->index);
249 return rc;
250 }
251
252 n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
253 n2div >>= 4;
254 n2div &= 0x0f;
255
256 mdss_pll_resource_enable(pll, false);
257
258 pr_debug("ndx=%d div=%d\n", pll->index, n2div);
259
260 return n2div;
261}
262
263static bool pll_is_pll_locked_8996(struct mdss_pll_resources *pll)
264{
265 u32 status;
266 bool pll_locked;
267
268 /* poll for PLL ready status */
269 if (readl_poll_timeout_atomic((pll->pll_base +
270 DSIPHY_PLL_RESET_SM_READY_STATUS),
271 status,
272 ((status & BIT(5)) > 0),
273 DSI_PLL_POLL_MAX_READS,
274 DSI_PLL_POLL_TIMEOUT_US)) {
275 pr_err("DSI PLL ndx=%d status=%x failed to Lock\n",
276 pll->index, status);
277 pll_locked = false;
278 } else if (readl_poll_timeout_atomic((pll->pll_base +
279 DSIPHY_PLL_RESET_SM_READY_STATUS),
280 status,
281 ((status & BIT(0)) > 0),
282 DSI_PLL_POLL_MAX_READS,
283 DSI_PLL_POLL_TIMEOUT_US)) {
284 pr_err("DSI PLL ndx=%d status=%x PLl not ready\n",
285 pll->index, status);
286 pll_locked = false;
287 } else {
288 pll_locked = true;
289 }
290
291 return pll_locked;
292}
293
294static void dsi_pll_start_8996(void __iomem *pll_base)
295{
296 pr_debug("start PLL at base=%pk\n", pll_base);
297
298 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VREF_CFG1, 0x10);
299 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 1);
300 wmb(); /* make sure register committed */
301}
302
303static void dsi_pll_stop_8996(void __iomem *pll_base)
304{
305 pr_debug("stop PLL at base=%pk\n", pll_base);
306
307 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0);
308 wmb(); /* make sure register committed */
309}
310
311static inline bool pll_use_precal(struct mdss_pll_resources *pll)
312{
313 bool ret = true;
314 u32 spare = MDSS_PLL_REG_R(pll->pll_base,
315 DSIPHY_CMN_GLBL_DIGTOP_SPARE2);
316
317 if (!pll->cache_pll_trim_codes[0] || /* kvco code */
318 !pll->cache_pll_trim_codes[1] || /* vco tune */
319 !pll->cache_pll_trim_codes_rate ||
320 (pll->cache_pll_trim_codes_rate != pll->vco_current_rate) ||
321 (spare != DSI_PHY_SPARE_VAL)) /* phy reset */
322 ret = false;
323
324 pr_debug("ndx:%d kvco:%d vco_tune:%d spare:0x%x rate:%llu old:%llu ret:%d\n",
325 pll->index, pll->cache_pll_trim_codes[0],
326 pll->cache_pll_trim_codes[1], spare,
327 pll->cache_pll_trim_codes_rate,
328 pll->vco_current_rate, ret);
329
330 return ret;
331}
332
333int dsi_pll_enable_seq_8996(struct mdss_pll_resources *pll)
334{
335 int rc = 0;
336 struct dsi_pll_db *pdb;
337 struct mdss_pll_resources *slave;
338
339 if (!pll) {
340 pr_err("Invalid PLL resources\n");
341 return -EINVAL;
342 }
343
344 pdb = (struct dsi_pll_db *)pll->priv;
345 if (!pdb) {
346 pr_err("No priv found\n");
347 return -EINVAL;
348 }
349
350 dsi_pll_start_8996(pll->pll_base);
351
352 /*
353 * both DSIPHY_PLL_CLKBUFLR_EN and DSIPHY_CMN_GLBL_TEST_CTRL
354 * enabled at mdss_dsi_8996_phy_config()
355 */
356
357 if (!pll_is_pll_locked_8996(pll)) {
358 pr_err("DSI PLL ndx=%d lock failed, retry full sequence!\n",
359 pll->index);
360 slave = pll->slave;
361
362 /* commit slave if split display is enabled */
363 if (slave)
364 pll_db_commit_8996(slave, pdb);
365
366 /* commit master itself */
367 pll_db_commit_8996(pll, pdb);
368
369 dsi_pll_start_8996(pll->pll_base);
370 if (!pll_is_pll_locked_8996(pll)) {
371 pr_err("DSI PLL ndx=%d lock failed!!!\n",
372 pll->index);
373 rc = -EINVAL;
374 goto init_lock_err;
375 }
376 }
377
378 if (!pll_use_precal(pll)) {
379 /* cache vco settings */
380 pll->cache_pll_trim_codes[0] = MDSS_PLL_REG_R(pll->pll_base,
381 DSIPHY_PLL_CORE_KVCO_CODE_STATUS);
382 pll->cache_pll_trim_codes[1] = MDSS_PLL_REG_R(pll->pll_base,
383 DSIPHY_PLL_CORE_VCO_TUNE_STATUS);
384 pll->cache_pll_trim_codes_rate = pll->vco_current_rate;
385
386 /* write spare */
387 MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_GLBL_DIGTOP_SPARE2,
388 DSI_PHY_SPARE_VAL);
389 }
390
391 pr_debug("DSI PLL ndx:%d Locked! kvco=0x%x vco_tune=0x%x rate=%llu\n",
392 pll->index, pll->cache_pll_trim_codes[0],
393 pll->cache_pll_trim_codes[1],
394 pll->cache_pll_trim_codes_rate);
395
396init_lock_err:
397 return rc;
398}
399
400static int dsi_pll_enable(struct clk *c)
401{
402 int i, rc = 0;
403 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
404 struct mdss_pll_resources *pll = vco->priv;
405
406 /* Try all enable sequences until one succeeds */
407 for (i = 0; i < vco->pll_en_seq_cnt; i++) {
408 rc = vco->pll_enable_seqs[i](pll);
409 pr_debug("DSI PLL %s after sequence #%d\n",
410 rc ? "unlocked" : "locked", i + 1);
411 if (!rc)
412 break;
413 }
414
415 if (rc)
416 pr_err("ndx=%d DSI PLL failed to lock\n", pll->index);
417 else
418 pll->pll_on = true;
419
420 return rc;
421}
422
423static void dsi_pll_disable(struct clk *c)
424{
425 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
426 struct mdss_pll_resources *pll = vco->priv;
427 struct mdss_pll_resources *slave;
428
429 if (!pll->pll_on &&
430 mdss_pll_resource_enable(pll, true)) {
431 pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
432 return;
433 }
434
435 pll->handoff_resources = false;
436 slave = pll->slave;
437
438 dsi_pll_stop_8996(pll->pll_base);
439
440 mdss_pll_resource_enable(pll, false);
441
442 pll->pll_on = false;
443
444 pr_debug("DSI PLL ndx=%d Disabled\n", pll->index);
445}
446
447static void mdss_dsi_pll_8996_input_init(struct mdss_pll_resources *pll,
448 struct dsi_pll_db *pdb)
449{
450 pdb->in.fref = 19200000; /* 19.2 Mhz*/
451 pdb->in.fdata = 0; /* bit clock rate */
452 pdb->in.dsiclk_sel = 1; /* 1, reg: 0x0014 */
453 pdb->in.ssc_en = pll->ssc_en; /* 1, reg: 0x0494, bit 0 */
454 pdb->in.ldo_en = 0; /* 0, reg: 0x004c, bit 0 */
455
456 /* fixed input */
457 pdb->in.refclk_dbler_en = 0; /* 0, reg: 0x04c0, bit 1 */
458 pdb->in.vco_measure_time = 5; /* 5, unknown */
459 pdb->in.kvco_measure_time = 5; /* 5, unknown */
460 pdb->in.bandgap_timer = 4; /* 4, reg: 0x0430, bit 3 - 5 */
461 pdb->in.pll_wakeup_timer = 5; /* 5, reg: 0x043c, bit 0 - 2 */
462 pdb->in.plllock_cnt = 1; /* 1, reg: 0x0488, bit 1 - 2 */
463 pdb->in.plllock_rng = 0; /* 0, reg: 0x0488, bit 3 - 4 */
464 pdb->in.ssc_center = pll->ssc_center;/* 0, reg: 0x0494, bit 1 */
465 pdb->in.ssc_adj_period = 37; /* 37, reg: 0x498, bit 0 - 9 */
466 pdb->in.ssc_spread = pll->ssc_ppm / 1000;
467 pdb->in.ssc_freq = pll->ssc_freq;
468
469 pdb->in.pll_ie_trim = 4; /* 4, reg: 0x0400 */
470 pdb->in.pll_ip_trim = 4; /* 4, reg: 0x0404 */
471 pdb->in.pll_cpcset_cur = 1; /* 1, reg: 0x04f0, bit 0 - 2 */
472 pdb->in.pll_cpmset_cur = 1; /* 1, reg: 0x04f0, bit 3 - 5 */
473 pdb->in.pll_icpmset = 4; /* 4, reg: 0x04fc, bit 3 - 5 */
474 pdb->in.pll_icpcset = 4; /* 4, reg: 0x04fc, bit 0 - 2 */
475 pdb->in.pll_icpmset_p = 0; /* 0, reg: 0x04f4, bit 0 - 2 */
476 pdb->in.pll_icpmset_m = 0; /* 0, reg: 0x04f4, bit 3 - 5 */
477 pdb->in.pll_icpcset_p = 0; /* 0, reg: 0x04f8, bit 0 - 2 */
478 pdb->in.pll_icpcset_m = 0; /* 0, reg: 0x04f8, bit 3 - 5 */
479 pdb->in.pll_lpf_res1 = 3; /* 3, reg: 0x0504, bit 0 - 3 */
480 pdb->in.pll_lpf_cap1 = 11; /* 11, reg: 0x0500, bit 0 - 3 */
481 pdb->in.pll_lpf_cap2 = 1; /* 1, reg: 0x0500, bit 4 - 7 */
482 pdb->in.pll_iptat_trim = 7;
483 pdb->in.pll_c3ctrl = 2; /* 2 */
484 pdb->in.pll_r3ctrl = 1; /* 1 */
485}
486
487static void pll_8996_ssc_calc(struct mdss_pll_resources *pll,
488 struct dsi_pll_db *pdb)
489{
490 u32 period, ssc_period;
491 u32 ref, rem;
492 s64 step_size;
493
494 pr_debug("%s: vco=%lld ref=%lld\n", __func__,
495 pll->vco_current_rate, pll->vco_ref_clk_rate);
496
497 ssc_period = pdb->in.ssc_freq / 500;
498 period = (unsigned long)pll->vco_ref_clk_rate / 1000;
499 ssc_period = CEIL(period, ssc_period);
500 ssc_period -= 1;
501 pdb->out.ssc_period = ssc_period;
502
503 pr_debug("%s: ssc, freq=%d spread=%d period=%d\n", __func__,
504 pdb->in.ssc_freq, pdb->in.ssc_spread, pdb->out.ssc_period);
505
506 step_size = (u32)pll->vco_current_rate;
507 ref = pll->vco_ref_clk_rate;
508 ref /= 1000;
509 step_size = div_s64(step_size, ref);
510 step_size <<= 20;
511 step_size = div_s64(step_size, 1000);
512 step_size *= pdb->in.ssc_spread;
513 step_size = div_s64(step_size, 1000);
514 step_size *= (pdb->in.ssc_adj_period + 1);
515
516 rem = 0;
517 step_size = div_s64_rem(step_size, ssc_period + 1, &rem);
518 if (rem)
519 step_size++;
520
521 pr_debug("%s: step_size=%lld\n", __func__, step_size);
522
523 step_size &= 0x0ffff; /* take lower 16 bits */
524
525 pdb->out.ssc_step_size = step_size;
526}
527
528static void pll_8996_dec_frac_calc(struct mdss_pll_resources *pll,
529 struct dsi_pll_db *pdb)
530{
531 struct dsi_pll_input *pin = &pdb->in;
532 struct dsi_pll_output *pout = &pdb->out;
533 s64 multiplier = BIT(20);
534 s64 dec_start_multiple, dec_start, pll_comp_val;
535 s32 duration, div_frac_start;
536 s64 vco_clk_rate = pll->vco_current_rate;
537 s64 fref = pll->vco_ref_clk_rate;
538
539 pr_debug("vco_clk_rate=%lld ref_clk_rate=%lld\n",
540 vco_clk_rate, fref);
541
542 dec_start_multiple = div_s64(vco_clk_rate * multiplier, fref);
543 div_s64_rem(dec_start_multiple, multiplier, &div_frac_start);
544
545 dec_start = div_s64(dec_start_multiple, multiplier);
546
547 pout->dec_start = (u32)dec_start;
548 pout->div_frac_start = div_frac_start;
549
550 if (pin->plllock_cnt == 0)
551 duration = 1024;
552 else if (pin->plllock_cnt == 1)
553 duration = 256;
554 else if (pin->plllock_cnt == 2)
555 duration = 128;
556 else
557 duration = 32;
558
559 pll_comp_val = duration * dec_start_multiple;
560 pll_comp_val = div_s64(pll_comp_val, multiplier);
561 do_div(pll_comp_val, 10);
562
563 pout->plllock_cmp = (u32)pll_comp_val;
564
565 pout->pll_txclk_en = 1;
566 if (pll->revision == MSM8996_DSI_PLL_REVISION_2)
567 pout->cmn_ldo_cntrl = 0x3c;
568 else
569 pout->cmn_ldo_cntrl = 0x1c;
570}
571
572static u32 pll_8996_kvco_slop(u32 vrate)
573{
574 u32 slop = 0;
575
576 if (vrate > 1300000000UL && vrate <= 1800000000UL)
577 slop = 600;
578 else if (vrate > 1800000000UL && vrate < 2300000000UL)
579 slop = 400;
580 else if (vrate > 2300000000UL && vrate < 2600000000UL)
581 slop = 280;
582
583 return slop;
584}
585
586static inline u32 pll_8996_calc_kvco_code(s64 vco_clk_rate)
587{
588 u32 kvco_code;
589
590 if ((vco_clk_rate >= 2300000000ULL) &&
591 (vco_clk_rate <= 2600000000ULL))
592 kvco_code = 0x2f;
593 else if ((vco_clk_rate >= 1800000000ULL) &&
594 (vco_clk_rate < 2300000000ULL))
595 kvco_code = 0x2c;
596 else
597 kvco_code = 0x28;
598
599 pr_debug("rate: %llu kvco_code: 0x%x\n",
600 vco_clk_rate, kvco_code);
601 return kvco_code;
602}
603
604static void pll_8996_calc_vco_count(struct dsi_pll_db *pdb,
605 s64 vco_clk_rate, s64 fref)
606{
607 struct dsi_pll_input *pin = &pdb->in;
608 struct dsi_pll_output *pout = &pdb->out;
609 s64 data;
610 u32 cnt;
611
612 data = fref * pin->vco_measure_time;
613 do_div(data, 1000000);
614 data &= 0x03ff; /* 10 bits */
615 data -= 2;
616 pout->pll_vco_div_ref = data;
617
618 data = (unsigned long)vco_clk_rate / 1000000; /* unit is Mhz */
619 data *= pin->vco_measure_time;
620 do_div(data, 10);
621 pout->pll_vco_count = data; /* reg: 0x0474, 0x0478 */
622
623 data = fref * pin->kvco_measure_time;
624 do_div(data, 1000000);
625 data &= 0x03ff; /* 10 bits */
626 data -= 1;
627 pout->pll_kvco_div_ref = data;
628
629 cnt = pll_8996_kvco_slop(vco_clk_rate);
630 cnt *= 2;
631 do_div(cnt, 100);
632 cnt *= pin->kvco_measure_time;
633 pout->pll_kvco_count = cnt;
634
635 pout->pll_misc1 = 16;
636 pout->pll_resetsm_cntrl = 48;
637 pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3;
638 pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer;
639 pout->pll_kvco_code = pll_8996_calc_kvco_code(vco_clk_rate);
640}
641
642static void pll_db_commit_ssc(struct mdss_pll_resources *pll,
643 struct dsi_pll_db *pdb)
644{
645 void __iomem *pll_base = pll->pll_base;
646 struct dsi_pll_input *pin = &pdb->in;
647 struct dsi_pll_output *pout = &pdb->out;
648 char data;
649
650 data = pin->ssc_adj_period;
651 data &= 0x0ff;
652 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_ADJ_PER1, data);
653 data = (pin->ssc_adj_period >> 8);
654 data &= 0x03;
655 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_ADJ_PER2, data);
656
657 data = pout->ssc_period;
658 data &= 0x0ff;
659 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_PER1, data);
660 data = (pout->ssc_period >> 8);
661 data &= 0x0ff;
662 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_PER2, data);
663
664 data = pout->ssc_step_size;
665 data &= 0x0ff;
666 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_STEP_SIZE1, data);
667 data = (pout->ssc_step_size >> 8);
668 data &= 0x0ff;
669 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_STEP_SIZE2, data);
670
671 data = (pin->ssc_center & 0x01);
672 data <<= 1;
673 data |= 0x01; /* enable */
674 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_EN_CENTER, data);
675
676 wmb(); /* make sure register committed */
677}
678
679static int pll_precal_commit_8996(struct mdss_pll_resources *pll,
680 struct dsi_pll_db *pdb)
681{
682 void __iomem *pll_base = pll->pll_base;
683 struct dsi_pll_output *pout = &pdb->out;
684 char data;
685
686 /*
687 * if pre-calibrated values cannot be used, return
688 * error, so we use full sequence.
689 */
690 if (!pll_use_precal(pll)) {
691 pr_debug("cannot use precal sequence ndx:%d\n", pll->index);
692 return -EINVAL;
693 }
694
695 data = pout->cmn_ldo_cntrl;
696 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_LDO_CNTRL, data);
697
698 /* stop pll */
699 data = 0;
700 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, data);
701
702 data = 0x7f;
703 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_0, data);
704
705 data = 0x20;
706 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, data);
707
708 data = 0x38;
709 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL, data);
710
711 data = BIT(7);
712 data |= pll->cache_pll_trim_codes[1]; /* vco tune */
713 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_VCO_TUNE, data);
714
715 data = BIT(5);
716 data |= pll->cache_pll_trim_codes[0]; /* kvco code */
717 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_CODE, data);
718
719 data = 0xff; /* data, clk, pll normal operation */
720 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_0, data);
721
722 data = 0x0;
723 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, data);
724 wmb(); /* make sure register committed */
725
726 return 0;
727}
728
729static void pll_db_commit_common(struct mdss_pll_resources *pll,
730 struct dsi_pll_db *pdb)
731{
732 void __iomem *pll_base = pll->pll_base;
733 struct dsi_pll_input *pin = &pdb->in;
734 struct dsi_pll_output *pout = &pdb->out;
735 char data;
736
737 /* confgiure the non frequency dependent pll registers */
738 data = 0;
739 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SYSCLK_EN_RESET, data);
740
741 /* DSIPHY_PLL_CLKBUFLR_EN updated at dsi phy */
742
743 data = pout->pll_txclk_en;
744 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_TXCLK_EN, data);
745
746 data = pout->pll_resetsm_cntrl;
747 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL, data);
748 data = pout->pll_resetsm_cntrl2;
749 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL2, data);
750 data = pout->pll_resetsm_cntrl5;
751 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL5, data);
752
753 data = pout->pll_vco_div_ref;
754 data &= 0x0ff;
755 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_DIV_REF1, data);
756 data = (pout->pll_vco_div_ref >> 8);
757 data &= 0x03;
758 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_DIV_REF2, data);
759
760 data = pout->pll_kvco_div_ref;
761 data &= 0x0ff;
762 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_DIV_REF1, data);
763 data = (pout->pll_kvco_div_ref >> 8);
764 data &= 0x03;
765 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_DIV_REF2, data);
766
767 data = pout->pll_misc1;
768 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_MISC1, data);
769
770 data = pin->pll_ie_trim;
771 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IE_TRIM, data);
772
773 data = pin->pll_ip_trim;
774 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IP_TRIM, data);
775
776 data = ((pin->pll_cpmset_cur << 3) | pin->pll_cpcset_cur);
777 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CP_SET_CUR, data);
778
779 data = ((pin->pll_icpcset_p << 3) | pin->pll_icpcset_m);
780 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICPCSET, data);
781
782 data = ((pin->pll_icpmset_p << 3) | pin->pll_icpcset_m);
783 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICPMSET, data);
784
785 data = ((pin->pll_icpmset << 3) | pin->pll_icpcset);
786 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICP_SET, data);
787
788 data = ((pdb->in.pll_lpf_cap2 << 4) | pdb->in.pll_lpf_cap1);
789 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF1, data);
790
791 data = pin->pll_iptat_trim;
792 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IPTAT_TRIM, data);
793
794 data = (pdb->in.pll_c3ctrl | (pdb->in.pll_r3ctrl << 4));
795 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_CRCTRL, data);
796}
797
798static void pll_db_commit_8996(struct mdss_pll_resources *pll,
799 struct dsi_pll_db *pdb)
800{
801 void __iomem *pll_base = pll->pll_base;
802 struct dsi_pll_input *pin = &pdb->in;
803 struct dsi_pll_output *pout = &pdb->out;
804 char data;
805
806 data = pout->cmn_ldo_cntrl;
807 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_LDO_CNTRL, data);
808
809 pll_db_commit_common(pll, pdb);
810
811 /* de assert pll start and apply pll sw reset */
812 /* stop pll */
813 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0);
814
815 /* pll sw reset */
816 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, 0x20);
817 wmb(); /* make sure register committed */
818 udelay(10);
819
820 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, 0);
821 wmb(); /* make sure register committed */
822
823 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_VCO_TUNE, 0);
824 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_CODE, 0);
825 wmb(); /* make sure register committed */
826
827 data = pdb->in.dsiclk_sel; /* set dsiclk_sel = 1 */
828 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CLK_CFG1, data);
829
830 data = 0xff; /* data, clk, pll normal operation */
831 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_0, data);
832
833 /* configure the frequency dependent pll registers */
834 data = pout->dec_start;
835 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DEC_START, data);
836
837 data = pout->div_frac_start;
838 data &= 0x0ff;
839 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START1, data);
840 data = (pout->div_frac_start >> 8);
841 data &= 0x0ff;
842 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START2, data);
843 data = (pout->div_frac_start >> 16);
844 data &= 0x0f;
845 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START3, data);
846
847 data = pout->plllock_cmp;
848 data &= 0x0ff;
849 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP1, data);
850 data = (pout->plllock_cmp >> 8);
851 data &= 0x0ff;
852 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP2, data);
853 data = (pout->plllock_cmp >> 16);
854 data &= 0x03;
855 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP3, data);
856
857 data = ((pin->plllock_cnt << 1) | (pin->plllock_rng << 3));
858 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP_EN, data);
859
860 data = pout->pll_vco_count;
861 data &= 0x0ff;
862 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_COUNT1, data);
863 data = (pout->pll_vco_count >> 8);
864 data &= 0x0ff;
865 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_COUNT2, data);
866
867 data = pout->pll_kvco_count;
868 data &= 0x0ff;
869 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_COUNT1, data);
870 data = (pout->pll_kvco_count >> 8);
871 data &= 0x03;
872 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_COUNT2, data);
873
874 data = (((pout->pll_postdiv - 1) << 4) | pdb->in.pll_lpf_res1);
875 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF2_POSTDIV, data);
876
877 data = pout->pll_kvco_code;
878 MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_CODE, data);
879 pr_debug("kvco_code:0x%x\n", data);
880
881 data = (pout->pll_n1div | (pout->pll_n2div << 4));
882 MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CLK_CFG0, data);
883
884 if (pll->ssc_en)
885 pll_db_commit_ssc(pll, pdb);
886
887 pr_debug("pll:%d\n", pll->index);
888 wmb(); /* make sure register committed */
889}
890
891/*
892 * pll_source_finding:
893 * Both GLBL_TEST_CTRL and CLKBUFLR_EN are configured
894 * at mdss_dsi_8996_phy_config()
895 */
896static int pll_source_finding(struct mdss_pll_resources *pll)
897{
898 u32 clk_buf_en;
899 u32 glbl_test_ctrl;
900
901 glbl_test_ctrl = MDSS_PLL_REG_R(pll->pll_base,
902 DSIPHY_CMN_GLBL_TEST_CTRL);
903 clk_buf_en = MDSS_PLL_REG_R(pll->pll_base,
904 DSIPHY_PLL_CLKBUFLR_EN);
905
906 glbl_test_ctrl &= BIT(2);
907 glbl_test_ctrl >>= 2;
908
909 pr_debug("%s: pll=%d clk_buf_en=%x glbl_test_ctrl=%x\n",
910 __func__, pll->index, clk_buf_en, glbl_test_ctrl);
911
912 clk_buf_en &= (PLL_OUTPUT_RIGHT | PLL_OUTPUT_LEFT);
913
914 if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) &&
915 (clk_buf_en == PLL_OUTPUT_BOTH))
916 return PLL_MASTER;
917
918 if ((glbl_test_ctrl == PLL_SOURCE_FROM_RIGHT) &&
919 (clk_buf_en == PLL_OUTPUT_NONE))
920 return PLL_SLAVE;
921
922 if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) &&
923 (clk_buf_en == PLL_OUTPUT_RIGHT))
924 return PLL_STANDALONE;
925
926 pr_debug("%s: Error pll setup, clk_buf_en=%x glbl_test_ctrl=%x\n",
927 __func__, clk_buf_en, glbl_test_ctrl);
928
929 return PLL_UNKNOWN;
930}
931
932static void pll_source_setup(struct mdss_pll_resources *pll)
933{
934 int status;
935 struct dsi_pll_db *pdb = (struct dsi_pll_db *)pll->priv;
936 struct mdss_pll_resources *other;
937
938 if (pdb->source_setup_done)
939 return;
940
941 pdb->source_setup_done++;
942
943 status = pll_source_finding(pll);
944
945 if (status == PLL_STANDALONE || status == PLL_UNKNOWN)
946 return;
947
948 other = pdb->next->pll;
949 if (!other)
950 return;
951
952 pr_debug("%s: status=%d pll=%d other=%d\n", __func__,
953 status, pll->index, other->index);
954
955 if (status == PLL_MASTER)
956 pll->slave = other;
957 else
958 other->slave = pll;
959}
960
961int pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
962{
963 int rc;
964 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
965 struct mdss_pll_resources *pll = vco->priv;
966 struct mdss_pll_resources *slave;
967 struct dsi_pll_db *pdb;
968
969 pdb = (struct dsi_pll_db *)pll->priv;
970 if (!pdb) {
971 pr_err("No prov found\n");
972 return -EINVAL;
973 }
974
975 rc = mdss_pll_resource_enable(pll, true);
976 if (rc) {
977 pr_err("Failed to enable mdss dsi plla=%d\n", pll->index);
978 return rc;
979 }
980
981 pll_source_setup(pll);
982
983 pr_debug("%s: ndx=%d base=%pk rate=%lu slave=%pk\n", __func__,
984 pll->index, pll->pll_base, rate, pll->slave);
985
986 pll->vco_current_rate = rate;
987 pll->vco_ref_clk_rate = vco->ref_clk_rate;
988
989 mdss_dsi_pll_8996_input_init(pll, pdb);
990 /*
991 * tx_band = pll_postdiv
992 * 0: divided by 1 <== for now
993 * 1: divided by 2
994 * 2: divided by 4
995 * 3: divided by 8
996 */
997 pdb->out.pll_postdiv = DSI_PLL_DEFAULT_POSTDIV;
998
999 pll_8996_dec_frac_calc(pll, pdb);
1000
1001 if (pll->ssc_en)
1002 pll_8996_ssc_calc(pll, pdb);
1003
1004 pll_8996_calc_vco_count(pdb, pll->vco_current_rate,
1005 pll->vco_ref_clk_rate);
1006
1007 /* precal sequence, only for the master */
1008 if (pll_precal_commit_8996(pll, pdb)) {
1009 pr_debug("retry full sequence\n");
1010 slave = pll->slave;
1011
1012 /* commit slave if split display is enabled */
1013 if (slave)
1014 pll_db_commit_8996(slave, pdb);
1015
1016 /* commit master itself */
1017 pll_db_commit_8996(pll, pdb);
1018 }
1019
1020 mdss_pll_resource_enable(pll, false);
1021
1022 return rc;
1023}
1024
1025static void shadow_pll_dynamic_refresh_8996(struct mdss_pll_resources *pll,
1026 struct dsi_pll_db *pdb, int *pll_trim_codes)
1027{
1028 struct dsi_pll_output *pout = &pdb->out;
1029
1030 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1031 DSI_DYNAMIC_REFRESH_PLL_CTRL20,
1032 DSIPHY_CMN_CTRL_0, DSIPHY_PLL_SYSCLK_EN_RESET,
1033 0xFF, 0x0);
1034 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1035 DSI_DYNAMIC_REFRESH_PLL_CTRL21,
1036 DSIPHY_PLL_DEC_START, DSIPHY_PLL_DIV_FRAC_START1,
1037 pout->dec_start, (pout->div_frac_start & 0x0FF));
1038 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1039 DSI_DYNAMIC_REFRESH_PLL_CTRL22,
1040 DSIPHY_PLL_DIV_FRAC_START2, DSIPHY_PLL_DIV_FRAC_START3,
1041 ((pout->div_frac_start >> 8) & 0x0FF),
1042 ((pout->div_frac_start >> 16) & 0x0F));
1043 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1044 DSI_DYNAMIC_REFRESH_PLL_CTRL23,
1045 DSIPHY_PLL_PLLLOCK_CMP1, DSIPHY_PLL_PLLLOCK_CMP2,
1046 (pout->plllock_cmp & 0x0FF),
1047 ((pout->plllock_cmp >> 8) & 0x0FF));
1048 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1049 DSI_DYNAMIC_REFRESH_PLL_CTRL24,
1050 DSIPHY_PLL_PLLLOCK_CMP3, DSIPHY_PLL_PLL_VCO_TUNE,
1051 ((pout->plllock_cmp >> 16) & 0x03),
1052 (pll_trim_codes[1] | BIT(7))); /* VCO tune*/
1053 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1054 DSI_DYNAMIC_REFRESH_PLL_CTRL25,
1055 DSIPHY_PLL_KVCO_CODE, DSIPHY_PLL_RESETSM_CNTRL,
1056 (pll_trim_codes[0] | BIT(5)), 0x38);
1057 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1058 DSI_DYNAMIC_REFRESH_PLL_CTRL26,
1059 DSIPHY_PLL_PLL_LPF2_POSTDIV, DSIPHY_CMN_PLL_CNTRL,
1060 (((pout->pll_postdiv - 1) << 4) | pdb->in.pll_lpf_res1), 0x01);
1061 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1062 DSI_DYNAMIC_REFRESH_PLL_CTRL27,
1063 DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL,
1064 0x01, 0x01);
1065 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1066 DSI_DYNAMIC_REFRESH_PLL_CTRL28,
1067 DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL,
1068 0x01, 0x01);
1069 MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
1070 DSI_DYNAMIC_REFRESH_PLL_CTRL29,
1071 DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL,
1072 0x01, 0x01);
1073 MDSS_PLL_REG_W(pll->dyn_pll_base,
1074 DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR, 0x0000001E);
1075 MDSS_PLL_REG_W(pll->dyn_pll_base,
1076 DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2, 0x001FFE00);
1077
1078 pr_debug("core_kvco_code=0x%x core_vco_tune=0x%x\n",
1079 pll_trim_codes[0], pll_trim_codes[1]);
1080
1081 /*
1082 * Ensure all the dynamic refresh registers are written before
1083 * dynamic refresh to change the fps is triggered
1084 */
1085 wmb();
1086}
1087
1088int shadow_pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
1089{
1090 int rc;
1091 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
1092 struct mdss_pll_resources *pll = vco->priv;
1093 struct dsi_pll_db *pdb;
1094 s64 vco_clk_rate = (s64)rate;
1095 int pll_trim_codes[2];
1096
1097 if (!pll) {
1098 pr_err("PLL data not found\n");
1099 return -EINVAL;
1100 }
1101
1102 pdb = pll->priv;
1103 if (!pdb) {
1104 pr_err("No priv data found\n");
1105 return -EINVAL;
1106 }
1107
1108 rc = mdss_pll_read_stored_trim_codes(pll, vco_clk_rate, pll_trim_codes);
1109 if (rc) {
1110 pr_err("cannot find pll codes rate=%lld\n", vco_clk_rate);
1111 return -EINVAL;
1112 }
1113
1114 rc = mdss_pll_resource_enable(pll, true);
1115 if (rc) {
1116 pr_err("Failed to enable mdss dsi plla=%d\n", pll->index);
1117 return rc;
1118 }
1119
1120 pr_debug("%s: ndx=%d base=%pk rate=%lu\n", __func__,
1121 pll->index, pll->pll_base, rate);
1122
1123 pll->vco_current_rate = rate;
1124 pll->vco_ref_clk_rate = vco->ref_clk_rate;
1125
1126 mdss_dsi_pll_8996_input_init(pll, pdb);
1127
1128 pll_8996_dec_frac_calc(pll, pdb);
1129
1130 pll_8996_calc_vco_count(pdb, pll->vco_current_rate,
1131 pll->vco_ref_clk_rate);
1132
1133 shadow_pll_dynamic_refresh_8996(pll, pdb, pll_trim_codes);
1134
1135 rc = mdss_pll_resource_enable(pll, false);
1136 if (rc) {
1137 pr_err("Failed to enable mdss dsi plla=%d\n", pll->index);
1138 return rc;
1139 }
1140
1141 return rc;
1142}
1143
1144unsigned long pll_vco_get_rate_8996(struct clk *c)
1145{
1146 u64 vco_rate, multiplier = BIT(20);
1147 s32 div_frac_start;
1148 u32 dec_start;
1149 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
1150 u64 ref_clk = vco->ref_clk_rate;
1151 int rc;
1152 struct mdss_pll_resources *pll = vco->priv;
1153
1154 if (is_gdsc_disabled(pll))
1155 return 0;
1156
1157 rc = mdss_pll_resource_enable(pll, true);
1158 if (rc) {
1159 pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
1160 return rc;
1161 }
1162
1163 dec_start = MDSS_PLL_REG_R(pll->pll_base,
1164 DSIPHY_PLL_DEC_START);
1165 dec_start &= 0x0ff;
1166 pr_debug("dec_start = 0x%x\n", dec_start);
1167
1168 div_frac_start = (MDSS_PLL_REG_R(pll->pll_base,
1169 DSIPHY_PLL_DIV_FRAC_START3) & 0x0f) << 16;
1170 div_frac_start |= (MDSS_PLL_REG_R(pll->pll_base,
1171 DSIPHY_PLL_DIV_FRAC_START2) & 0x0ff) << 8;
1172 div_frac_start |= MDSS_PLL_REG_R(pll->pll_base,
1173 DSIPHY_PLL_DIV_FRAC_START1) & 0x0ff;
1174 pr_debug("div_frac_start = 0x%x\n", div_frac_start);
1175
1176 vco_rate = ref_clk * dec_start;
1177 vco_rate += ((ref_clk * div_frac_start) / multiplier);
1178
1179 pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);
1180
1181 mdss_pll_resource_enable(pll, false);
1182
1183 return (unsigned long)vco_rate;
1184}
1185
1186long pll_vco_round_rate_8996(struct clk *c, unsigned long rate)
1187{
1188 unsigned long rrate = rate;
1189 u32 div;
1190 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
1191
1192 div = vco->min_rate / rate;
1193 if (div > 15) {
1194 /* rate < 86.67 Mhz */
1195 pr_err("rate=%lu NOT supportted\n", rate);
1196 return -EINVAL;
1197 }
1198
1199 if (rate < vco->min_rate)
1200 rrate = vco->min_rate;
1201 if (rate > vco->max_rate)
1202 rrate = vco->max_rate;
1203
1204 return rrate;
1205}
1206
1207enum handoff pll_vco_handoff_8996(struct clk *c)
1208{
1209 int rc;
1210 enum handoff ret = HANDOFF_DISABLED_CLK;
1211 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
1212 struct mdss_pll_resources *pll = vco->priv;
1213
1214 if (is_gdsc_disabled(pll))
1215 return HANDOFF_DISABLED_CLK;
1216
1217 rc = mdss_pll_resource_enable(pll, true);
1218 if (rc) {
1219 pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
1220 return ret;
1221 }
1222
1223 if (pll_is_pll_locked_8996(pll)) {
1224 pll->handoff_resources = true;
1225 pll->pll_on = true;
1226 c->rate = pll_vco_get_rate_8996(c);
1227 ret = HANDOFF_ENABLED_CLK;
1228 } else {
1229 mdss_pll_resource_enable(pll, false);
1230 }
1231
1232 return ret;
1233}
1234
1235enum handoff shadow_pll_vco_handoff_8996(struct clk *c)
1236{
1237 return HANDOFF_DISABLED_CLK;
1238}
1239
1240int pll_vco_prepare_8996(struct clk *c)
1241{
1242 int rc = 0;
1243 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
1244 struct mdss_pll_resources *pll = vco->priv;
1245
1246 if (!pll) {
1247 pr_err("Dsi pll resources are not available\n");
1248 return -EINVAL;
1249 }
1250
1251 rc = mdss_pll_resource_enable(pll, true);
1252 if (rc) {
1253 pr_err("ndx=%d Failed to enable mdss dsi pll resources\n",
1254 pll->index);
1255 return rc;
1256 }
1257
1258 if ((pll->vco_cached_rate != 0)
1259 && (pll->vco_cached_rate == c->rate)) {
1260 rc = c->ops->set_rate(c, pll->vco_cached_rate);
1261 if (rc) {
1262 pr_err("index=%d vco_set_rate failed. rc=%d\n",
1263 rc, pll->index);
1264 mdss_pll_resource_enable(pll, false);
1265 goto error;
1266 }
1267 }
1268
1269 rc = dsi_pll_enable(c);
1270
1271 if (rc) {
1272 mdss_pll_resource_enable(pll, false);
1273 pr_err("ndx=%d failed to enable dsi pll\n", pll->index);
1274 }
1275
1276error:
1277 return rc;
1278}
1279
1280void pll_vco_unprepare_8996(struct clk *c)
1281{
1282 struct dsi_pll_vco_clk *vco = to_vco_clk(c);
1283 struct mdss_pll_resources *pll = vco->priv;
1284
1285 if (!pll) {
1286 pr_err("Dsi pll resources are not available\n");
1287 return;
1288 }
1289
1290 pll->vco_cached_rate = c->rate;
1291 dsi_pll_disable(c);
1292}