1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
6 #include <linux/clk-provider.h>
7 #include <linux/delay.h>
11 #define HDMI_VCO_MAX_FREQ 12000000000UL
12 #define HDMI_VCO_MIN_FREQ 8000000000UL
14 #define HDMI_PCLK_MAX_FREQ 600000000
15 #define HDMI_PCLK_MIN_FREQ 25000000
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
24 #define HDMI_PLL_POLL_MAX_READS 100
25 #define HDMI_PLL_POLL_TIMEOUT_US 150
27 #define HDMI_NUM_TX_CHANNEL 4
29 struct hdmi_pll_8996
{
30 struct platform_device
*pdev
;
34 void __iomem
*mmio_qserdes_com
;
36 void __iomem
*mmio_qserdes_tx
[HDMI_NUM_TX_CHANNEL
];
39 #define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8996, clk_hw)
41 struct 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
;
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
;
56 u32 com_lock_cmp1_mode0
;
57 u32 com_lock_cmp2_mode0
;
58 u32 com_lock_cmp3_mode0
;
61 u32 com_vco_tune_ctrl
;
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
];
73 struct hdmi_8996_post_divider
{
81 static inline struct hdmi_phy
*pll_get_phy(struct hdmi_pll_8996
*pll
)
83 return platform_get_drvdata(pll
->pdev
);
86 static inline void hdmi_pll_write(struct hdmi_pll_8996
*pll
, int offset
,
89 msm_writel(data
, pll
->mmio_qserdes_com
+ offset
);
92 static inline u32
hdmi_pll_read(struct hdmi_pll_8996
*pll
, int offset
)
94 return msm_readl(pll
->mmio_qserdes_com
+ offset
);
97 static inline void hdmi_tx_chan_write(struct hdmi_pll_8996
*pll
, int channel
,
100 msm_writel(data
, pll
->mmio_qserdes_tx
[channel
] + offset
);
103 static inline u32
pll_get_cpctrl(u64 frac_start
, unsigned long ref_clk
,
106 if ((frac_start
!= 0) || gen_ssc
)
107 return (11000000 / (ref_clk
/ 20));
112 static inline u32
pll_get_rctrl(u64 frac_start
, bool gen_ssc
)
114 if ((frac_start
!= 0) || gen_ssc
)
120 static inline u32
pll_get_cctrl(u64 frac_start
, bool gen_ssc
)
122 if ((frac_start
!= 0) || gen_ssc
)
128 static inline u32
pll_get_integloop_gain(u64 frac_start
, u64 bclk
, u32 ref_clk
,
131 int digclk_divsel
= bclk
>= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD
? 1 : 2;
134 if ((frac_start
!= 0) || gen_ssc
)
135 base
= (64 * ref_clk
) / HDMI_DEFAULT_REF_CLOCK
;
137 base
= (1022 * ref_clk
) / 100;
139 base
<<= digclk_divsel
;
141 return (base
<= 2046 ? base
: 2046);
144 static inline u32
pll_get_pll_cmp(u64 fdata
, unsigned long ref_clk
)
146 u64 dividend
= HDMI_PLL_CMP_CNT
* fdata
;
147 u32 divisor
= ref_clk
* 10;
150 rem
= do_div(dividend
, divisor
);
151 if (rem
> (divisor
>> 1))
157 static inline u64
pll_cmp_to_fdata(u32 pll_cmp
, unsigned long ref_clk
)
159 u64 fdata
= ((u64
)pll_cmp
) * ref_clk
* 10;
161 do_div(fdata
, HDMI_PLL_CMP_CNT
);
166 static int pll_get_post_div(struct hdmi_8996_post_divider
*pd
, u64 bclk
)
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 };
172 u64 vco
, vco_optimal
;
173 int half_rate_mode
= 0;
174 int vco_optimal_index
, vco_freq_index
;
178 vco_optimal
= HDMI_VCO_MAX_FREQ
;
179 vco_optimal_index
= -1;
181 for (i
= 0; i
< 15; i
++) {
182 for (j
= 0; j
< 4; j
++) {
183 u32 ratio_mult
= ratio
[i
] << tx_band_sel
[j
];
185 vco
= bclk
>> half_rate_mode
;
187 vco_freq
[vco_freq_index
++] = vco
;
191 for (i
= 0; i
< 60; i
++) {
192 u64 vco_tmp
= vco_freq
[i
];
194 if ((vco_tmp
>= HDMI_VCO_MIN_FREQ
) &&
195 (vco_tmp
<= vco_optimal
)) {
196 vco_optimal
= vco_tmp
;
197 vco_optimal_index
= i
;
201 if (vco_optimal_index
== -1) {
202 if (!half_rate_mode
) {
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];
218 static int pll_calculate(unsigned long pix_clk
, unsigned long ref_clk
,
219 struct hdmi_8996_phy_pll_reg_cfg
*cfg
)
221 struct hdmi_8996_post_divider pd
;
236 /* bit clk = 10 * pix_clk */
237 bclk
= ((u64
)pix_clk
) * 10;
239 if (bclk
> HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD
)
240 tmds_clk
= pix_clk
>> 2;
244 ret
= pll_get_post_div(&pd
, bclk
);
248 dec_start
= pd
.vco_freq
;
249 pll_divisor
= 4 * ref_clk
;
250 do_div(dec_start
, pll_divisor
);
252 frac_start
= pd
.vco_freq
* (1 << 20);
254 rem
= do_div(frac_start
, pll_divisor
);
255 frac_start
-= dec_start
* (1 << 20);
256 if (rem
> (pll_divisor
>> 1))
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
,
266 do_div(fdata
, pd
.vco_ratio
);
268 pll_cmp
= pll_get_pll_cmp(fdata
, ref_clk
);
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
);
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;
288 cfg
->com_svs_mode_clk_sel
= 2;
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;
309 cfg
->tx_lx_lane_mode
[0] =
310 cfg
->tx_lx_lane_mode
[2] = 0x43;
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;
317 for (i
= 0; i
< HDMI_NUM_TX_CHANNEL
; i
++)
318 cfg
->tx_lx_tx_band
[i
] = pd
.tx_band_sel
+ 4;
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;
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;
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;
336 cfg
->tx_lx_vmode_ctrl2
[0] =
337 cfg
->tx_lx_vmode_ctrl2
[1] =
338 cfg
->tx_lx_vmode_ctrl2
[2] = 0x0D;
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;
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;
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;
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
);
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]);
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
]);
395 static int hdmi_8996_pll_set_clk_rate(struct clk_hw
*hw
, unsigned long rate
,
396 unsigned long parent_rate
)
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
;
403 memset(&cfg
, 0x00, sizeof(cfg
));
405 ret
= pll_calculate(rate
, parent_rate
, &cfg
);
407 DRM_ERROR("PLL calculation failed\n");
411 /* Initially shut down PHY */
412 DBG("Disabling PHY");
413 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_PD_CTL
, 0x0);
416 /* Power up sequence */
417 hdmi_pll_write(pll
, REG_HDMI_PHY_QSERDES_COM_BG_CTRL
, 0x04);
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);
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
,
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
,
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]);
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);
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
);
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
);
456 hdmi_pll_write(pll
, REG_HDMI_PHY_QSERDES_COM_BG_CTRL
, 0x06);
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
,
461 hdmi_pll_write(pll
, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN
,
462 cfg
.com_lock_cmp_en
);
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
);
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
);
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
);
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);
498 hdmi_pll_write(pll
, REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM
, 0x15);
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
,
517 hdmi_tx_chan_write(pll
, i
,
518 REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET
,
520 hdmi_tx_chan_write(pll
, i
,
521 REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN
,
523 hdmi_tx_chan_write(pll
, i
,
524 REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN
,
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
]);
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);
535 * Ensure that vco configuration gets flushed to hardware before
543 static int hdmi_8996_phy_ready_status(struct hdmi_phy
*phy
)
545 u32 nb_tries
= HDMI_PLL_POLL_MAX_READS
;
546 unsigned long timeout
= HDMI_PLL_POLL_TIMEOUT_US
;
550 DBG("Waiting for PHY ready");
553 status
= hdmi_phy_read(phy
, REG_HDMI_8996_PHY_STATUS
);
554 phy_ready
= status
& BIT(0);
562 DBG("PHY is %sready", phy_ready
? "" : "*not* ");
567 static int hdmi_8996_pll_lock_status(struct hdmi_pll_8996
*pll
)
570 int nb_tries
= HDMI_PLL_POLL_MAX_READS
;
571 unsigned long timeout
= HDMI_PLL_POLL_TIMEOUT_US
;
574 DBG("Waiting for PLL lock");
577 status
= hdmi_pll_read(pll
,
578 REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS
);
579 pll_locked
= status
& BIT(0);
587 DBG("HDMI PLL is %slocked", pll_locked
? "" : "*not* ");
592 static int hdmi_8996_pll_prepare(struct clk_hw
*hw
)
594 struct hdmi_pll_8996
*pll
= hw_clk_to_pll(hw
);
595 struct hdmi_phy
*phy
= pll_get_phy(pll
);
598 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x1);
601 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x19);
604 ret
= hdmi_8996_pll_lock_status(pll
);
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
,
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);
620 ret
= hdmi_8996_phy_ready_status(phy
);
624 /* Restart the retiming buffer */
625 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x18);
627 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x19);
632 static long hdmi_8996_pll_round_rate(struct clk_hw
*hw
,
634 unsigned long *parent_rate
)
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
;
644 static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw
*hw
,
645 unsigned long parent_rate
)
647 struct hdmi_pll_8996
*pll
= hw_clk_to_pll(hw
);
649 u32 cmp1
, cmp2
, cmp3
, pll_cmp
;
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
);
655 pll_cmp
= cmp1
| (cmp2
<< 8) | (cmp3
<< 16);
657 fdata
= pll_cmp_to_fdata(pll_cmp
+ 1, parent_rate
);
664 static void hdmi_8996_pll_unprepare(struct clk_hw
*hw
)
666 struct hdmi_pll_8996
*pll
= hw_clk_to_pll(hw
);
667 struct hdmi_phy
*phy
= pll_get_phy(pll
);
669 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x6);
670 usleep_range(100, 150);
673 static int hdmi_8996_pll_is_enabled(struct clk_hw
*hw
)
675 struct hdmi_pll_8996
*pll
= hw_clk_to_pll(hw
);
679 status
= hdmi_pll_read(pll
, REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS
);
680 pll_locked
= status
& BIT(0);
685 static 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
,
694 static const char * const hdmi_pll_parents
[] = {
698 static struct clk_init_data pll_init
= {
700 .ops
= &hdmi_8996_pll_ops
,
701 .parent_names
= hdmi_pll_parents
,
702 .num_parents
= ARRAY_SIZE(hdmi_pll_parents
),
703 .flags
= CLK_IGNORE_UNUSED
,
706 int msm_hdmi_pll_8996_init(struct platform_device
*pdev
)
708 struct device
*dev
= &pdev
->dev
;
709 struct hdmi_pll_8996
*pll
;
713 pll
= devm_kzalloc(dev
, sizeof(*pll
), GFP_KERNEL
);
719 pll
->mmio_qserdes_com
= msm_ioremap(pdev
, "hdmi_pll", "HDMI_PLL");
720 if (IS_ERR(pll
->mmio_qserdes_com
)) {
721 DRM_DEV_ERROR(dev
, "failed to map pll base\n");
725 for (i
= 0; i
< HDMI_NUM_TX_CHANNEL
; i
++) {
726 char name
[32], label
[32];
728 snprintf(name
, sizeof(name
), "hdmi_tx_l%d", i
);
729 snprintf(label
, sizeof(label
), "HDMI_TX_L%d", i
);
731 pll
->mmio_qserdes_tx
[i
] = msm_ioremap(pdev
, name
, label
);
732 if (IS_ERR(pll
->mmio_qserdes_tx
[i
])) {
733 DRM_DEV_ERROR(dev
, "failed to map pll base\n");
737 pll
->clk_hw
.init
= &pll_init
;
739 clk
= devm_clk_register(dev
, &pll
->clk_hw
);
741 DRM_DEV_ERROR(dev
, "failed to register pll clock\n");
748 static const char * const hdmi_phy_8996_reg_names
[] = {
753 static const char * const hdmi_phy_8996_clk_names
[] = {
757 const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg
= {
758 .type
= MSM_HDMI_PHY_8996
,
759 .reg_names
= hdmi_phy_8996_reg_names
,
760 .num_regs
= ARRAY_SIZE(hdmi_phy_8996_reg_names
),
761 .clk_names
= hdmi_phy_8996_clk_names
,
762 .num_clks
= ARRAY_SIZE(hdmi_phy_8996_clk_names
),