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