]> Git Repo - linux.git/blob - drivers/phy/qualcomm/phy-qcom-edp.c
arm64: avoid prototype warnings for syscalls
[linux.git] / drivers / phy / qualcomm / phy-qcom-edp.c
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/of_device.h>
17 #include <linux/of_address.h>
18 #include <linux/phy/phy.h>
19 #include <linux/platform_device.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/reset.h>
22 #include <linux/slab.h>
23
24 #include <dt-bindings/phy/phy.h>
25
26 #include "phy-qcom-qmp.h"
27
28 /* EDP_PHY registers */
29 #define DP_PHY_CFG                              0x0010
30 #define DP_PHY_CFG_1                            0x0014
31 #define DP_PHY_PD_CTL                           0x001c
32 #define DP_PHY_MODE                             0x0020
33
34 #define DP_PHY_AUX_CFG0                         0x0024
35 #define DP_PHY_AUX_CFG1                         0x0028
36 #define DP_PHY_AUX_CFG2                         0x002C
37 #define DP_PHY_AUX_CFG3                         0x0030
38 #define DP_PHY_AUX_CFG4                         0x0034
39 #define DP_PHY_AUX_CFG5                         0x0038
40 #define DP_PHY_AUX_CFG6                         0x003C
41 #define DP_PHY_AUX_CFG7                         0x0040
42 #define DP_PHY_AUX_CFG8                         0x0044
43 #define DP_PHY_AUX_CFG9                         0x0048
44
45 #define DP_PHY_AUX_INTERRUPT_MASK               0x0058
46
47 #define DP_PHY_VCO_DIV                          0x0074
48 #define DP_PHY_TX0_TX1_LANE_CTL                 0x007c
49 #define DP_PHY_TX2_TX3_LANE_CTL                 0x00a0
50
51 #define DP_PHY_STATUS                           0x00e0
52
53 /* LANE_TXn registers */
54 #define TXn_CLKBUF_ENABLE                       0x0000
55 #define TXn_TX_EMP_POST1_LVL                    0x0004
56
57 #define TXn_TX_DRV_LVL                          0x0014
58 #define TXn_TX_DRV_LVL_OFFSET                   0x0018
59 #define TXn_RESET_TSYNC_EN                      0x001c
60 #define TXn_LDO_CONFIG                          0x0084
61 #define TXn_TX_BAND                             0x0028
62
63 #define TXn_RES_CODE_LANE_OFFSET_TX0            0x0044
64 #define TXn_RES_CODE_LANE_OFFSET_TX1            0x0048
65
66 #define TXn_TRANSCEIVER_BIAS_EN                 0x0054
67 #define TXn_HIGHZ_DRVR_EN                       0x0058
68 #define TXn_TX_POL_INV                          0x005c
69 #define TXn_LANE_MODE_1                         0x0064
70
71 #define TXn_TRAN_DRVR_EMP_EN                    0x0078
72
73 struct qcom_edp_cfg {
74         bool is_dp;
75
76         /* DP PHY swing and pre_emphasis tables */
77         const u8 (*swing_hbr_rbr)[4][4];
78         const u8 (*swing_hbr3_hbr2)[4][4];
79         const u8 (*pre_emphasis_hbr_rbr)[4][4];
80         const u8 (*pre_emphasis_hbr3_hbr2)[4][4];
81 };
82
83 struct qcom_edp {
84         struct device *dev;
85         const struct qcom_edp_cfg *cfg;
86
87         struct phy *phy;
88
89         void __iomem *edp;
90         void __iomem *tx0;
91         void __iomem *tx1;
92         void __iomem *pll;
93
94         struct clk_hw dp_link_hw;
95         struct clk_hw dp_pixel_hw;
96
97         struct phy_configure_opts_dp dp_opts;
98
99         struct clk_bulk_data clks[2];
100         struct regulator_bulk_data supplies[2];
101 };
102
103 static const u8 dp_swing_hbr_rbr[4][4] = {
104         { 0x08, 0x0f, 0x16, 0x1f },
105         { 0x11, 0x1e, 0x1f, 0xff },
106         { 0x16, 0x1f, 0xff, 0xff },
107         { 0x1f, 0xff, 0xff, 0xff }
108 };
109
110 static const u8 dp_pre_emp_hbr_rbr[4][4] = {
111         { 0x00, 0x0d, 0x14, 0x1a },
112         { 0x00, 0x0e, 0x15, 0xff },
113         { 0x00, 0x0e, 0xff, 0xff },
114         { 0x03, 0xff, 0xff, 0xff }
115 };
116
117 static const u8 dp_swing_hbr2_hbr3[4][4] = {
118         { 0x02, 0x12, 0x16, 0x1a },
119         { 0x09, 0x19, 0x1f, 0xff },
120         { 0x10, 0x1f, 0xff, 0xff },
121         { 0x1f, 0xff, 0xff, 0xff }
122 };
123
124 static const u8 dp_pre_emp_hbr2_hbr3[4][4] = {
125         { 0x00, 0x0c, 0x15, 0x1b },
126         { 0x02, 0x0e, 0x16, 0xff },
127         { 0x02, 0x11, 0xff, 0xff },
128         { 0x04, 0xff, 0xff, 0xff }
129 };
130
131 static const struct qcom_edp_cfg dp_phy_cfg = {
132         .is_dp = true,
133         .swing_hbr_rbr = &dp_swing_hbr_rbr,
134         .swing_hbr3_hbr2 = &dp_swing_hbr2_hbr3,
135         .pre_emphasis_hbr_rbr = &dp_pre_emp_hbr_rbr,
136         .pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3,
137 };
138
139 static const u8 edp_swing_hbr_rbr[4][4] = {
140         { 0x07, 0x0f, 0x16, 0x1f },
141         { 0x0d, 0x16, 0x1e, 0xff },
142         { 0x11, 0x1b, 0xff, 0xff },
143         { 0x16, 0xff, 0xff, 0xff }
144 };
145
146 static const u8 edp_pre_emp_hbr_rbr[4][4] = {
147         { 0x05, 0x12, 0x17, 0x1d },
148         { 0x05, 0x11, 0x18, 0xff },
149         { 0x06, 0x11, 0xff, 0xff },
150         { 0x00, 0xff, 0xff, 0xff }
151 };
152
153 static const u8 edp_swing_hbr2_hbr3[4][4] = {
154         { 0x0b, 0x11, 0x17, 0x1c },
155         { 0x10, 0x19, 0x1f, 0xff },
156         { 0x19, 0x1f, 0xff, 0xff },
157         { 0x1f, 0xff, 0xff, 0xff }
158 };
159
160 static const u8 edp_pre_emp_hbr2_hbr3[4][4] = {
161         { 0x08, 0x11, 0x17, 0x1b },
162         { 0x00, 0x0c, 0x13, 0xff },
163         { 0x05, 0x10, 0xff, 0xff },
164         { 0x00, 0xff, 0xff, 0xff }
165 };
166
167 static const struct qcom_edp_cfg edp_phy_cfg = {
168         .is_dp = false,
169         .swing_hbr_rbr = &edp_swing_hbr_rbr,
170         .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3,
171         .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr,
172         .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
173 };
174
175 static int qcom_edp_phy_init(struct phy *phy)
176 {
177         struct qcom_edp *edp = phy_get_drvdata(phy);
178         const struct qcom_edp_cfg *cfg = edp->cfg;
179         int ret;
180         u8 cfg8;
181
182         ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
183         if (ret)
184                 return ret;
185
186         ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
187         if (ret)
188                 goto out_disable_supplies;
189
190         writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
191                DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
192                edp->edp + DP_PHY_PD_CTL);
193
194         /* Turn on BIAS current for PHY/PLL */
195         writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
196
197         writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
198         msleep(20);
199
200         writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
201                DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
202                DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
203                edp->edp + DP_PHY_PD_CTL);
204
205         if (cfg && cfg->is_dp)
206                 cfg8 = 0xb7;
207         else
208                 cfg8 = 0x37;
209
210         writel(0xfc, edp->edp + DP_PHY_MODE);
211
212         writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
213         writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
214         writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
215         writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
216         writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
217         writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
218         writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
219         writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
220         writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
221         writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
222
223         writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
224                PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
225                PHY_AUX_REQ_ERR_MASK, edp->edp + DP_PHY_AUX_INTERRUPT_MASK);
226
227         msleep(20);
228
229         return 0;
230
231 out_disable_supplies:
232         regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
233
234         return ret;
235 }
236
237 static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
238 {
239         const struct qcom_edp_cfg *cfg = edp->cfg;
240         unsigned int v_level = 0;
241         unsigned int p_level = 0;
242         u8 ldo_config;
243         u8 swing;
244         u8 emph;
245         int i;
246
247         if (!cfg)
248                 return 0;
249
250         for (i = 0; i < dp_opts->lanes; i++) {
251                 v_level = max(v_level, dp_opts->voltage[i]);
252                 p_level = max(p_level, dp_opts->pre[i]);
253         }
254
255         if (dp_opts->link_rate <= 2700) {
256                 swing = (*cfg->swing_hbr_rbr)[v_level][p_level];
257                 emph = (*cfg->pre_emphasis_hbr_rbr)[v_level][p_level];
258         } else {
259                 swing = (*cfg->swing_hbr3_hbr2)[v_level][p_level];
260                 emph = (*cfg->pre_emphasis_hbr3_hbr2)[v_level][p_level];
261         }
262
263         if (swing == 0xff || emph == 0xff)
264                 return -EINVAL;
265
266         ldo_config = (cfg && cfg->is_dp) ? 0x1 : 0x0;
267
268         writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
269         writel(swing, edp->tx0 + TXn_TX_DRV_LVL);
270         writel(emph, edp->tx0 + TXn_TX_EMP_POST1_LVL);
271
272         writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
273         writel(swing, edp->tx1 + TXn_TX_DRV_LVL);
274         writel(emph, edp->tx1 + TXn_TX_EMP_POST1_LVL);
275
276         return 0;
277 }
278
279 static int qcom_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
280 {
281         const struct phy_configure_opts_dp *dp_opts = &opts->dp;
282         struct qcom_edp *edp = phy_get_drvdata(phy);
283         int ret = 0;
284
285         memcpy(&edp->dp_opts, dp_opts, sizeof(*dp_opts));
286
287         if (dp_opts->set_voltages)
288                 ret = qcom_edp_set_voltages(edp, dp_opts);
289
290         return ret;
291 }
292
293 static int qcom_edp_configure_ssc(const struct qcom_edp *edp)
294 {
295         const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
296         u32 step1;
297         u32 step2;
298
299         switch (dp_opts->link_rate) {
300         case 1620:
301         case 2700:
302         case 8100:
303                 step1 = 0x45;
304                 step2 = 0x06;
305                 break;
306
307         case 5400:
308                 step1 = 0x5c;
309                 step2 = 0x08;
310                 break;
311
312         default:
313                 /* Other link rates aren't supported */
314                 return -EINVAL;
315         }
316
317         writel(0x01, edp->pll + QSERDES_V4_COM_SSC_EN_CENTER);
318         writel(0x00, edp->pll + QSERDES_V4_COM_SSC_ADJ_PER1);
319         writel(0x36, edp->pll + QSERDES_V4_COM_SSC_PER1);
320         writel(0x01, edp->pll + QSERDES_V4_COM_SSC_PER2);
321         writel(step1, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0);
322         writel(step2, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0);
323
324         return 0;
325 }
326
327 static int qcom_edp_configure_pll(const struct qcom_edp *edp)
328 {
329         const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
330         u32 div_frac_start2_mode0;
331         u32 div_frac_start3_mode0;
332         u32 dec_start_mode0;
333         u32 lock_cmp1_mode0;
334         u32 lock_cmp2_mode0;
335         u32 hsclk_sel;
336
337         switch (dp_opts->link_rate) {
338         case 1620:
339                 hsclk_sel = 0x5;
340                 dec_start_mode0 = 0x69;
341                 div_frac_start2_mode0 = 0x80;
342                 div_frac_start3_mode0 = 0x07;
343                 lock_cmp1_mode0 = 0x6f;
344                 lock_cmp2_mode0 = 0x08;
345                 break;
346
347         case 2700:
348                 hsclk_sel = 0x3;
349                 dec_start_mode0 = 0x69;
350                 div_frac_start2_mode0 = 0x80;
351                 div_frac_start3_mode0 = 0x07;
352                 lock_cmp1_mode0 = 0x0f;
353                 lock_cmp2_mode0 = 0x0e;
354                 break;
355
356         case 5400:
357                 hsclk_sel = 0x1;
358                 dec_start_mode0 = 0x8c;
359                 div_frac_start2_mode0 = 0x00;
360                 div_frac_start3_mode0 = 0x0a;
361                 lock_cmp1_mode0 = 0x1f;
362                 lock_cmp2_mode0 = 0x1c;
363                 break;
364
365         case 8100:
366                 hsclk_sel = 0x0;
367                 dec_start_mode0 = 0x69;
368                 div_frac_start2_mode0 = 0x80;
369                 div_frac_start3_mode0 = 0x07;
370                 lock_cmp1_mode0 = 0x2f;
371                 lock_cmp2_mode0 = 0x2a;
372                 break;
373
374         default:
375                 /* Other link rates aren't supported */
376                 return -EINVAL;
377         }
378
379         writel(0x01, edp->pll + QSERDES_V4_COM_SVS_MODE_CLK_SEL);
380         writel(0x0b, edp->pll + QSERDES_V4_COM_SYSCLK_EN_SEL);
381         writel(0x02, edp->pll + QSERDES_V4_COM_SYS_CLK_CTRL);
382         writel(0x0c, edp->pll + QSERDES_V4_COM_CLK_ENABLE1);
383         writel(0x06, edp->pll + QSERDES_V4_COM_SYSCLK_BUF_ENABLE);
384         writel(0x30, edp->pll + QSERDES_V4_COM_CLK_SELECT);
385         writel(hsclk_sel, edp->pll + QSERDES_V4_COM_HSCLK_SEL);
386         writel(0x0f, edp->pll + QSERDES_V4_COM_PLL_IVCO);
387         writel(0x08, edp->pll + QSERDES_V4_COM_LOCK_CMP_EN);
388         writel(0x36, edp->pll + QSERDES_V4_COM_PLL_CCTRL_MODE0);
389         writel(0x16, edp->pll + QSERDES_V4_COM_PLL_RCTRL_MODE0);
390         writel(0x06, edp->pll + QSERDES_V4_COM_CP_CTRL_MODE0);
391         writel(dec_start_mode0, edp->pll + QSERDES_V4_COM_DEC_START_MODE0);
392         writel(0x00, edp->pll + QSERDES_V4_COM_DIV_FRAC_START1_MODE0);
393         writel(div_frac_start2_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START2_MODE0);
394         writel(div_frac_start3_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START3_MODE0);
395         writel(0x02, edp->pll + QSERDES_V4_COM_CMN_CONFIG);
396         writel(0x3f, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0);
397         writel(0x00, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0);
398         writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_MAP);
399         writel(lock_cmp1_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP1_MODE0);
400         writel(lock_cmp2_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP2_MODE0);
401
402         writel(0x0a, edp->pll + QSERDES_V4_COM_BG_TIMER);
403         writel(0x14, edp->pll + QSERDES_V4_COM_CORECLK_DIV_MODE0);
404         writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_CTRL);
405         writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
406         writel(0x0f, edp->pll + QSERDES_V4_COM_CORE_CLK_EN);
407         writel(0xa0, edp->pll + QSERDES_V4_COM_VCO_TUNE1_MODE0);
408         writel(0x03, edp->pll + QSERDES_V4_COM_VCO_TUNE2_MODE0);
409
410         return 0;
411 }
412
413 static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel_freq)
414 {
415         const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
416         u32 vco_div;
417
418         switch (dp_opts->link_rate) {
419         case 1620:
420                 vco_div = 0x1;
421                 *pixel_freq = 1620000000UL / 2;
422                 break;
423
424         case 2700:
425                 vco_div = 0x1;
426                 *pixel_freq = 2700000000UL / 2;
427                 break;
428
429         case 5400:
430                 vco_div = 0x2;
431                 *pixel_freq = 5400000000UL / 4;
432                 break;
433
434         case 8100:
435                 vco_div = 0x0;
436                 *pixel_freq = 8100000000UL / 6;
437                 break;
438
439         default:
440                 /* Other link rates aren't supported */
441                 return -EINVAL;
442         }
443
444         writel(vco_div, edp->edp + DP_PHY_VCO_DIV);
445
446         return 0;
447 }
448
449 static int qcom_edp_phy_power_on(struct phy *phy)
450 {
451         const struct qcom_edp *edp = phy_get_drvdata(phy);
452         const struct qcom_edp_cfg *cfg = edp->cfg;
453         u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
454         unsigned long pixel_freq;
455         u8 ldo_config;
456         int timeout;
457         int ret;
458         u32 val;
459         u8 cfg1;
460
461         writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
462                DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
463                DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
464                edp->edp + DP_PHY_PD_CTL);
465         writel(0xfc, edp->edp + DP_PHY_MODE);
466
467         timeout = readl_poll_timeout(edp->pll + QSERDES_V4_COM_CMN_STATUS,
468                                      val, val & BIT(7), 5, 200);
469         if (timeout)
470                 return timeout;
471
472
473         ldo_config = (cfg && cfg->is_dp) ? 0x1 : 0x0;
474
475         writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
476         writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
477         writel(0x00, edp->tx0 + TXn_LANE_MODE_1);
478         writel(0x00, edp->tx1 + TXn_LANE_MODE_1);
479
480         if (edp->dp_opts.ssc) {
481                 ret = qcom_edp_configure_ssc(edp);
482                 if (ret)
483                         return ret;
484         }
485
486         ret = qcom_edp_configure_pll(edp);
487         if (ret)
488                 return ret;
489
490         /* TX Lane configuration */
491         writel(0x05, edp->edp + DP_PHY_TX0_TX1_LANE_CTL);
492         writel(0x05, edp->edp + DP_PHY_TX2_TX3_LANE_CTL);
493
494         /* TX-0 register configuration */
495         writel(0x03, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN);
496         writel(0x0f, edp->tx0 + TXn_CLKBUF_ENABLE);
497         writel(0x03, edp->tx0 + TXn_RESET_TSYNC_EN);
498         writel(0x01, edp->tx0 + TXn_TRAN_DRVR_EMP_EN);
499         writel(0x04, edp->tx0 + TXn_TX_BAND);
500
501         /* TX-1 register configuration */
502         writel(0x03, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN);
503         writel(0x0f, edp->tx1 + TXn_CLKBUF_ENABLE);
504         writel(0x03, edp->tx1 + TXn_RESET_TSYNC_EN);
505         writel(0x01, edp->tx1 + TXn_TRAN_DRVR_EMP_EN);
506         writel(0x04, edp->tx1 + TXn_TX_BAND);
507
508         ret = qcom_edp_set_vco_div(edp, &pixel_freq);
509         if (ret)
510                 return ret;
511
512         writel(0x01, edp->edp + DP_PHY_CFG);
513         writel(0x05, edp->edp + DP_PHY_CFG);
514         writel(0x01, edp->edp + DP_PHY_CFG);
515         writel(0x09, edp->edp + DP_PHY_CFG);
516
517         writel(0x20, edp->pll + QSERDES_V4_COM_RESETSM_CNTRL);
518
519         timeout = readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS,
520                                      val, val & BIT(0), 500, 10000);
521         if (timeout)
522                 return timeout;
523
524         writel(0x19, edp->edp + DP_PHY_CFG);
525         writel(0x1f, edp->tx0 + TXn_HIGHZ_DRVR_EN);
526         writel(0x04, edp->tx0 + TXn_HIGHZ_DRVR_EN);
527         writel(0x00, edp->tx0 + TXn_TX_POL_INV);
528         writel(0x1f, edp->tx1 + TXn_HIGHZ_DRVR_EN);
529         writel(0x04, edp->tx1 + TXn_HIGHZ_DRVR_EN);
530         writel(0x00, edp->tx1 + TXn_TX_POL_INV);
531         writel(0x10, edp->tx0 + TXn_TX_DRV_LVL_OFFSET);
532         writel(0x10, edp->tx1 + TXn_TX_DRV_LVL_OFFSET);
533         writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX0);
534         writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX1);
535         writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX0);
536         writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX1);
537
538         writel(0x10, edp->tx0 + TXn_TX_EMP_POST1_LVL);
539         writel(0x10, edp->tx1 + TXn_TX_EMP_POST1_LVL);
540         writel(0x1f, edp->tx0 + TXn_TX_DRV_LVL);
541         writel(0x1f, edp->tx1 + TXn_TX_DRV_LVL);
542
543         if (edp->dp_opts.lanes == 1) {
544                 bias0_en = 0x01;
545                 bias1_en = 0x00;
546                 drvr0_en = 0x06;
547                 drvr1_en = 0x07;
548                 cfg1 = 0x1;
549         } else if (edp->dp_opts.lanes == 2) {
550                 bias0_en = 0x03;
551                 bias1_en = 0x00;
552                 drvr0_en = 0x04;
553                 drvr1_en = 0x07;
554                 cfg1 = 0x3;
555         } else {
556                 bias0_en = 0x03;
557                 bias1_en = 0x03;
558                 drvr0_en = 0x04;
559                 drvr1_en = 0x04;
560                 cfg1 = 0xf;
561         }
562
563         writel(drvr0_en, edp->tx0 + TXn_HIGHZ_DRVR_EN);
564         writel(bias0_en, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN);
565         writel(drvr1_en, edp->tx1 + TXn_HIGHZ_DRVR_EN);
566         writel(bias1_en, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN);
567         writel(cfg1, edp->edp + DP_PHY_CFG_1);
568
569         writel(0x18, edp->edp + DP_PHY_CFG);
570         usleep_range(100, 1000);
571
572         writel(0x19, edp->edp + DP_PHY_CFG);
573
574         ret = readl_poll_timeout(edp->edp + DP_PHY_STATUS,
575                                  val, val & BIT(1), 500, 10000);
576         if (ret)
577                 return ret;
578
579         clk_set_rate(edp->dp_link_hw.clk, edp->dp_opts.link_rate * 100000);
580         clk_set_rate(edp->dp_pixel_hw.clk, pixel_freq);
581
582         return 0;
583 }
584
585 static int qcom_edp_phy_power_off(struct phy *phy)
586 {
587         const struct qcom_edp *edp = phy_get_drvdata(phy);
588
589         writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
590
591         return 0;
592 }
593
594 static int qcom_edp_phy_exit(struct phy *phy)
595 {
596         struct qcom_edp *edp = phy_get_drvdata(phy);
597
598         clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
599         regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
600
601         return 0;
602 }
603
604 static const struct phy_ops qcom_edp_ops = {
605         .init           = qcom_edp_phy_init,
606         .configure      = qcom_edp_phy_configure,
607         .power_on       = qcom_edp_phy_power_on,
608         .power_off      = qcom_edp_phy_power_off,
609         .exit           = qcom_edp_phy_exit,
610         .owner          = THIS_MODULE,
611 };
612
613 /*
614  * Embedded Display Port PLL driver block diagram for branch clocks
615  *
616  *              +------------------------------+
617  *              |        EDP_VCO_CLK           |
618  *              |                              |
619  *              |    +-------------------+     |
620  *              |    |  (EDP PLL/VCO)    |     |
621  *              |    +---------+---------+     |
622  *              |              v               |
623  *              |   +----------+-----------+   |
624  *              |   | hsclk_divsel_clk_src |   |
625  *              |   +----------+-----------+   |
626  *              +------------------------------+
627  *                              |
628  *          +---------<---------v------------>----------+
629  *          |                                           |
630  * +--------v----------------+                          |
631  * |   edp_phy_pll_link_clk  |                          |
632  * |     link_clk            |                          |
633  * +--------+----------------+                          |
634  *          |                                           |
635  *          |                                           |
636  *          v                                           v
637  * Input to DISPCC block                                |
638  * for link clk, crypto clk                             |
639  * and interface clock                                  |
640  *                                                      |
641  *                                                      |
642  *      +--------<------------+-----------------+---<---+
643  *      |                     |                 |
644  * +----v---------+  +--------v-----+  +--------v------+
645  * | vco_divided  |  | vco_divided  |  | vco_divided   |
646  * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
647  * |              |  |              |  |               |
648  * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
649  * +-------+------+  +-----+--------+  +--------+------+
650  *         |                 |                  |
651  *         v---->----------v-------------<------v
652  *                         |
653  *              +----------+-----------------+
654  *              |   edp_phy_pll_vco_div_clk  |
655  *              +---------+------------------+
656  *                        |
657  *                        v
658  *              Input to DISPCC block
659  *              for EDP pixel clock
660  *
661  */
662 static int qcom_edp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
663                                                 struct clk_rate_request *req)
664 {
665         switch (req->rate) {
666         case 1620000000UL / 2:
667         case 2700000000UL / 2:
668         /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
669                 return 0;
670
671         default:
672                 return -EINVAL;
673         }
674 }
675
676 static unsigned long
677 qcom_edp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
678 {
679         const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_pixel_hw);
680         const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
681
682         switch (dp_opts->link_rate) {
683         case 1620:
684                 return 1620000000UL / 2;
685         case 2700:
686                 return 2700000000UL / 2;
687         case 5400:
688                 return 5400000000UL / 4;
689         case 8100:
690                 return 8100000000UL / 6;
691         default:
692                 return 0;
693         }
694 }
695
696 static const struct clk_ops qcom_edp_dp_pixel_clk_ops = {
697         .determine_rate = qcom_edp_dp_pixel_clk_determine_rate,
698         .recalc_rate = qcom_edp_dp_pixel_clk_recalc_rate,
699 };
700
701 static int qcom_edp_dp_link_clk_determine_rate(struct clk_hw *hw,
702                                                struct clk_rate_request *req)
703 {
704         switch (req->rate) {
705         case 162000000:
706         case 270000000:
707         case 540000000:
708         case 810000000:
709                 return 0;
710
711         default:
712                 return -EINVAL;
713         }
714 }
715
716 static unsigned long
717 qcom_edp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
718 {
719         const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_link_hw);
720         const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
721
722         switch (dp_opts->link_rate) {
723         case 1620:
724         case 2700:
725         case 5400:
726         case 8100:
727                 return dp_opts->link_rate * 100000;
728
729         default:
730                 return 0;
731         }
732 }
733
734 static const struct clk_ops qcom_edp_dp_link_clk_ops = {
735         .determine_rate = qcom_edp_dp_link_clk_determine_rate,
736         .recalc_rate = qcom_edp_dp_link_clk_recalc_rate,
737 };
738
739 static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
740 {
741         struct clk_hw_onecell_data *data;
742         struct clk_init_data init = { };
743         char name[64];
744         int ret;
745
746         data = devm_kzalloc(edp->dev, struct_size(data, hws, 2), GFP_KERNEL);
747         if (!data)
748                 return -ENOMEM;
749
750         snprintf(name, sizeof(name), "%s::link_clk", dev_name(edp->dev));
751         init.ops = &qcom_edp_dp_link_clk_ops;
752         init.name = name;
753         edp->dp_link_hw.init = &init;
754         ret = devm_clk_hw_register(edp->dev, &edp->dp_link_hw);
755         if (ret)
756                 return ret;
757
758         snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(edp->dev));
759         init.ops = &qcom_edp_dp_pixel_clk_ops;
760         init.name = name;
761         edp->dp_pixel_hw.init = &init;
762         ret = devm_clk_hw_register(edp->dev, &edp->dp_pixel_hw);
763         if (ret)
764                 return ret;
765
766         data->hws[0] = &edp->dp_link_hw;
767         data->hws[1] = &edp->dp_pixel_hw;
768         data->num = 2;
769
770         return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
771 }
772
773 static int qcom_edp_phy_probe(struct platform_device *pdev)
774 {
775         struct phy_provider *phy_provider;
776         struct device *dev = &pdev->dev;
777         struct qcom_edp *edp;
778         int ret;
779
780         edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL);
781         if (!edp)
782                 return -ENOMEM;
783
784         edp->dev = dev;
785         edp->cfg = of_device_get_match_data(&pdev->dev);
786
787         edp->edp = devm_platform_ioremap_resource(pdev, 0);
788         if (IS_ERR(edp->edp))
789                 return PTR_ERR(edp->edp);
790
791         edp->tx0 = devm_platform_ioremap_resource(pdev, 1);
792         if (IS_ERR(edp->tx0))
793                 return PTR_ERR(edp->tx0);
794
795         edp->tx1 = devm_platform_ioremap_resource(pdev, 2);
796         if (IS_ERR(edp->tx1))
797                 return PTR_ERR(edp->tx1);
798
799         edp->pll = devm_platform_ioremap_resource(pdev, 3);
800         if (IS_ERR(edp->pll))
801                 return PTR_ERR(edp->pll);
802
803         edp->clks[0].id = "aux";
804         edp->clks[1].id = "cfg_ahb";
805         ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks);
806         if (ret)
807                 return ret;
808
809         edp->supplies[0].supply = "vdda-phy";
810         edp->supplies[1].supply = "vdda-pll";
811         ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies), edp->supplies);
812         if (ret)
813                 return ret;
814
815         ret = regulator_set_load(edp->supplies[0].consumer, 21800); /* 1.2 V vdda-phy */
816         if (ret) {
817                 dev_err(dev, "failed to set load at %s\n", edp->supplies[0].supply);
818                 return ret;
819         }
820
821         ret = regulator_set_load(edp->supplies[1].consumer, 36000); /* 0.9 V vdda-pll */
822         if (ret) {
823                 dev_err(dev, "failed to set load at %s\n", edp->supplies[1].supply);
824                 return ret;
825         }
826
827         ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
828         if (ret)
829                 return ret;
830
831         edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
832         if (IS_ERR(edp->phy)) {
833                 dev_err(dev, "failed to register phy\n");
834                 return PTR_ERR(edp->phy);
835         }
836
837         phy_set_drvdata(edp->phy, edp);
838
839         phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
840         return PTR_ERR_OR_ZERO(phy_provider);
841 }
842
843 static const struct of_device_id qcom_edp_phy_match_table[] = {
844         { .compatible = "qcom,sc7280-edp-phy" },
845         { .compatible = "qcom,sc8180x-edp-phy" },
846         { .compatible = "qcom,sc8280xp-dp-phy", .data = &dp_phy_cfg },
847         { .compatible = "qcom,sc8280xp-edp-phy", .data = &edp_phy_cfg },
848         { }
849 };
850 MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
851
852 static struct platform_driver qcom_edp_phy_driver = {
853         .probe          = qcom_edp_phy_probe,
854         .driver = {
855                 .name   = "qcom-edp-phy",
856                 .of_match_table = qcom_edp_phy_match_table,
857         },
858 };
859
860 module_platform_driver(qcom_edp_phy_driver);
861
862 MODULE_AUTHOR("Bjorn Andersson <[email protected]>");
863 MODULE_DESCRIPTION("Qualcomm eDP QMP PHY driver");
864 MODULE_LICENSE("GPL v2");
This page took 0.08265 seconds and 4 git commands to generate.