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