drm/msm/dsi: Add DSI PLL clock driver support
[deliverable/linux.git] / drivers / gpu / drm / msm / dsi / pll / dsi_pll_28nm.c
1 /*
2 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
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
14 #include <linux/clk.h>
15 #include <linux/clk-provider.h>
16
17 #include "dsi_pll.h"
18 #include "dsi.xml.h"
19
20 /*
21 * DSI PLL 28nm - clock diagram (eg: DSI0):
22 *
23 * dsi0analog_postdiv_clk
24 * | dsi0indirect_path_div2_clk
25 * | |
26 * +------+ | +----+ | |\ dsi0byte_mux
27 * dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \ |
28 * | +------+ +----+ | m| | +----+
29 * | | u|--o--| /4 |-- dsi0pllbyte
30 * | | x| +----+
31 * o--------------------------| /
32 * | |/
33 * | +------+
34 * o----------| DIV3 |------------------------- dsi0pll
35 * +------+
36 */
37
38 #define POLL_MAX_READS 10
39 #define POLL_TIMEOUT_US 50
40
41 #define NUM_PROVIDED_CLKS 2
42
43 #define VCO_REF_CLK_RATE 19200000
44 #define VCO_MIN_RATE 350000000
45 #define VCO_MAX_RATE 750000000
46
47 #define DSI_BYTE_PLL_CLK 0
48 #define DSI_PIXEL_PLL_CLK 1
49
50 #define LPFR_LUT_SIZE 10
51 struct lpfr_cfg {
52 unsigned long vco_rate;
53 u32 resistance;
54 };
55
56 /* Loop filter resistance: */
57 static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = {
58 { 479500000, 8 },
59 { 480000000, 11 },
60 { 575500000, 8 },
61 { 576000000, 12 },
62 { 610500000, 8 },
63 { 659500000, 9 },
64 { 671500000, 10 },
65 { 672000000, 14 },
66 { 708500000, 10 },
67 { 750000000, 11 },
68 };
69
70 struct pll_28nm_cached_state {
71 unsigned long vco_rate;
72 u8 postdiv3;
73 u8 postdiv1;
74 u8 byte_mux;
75 };
76
77 struct dsi_pll_28nm {
78 struct msm_dsi_pll base;
79
80 int id;
81 struct platform_device *pdev;
82 void __iomem *mmio;
83
84 int vco_delay;
85
86 /* private clocks: */
87 struct clk *clks[NUM_DSI_CLOCKS_MAX];
88 u32 num_clks;
89
90 /* clock-provider: */
91 struct clk *provided_clks[NUM_PROVIDED_CLKS];
92 struct clk_onecell_data clk_data;
93
94 struct pll_28nm_cached_state cached_state;
95 };
96
97 #define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base)
98
99 static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
100 u32 nb_tries, u32 timeout_us)
101 {
102 bool pll_locked = false;
103 u32 val;
104
105 while (nb_tries--) {
106 val = pll_read(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_STATUS);
107 pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY);
108
109 if (pll_locked)
110 break;
111
112 udelay(timeout_us);
113 }
114 DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
115
116 return pll_locked;
117 }
118
119 static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm)
120 {
121 void __iomem *base = pll_28nm->mmio;
122
123 /*
124 * Add HW recommended delays after toggling the software
125 * reset bit off and back on.
126 */
127 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG,
128 DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, 1);
129 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, 0x00, 1);
130 }
131
132 /*
133 * Clock Callbacks
134 */
135 static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
136 unsigned long parent_rate)
137 {
138 struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
139 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
140 struct device *dev = &pll_28nm->pdev->dev;
141 void __iomem *base = pll_28nm->mmio;
142 unsigned long div_fbx1000, gen_vco_clk;
143 u32 refclk_cfg, frac_n_mode, frac_n_value;
144 u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3;
145 u32 cal_cfg10, cal_cfg11;
146 u32 rem;
147 int i;
148
149 VERB("rate=%lu, parent's=%lu", rate, parent_rate);
150
151 /* Force postdiv2 to be div-4 */
152 pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3);
153
154 /* Configure the Loop filter resistance */
155 for (i = 0; i < LPFR_LUT_SIZE; i++)
156 if (rate <= lpfr_lut[i].vco_rate)
157 break;
158 if (i == LPFR_LUT_SIZE) {
159 dev_err(dev, "unable to get loop filter resistance. vco=%lu\n",
160 rate);
161 return -EINVAL;
162 }
163 pll_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance);
164
165 /* Loop filter capacitance values : c1 and c2 */
166 pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70);
167 pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15);
168
169 rem = rate % VCO_REF_CLK_RATE;
170 if (rem) {
171 refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
172 frac_n_mode = 1;
173 div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500);
174 gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500);
175 } else {
176 refclk_cfg = 0x0;
177 frac_n_mode = 0;
178 div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000);
179 gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000);
180 }
181
182 DBG("refclk_cfg = %d", refclk_cfg);
183
184 rem = div_fbx1000 % 1000;
185 frac_n_value = (rem << 16) / 1000;
186
187 DBG("div_fb = %lu", div_fbx1000);
188 DBG("frac_n_value = %d", frac_n_value);
189
190 DBG("Generated VCO Clock: %lu", gen_vco_clk);
191 rem = 0;
192 sdm_cfg1 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1);
193 sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK;
194 if (frac_n_mode) {
195 sdm_cfg0 = 0x0;
196 sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0);
197 sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(
198 (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
199 sdm_cfg3 = frac_n_value >> 8;
200 sdm_cfg2 = frac_n_value & 0xff;
201 } else {
202 sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP;
203 sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(
204 (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
205 sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0);
206 sdm_cfg2 = 0;
207 sdm_cfg3 = 0;
208 }
209
210 DBG("sdm_cfg0=%d", sdm_cfg0);
211 DBG("sdm_cfg1=%d", sdm_cfg1);
212 DBG("sdm_cfg2=%d", sdm_cfg2);
213 DBG("sdm_cfg3=%d", sdm_cfg3);
214
215 cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000));
216 cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000);
217 DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11);
218
219 pll_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02);
220 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3, 0x2b);
221 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4, 0x06);
222 pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d);
223
224 pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1);
225 pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2,
226 DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2));
227 pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3,
228 DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3));
229 pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00);
230
231 /* Add hardware recommended delay for correct PLL configuration */
232 if (pll_28nm->vco_delay)
233 udelay(pll_28nm->vco_delay);
234
235 pll_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg);
236 pll_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00);
237 pll_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31);
238 pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0, sdm_cfg0);
239 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0, 0x12);
240 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6, 0x30);
241 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7, 0x00);
242 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8, 0x60);
243 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9, 0x00);
244 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10, cal_cfg10 & 0xff);
245 pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11, cal_cfg11 & 0xff);
246 pll_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG, 0x20);
247
248 return 0;
249 }
250
251 static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
252 {
253 struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
254 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
255
256 return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
257 POLL_TIMEOUT_US);
258 }
259
260 static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
261 unsigned long parent_rate)
262 {
263 struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
264 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
265 void __iomem *base = pll_28nm->mmio;
266 u32 sdm0, doubler, sdm_byp_div;
267 u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3;
268 u32 ref_clk = VCO_REF_CLK_RATE;
269 unsigned long vco_rate;
270
271 VERB("parent_rate=%lu", parent_rate);
272
273 /* Check to see if the ref clk doubler is enabled */
274 doubler = pll_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) &
275 DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
276 ref_clk += (doubler * VCO_REF_CLK_RATE);
277
278 /* see if it is integer mode or sdm mode */
279 sdm0 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0);
280 if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) {
281 /* integer mode */
282 sdm_byp_div = FIELD(
283 pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0),
284 DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1;
285 vco_rate = ref_clk * sdm_byp_div;
286 } else {
287 /* sdm mode */
288 sdm_dc_off = FIELD(
289 pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1),
290 DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET);
291 DBG("sdm_dc_off = %d", sdm_dc_off);
292 sdm2 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2),
293 DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0);
294 sdm3 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3),
295 DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8);
296 sdm_freq_seed = (sdm3 << 8) | sdm2;
297 DBG("sdm_freq_seed = %d", sdm_freq_seed);
298
299 vco_rate = (ref_clk * (sdm_dc_off + 1)) +
300 mult_frac(ref_clk, sdm_freq_seed, BIT(16));
301 DBG("vco rate = %lu", vco_rate);
302 }
303
304 DBG("returning vco rate = %lu", vco_rate);
305
306 return vco_rate;
307 }
308
309 static const struct clk_ops clk_ops_dsi_pll_28nm_vco = {
310 .round_rate = msm_dsi_pll_helper_clk_round_rate,
311 .set_rate = dsi_pll_28nm_clk_set_rate,
312 .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
313 .prepare = msm_dsi_pll_helper_clk_prepare,
314 .unprepare = msm_dsi_pll_helper_clk_unprepare,
315 .is_enabled = dsi_pll_28nm_clk_is_enabled,
316 };
317
318 /*
319 * PLL Callbacks
320 */
321 static int dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll)
322 {
323 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
324 struct device *dev = &pll_28nm->pdev->dev;
325 void __iomem *base = pll_28nm->mmio;
326 u32 max_reads = 5, timeout_us = 100;
327 bool locked;
328 u32 val;
329 int i;
330
331 DBG("id=%d", pll_28nm->id);
332
333 pll_28nm_software_reset(pll_28nm);
334
335 /*
336 * PLL power up sequence.
337 * Add necessary delays recommended by hardware.
338 */
339 val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
340 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
341
342 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
343 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
344
345 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
346 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
347
348 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
349 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
350
351 for (i = 0; i < 2; i++) {
352 /* DSI Uniphy lock detect setting */
353 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,
354 0x0c, 100);
355 pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d);
356
357 /* poll for PLL ready status */
358 locked = pll_28nm_poll_for_ready(pll_28nm,
359 max_reads, timeout_us);
360 if (locked)
361 break;
362
363 pll_28nm_software_reset(pll_28nm);
364
365 /*
366 * PLL power up sequence.
367 * Add necessary delays recommended by hardware.
368 */
369 val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
370 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
371
372 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
373 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
374
375 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
376 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 250);
377
378 val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
379 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
380
381 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
382 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
383
384 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
385 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
386 }
387
388 if (unlikely(!locked))
389 dev_err(dev, "DSI PLL lock failed\n");
390 else
391 DBG("DSI PLL Lock success");
392
393 return locked ? 0 : -EINVAL;
394 }
395
396 static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll)
397 {
398 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
399 struct device *dev = &pll_28nm->pdev->dev;
400 void __iomem *base = pll_28nm->mmio;
401 bool locked;
402 u32 max_reads = 10, timeout_us = 50;
403 u32 val;
404
405 DBG("id=%d", pll_28nm->id);
406
407 pll_28nm_software_reset(pll_28nm);
408
409 /*
410 * PLL power up sequence.
411 * Add necessary delays recommended by hardware.
412 */
413 pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34, 500);
414
415 val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
416 pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
417
418 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
419 pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
420
421 val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B |
422 DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
423 pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
424
425 /* DSI PLL toggle lock detect setting */
426 pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x04, 500);
427 pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x05, 512);
428
429 locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
430
431 if (unlikely(!locked))
432 dev_err(dev, "DSI PLL lock failed\n");
433 else
434 DBG("DSI PLL lock success");
435
436 return locked ? 0 : -EINVAL;
437 }
438
439 static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll)
440 {
441 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
442
443 DBG("id=%d", pll_28nm->id);
444 pll_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00);
445 }
446
447 static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll)
448 {
449 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
450 struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
451 void __iomem *base = pll_28nm->mmio;
452
453 cached_state->postdiv3 =
454 pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG);
455 cached_state->postdiv1 =
456 pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG);
457 cached_state->byte_mux = pll_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG);
458 cached_state->vco_rate = __clk_get_rate(pll->clk_hw.clk);
459 }
460
461 static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll)
462 {
463 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
464 struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
465 void __iomem *base = pll_28nm->mmio;
466 int ret;
467
468 if ((cached_state->vco_rate != 0) &&
469 (cached_state->vco_rate == __clk_get_rate(pll->clk_hw.clk))) {
470 ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw,
471 cached_state->vco_rate, 0);
472 if (ret) {
473 dev_err(&pll_28nm->pdev->dev,
474 "restore vco rate failed. ret=%d\n", ret);
475 return ret;
476 }
477
478 pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
479 cached_state->postdiv3);
480 pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
481 cached_state->postdiv1);
482 pll_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG,
483 cached_state->byte_mux);
484
485 cached_state->vco_rate = 0;
486 }
487
488 return 0;
489 }
490
491 static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll,
492 struct clk **byte_clk_provider,
493 struct clk **pixel_clk_provider)
494 {
495 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
496
497 if (byte_clk_provider)
498 *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK];
499 if (pixel_clk_provider)
500 *pixel_clk_provider =
501 pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK];
502
503 return 0;
504 }
505
506 static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll)
507 {
508 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
509 int i;
510
511 msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev,
512 pll_28nm->clks, pll_28nm->num_clks);
513
514 for (i = 0; i < NUM_PROVIDED_CLKS; i++)
515 pll_28nm->provided_clks[i] = NULL;
516
517 pll_28nm->num_clks = 0;
518 pll_28nm->clk_data.clks = NULL;
519 pll_28nm->clk_data.clk_num = 0;
520 }
521
522 static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm)
523 {
524 char clk_name[32], parent1[32], parent2[32], vco_name[32];
525 struct clk_init_data vco_init = {
526 .parent_names = (const char *[]){ "xo" },
527 .num_parents = 1,
528 .name = vco_name,
529 .ops = &clk_ops_dsi_pll_28nm_vco,
530 };
531 struct device *dev = &pll_28nm->pdev->dev;
532 struct clk **clks = pll_28nm->clks;
533 struct clk **provided_clks = pll_28nm->provided_clks;
534 int num = 0;
535 int ret;
536
537 DBG("%d", pll_28nm->id);
538
539 snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id);
540 pll_28nm->base.clk_hw.init = &vco_init;
541 clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw);
542
543 snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->id);
544 snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
545 clks[num++] = clk_register_divider(dev, clk_name,
546 parent1, CLK_SET_RATE_PARENT,
547 pll_28nm->mmio +
548 REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
549 0, 4, 0, NULL);
550
551 snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id);
552 snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->id);
553 clks[num++] = clk_register_fixed_factor(dev, clk_name,
554 parent1, CLK_SET_RATE_PARENT,
555 1, 2);
556
557 snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id);
558 snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
559 clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] =
560 clk_register_divider(dev, clk_name,
561 parent1, 0, pll_28nm->mmio +
562 REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
563 0, 8, 0, NULL);
564
565 snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->id);
566 snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
567 snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id);
568 clks[num++] = clk_register_mux(dev, clk_name,
569 (const char *[]){
570 parent1, parent2
571 }, 2, CLK_SET_RATE_PARENT, pll_28nm->mmio +
572 REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL);
573
574 snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id);
575 snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->id);
576 clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] =
577 clk_register_fixed_factor(dev, clk_name,
578 parent1, CLK_SET_RATE_PARENT, 1, 4);
579
580 pll_28nm->num_clks = num;
581
582 pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS;
583 pll_28nm->clk_data.clks = provided_clks;
584
585 ret = of_clk_add_provider(dev->of_node,
586 of_clk_src_onecell_get, &pll_28nm->clk_data);
587 if (ret) {
588 dev_err(dev, "failed to register clk provider: %d\n", ret);
589 return ret;
590 }
591
592 return 0;
593 }
594
595 struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev,
596 enum msm_dsi_phy_type type, int id)
597 {
598 struct dsi_pll_28nm *pll_28nm;
599 struct msm_dsi_pll *pll;
600 int ret;
601
602 if (!pdev)
603 return ERR_PTR(-ENODEV);
604
605 pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
606 if (!pll_28nm)
607 return ERR_PTR(-ENOMEM);
608
609 pll_28nm->pdev = pdev;
610 pll_28nm->id = id;
611
612 pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
613 if (IS_ERR_OR_NULL(pll_28nm->mmio)) {
614 dev_err(&pdev->dev, "%s: failed to map pll base\n", __func__);
615 return ERR_PTR(-ENOMEM);
616 }
617
618 pll = &pll_28nm->base;
619 pll->min_rate = VCO_MIN_RATE;
620 pll->max_rate = VCO_MAX_RATE;
621 pll->get_provider = dsi_pll_28nm_get_provider;
622 pll->destroy = dsi_pll_28nm_destroy;
623 pll->disable_seq = dsi_pll_28nm_disable_seq;
624 pll->save_state = dsi_pll_28nm_save_state;
625 pll->restore_state = dsi_pll_28nm_restore_state;
626
627 if (type == MSM_DSI_PHY_28NM_HPM) {
628 pll_28nm->vco_delay = 1;
629
630 pll->en_seq_cnt = 3;
631 pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_hpm;
632 pll->enable_seqs[1] = dsi_pll_28nm_enable_seq_hpm;
633 pll->enable_seqs[2] = dsi_pll_28nm_enable_seq_hpm;
634 } else if (type == MSM_DSI_PHY_28NM_LP) {
635 pll_28nm->vco_delay = 1000;
636
637 pll->en_seq_cnt = 1;
638 pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_lp;
639 } else {
640 dev_err(&pdev->dev, "phy type (%d) is not 28nm\n", type);
641 return ERR_PTR(-EINVAL);
642 }
643
644 ret = pll_28nm_register(pll_28nm);
645 if (ret) {
646 dev_err(&pdev->dev, "failed to register PLL: %d\n", ret);
647 return ERR_PTR(ret);
648 }
649
650 return pll;
651 }
652
This page took 0.046598 seconds and 5 git commands to generate.