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