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