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