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