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