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