1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Rockchip USBDP Combo PHY with Samsung IP block driver
4 *
5 * Copyright (C) 2021 Rockchip Electronics Co., Ltd
6 */
7
8 #include <common.h>
9 #include <clk.h>
10 #include <dm.h>
11 #include <dm/lists.h>
12 #include <dm/of.h>
13 #include <dm/of_access.h>
14 #include <generic-phy.h>
15 #include <linux/bitfield.h>
16 #include <linux/usb/ch9.h>
17 #include <linux/usb/otg.h>
18 #include <regmap.h>
19 #include <reset.h>
20 #include <syscon.h>
21 #include <asm/arch/clock.h>
22 #include <asm/arch/cpu.h>
23
24 #include <linux/usb/phy-rockchip-usbdp.h>
25
26 #define BIT_WRITEABLE_SHIFT 16
27
28 enum {
29 DP_BW_RBR,
30 DP_BW_HBR,
31 DP_BW_HBR2,
32 DP_BW_HBR3,
33 };
34
35 enum {
36 UDPHY_MODE_NONE = 0,
37 UDPHY_MODE_USB = BIT(0),
38 UDPHY_MODE_DP = BIT(1),
39 UDPHY_MODE_DP_USB = BIT(1) | BIT(0),
40 };
41
42 struct udphy_grf_reg {
43 unsigned int offset;
44 unsigned int bitend;
45 unsigned int bitstart;
46 unsigned int disable;
47 unsigned int enable;
48 };
49
50 /**
51 * struct reg_sequence - An individual write from a sequence of writes.
52 *
53 * @reg: Register address.
54 * @def: Register value.
55 * @delay_us: Delay to be applied after the register write in microseconds
56 *
57 * Register/value pairs for sequences of writes with an optional delay in
58 * microseconds to be applied after each write.
59 */
60 struct reg_sequence {
61 unsigned int reg;
62 unsigned int def;
63 unsigned int delay_us;
64 };
65
66 struct udphy_grf_cfg {
67 /* u2phy-grf */
68 struct udphy_grf_reg bvalid_phy_con;
69 struct udphy_grf_reg bvalid_grf_con;
70
71 /* usb-grf */
72 struct udphy_grf_reg usb3otg0_cfg;
73 struct udphy_grf_reg usb3otg1_cfg;
74
75 /* usbdpphy-grf */
76 struct udphy_grf_reg low_pwrn;
77 struct udphy_grf_reg rx_lfps;
78 };
79
80 struct dp_tx_drv_ctrl {
81 u32 trsv_reg0204;
82 u32 trsv_reg0205;
83 u32 trsv_reg0206;
84 u32 trsv_reg0207;
85 };
86
87 struct rockchip_udphy;
88
89 struct rockchip_udphy_cfg {
90 /* resets to be requested */
91 const char * const *rst_list;
92 int num_rsts;
93
94 struct udphy_grf_cfg grfcfg;
95 const struct dp_tx_drv_ctrl (*dp_tx_ctrl_cfg[4])[4];
96 int (*combophy_init)(struct rockchip_udphy *udphy);
97 int (*dp_phy_set_rate)(struct rockchip_udphy *udphy,
98 struct phy_configure_opts_dp *dp);
99 int (*dp_phy_set_voltages)(struct rockchip_udphy *udphy,
100 struct phy_configure_opts_dp *dp);
101 int (*dplane_enable)(struct rockchip_udphy *udphy, int dp_lanes);
102 int (*dplane_select)(struct rockchip_udphy *udphy);
103 };
104
105 struct rockchip_udphy {
106 struct udevice *dev;
107 struct regmap *pma_regmap;
108 struct regmap *u2phygrf;
109 struct regmap *udphygrf;
110 struct regmap *usbgrf;
111 struct regmap *vogrf;
112 // struct typec_switch *sw;
113 // struct typec_mux *mux;
114
115 /* clocks and rests */
116 struct reset_ctl *rsts;
117
118 /* PHY status management */
119 bool flip;
120 bool mode_change;
121 u8 mode;
122 u8 status;
123
124 /* utilized for USB */
125 bool hs; /* flag for high-speed */
126
127 /* utilized for DP */
128 struct gpio_desc *sbu1_dc_gpio;
129 struct gpio_desc *sbu2_dc_gpio;
130 u32 lane_mux_sel[4];
131 u32 dp_lane_sel[4];
132 u32 dp_aux_dout_sel;
133 u32 dp_aux_din_sel;
134 u32 max_link_rate;
135 u8 bw; /* dp bandwidth */
136 int id;
137
138 /* PHY const config */
139 const struct rockchip_udphy_cfg *cfgs;
140 };
141
142 static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr[4][4] = {
143 /* voltage swing 0, pre-emphasis 0->3 */
144 {
145 { 0x20, 0x10, 0x42, 0xe5 },
146 { 0x26, 0x14, 0x42, 0xe5 },
147 { 0x29, 0x18, 0x42, 0xe5 },
148 { 0x2b, 0x1c, 0x43, 0xe7 },
149 },
150
151 /* voltage swing 1, pre-emphasis 0->2 */
152 {
153 { 0x23, 0x10, 0x42, 0xe7 },
154 { 0x2a, 0x17, 0x43, 0xe7 },
155 { 0x2b, 0x1a, 0x43, 0xe7 },
156 },
157
158 /* voltage swing 2, pre-emphasis 0->1 */
159 {
160 { 0x27, 0x10, 0x42, 0xe7 },
161 { 0x2b, 0x17, 0x43, 0xe7 },
162 },
163
164 /* voltage swing 3, pre-emphasis 0 */
165 {
166 { 0x29, 0x10, 0x43, 0xe7 },
167 },
168 };
169
170 static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr2[4][4] = {
171 /* voltage swing 0, pre-emphasis 0->3 */
172 {
173 { 0x21, 0x10, 0x42, 0xe5 },
174 { 0x26, 0x14, 0x42, 0xe5 },
175 { 0x26, 0x16, 0x43, 0xe5 },
176 { 0x2a, 0x19, 0x43, 0xe7 },
177 },
178
179 /* voltage swing 1, pre-emphasis 0->2 */
180 {
181 { 0x24, 0x10, 0x42, 0xe7 },
182 { 0x2a, 0x17, 0x43, 0xe7 },
183 { 0x2b, 0x1a, 0x43, 0xe7 },
184 },
185
186 /* voltage swing 2, pre-emphasis 0->1 */
187 {
188 { 0x28, 0x10, 0x42, 0xe7 },
189 { 0x2b, 0x17, 0x43, 0xe7 },
190 },
191
192 /* voltage swing 3, pre-emphasis 0 */
193 {
194 { 0x28, 0x10, 0x43, 0xe7 },
195 },
196 };
197
198 static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr3[4][4] = {
199 /* voltage swing 0, pre-emphasis 0->3 */
200 {
201 { 0x21, 0x10, 0x42, 0xe5 },
202 { 0x26, 0x14, 0x42, 0xe5 },
203 { 0x26, 0x16, 0x43, 0xe5 },
204 { 0x29, 0x18, 0x43, 0xe7 },
205 },
206
207 /* voltage swing 1, pre-emphasis 0->2 */
208 {
209 { 0x24, 0x10, 0x42, 0xe7 },
210 { 0x2a, 0x18, 0x43, 0xe7 },
211 { 0x2b, 0x1b, 0x43, 0xe7 }
212 },
213
214 /* voltage swing 2, pre-emphasis 0->1 */
215 {
216 { 0x27, 0x10, 0x42, 0xe7 },
217 { 0x2b, 0x18, 0x43, 0xe7 }
218 },
219
220 /* voltage swing 3, pre-emphasis 0 */
221 {
222 { 0x28, 0x10, 0x43, 0xe7 },
223 },
224 };
225
226 static const struct reg_sequence rk3588_udphy_24m_refclk_cfg[] = {
227 {0x0090, 0x68}, {0x0094, 0x68},
228 {0x0128, 0x24}, {0x012c, 0x44},
229 {0x0130, 0x3f}, {0x0134, 0x44},
230 {0x015c, 0xa9}, {0x0160, 0x71},
231 {0x0164, 0x71}, {0x0168, 0xa9},
232 {0x0174, 0xa9}, {0x0178, 0x71},
233 {0x017c, 0x71}, {0x0180, 0xa9},
234 {0x018c, 0x41}, {0x0190, 0x00},
235 {0x0194, 0x05}, {0x01ac, 0x2a},
236 {0x01b0, 0x17}, {0x01b4, 0x17},
237 {0x01b8, 0x2a}, {0x01c8, 0x04},
238 {0x01cc, 0x08}, {0x01d0, 0x08},
239 {0x01d4, 0x04}, {0x01d8, 0x20},
240 {0x01dc, 0x01}, {0x01e0, 0x09},
241 {0x01e4, 0x03}, {0x01f0, 0x29},
242 {0x01f4, 0x02}, {0x01f8, 0x02},
243 {0x01fc, 0x29}, {0x0208, 0x2a},
244 {0x020c, 0x17}, {0x0210, 0x17},
245 {0x0214, 0x2a}, {0x0224, 0x20},
246 {0x03f0, 0x0a}, {0x03f4, 0x07},
247 {0x03f8, 0x07}, {0x03fc, 0x0c},
248 {0x0404, 0x12}, {0x0408, 0x1a},
249 {0x040c, 0x1a}, {0x0410, 0x3f},
250 {0x0ce0, 0x68}, {0x0ce8, 0xd0},
251 {0x0cf0, 0x87}, {0x0cf8, 0x70},
252 {0x0d00, 0x70}, {0x0d08, 0xa9},
253 {0x1ce0, 0x68}, {0x1ce8, 0xd0},
254 {0x1cf0, 0x87}, {0x1cf8, 0x70},
255 {0x1d00, 0x70}, {0x1d08, 0xa9},
256 {0x0a3c, 0xd0}, {0x0a44, 0xd0},
257 {0x0a48, 0x01}, {0x0a4c, 0x0d},
258 {0x0a54, 0xe0}, {0x0a5c, 0xe0},
259 {0x0a64, 0xa8}, {0x1a3c, 0xd0},
260 {0x1a44, 0xd0}, {0x1a48, 0x01},
261 {0x1a4c, 0x0d}, {0x1a54, 0xe0},
262 {0x1a5c, 0xe0}, {0x1a64, 0xa8}
263 };
264
265 static const struct reg_sequence rk3588_udphy_init_sequence[] = {
266 {0x0104, 0x44}, {0x0234, 0xE8},
267 {0x0248, 0x44}, {0x028C, 0x18},
268 {0x081C, 0xE5}, {0x0878, 0x00},
269 {0x0994, 0x1C}, {0x0AF0, 0x00},
270 {0x181C, 0xE5}, {0x1878, 0x00},
271 {0x1994, 0x1C}, {0x1AF0, 0x00},
272 {0x0428, 0x60}, {0x0D58, 0x33},
273 {0x1D58, 0x33}, {0x0990, 0x74},
274 {0x0D64, 0x17}, {0x08C8, 0x13},
275 {0x1990, 0x74}, {0x1D64, 0x17},
276 {0x18C8, 0x13}, {0x0D90, 0x40},
277 {0x0DA8, 0x40}, {0x0DC0, 0x40},
278 {0x0DD8, 0x40}, {0x1D90, 0x40},
279 {0x1DA8, 0x40}, {0x1DC0, 0x40},
280 {0x1DD8, 0x40}, {0x03C0, 0x30},
281 {0x03C4, 0x06}, {0x0E10, 0x00},
282 {0x1E10, 0x00}, {0x043C, 0x0F},
283 {0x0D2C, 0xFF}, {0x1D2C, 0xFF},
284 {0x0D34, 0x0F}, {0x1D34, 0x0F},
285 {0x08FC, 0x2A}, {0x0914, 0x28},
286 {0x0A30, 0x03}, {0x0E38, 0x05},
287 {0x0ECC, 0x27}, {0x0ED0, 0x22},
288 {0x0ED4, 0x26}, {0x18FC, 0x2A},
289 {0x1914, 0x28}, {0x1A30, 0x03},
290 {0x1E38, 0x05}, {0x1ECC, 0x27},
291 {0x1ED0, 0x22}, {0x1ED4, 0x26},
292 {0x0048, 0x0F}, {0x0060, 0x3C},
293 {0x0064, 0xF7}, {0x006C, 0x20},
294 {0x0070, 0x7D}, {0x0074, 0x68},
295 {0x0AF4, 0x1A}, {0x1AF4, 0x1A},
296 {0x0440, 0x3F}, {0x10D4, 0x08},
297 {0x20D4, 0x08}, {0x00D4, 0x30},
298 {0x0024, 0x6e},
299 };
300
grfreg_write(struct regmap * base,const struct udphy_grf_reg * reg,bool en)301 static inline int grfreg_write(struct regmap *base,
302 const struct udphy_grf_reg *reg, bool en)
303 {
304 u32 val, mask, tmp;
305
306 tmp = en ? reg->enable : reg->disable;
307 mask = GENMASK(reg->bitend, reg->bitstart);
308 val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
309
310 return regmap_write(base, reg->offset, val);
311 }
312
__regmap_multi_reg_write(struct regmap * map,const struct reg_sequence * regs,int num_regs)313 static int __regmap_multi_reg_write(struct regmap *map,
314 const struct reg_sequence *regs, int num_regs)
315 {
316 int i, ret = 0;
317
318 for (i = 0; i < num_regs; i++) {
319 ret = regmap_write(map, regs[i].reg, regs[i].def);
320
321 if (regs[i].delay_us)
322 udelay(regs[i].delay_us);
323 }
324
325 return ret;
326 }
327
udphy_clk_init(struct rockchip_udphy * udphy,struct udevice * dev)328 static int udphy_clk_init(struct rockchip_udphy *udphy, struct udevice *dev)
329 {
330 return 0;
331 }
332
udphy_reset_init(struct rockchip_udphy * udphy,struct udevice * dev)333 static int udphy_reset_init(struct rockchip_udphy *udphy, struct udevice *dev)
334 {
335 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
336 int idx;
337 int ret;
338
339 udphy->rsts = devm_kcalloc(dev, cfg->num_rsts,
340 sizeof(*udphy->rsts), GFP_KERNEL);
341 if (!udphy->rsts)
342 return -ENOMEM;
343
344 for (idx = 0; idx < cfg->num_rsts; idx++) {
345 const char *name = cfg->rst_list[idx];
346
347 ret = reset_get_by_name(dev, name, &udphy->rsts[idx]);
348 if (ret) {
349 dev_err(dev, "failed to get %s reset\n", name);
350 goto err;
351 }
352
353 reset_assert(&udphy->rsts[idx]);
354 }
355
356 return 0;
357
358 err:
359 devm_kfree(dev, udphy->rsts);
360 return ret;
361 }
362
udphy_get_rst_idx(const char * const * list,int num,char * name)363 static int udphy_get_rst_idx(const char * const *list, int num, char *name)
364 {
365 int idx;
366
367 for (idx = 0; idx < num; idx++) {
368 if (!strcmp(list[idx], name))
369 return idx;
370 }
371
372 return -EINVAL;
373 }
374
udphy_reset_assert(struct rockchip_udphy * udphy,char * name)375 static int udphy_reset_assert(struct rockchip_udphy *udphy, char *name)
376 {
377 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
378 int idx;
379
380 idx = udphy_get_rst_idx(cfg->rst_list, cfg->num_rsts, name);
381 if (idx < 0)
382 return idx;
383
384 return reset_assert(&udphy->rsts[idx]);
385 }
386
udphy_reset_deassert(struct rockchip_udphy * udphy,char * name)387 static int udphy_reset_deassert(struct rockchip_udphy *udphy, char *name)
388 {
389 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
390 int idx;
391
392 idx = udphy_get_rst_idx(cfg->rst_list, cfg->num_rsts, name);
393 if (idx < 0)
394 return idx;
395
396 return reset_deassert(&udphy->rsts[idx]);
397 }
398
udphy_u3_port_disable(struct rockchip_udphy * udphy,u8 disable)399 static void udphy_u3_port_disable(struct rockchip_udphy *udphy, u8 disable)
400 {
401 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
402 const struct udphy_grf_reg *preg;
403
404 preg = udphy->id ? &cfg->grfcfg.usb3otg1_cfg : &cfg->grfcfg.usb3otg0_cfg;
405 grfreg_write(udphy->usbgrf, preg, disable);
406 }
407
408 __maybe_unused
udphy_usb_bvalid_enable(struct rockchip_udphy * udphy,u8 enable)409 static void udphy_usb_bvalid_enable(struct rockchip_udphy *udphy, u8 enable)
410 {
411 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
412
413 grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_phy_con, enable);
414 grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_grf_con, enable);
415 }
416
417 /*
418 * In usb/dp combo phy driver, here are 2 ways to mapping lanes.
419 *
420 * 1 Type-C Mapping table (DP_Alt_Mode V1.0b remove ABF pin mapping)
421 * ---------------------------------------------------------------------------
422 * Type-C Pin B11-B10 A2-A3 A11-A10 B2-B3
423 * PHY Pad ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
424 * C/E(Normal) dpln3 dpln2 dpln0 dpln1
425 * C/E(Flip ) dpln0 dpln1 dpln3 dpln2
426 * D/F(Normal) usbrx usbtx dpln0 dpln1
427 * D/F(Flip ) dpln0 dpln1 usbrx usbtx
428 * A(Normal ) dpln3 dpln1 dpln2 dpln0
429 * A(Flip ) dpln2 dpln0 dpln3 dpln1
430 * B(Normal ) usbrx usbtx dpln1 dpln0
431 * B(Flip ) dpln1 dpln0 usbrx usbtx
432 * ---------------------------------------------------------------------------
433 *
434 * 2 Mapping the lanes in dtsi
435 * if all 4 lane assignment for dp function, define rockchip,dp-lane-mux = <x x x x>;
436 * sample as follow:
437 * ---------------------------------------------------------------------------
438 * B11-B10 A2-A3 A11-A10 B2-B3
439 * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
440 * <0 1 2 3> dpln0 dpln1 dpln2 dpln3
441 * <2 3 0 1> dpln2 dpln3 dpln0 dpln1
442 * ---------------------------------------------------------------------------
443 * if 2 lane for dp function, 2 lane for usb function, define rockchip,dp-lane-mux = <x x>;
444 * sample as follow:
445 * ---------------------------------------------------------------------------
446 * B11-B10 A2-A3 A11-A10 B2-B3
447 * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
448 * <0 1> dpln0 dpln1 usbrx usbtx
449 * <2 3> usbrx usbtx dpln0 dpln1
450 * ---------------------------------------------------------------------------
451 */
udphy_dplane_select(struct rockchip_udphy * udphy)452 static int udphy_dplane_select(struct rockchip_udphy *udphy)
453 {
454 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
455
456 if (cfg->dplane_select)
457 return cfg->dplane_select(udphy);
458
459 return 0;
460 }
461
udphy_dplane_get(struct rockchip_udphy * udphy)462 static int udphy_dplane_get(struct rockchip_udphy *udphy)
463 {
464 int dp_lanes;
465
466 switch (udphy->mode) {
467 case UDPHY_MODE_DP:
468 dp_lanes = 4;
469 break;
470 case UDPHY_MODE_DP_USB:
471 dp_lanes = 2;
472 break;
473 case UDPHY_MODE_USB:
474 /* fallthrough; */
475 default:
476 dp_lanes = 0;
477 break;
478 }
479
480 return dp_lanes;
481 }
482
udphy_dplane_enable(struct rockchip_udphy * udphy,int dp_lanes)483 static int udphy_dplane_enable(struct rockchip_udphy *udphy, int dp_lanes)
484 {
485 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
486 int ret = 0;
487
488 if (cfg->dplane_enable)
489 ret = cfg->dplane_enable(udphy, dp_lanes);
490
491 return ret;
492 }
493
494
495 __maybe_unused
upphy_set_typec_default_mapping(struct rockchip_udphy * udphy)496 static int upphy_set_typec_default_mapping(struct rockchip_udphy *udphy)
497 {
498 if (udphy->flip) {
499 udphy->dp_lane_sel[0] = 0;
500 udphy->dp_lane_sel[1] = 1;
501 udphy->dp_lane_sel[2] = 3;
502 udphy->dp_lane_sel[3] = 2;
503 udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
504 udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
505 udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB;
506 udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB;
507 udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_INVERT;
508 udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_INVERT;
509 } else {
510 udphy->dp_lane_sel[0] = 2;
511 udphy->dp_lane_sel[1] = 3;
512 udphy->dp_lane_sel[2] = 1;
513 udphy->dp_lane_sel[3] = 0;
514 udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB;
515 udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB;
516 udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
517 udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
518 udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_NORMAL;
519 udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_NORMAL;
520 }
521
522 udphy->mode = UDPHY_MODE_DP_USB;
523
524 return 0;
525 }
526
udphy_setup(struct rockchip_udphy * udphy)527 static int udphy_setup(struct rockchip_udphy *udphy)
528 {
529 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
530 int ret = 0;
531
532 if (cfg->combophy_init) {
533 ret = cfg->combophy_init(udphy);
534 if (ret)
535 dev_err(udphy->dev, "failed to init combophy\n");
536 }
537
538 return ret;
539 }
540
udphy_disable(struct rockchip_udphy * udphy)541 static int udphy_disable(struct rockchip_udphy *udphy)
542 {
543 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
544 int i;
545
546 for (i = 0; i < cfg->num_rsts; i++)
547 reset_assert(&udphy->rsts[i]);
548
549 return 0;
550 }
551
udphy_parse_lane_mux_data(struct rockchip_udphy * udphy,struct udevice * dev)552 static int udphy_parse_lane_mux_data(struct rockchip_udphy *udphy, struct udevice *dev)
553 {
554 const struct device_node *np = ofnode_to_np(dev->node);
555 struct property *prop;
556 int ret, i, len, num_lanes;
557
558 prop = of_find_property(np, "rockchip,dp-lane-mux", &len);
559 if (!prop) {
560 dev_dbg(dev, "failed to find dp lane mux, following dp alt mode\n");
561 udphy->mode = UDPHY_MODE_USB;
562 return 0;
563 }
564
565 num_lanes = len / sizeof(u32);
566
567 if (num_lanes != 2 && num_lanes != 4) {
568 dev_err(dev, "invalid number of lane mux\n");
569 return -EINVAL;
570 }
571
572 ret = of_read_u32_array(np, "rockchip,dp-lane-mux", udphy->dp_lane_sel, num_lanes);
573 if (ret) {
574 dev_err(dev, "get dp lane mux failed\n");
575 return -EINVAL;
576 }
577
578 for (i = 0; i < num_lanes; i++) {
579 int j;
580
581 if (udphy->dp_lane_sel[i] > 3) {
582 dev_err(dev, "lane mux between 0 and 3, exceeding the range\n");
583 return -EINVAL;
584 }
585
586 udphy->lane_mux_sel[udphy->dp_lane_sel[i]] = PHY_LANE_MUX_DP;
587
588 for (j = i + 1; j < num_lanes; j++) {
589 if (udphy->dp_lane_sel[i] == udphy->dp_lane_sel[j]) {
590 dev_err(dev, "set repeat lane mux value\n");
591 return -EINVAL;
592 }
593 }
594 }
595
596 udphy->mode = UDPHY_MODE_DP;
597 if (num_lanes == 2) {
598 udphy->mode |= UDPHY_MODE_USB;
599 udphy->flip = udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP ? true : false;
600 }
601
602 return 0;
603 }
604
udphy_parse_dt(struct rockchip_udphy * udphy,struct udevice * dev)605 static int udphy_parse_dt(struct rockchip_udphy *udphy, struct udevice *dev)
606 {
607 enum usb_device_speed maximum_speed;
608 int ret;
609
610 udphy->u2phygrf = syscon_regmap_lookup_by_phandle(dev, "rockchip,u2phy-grf");
611 if (IS_ERR(udphy->u2phygrf)) {
612 if (PTR_ERR(udphy->u2phygrf) == -ENODEV) {
613 dev_warn(dev, "missing u2phy-grf dt node\n");
614 udphy->u2phygrf = NULL;
615 } else {
616 return PTR_ERR(udphy->u2phygrf);
617 }
618 }
619
620 udphy->udphygrf = syscon_regmap_lookup_by_phandle(dev, "rockchip,usbdpphy-grf");
621 if (IS_ERR(udphy->udphygrf)) {
622 if (PTR_ERR(udphy->udphygrf) == -ENODEV) {
623 dev_warn(dev, "missing usbdpphy-grf dt node\n");
624 udphy->udphygrf = NULL;
625 } else {
626 return PTR_ERR(udphy->udphygrf);
627 }
628 }
629
630 udphy->usbgrf = syscon_regmap_lookup_by_phandle(dev, "rockchip,usb-grf");
631 if (IS_ERR(udphy->usbgrf)) {
632 if (PTR_ERR(udphy->usbgrf) == -ENODEV) {
633 dev_warn(dev, "missing usb-grf dt node\n");
634 udphy->usbgrf = NULL;
635 } else {
636 return PTR_ERR(udphy->usbgrf);
637 }
638 }
639
640 udphy->vogrf = syscon_regmap_lookup_by_phandle(dev, "rockchip,vo-grf");
641 if (IS_ERR(udphy->vogrf)) {
642 if (PTR_ERR(udphy->vogrf) == -ENODEV) {
643 dev_warn(dev, "missing vo-grf dt node\n");
644 udphy->vogrf = NULL;
645 } else {
646 return PTR_ERR(udphy->vogrf);
647 }
648 }
649
650 ret = udphy_parse_lane_mux_data(udphy, dev);
651 if (ret)
652 return ret;
653
654 if (dev_read_prop(dev, "maximum-speed", NULL)) {
655 maximum_speed = usb_get_maximum_speed(dev->node);
656 udphy->hs = maximum_speed <= USB_SPEED_HIGH ? true : false;
657 }
658
659 ret = udphy_clk_init(udphy, dev);
660 if (ret)
661 return ret;
662
663 ret = udphy_reset_init(udphy, dev);
664 if (ret)
665 return ret;
666
667 return 0;
668 }
669
udphy_power_on(struct rockchip_udphy * udphy,u8 mode)670 static int udphy_power_on(struct rockchip_udphy *udphy, u8 mode)
671 {
672 int ret;
673
674 if (!(udphy->mode & mode)) {
675 printf("%s: mode 0x%02x is not support\n", udphy->dev->name,
676 mode);
677 return -EINVAL;
678 }
679
680 if (udphy->status == UDPHY_MODE_NONE) {
681 udphy->mode_change = false;
682 ret = udphy_setup(udphy);
683 if (ret)
684 return ret;
685
686 if (udphy->mode & UDPHY_MODE_USB)
687 udphy_u3_port_disable(udphy, false);
688 } else if (udphy->mode_change) {
689 udphy->mode_change = false;
690 udphy->status = UDPHY_MODE_NONE;
691 if (udphy->mode == UDPHY_MODE_DP)
692 udphy_u3_port_disable(udphy, true);
693
694 ret = udphy_disable(udphy);
695 if (ret)
696 return ret;
697 ret = udphy_setup(udphy);
698 if (ret)
699 return ret;
700 }
701
702 udphy->status |= mode;
703
704 return 0;
705 }
706
udphy_power_off(struct rockchip_udphy * udphy,u8 mode)707 static int udphy_power_off(struct rockchip_udphy *udphy, u8 mode)
708 {
709 int ret;
710
711 if (!(udphy->mode & mode)) {
712 dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
713 return 0;
714 }
715
716 if (!udphy->status)
717 return 0;
718
719 udphy->status &= ~mode;
720
721 if (udphy->status == UDPHY_MODE_NONE) {
722 ret = udphy_disable(udphy);
723 if (ret)
724 return ret;
725 }
726
727 return 0;
728 }
729
rockchip_dpphy_power_on(struct phy * phy)730 static int rockchip_dpphy_power_on(struct phy *phy)
731 {
732 struct udevice *parent = phy->dev->parent;
733 struct rockchip_udphy *udphy = dev_get_priv(parent);
734 int ret, dp_lanes;
735
736 dp_lanes = udphy_dplane_get(udphy);
737 phy->attrs.bus_width = dp_lanes;
738 phy->attrs.max_link_rate = udphy->max_link_rate;
739
740 ret = udphy_power_on(udphy, UDPHY_MODE_DP);
741 if (ret)
742 return ret;
743
744 ret = udphy_dplane_enable(udphy, dp_lanes);
745 if (ret)
746 return ret;
747
748 return udphy_dplane_select(udphy);
749 }
750
rockchip_dpphy_power_off(struct phy * phy)751 static int rockchip_dpphy_power_off(struct phy *phy)
752 {
753 struct udevice *parent = phy->dev->parent;
754 struct rockchip_udphy *udphy = dev_get_priv(parent);
755 int ret;
756
757 ret = udphy_dplane_enable(udphy, 0);
758 if (ret)
759 return ret;
760
761 return udphy_power_off(udphy, UDPHY_MODE_DP);
762 }
763
rockchip_dpphy_verify_config(struct rockchip_udphy * udphy,struct phy_configure_opts_dp * dp)764 static int rockchip_dpphy_verify_config(struct rockchip_udphy *udphy,
765 struct phy_configure_opts_dp *dp)
766 {
767 int i;
768
769 /* If changing link rate was required, verify it's supported. */
770 if (dp->set_rate) {
771 switch (dp->link_rate) {
772 case 1620:
773 case 2700:
774 case 5400:
775 case 8100:
776 /* valid bit rate */
777 break;
778 default:
779 return -EINVAL;
780 }
781 }
782
783 /* Verify lane count. */
784 switch (dp->lanes) {
785 case 1:
786 case 2:
787 case 4:
788 /* valid lane count. */
789 break;
790 default:
791 return -EINVAL;
792 }
793
794 /*
795 * If changing voltages is required, check swing and pre-emphasis
796 * levels, per-lane.
797 */
798 if (dp->set_voltages) {
799 /* Lane count verified previously. */
800 for (i = 0; i < dp->lanes; i++) {
801 if (dp->voltage[i] > 3 || dp->pre[i] > 3)
802 return -EINVAL;
803
804 /*
805 * Sum of voltage swing and pre-emphasis levels cannot
806 * exceed 3.
807 */
808 if (dp->voltage[i] + dp->pre[i] > 3)
809 return -EINVAL;
810 }
811 }
812
813 return 0;
814 }
815
rockchip_dpphy_configure(struct phy * phy,union phy_configure_opts * opts)816 static int rockchip_dpphy_configure(struct phy *phy,
817 union phy_configure_opts *opts)
818 {
819 struct udevice *parent = phy->dev->parent;
820 struct rockchip_udphy *udphy = dev_get_priv(parent);
821 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
822 int ret;
823
824 ret = rockchip_dpphy_verify_config(udphy, &opts->dp);
825 if (ret)
826 return ret;
827
828 if (opts->dp.set_rate && cfg->dp_phy_set_rate) {
829 ret = cfg->dp_phy_set_rate(udphy, &opts->dp);
830 if (ret) {
831 printf("%s: rockchip_hdptx_phy_set_rate failed\n",
832 udphy->dev->name);
833 return ret;
834 }
835 }
836
837 if (opts->dp.set_voltages && cfg->dp_phy_set_voltages) {
838 ret = cfg->dp_phy_set_voltages(udphy, &opts->dp);
839 if (ret) {
840 printf("%s: rockchip_dp_phy_set_voltages failed\n",
841 udphy->dev->name);
842 return ret;
843 }
844 }
845
846 return 0;
847 }
848
849 static const struct phy_ops rockchip_dpphy_ops = {
850 .power_on = rockchip_dpphy_power_on,
851 .power_off = rockchip_dpphy_power_off,
852 .configure = rockchip_dpphy_configure,
853 };
854
rockchip_u3phy_init(struct phy * phy)855 static int rockchip_u3phy_init(struct phy *phy)
856 {
857 struct udevice *parent = phy->dev->parent;
858 struct rockchip_udphy *udphy = dev_get_priv(parent);
859
860 /* DP only or high-speed, disable U3 port */
861 if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) {
862 udphy_u3_port_disable(udphy, true);
863 return 0;
864 }
865
866 return udphy_power_on(udphy, UDPHY_MODE_USB);
867 }
868
rockchip_u3phy_exit(struct phy * phy)869 static int rockchip_u3phy_exit(struct phy *phy)
870 {
871 struct udevice *parent = phy->dev->parent;
872 struct rockchip_udphy *udphy = dev_get_priv(parent);
873
874 /* DP only or high-speed */
875 if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs)
876 return 0;
877
878 return udphy_power_off(udphy, UDPHY_MODE_USB);
879 }
880
881 static const struct phy_ops rockchip_u3phy_ops = {
882 .init = rockchip_u3phy_init,
883 .exit = rockchip_u3phy_exit,
884 };
885
rockchip_u3phy_uboot_init(void)886 int rockchip_u3phy_uboot_init(void)
887 {
888 struct udevice *udev;
889 struct rockchip_udphy *udphy;
890 int ret;
891
892 ret = uclass_get_device_by_driver(UCLASS_PHY,
893 DM_GET_DRIVER(rockchip_udphy_u3_port),
894 &udev);
895 if (ret) {
896 pr_err("%s: get u3-port failed: %d\n", __func__, ret);
897 return ret;
898 }
899
900 /* DP only or high-speed, disable U3 port */
901 udphy = dev_get_priv(udev->parent);
902 if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) {
903 udphy_u3_port_disable(udphy, true);
904 return 0;
905 }
906
907 return udphy_power_on(udphy, UDPHY_MODE_USB);
908 }
909
rockchip_udphy_probe(struct udevice * dev)910 static int rockchip_udphy_probe(struct udevice *dev)
911 {
912 const struct device_node *np = ofnode_to_np(dev->node);
913 struct rockchip_udphy *udphy = dev_get_priv(dev);
914 const struct rockchip_udphy_cfg *phy_cfgs;
915 int id, ret;
916
917 udphy->dev = dev;
918
919 id = of_alias_get_id(np, "usbdp");
920 if (id < 0)
921 id = 0;
922 udphy->id = id;
923
924 phy_cfgs = (const struct rockchip_udphy_cfg *) dev_get_driver_data(dev);
925 if (!phy_cfgs) {
926 dev_err(dev, "unable to get phy_cfgs\n");
927 return -EINVAL;
928 }
929 udphy->cfgs = phy_cfgs;
930
931 ret = regmap_init_mem(dev, &udphy->pma_regmap);
932 if (ret)
933 return ret;
934 udphy->pma_regmap->base += UDPHY_PMA;
935
936 ret = udphy_parse_dt(udphy, dev);
937 if (ret)
938 return ret;
939
940 return 0;
941 }
942
rockchip_udphy_bind(struct udevice * parent)943 static int rockchip_udphy_bind(struct udevice *parent)
944 {
945 struct udevice *child;
946 ofnode subnode;
947 const char *node_name;
948 int ret;
949
950 dev_for_each_subnode(subnode, parent) {
951 if (!ofnode_valid(subnode)) {
952 printf("%s: no subnode for %s\n", __func__, parent->name);
953 return -ENXIO;
954 }
955
956 node_name = ofnode_get_name(subnode);
957 debug("%s: subnode %s\n", __func__, node_name);
958
959 if (!strcasecmp(node_name, "u3-port")) {
960 ret = device_bind_driver_to_node(parent,
961 "rockchip_udphy_u3_port",
962 node_name, subnode, &child);
963 if (ret) {
964 printf("%s: '%s' cannot bind its driver\n",
965 __func__, node_name);
966 return ret;
967 }
968 } else if (!strcasecmp(node_name, "dp-port")) {
969 ret = device_bind_driver_to_node(parent,
970 "rockchip_udphy_dp_port",
971 node_name, subnode, &child);
972 if (ret) {
973 printf("%s: '%s' cannot bind its driver\n",
974 __func__, node_name);
975 return ret;
976 }
977 }
978 }
979
980 return 0;
981 }
982
rk3588_udphy_refclk_set(struct rockchip_udphy * udphy)983 static int rk3588_udphy_refclk_set(struct rockchip_udphy *udphy)
984 {
985 int ret;
986
987 /* configure phy reference clock */
988 ret = __regmap_multi_reg_write(udphy->pma_regmap, rk3588_udphy_24m_refclk_cfg,
989 ARRAY_SIZE(rk3588_udphy_24m_refclk_cfg));
990 if (ret)
991 return ret;
992
993 return 0;
994 }
995
rk3588_udphy_status_check(struct rockchip_udphy * udphy)996 static int rk3588_udphy_status_check(struct rockchip_udphy *udphy)
997 {
998 unsigned int val;
999 int ret;
1000
1001 /* LCPLL check */
1002 if (udphy->mode & UDPHY_MODE_USB) {
1003 ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_LCPLL_DONE_OFFSET,
1004 val, (val & CMN_ANA_LCPLL_AFC_DONE) &&
1005 (val & CMN_ANA_LCPLL_LOCK_DONE), 200, 100);
1006 if (ret) {
1007 dev_err(udphy->dev, "cmn ana lcpll lock timeout\n");
1008 return ret;
1009 }
1010 }
1011
1012 if (udphy->mode & UDPHY_MODE_USB) {
1013 if (!udphy->flip) {
1014 ret = regmap_read_poll_timeout(udphy->pma_regmap,
1015 TRSV_LN0_MON_RX_CDR_DONE_OFFSET, val,
1016 val & TRSV_LN0_MON_RX_CDR_LOCK_DONE,
1017 200, 100);
1018 if (ret)
1019 dev_notice(udphy->dev, "trsv ln0 mon rx cdr lock timeout\n");
1020 } else {
1021 ret = regmap_read_poll_timeout(udphy->pma_regmap,
1022 TRSV_LN2_MON_RX_CDR_DONE_OFFSET, val,
1023 val & TRSV_LN2_MON_RX_CDR_LOCK_DONE,
1024 200, 100);
1025 if (ret)
1026 dev_notice(udphy->dev, "trsv ln2 mon rx cdr lock timeout\n");
1027 }
1028 }
1029
1030 return 0;
1031 }
1032
rk3588_udphy_init(struct rockchip_udphy * udphy)1033 static int rk3588_udphy_init(struct rockchip_udphy *udphy)
1034 {
1035 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
1036 int ret;
1037
1038 /* enable rx lfps for usb */
1039 if (udphy->mode & UDPHY_MODE_USB)
1040 grfreg_write(udphy->udphygrf, &cfg->grfcfg.rx_lfps, true);
1041
1042 /* Step 1: power on pma and deassert apb rstn */
1043 grfreg_write(udphy->udphygrf, &cfg->grfcfg.low_pwrn, true);
1044
1045 udphy_reset_deassert(udphy, "pma_apb");
1046 udphy_reset_deassert(udphy, "pcs_apb");
1047
1048 /* Step 2: set init sequence and phy refclk */
1049 ret = __regmap_multi_reg_write(udphy->pma_regmap, rk3588_udphy_init_sequence,
1050 ARRAY_SIZE(rk3588_udphy_init_sequence));
1051 if (ret) {
1052 dev_err(udphy->dev, "init sequence set error %d\n", ret);
1053 goto assert_apb;
1054 }
1055
1056 ret = rk3588_udphy_refclk_set(udphy);
1057 if (ret) {
1058 dev_err(udphy->dev, "refclk set error %d\n", ret);
1059 goto assert_apb;
1060 }
1061
1062 /* Step 3: configure lane mux */
1063 regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET,
1064 CMN_DP_LANE_MUX_ALL | CMN_DP_LANE_EN_ALL,
1065 FIELD_PREP(CMN_DP_LANE_MUX_N(3), udphy->lane_mux_sel[3]) |
1066 FIELD_PREP(CMN_DP_LANE_MUX_N(2), udphy->lane_mux_sel[2]) |
1067 FIELD_PREP(CMN_DP_LANE_MUX_N(1), udphy->lane_mux_sel[1]) |
1068 FIELD_PREP(CMN_DP_LANE_MUX_N(0), udphy->lane_mux_sel[0]) |
1069 FIELD_PREP(CMN_DP_LANE_EN_ALL, 0));
1070
1071 /* Step 4: deassert init rstn and wait for 200ns from datasheet */
1072 if (udphy->mode & UDPHY_MODE_USB)
1073 udphy_reset_deassert(udphy, "init");
1074
1075 if (udphy->mode & UDPHY_MODE_DP) {
1076 regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
1077 CMN_DP_INIT_RSTN,
1078 FIELD_PREP(CMN_DP_INIT_RSTN, 0x1));
1079 }
1080
1081 udelay(1);
1082
1083 /* Step 5: deassert cmn/lane rstn */
1084 if (udphy->mode & UDPHY_MODE_USB) {
1085 udphy_reset_deassert(udphy, "cmn");
1086 udphy_reset_deassert(udphy, "lane");
1087 }
1088
1089 /* Step 6: wait for lock done of pll */
1090 ret = rk3588_udphy_status_check(udphy);
1091 if (ret)
1092 goto assert_phy;
1093
1094 return 0;
1095
1096 assert_phy:
1097 udphy_reset_assert(udphy, "init");
1098 udphy_reset_assert(udphy, "cmn");
1099 udphy_reset_assert(udphy, "lane");
1100
1101 assert_apb:
1102 udphy_reset_assert(udphy, "pma_apb");
1103 udphy_reset_assert(udphy, "pcs_apb");
1104 return ret;
1105 }
1106
rk3588_udphy_dplane_enable(struct rockchip_udphy * udphy,int dp_lanes)1107 static int rk3588_udphy_dplane_enable(struct rockchip_udphy *udphy, int dp_lanes)
1108 {
1109 int i;
1110 u32 val = 0;
1111
1112 for (i = 0; i < dp_lanes; i++)
1113 val |= BIT(udphy->dp_lane_sel[i]);
1114
1115 regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, CMN_DP_LANE_EN_ALL,
1116 FIELD_PREP(CMN_DP_LANE_EN_ALL, val));
1117
1118 if (!dp_lanes)
1119 regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
1120 CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
1121
1122 return 0;
1123 }
1124
rk3588_udphy_dplane_select(struct rockchip_udphy * udphy)1125 static int rk3588_udphy_dplane_select(struct rockchip_udphy *udphy)
1126 {
1127 u32 value = 0;
1128
1129 switch (udphy->mode) {
1130 case UDPHY_MODE_DP:
1131 value |= 2 << udphy->dp_lane_sel[2] * 2;
1132 value |= 3 << udphy->dp_lane_sel[3] * 2;
1133 case UDPHY_MODE_DP_USB:
1134 value |= 0 << udphy->dp_lane_sel[0] * 2;
1135 value |= 1 << udphy->dp_lane_sel[1] * 2;
1136 break;
1137 case UDPHY_MODE_USB:
1138 break;
1139 default:
1140 break;
1141 }
1142
1143 regmap_write(udphy->vogrf, udphy->id ? RK3588_GRF_VO0_CON2 : RK3588_GRF_VO0_CON0,
1144 ((DP_AUX_DIN_SEL | DP_AUX_DOUT_SEL | DP_LANE_SEL_ALL) << 16) |
1145 FIELD_PREP(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel) |
1146 FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
1147
1148 return 0;
1149 }
1150
rk3588_dp_phy_set_rate(struct rockchip_udphy * udphy,struct phy_configure_opts_dp * dp)1151 static int rk3588_dp_phy_set_rate(struct rockchip_udphy *udphy,
1152 struct phy_configure_opts_dp *dp)
1153 {
1154 u32 val;
1155 int ret;
1156
1157 regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
1158 CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
1159
1160 switch (dp->link_rate) {
1161 case 1620:
1162 udphy->bw = DP_BW_RBR;
1163 break;
1164 case 2700:
1165 udphy->bw = DP_BW_HBR;
1166 break;
1167 case 5400:
1168 udphy->bw = DP_BW_HBR2;
1169 break;
1170 case 8100:
1171 udphy->bw = DP_BW_HBR3;
1172 break;
1173 default:
1174 return -EINVAL;
1175 }
1176
1177 regmap_update_bits(udphy->pma_regmap, CMN_DP_LINK_OFFSET, CMN_DP_TX_LINK_BW,
1178 FIELD_PREP(CMN_DP_TX_LINK_BW, udphy->bw));
1179 regmap_update_bits(udphy->pma_regmap, CMN_SSC_EN_OFFSET, CMN_ROPLL_SSC_EN,
1180 FIELD_PREP(CMN_ROPLL_SSC_EN, dp->ssc));
1181 regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, CMN_DP_CMN_RSTN,
1182 FIELD_PREP(CMN_DP_CMN_RSTN, 0x1));
1183
1184 ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_ROPLL_DONE_OFFSET, val,
1185 FIELD_GET(CMN_ANA_ROPLL_LOCK_DONE, val) &&
1186 FIELD_GET(CMN_ANA_ROPLL_AFC_DONE, val),
1187 0, 1000);
1188 if (ret) {
1189 printf("ROPLL is not lock\n");
1190 return ret;
1191 }
1192
1193 return 0;
1194 }
1195
rk3588_dp_phy_set_voltage(struct rockchip_udphy * udphy,u8 bw,u32 voltage,u32 pre,u32 lane)1196 static void rk3588_dp_phy_set_voltage(struct rockchip_udphy *udphy, u8 bw,
1197 u32 voltage, u32 pre, u32 lane)
1198 {
1199 u32 offset = 0x800 * lane;
1200 u32 val;
1201 const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
1202 const struct dp_tx_drv_ctrl (*dp_ctrl)[4];
1203
1204 dp_ctrl = cfg->dp_tx_ctrl_cfg[bw];
1205 val = dp_ctrl[voltage][pre].trsv_reg0204;
1206 regmap_write(udphy->pma_regmap, 0x0810 + offset, val);
1207
1208 val = dp_ctrl[voltage][pre].trsv_reg0205;
1209 regmap_write(udphy->pma_regmap, 0x0814 + offset, val);
1210
1211 val = dp_ctrl[voltage][pre].trsv_reg0206;
1212 regmap_write(udphy->pma_regmap, 0x0818 + offset, val);
1213
1214 val = dp_ctrl[voltage][pre].trsv_reg0207;
1215 regmap_write(udphy->pma_regmap, 0x081c + offset, val);
1216 }
1217
rk3588_dp_phy_set_voltages(struct rockchip_udphy * udphy,struct phy_configure_opts_dp * dp)1218 static int rk3588_dp_phy_set_voltages(struct rockchip_udphy *udphy,
1219 struct phy_configure_opts_dp *dp)
1220 {
1221 u32 i, lane;
1222
1223 for (i = 0; i < dp->lanes; i++) {
1224 lane = udphy->dp_lane_sel[i];
1225 switch (dp->link_rate) {
1226 case 1620:
1227 case 2700:
1228 regmap_update_bits(udphy->pma_regmap, TRSV_ANA_TX_CLK_OFFSET_N(lane),
1229 LN_ANA_TX_SER_TXCLK_INV,
1230 FIELD_PREP(LN_ANA_TX_SER_TXCLK_INV,
1231 udphy->lane_mux_sel[lane]));
1232 break;
1233 case 5400:
1234 case 8100:
1235 regmap_update_bits(udphy->pma_regmap, TRSV_ANA_TX_CLK_OFFSET_N(lane),
1236 LN_ANA_TX_SER_TXCLK_INV,
1237 FIELD_PREP(LN_ANA_TX_SER_TXCLK_INV, 0x0));
1238 break;
1239 }
1240
1241 rk3588_dp_phy_set_voltage(udphy, udphy->bw, dp->voltage[i], dp->pre[i], lane);
1242 }
1243
1244 return 0;
1245 }
1246
rockchip_dpphy_probe(struct udevice * dev)1247 static int rockchip_dpphy_probe(struct udevice *dev)
1248 {
1249 struct rockchip_udphy *udphy = dev_get_priv(dev->parent);
1250 u32 max_link_rate;
1251
1252 max_link_rate = dev_read_u32_default(dev, "max-link-rate", 8100);
1253 switch (max_link_rate) {
1254 case 1620:
1255 case 2700:
1256 case 5400:
1257 case 8100:
1258 break;
1259 default:
1260 dev_warn(dev, "invalid max-link-rate %d, using 8100\n", max_link_rate);
1261 max_link_rate = 8100;
1262 break;
1263 }
1264
1265 udphy->max_link_rate = max_link_rate;
1266
1267 return 0;
1268 }
1269
1270 static const char * const rk3588_udphy_rst_l[] = {
1271 "init", "cmn", "lane", "pcs_apb", "pma_apb"
1272 };
1273
1274 static const struct rockchip_udphy_cfg rk3588_udphy_cfgs = {
1275 .num_rsts = ARRAY_SIZE(rk3588_udphy_rst_l),
1276 .rst_list = rk3588_udphy_rst_l,
1277 .grfcfg = {
1278 /* u2phy-grf */
1279 .bvalid_phy_con = { 0x0008, 1, 0, 0x2, 0x3 },
1280 .bvalid_grf_con = { 0x0010, 3, 2, 0x2, 0x3 },
1281
1282 /* usb-grf */
1283 .usb3otg0_cfg = { 0x001c, 15, 0, 0x1100, 0x0188 },
1284 .usb3otg1_cfg = { 0x0034, 15, 0, 0x1100, 0x0188 },
1285
1286 /* usbdpphy-grf */
1287 .low_pwrn = { 0x0004, 13, 13, 0, 1 },
1288 .rx_lfps = { 0x0004, 14, 14, 0, 1 },
1289 },
1290 .dp_tx_ctrl_cfg = {
1291 rk3588_dp_tx_drv_ctrl_rbr_hbr,
1292 rk3588_dp_tx_drv_ctrl_rbr_hbr,
1293 rk3588_dp_tx_drv_ctrl_hbr2,
1294 rk3588_dp_tx_drv_ctrl_hbr3,
1295 },
1296 .combophy_init = rk3588_udphy_init,
1297 .dp_phy_set_rate = rk3588_dp_phy_set_rate,
1298 .dp_phy_set_voltages = rk3588_dp_phy_set_voltages,
1299 .dplane_enable = rk3588_udphy_dplane_enable,
1300 .dplane_select = rk3588_udphy_dplane_select,
1301 };
1302
1303 static const struct udevice_id rockchip_udphy_dt_match[] = {
1304 {
1305 .compatible = "rockchip,rk3588-usbdp-phy",
1306 .data = (ulong)&rk3588_udphy_cfgs
1307 },
1308 { /* sentinel */ }
1309 };
1310
1311 U_BOOT_DRIVER(rockchip_udphy_u3_port) = {
1312 .name = "rockchip_udphy_u3_port",
1313 .id = UCLASS_PHY,
1314 .ops = &rockchip_u3phy_ops,
1315 };
1316
1317 U_BOOT_DRIVER(rockchip_udphy_dp_port) = {
1318 .name = "rockchip_udphy_dp_port",
1319 .id = UCLASS_PHY,
1320 .ops = &rockchip_dpphy_ops,
1321 .probe = rockchip_dpphy_probe,
1322 };
1323
1324 U_BOOT_DRIVER(rockchip_udphy) = {
1325 .name = "rockchip_udphy",
1326 .id = UCLASS_PHY,
1327 .of_match = rockchip_udphy_dt_match,
1328 .probe = rockchip_udphy_probe,
1329 .bind = rockchip_udphy_bind,
1330 .priv_auto_alloc_size = sizeof(struct rockchip_udphy),
1331 };
1332