xref: /linux/drivers/gpu/drm/msm/hdmi/hdmi_phy_8998.c (revision b8ea7da314c2efcb9c2f559ed65b7a36c869d68e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2016, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2024 Freebox SAS
5  */
6 
7 #include <linux/clk-provider.h>
8 #include <linux/delay.h>
9 
10 #include "hdmi.h"
11 
12 #define HDMI_VCO_MAX_FREQ			12000000000UL
13 #define HDMI_VCO_MIN_FREQ			8000000000UL
14 
15 #define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD	3400000000UL
16 #define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD		1500000000UL
17 #define HDMI_MID_FREQ_BIT_CLK_THRESHOLD		750000000UL
18 #define HDMI_CORECLK_DIV			5
19 #define HDMI_DEFAULT_REF_CLOCK			19200000
20 #define HDMI_PLL_CMP_CNT			1024
21 
22 #define HDMI_PLL_POLL_MAX_READS			100
23 #define HDMI_PLL_POLL_TIMEOUT_US		150
24 
25 #define HDMI_NUM_TX_CHANNEL			4
26 
27 struct hdmi_pll_8998 {
28 	struct platform_device *pdev;
29 	struct clk_hw clk_hw;
30 	unsigned long rate;
31 
32 	/* pll mmio base */
33 	void __iomem *mmio_qserdes_com;
34 	/* tx channel base */
35 	void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL];
36 };
37 
38 #define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8998, clk_hw)
39 
40 struct hdmi_8998_phy_pll_reg_cfg {
41 	u32 com_svs_mode_clk_sel;
42 	u32 com_hsclk_sel;
43 	u32 com_pll_cctrl_mode0;
44 	u32 com_pll_rctrl_mode0;
45 	u32 com_cp_ctrl_mode0;
46 	u32 com_dec_start_mode0;
47 	u32 com_div_frac_start1_mode0;
48 	u32 com_div_frac_start2_mode0;
49 	u32 com_div_frac_start3_mode0;
50 	u32 com_integloop_gain0_mode0;
51 	u32 com_integloop_gain1_mode0;
52 	u32 com_lock_cmp_en;
53 	u32 com_lock_cmp1_mode0;
54 	u32 com_lock_cmp2_mode0;
55 	u32 com_lock_cmp3_mode0;
56 	u32 com_core_clk_en;
57 	u32 com_coreclk_div_mode0;
58 
59 	u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL];
60 	u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL];
61 	u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL];
62 	u32 tx_lx_pre_driver_1[HDMI_NUM_TX_CHANNEL];
63 	u32 tx_lx_pre_driver_2[HDMI_NUM_TX_CHANNEL];
64 	u32 tx_lx_res_code_offset[HDMI_NUM_TX_CHANNEL];
65 
66 	u32 phy_mode;
67 };
68 
69 struct hdmi_8998_post_divider {
70 	u64 vco_freq;
71 	int hsclk_divsel;
72 	int vco_ratio;
73 	int tx_band_sel;
74 	int half_rate_mode;
75 };
76 
77 static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8998 *pll)
78 {
79 	return platform_get_drvdata(pll->pdev);
80 }
81 
82 static inline void hdmi_pll_write(struct hdmi_pll_8998 *pll, int offset,
83 				  u32 data)
84 {
85 	writel(data, pll->mmio_qserdes_com + offset);
86 }
87 
88 static inline u32 hdmi_pll_read(struct hdmi_pll_8998 *pll, int offset)
89 {
90 	return readl(pll->mmio_qserdes_com + offset);
91 }
92 
93 static inline void hdmi_tx_chan_write(struct hdmi_pll_8998 *pll, int channel,
94 				      int offset, int data)
95 {
96 	 writel(data, pll->mmio_qserdes_tx[channel] + offset);
97 }
98 
99 static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk,
100 				 bool gen_ssc)
101 {
102 	if ((frac_start != 0) || gen_ssc)
103 		return 0x8;
104 
105 	return 0x30;
106 }
107 
108 static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc)
109 {
110 	if ((frac_start != 0) || gen_ssc)
111 		return 0x16;
112 
113 	return 0x18;
114 }
115 
116 static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc)
117 {
118 	if ((frac_start != 0) || gen_ssc)
119 		return 0x34;
120 
121 	return 0x2;
122 }
123 
124 static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk,
125 					 bool gen_ssc)
126 {
127 	int digclk_divsel = bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2;
128 	u64 base;
129 
130 	if ((frac_start != 0) || gen_ssc)
131 		base = 0x3F;
132 	else
133 		base = 0xC4;
134 
135 	base <<= (digclk_divsel == 2 ? 1 : 0);
136 
137 	return base;
138 }
139 
140 static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk)
141 {
142 	u64 dividend = HDMI_PLL_CMP_CNT * fdata;
143 	u32 divisor = ref_clk * 10;
144 	u32 rem;
145 
146 	rem = do_div(dividend, divisor);
147 	if (rem > (divisor >> 1))
148 		dividend++;
149 
150 	return dividend - 1;
151 }
152 
153 #define HDMI_REF_CLOCK_HZ ((u64)19200000)
154 #define HDMI_MHZ_TO_HZ ((u64)1000000)
155 static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk)
156 {
157 	static const u32 ratio_list[] = {1, 2, 3, 4, 5, 6, 9, 10, 12, 15, 25};
158 	static const u32 band_list[] = {0, 1, 2, 3};
159 	u32 const sz_ratio = ARRAY_SIZE(ratio_list);
160 	u32 const sz_band = ARRAY_SIZE(band_list);
161 	u32 const cmp_cnt = 1024;
162 	u32 const th_min = 500, th_max = 1000;
163 	u32 half_rate_mode = 0;
164 	u32 list_elements;
165 	int optimal_index;
166 	u32 i, j, k;
167 	u32 found_hsclk_divsel = 0, found_vco_ratio;
168 	u32 found_tx_band_sel;
169 	u64 const min_freq = HDMI_VCO_MIN_FREQ, max_freq = HDMI_VCO_MAX_FREQ;
170 	u64 freq_list[ARRAY_SIZE(ratio_list) * ARRAY_SIZE(band_list)];
171 	u64 found_vco_freq;
172 	u64 freq_optimal;
173 
174 find_optimal_index:
175 	freq_optimal = max_freq;
176 	optimal_index = -1;
177 	list_elements = 0;
178 
179 	for (i = 0; i < sz_ratio; i++) {
180 		for (j = 0; j < sz_band; j++) {
181 			u64 freq = div_u64(bclk, (1 << half_rate_mode));
182 
183 			freq *= (ratio_list[i] * (1 << band_list[j]));
184 			freq_list[list_elements++] = freq;
185 		}
186 	}
187 
188 	for (k = 0; k < ARRAY_SIZE(freq_list); k++) {
189 		u32 const clks_pll_div = 2, core_clk_div = 5;
190 		u32 const rng1 = 16, rng2 = 8;
191 		u32 th1, th2;
192 		u64 core_clk, rvar1, rem;
193 
194 		core_clk = div_u64(freq_list[k],
195 				   ratio_list[k / sz_band] * clks_pll_div *
196 				   core_clk_div);
197 
198 		rvar1 = HDMI_REF_CLOCK_HZ * rng1 * HDMI_MHZ_TO_HZ;
199 		rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem);
200 		if (rem > ((cmp_cnt * core_clk) >> 1))
201 			rvar1++;
202 		th1 = rvar1;
203 
204 		rvar1 = HDMI_REF_CLOCK_HZ * rng2 * HDMI_MHZ_TO_HZ;
205 		rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem);
206 		if (rem > ((cmp_cnt * core_clk) >> 1))
207 			rvar1++;
208 		th2 = rvar1;
209 
210 		if (freq_list[k] >= min_freq &&
211 				freq_list[k] <= max_freq) {
212 			if ((th1 >= th_min && th1 <= th_max) ||
213 					(th2 >= th_min && th2 <= th_max)) {
214 				if (freq_list[k] <= freq_optimal) {
215 					freq_optimal = freq_list[k];
216 					optimal_index = k;
217 				}
218 			}
219 		}
220 	}
221 
222 	if (optimal_index == -1) {
223 		if (!half_rate_mode) {
224 			half_rate_mode = 1;
225 			goto find_optimal_index;
226 		} else {
227 			return -EINVAL;
228 		}
229 	} else {
230 		found_vco_ratio = ratio_list[optimal_index / sz_band];
231 		found_tx_band_sel = band_list[optimal_index % sz_band];
232 		found_vco_freq = freq_optimal;
233 	}
234 
235 	switch (found_vco_ratio) {
236 	case 1:
237 		found_hsclk_divsel = 15;
238 		break;
239 	case 2:
240 		found_hsclk_divsel = 0;
241 		break;
242 	case 3:
243 		found_hsclk_divsel = 4;
244 		break;
245 	case 4:
246 		found_hsclk_divsel = 8;
247 		break;
248 	case 5:
249 		found_hsclk_divsel = 12;
250 		break;
251 	case 6:
252 		found_hsclk_divsel = 1;
253 		break;
254 	case 9:
255 		found_hsclk_divsel = 5;
256 		break;
257 	case 10:
258 		found_hsclk_divsel = 2;
259 		break;
260 	case 12:
261 		found_hsclk_divsel = 9;
262 		break;
263 	case 15:
264 		found_hsclk_divsel = 13;
265 		break;
266 	case 25:
267 		found_hsclk_divsel = 14;
268 		break;
269 	}
270 
271 	pd->vco_freq = found_vco_freq;
272 	pd->tx_band_sel = found_tx_band_sel;
273 	pd->vco_ratio = found_vco_ratio;
274 	pd->hsclk_divsel = found_hsclk_divsel;
275 
276 	return 0;
277 }
278 
279 static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk,
280 			 struct hdmi_8998_phy_pll_reg_cfg *cfg)
281 {
282 	struct hdmi_8998_post_divider pd;
283 	u64 bclk;
284 	u64 dec_start;
285 	u64 frac_start;
286 	u64 fdata;
287 	u32 pll_divisor;
288 	u32 rem;
289 	u32 cpctrl;
290 	u32 rctrl;
291 	u32 cctrl;
292 	u32 integloop_gain;
293 	u32 pll_cmp;
294 	int i, ret;
295 
296 	/* bit clk = 10 * pix_clk */
297 	bclk = ((u64)pix_clk) * 10;
298 
299 	ret = pll_get_post_div(&pd, bclk);
300 	if (ret)
301 		return ret;
302 
303 	dec_start = pd.vco_freq;
304 	pll_divisor = 4 * ref_clk;
305 	do_div(dec_start, pll_divisor);
306 
307 	frac_start = pd.vco_freq * (1 << 20);
308 
309 	rem = do_div(frac_start, pll_divisor);
310 	frac_start -= dec_start * (1 << 20);
311 	if (rem > (pll_divisor >> 1))
312 		frac_start++;
313 
314 	cpctrl = pll_get_cpctrl(frac_start, ref_clk, false);
315 	rctrl = pll_get_rctrl(frac_start, false);
316 	cctrl = pll_get_cctrl(frac_start, false);
317 	integloop_gain = pll_get_integloop_gain(frac_start, bclk,
318 						ref_clk, false);
319 
320 	fdata = pd.vco_freq;
321 	do_div(fdata, pd.vco_ratio);
322 
323 	pll_cmp = pll_get_pll_cmp(fdata, ref_clk);
324 
325 	/* Convert these values to register specific values */
326 	if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
327 		cfg->com_svs_mode_clk_sel = 1;
328 	else
329 		cfg->com_svs_mode_clk_sel = 2;
330 
331 	cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel);
332 	cfg->com_pll_cctrl_mode0 = cctrl;
333 	cfg->com_pll_rctrl_mode0 = rctrl;
334 	cfg->com_cp_ctrl_mode0 = cpctrl;
335 	cfg->com_dec_start_mode0 = dec_start;
336 	cfg->com_div_frac_start1_mode0 = (frac_start & 0xff);
337 	cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8);
338 	cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16);
339 	cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff);
340 	cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8);
341 	cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff);
342 	cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8);
343 	cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
344 	cfg->com_lock_cmp_en = 0x0;
345 	cfg->com_core_clk_en = 0x2c;
346 	cfg->com_coreclk_div_mode0 = HDMI_CORECLK_DIV;
347 	cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x5 : 0x4;
348 
349 	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
350 		cfg->tx_lx_tx_band[i] = pd.tx_band_sel;
351 
352 	if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
353 		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
354 		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
355 		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
356 		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
357 		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x03;
358 		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x02;
359 		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x03;
360 		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
361 		cfg->tx_lx_pre_driver_1[0] = 0x00;
362 		cfg->tx_lx_pre_driver_1[1] = 0x00;
363 		cfg->tx_lx_pre_driver_1[2] = 0x00;
364 		cfg->tx_lx_pre_driver_1[3] = 0x00;
365 		cfg->tx_lx_pre_driver_2[0] = 0x1C;
366 		cfg->tx_lx_pre_driver_2[1] = 0x1C;
367 		cfg->tx_lx_pre_driver_2[2] = 0x1C;
368 		cfg->tx_lx_pre_driver_2[3] = 0x00;
369 		cfg->tx_lx_res_code_offset[0] = 0x03;
370 		cfg->tx_lx_res_code_offset[1] = 0x00;
371 		cfg->tx_lx_res_code_offset[2] = 0x00;
372 		cfg->tx_lx_res_code_offset[3] = 0x03;
373 	} else if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) {
374 		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
375 		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
376 		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
377 		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
378 		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x03;
379 		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x03;
380 		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x03;
381 		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
382 		cfg->tx_lx_pre_driver_1[0] = 0x00;
383 		cfg->tx_lx_pre_driver_1[1] = 0x00;
384 		cfg->tx_lx_pre_driver_1[2] = 0x00;
385 		cfg->tx_lx_pre_driver_1[3] = 0x00;
386 		cfg->tx_lx_pre_driver_2[0] = 0x16;
387 		cfg->tx_lx_pre_driver_2[1] = 0x16;
388 		cfg->tx_lx_pre_driver_2[2] = 0x16;
389 		cfg->tx_lx_pre_driver_2[3] = 0x18;
390 		cfg->tx_lx_res_code_offset[0] = 0x03;
391 		cfg->tx_lx_res_code_offset[1] = 0x00;
392 		cfg->tx_lx_res_code_offset[2] = 0x00;
393 		cfg->tx_lx_res_code_offset[3] = 0x00;
394 	} else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
395 		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
396 		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
397 		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
398 		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
399 		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x05;
400 		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x05;
401 		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x05;
402 		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
403 		cfg->tx_lx_pre_driver_1[0] = 0x00;
404 		cfg->tx_lx_pre_driver_1[1] = 0x00;
405 		cfg->tx_lx_pre_driver_1[2] = 0x00;
406 		cfg->tx_lx_pre_driver_1[3] = 0x00;
407 		cfg->tx_lx_pre_driver_2[0] = 0x0E;
408 		cfg->tx_lx_pre_driver_2[1] = 0x0E;
409 		cfg->tx_lx_pre_driver_2[2] = 0x0E;
410 		cfg->tx_lx_pre_driver_2[3] = 0x0E;
411 		cfg->tx_lx_res_code_offset[0] = 0x00;
412 		cfg->tx_lx_res_code_offset[1] = 0x00;
413 		cfg->tx_lx_res_code_offset[2] = 0x00;
414 		cfg->tx_lx_res_code_offset[3] = 0x00;
415 	} else {
416 		cfg->tx_lx_tx_drv_lvl[0] = 0x01;
417 		cfg->tx_lx_tx_drv_lvl[1] = 0x01;
418 		cfg->tx_lx_tx_drv_lvl[2] = 0x01;
419 		cfg->tx_lx_tx_drv_lvl[3] = 0x00;
420 		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x00;
421 		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x00;
422 		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x00;
423 		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
424 		cfg->tx_lx_pre_driver_1[0] = 0x00;
425 		cfg->tx_lx_pre_driver_1[1] = 0x00;
426 		cfg->tx_lx_pre_driver_1[2] = 0x00;
427 		cfg->tx_lx_pre_driver_1[3] = 0x00;
428 		cfg->tx_lx_pre_driver_2[0] = 0x16;
429 		cfg->tx_lx_pre_driver_2[1] = 0x16;
430 		cfg->tx_lx_pre_driver_2[2] = 0x16;
431 		cfg->tx_lx_pre_driver_2[3] = 0x18;
432 		cfg->tx_lx_res_code_offset[0] = 0x00;
433 		cfg->tx_lx_res_code_offset[1] = 0x00;
434 		cfg->tx_lx_res_code_offset[2] = 0x00;
435 		cfg->tx_lx_res_code_offset[3] = 0x00;
436 	}
437 
438 	return 0;
439 }
440 
441 static int hdmi_8998_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate,
442 				      unsigned long parent_rate)
443 {
444 	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
445 	struct hdmi_phy *phy = pll_get_phy(pll);
446 	struct hdmi_8998_phy_pll_reg_cfg cfg = {};
447 	int i, ret;
448 
449 	ret = pll_calculate(rate, parent_rate, &cfg);
450 	if (ret) {
451 		DRM_ERROR("PLL calculation failed\n");
452 		return ret;
453 	}
454 
455 	/* Initially shut down PHY */
456 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0x0);
457 	udelay(500);
458 
459 	/* Power up sequence */
460 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0x1);
461 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20);
462 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CMN_CTRL, 0x6);
463 
464 	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
465 		hdmi_tx_chan_write(pll, i,
466 				   REG_HDMI_8998_PHY_TXn_INTERFACE_SELECT_TX_BAND,
467 				   cfg.tx_lx_tx_band[i]);
468 		hdmi_tx_chan_write(pll, i,
469 				   REG_HDMI_8998_PHY_TXn_CLKBUF_TERM_ENABLE,
470 				   0x1);
471 		hdmi_tx_chan_write(pll, i,
472 				   REG_HDMI_8998_PHY_TXn_LANE_MODE,
473 				   0x20);
474 	}
475 
476 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x02);
477 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x0B);
478 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37);
479 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02);
480 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E);
481 
482 	/* Bypass VCO calibration */
483 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SVS_MODE_CLK_SEL,
484 		       cfg.com_svs_mode_clk_sel);
485 
486 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_IVCO, 0x07);
487 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_VCO_TUNE_CTRL, 0x00);
488 
489 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CLK_SEL, 0x30);
490 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_HSCLK_SEL,
491 		       cfg.com_hsclk_sel);
492 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP_EN,
493 		       cfg.com_lock_cmp_en);
494 
495 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_CCTRL_MODE0,
496 		       cfg.com_pll_cctrl_mode0);
497 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_RCTRL_MODE0,
498 		       cfg.com_pll_rctrl_mode0);
499 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CP_CTRL_MODE0,
500 		       cfg.com_cp_ctrl_mode0);
501 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DEC_START_MODE0,
502 		       cfg.com_dec_start_mode0);
503 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0,
504 		       cfg.com_div_frac_start1_mode0);
505 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0,
506 		       cfg.com_div_frac_start2_mode0);
507 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0,
508 		       cfg.com_div_frac_start3_mode0);
509 
510 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
511 		       cfg.com_integloop_gain0_mode0);
512 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
513 		       cfg.com_integloop_gain1_mode0);
514 
515 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP1_MODE0,
516 		       cfg.com_lock_cmp1_mode0);
517 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP2_MODE0,
518 		       cfg.com_lock_cmp2_mode0);
519 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP3_MODE0,
520 		       cfg.com_lock_cmp3_mode0);
521 
522 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00);
523 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CORE_CLK_EN,
524 		       cfg.com_core_clk_en);
525 	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CORECLK_DIV_MODE0,
526 		       cfg.com_coreclk_div_mode0);
527 
528 	/* TX lanes setup (TX 0/1/2/3) */
529 	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
530 		hdmi_tx_chan_write(pll, i,
531 				   REG_HDMI_8998_PHY_TXn_DRV_LVL,
532 				   cfg.tx_lx_tx_drv_lvl[i]);
533 		hdmi_tx_chan_write(pll, i,
534 				   REG_HDMI_8998_PHY_TXn_EMP_POST1_LVL,
535 				   cfg.tx_lx_tx_emp_post1_lvl[i]);
536 		hdmi_tx_chan_write(pll, i,
537 				   REG_HDMI_8998_PHY_TXn_PRE_DRIVER_1,
538 				   cfg.tx_lx_pre_driver_1[i]);
539 		hdmi_tx_chan_write(pll, i,
540 				   REG_HDMI_8998_PHY_TXn_PRE_DRIVER_2,
541 				   cfg.tx_lx_pre_driver_2[i]);
542 		hdmi_tx_chan_write(pll, i,
543 				   REG_HDMI_8998_PHY_TXn_DRV_LVL_RES_CODE_OFFSET,
544 				   cfg.tx_lx_res_code_offset[i]);
545 	}
546 
547 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_MODE, cfg.phy_mode);
548 
549 	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
550 		hdmi_tx_chan_write(pll, i,
551 				   REG_HDMI_8998_PHY_TXn_LANE_CONFIG,
552 				   0x10);
553 	}
554 
555 	/*
556 	 * Ensure that vco configuration gets flushed to hardware before
557 	 * enabling the PLL
558 	 */
559 	wmb();
560 
561 	pll->rate = rate;
562 
563 	return 0;
564 }
565 
566 static int hdmi_8998_phy_ready_status(struct hdmi_phy *phy)
567 {
568 	u32 nb_tries = HDMI_PLL_POLL_MAX_READS;
569 	unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
570 	u32 status;
571 	int phy_ready = 0;
572 
573 	while (nb_tries--) {
574 		status = hdmi_phy_read(phy, REG_HDMI_8998_PHY_STATUS);
575 		phy_ready = status & BIT(0);
576 
577 		if (phy_ready)
578 			break;
579 
580 		udelay(timeout);
581 	}
582 
583 	return phy_ready;
584 }
585 
586 static int hdmi_8998_pll_lock_status(struct hdmi_pll_8998 *pll)
587 {
588 	u32 status;
589 	int nb_tries = HDMI_PLL_POLL_MAX_READS;
590 	unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
591 	int pll_locked = 0;
592 
593 	while (nb_tries--) {
594 		status = hdmi_pll_read(pll,
595 				       REG_HDMI_8998_PHY_QSERDES_COM_C_READY_STATUS);
596 		pll_locked = status & BIT(0);
597 
598 		if (pll_locked)
599 			break;
600 
601 		udelay(timeout);
602 	}
603 
604 	return pll_locked;
605 }
606 
607 static int hdmi_8998_pll_prepare(struct clk_hw *hw)
608 {
609 	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
610 	struct hdmi_phy *phy = pll_get_phy(pll);
611 	int i, ret = 0;
612 
613 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x1);
614 	udelay(100);
615 
616 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x59);
617 	udelay(100);
618 
619 	ret = hdmi_8998_pll_lock_status(pll);
620 	if (!ret)
621 		return ret;
622 
623 	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
624 		hdmi_tx_chan_write(pll, i,
625 				   REG_HDMI_8998_PHY_TXn_LANE_CONFIG, 0x1F);
626 	}
627 
628 	/* Ensure all registers are flushed to hardware */
629 	wmb();
630 
631 	ret = hdmi_8998_phy_ready_status(phy);
632 	if (!ret)
633 		return ret;
634 
635 	/* Restart the retiming buffer */
636 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x58);
637 	udelay(1);
638 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x59);
639 
640 	/* Ensure all registers are flushed to hardware */
641 	wmb();
642 
643 	return 0;
644 }
645 
646 static int hdmi_8998_pll_determine_rate(struct clk_hw *hw,
647 					struct clk_rate_request *req)
648 {
649 	req->rate = clamp_t(unsigned long, req->rate, HDMI_TMDS_CHAR_RATE_MIN_HZ,
650 			    HDMI_2_0_TMDS_CHAR_RATE_MAX_HZ);
651 
652 	return 0;
653 }
654 
655 static unsigned long hdmi_8998_pll_recalc_rate(struct clk_hw *hw,
656 					       unsigned long parent_rate)
657 {
658 	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
659 	return pll->rate;
660 }
661 
662 static void hdmi_8998_pll_unprepare(struct clk_hw *hw)
663 {
664 	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
665 	struct hdmi_phy *phy = pll_get_phy(pll);
666 
667 	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0);
668 	usleep_range(100, 150);
669 }
670 
671 static int hdmi_8998_pll_is_enabled(struct clk_hw *hw)
672 {
673 	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
674 	u32 status;
675 	int pll_locked;
676 
677 	status = hdmi_pll_read(pll, REG_HDMI_8998_PHY_QSERDES_COM_C_READY_STATUS);
678 	pll_locked = status & BIT(0);
679 
680 	return pll_locked;
681 }
682 
683 static const struct clk_ops hdmi_8998_pll_ops = {
684 	.set_rate = hdmi_8998_pll_set_clk_rate,
685 	.determine_rate = hdmi_8998_pll_determine_rate,
686 	.recalc_rate = hdmi_8998_pll_recalc_rate,
687 	.prepare = hdmi_8998_pll_prepare,
688 	.unprepare = hdmi_8998_pll_unprepare,
689 	.is_enabled = hdmi_8998_pll_is_enabled,
690 };
691 
692 static const struct clk_init_data pll_init = {
693 	.name = "hdmipll",
694 	.ops = &hdmi_8998_pll_ops,
695 	.parent_data = (const struct clk_parent_data[]){
696 		{ .fw_name = "xo", .name = "xo_board" },
697 	},
698 	.num_parents = 1,
699 	.flags = CLK_IGNORE_UNUSED,
700 };
701 
702 int msm_hdmi_pll_8998_init(struct platform_device *pdev)
703 {
704 	struct device *dev = &pdev->dev;
705 	struct hdmi_pll_8998 *pll;
706 	int ret, i;
707 
708 	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
709 	if (!pll)
710 		return -ENOMEM;
711 
712 	pll->pdev = pdev;
713 
714 	pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll");
715 	if (IS_ERR(pll->mmio_qserdes_com)) {
716 		DRM_DEV_ERROR(dev, "failed to map pll base\n");
717 		return -ENOMEM;
718 	}
719 
720 	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
721 		char name[32];
722 
723 		snprintf(name, sizeof(name), "hdmi_tx_l%d", i);
724 
725 		pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name);
726 		if (IS_ERR(pll->mmio_qserdes_tx[i])) {
727 			DRM_DEV_ERROR(dev, "failed to map pll base\n");
728 			return -ENOMEM;
729 		}
730 	}
731 	pll->clk_hw.init = &pll_init;
732 
733 	ret = devm_clk_hw_register(dev, &pll->clk_hw);
734 	if (ret) {
735 		DRM_DEV_ERROR(dev, "failed to register pll clock\n");
736 		return ret;
737 	}
738 
739 	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw);
740 	if (ret) {
741 		DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
742 		return ret;
743 	}
744 
745 	return 0;
746 }
747 
748 static const char * const hdmi_phy_8998_reg_names[] = {
749 	"vddio",
750 	"vcca",
751 };
752 
753 static const char * const hdmi_phy_8998_clk_names[] = {
754 	"iface", "ref", "xo",
755 };
756 
757 const struct hdmi_phy_cfg msm_hdmi_phy_8998_cfg = {
758 	.type = MSM_HDMI_PHY_8998,
759 	.reg_names = hdmi_phy_8998_reg_names,
760 	.num_regs = ARRAY_SIZE(hdmi_phy_8998_reg_names),
761 	.clk_names = hdmi_phy_8998_clk_names,
762 	.num_clks = ARRAY_SIZE(hdmi_phy_8998_clk_names),
763 };
764