1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Wyon Bi <bivvy.bi@rock-chips.com>
6 */
7
8 #include <common.h>
9 #include <dm.h>
10 #include <generic-phy.h>
11 #include <syscon.h>
12 #include <regmap.h>
13 #include <asm/io.h>
14 #include <linux/bitfield.h>
15 #include <linux/iopoll.h>
16
17 #define EDP_PHY_GRF_CON0 0x0000
18 #define EDP_PHY_TX_IDLE GENMASK(11, 8)
19 #define EDP_PHY_TX_PD GENMASK(7, 4)
20 #define EDP_PHY_IDDQ_EN BIT(1)
21 #define EDP_PHY_PD_PLL BIT(0)
22 #define EDP_PHY_GRF_CON1 0x0004
23 #define EDP_PHY_PLL_DIV GENMASK(14, 0)
24 #define EDP_PHY_GRF_CON2 0x0008
25 #define EDP_PHY_TX_RTERM GENMASK(10, 8)
26 #define EDP_PHY_RATE GENMASK(5, 4)
27 #define EDP_PHY_REF_DIV GENMASK(3, 0)
28 #define EDP_PHY_GRF_CON3 0x000c
29 #define EDP_PHY_TX3_EMP GENMASK(15, 12)
30 #define EDP_PHY_TX2_EMP GENMASK(11, 8)
31 #define EDP_PHY_TX1_EMP GENMASK(7, 4)
32 #define EDP_PHY_TX0_EMP GENMASK(3, 0)
33 #define EDP_PHY_GRF_CON4 0x0010
34 #define EDP_PHY_TX3_AMP GENMASK(14, 12)
35 #define EDP_PHY_TX2_AMP GENMASK(10, 8)
36 #define EDP_PHY_TX1_AMP GENMASK(6, 4)
37 #define EDP_PHY_TX0_AMP GENMASK(2, 0)
38 #define EDP_PHY_GRF_CON5 0x0014
39 #define EDP_PHY_TX_MODE GENMASK(9, 8)
40 #define EDP_PHY_TX3_AMP_SCALE GENMASK(7, 6)
41 #define EDP_PHY_TX2_AMP_SCALE GENMASK(5, 4)
42 #define EDP_PHY_TX1_AMP_SCALE GENMASK(3, 2)
43 #define EDP_PHY_TX0_AMP_SCALE GENMASK(1, 0)
44 #define EDP_PHY_GRF_CON6 0x0018
45 #define EDP_PHY_SSC_DEPTH GENMASK(15, 12)
46 #define EDP_PHY_SSC_EN BIT(11)
47 #define EDP_PHY_SSC_CNT GENMASK(9, 0)
48 #define EDP_PHY_GRF_CON7 0x001c
49 #define EDP_PHY_GRF_CON8 0x0020
50 #define EDP_PHY_PLL_CTL_H GENMASK(15, 0)
51 #define EDP_PHY_GRF_CON9 0x0024
52 #define EDP_PHY_TX_CTL GENMASK(15, 0)
53 #define EDP_PHY_GRF_CON10 0x0028
54 #define EDP_PHY_AUX_RCV_PD_SEL BIT(5)
55 #define EDP_PHY_AUX_DRV_PD_SEL BIT(4)
56 #define EDP_PHY_AUX_IDLE BIT(2)
57 #define EDP_PHY_AUX_RCV_PD BIT(1)
58 #define EDP_PHY_AUX_DRV_PD BIT(0)
59 #define EDP_PHY_GRF_CON11 0x002c
60 #define EDP_PHY_AUX_RCV_VCM GENMASK(14, 12)
61 #define EDP_PHY_AUX_MODE GENMASK(11, 10)
62 #define EDP_PHY_AUX_AMP_SCALE GENMASK(9, 8)
63 #define EDP_PHY_AUX_AMP GENMASK(6, 4)
64 #define EDP_PHY_AUX_RTERM GENMASK(2, 0)
65 #define EDP_PHY_GRF_STATUS0 0x0030
66 #define PLL_RDY BIT(0)
67 #define EDP_PHY_GRF_STATUS1 0x0034
68
69 struct rockchip_edp_phy {
70 struct regmap *grf;
71 struct udevice *dev;
72 };
73
rockchip_grf_write(struct regmap * grf,uint reg,uint mask,uint val)74 static inline int rockchip_grf_write(struct regmap *grf, uint reg, uint mask,
75 uint val)
76 {
77 return regmap_write(grf, reg, (mask << 16) | (val & mask));
78 }
79
80 static struct {
81 int amp;
82 int amp_scale;
83 int emp;
84 } vp[4][4] = {
85 { {0x1, 0x1, 0x0}, {0x2, 0x1, 0x4}, {0x3, 0x1, 0x8}, {0x4, 0x1, 0xd} },
86 { {0x3, 0x1, 0x0}, {0x5, 0x1, 0x7}, {0x6, 0x1, 0x6}, { -1, -1, -1} },
87 { {0x5, 0x1, 0x0}, {0x7, 0x1, 0x4}, { -1, -1, -1}, { -1, -1, -1} },
88 { {0x7, 0x1, 0x0}, { -1, -1, -1}, { -1, -1, -1}, { -1, -1, -1} },
89 };
90
rockchip_edp_phy_set_voltage(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp,u8 lane)91 static void rockchip_edp_phy_set_voltage(struct rockchip_edp_phy *edpphy,
92 struct phy_configure_opts_dp *dp,
93 u8 lane)
94 {
95 u32 amp, amp_scale, emp;
96
97 amp = vp[dp->voltage[lane]][dp->pre[lane]].amp;
98 amp_scale = vp[dp->voltage[lane]][dp->pre[lane]].amp_scale;
99 emp = vp[dp->voltage[lane]][dp->pre[lane]].emp;
100
101 switch (lane) {
102 case 0:
103 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON3,
104 EDP_PHY_TX0_EMP,
105 FIELD_PREP(EDP_PHY_TX0_EMP, emp));
106 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON4,
107 EDP_PHY_TX0_AMP,
108 FIELD_PREP(EDP_PHY_TX0_AMP, amp));
109 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5,
110 EDP_PHY_TX0_AMP_SCALE,
111 FIELD_PREP(EDP_PHY_TX0_AMP_SCALE, amp_scale));
112 break;
113 case 1:
114 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON3,
115 EDP_PHY_TX1_EMP,
116 FIELD_PREP(EDP_PHY_TX1_EMP, emp));
117 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON4,
118 EDP_PHY_TX1_AMP,
119 FIELD_PREP(EDP_PHY_TX1_AMP, amp));
120 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5,
121 EDP_PHY_TX1_AMP_SCALE,
122 FIELD_PREP(EDP_PHY_TX1_AMP_SCALE, amp_scale));
123 break;
124 case 2:
125 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON3,
126 EDP_PHY_TX2_EMP,
127 FIELD_PREP(EDP_PHY_TX2_EMP, emp));
128 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON4,
129 EDP_PHY_TX2_AMP,
130 FIELD_PREP(EDP_PHY_TX2_AMP, amp));
131 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5,
132 EDP_PHY_TX2_AMP_SCALE,
133 FIELD_PREP(EDP_PHY_TX2_AMP_SCALE, amp_scale));
134 break;
135 case 3:
136 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON3,
137 EDP_PHY_TX3_EMP,
138 FIELD_PREP(EDP_PHY_TX3_EMP, emp));
139 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON4,
140 EDP_PHY_TX3_AMP,
141 FIELD_PREP(EDP_PHY_TX3_AMP, amp));
142 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5,
143 EDP_PHY_TX3_AMP_SCALE,
144 FIELD_PREP(EDP_PHY_TX3_AMP_SCALE, amp_scale));
145 break;
146 }
147 }
148
rockchip_edp_phy_set_voltages(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)149 static int rockchip_edp_phy_set_voltages(struct rockchip_edp_phy *edpphy,
150 struct phy_configure_opts_dp *dp)
151 {
152
153 u8 lane;
154
155 for (lane = 0; lane < dp->lanes; lane++)
156 rockchip_edp_phy_set_voltage(edpphy, dp, lane);
157
158 return 0;
159 }
160
rockchip_edp_phy_set_rate(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)161 static int rockchip_edp_phy_set_rate(struct rockchip_edp_phy *edpphy,
162 struct phy_configure_opts_dp *dp)
163 {
164 u32 value;
165 int ret;
166
167 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0,
168 EDP_PHY_TX_IDLE | EDP_PHY_TX_PD,
169 FIELD_PREP(EDP_PHY_TX_IDLE, 0xf) |
170 FIELD_PREP(EDP_PHY_TX_PD, 0xf));
171 udelay(100);
172 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5, EDP_PHY_TX_MODE,
173 FIELD_PREP(EDP_PHY_TX_MODE, 0x3));
174 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_PD_PLL,
175 FIELD_PREP(EDP_PHY_PD_PLL, 0x1));
176
177 switch (dp->link_rate) {
178 case 1620:
179 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON1,
180 EDP_PHY_PLL_DIV,
181 FIELD_PREP(EDP_PHY_PLL_DIV, 0x4380));
182 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON2,
183 EDP_PHY_TX_RTERM | EDP_PHY_RATE | EDP_PHY_REF_DIV,
184 FIELD_PREP(EDP_PHY_TX_RTERM, 0x1) |
185 FIELD_PREP(EDP_PHY_RATE, 0x1) |
186 FIELD_PREP(EDP_PHY_REF_DIV, 0x0));
187 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON8,
188 EDP_PHY_PLL_CTL_H,
189 FIELD_PREP(EDP_PHY_PLL_CTL_H, 0x0800));
190 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON9,
191 EDP_PHY_TX_CTL,
192 FIELD_PREP(EDP_PHY_TX_CTL, 0x0000));
193 break;
194 case 2700:
195 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON1,
196 EDP_PHY_PLL_DIV,
197 FIELD_PREP(EDP_PHY_PLL_DIV, 0x3840));
198 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON2,
199 EDP_PHY_TX_RTERM | EDP_PHY_RATE | EDP_PHY_REF_DIV,
200 FIELD_PREP(EDP_PHY_TX_RTERM, 0x1) |
201 FIELD_PREP(EDP_PHY_RATE, 0x0) |
202 FIELD_PREP(EDP_PHY_REF_DIV, 0x0));
203 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON8,
204 EDP_PHY_PLL_CTL_H,
205 FIELD_PREP(EDP_PHY_PLL_CTL_H, 0x0800));
206 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON9,
207 EDP_PHY_TX_CTL,
208 FIELD_PREP(EDP_PHY_TX_CTL, 0x0000));
209 break;
210 }
211
212 if (dp->ssc)
213 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON6,
214 EDP_PHY_SSC_DEPTH | EDP_PHY_SSC_EN | EDP_PHY_SSC_CNT,
215 FIELD_PREP(EDP_PHY_SSC_DEPTH, 0x9) |
216 FIELD_PREP(EDP_PHY_SSC_EN, 0x1) |
217 FIELD_PREP(EDP_PHY_SSC_CNT, 0x17d));
218 else
219 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON6,
220 EDP_PHY_SSC_EN,
221 FIELD_PREP(EDP_PHY_SSC_EN, 0x0));
222
223 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_PD_PLL,
224 FIELD_PREP(EDP_PHY_PD_PLL, 0));
225 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_TX_PD,
226 FIELD_PREP(EDP_PHY_TX_PD, ~GENMASK(dp->lanes - 1, 0)));
227 ret = regmap_read_poll_timeout(edpphy->grf, EDP_PHY_GRF_STATUS0,
228 value, value & PLL_RDY, 100, 1000);
229 if (ret) {
230 dev_err(edpphy->dev, "pll is not ready: %d\n", ret);
231 return ret;
232 }
233
234 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5, EDP_PHY_TX_MODE,
235 FIELD_PREP(EDP_PHY_TX_MODE, 0x0));
236 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_TX_IDLE,
237 FIELD_PREP(EDP_PHY_TX_IDLE, ~GENMASK(dp->lanes - 1, 0)));
238
239 return 0;
240 }
241
rockchip_edp_phy_verify_config(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)242 static int rockchip_edp_phy_verify_config(struct rockchip_edp_phy *edpphy,
243 struct phy_configure_opts_dp *dp)
244 {
245 int i;
246
247 /* If changing link rate was required, verify it's supported. */
248 if (dp->set_rate) {
249 switch (dp->link_rate) {
250 case 1620:
251 case 2700:
252 /* valid bit rate */
253 break;
254 default:
255 return -EINVAL;
256 }
257 }
258
259 /* Verify lane count. */
260 switch (dp->lanes) {
261 case 1:
262 case 2:
263 case 4:
264 /* valid lane count. */
265 break;
266 default:
267 return -EINVAL;
268 }
269
270 /*
271 * If changing voltages is required, check swing and pre-emphasis
272 * levels, per-lane.
273 */
274 if (dp->set_voltages) {
275 /* Lane count verified previously. */
276 for (i = 0; i < dp->lanes; i++) {
277 if (dp->voltage[i] > 3 || dp->pre[i] > 3)
278 return -EINVAL;
279
280 /*
281 * Sum of voltage swing and pre-emphasis levels cannot
282 * exceed 3.
283 */
284 if (dp->voltage[i] + dp->pre[i] > 3)
285 return -EINVAL;
286 }
287 }
288
289 return 0;
290 }
291
rockchip_edp_phy_configure(struct phy * phy,union phy_configure_opts * opts)292 static int rockchip_edp_phy_configure(struct phy *phy,
293 union phy_configure_opts *opts)
294 {
295 struct rockchip_edp_phy *edpphy = dev_get_priv(phy->dev);
296 int ret;
297
298 ret = rockchip_edp_phy_verify_config(edpphy, &opts->dp);
299 if (ret) {
300 dev_err(edpphy->dev, "invalid params for phy configure\n");
301 return ret;
302 }
303
304 if (opts->dp.set_rate) {
305 ret = rockchip_edp_phy_set_rate(edpphy, &opts->dp);
306 if (ret) {
307 dev_err(edpphy->dev,
308 "rockchip_edp_phy_set_rate failed\n");
309 return ret;
310 }
311 }
312
313 if (opts->dp.set_voltages) {
314 ret = rockchip_edp_phy_set_voltages(edpphy, &opts->dp);
315 if (ret) {
316 dev_err(edpphy->dev,
317 "rockchip_edp_phy_set_voltages failed\n");
318 return ret;
319 }
320 }
321
322 return 0;
323 }
324
rockchip_edp_phy_power_on(struct phy * phy)325 static int rockchip_edp_phy_power_on(struct phy *phy)
326 {
327 struct rockchip_edp_phy *edpphy = dev_get_priv(phy->dev);
328
329 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON10,
330 EDP_PHY_AUX_RCV_PD | EDP_PHY_AUX_DRV_PD | EDP_PHY_AUX_IDLE,
331 FIELD_PREP(EDP_PHY_AUX_RCV_PD, 0x1) |
332 FIELD_PREP(EDP_PHY_AUX_DRV_PD, 0x1) |
333 FIELD_PREP(EDP_PHY_AUX_IDLE, 0x1));
334 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0,
335 EDP_PHY_TX_IDLE | EDP_PHY_TX_PD | EDP_PHY_PD_PLL,
336 FIELD_PREP(EDP_PHY_TX_IDLE, 0xf) |
337 FIELD_PREP(EDP_PHY_TX_PD, 0xf) |
338 FIELD_PREP(EDP_PHY_PD_PLL, 0x1));
339 udelay(100);
340
341 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON11,
342 EDP_PHY_AUX_RCV_VCM | EDP_PHY_AUX_MODE |
343 EDP_PHY_AUX_AMP_SCALE | EDP_PHY_AUX_AMP |
344 EDP_PHY_AUX_RTERM,
345 FIELD_PREP(EDP_PHY_AUX_RCV_VCM, 0x4) |
346 FIELD_PREP(EDP_PHY_AUX_MODE, 0x1) |
347 FIELD_PREP(EDP_PHY_AUX_AMP_SCALE, 0x1) |
348 FIELD_PREP(EDP_PHY_AUX_AMP, 0x3) |
349 FIELD_PREP(EDP_PHY_AUX_RTERM, 0x1));
350
351 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON10,
352 EDP_PHY_AUX_RCV_PD | EDP_PHY_AUX_DRV_PD,
353 FIELD_PREP(EDP_PHY_AUX_RCV_PD, 0x0) |
354 FIELD_PREP(EDP_PHY_AUX_DRV_PD, 0x0));
355 udelay(100);
356
357 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON10,
358 EDP_PHY_AUX_IDLE,
359 FIELD_PREP(EDP_PHY_AUX_IDLE, 0x0));
360 mdelay(20);
361
362 return 0;
363 }
364
rockchip_edp_phy_power_off(struct phy * phy)365 static int rockchip_edp_phy_power_off(struct phy *phy)
366 {
367 struct rockchip_edp_phy *edpphy = dev_get_priv(phy->dev);
368
369 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0,
370 EDP_PHY_TX_IDLE | EDP_PHY_TX_PD,
371 FIELD_PREP(EDP_PHY_TX_IDLE, 0xf) |
372 FIELD_PREP(EDP_PHY_TX_PD, 0xf));
373 udelay(100);
374 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON5, EDP_PHY_TX_MODE,
375 FIELD_PREP(EDP_PHY_TX_MODE, 0x3));
376 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON0, EDP_PHY_PD_PLL,
377 FIELD_PREP(EDP_PHY_PD_PLL, 0x1));
378 rockchip_grf_write(edpphy->grf, EDP_PHY_GRF_CON10,
379 EDP_PHY_AUX_RCV_PD | EDP_PHY_AUX_DRV_PD | EDP_PHY_AUX_IDLE,
380 FIELD_PREP(EDP_PHY_AUX_RCV_PD, 0x1) |
381 FIELD_PREP(EDP_PHY_AUX_DRV_PD, 0x1) |
382 FIELD_PREP(EDP_PHY_AUX_IDLE, 0x1));
383
384 return 0;
385 }
386
387 static struct phy_ops rockchip_edp_phy_ops = {
388 .power_on = rockchip_edp_phy_power_on,
389 .power_off = rockchip_edp_phy_power_off,
390 .configure = rockchip_edp_phy_configure,
391 };
392
rockchip_edp_phy_probe(struct udevice * dev)393 static int rockchip_edp_phy_probe(struct udevice *dev)
394 {
395 struct rockchip_edp_phy *edpphy = dev_get_priv(dev);
396 int ret;
397
398 ret = uclass_get_device_by_name(UCLASS_SYSCON, "syscon@fdcb0000", &dev);
399 if (ret)
400 return ret;
401
402 edpphy->grf = syscon_get_regmap(dev);
403 if (!edpphy->grf){
404 printf("edpphy grf success\n");
405 return -ENOENT;
406 }
407
408 edpphy->dev = dev;
409
410 return 0;
411 }
412
413 static const struct udevice_id rockchip_edp_phy_ids[] = {
414 { .compatible = "rockchip,rk3568-edp-phy", },
415 {}
416 };
417
418 U_BOOT_DRIVER(rockchip_edp_phy) = {
419 .name = "rockchip_edp_phy",
420 .id = UCLASS_PHY,
421 .ops = &rockchip_edp_phy_ops,
422 .of_match = rockchip_edp_phy_ids,
423 .probe = rockchip_edp_phy_probe,
424 .priv_auto_alloc_size = sizeof(struct rockchip_edp_phy),
425 };
426