Loading...
1/*
2 * Copyright (c) 2016, 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-provider.h>
15
16#include "hdmi.h"
17
18#define HDMI_VCO_MAX_FREQ 12000000000UL
19#define HDMI_VCO_MIN_FREQ 8000000000UL
20
21#define HDMI_PCLK_MAX_FREQ 600000000
22#define HDMI_PCLK_MIN_FREQ 25000000
23
24#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL
25#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL
26#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000UL
27#define HDMI_CORECLK_DIV 5
28#define HDMI_DEFAULT_REF_CLOCK 19200000
29#define HDMI_PLL_CMP_CNT 1024
30
31#define HDMI_PLL_POLL_MAX_READS 100
32#define HDMI_PLL_POLL_TIMEOUT_US 150
33
34#define HDMI_NUM_TX_CHANNEL 4
35
36struct hdmi_pll_8996 {
37 struct platform_device *pdev;
38 struct clk_hw clk_hw;
39
40 /* pll mmio base */
41 void __iomem *mmio_qserdes_com;
42 /* tx channel base */
43 void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL];
44};
45
46#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8996, clk_hw)
47
48struct hdmi_8996_phy_pll_reg_cfg {
49 u32 tx_lx_lane_mode[HDMI_NUM_TX_CHANNEL];
50 u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL];
51 u32 com_svs_mode_clk_sel;
52 u32 com_hsclk_sel;
53 u32 com_pll_cctrl_mode0;
54 u32 com_pll_rctrl_mode0;
55 u32 com_cp_ctrl_mode0;
56 u32 com_dec_start_mode0;
57 u32 com_div_frac_start1_mode0;
58 u32 com_div_frac_start2_mode0;
59 u32 com_div_frac_start3_mode0;
60 u32 com_integloop_gain0_mode0;
61 u32 com_integloop_gain1_mode0;
62 u32 com_lock_cmp_en;
63 u32 com_lock_cmp1_mode0;
64 u32 com_lock_cmp2_mode0;
65 u32 com_lock_cmp3_mode0;
66 u32 com_core_clk_en;
67 u32 com_coreclk_div;
68 u32 com_vco_tune_ctrl;
69
70 u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL];
71 u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL];
72 u32 tx_lx_vmode_ctrl1[HDMI_NUM_TX_CHANNEL];
73 u32 tx_lx_vmode_ctrl2[HDMI_NUM_TX_CHANNEL];
74 u32 tx_lx_res_code_lane_tx[HDMI_NUM_TX_CHANNEL];
75 u32 tx_lx_hp_pd_enables[HDMI_NUM_TX_CHANNEL];
76
77 u32 phy_mode;
78};
79
80struct hdmi_8996_post_divider {
81 u64 vco_freq;
82 int hsclk_divsel;
83 int vco_ratio;
84 int tx_band_sel;
85 int half_rate_mode;
86};
87
88static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8996 *pll)
89{
90 return platform_get_drvdata(pll->pdev);
91}
92
93static inline void hdmi_pll_write(struct hdmi_pll_8996 *pll, int offset,
94 u32 data)
95{
96 msm_writel(data, pll->mmio_qserdes_com + offset);
97}
98
99static inline u32 hdmi_pll_read(struct hdmi_pll_8996 *pll, int offset)
100{
101 return msm_readl(pll->mmio_qserdes_com + offset);
102}
103
104static inline void hdmi_tx_chan_write(struct hdmi_pll_8996 *pll, int channel,
105 int offset, int data)
106{
107 msm_writel(data, pll->mmio_qserdes_tx[channel] + offset);
108}
109
110static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk,
111 bool gen_ssc)
112{
113 if ((frac_start != 0) || gen_ssc)
114 return (11000000 / (ref_clk / 20));
115
116 return 0x23;
117}
118
119static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc)
120{
121 if ((frac_start != 0) || gen_ssc)
122 return 0x16;
123
124 return 0x10;
125}
126
127static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc)
128{
129 if ((frac_start != 0) || gen_ssc)
130 return 0x28;
131
132 return 0x1;
133}
134
135static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk,
136 bool gen_ssc)
137{
138 int digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2;
139 u64 base;
140
141 if ((frac_start != 0) || gen_ssc)
142 base = (64 * ref_clk) / HDMI_DEFAULT_REF_CLOCK;
143 else
144 base = (1022 * ref_clk) / 100;
145
146 base <<= digclk_divsel;
147
148 return (base <= 2046 ? base : 2046);
149}
150
151static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk)
152{
153 u64 dividend = HDMI_PLL_CMP_CNT * fdata;
154 u32 divisor = ref_clk * 10;
155 u32 rem;
156
157 rem = do_div(dividend, divisor);
158 if (rem > (divisor >> 1))
159 dividend++;
160
161 return dividend - 1;
162}
163
164static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk)
165{
166 u64 fdata = ((u64)pll_cmp) * ref_clk * 10;
167
168 do_div(fdata, HDMI_PLL_CMP_CNT);
169
170 return fdata;
171}
172
173static int pll_get_post_div(struct hdmi_8996_post_divider *pd, u64 bclk)
174{
175 int ratio[] = { 2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35 };
176 int hs_divsel[] = { 0, 4, 8, 12, 1, 5, 2, 9, 3, 13, 10, 7, 14, 11, 15 };
177 int tx_band_sel[] = { 0, 1, 2, 3 };
178 u64 vco_freq[60];
179 u64 vco, vco_optimal;
180 int half_rate_mode = 0;
181 int vco_optimal_index, vco_freq_index;
182 int i, j;
183
184retry:
185 vco_optimal = HDMI_VCO_MAX_FREQ;
186 vco_optimal_index = -1;
187 vco_freq_index = 0;
188 for (i = 0; i < 15; i++) {
189 for (j = 0; j < 4; j++) {
190 u32 ratio_mult = ratio[i] << tx_band_sel[j];
191
192 vco = bclk >> half_rate_mode;
193 vco *= ratio_mult;
194 vco_freq[vco_freq_index++] = vco;
195 }
196 }
197
198 for (i = 0; i < 60; i++) {
199 u64 vco_tmp = vco_freq[i];
200
201 if ((vco_tmp >= HDMI_VCO_MIN_FREQ) &&
202 (vco_tmp <= vco_optimal)) {
203 vco_optimal = vco_tmp;
204 vco_optimal_index = i;
205 }
206 }
207
208 if (vco_optimal_index == -1) {
209 if (!half_rate_mode) {
210 half_rate_mode = 1;
211 goto retry;
212 }
213 } else {
214 pd->vco_freq = vco_optimal;
215 pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4];
216 pd->vco_ratio = ratio[vco_optimal_index / 4];
217 pd->hsclk_divsel = hs_divsel[vco_optimal_index / 4];
218
219 return 0;
220 }
221
222 return -EINVAL;
223}
224
225static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk,
226 struct hdmi_8996_phy_pll_reg_cfg *cfg)
227{
228 struct hdmi_8996_post_divider pd;
229 u64 bclk;
230 u64 tmds_clk;
231 u64 dec_start;
232 u64 frac_start;
233 u64 fdata;
234 u32 pll_divisor;
235 u32 rem;
236 u32 cpctrl;
237 u32 rctrl;
238 u32 cctrl;
239 u32 integloop_gain;
240 u32 pll_cmp;
241 int i, ret;
242
243 /* bit clk = 10 * pix_clk */
244 bclk = ((u64)pix_clk) * 10;
245
246 if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
247 tmds_clk = pix_clk >> 2;
248 else
249 tmds_clk = pix_clk;
250
251 ret = pll_get_post_div(&pd, bclk);
252 if (ret)
253 return ret;
254
255 dec_start = pd.vco_freq;
256 pll_divisor = 4 * ref_clk;
257 do_div(dec_start, pll_divisor);
258
259 frac_start = pd.vco_freq * (1 << 20);
260
261 rem = do_div(frac_start, pll_divisor);
262 frac_start -= dec_start * (1 << 20);
263 if (rem > (pll_divisor >> 1))
264 frac_start++;
265
266 cpctrl = pll_get_cpctrl(frac_start, ref_clk, false);
267 rctrl = pll_get_rctrl(frac_start, false);
268 cctrl = pll_get_cctrl(frac_start, false);
269 integloop_gain = pll_get_integloop_gain(frac_start, bclk,
270 ref_clk, false);
271
272 fdata = pd.vco_freq;
273 do_div(fdata, pd.vco_ratio);
274
275 pll_cmp = pll_get_pll_cmp(fdata, ref_clk);
276
277 DBG("VCO freq: %llu", pd.vco_freq);
278 DBG("fdata: %llu", fdata);
279 DBG("pix_clk: %lu", pix_clk);
280 DBG("tmds clk: %llu", tmds_clk);
281 DBG("HSCLK_SEL: %d", pd.hsclk_divsel);
282 DBG("DEC_START: %llu", dec_start);
283 DBG("DIV_FRAC_START: %llu", frac_start);
284 DBG("PLL_CPCTRL: %u", cpctrl);
285 DBG("PLL_RCTRL: %u", rctrl);
286 DBG("PLL_CCTRL: %u", cctrl);
287 DBG("INTEGLOOP_GAIN: %u", integloop_gain);
288 DBG("TX_BAND: %d", pd.tx_band_sel);
289 DBG("PLL_CMP: %u", pll_cmp);
290
291 /* Convert these values to register specific values */
292 if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
293 cfg->com_svs_mode_clk_sel = 1;
294 else
295 cfg->com_svs_mode_clk_sel = 2;
296
297 cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel);
298 cfg->com_pll_cctrl_mode0 = cctrl;
299 cfg->com_pll_rctrl_mode0 = rctrl;
300 cfg->com_cp_ctrl_mode0 = cpctrl;
301 cfg->com_dec_start_mode0 = dec_start;
302 cfg->com_div_frac_start1_mode0 = (frac_start & 0xff);
303 cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8);
304 cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16);
305 cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff);
306 cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8);
307 cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff);
308 cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8);
309 cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
310 cfg->com_lock_cmp_en = 0x0;
311 cfg->com_core_clk_en = 0x2c;
312 cfg->com_coreclk_div = HDMI_CORECLK_DIV;
313 cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
314 cfg->com_vco_tune_ctrl = 0x0;
315
316 cfg->tx_lx_lane_mode[0] =
317 cfg->tx_lx_lane_mode[2] = 0x43;
318
319 cfg->tx_lx_hp_pd_enables[0] =
320 cfg->tx_lx_hp_pd_enables[1] =
321 cfg->tx_lx_hp_pd_enables[2] = 0x0c;
322 cfg->tx_lx_hp_pd_enables[3] = 0x3;
323
324 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
325 cfg->tx_lx_tx_band[i] = pd.tx_band_sel + 4;
326
327 if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
328 cfg->tx_lx_tx_drv_lvl[0] =
329 cfg->tx_lx_tx_drv_lvl[1] =
330 cfg->tx_lx_tx_drv_lvl[2] = 0x25;
331 cfg->tx_lx_tx_drv_lvl[3] = 0x22;
332
333 cfg->tx_lx_tx_emp_post1_lvl[0] =
334 cfg->tx_lx_tx_emp_post1_lvl[1] =
335 cfg->tx_lx_tx_emp_post1_lvl[2] = 0x23;
336 cfg->tx_lx_tx_emp_post1_lvl[3] = 0x27;
337
338 cfg->tx_lx_vmode_ctrl1[0] =
339 cfg->tx_lx_vmode_ctrl1[1] =
340 cfg->tx_lx_vmode_ctrl1[2] =
341 cfg->tx_lx_vmode_ctrl1[3] = 0x00;
342
343 cfg->tx_lx_vmode_ctrl2[0] =
344 cfg->tx_lx_vmode_ctrl2[1] =
345 cfg->tx_lx_vmode_ctrl2[2] = 0x0D;
346
347 cfg->tx_lx_vmode_ctrl2[3] = 0x00;
348 } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
349 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
350 cfg->tx_lx_tx_drv_lvl[i] = 0x25;
351 cfg->tx_lx_tx_emp_post1_lvl[i] = 0x23;
352 cfg->tx_lx_vmode_ctrl1[i] = 0x00;
353 }
354
355 cfg->tx_lx_vmode_ctrl2[0] =
356 cfg->tx_lx_vmode_ctrl2[1] =
357 cfg->tx_lx_vmode_ctrl2[2] = 0x0D;
358 cfg->tx_lx_vmode_ctrl2[3] = 0x00;
359 } else {
360 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
361 cfg->tx_lx_tx_drv_lvl[i] = 0x20;
362 cfg->tx_lx_tx_emp_post1_lvl[i] = 0x20;
363 cfg->tx_lx_vmode_ctrl1[i] = 0x00;
364 cfg->tx_lx_vmode_ctrl2[i] = 0x0E;
365 }
366 }
367
368 DBG("com_svs_mode_clk_sel = 0x%x", cfg->com_svs_mode_clk_sel);
369 DBG("com_hsclk_sel = 0x%x", cfg->com_hsclk_sel);
370 DBG("com_lock_cmp_en = 0x%x", cfg->com_lock_cmp_en);
371 DBG("com_pll_cctrl_mode0 = 0x%x", cfg->com_pll_cctrl_mode0);
372 DBG("com_pll_rctrl_mode0 = 0x%x", cfg->com_pll_rctrl_mode0);
373 DBG("com_cp_ctrl_mode0 = 0x%x", cfg->com_cp_ctrl_mode0);
374 DBG("com_dec_start_mode0 = 0x%x", cfg->com_dec_start_mode0);
375 DBG("com_div_frac_start1_mode0 = 0x%x", cfg->com_div_frac_start1_mode0);
376 DBG("com_div_frac_start2_mode0 = 0x%x", cfg->com_div_frac_start2_mode0);
377 DBG("com_div_frac_start3_mode0 = 0x%x", cfg->com_div_frac_start3_mode0);
378 DBG("com_integloop_gain0_mode0 = 0x%x", cfg->com_integloop_gain0_mode0);
379 DBG("com_integloop_gain1_mode0 = 0x%x", cfg->com_integloop_gain1_mode0);
380 DBG("com_lock_cmp1_mode0 = 0x%x", cfg->com_lock_cmp1_mode0);
381 DBG("com_lock_cmp2_mode0 = 0x%x", cfg->com_lock_cmp2_mode0);
382 DBG("com_lock_cmp3_mode0 = 0x%x", cfg->com_lock_cmp3_mode0);
383 DBG("com_core_clk_en = 0x%x", cfg->com_core_clk_en);
384 DBG("com_coreclk_div = 0x%x", cfg->com_coreclk_div);
385 DBG("phy_mode = 0x%x", cfg->phy_mode);
386
387 DBG("tx_l0_lane_mode = 0x%x", cfg->tx_lx_lane_mode[0]);
388 DBG("tx_l2_lane_mode = 0x%x", cfg->tx_lx_lane_mode[2]);
389
390 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
391 DBG("tx_l%d_tx_band = 0x%x", i, cfg->tx_lx_tx_band[i]);
392 DBG("tx_l%d_tx_drv_lvl = 0x%x", i, cfg->tx_lx_tx_drv_lvl[i]);
393 DBG("tx_l%d_tx_emp_post1_lvl = 0x%x", i,
394 cfg->tx_lx_tx_emp_post1_lvl[i]);
395 DBG("tx_l%d_vmode_ctrl1 = 0x%x", i, cfg->tx_lx_vmode_ctrl1[i]);
396 DBG("tx_l%d_vmode_ctrl2 = 0x%x", i, cfg->tx_lx_vmode_ctrl2[i]);
397 }
398
399 return 0;
400}
401
402static int hdmi_8996_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate,
403 unsigned long parent_rate)
404{
405 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
406 struct hdmi_phy *phy = pll_get_phy(pll);
407 struct hdmi_8996_phy_pll_reg_cfg cfg;
408 int i, ret;
409
410 memset(&cfg, 0x00, sizeof(cfg));
411
412 ret = pll_calculate(rate, parent_rate, &cfg);
413 if (ret) {
414 DRM_ERROR("PLL calculation failed\n");
415 return ret;
416 }
417
418 /* Initially shut down PHY */
419 DBG("Disabling PHY");
420 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x0);
421 udelay(500);
422
423 /* Power up sequence */
424 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x04);
425
426 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1);
427 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20);
428 hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL, 0x0F);
429 hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL, 0x0F);
430
431 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
432 hdmi_tx_chan_write(pll, i,
433 REG_HDMI_PHY_QSERDES_TX_LX_CLKBUF_ENABLE,
434 0x03);
435 hdmi_tx_chan_write(pll, i,
436 REG_HDMI_PHY_QSERDES_TX_LX_TX_BAND,
437 cfg.tx_lx_tx_band[i]);
438 hdmi_tx_chan_write(pll, i,
439 REG_HDMI_PHY_QSERDES_TX_LX_RESET_TSYNC_EN,
440 0x03);
441 }
442
443 hdmi_tx_chan_write(pll, 0, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE,
444 cfg.tx_lx_lane_mode[0]);
445 hdmi_tx_chan_write(pll, 2, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE,
446 cfg.tx_lx_lane_mode[2]);
447
448 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E);
449 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07);
450 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37);
451 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02);
452 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E);
453
454 /* Bypass VCO calibration */
455 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SVS_MODE_CLK_SEL,
456 cfg.com_svs_mode_clk_sel);
457
458 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_TRIM, 0x0F);
459 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_IVCO, 0x0F);
460 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_CTRL,
461 cfg.com_vco_tune_ctrl);
462
463 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x06);
464
465 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_SELECT, 0x30);
466 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_HSCLK_SEL,
467 cfg.com_hsclk_sel);
468 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN,
469 cfg.com_lock_cmp_en);
470
471 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE0,
472 cfg.com_pll_cctrl_mode0);
473 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE0,
474 cfg.com_pll_rctrl_mode0);
475 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE0,
476 cfg.com_cp_ctrl_mode0);
477 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE0,
478 cfg.com_dec_start_mode0);
479 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0,
480 cfg.com_div_frac_start1_mode0);
481 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0,
482 cfg.com_div_frac_start2_mode0);
483 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0,
484 cfg.com_div_frac_start3_mode0);
485
486 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
487 cfg.com_integloop_gain0_mode0);
488 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
489 cfg.com_integloop_gain1_mode0);
490
491 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0,
492 cfg.com_lock_cmp1_mode0);
493 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0,
494 cfg.com_lock_cmp2_mode0);
495 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0,
496 cfg.com_lock_cmp3_mode0);
497
498 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00);
499 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORE_CLK_EN,
500 cfg.com_core_clk_en);
501 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV,
502 cfg.com_coreclk_div);
503 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CMN_CONFIG, 0x02);
504
505 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM, 0x15);
506
507 /* TX lanes setup (TX 0/1/2/3) */
508 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
509 hdmi_tx_chan_write(pll, i,
510 REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL,
511 cfg.tx_lx_tx_drv_lvl[i]);
512 hdmi_tx_chan_write(pll, i,
513 REG_HDMI_PHY_QSERDES_TX_LX_TX_EMP_POST1_LVL,
514 cfg.tx_lx_tx_emp_post1_lvl[i]);
515 hdmi_tx_chan_write(pll, i,
516 REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL1,
517 cfg.tx_lx_vmode_ctrl1[i]);
518 hdmi_tx_chan_write(pll, i,
519 REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL2,
520 cfg.tx_lx_vmode_ctrl2[i]);
521 hdmi_tx_chan_write(pll, i,
522 REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL_OFFSET,
523 0x00);
524 hdmi_tx_chan_write(pll, i,
525 REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET,
526 0x00);
527 hdmi_tx_chan_write(pll, i,
528 REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN,
529 0x03);
530 hdmi_tx_chan_write(pll, i,
531 REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN,
532 0x40);
533 hdmi_tx_chan_write(pll, i,
534 REG_HDMI_PHY_QSERDES_TX_LX_HP_PD_ENABLES,
535 cfg.tx_lx_hp_pd_enables[i]);
536 }
537
538 hdmi_phy_write(phy, REG_HDMI_8996_PHY_MODE, cfg.phy_mode);
539 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1F);
540
541 /*
542 * Ensure that vco configuration gets flushed to hardware before
543 * enabling the PLL
544 */
545 wmb();
546
547 return 0;
548}
549
550static int hdmi_8996_phy_ready_status(struct hdmi_phy *phy)
551{
552 u32 nb_tries = HDMI_PLL_POLL_MAX_READS;
553 unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
554 u32 status;
555 int phy_ready = 0;
556
557 DBG("Waiting for PHY ready");
558
559 while (nb_tries--) {
560 status = hdmi_phy_read(phy, REG_HDMI_8996_PHY_STATUS);
561 phy_ready = status & BIT(0);
562
563 if (phy_ready)
564 break;
565
566 udelay(timeout);
567 }
568
569 DBG("PHY is %sready", phy_ready ? "" : "*not* ");
570
571 return phy_ready;
572}
573
574static int hdmi_8996_pll_lock_status(struct hdmi_pll_8996 *pll)
575{
576 u32 status;
577 int nb_tries = HDMI_PLL_POLL_MAX_READS;
578 unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
579 int pll_locked = 0;
580
581 DBG("Waiting for PLL lock");
582
583 while (nb_tries--) {
584 status = hdmi_pll_read(pll,
585 REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS);
586 pll_locked = status & BIT(0);
587
588 if (pll_locked)
589 break;
590
591 udelay(timeout);
592 }
593
594 DBG("HDMI PLL is %slocked", pll_locked ? "" : "*not* ");
595
596 return pll_locked;
597}
598
599static int hdmi_8996_pll_prepare(struct clk_hw *hw)
600{
601 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
602 struct hdmi_phy *phy = pll_get_phy(pll);
603 int i, ret = 0;
604
605 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x1);
606 udelay(100);
607
608 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19);
609 udelay(100);
610
611 ret = hdmi_8996_pll_lock_status(pll);
612 if (!ret)
613 return ret;
614
615 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
616 hdmi_tx_chan_write(pll, i,
617 REG_HDMI_PHY_QSERDES_TX_LX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
618 0x6F);
619
620 /* Disable SSC */
621 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER1, 0x0);
622 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER2, 0x0);
623 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE1, 0x0);
624 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE2, 0x0);
625 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_EN_CENTER, 0x2);
626
627 ret = hdmi_8996_phy_ready_status(phy);
628 if (!ret)
629 return ret;
630
631 /* Restart the retiming buffer */
632 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x18);
633 udelay(1);
634 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19);
635
636 return 0;
637}
638
639static long hdmi_8996_pll_round_rate(struct clk_hw *hw,
640 unsigned long rate,
641 unsigned long *parent_rate)
642{
643 if (rate < HDMI_PCLK_MIN_FREQ)
644 return HDMI_PCLK_MIN_FREQ;
645 else if (rate > HDMI_PCLK_MAX_FREQ)
646 return HDMI_PCLK_MAX_FREQ;
647 else
648 return rate;
649}
650
651static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw *hw,
652 unsigned long parent_rate)
653{
654 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
655 u64 fdata;
656 u32 cmp1, cmp2, cmp3, pll_cmp;
657
658 cmp1 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0);
659 cmp2 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0);
660 cmp3 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0);
661
662 pll_cmp = cmp1 | (cmp2 << 8) | (cmp3 << 16);
663
664 fdata = pll_cmp_to_fdata(pll_cmp + 1, parent_rate);
665
666 do_div(fdata, 10);
667
668 return fdata;
669}
670
671static void hdmi_8996_pll_unprepare(struct clk_hw *hw)
672{
673}
674
675static int hdmi_8996_pll_is_enabled(struct clk_hw *hw)
676{
677 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
678 u32 status;
679 int pll_locked;
680
681 status = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS);
682 pll_locked = status & BIT(0);
683
684 return pll_locked;
685}
686
687static struct clk_ops hdmi_8996_pll_ops = {
688 .set_rate = hdmi_8996_pll_set_clk_rate,
689 .round_rate = hdmi_8996_pll_round_rate,
690 .recalc_rate = hdmi_8996_pll_recalc_rate,
691 .prepare = hdmi_8996_pll_prepare,
692 .unprepare = hdmi_8996_pll_unprepare,
693 .is_enabled = hdmi_8996_pll_is_enabled,
694};
695
696static const char * const hdmi_pll_parents[] = {
697 "xo",
698};
699
700static struct clk_init_data pll_init = {
701 .name = "hdmipll",
702 .ops = &hdmi_8996_pll_ops,
703 .parent_names = hdmi_pll_parents,
704 .num_parents = ARRAY_SIZE(hdmi_pll_parents),
705};
706
707int msm_hdmi_pll_8996_init(struct platform_device *pdev)
708{
709 struct device *dev = &pdev->dev;
710 struct hdmi_pll_8996 *pll;
711 struct clk *clk;
712 int i;
713
714 pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
715 if (!pll)
716 return -ENOMEM;
717
718 pll->pdev = pdev;
719
720 pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL");
721 if (IS_ERR(pll->mmio_qserdes_com)) {
722 dev_err(dev, "failed to map pll base\n");
723 return -ENOMEM;
724 }
725
726 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
727 char name[32], label[32];
728
729 snprintf(name, sizeof(name), "hdmi_tx_l%d", i);
730 snprintf(label, sizeof(label), "HDMI_TX_L%d", i);
731
732 pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name, label);
733 if (IS_ERR(pll->mmio_qserdes_tx[i])) {
734 dev_err(dev, "failed to map pll base\n");
735 return -ENOMEM;
736 }
737 }
738 pll->clk_hw.init = &pll_init;
739
740 clk = devm_clk_register(dev, &pll->clk_hw);
741 if (IS_ERR(clk)) {
742 dev_err(dev, "failed to register pll clock\n");
743 return -EINVAL;
744 }
745
746 return 0;
747}
748
749static const char * const hdmi_phy_8996_reg_names[] = {
750 "vddio",
751 "vcca",
752};
753
754static const char * const hdmi_phy_8996_clk_names[] = {
755 "mmagic_iface_clk",
756 "iface_clk",
757 "ref_clk",
758};
759
760const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg = {
761 .type = MSM_HDMI_PHY_8996,
762 .reg_names = hdmi_phy_8996_reg_names,
763 .num_regs = ARRAY_SIZE(hdmi_phy_8996_reg_names),
764 .clk_names = hdmi_phy_8996_clk_names,
765 .num_clks = ARRAY_SIZE(hdmi_phy_8996_clk_names),
766};
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/clk-provider.h>
7#include <linux/delay.h>
8
9#include "hdmi.h"
10
11#define HDMI_VCO_MAX_FREQ 12000000000UL
12#define HDMI_VCO_MIN_FREQ 8000000000UL
13
14#define HDMI_PCLK_MAX_FREQ 600000000
15#define HDMI_PCLK_MIN_FREQ 25000000
16
17#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL
18#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL
19#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000UL
20#define HDMI_CORECLK_DIV 5
21#define HDMI_DEFAULT_REF_CLOCK 19200000
22#define HDMI_PLL_CMP_CNT 1024
23
24#define HDMI_PLL_POLL_MAX_READS 100
25#define HDMI_PLL_POLL_TIMEOUT_US 150
26
27#define HDMI_NUM_TX_CHANNEL 4
28
29struct hdmi_pll_8996 {
30 struct platform_device *pdev;
31 struct clk_hw clk_hw;
32
33 /* pll mmio base */
34 void __iomem *mmio_qserdes_com;
35 /* tx channel base */
36 void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL];
37};
38
39#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8996, clk_hw)
40
41struct hdmi_8996_phy_pll_reg_cfg {
42 u32 tx_lx_lane_mode[HDMI_NUM_TX_CHANNEL];
43 u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL];
44 u32 com_svs_mode_clk_sel;
45 u32 com_hsclk_sel;
46 u32 com_pll_cctrl_mode0;
47 u32 com_pll_rctrl_mode0;
48 u32 com_cp_ctrl_mode0;
49 u32 com_dec_start_mode0;
50 u32 com_div_frac_start1_mode0;
51 u32 com_div_frac_start2_mode0;
52 u32 com_div_frac_start3_mode0;
53 u32 com_integloop_gain0_mode0;
54 u32 com_integloop_gain1_mode0;
55 u32 com_lock_cmp_en;
56 u32 com_lock_cmp1_mode0;
57 u32 com_lock_cmp2_mode0;
58 u32 com_lock_cmp3_mode0;
59 u32 com_core_clk_en;
60 u32 com_coreclk_div;
61 u32 com_vco_tune_ctrl;
62
63 u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL];
64 u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL];
65 u32 tx_lx_vmode_ctrl1[HDMI_NUM_TX_CHANNEL];
66 u32 tx_lx_vmode_ctrl2[HDMI_NUM_TX_CHANNEL];
67 u32 tx_lx_res_code_lane_tx[HDMI_NUM_TX_CHANNEL];
68 u32 tx_lx_hp_pd_enables[HDMI_NUM_TX_CHANNEL];
69
70 u32 phy_mode;
71};
72
73struct hdmi_8996_post_divider {
74 u64 vco_freq;
75 int hsclk_divsel;
76 int vco_ratio;
77 int tx_band_sel;
78 int half_rate_mode;
79};
80
81static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8996 *pll)
82{
83 return platform_get_drvdata(pll->pdev);
84}
85
86static inline void hdmi_pll_write(struct hdmi_pll_8996 *pll, int offset,
87 u32 data)
88{
89 msm_writel(data, pll->mmio_qserdes_com + offset);
90}
91
92static inline u32 hdmi_pll_read(struct hdmi_pll_8996 *pll, int offset)
93{
94 return msm_readl(pll->mmio_qserdes_com + offset);
95}
96
97static inline void hdmi_tx_chan_write(struct hdmi_pll_8996 *pll, int channel,
98 int offset, int data)
99{
100 msm_writel(data, pll->mmio_qserdes_tx[channel] + offset);
101}
102
103static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk,
104 bool gen_ssc)
105{
106 if ((frac_start != 0) || gen_ssc)
107 return (11000000 / (ref_clk / 20));
108
109 return 0x23;
110}
111
112static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc)
113{
114 if ((frac_start != 0) || gen_ssc)
115 return 0x16;
116
117 return 0x10;
118}
119
120static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc)
121{
122 if ((frac_start != 0) || gen_ssc)
123 return 0x28;
124
125 return 0x1;
126}
127
128static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk,
129 bool gen_ssc)
130{
131 int digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2;
132 u64 base;
133
134 if ((frac_start != 0) || gen_ssc)
135 base = (64 * ref_clk) / HDMI_DEFAULT_REF_CLOCK;
136 else
137 base = (1022 * ref_clk) / 100;
138
139 base <<= digclk_divsel;
140
141 return (base <= 2046 ? base : 2046);
142}
143
144static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk)
145{
146 u64 dividend = HDMI_PLL_CMP_CNT * fdata;
147 u32 divisor = ref_clk * 10;
148 u32 rem;
149
150 rem = do_div(dividend, divisor);
151 if (rem > (divisor >> 1))
152 dividend++;
153
154 return dividend - 1;
155}
156
157static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk)
158{
159 u64 fdata = ((u64)pll_cmp) * ref_clk * 10;
160
161 do_div(fdata, HDMI_PLL_CMP_CNT);
162
163 return fdata;
164}
165
166static int pll_get_post_div(struct hdmi_8996_post_divider *pd, u64 bclk)
167{
168 int ratio[] = { 2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35 };
169 int hs_divsel[] = { 0, 4, 8, 12, 1, 5, 2, 9, 3, 13, 10, 7, 14, 11, 15 };
170 int tx_band_sel[] = { 0, 1, 2, 3 };
171 u64 vco_freq[60];
172 u64 vco, vco_optimal;
173 int half_rate_mode = 0;
174 int vco_optimal_index, vco_freq_index;
175 int i, j;
176
177retry:
178 vco_optimal = HDMI_VCO_MAX_FREQ;
179 vco_optimal_index = -1;
180 vco_freq_index = 0;
181 for (i = 0; i < 15; i++) {
182 for (j = 0; j < 4; j++) {
183 u32 ratio_mult = ratio[i] << tx_band_sel[j];
184
185 vco = bclk >> half_rate_mode;
186 vco *= ratio_mult;
187 vco_freq[vco_freq_index++] = vco;
188 }
189 }
190
191 for (i = 0; i < 60; i++) {
192 u64 vco_tmp = vco_freq[i];
193
194 if ((vco_tmp >= HDMI_VCO_MIN_FREQ) &&
195 (vco_tmp <= vco_optimal)) {
196 vco_optimal = vco_tmp;
197 vco_optimal_index = i;
198 }
199 }
200
201 if (vco_optimal_index == -1) {
202 if (!half_rate_mode) {
203 half_rate_mode = 1;
204 goto retry;
205 }
206 } else {
207 pd->vco_freq = vco_optimal;
208 pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4];
209 pd->vco_ratio = ratio[vco_optimal_index / 4];
210 pd->hsclk_divsel = hs_divsel[vco_optimal_index / 4];
211
212 return 0;
213 }
214
215 return -EINVAL;
216}
217
218static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk,
219 struct hdmi_8996_phy_pll_reg_cfg *cfg)
220{
221 struct hdmi_8996_post_divider pd;
222 u64 bclk;
223 u64 tmds_clk;
224 u64 dec_start;
225 u64 frac_start;
226 u64 fdata;
227 u32 pll_divisor;
228 u32 rem;
229 u32 cpctrl;
230 u32 rctrl;
231 u32 cctrl;
232 u32 integloop_gain;
233 u32 pll_cmp;
234 int i, ret;
235
236 /* bit clk = 10 * pix_clk */
237 bclk = ((u64)pix_clk) * 10;
238
239 if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
240 tmds_clk = pix_clk >> 2;
241 else
242 tmds_clk = pix_clk;
243
244 ret = pll_get_post_div(&pd, bclk);
245 if (ret)
246 return ret;
247
248 dec_start = pd.vco_freq;
249 pll_divisor = 4 * ref_clk;
250 do_div(dec_start, pll_divisor);
251
252 frac_start = pd.vco_freq * (1 << 20);
253
254 rem = do_div(frac_start, pll_divisor);
255 frac_start -= dec_start * (1 << 20);
256 if (rem > (pll_divisor >> 1))
257 frac_start++;
258
259 cpctrl = pll_get_cpctrl(frac_start, ref_clk, false);
260 rctrl = pll_get_rctrl(frac_start, false);
261 cctrl = pll_get_cctrl(frac_start, false);
262 integloop_gain = pll_get_integloop_gain(frac_start, bclk,
263 ref_clk, false);
264
265 fdata = pd.vco_freq;
266 do_div(fdata, pd.vco_ratio);
267
268 pll_cmp = pll_get_pll_cmp(fdata, ref_clk);
269
270 DBG("VCO freq: %llu", pd.vco_freq);
271 DBG("fdata: %llu", fdata);
272 DBG("pix_clk: %lu", pix_clk);
273 DBG("tmds clk: %llu", tmds_clk);
274 DBG("HSCLK_SEL: %d", pd.hsclk_divsel);
275 DBG("DEC_START: %llu", dec_start);
276 DBG("DIV_FRAC_START: %llu", frac_start);
277 DBG("PLL_CPCTRL: %u", cpctrl);
278 DBG("PLL_RCTRL: %u", rctrl);
279 DBG("PLL_CCTRL: %u", cctrl);
280 DBG("INTEGLOOP_GAIN: %u", integloop_gain);
281 DBG("TX_BAND: %d", pd.tx_band_sel);
282 DBG("PLL_CMP: %u", pll_cmp);
283
284 /* Convert these values to register specific values */
285 if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
286 cfg->com_svs_mode_clk_sel = 1;
287 else
288 cfg->com_svs_mode_clk_sel = 2;
289
290 cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel);
291 cfg->com_pll_cctrl_mode0 = cctrl;
292 cfg->com_pll_rctrl_mode0 = rctrl;
293 cfg->com_cp_ctrl_mode0 = cpctrl;
294 cfg->com_dec_start_mode0 = dec_start;
295 cfg->com_div_frac_start1_mode0 = (frac_start & 0xff);
296 cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8);
297 cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16);
298 cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff);
299 cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8);
300 cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff);
301 cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8);
302 cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
303 cfg->com_lock_cmp_en = 0x0;
304 cfg->com_core_clk_en = 0x2c;
305 cfg->com_coreclk_div = HDMI_CORECLK_DIV;
306 cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
307 cfg->com_vco_tune_ctrl = 0x0;
308
309 cfg->tx_lx_lane_mode[0] =
310 cfg->tx_lx_lane_mode[2] = 0x43;
311
312 cfg->tx_lx_hp_pd_enables[0] =
313 cfg->tx_lx_hp_pd_enables[1] =
314 cfg->tx_lx_hp_pd_enables[2] = 0x0c;
315 cfg->tx_lx_hp_pd_enables[3] = 0x3;
316
317 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
318 cfg->tx_lx_tx_band[i] = pd.tx_band_sel + 4;
319
320 if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
321 cfg->tx_lx_tx_drv_lvl[0] =
322 cfg->tx_lx_tx_drv_lvl[1] =
323 cfg->tx_lx_tx_drv_lvl[2] = 0x25;
324 cfg->tx_lx_tx_drv_lvl[3] = 0x22;
325
326 cfg->tx_lx_tx_emp_post1_lvl[0] =
327 cfg->tx_lx_tx_emp_post1_lvl[1] =
328 cfg->tx_lx_tx_emp_post1_lvl[2] = 0x23;
329 cfg->tx_lx_tx_emp_post1_lvl[3] = 0x27;
330
331 cfg->tx_lx_vmode_ctrl1[0] =
332 cfg->tx_lx_vmode_ctrl1[1] =
333 cfg->tx_lx_vmode_ctrl1[2] =
334 cfg->tx_lx_vmode_ctrl1[3] = 0x00;
335
336 cfg->tx_lx_vmode_ctrl2[0] =
337 cfg->tx_lx_vmode_ctrl2[1] =
338 cfg->tx_lx_vmode_ctrl2[2] = 0x0D;
339
340 cfg->tx_lx_vmode_ctrl2[3] = 0x00;
341 } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
342 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
343 cfg->tx_lx_tx_drv_lvl[i] = 0x25;
344 cfg->tx_lx_tx_emp_post1_lvl[i] = 0x23;
345 cfg->tx_lx_vmode_ctrl1[i] = 0x00;
346 }
347
348 cfg->tx_lx_vmode_ctrl2[0] =
349 cfg->tx_lx_vmode_ctrl2[1] =
350 cfg->tx_lx_vmode_ctrl2[2] = 0x0D;
351 cfg->tx_lx_vmode_ctrl2[3] = 0x00;
352 } else {
353 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
354 cfg->tx_lx_tx_drv_lvl[i] = 0x20;
355 cfg->tx_lx_tx_emp_post1_lvl[i] = 0x20;
356 cfg->tx_lx_vmode_ctrl1[i] = 0x00;
357 cfg->tx_lx_vmode_ctrl2[i] = 0x0E;
358 }
359 }
360
361 DBG("com_svs_mode_clk_sel = 0x%x", cfg->com_svs_mode_clk_sel);
362 DBG("com_hsclk_sel = 0x%x", cfg->com_hsclk_sel);
363 DBG("com_lock_cmp_en = 0x%x", cfg->com_lock_cmp_en);
364 DBG("com_pll_cctrl_mode0 = 0x%x", cfg->com_pll_cctrl_mode0);
365 DBG("com_pll_rctrl_mode0 = 0x%x", cfg->com_pll_rctrl_mode0);
366 DBG("com_cp_ctrl_mode0 = 0x%x", cfg->com_cp_ctrl_mode0);
367 DBG("com_dec_start_mode0 = 0x%x", cfg->com_dec_start_mode0);
368 DBG("com_div_frac_start1_mode0 = 0x%x", cfg->com_div_frac_start1_mode0);
369 DBG("com_div_frac_start2_mode0 = 0x%x", cfg->com_div_frac_start2_mode0);
370 DBG("com_div_frac_start3_mode0 = 0x%x", cfg->com_div_frac_start3_mode0);
371 DBG("com_integloop_gain0_mode0 = 0x%x", cfg->com_integloop_gain0_mode0);
372 DBG("com_integloop_gain1_mode0 = 0x%x", cfg->com_integloop_gain1_mode0);
373 DBG("com_lock_cmp1_mode0 = 0x%x", cfg->com_lock_cmp1_mode0);
374 DBG("com_lock_cmp2_mode0 = 0x%x", cfg->com_lock_cmp2_mode0);
375 DBG("com_lock_cmp3_mode0 = 0x%x", cfg->com_lock_cmp3_mode0);
376 DBG("com_core_clk_en = 0x%x", cfg->com_core_clk_en);
377 DBG("com_coreclk_div = 0x%x", cfg->com_coreclk_div);
378 DBG("phy_mode = 0x%x", cfg->phy_mode);
379
380 DBG("tx_l0_lane_mode = 0x%x", cfg->tx_lx_lane_mode[0]);
381 DBG("tx_l2_lane_mode = 0x%x", cfg->tx_lx_lane_mode[2]);
382
383 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
384 DBG("tx_l%d_tx_band = 0x%x", i, cfg->tx_lx_tx_band[i]);
385 DBG("tx_l%d_tx_drv_lvl = 0x%x", i, cfg->tx_lx_tx_drv_lvl[i]);
386 DBG("tx_l%d_tx_emp_post1_lvl = 0x%x", i,
387 cfg->tx_lx_tx_emp_post1_lvl[i]);
388 DBG("tx_l%d_vmode_ctrl1 = 0x%x", i, cfg->tx_lx_vmode_ctrl1[i]);
389 DBG("tx_l%d_vmode_ctrl2 = 0x%x", i, cfg->tx_lx_vmode_ctrl2[i]);
390 }
391
392 return 0;
393}
394
395static int hdmi_8996_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate,
396 unsigned long parent_rate)
397{
398 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
399 struct hdmi_phy *phy = pll_get_phy(pll);
400 struct hdmi_8996_phy_pll_reg_cfg cfg;
401 int i, ret;
402
403 memset(&cfg, 0x00, sizeof(cfg));
404
405 ret = pll_calculate(rate, parent_rate, &cfg);
406 if (ret) {
407 DRM_ERROR("PLL calculation failed\n");
408 return ret;
409 }
410
411 /* Initially shut down PHY */
412 DBG("Disabling PHY");
413 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x0);
414 udelay(500);
415
416 /* Power up sequence */
417 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x04);
418
419 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1);
420 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20);
421 hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL, 0x0F);
422 hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL, 0x0F);
423
424 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
425 hdmi_tx_chan_write(pll, i,
426 REG_HDMI_PHY_QSERDES_TX_LX_CLKBUF_ENABLE,
427 0x03);
428 hdmi_tx_chan_write(pll, i,
429 REG_HDMI_PHY_QSERDES_TX_LX_TX_BAND,
430 cfg.tx_lx_tx_band[i]);
431 hdmi_tx_chan_write(pll, i,
432 REG_HDMI_PHY_QSERDES_TX_LX_RESET_TSYNC_EN,
433 0x03);
434 }
435
436 hdmi_tx_chan_write(pll, 0, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE,
437 cfg.tx_lx_lane_mode[0]);
438 hdmi_tx_chan_write(pll, 2, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE,
439 cfg.tx_lx_lane_mode[2]);
440
441 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E);
442 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07);
443 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37);
444 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02);
445 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E);
446
447 /* Bypass VCO calibration */
448 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SVS_MODE_CLK_SEL,
449 cfg.com_svs_mode_clk_sel);
450
451 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_TRIM, 0x0F);
452 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_IVCO, 0x0F);
453 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_CTRL,
454 cfg.com_vco_tune_ctrl);
455
456 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x06);
457
458 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_SELECT, 0x30);
459 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_HSCLK_SEL,
460 cfg.com_hsclk_sel);
461 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN,
462 cfg.com_lock_cmp_en);
463
464 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE0,
465 cfg.com_pll_cctrl_mode0);
466 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE0,
467 cfg.com_pll_rctrl_mode0);
468 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE0,
469 cfg.com_cp_ctrl_mode0);
470 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE0,
471 cfg.com_dec_start_mode0);
472 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0,
473 cfg.com_div_frac_start1_mode0);
474 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0,
475 cfg.com_div_frac_start2_mode0);
476 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0,
477 cfg.com_div_frac_start3_mode0);
478
479 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
480 cfg.com_integloop_gain0_mode0);
481 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
482 cfg.com_integloop_gain1_mode0);
483
484 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0,
485 cfg.com_lock_cmp1_mode0);
486 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0,
487 cfg.com_lock_cmp2_mode0);
488 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0,
489 cfg.com_lock_cmp3_mode0);
490
491 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00);
492 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORE_CLK_EN,
493 cfg.com_core_clk_en);
494 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV,
495 cfg.com_coreclk_div);
496 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CMN_CONFIG, 0x02);
497
498 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM, 0x15);
499
500 /* TX lanes setup (TX 0/1/2/3) */
501 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
502 hdmi_tx_chan_write(pll, i,
503 REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL,
504 cfg.tx_lx_tx_drv_lvl[i]);
505 hdmi_tx_chan_write(pll, i,
506 REG_HDMI_PHY_QSERDES_TX_LX_TX_EMP_POST1_LVL,
507 cfg.tx_lx_tx_emp_post1_lvl[i]);
508 hdmi_tx_chan_write(pll, i,
509 REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL1,
510 cfg.tx_lx_vmode_ctrl1[i]);
511 hdmi_tx_chan_write(pll, i,
512 REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL2,
513 cfg.tx_lx_vmode_ctrl2[i]);
514 hdmi_tx_chan_write(pll, i,
515 REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL_OFFSET,
516 0x00);
517 hdmi_tx_chan_write(pll, i,
518 REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET,
519 0x00);
520 hdmi_tx_chan_write(pll, i,
521 REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN,
522 0x03);
523 hdmi_tx_chan_write(pll, i,
524 REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN,
525 0x40);
526 hdmi_tx_chan_write(pll, i,
527 REG_HDMI_PHY_QSERDES_TX_LX_HP_PD_ENABLES,
528 cfg.tx_lx_hp_pd_enables[i]);
529 }
530
531 hdmi_phy_write(phy, REG_HDMI_8996_PHY_MODE, cfg.phy_mode);
532 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1F);
533
534 /*
535 * Ensure that vco configuration gets flushed to hardware before
536 * enabling the PLL
537 */
538 wmb();
539
540 return 0;
541}
542
543static int hdmi_8996_phy_ready_status(struct hdmi_phy *phy)
544{
545 u32 nb_tries = HDMI_PLL_POLL_MAX_READS;
546 unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
547 u32 status;
548 int phy_ready = 0;
549
550 DBG("Waiting for PHY ready");
551
552 while (nb_tries--) {
553 status = hdmi_phy_read(phy, REG_HDMI_8996_PHY_STATUS);
554 phy_ready = status & BIT(0);
555
556 if (phy_ready)
557 break;
558
559 udelay(timeout);
560 }
561
562 DBG("PHY is %sready", phy_ready ? "" : "*not* ");
563
564 return phy_ready;
565}
566
567static int hdmi_8996_pll_lock_status(struct hdmi_pll_8996 *pll)
568{
569 u32 status;
570 int nb_tries = HDMI_PLL_POLL_MAX_READS;
571 unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
572 int pll_locked = 0;
573
574 DBG("Waiting for PLL lock");
575
576 while (nb_tries--) {
577 status = hdmi_pll_read(pll,
578 REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS);
579 pll_locked = status & BIT(0);
580
581 if (pll_locked)
582 break;
583
584 udelay(timeout);
585 }
586
587 DBG("HDMI PLL is %slocked", pll_locked ? "" : "*not* ");
588
589 return pll_locked;
590}
591
592static int hdmi_8996_pll_prepare(struct clk_hw *hw)
593{
594 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
595 struct hdmi_phy *phy = pll_get_phy(pll);
596 int i, ret = 0;
597
598 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x1);
599 udelay(100);
600
601 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19);
602 udelay(100);
603
604 ret = hdmi_8996_pll_lock_status(pll);
605 if (!ret)
606 return ret;
607
608 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
609 hdmi_tx_chan_write(pll, i,
610 REG_HDMI_PHY_QSERDES_TX_LX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
611 0x6F);
612
613 /* Disable SSC */
614 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER1, 0x0);
615 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER2, 0x0);
616 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE1, 0x0);
617 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE2, 0x0);
618 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_EN_CENTER, 0x2);
619
620 ret = hdmi_8996_phy_ready_status(phy);
621 if (!ret)
622 return ret;
623
624 /* Restart the retiming buffer */
625 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x18);
626 udelay(1);
627 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19);
628
629 return 0;
630}
631
632static long hdmi_8996_pll_round_rate(struct clk_hw *hw,
633 unsigned long rate,
634 unsigned long *parent_rate)
635{
636 if (rate < HDMI_PCLK_MIN_FREQ)
637 return HDMI_PCLK_MIN_FREQ;
638 else if (rate > HDMI_PCLK_MAX_FREQ)
639 return HDMI_PCLK_MAX_FREQ;
640 else
641 return rate;
642}
643
644static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw *hw,
645 unsigned long parent_rate)
646{
647 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
648 u64 fdata;
649 u32 cmp1, cmp2, cmp3, pll_cmp;
650
651 cmp1 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0);
652 cmp2 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0);
653 cmp3 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0);
654
655 pll_cmp = cmp1 | (cmp2 << 8) | (cmp3 << 16);
656
657 fdata = pll_cmp_to_fdata(pll_cmp + 1, parent_rate);
658
659 do_div(fdata, 10);
660
661 return fdata;
662}
663
664static void hdmi_8996_pll_unprepare(struct clk_hw *hw)
665{
666 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
667 struct hdmi_phy *phy = pll_get_phy(pll);
668
669 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x6);
670 usleep_range(100, 150);
671}
672
673static int hdmi_8996_pll_is_enabled(struct clk_hw *hw)
674{
675 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
676 u32 status;
677 int pll_locked;
678
679 status = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS);
680 pll_locked = status & BIT(0);
681
682 return pll_locked;
683}
684
685static const struct clk_ops hdmi_8996_pll_ops = {
686 .set_rate = hdmi_8996_pll_set_clk_rate,
687 .round_rate = hdmi_8996_pll_round_rate,
688 .recalc_rate = hdmi_8996_pll_recalc_rate,
689 .prepare = hdmi_8996_pll_prepare,
690 .unprepare = hdmi_8996_pll_unprepare,
691 .is_enabled = hdmi_8996_pll_is_enabled,
692};
693
694static const struct clk_init_data pll_init = {
695 .name = "hdmipll",
696 .ops = &hdmi_8996_pll_ops,
697 .parent_data = (const struct clk_parent_data[]){
698 { .fw_name = "xo", .name = "xo_board" },
699 },
700 .num_parents = 1,
701 .flags = CLK_IGNORE_UNUSED,
702};
703
704int msm_hdmi_pll_8996_init(struct platform_device *pdev)
705{
706 struct device *dev = &pdev->dev;
707 struct hdmi_pll_8996 *pll;
708 int i, ret;
709
710 pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
711 if (!pll)
712 return -ENOMEM;
713
714 pll->pdev = pdev;
715
716 pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll");
717 if (IS_ERR(pll->mmio_qserdes_com)) {
718 DRM_DEV_ERROR(dev, "failed to map pll base\n");
719 return -ENOMEM;
720 }
721
722 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
723 char name[32];
724
725 snprintf(name, sizeof(name), "hdmi_tx_l%d", i);
726
727 pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name);
728 if (IS_ERR(pll->mmio_qserdes_tx[i])) {
729 DRM_DEV_ERROR(dev, "failed to map pll base\n");
730 return -ENOMEM;
731 }
732 }
733 pll->clk_hw.init = &pll_init;
734
735 ret = devm_clk_hw_register(dev, &pll->clk_hw);
736 if (ret) {
737 DRM_DEV_ERROR(dev, "failed to register pll clock\n");
738 return ret;
739 }
740
741 ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw);
742 if (ret) {
743 DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret);
744 return ret;
745 }
746
747 return 0;
748}
749
750static const char * const hdmi_phy_8996_reg_names[] = {
751 "vddio",
752 "vcca",
753};
754
755static const char * const hdmi_phy_8996_clk_names[] = {
756 "iface", "ref",
757};
758
759const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg = {
760 .type = MSM_HDMI_PHY_8996,
761 .reg_names = hdmi_phy_8996_reg_names,
762 .num_regs = ARRAY_SIZE(hdmi_phy_8996_reg_names),
763 .clk_names = hdmi_phy_8996_clk_names,
764 .num_clks = ARRAY_SIZE(hdmi_phy_8996_clk_names),
765};