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