2 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
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.
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.
14 #include <linux/clk-provider.h>
18 #define HDMI_VCO_MAX_FREQ 12000000000UL
19 #define HDMI_VCO_MIN_FREQ 8000000000UL
21 #define HDMI_PCLK_MAX_FREQ 600000000
22 #define HDMI_PCLK_MIN_FREQ 25000000
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
31 #define HDMI_PLL_POLL_MAX_READS 100
32 #define HDMI_PLL_POLL_TIMEOUT_US 150
34 #define HDMI_NUM_TX_CHANNEL 4
36 struct hdmi_pll_8996
{
37 struct platform_device
*pdev
;
41 void __iomem
*mmio_qserdes_com
;
43 void __iomem
*mmio_qserdes_tx
[HDMI_NUM_TX_CHANNEL
];
46 #define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8996, clk_hw)
48 struct 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
;
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
;
63 u32 com_lock_cmp1_mode0
;
64 u32 com_lock_cmp2_mode0
;
65 u32 com_lock_cmp3_mode0
;
68 u32 com_vco_tune_ctrl
;
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
];
80 struct hdmi_8996_post_divider
{
88 static inline struct hdmi_phy
*pll_get_phy(struct hdmi_pll_8996
*pll
)
90 return platform_get_drvdata(pll
->pdev
);
93 static inline void hdmi_pll_write(struct hdmi_pll_8996
*pll
, int offset
,
96 msm_writel(data
, pll
->mmio_qserdes_com
+ offset
);
99 static inline u32
hdmi_pll_read(struct hdmi_pll_8996
*pll
, int offset
)
101 return msm_readl(pll
->mmio_qserdes_com
+ offset
);
104 static inline void hdmi_tx_chan_write(struct hdmi_pll_8996
*pll
, int channel
,
105 int offset
, int data
)
107 msm_writel(data
, pll
->mmio_qserdes_tx
[channel
] + offset
);
110 static inline u32
pll_get_cpctrl(u64 frac_start
, unsigned long ref_clk
,
113 if ((frac_start
!= 0) || gen_ssc
)
114 return (11000000 / (ref_clk
/ 20));
119 static inline u32
pll_get_rctrl(u64 frac_start
, bool gen_ssc
)
121 if ((frac_start
!= 0) || gen_ssc
)
127 static inline u32
pll_get_cctrl(u64 frac_start
, bool gen_ssc
)
129 if ((frac_start
!= 0) || gen_ssc
)
135 static inline u32
pll_get_integloop_gain(u64 frac_start
, u64 bclk
, u32 ref_clk
,
138 int digclk_divsel
= bclk
>= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD
? 1 : 2;
141 if ((frac_start
!= 0) || gen_ssc
)
142 base
= (64 * ref_clk
) / HDMI_DEFAULT_REF_CLOCK
;
144 base
= (1022 * ref_clk
) / 100;
146 base
<<= digclk_divsel
;
148 return (base
<= 2046 ? base
: 2046);
151 static inline u32
pll_get_pll_cmp(u64 fdata
, unsigned long ref_clk
)
153 u64 dividend
= HDMI_PLL_CMP_CNT
* fdata
;
154 u32 divisor
= ref_clk
* 10;
157 rem
= do_div(dividend
, divisor
);
158 if (rem
> (divisor
>> 1))
164 static inline u64
pll_cmp_to_fdata(u32 pll_cmp
, unsigned long ref_clk
)
166 u64 fdata
= ((u64
)pll_cmp
) * ref_clk
* 10;
168 do_div(fdata
, HDMI_PLL_CMP_CNT
);
173 static int pll_get_post_div(struct hdmi_8996_post_divider
*pd
, u64 bclk
)
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 };
179 u64 vco
, vco_optimal
;
180 int half_rate_mode
= 0;
181 int vco_optimal_index
, vco_freq_index
;
185 vco_optimal
= HDMI_VCO_MAX_FREQ
;
186 vco_optimal_index
= -1;
188 for (i
= 0; i
< 15; i
++) {
189 for (j
= 0; j
< 4; j
++) {
190 u32 ratio_mult
= ratio
[i
] << tx_band_sel
[j
];
192 vco
= bclk
>> half_rate_mode
;
194 vco_freq
[vco_freq_index
++] = vco
;
198 for (i
= 0; i
< 60; i
++) {
199 u64 vco_tmp
= vco_freq
[i
];
201 if ((vco_tmp
>= HDMI_VCO_MIN_FREQ
) &&
202 (vco_tmp
<= vco_optimal
)) {
203 vco_optimal
= vco_tmp
;
204 vco_optimal_index
= i
;
208 if (vco_optimal_index
== -1) {
209 if (!half_rate_mode
) {
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];
225 static int pll_calculate(unsigned long pix_clk
, unsigned long ref_clk
,
226 struct hdmi_8996_phy_pll_reg_cfg
*cfg
)
228 struct hdmi_8996_post_divider pd
;
243 /* bit clk = 10 * pix_clk */
244 bclk
= ((u64
)pix_clk
) * 10;
246 if (bclk
> HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD
)
247 tmds_clk
= pix_clk
>> 2;
251 ret
= pll_get_post_div(&pd
, bclk
);
255 dec_start
= pd
.vco_freq
;
256 pll_divisor
= 4 * ref_clk
;
257 do_div(dec_start
, pll_divisor
);
259 frac_start
= pd
.vco_freq
* (1 << 20);
261 rem
= do_div(frac_start
, pll_divisor
);
262 frac_start
-= dec_start
* (1 << 20);
263 if (rem
> (pll_divisor
>> 1))
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
,
273 do_div(fdata
, pd
.vco_ratio
);
275 pll_cmp
= pll_get_pll_cmp(fdata
, ref_clk
);
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
);
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;
295 cfg
->com_svs_mode_clk_sel
= 2;
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;
316 cfg
->tx_lx_lane_mode
[0] =
317 cfg
->tx_lx_lane_mode
[2] = 0x43;
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;
324 for (i
= 0; i
< HDMI_NUM_TX_CHANNEL
; i
++)
325 cfg
->tx_lx_tx_band
[i
] = pd
.tx_band_sel
+ 4;
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;
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;
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;
343 cfg
->tx_lx_vmode_ctrl2
[0] =
344 cfg
->tx_lx_vmode_ctrl2
[1] =
345 cfg
->tx_lx_vmode_ctrl2
[2] = 0x0D;
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;
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;
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;
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
);
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]);
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
]);
402 static int hdmi_8996_pll_set_clk_rate(struct clk_hw
*hw
, unsigned long rate
,
403 unsigned long parent_rate
)
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
;
410 memset(&cfg
, 0x00, sizeof(cfg
));
412 ret
= pll_calculate(rate
, parent_rate
, &cfg
);
414 DRM_ERROR("PLL calculation failed\n");
418 /* Initially shut down PHY */
419 DBG("Disabling PHY");
420 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_PD_CTL
, 0x0);
423 /* Power up sequence */
424 hdmi_pll_write(pll
, REG_HDMI_PHY_QSERDES_COM_BG_CTRL
, 0x04);
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);
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
,
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
,
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]);
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);
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
);
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
);
463 hdmi_pll_write(pll
, REG_HDMI_PHY_QSERDES_COM_BG_CTRL
, 0x06);
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
,
468 hdmi_pll_write(pll
, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN
,
469 cfg
.com_lock_cmp_en
);
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
);
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
);
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
);
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);
505 hdmi_pll_write(pll
, REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM
, 0x15);
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
,
524 hdmi_tx_chan_write(pll
, i
,
525 REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET
,
527 hdmi_tx_chan_write(pll
, i
,
528 REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN
,
530 hdmi_tx_chan_write(pll
, i
,
531 REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN
,
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
]);
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);
542 * Ensure that vco configuration gets flushed to hardware before
550 static int hdmi_8996_phy_ready_status(struct hdmi_phy
*phy
)
552 u32 nb_tries
= HDMI_PLL_POLL_MAX_READS
;
553 unsigned long timeout
= HDMI_PLL_POLL_TIMEOUT_US
;
557 DBG("Waiting for PHY ready");
560 status
= hdmi_phy_read(phy
, REG_HDMI_8996_PHY_STATUS
);
561 phy_ready
= status
& BIT(0);
569 DBG("PHY is %sready", phy_ready
? "" : "*not* ");
574 static int hdmi_8996_pll_lock_status(struct hdmi_pll_8996
*pll
)
577 int nb_tries
= HDMI_PLL_POLL_MAX_READS
;
578 unsigned long timeout
= HDMI_PLL_POLL_TIMEOUT_US
;
581 DBG("Waiting for PLL lock");
584 status
= hdmi_pll_read(pll
,
585 REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS
);
586 pll_locked
= status
& BIT(0);
594 DBG("HDMI PLL is %slocked", pll_locked
? "" : "*not* ");
599 static int hdmi_8996_pll_prepare(struct clk_hw
*hw
)
601 struct hdmi_pll_8996
*pll
= hw_clk_to_pll(hw
);
602 struct hdmi_phy
*phy
= pll_get_phy(pll
);
605 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x1);
608 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x19);
611 ret
= hdmi_8996_pll_lock_status(pll
);
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
,
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);
627 ret
= hdmi_8996_phy_ready_status(phy
);
631 /* Restart the retiming buffer */
632 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x18);
634 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x19);
639 static long hdmi_8996_pll_round_rate(struct clk_hw
*hw
,
641 unsigned long *parent_rate
)
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
;
651 static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw
*hw
,
652 unsigned long parent_rate
)
654 struct hdmi_pll_8996
*pll
= hw_clk_to_pll(hw
);
656 u32 cmp1
, cmp2
, cmp3
, pll_cmp
;
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
);
662 pll_cmp
= cmp1
| (cmp2
<< 8) | (cmp3
<< 16);
664 fdata
= pll_cmp_to_fdata(pll_cmp
+ 1, parent_rate
);
671 static void hdmi_8996_pll_unprepare(struct clk_hw
*hw
)
673 struct hdmi_pll_8996
*pll
= hw_clk_to_pll(hw
);
674 struct hdmi_phy
*phy
= pll_get_phy(pll
);
676 hdmi_phy_write(phy
, REG_HDMI_8996_PHY_CFG
, 0x6);
677 usleep_range(100, 150);
680 static int hdmi_8996_pll_is_enabled(struct clk_hw
*hw
)
682 struct hdmi_pll_8996
*pll
= hw_clk_to_pll(hw
);
686 status
= hdmi_pll_read(pll
, REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS
);
687 pll_locked
= status
& BIT(0);
692 static struct clk_ops hdmi_8996_pll_ops
= {
693 .set_rate
= hdmi_8996_pll_set_clk_rate
,
694 .round_rate
= hdmi_8996_pll_round_rate
,
695 .recalc_rate
= hdmi_8996_pll_recalc_rate
,
696 .prepare
= hdmi_8996_pll_prepare
,
697 .unprepare
= hdmi_8996_pll_unprepare
,
698 .is_enabled
= hdmi_8996_pll_is_enabled
,
701 static const char * const hdmi_pll_parents
[] = {
705 static struct clk_init_data pll_init
= {
707 .ops
= &hdmi_8996_pll_ops
,
708 .parent_names
= hdmi_pll_parents
,
709 .num_parents
= ARRAY_SIZE(hdmi_pll_parents
),
710 .flags
= CLK_IGNORE_UNUSED
,
713 int msm_hdmi_pll_8996_init(struct platform_device
*pdev
)
715 struct device
*dev
= &pdev
->dev
;
716 struct hdmi_pll_8996
*pll
;
720 pll
= devm_kzalloc(dev
, sizeof(*pll
), GFP_KERNEL
);
726 pll
->mmio_qserdes_com
= msm_ioremap(pdev
, "hdmi_pll", "HDMI_PLL");
727 if (IS_ERR(pll
->mmio_qserdes_com
)) {
728 DRM_DEV_ERROR(dev
, "failed to map pll base\n");
732 for (i
= 0; i
< HDMI_NUM_TX_CHANNEL
; i
++) {
733 char name
[32], label
[32];
735 snprintf(name
, sizeof(name
), "hdmi_tx_l%d", i
);
736 snprintf(label
, sizeof(label
), "HDMI_TX_L%d", i
);
738 pll
->mmio_qserdes_tx
[i
] = msm_ioremap(pdev
, name
, label
);
739 if (IS_ERR(pll
->mmio_qserdes_tx
[i
])) {
740 DRM_DEV_ERROR(dev
, "failed to map pll base\n");
744 pll
->clk_hw
.init
= &pll_init
;
746 clk
= devm_clk_register(dev
, &pll
->clk_hw
);
748 DRM_DEV_ERROR(dev
, "failed to register pll clock\n");
755 static const char * const hdmi_phy_8996_reg_names
[] = {
760 static const char * const hdmi_phy_8996_clk_names
[] = {
764 const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg
= {
765 .type
= MSM_HDMI_PHY_8996
,
766 .reg_names
= hdmi_phy_8996_reg_names
,
767 .num_regs
= ARRAY_SIZE(hdmi_phy_8996_reg_names
),
768 .clk_names
= hdmi_phy_8996_clk_names
,
769 .num_clks
= ARRAY_SIZE(hdmi_phy_8996_clk_names
),