xref: /linux/drivers/phy/qualcomm/phy-qcom-edp.c (revision 02cf3710c55d55d956f080e6610b841e2b6ddca0)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021, Linaro Ltd.
5  */
6 
7 #include <linux/clk.h>
8 #include <linux/clk-provider.h>
9 #include <linux/delay.h>
10 #include <linux/err.h>
11 #include <linux/io.h>
12 #include <linux/iopoll.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/phy/phy.h>
17 #include <linux/phy/phy-dp.h>
18 #include <linux/platform_device.h>
19 #include <linux/regulator/consumer.h>
20 #include <linux/reset.h>
21 #include <linux/slab.h>
22 
23 #include <dt-bindings/phy/phy.h>
24 
25 #include "phy-qcom-qmp-dp-phy.h"
26 #include "phy-qcom-qmp-qserdes-com-v4.h"
27 #include "phy-qcom-qmp-qserdes-com-v6.h"
28 
29 #include "phy-qcom-qmp-qserdes-dp-com-v8.h"
30 
31 /* EDP_PHY registers */
32 #define DP_PHY_CFG                              0x0010
33 #define DP_PHY_CFG_1                            0x0014
34 #define DP_PHY_PD_CTL                           0x001c
35 #define DP_PHY_MODE                             0x0020
36 
37 #define DP_AUX_CFG_SIZE                         13
38 #define DP_PHY_AUX_CFG(n)                       (0x24 + (0x04 * (n)))
39 
40 #define DP_PHY_AUX_INTERRUPT_MASK		0x0058
41 
42 #define DP_PHY_VCO_DIV                          0x0074
43 #define DP_PHY_TX0_TX1_LANE_CTL                 0x007c
44 #define DP_PHY_TX2_TX3_LANE_CTL                 0x00a0
45 
46 #define DP_PHY_STATUS                           0x00e0
47 
48 /* LANE_TXn registers */
49 #define TXn_CLKBUF_ENABLE                       0x0000
50 #define TXn_TX_EMP_POST1_LVL                    0x0004
51 
52 #define TXn_TX_DRV_LVL                          0x0014
53 #define TXn_TX_DRV_LVL_OFFSET                   0x0018
54 #define TXn_RESET_TSYNC_EN                      0x001c
55 #define TXn_LDO_CONFIG                          0x0084
56 #define TXn_TX_BAND                             0x0028
57 
58 #define TXn_RES_CODE_LANE_OFFSET_TX0            0x0044
59 #define TXn_RES_CODE_LANE_OFFSET_TX1            0x0048
60 
61 #define TXn_TRANSCEIVER_BIAS_EN                 0x0054
62 #define TXn_HIGHZ_DRVR_EN                       0x0058
63 #define TXn_TX_POL_INV                          0x005c
64 #define TXn_LANE_MODE_1                         0x0064
65 
66 #define TXn_TRAN_DRVR_EMP_EN                    0x0078
67 
68 struct qcom_edp_swing_pre_emph_cfg {
69 	const u8 (*swing_hbr_rbr)[4][4];
70 	const u8 (*swing_hbr3_hbr2)[4][4];
71 	const u8 (*pre_emphasis_hbr_rbr)[4][4];
72 	const u8 (*pre_emphasis_hbr3_hbr2)[4][4];
73 };
74 
75 struct qcom_edp;
76 
77 struct phy_ver_ops {
78 	int (*com_power_on)(const struct qcom_edp *edp);
79 	int (*com_resetsm_cntrl)(const struct qcom_edp *edp);
80 	int (*com_bias_en_clkbuflr)(const struct qcom_edp *edp);
81 	int (*com_clk_fwd_cfg)(const struct qcom_edp *edp);
82 	int (*com_configure_pll)(const struct qcom_edp *edp);
83 	int (*com_configure_ssc)(const struct qcom_edp *edp);
84 };
85 
86 struct qcom_edp_phy_cfg {
87 	bool is_edp;
88 	const u8 *aux_cfg;
89 	const u8 *vco_div_cfg;
90 	const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
91 	const struct phy_ver_ops *ver_ops;
92 };
93 
94 struct qcom_edp {
95 	struct device *dev;
96 	const struct qcom_edp_phy_cfg *cfg;
97 
98 	struct phy *phy;
99 
100 	void __iomem *edp;
101 	void __iomem *tx0;
102 	void __iomem *tx1;
103 	void __iomem *pll;
104 
105 	struct clk_hw dp_link_hw;
106 	struct clk_hw dp_pixel_hw;
107 
108 	struct phy_configure_opts_dp dp_opts;
109 
110 	struct clk_bulk_data *clks;
111 	int num_clks;
112 
113 	struct regulator_bulk_data supplies[2];
114 
115 	bool is_edp;
116 };
117 
118 static const u8 dp_swing_hbr_rbr[4][4] = {
119 	{ 0x08, 0x0f, 0x16, 0x1f },
120 	{ 0x11, 0x1e, 0x1f, 0xff },
121 	{ 0x16, 0x1f, 0xff, 0xff },
122 	{ 0x1f, 0xff, 0xff, 0xff }
123 };
124 
125 static const u8 dp_pre_emp_hbr_rbr[4][4] = {
126 	{ 0x00, 0x0d, 0x14, 0x1a },
127 	{ 0x00, 0x0e, 0x15, 0xff },
128 	{ 0x00, 0x0e, 0xff, 0xff },
129 	{ 0x03, 0xff, 0xff, 0xff }
130 };
131 
132 static const u8 dp_swing_hbr2_hbr3[4][4] = {
133 	{ 0x02, 0x12, 0x16, 0x1a },
134 	{ 0x09, 0x19, 0x1f, 0xff },
135 	{ 0x10, 0x1f, 0xff, 0xff },
136 	{ 0x1f, 0xff, 0xff, 0xff }
137 };
138 
139 static const u8 dp_pre_emp_hbr2_hbr3[4][4] = {
140 	{ 0x00, 0x0c, 0x15, 0x1b },
141 	{ 0x02, 0x0e, 0x16, 0xff },
142 	{ 0x02, 0x11, 0xff, 0xff },
143 	{ 0x04, 0xff, 0xff, 0xff }
144 };
145 
146 static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg = {
147 	.swing_hbr_rbr = &dp_swing_hbr_rbr,
148 	.swing_hbr3_hbr2 = &dp_swing_hbr2_hbr3,
149 	.pre_emphasis_hbr_rbr = &dp_pre_emp_hbr_rbr,
150 	.pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3,
151 };
152 
153 static const u8 edp_swing_hbr_rbr[4][4] = {
154 	{ 0x07, 0x0f, 0x16, 0x1f },
155 	{ 0x0d, 0x16, 0x1e, 0xff },
156 	{ 0x11, 0x1b, 0xff, 0xff },
157 	{ 0x16, 0xff, 0xff, 0xff }
158 };
159 
160 static const u8 edp_pre_emp_hbr_rbr[4][4] = {
161 	{ 0x05, 0x12, 0x17, 0x1d },
162 	{ 0x05, 0x11, 0x18, 0xff },
163 	{ 0x06, 0x11, 0xff, 0xff },
164 	{ 0x00, 0xff, 0xff, 0xff }
165 };
166 
167 static const u8 edp_swing_hbr2_hbr3[4][4] = {
168 	{ 0x0b, 0x11, 0x17, 0x1c },
169 	{ 0x10, 0x19, 0x1f, 0xff },
170 	{ 0x19, 0x1f, 0xff, 0xff },
171 	{ 0x1f, 0xff, 0xff, 0xff }
172 };
173 
174 static const u8 edp_pre_emp_hbr2_hbr3[4][4] = {
175 	{ 0x08, 0x11, 0x17, 0x1b },
176 	{ 0x00, 0x0c, 0x13, 0xff },
177 	{ 0x05, 0x10, 0xff, 0xff },
178 	{ 0x00, 0xff, 0xff, 0xff }
179 };
180 
181 static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
182 	.swing_hbr_rbr = &edp_swing_hbr_rbr,
183 	.swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3,
184 	.pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr,
185 	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
186 };
187 
188 static const u8 edp_phy_aux_cfg_v4[DP_AUX_CFG_SIZE] = {
189 	0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00,
190 };
191 
192 static const u8 edp_phy_vco_div_cfg_v4[4] = {
193 	0x01, 0x01, 0x02, 0x00,
194 };
195 
196 static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
197 	{ 0x05, 0x11, 0x17, 0x1d },
198 	{ 0x05, 0x11, 0x18, 0xff },
199 	{ 0x06, 0x11, 0xff, 0xff },
200 	{ 0x00, 0xff, 0xff, 0xff }
201 };
202 
203 static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
204 	{ 0x0c, 0x15, 0x19, 0x1e },
205 	{ 0x0b, 0x15, 0x19, 0xff },
206 	{ 0x0e, 0x14, 0xff, 0xff },
207 	{ 0x0d, 0xff, 0xff, 0xff }
208 };
209 
210 static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
211 	.swing_hbr_rbr = &edp_swing_hbr_rbr,
212 	.swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3,
213 	.pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
214 	.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
215 };
216 
217 static const u8 edp_phy_aux_cfg_v5[DP_AUX_CFG_SIZE] = {
218 	0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00,
219 };
220 
221 static const u8 edp_phy_aux_cfg_v8[DP_AUX_CFG_SIZE] = {
222 	0x00, 0x00, 0xa0, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x04,
223 };
224 
225 static const u8 edp_phy_vco_div_cfg_v8[4] = {
226 	0x00, 0x00, 0x02, 0x01,
227 };
228 
229 static int qcom_edp_phy_init(struct phy *phy)
230 {
231 	struct qcom_edp *edp = phy_get_drvdata(phy);
232 	u8 aux_cfg[DP_AUX_CFG_SIZE];
233 	int ret;
234 
235 	ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
236 	if (ret)
237 		return ret;
238 
239 	ret = clk_bulk_prepare_enable(edp->num_clks, edp->clks);
240 	if (ret)
241 		goto out_disable_supplies;
242 
243 	memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg));
244 
245 	ret = edp->cfg->ver_ops->com_clk_fwd_cfg(edp);
246 	if (ret)
247 		return ret;
248 
249 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
250 	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
251 	       edp->edp + DP_PHY_PD_CTL);
252 
253 	ret = edp->cfg->ver_ops->com_bias_en_clkbuflr(edp);
254 	if (ret)
255 		return ret;
256 
257 	writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
258 	msleep(20);
259 
260 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
261 	       DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
262 	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
263 	       edp->edp + DP_PHY_PD_CTL);
264 
265 	/*
266 	 * TODO: Re-work the conditions around setting the cfg8 value
267 	 * when more information becomes available about why this is
268 	 * even needed.
269 	 */
270 	if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
271 		aux_cfg[8] = 0xb7;
272 
273 	writel(0xfc, edp->edp + DP_PHY_MODE);
274 
275 	for (int i = 0; i < DP_AUX_CFG_SIZE; i++)
276 		writel(aux_cfg[i], edp->edp + DP_PHY_AUX_CFG(i));
277 
278 	writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
279 	       PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
280 	       PHY_AUX_REQ_ERR_MASK, edp->edp + DP_PHY_AUX_INTERRUPT_MASK);
281 
282 	msleep(20);
283 
284 	return 0;
285 
286 out_disable_supplies:
287 	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
288 
289 	return ret;
290 }
291 
292 static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
293 {
294 	const struct qcom_edp_swing_pre_emph_cfg *cfg = edp->cfg->swing_pre_emph_cfg;
295 	unsigned int v_level = 0;
296 	unsigned int p_level = 0;
297 	u8 ldo_config;
298 	u8 swing;
299 	u8 emph;
300 	int i;
301 
302 	if (!cfg)
303 		return 0;
304 
305 	if (edp->is_edp)
306 		cfg = &edp_phy_swing_pre_emph_cfg;
307 
308 	for (i = 0; i < dp_opts->lanes; i++) {
309 		v_level = max(v_level, dp_opts->voltage[i]);
310 		p_level = max(p_level, dp_opts->pre[i]);
311 	}
312 
313 	if (dp_opts->link_rate <= 2700) {
314 		swing = (*cfg->swing_hbr_rbr)[v_level][p_level];
315 		emph = (*cfg->pre_emphasis_hbr_rbr)[v_level][p_level];
316 	} else {
317 		swing = (*cfg->swing_hbr3_hbr2)[v_level][p_level];
318 		emph = (*cfg->pre_emphasis_hbr3_hbr2)[v_level][p_level];
319 	}
320 
321 	if (swing == 0xff || emph == 0xff)
322 		return -EINVAL;
323 
324 	ldo_config = edp->is_edp ? 0x0 : 0x1;
325 
326 	writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
327 	writel(swing, edp->tx0 + TXn_TX_DRV_LVL);
328 	writel(emph, edp->tx0 + TXn_TX_EMP_POST1_LVL);
329 
330 	writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
331 	writel(swing, edp->tx1 + TXn_TX_DRV_LVL);
332 	writel(emph, edp->tx1 + TXn_TX_EMP_POST1_LVL);
333 
334 	return 0;
335 }
336 
337 static int qcom_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
338 {
339 	const struct phy_configure_opts_dp *dp_opts = &opts->dp;
340 	struct qcom_edp *edp = phy_get_drvdata(phy);
341 	int ret = 0;
342 
343 	memcpy(&edp->dp_opts, dp_opts, sizeof(*dp_opts));
344 
345 	if (dp_opts->set_voltages)
346 		ret = qcom_edp_set_voltages(edp, dp_opts);
347 
348 	return ret;
349 }
350 
351 static int qcom_edp_configure_ssc(const struct qcom_edp *edp)
352 {
353 	return edp->cfg->ver_ops->com_configure_ssc(edp);
354 }
355 
356 static int qcom_edp_configure_pll(const struct qcom_edp *edp)
357 {
358 	return edp->cfg->ver_ops->com_configure_pll(edp);
359 }
360 
361 static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel_freq)
362 {
363 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
364 	u32 vco_div;
365 
366 	switch (dp_opts->link_rate) {
367 	case 1620:
368 		vco_div = edp->cfg->vco_div_cfg[0];
369 		*pixel_freq = 1620000000UL / 2;
370 		break;
371 
372 	case 2700:
373 		vco_div = edp->cfg->vco_div_cfg[1];
374 		*pixel_freq = 2700000000UL / 2;
375 		break;
376 
377 	case 5400:
378 		vco_div = edp->cfg->vco_div_cfg[2];
379 		*pixel_freq = 5400000000UL / 4;
380 		break;
381 
382 	case 8100:
383 		vco_div = edp->cfg->vco_div_cfg[3];
384 		*pixel_freq = 8100000000UL / 6;
385 		break;
386 
387 	default:
388 		/* Other link rates aren't supported */
389 		return -EINVAL;
390 	}
391 
392 	writel(vco_div, edp->edp + DP_PHY_VCO_DIV);
393 
394 	return 0;
395 }
396 
397 static int qcom_edp_phy_power_on_v4(const struct qcom_edp *edp)
398 {
399 	u32 val;
400 
401 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
402 	       DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
403 	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
404 	       edp->edp + DP_PHY_PD_CTL);
405 	writel(0xfc, edp->edp + DP_PHY_MODE);
406 
407 	return readl_poll_timeout(edp->pll + QSERDES_V4_COM_CMN_STATUS,
408 				     val, val & BIT(7), 5, 200);
409 }
410 
411 static int qcom_edp_phy_com_resetsm_cntrl_v4(const struct qcom_edp *edp)
412 {
413 	u32 val;
414 
415 	writel(0x20, edp->pll + QSERDES_V4_COM_RESETSM_CNTRL);
416 
417 	return readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS,
418 				     val, val & BIT(0), 500, 10000);
419 }
420 
421 static int qcom_edp_com_clk_fwd_cfg_v4(const struct qcom_edp *edp)
422 {
423 	return 0;
424 }
425 
426 static int qcom_edp_com_bias_en_clkbuflr_v4(const struct qcom_edp *edp)
427 {
428 	/* Turn on BIAS current for PHY/PLL */
429 	writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
430 
431 	return 0;
432 }
433 
434 static int qcom_edp_com_configure_ssc_v4(const struct qcom_edp *edp)
435 {
436 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
437 	u32 step1;
438 	u32 step2;
439 
440 	switch (dp_opts->link_rate) {
441 	case 1620:
442 	case 2700:
443 	case 8100:
444 		step1 = 0x45;
445 		step2 = 0x06;
446 		break;
447 
448 	case 5400:
449 		step1 = 0x5c;
450 		step2 = 0x08;
451 		break;
452 
453 	default:
454 		/* Other link rates aren't supported */
455 		return -EINVAL;
456 	}
457 
458 	writel(0x01, edp->pll + QSERDES_V4_COM_SSC_EN_CENTER);
459 	writel(0x00, edp->pll + QSERDES_V4_COM_SSC_ADJ_PER1);
460 	writel(0x36, edp->pll + QSERDES_V4_COM_SSC_PER1);
461 	writel(0x01, edp->pll + QSERDES_V4_COM_SSC_PER2);
462 	writel(step1, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0);
463 	writel(step2, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0);
464 
465 	return 0;
466 }
467 
468 static int qcom_edp_com_configure_pll_v4(const struct qcom_edp *edp)
469 {
470 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
471 	u32 div_frac_start2_mode0;
472 	u32 div_frac_start3_mode0;
473 	u32 dec_start_mode0;
474 	u32 lock_cmp1_mode0;
475 	u32 lock_cmp2_mode0;
476 	u32 hsclk_sel;
477 
478 	switch (dp_opts->link_rate) {
479 	case 1620:
480 		hsclk_sel = 0x5;
481 		dec_start_mode0 = 0x69;
482 		div_frac_start2_mode0 = 0x80;
483 		div_frac_start3_mode0 = 0x07;
484 		lock_cmp1_mode0 = 0x6f;
485 		lock_cmp2_mode0 = 0x08;
486 		break;
487 
488 	case 2700:
489 		hsclk_sel = 0x3;
490 		dec_start_mode0 = 0x69;
491 		div_frac_start2_mode0 = 0x80;
492 		div_frac_start3_mode0 = 0x07;
493 		lock_cmp1_mode0 = 0x0f;
494 		lock_cmp2_mode0 = 0x0e;
495 		break;
496 
497 	case 5400:
498 		hsclk_sel = 0x1;
499 		dec_start_mode0 = 0x8c;
500 		div_frac_start2_mode0 = 0x00;
501 		div_frac_start3_mode0 = 0x0a;
502 		lock_cmp1_mode0 = 0x1f;
503 		lock_cmp2_mode0 = 0x1c;
504 		break;
505 
506 	case 8100:
507 		hsclk_sel = 0x0;
508 		dec_start_mode0 = 0x69;
509 		div_frac_start2_mode0 = 0x80;
510 		div_frac_start3_mode0 = 0x07;
511 		lock_cmp1_mode0 = 0x2f;
512 		lock_cmp2_mode0 = 0x2a;
513 		break;
514 
515 	default:
516 		/* Other link rates aren't supported */
517 		return -EINVAL;
518 	}
519 
520 	writel(0x01, edp->pll + QSERDES_V4_COM_SVS_MODE_CLK_SEL);
521 	writel(0x0b, edp->pll + QSERDES_V4_COM_SYSCLK_EN_SEL);
522 	writel(0x02, edp->pll + QSERDES_V4_COM_SYS_CLK_CTRL);
523 	writel(0x0c, edp->pll + QSERDES_V4_COM_CLK_ENABLE1);
524 	writel(0x06, edp->pll + QSERDES_V4_COM_SYSCLK_BUF_ENABLE);
525 	writel(0x30, edp->pll + QSERDES_V4_COM_CLK_SELECT);
526 	writel(hsclk_sel, edp->pll + QSERDES_V4_COM_HSCLK_SEL);
527 	writel(0x0f, edp->pll + QSERDES_V4_COM_PLL_IVCO);
528 	writel(0x08, edp->pll + QSERDES_V4_COM_LOCK_CMP_EN);
529 	writel(0x36, edp->pll + QSERDES_V4_COM_PLL_CCTRL_MODE0);
530 	writel(0x16, edp->pll + QSERDES_V4_COM_PLL_RCTRL_MODE0);
531 	writel(0x06, edp->pll + QSERDES_V4_COM_CP_CTRL_MODE0);
532 	writel(dec_start_mode0, edp->pll + QSERDES_V4_COM_DEC_START_MODE0);
533 	writel(0x00, edp->pll + QSERDES_V4_COM_DIV_FRAC_START1_MODE0);
534 	writel(div_frac_start2_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START2_MODE0);
535 	writel(div_frac_start3_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START3_MODE0);
536 	writel(0x02, edp->pll + QSERDES_V4_COM_CMN_CONFIG);
537 	writel(0x3f, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0);
538 	writel(0x00, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0);
539 	writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_MAP);
540 	writel(lock_cmp1_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP1_MODE0);
541 	writel(lock_cmp2_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP2_MODE0);
542 
543 	writel(0x0a, edp->pll + QSERDES_V4_COM_BG_TIMER);
544 	writel(0x14, edp->pll + QSERDES_V4_COM_CORECLK_DIV_MODE0);
545 	writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_CTRL);
546 	writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
547 	writel(0x0f, edp->pll + QSERDES_V4_COM_CORE_CLK_EN);
548 	writel(0xa0, edp->pll + QSERDES_V4_COM_VCO_TUNE1_MODE0);
549 	writel(0x03, edp->pll + QSERDES_V4_COM_VCO_TUNE2_MODE0);
550 
551 	return 0;
552 }
553 
554 static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
555 	.com_power_on		= qcom_edp_phy_power_on_v4,
556 	.com_resetsm_cntrl	= qcom_edp_phy_com_resetsm_cntrl_v4,
557 	.com_bias_en_clkbuflr	= qcom_edp_com_bias_en_clkbuflr_v4,
558 	.com_clk_fwd_cfg	= qcom_edp_com_clk_fwd_cfg_v4,
559 	.com_configure_pll	= qcom_edp_com_configure_pll_v4,
560 	.com_configure_ssc	= qcom_edp_com_configure_ssc_v4,
561 };
562 
563 static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
564 	.is_edp = false,
565 	.aux_cfg = edp_phy_aux_cfg_v5,
566 	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
567 	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
568 	.ver_ops = &qcom_edp_phy_ops_v4,
569 };
570 
571 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
572 	.aux_cfg = edp_phy_aux_cfg_v4,
573 	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
574 	.ver_ops = &qcom_edp_phy_ops_v4,
575 };
576 
577 static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
578 	.aux_cfg = edp_phy_aux_cfg_v4,
579 	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
580 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
581 	.ver_ops = &qcom_edp_phy_ops_v4,
582 };
583 
584 static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
585 	.is_edp = true,
586 	.aux_cfg = edp_phy_aux_cfg_v4,
587 	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
588 	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
589 	.ver_ops = &qcom_edp_phy_ops_v4,
590 };
591 
592 static int qcom_edp_phy_power_on_v6(const struct qcom_edp *edp)
593 {
594 	u32 val;
595 
596 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
597 	       DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
598 	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
599 	       edp->edp + DP_PHY_PD_CTL);
600 	writel(0xfc, edp->edp + DP_PHY_MODE);
601 
602 	return readl_poll_timeout(edp->pll + QSERDES_V6_COM_CMN_STATUS,
603 				     val, val & BIT(7), 5, 200);
604 }
605 
606 static int qcom_edp_phy_com_resetsm_cntrl_v6(const struct qcom_edp *edp)
607 {
608 	u32 val;
609 
610 	writel(0x20, edp->pll + QSERDES_V6_COM_RESETSM_CNTRL);
611 
612 	return readl_poll_timeout(edp->pll + QSERDES_V6_COM_C_READY_STATUS,
613 				     val, val & BIT(0), 500, 10000);
614 }
615 
616 static int qcom_edp_com_bias_en_clkbuflr_v6(const struct qcom_edp *edp)
617 {
618 	/* Turn on BIAS current for PHY/PLL */
619 	writel(0x1f, edp->pll + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN);
620 
621 	return 0;
622 }
623 
624 static int qcom_edp_com_configure_ssc_v6(const struct qcom_edp *edp)
625 {
626 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
627 	u32 step1;
628 	u32 step2;
629 
630 	switch (dp_opts->link_rate) {
631 	case 1620:
632 	case 2700:
633 	case 8100:
634 		step1 = 0x92;
635 		step2 = 0x01;
636 		break;
637 
638 	case 5400:
639 		step1 = 0x18;
640 		step2 = 0x02;
641 		break;
642 
643 	default:
644 		/* Other link rates aren't supported */
645 		return -EINVAL;
646 	}
647 
648 	writel(0x01, edp->pll + QSERDES_V6_COM_SSC_EN_CENTER);
649 	writel(0x00, edp->pll + QSERDES_V6_COM_SSC_ADJ_PER1);
650 	writel(0x36, edp->pll + QSERDES_V6_COM_SSC_PER1);
651 	writel(0x01, edp->pll + QSERDES_V6_COM_SSC_PER2);
652 	writel(step1, edp->pll + QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0);
653 	writel(step2, edp->pll + QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0);
654 
655 	return 0;
656 }
657 
658 static int qcom_edp_com_configure_pll_v6(const struct qcom_edp *edp)
659 {
660 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
661 	u32 div_frac_start2_mode0;
662 	u32 div_frac_start3_mode0;
663 	u32 dec_start_mode0;
664 	u32 lock_cmp1_mode0;
665 	u32 lock_cmp2_mode0;
666 	u32 code1_mode0;
667 	u32 code2_mode0;
668 	u32 hsclk_sel;
669 
670 	switch (dp_opts->link_rate) {
671 	case 1620:
672 		hsclk_sel = 0x5;
673 		dec_start_mode0 = 0x34;
674 		div_frac_start2_mode0 = 0xc0;
675 		div_frac_start3_mode0 = 0x0b;
676 		lock_cmp1_mode0 = 0x37;
677 		lock_cmp2_mode0 = 0x04;
678 		code1_mode0 = 0x71;
679 		code2_mode0 = 0x0c;
680 		break;
681 
682 	case 2700:
683 		hsclk_sel = 0x3;
684 		dec_start_mode0 = 0x34;
685 		div_frac_start2_mode0 = 0xc0;
686 		div_frac_start3_mode0 = 0x0b;
687 		lock_cmp1_mode0 = 0x07;
688 		lock_cmp2_mode0 = 0x07;
689 		code1_mode0 = 0x71;
690 		code2_mode0 = 0x0c;
691 		break;
692 
693 	case 5400:
694 		hsclk_sel = 0x1;
695 		dec_start_mode0 = 0x46;
696 		div_frac_start2_mode0 = 0x00;
697 		div_frac_start3_mode0 = 0x05;
698 		lock_cmp1_mode0 = 0x0f;
699 		lock_cmp2_mode0 = 0x0e;
700 		code1_mode0 = 0x97;
701 		code2_mode0 = 0x10;
702 		break;
703 
704 	case 8100:
705 		hsclk_sel = 0x0;
706 		dec_start_mode0 = 0x34;
707 		div_frac_start2_mode0 = 0xc0;
708 		div_frac_start3_mode0 = 0x0b;
709 		lock_cmp1_mode0 = 0x17;
710 		lock_cmp2_mode0 = 0x15;
711 		code1_mode0 = 0x71;
712 		code2_mode0 = 0x0c;
713 		break;
714 
715 	default:
716 		/* Other link rates aren't supported */
717 		return -EINVAL;
718 	}
719 
720 	writel(0x01, edp->pll + QSERDES_V6_COM_SVS_MODE_CLK_SEL);
721 	writel(0x0b, edp->pll + QSERDES_V6_COM_SYSCLK_EN_SEL);
722 	writel(0x02, edp->pll + QSERDES_V6_COM_SYS_CLK_CTRL);
723 	writel(0x0c, edp->pll + QSERDES_V6_COM_CLK_ENABLE1);
724 	writel(0x06, edp->pll + QSERDES_V6_COM_SYSCLK_BUF_ENABLE);
725 	writel(0x30, edp->pll + QSERDES_V6_COM_CLK_SELECT);
726 	writel(hsclk_sel, edp->pll + QSERDES_V6_COM_HSCLK_SEL_1);
727 	writel(0x07, edp->pll + QSERDES_V6_COM_PLL_IVCO);
728 	writel(0x08, edp->pll + QSERDES_V6_COM_LOCK_CMP_EN);
729 	writel(0x36, edp->pll + QSERDES_V6_COM_PLL_CCTRL_MODE0);
730 	writel(0x16, edp->pll + QSERDES_V6_COM_PLL_RCTRL_MODE0);
731 	writel(0x06, edp->pll + QSERDES_V6_COM_CP_CTRL_MODE0);
732 	writel(dec_start_mode0, edp->pll + QSERDES_V6_COM_DEC_START_MODE0);
733 	writel(0x00, edp->pll + QSERDES_V6_COM_DIV_FRAC_START1_MODE0);
734 	writel(div_frac_start2_mode0, edp->pll + QSERDES_V6_COM_DIV_FRAC_START2_MODE0);
735 	writel(div_frac_start3_mode0, edp->pll + QSERDES_V6_COM_DIV_FRAC_START3_MODE0);
736 	writel(0x12, edp->pll + QSERDES_V6_COM_CMN_CONFIG_1);
737 	writel(0x3f, edp->pll + QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0);
738 	writel(0x00, edp->pll + QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0);
739 	writel(0x00, edp->pll + QSERDES_V6_COM_VCO_TUNE_MAP);
740 	writel(lock_cmp1_mode0, edp->pll + QSERDES_V6_COM_LOCK_CMP1_MODE0);
741 	writel(lock_cmp2_mode0, edp->pll + QSERDES_V6_COM_LOCK_CMP2_MODE0);
742 
743 	writel(0x0a, edp->pll + QSERDES_V6_COM_BG_TIMER);
744 	writel(0x14, edp->pll + QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0);
745 	writel(0x00, edp->pll + QSERDES_V6_COM_VCO_TUNE_CTRL);
746 	writel(0x1f, edp->pll + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN);
747 	writel(0x0f, edp->pll + QSERDES_V6_COM_CORE_CLK_EN);
748 	writel(0xa0, edp->pll + QSERDES_V6_COM_VCO_TUNE1_MODE0);
749 	writel(0x03, edp->pll + QSERDES_V6_COM_VCO_TUNE2_MODE0);
750 
751 	writel(code1_mode0, edp->pll + QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0);
752 	writel(code2_mode0, edp->pll + QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0);
753 
754 	return 0;
755 }
756 
757 static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
758 	.com_power_on		= qcom_edp_phy_power_on_v6,
759 	.com_resetsm_cntrl	= qcom_edp_phy_com_resetsm_cntrl_v6,
760 	.com_bias_en_clkbuflr	= qcom_edp_com_bias_en_clkbuflr_v6,
761 	.com_configure_pll	= qcom_edp_com_configure_pll_v6,
762 	.com_configure_ssc	= qcom_edp_com_configure_ssc_v6,
763 };
764 
765 static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
766 	.aux_cfg = edp_phy_aux_cfg_v4,
767 	.vco_div_cfg = edp_phy_vco_div_cfg_v4,
768 	.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
769 	.ver_ops = &qcom_edp_phy_ops_v6,
770 };
771 
772 static int qcom_edp_com_configure_ssc_v8(const struct qcom_edp *edp)
773 {
774 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
775 	u32 step1;
776 	u32 step2;
777 
778 	switch (dp_opts->link_rate) {
779 	case 1620:
780 	case 2700:
781 	case 8100:
782 		step1 = 0x5b;
783 		step2 = 0x02;
784 		break;
785 
786 	case 5400:
787 		step1 = 0x5b;
788 		step2 = 0x02;
789 		break;
790 
791 	default:
792 		/* Other link rates aren't supported */
793 		return -EINVAL;
794 	}
795 
796 	writel(0x01, edp->pll + DP_QSERDES_V8_COM_SSC_EN_CENTER);
797 	writel(0x00, edp->pll + DP_QSERDES_V8_COM_SSC_ADJ_PER1);
798 	writel(0x6b, edp->pll + DP_QSERDES_V8_COM_SSC_PER1);
799 	writel(0x02, edp->pll + DP_QSERDES_V8_COM_SSC_PER2);
800 	writel(step1, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0);
801 	writel(step2, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0);
802 
803 	return 0;
804 }
805 
806 static int qcom_edp_com_configure_pll_v8(const struct qcom_edp *edp)
807 {
808 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
809 	u32 div_frac_start2_mode0;
810 	u32 div_frac_start3_mode0;
811 	u32 dec_start_mode0;
812 	u32 lock_cmp1_mode0;
813 	u32 lock_cmp2_mode0;
814 	u32 code1_mode0;
815 	u32 code2_mode0;
816 	u32 hsclk_sel;
817 
818 	switch (dp_opts->link_rate) {
819 	case 1620:
820 		hsclk_sel = 0x5;
821 		dec_start_mode0 = 0x34;
822 		div_frac_start2_mode0 = 0xc0;
823 		div_frac_start3_mode0 = 0x0b;
824 		lock_cmp1_mode0 = 0x37;
825 		lock_cmp2_mode0 = 0x04;
826 		code1_mode0 = 0x71;
827 		code2_mode0 = 0x0c;
828 		break;
829 
830 	case 2700:
831 		hsclk_sel = 0x3;
832 		dec_start_mode0 = 0x34;
833 		div_frac_start2_mode0 = 0xc0;
834 		div_frac_start3_mode0 = 0x0b;
835 		lock_cmp1_mode0 = 0x07;
836 		lock_cmp2_mode0 = 0x07;
837 		code1_mode0 = 0x71;
838 		code2_mode0 = 0x0c;
839 		break;
840 
841 	case 5400:
842 	case 8100:
843 		hsclk_sel = 0x2;
844 		dec_start_mode0 = 0x4f;
845 		div_frac_start2_mode0 = 0xa0;
846 		div_frac_start3_mode0 = 0x01;
847 		lock_cmp1_mode0 = 0x18;
848 		lock_cmp2_mode0 = 0x15;
849 		code1_mode0 = 0x14;
850 		code2_mode0 = 0x25;
851 		break;
852 
853 	default:
854 		/* Other link rates aren't supported */
855 		return -EINVAL;
856 	}
857 
858 	writel(0x01, edp->pll + DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL);
859 	writel(0x3b, edp->pll + DP_QSERDES_V8_COM_SYSCLK_EN_SEL);
860 	writel(0x02, edp->pll + DP_QSERDES_V8_COM_SYS_CLK_CTRL);
861 	writel(0x0c, edp->pll + DP_QSERDES_V8_COM_CLK_ENABLE1);
862 	writel(0x06, edp->pll + DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE);
863 	writel(0x30, edp->pll + DP_QSERDES_V8_COM_CLK_SELECT);
864 	writel(hsclk_sel, edp->pll + DP_QSERDES_V8_COM_HSCLK_SEL_1);
865 	writel(0x07, edp->pll + DP_QSERDES_V8_COM_PLL_IVCO);
866 	writel(0x00, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP_EN);
867 	writel(0x36, edp->pll + DP_QSERDES_V8_COM_PLL_CCTRL_MODE0);
868 	writel(0x16, edp->pll + DP_QSERDES_V8_COM_PLL_RCTRL_MODE0);
869 	writel(0x06, edp->pll + DP_QSERDES_V8_COM_CP_CTRL_MODE0);
870 	writel(dec_start_mode0, edp->pll + DP_QSERDES_V8_COM_DEC_START_MODE0);
871 	writel(0x00, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0);
872 	writel(div_frac_start2_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0);
873 	writel(div_frac_start3_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0);
874 	writel(0x96, edp->pll + DP_QSERDES_V8_COM_CMN_CONFIG_1);
875 	writel(0x3f, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0);
876 	writel(0x00, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0);
877 	writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_MAP);
878 	writel(lock_cmp1_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP1_MODE0);
879 	writel(lock_cmp2_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP2_MODE0);
880 
881 	writel(0x0a, edp->pll + DP_QSERDES_V8_COM_BG_TIMER);
882 	writel(0x0a, edp->pll + DP_QSERDES_V8_COM_CORECLK_DIV_MODE0);
883 	writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_CTRL);
884 	writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN);
885 	writel(0x00, edp->pll + DP_QSERDES_V8_COM_CORE_CLK_EN);
886 	writel(0xa0, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE1_MODE0);
887 	writel(0x01, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE2_MODE0);
888 
889 	writel(code1_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0);
890 	writel(code2_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0);
891 
892 	return 0;
893 }
894 
895 
896 static int qcom_edp_phy_com_resetsm_cntrl_v8(const struct qcom_edp *edp)
897 {
898 	u32 val;
899 
900 	writel(0x20, edp->pll + DP_QSERDES_V8_COM_RESETSM_CNTRL);
901 
902 	return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_C_READY_STATUS,
903 				     val, val & BIT(0), 500, 10000);
904 }
905 
906 static int qcom_edp_com_clk_fwd_cfg_v8(const struct qcom_edp *edp)
907 {
908 	writel(0x3f, edp->pll + DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1);
909 
910 	return 0;
911 }
912 
913 static int qcom_edp_com_bias_en_clkbuflr_v8(const struct qcom_edp *edp)
914 {
915 	/* Turn on BIAS current for PHY/PLL */
916 	writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN);
917 
918 	return 0;
919 }
920 
921 static int qcom_edp_phy_power_on_v8(const struct qcom_edp *edp)
922 {
923 	u32 val;
924 
925 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
926 	       DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
927 	       DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
928 	       edp->edp + DP_PHY_PD_CTL);
929 	writel(0xfc, edp->edp + DP_PHY_MODE);
930 
931 	return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_CMN_STATUS,
932 				     val, val & BIT(7), 5, 200);
933 }
934 
935 static const struct phy_ver_ops qcom_edp_phy_ops_v8 = {
936 	.com_power_on		= qcom_edp_phy_power_on_v8,
937 	.com_resetsm_cntrl	= qcom_edp_phy_com_resetsm_cntrl_v8,
938 	.com_bias_en_clkbuflr	= qcom_edp_com_bias_en_clkbuflr_v8,
939 	.com_clk_fwd_cfg	= qcom_edp_com_clk_fwd_cfg_v8,
940 	.com_configure_pll	= qcom_edp_com_configure_pll_v8,
941 	.com_configure_ssc	= qcom_edp_com_configure_ssc_v8,
942 };
943 
944 static struct qcom_edp_phy_cfg glymur_phy_cfg = {
945 	.aux_cfg = edp_phy_aux_cfg_v8,
946 	.vco_div_cfg = edp_phy_vco_div_cfg_v8,
947 	.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
948 	.ver_ops = &qcom_edp_phy_ops_v8,
949 };
950 
951 static int qcom_edp_phy_power_on(struct phy *phy)
952 {
953 	const struct qcom_edp *edp = phy_get_drvdata(phy);
954 	u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
955 	unsigned long pixel_freq;
956 	u8 ldo_config = 0x0;
957 	int ret;
958 	u32 val;
959 	u8 cfg1;
960 
961 	ret = edp->cfg->ver_ops->com_power_on(edp);
962 	if (ret)
963 		return ret;
964 
965 	if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
966 		ldo_config = 0x1;
967 
968 	writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
969 	writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
970 	writel(0x00, edp->tx0 + TXn_LANE_MODE_1);
971 	writel(0x00, edp->tx1 + TXn_LANE_MODE_1);
972 
973 	if (edp->dp_opts.ssc) {
974 		ret = qcom_edp_configure_ssc(edp);
975 		if (ret)
976 			return ret;
977 	}
978 
979 	ret = qcom_edp_configure_pll(edp);
980 	if (ret)
981 		return ret;
982 
983 	/* TX Lane configuration */
984 	writel(0x05, edp->edp + DP_PHY_TX0_TX1_LANE_CTL);
985 	writel(0x05, edp->edp + DP_PHY_TX2_TX3_LANE_CTL);
986 
987 	/* TX-0 register configuration */
988 	writel(0x03, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN);
989 	writel(0x0f, edp->tx0 + TXn_CLKBUF_ENABLE);
990 	writel(0x03, edp->tx0 + TXn_RESET_TSYNC_EN);
991 	writel(0x01, edp->tx0 + TXn_TRAN_DRVR_EMP_EN);
992 	writel(0x04, edp->tx0 + TXn_TX_BAND);
993 
994 	/* TX-1 register configuration */
995 	writel(0x03, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN);
996 	writel(0x0f, edp->tx1 + TXn_CLKBUF_ENABLE);
997 	writel(0x03, edp->tx1 + TXn_RESET_TSYNC_EN);
998 	writel(0x01, edp->tx1 + TXn_TRAN_DRVR_EMP_EN);
999 	writel(0x04, edp->tx1 + TXn_TX_BAND);
1000 
1001 	ret = qcom_edp_set_vco_div(edp, &pixel_freq);
1002 	if (ret)
1003 		return ret;
1004 
1005 	writel(0x01, edp->edp + DP_PHY_CFG);
1006 	writel(0x05, edp->edp + DP_PHY_CFG);
1007 	writel(0x01, edp->edp + DP_PHY_CFG);
1008 	writel(0x09, edp->edp + DP_PHY_CFG);
1009 
1010 	ret = edp->cfg->ver_ops->com_resetsm_cntrl(edp);
1011 	if (ret)
1012 		return ret;
1013 
1014 	writel(0x19, edp->edp + DP_PHY_CFG);
1015 	writel(0x1f, edp->tx0 + TXn_HIGHZ_DRVR_EN);
1016 	writel(0x04, edp->tx0 + TXn_HIGHZ_DRVR_EN);
1017 	writel(0x00, edp->tx0 + TXn_TX_POL_INV);
1018 	writel(0x1f, edp->tx1 + TXn_HIGHZ_DRVR_EN);
1019 	writel(0x04, edp->tx1 + TXn_HIGHZ_DRVR_EN);
1020 	writel(0x00, edp->tx1 + TXn_TX_POL_INV);
1021 	writel(0x10, edp->tx0 + TXn_TX_DRV_LVL_OFFSET);
1022 	writel(0x10, edp->tx1 + TXn_TX_DRV_LVL_OFFSET);
1023 	writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX0);
1024 	writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX1);
1025 	writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX0);
1026 	writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX1);
1027 
1028 	writel(0x10, edp->tx0 + TXn_TX_EMP_POST1_LVL);
1029 	writel(0x10, edp->tx1 + TXn_TX_EMP_POST1_LVL);
1030 	writel(0x1f, edp->tx0 + TXn_TX_DRV_LVL);
1031 	writel(0x1f, edp->tx1 + TXn_TX_DRV_LVL);
1032 
1033 	if (edp->dp_opts.lanes == 1) {
1034 		bias0_en = 0x01;
1035 		bias1_en = 0x00;
1036 		drvr0_en = 0x06;
1037 		drvr1_en = 0x07;
1038 		cfg1 = 0x1;
1039 	} else if (edp->dp_opts.lanes == 2) {
1040 		bias0_en = 0x03;
1041 		bias1_en = 0x00;
1042 		drvr0_en = 0x04;
1043 		drvr1_en = 0x07;
1044 		cfg1 = 0x3;
1045 	} else {
1046 		bias0_en = 0x03;
1047 		bias1_en = 0x03;
1048 		drvr0_en = 0x04;
1049 		drvr1_en = 0x04;
1050 		cfg1 = 0xf;
1051 	}
1052 
1053 	writel(drvr0_en, edp->tx0 + TXn_HIGHZ_DRVR_EN);
1054 	writel(bias0_en, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN);
1055 	writel(drvr1_en, edp->tx1 + TXn_HIGHZ_DRVR_EN);
1056 	writel(bias1_en, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN);
1057 	writel(cfg1, edp->edp + DP_PHY_CFG_1);
1058 
1059 	writel(0x18, edp->edp + DP_PHY_CFG);
1060 	usleep_range(100, 1000);
1061 
1062 	writel(0x19, edp->edp + DP_PHY_CFG);
1063 
1064 	ret = readl_poll_timeout(edp->edp + DP_PHY_STATUS,
1065 				 val, val & BIT(1), 500, 10000);
1066 	if (ret)
1067 		return ret;
1068 
1069 	clk_set_rate(edp->dp_link_hw.clk, edp->dp_opts.link_rate * 100000);
1070 	clk_set_rate(edp->dp_pixel_hw.clk, pixel_freq);
1071 
1072 	return 0;
1073 }
1074 
1075 static int qcom_edp_phy_power_off(struct phy *phy)
1076 {
1077 	const struct qcom_edp *edp = phy_get_drvdata(phy);
1078 
1079 	writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
1080 
1081 	return 0;
1082 }
1083 
1084 static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
1085 {
1086 	struct qcom_edp *edp = phy_get_drvdata(phy);
1087 
1088 	if (mode != PHY_MODE_DP)
1089 		return -EINVAL;
1090 
1091 	edp->is_edp = submode == PHY_SUBMODE_EDP;
1092 
1093 	return 0;
1094 }
1095 
1096 static int qcom_edp_phy_exit(struct phy *phy)
1097 {
1098 	struct qcom_edp *edp = phy_get_drvdata(phy);
1099 
1100 	clk_bulk_disable_unprepare(edp->num_clks, edp->clks);
1101 	regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
1102 
1103 	return 0;
1104 }
1105 
1106 static const struct phy_ops qcom_edp_ops = {
1107 	.init		= qcom_edp_phy_init,
1108 	.configure	= qcom_edp_phy_configure,
1109 	.power_on	= qcom_edp_phy_power_on,
1110 	.power_off	= qcom_edp_phy_power_off,
1111 	.set_mode	= qcom_edp_phy_set_mode,
1112 	.exit		= qcom_edp_phy_exit,
1113 	.owner		= THIS_MODULE,
1114 };
1115 
1116 /*
1117  * Embedded Display Port PLL driver block diagram for branch clocks
1118  *
1119  *              +------------------------------+
1120  *              |        EDP_VCO_CLK           |
1121  *              |                              |
1122  *              |    +-------------------+     |
1123  *              |    |  (EDP PLL/VCO)    |     |
1124  *              |    +---------+---------+     |
1125  *              |              v               |
1126  *              |   +----------+-----------+   |
1127  *              |   | hsclk_divsel_clk_src |   |
1128  *              |   +----------+-----------+   |
1129  *              +------------------------------+
1130  *                              |
1131  *          +---------<---------v------------>----------+
1132  *          |                                           |
1133  * +--------v----------------+                          |
1134  * |   edp_phy_pll_link_clk  |                          |
1135  * |     link_clk            |                          |
1136  * +--------+----------------+                          |
1137  *          |                                           |
1138  *          |                                           |
1139  *          v                                           v
1140  * Input to DISPCC block                                |
1141  * for link clk, crypto clk                             |
1142  * and interface clock                                  |
1143  *                                                      |
1144  *                                                      |
1145  *      +--------<------------+-----------------+---<---+
1146  *      |                     |                 |
1147  * +----v---------+  +--------v-----+  +--------v------+
1148  * | vco_divided  |  | vco_divided  |  | vco_divided   |
1149  * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
1150  * |              |  |              |  |               |
1151  * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
1152  * +-------+------+  +-----+--------+  +--------+------+
1153  *         |                 |                  |
1154  *         v---->----------v-------------<------v
1155  *                         |
1156  *              +----------+-----------------+
1157  *              |   edp_phy_pll_vco_div_clk  |
1158  *              +---------+------------------+
1159  *                        |
1160  *                        v
1161  *              Input to DISPCC block
1162  *              for EDP pixel clock
1163  *
1164  */
1165 static int qcom_edp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
1166 						struct clk_rate_request *req)
1167 {
1168 	switch (req->rate) {
1169 	case 1620000000UL / 2:
1170 	case 2700000000UL / 2:
1171 	/* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
1172 		return 0;
1173 
1174 	default:
1175 		return -EINVAL;
1176 	}
1177 }
1178 
1179 static unsigned long
1180 qcom_edp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
1181 {
1182 	const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_pixel_hw);
1183 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
1184 
1185 	switch (dp_opts->link_rate) {
1186 	case 1620:
1187 		return 1620000000UL / 2;
1188 	case 2700:
1189 		return 2700000000UL / 2;
1190 	case 5400:
1191 		return 5400000000UL / 4;
1192 	case 8100:
1193 		return 8100000000UL / 6;
1194 	default:
1195 		return 0;
1196 	}
1197 }
1198 
1199 static const struct clk_ops qcom_edp_dp_pixel_clk_ops = {
1200 	.determine_rate = qcom_edp_dp_pixel_clk_determine_rate,
1201 	.recalc_rate = qcom_edp_dp_pixel_clk_recalc_rate,
1202 };
1203 
1204 static int qcom_edp_dp_link_clk_determine_rate(struct clk_hw *hw,
1205 					       struct clk_rate_request *req)
1206 {
1207 	switch (req->rate) {
1208 	case 162000000:
1209 	case 270000000:
1210 	case 540000000:
1211 	case 810000000:
1212 		return 0;
1213 
1214 	default:
1215 		return -EINVAL;
1216 	}
1217 }
1218 
1219 static unsigned long
1220 qcom_edp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
1221 {
1222 	const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_link_hw);
1223 	const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
1224 
1225 	switch (dp_opts->link_rate) {
1226 	case 1620:
1227 	case 2700:
1228 	case 5400:
1229 	case 8100:
1230 		return dp_opts->link_rate * 100000;
1231 
1232 	default:
1233 		return 0;
1234 	}
1235 }
1236 
1237 static const struct clk_ops qcom_edp_dp_link_clk_ops = {
1238 	.determine_rate = qcom_edp_dp_link_clk_determine_rate,
1239 	.recalc_rate = qcom_edp_dp_link_clk_recalc_rate,
1240 };
1241 
1242 static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
1243 {
1244 	struct clk_hw_onecell_data *data;
1245 	struct clk_init_data init = { };
1246 	char name[64];
1247 	int ret;
1248 
1249 	data = devm_kzalloc(edp->dev, struct_size(data, hws, 2), GFP_KERNEL);
1250 	if (!data)
1251 		return -ENOMEM;
1252 	data->num = 2;
1253 
1254 	snprintf(name, sizeof(name), "%s::link_clk", dev_name(edp->dev));
1255 	init.ops = &qcom_edp_dp_link_clk_ops;
1256 	init.name = name;
1257 	edp->dp_link_hw.init = &init;
1258 	ret = devm_clk_hw_register(edp->dev, &edp->dp_link_hw);
1259 	if (ret)
1260 		return ret;
1261 
1262 	snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(edp->dev));
1263 	init.ops = &qcom_edp_dp_pixel_clk_ops;
1264 	init.name = name;
1265 	edp->dp_pixel_hw.init = &init;
1266 	ret = devm_clk_hw_register(edp->dev, &edp->dp_pixel_hw);
1267 	if (ret)
1268 		return ret;
1269 
1270 	data->hws[0] = &edp->dp_link_hw;
1271 	data->hws[1] = &edp->dp_pixel_hw;
1272 
1273 	return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
1274 }
1275 
1276 static int qcom_edp_phy_probe(struct platform_device *pdev)
1277 {
1278 	struct phy_provider *phy_provider;
1279 	struct device *dev = &pdev->dev;
1280 	struct qcom_edp *edp;
1281 	int ret;
1282 
1283 	edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL);
1284 	if (!edp)
1285 		return -ENOMEM;
1286 
1287 	edp->dev = dev;
1288 	edp->cfg = of_device_get_match_data(&pdev->dev);
1289 	edp->is_edp = edp->cfg->is_edp;
1290 
1291 	edp->edp = devm_platform_ioremap_resource(pdev, 0);
1292 	if (IS_ERR(edp->edp))
1293 		return PTR_ERR(edp->edp);
1294 
1295 	edp->tx0 = devm_platform_ioremap_resource(pdev, 1);
1296 	if (IS_ERR(edp->tx0))
1297 		return PTR_ERR(edp->tx0);
1298 
1299 	edp->tx1 = devm_platform_ioremap_resource(pdev, 2);
1300 	if (IS_ERR(edp->tx1))
1301 		return PTR_ERR(edp->tx1);
1302 
1303 	edp->pll = devm_platform_ioremap_resource(pdev, 3);
1304 	if (IS_ERR(edp->pll))
1305 		return PTR_ERR(edp->pll);
1306 
1307 	edp->num_clks = devm_clk_bulk_get_all(dev, &edp->clks);
1308 	if (edp->num_clks < 0)
1309 		return dev_err_probe(dev, edp->num_clks, "failed to get clocks\n");
1310 
1311 	edp->supplies[0].supply = "vdda-phy";
1312 	edp->supplies[1].supply = "vdda-pll";
1313 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies), edp->supplies);
1314 	if (ret)
1315 		return ret;
1316 
1317 	ret = regulator_set_load(edp->supplies[0].consumer, 21800); /* 1.2 V vdda-phy */
1318 	if (ret) {
1319 		dev_err(dev, "failed to set load at %s\n", edp->supplies[0].supply);
1320 		return ret;
1321 	}
1322 
1323 	ret = regulator_set_load(edp->supplies[1].consumer, 36000); /* 0.9 V vdda-pll */
1324 	if (ret) {
1325 		dev_err(dev, "failed to set load at %s\n", edp->supplies[1].supply);
1326 		return ret;
1327 	}
1328 
1329 	ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
1330 	if (ret)
1331 		return ret;
1332 
1333 	edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
1334 	if (IS_ERR(edp->phy)) {
1335 		dev_err(dev, "failed to register phy\n");
1336 		return PTR_ERR(edp->phy);
1337 	}
1338 
1339 	phy_set_drvdata(edp->phy, edp);
1340 
1341 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1342 	return PTR_ERR_OR_ZERO(phy_provider);
1343 }
1344 
1345 static const struct of_device_id qcom_edp_phy_match_table[] = {
1346 	{ .compatible = "qcom,glymur-dp-phy", .data = &glymur_phy_cfg, },
1347 	{ .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, },
1348 	{ .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, },
1349 	{ .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
1350 	{ .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, },
1351 	{ .compatible = "qcom,sc8280xp-edp-phy", .data = &sc8280xp_edp_phy_cfg, },
1352 	{ .compatible = "qcom,x1e80100-dp-phy", .data = &x1e80100_phy_cfg, },
1353 	{ }
1354 };
1355 MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
1356 
1357 static struct platform_driver qcom_edp_phy_driver = {
1358 	.probe		= qcom_edp_phy_probe,
1359 	.driver = {
1360 		.name	= "qcom-edp-phy",
1361 		.of_match_table = qcom_edp_phy_match_table,
1362 	},
1363 };
1364 
1365 module_platform_driver(qcom_edp_phy_driver);
1366 
1367 MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@linaro.org>");
1368 MODULE_DESCRIPTION("Qualcomm eDP QMP PHY driver");
1369 MODULE_LICENSE("GPL v2");
1370