1 /*
2  * Copyright (c) 2019 - 2021, Broadcom
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <platform_usb.h>
8 #include <usb_phy.h>
9 
10 #define USB_PHY_ALREADY_STARTED	(-2)
11 #define USB_MAX_DEVICES		 2
12 #define USB3H_USB2DRD_PHY	 0
13 #define USB3_DRD_PHY		 1
14 
15 /* Common bit fields for all the USB2 phy */
16 #define USB2_PHY_ISO		DRDU2_U2PHY_ISO
17 #define USB2_AFE_PLL_PWRDWNB	DRDU2_U2AFE_PLL_PWRDWNB
18 #define USB2_AFE_BG_PWRDWNB	DRDU2_U2AFE_BG_PWRDWNB
19 #define USB2_AFE_LDO_PWRDWNB	DRDU2_U2AFE_LDO_PWRDWNB
20 #define USB2_CTRL_CORERDY	DRDU2_U2CTRL_CORERDY
21 
22 #define USB2_PHY_PCTL_MASK	DRDU2_U2PHY_PCTL_MASK
23 #define USB2_PHY_PCTL_OFFSET	DRDU2_U2PHY_PCTL_OFFSET
24 #define USB2_PHY_PCTL_VAL	U2PHY_PCTL_VAL
25 
26 #define USB2_PLL_RESETB		DRDU2_U2PLL_RESETB
27 #define USB2_PHY_RESETB		DRDU2_U2PHY_RESETB
28 
29 static usb_phy_port_t usb_phy_port[2U][MAX_NR_PORTS];
30 
31 static usb_phy_t usb_phy_info[2U] = {
32 	{DRDU2_U2PLL_NDIV_FRAC, USB3H_PIPE_CTRL, 0U, USB3H_DRDU2_PHY},
33 	{0U, 0U, DRDU3_PIPE_CTRL, DRDU3_PHY}
34 };
35 
36 typedef struct {
37 	void *pcd_id;
38 } usb_platform_dev;
39 
40 /* index 0: USB3H + USB2 DRD, 1: USB3 DRD */
41 static usb_platform_dev xhci_devices_configs[USB_MAX_DEVICES] = {
42 	{&usb_phy_info[0U]},
43 	{&usb_phy_info[1U]}
44 };
45 
pll_lock_check(uint32_t address,uint32_t bit)46 static int32_t pll_lock_check(uint32_t address, uint32_t bit)
47 {
48 	uint32_t retry;
49 	uint32_t data;
50 
51 	retry = PLL_LOCK_RETRY_COUNT;
52 	do {
53 		data = mmio_read_32(address);
54 		if ((data & bit) != 0U) {
55 			return 0;
56 		}
57 		udelay(1);
58 	} while (--retry != 0);
59 
60 	ERROR("%s(): FAIL (0x%08x)\n", __func__, address);
61 	return -1;
62 }
63 
64 /*
65  * USB2 PHY using external FSM bringup sequence
66  * Total #3 USB2 phys. All phys has the same
67  * bringup sequence. Register bit fields for
68  * some of the PHY's are different.
69  * Bit fields which are different are passed using
70  * struct u2_phy_ext_fsm with bit-fields and register addr.
71  */
72 
u2_phy_ext_fsm_power_on(struct u2_phy_ext_fsm * u2_phy)73 static void u2_phy_ext_fsm_power_on(struct u2_phy_ext_fsm *u2_phy)
74 {
75 	mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_PHY_ISO);
76 	/* Delay as per external FSM spec */
77 	udelay(10U);
78 
79 	mmio_setbits_32(u2_phy->phy_ctrl_reg, u2_phy->phy_iddq);
80 	/* Delay as per external FSM spec */
81 	udelay(10U);
82 
83 	mmio_clrbits_32(u2_phy->phy_ctrl_reg,
84 			(USB2_AFE_BG_PWRDWNB |
85 			 USB2_AFE_PLL_PWRDWNB |
86 			 USB2_AFE_LDO_PWRDWNB |
87 			 USB2_CTRL_CORERDY));
88 
89 	mmio_clrsetbits_32(u2_phy->phy_ctrl_reg,
90 			   (USB2_PHY_PCTL_MASK << USB2_PHY_PCTL_OFFSET),
91 			   (USB2_PHY_PCTL_VAL << USB2_PHY_PCTL_OFFSET));
92 	/* Delay as per external FSM spec */
93 	udelay(160U);
94 
95 	mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_CTRL_CORERDY);
96 	/* Delay as per external FSM spec */
97 	udelay(50U);
98 
99 	mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_AFE_BG_PWRDWNB);
100 	/* Delay as per external FSM spec */
101 	udelay(200U);
102 
103 	mmio_setbits_32(u2_phy->pwr_ctrl_reg, u2_phy->pwr_onin);
104 	mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_AFE_LDO_PWRDWNB);
105 	/* Delay as per external FSM spec */
106 	udelay(10U);
107 
108 	mmio_setbits_32(u2_phy->pwr_ctrl_reg, u2_phy->pwr_okin);
109 	/* Delay as per external FSM spec */
110 	udelay(10U);
111 
112 	mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_AFE_PLL_PWRDWNB);
113 	/* Delay as per external FSM spec */
114 	udelay(10U);
115 
116 	mmio_clrbits_32(u2_phy->phy_ctrl_reg, USB2_PHY_ISO);
117 	/* Delay as per external FSM spec */
118 	udelay(10U);
119 	mmio_clrbits_32(u2_phy->phy_ctrl_reg, u2_phy->phy_iddq);
120 	/* Delay as per external FSM spec */
121 	udelay(1U);
122 
123 	mmio_setbits_32(u2_phy->pll_ctrl_reg, USB2_PLL_RESETB);
124 	mmio_setbits_32(u2_phy->phy_ctrl_reg, USB2_PHY_RESETB);
125 
126 }
127 
usb3h_u2_phy_power_on(uint32_t base)128 static int32_t usb3h_u2_phy_power_on(uint32_t base)
129 {
130 	int32_t status;
131 	struct u2_phy_ext_fsm u2_phy;
132 
133 	u2_phy.pll_ctrl_reg = base + USB3H_U2PLL_CTRL;
134 	u2_phy.phy_ctrl_reg = base + USB3H_U2PHY_CTRL;
135 	u2_phy.phy_iddq = USB3H_U2PHY_IDDQ;
136 	u2_phy.pwr_ctrl_reg = base + USB3H_PWR_CTRL;
137 	u2_phy.pwr_okin = USB3H_PWR_CTRL_U2PHY_DFE_SWITCH_PWROKIN;
138 	u2_phy.pwr_onin = USB3H_PWR_CTRL_U2PHY_DFE_SWITCH_PWRONIN;
139 
140 	u2_phy_ext_fsm_power_on(&u2_phy);
141 
142 	status = pll_lock_check(base + USB3H_U2PLL_CTRL, USB3H_U2PLL_LOCK);
143 	if (status != 0) {
144 		/* re-try by toggling the PLL reset */
145 		mmio_clrbits_32(base + USB3H_U2PLL_CTRL,
146 				(uint32_t)USB3H_U2PLL_RESETB);
147 		mmio_setbits_32(base + USB3H_U2PLL_CTRL, USB3H_U2PLL_RESETB);
148 		status = pll_lock_check(base + USB3H_U2PLL_CTRL,
149 					USB3H_U2PLL_LOCK);
150 		if (status != 0)
151 			ERROR("%s() re-try PLL lock FAIL (0x%08x)\n", __func__,
152 			      base + USB3H_U2PLL_CTRL);
153 	}
154 
155 	mmio_clrsetbits_32(base + USB3H_U2PHY_CTRL,
156 			   (USB3H_U2PHY_PCTL_MASK << USB3H_U2PHY_PCTL_OFFSET),
157 			   (U2PHY_PCTL_NON_DRV_LOW << USB3H_U2PHY_PCTL_OFFSET));
158 	return status;
159 }
160 
usb3h_u3_phy_power_on(uint32_t base)161 static int32_t usb3h_u3_phy_power_on(uint32_t base)
162 {
163 	int32_t status;
164 
165 	/* Set pctl with mode and soft reset */
166 	mmio_clrsetbits_32(base + USB3H_U3PHY_CTRL,
167 			   (USB3H_U3PHY_PCTL_MASK << USB3H_U3PHY_PCTL_OFFSET),
168 			   (U3PHY_PCTL_VAL << USB3H_U3PHY_PCTL_OFFSET));
169 
170 	mmio_clrbits_32(base + USB3H_U3PHY_PLL_CTRL,
171 			(uint32_t) USB3H_U3SSPLL_SUSPEND_EN);
172 	mmio_setbits_32(base + USB3H_U3PHY_PLL_CTRL, USB3H_U3PLL_SEQ_START);
173 	mmio_setbits_32(base + USB3H_U3PHY_PLL_CTRL, USB3H_U3PLL_RESETB);
174 
175 	/* Time to stabilize the PLL Control */
176 	mdelay(1U);
177 
178 	status = pll_lock_check(base + USB3H_U3PHY_PLL_CTRL,
179 				USB3H_U3PLL_SS_LOCK);
180 
181 	return status;
182 }
183 
drdu3_u2_phy_power_on(uint32_t base)184 static int32_t drdu3_u2_phy_power_on(uint32_t base)
185 {
186 	int32_t status;
187 	struct u2_phy_ext_fsm u2_phy;
188 
189 	u2_phy.pll_ctrl_reg = base + DRDU3_U2PLL_CTRL;
190 	u2_phy.phy_ctrl_reg = base + DRDU3_U2PHY_CTRL;
191 	u2_phy.phy_iddq = DRDU3_U2PHY_IDDQ;
192 	u2_phy.pwr_ctrl_reg = base + DRDU3_PWR_CTRL;
193 	u2_phy.pwr_okin = DRDU3_U2PHY_DFE_SWITCH_PWROKIN;
194 	u2_phy.pwr_onin = DRDU3_U2PHY_DFE_SWITCH_PWRONIN;
195 
196 	u2_phy_ext_fsm_power_on(&u2_phy);
197 
198 	status = pll_lock_check(base + DRDU3_U2PLL_CTRL, DRDU3_U2PLL_LOCK);
199 	if (status != 0) {
200 		/* re-try by toggling the PLL reset */
201 		mmio_clrbits_32(base + DRDU3_U2PLL_CTRL,
202 				(uint32_t)DRDU2_U2PLL_RESETB);
203 		mmio_setbits_32(base + DRDU3_U2PLL_CTRL, DRDU3_U2PLL_RESETB);
204 
205 		status = pll_lock_check(base + DRDU3_U2PLL_CTRL,
206 					DRDU3_U2PLL_LOCK);
207 		if (status != 0) {
208 			ERROR("%s() re-try PLL lock FAIL (0x%08x)\n", __func__,
209 			      base + DRDU3_U2PLL_CTRL);
210 		}
211 	}
212 	mmio_clrsetbits_32(base + DRDU3_U2PHY_CTRL,
213 			   (DRDU3_U2PHY_PCTL_MASK << DRDU3_U2PHY_PCTL_OFFSET),
214 			   (U2PHY_PCTL_NON_DRV_LOW << DRDU3_U2PHY_PCTL_OFFSET));
215 
216 	return status;
217 }
218 
drdu3_u3_phy_power_on(uint32_t base)219 static int32_t drdu3_u3_phy_power_on(uint32_t base)
220 {
221 	int32_t status;
222 
223 	/* Set pctl with mode and soft reset */
224 	mmio_clrsetbits_32(base + DRDU3_U3PHY_CTRL,
225 			   (DRDU3_U3PHY_PCTL_MASK << DRDU3_U3PHY_PCTL_OFFSET),
226 			   (U3PHY_PCTL_VAL << DRDU3_U3PHY_PCTL_OFFSET));
227 
228 	mmio_clrbits_32(base + DRDU3_U3PHY_PLL_CTRL,
229 			(uint32_t) DRDU3_U3SSPLL_SUSPEND_EN);
230 	mmio_setbits_32(base + DRDU3_U3PHY_PLL_CTRL, DRDU3_U3PLL_SEQ_START);
231 	mmio_setbits_32(base + DRDU3_U3PHY_PLL_CTRL, DRDU3_U3PLL_RESETB);
232 
233 	/* Time to stabilize the PLL Control */
234 	mdelay(1U);
235 
236 	status = pll_lock_check(base + DRDU3_U3PHY_PLL_CTRL,
237 				DRDU3_U3PLL_SS_LOCK);
238 
239 	return status;
240 }
241 
drdu2_u2_phy_power_on(uint32_t base)242 static int32_t drdu2_u2_phy_power_on(uint32_t base)
243 {
244 	int32_t status;
245 	struct u2_phy_ext_fsm u2_phy;
246 
247 	u2_phy.pll_ctrl_reg = base + DRDU2_U2PLL_CTRL;
248 	u2_phy.phy_ctrl_reg = base + DRDU2_PHY_CTRL;
249 	u2_phy.phy_iddq = DRDU2_U2IDDQ;
250 	u2_phy.pwr_ctrl_reg = base + DRDU2_PWR_CTRL;
251 	u2_phy.pwr_okin = DRDU2_U2PHY_DFE_SWITCH_PWROKIN_I;
252 	u2_phy.pwr_onin = DRDU2_U2PHY_DFE_SWITCH_PWRONIN_I;
253 
254 	u2_phy_ext_fsm_power_on(&u2_phy);
255 
256 	status = pll_lock_check(base + DRDU2_U2PLL_CTRL, DRDU2_U2PLL_LOCK);
257 	if (status != 0) {
258 		/* re-try by toggling the PLL reset */
259 		mmio_clrbits_32(base + DRDU2_U2PLL_CTRL,
260 				(uint32_t)DRDU2_U2PLL_RESETB);
261 		mmio_setbits_32(base + DRDU2_U2PLL_CTRL, DRDU2_U2PLL_RESETB);
262 
263 		status = pll_lock_check(base + DRDU2_U2PLL_CTRL,
264 					DRDU2_U2PLL_LOCK);
265 		if (status != 0)
266 			ERROR("%s() re-try PLL lock FAIL (0x%08x)\n", __func__,
267 			      base + DRDU2_U2PLL_CTRL);
268 	}
269 	mmio_clrsetbits_32(base + DRDU2_PHY_CTRL,
270 			   (DRDU2_U2PHY_PCTL_MASK << DRDU2_U2PHY_PCTL_OFFSET),
271 			   (U2PHY_PCTL_NON_DRV_LOW << DRDU2_U2PHY_PCTL_OFFSET));
272 
273 	return status;
274 }
275 
u3h_u2drd_phy_reset(usb_phy_port_t * phy_port)276 void u3h_u2drd_phy_reset(usb_phy_port_t *phy_port)
277 {
278 	usb_phy_t *phy = phy_port->p;
279 
280 	switch (phy_port->port_id) {
281 	case USB3HS_PORT:
282 		mmio_clrbits_32(phy->usb3hreg + USB3H_U2PHY_CTRL,
283 				(uint32_t) USB3H_U2CTRL_CORERDY);
284 		mmio_setbits_32(phy->usb3hreg + USB3H_U2PHY_CTRL,
285 				USB3H_U2CTRL_CORERDY);
286 		break;
287 	case DRDU2_PORT:
288 		mmio_clrbits_32(phy->drdu2reg + DRDU2_PHY_CTRL,
289 				(uint32_t) DRDU2_U2CTRL_CORERDY);
290 		mmio_setbits_32(phy->drdu2reg + DRDU2_PHY_CTRL,
291 				DRDU2_U2CTRL_CORERDY);
292 		break;
293 	}
294 }
295 
u3drd_phy_reset(usb_phy_port_t * phy_port)296 void u3drd_phy_reset(usb_phy_port_t *phy_port)
297 {
298 	usb_phy_t *phy = phy_port->p;
299 
300 	if (phy_port->port_id == DRD3HS_PORT) {
301 		mmio_clrbits_32(phy->drdu3reg + DRDU3_U2PHY_CTRL,
302 				(uint32_t) DRDU3_U2CTRL_CORERDY);
303 		mmio_setbits_32(phy->drdu3reg + DRDU3_U2PHY_CTRL,
304 				DRDU3_U2CTRL_CORERDY);
305 	}
306 }
307 
u3h_u2drd_phy_power_on(usb_phy_port_t * phy_port)308 static int32_t u3h_u2drd_phy_power_on(usb_phy_port_t *phy_port)
309 {
310 	usb_phy_t *phy = phy_port->p;
311 	int32_t status;
312 
313 	switch (phy_port->port_id) {
314 	case USB3SS_PORT:
315 		mmio_clrbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
316 				(uint32_t) USB3H_DISABLE_USB30_P0);
317 		status = usb3h_u3_phy_power_on(phy->usb3hreg);
318 		if (status != 0) {
319 			goto err_usb3h_phy_on;
320 		}
321 		break;
322 	case USB3HS_PORT:
323 		mmio_clrbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
324 				(uint32_t) USB3H_DISABLE_EUSB_P1);
325 		mmio_setbits_32(AXI_DEBUG_CTRL,
326 				AXI_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
327 		mmio_setbits_32(USB3H_DEBUG_CTRL,
328 				USB3H_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
329 
330 		mmio_clrbits_32(phy->usb3hreg + USB3H_PWR_CTRL,
331 				USB3H_PWR_CTRL_U2PHY_DFE_SWITCH_PWRONIN);
332 		/* Delay as per external FSM spec */
333 		udelay(10U);
334 		mmio_clrbits_32(phy->usb3hreg + USB3H_PWR_CTRL,
335 				USB3H_PWR_CTRL_U2PHY_DFE_SWITCH_PWROKIN);
336 		status = usb3h_u2_phy_power_on(phy->usb3hreg);
337 		if (status != 0) {
338 			goto err_usb3h_phy_on;
339 		}
340 		break;
341 	case DRDU2_PORT:
342 		mmio_clrbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
343 				(uint32_t) USB3H_DISABLE_EUSB_P0);
344 		mmio_setbits_32(AXI_DEBUG_CTRL,
345 				AXI_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
346 		mmio_setbits_32(USB3H_DEBUG_CTRL,
347 				USB3H_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
348 
349 		mmio_clrbits_32(phy->usb3hreg + DRDU2_PWR_CTRL,
350 				DRDU2_U2PHY_DFE_SWITCH_PWRONIN_I);
351 		/* Delay as per external FSM spec */
352 		udelay(10U);
353 		mmio_clrbits_32(phy->usb3hreg + DRDU2_PWR_CTRL,
354 				DRDU2_U2PHY_DFE_SWITCH_PWROKIN_I);
355 
356 		status = drdu2_u2_phy_power_on(phy->drdu2reg);
357 		if (status != 0) {
358 			mmio_setbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
359 					USB3H_DISABLE_EUSB_P0);
360 			goto err_drdu2_phy_on;
361 		}
362 		break;
363 	}
364 
365 	/* Device Mode */
366 	if (phy_port->port_id == DRDU2_PORT) {
367 		mmio_write_32(phy->drdu2reg + DRDU2_SOFT_RESET_CTRL,
368 			      DRDU2_BDC_AXI_SOFT_RST_N);
369 		mmio_setbits_32(phy->drdu2reg + DRDU2_PHY_CTRL,
370 				DRDU2_U2SOFT_RST_N);
371 	}
372 	/* Host Mode */
373 	mmio_write_32(phy->usb3hreg + USB3H_SOFT_RESET_CTRL,
374 		      USB3H_XHC_AXI_SOFT_RST_N);
375 	mmio_setbits_32(phy->usb3hreg + USB3H_U3PHY_CTRL, USB3H_U3SOFT_RST_N);
376 
377 	return 0U;
378  err_usb3h_phy_on:mmio_setbits_32(phy->usb3hreg + USB3H_PHY_PWR_CTRL,
379 			(USB3H_DISABLE_EUSB_P1 |
380 			 USB3H_DISABLE_USB30_P0));
381  err_drdu2_phy_on:
382 
383 	return status;
384 }
385 
u3drd_phy_power_on(usb_phy_port_t * phy_port)386 static int32_t u3drd_phy_power_on(usb_phy_port_t *phy_port)
387 {
388 	usb_phy_t *phy = phy_port->p;
389 	int32_t status;
390 
391 	switch (phy_port->port_id) {
392 	case DRD3SS_PORT:
393 		mmio_clrbits_32(phy->drdu3reg + DRDU3_PHY_PWR_CTRL,
394 				(uint32_t) DRDU3_DISABLE_USB30_P0);
395 
396 		status = drdu3_u3_phy_power_on(phy->drdu3reg);
397 		if (status != 0) {
398 			goto err_drdu3_phy_on;
399 		}
400 		break;
401 	case DRD3HS_PORT:
402 		mmio_clrbits_32(phy->drdu3reg + DRDU3_PHY_PWR_CTRL,
403 				(uint32_t) DRDU3_DISABLE_EUSB_P0);
404 		mmio_setbits_32(AXI_DEBUG_CTRL,
405 				AXI_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
406 		mmio_setbits_32(USB3H_DEBUG_CTRL,
407 				USB3H_DBG_CTRL_SSPHY_DRD_MODE_DISABLE);
408 
409 		mmio_clrbits_32(phy->drdu3reg + DRDU3_PWR_CTRL,
410 				DRDU3_U2PHY_DFE_SWITCH_PWRONIN);
411 		/* Delay as per external FSM spec */
412 		udelay(10U);
413 		mmio_clrbits_32(phy->drdu3reg + DRDU3_PWR_CTRL,
414 				DRDU3_U2PHY_DFE_SWITCH_PWROKIN);
415 
416 		status = drdu3_u2_phy_power_on(phy->drdu3reg);
417 		if (status != 0) {
418 			goto err_drdu3_phy_on;
419 		}
420 
421 		/* Host Mode */
422 		mmio_setbits_32(phy->drdu3reg + DRDU3_SOFT_RESET_CTRL,
423 				DRDU3_XHC_AXI_SOFT_RST_N);
424 		mmio_setbits_32(phy->drdu3reg + DRDU3_U3PHY_CTRL,
425 				DRDU3_U3XHC_SOFT_RST_N);
426 		/* Device Mode */
427 		mmio_setbits_32(phy->drdu3reg + DRDU3_SOFT_RESET_CTRL,
428 				DRDU3_BDC_AXI_SOFT_RST_N);
429 		mmio_setbits_32(phy->drdu3reg + DRDU3_U3PHY_CTRL,
430 				DRDU3_U3BDC_SOFT_RST_N);
431 		break;
432 	}
433 
434 	return 0U;
435  err_drdu3_phy_on:mmio_setbits_32(phy->drdu3reg + DRDU3_PHY_PWR_CTRL,
436 			(DRDU3_DISABLE_EUSB_P0 |
437 			 DRDU3_DISABLE_USB30_P0));
438 
439 	return status;
440 }
441 
u3h_u2drd_phy_power_off(usb_phy_port_t * phy_port)442 static void u3h_u2drd_phy_power_off(usb_phy_port_t *phy_port)
443 {
444 	usb_phy_t *p = phy_port->p;
445 
446 	switch (phy_port->port_id) {
447 	case USB3SS_PORT:
448 		mmio_setbits_32(p->usb3hreg + USB3H_PHY_PWR_CTRL,
449 				USB3H_DISABLE_USB30_P0);
450 		break;
451 	case USB3HS_PORT:
452 		mmio_setbits_32(p->usb3hreg + USB3H_PHY_PWR_CTRL,
453 				USB3H_DISABLE_EUSB_P1);
454 		break;
455 	case DRDU2_PORT:
456 		mmio_setbits_32(p->usb3hreg + USB3H_PHY_PWR_CTRL,
457 				USB3H_DISABLE_EUSB_P0);
458 		break;
459 	}
460 }
461 
u3drd_phy_power_off(usb_phy_port_t * phy_port)462 static void u3drd_phy_power_off(usb_phy_port_t *phy_port)
463 {
464 	usb_phy_t *p = phy_port->p;
465 
466 	switch (phy_port->port_id) {
467 	case DRD3SS_PORT:
468 		mmio_setbits_32(p->drdu3reg + DRDU3_PHY_PWR_CTRL,
469 				DRDU3_DISABLE_USB30_P0);
470 		break;
471 	case DRD3HS_PORT:
472 		mmio_setbits_32(p->drdu3reg + DRDU3_PHY_PWR_CTRL,
473 				DRDU3_DISABLE_EUSB_P0);
474 		break;
475 	}
476 }
477 
usb_info_fill(usb_phy_t * phy_info)478 int32_t usb_info_fill(usb_phy_t *phy_info)
479 {
480 	int32_t index;
481 
482 	if (phy_info->initialized != 0U) {
483 		return USB_PHY_ALREADY_STARTED;
484 	}
485 
486 	if (phy_info->phy_id == USB3H_DRDU2_PHY) {
487 		phy_info->phy_port = usb_phy_port[USB3H_DRDU2_PHY - 1U];
488 		phy_info->ports_enabled = 0x7U;
489 	} else {
490 		phy_info->phy_port = usb_phy_port[DRDU3_PHY - 1U];
491 		phy_info->ports_enabled = 0x3U;
492 	}
493 
494 	for (index = MAX_NR_PORTS - 1U; index > -1; index--) {
495 		phy_info->phy_port[index].enabled = (phy_info->ports_enabled
496 						     >> index) & 0x1U;
497 		phy_info->phy_port[index].p = phy_info;
498 		phy_info->phy_port[index].port_id = index;
499 	}
500 
501 	return 0U;
502 }
503 
usb_phy_init(usb_platform_dev * device)504 int32_t usb_phy_init(usb_platform_dev *device)
505 {
506 	int32_t status;
507 	usb_phy_t *phy_info;
508 	uint32_t index;
509 
510 	phy_info = (usb_phy_t *)device->pcd_id;
511 
512 	status = usb_info_fill(phy_info);
513 	if (status != 0) {
514 		return (status == USB_PHY_ALREADY_STARTED) ? 0 : status;
515 	}
516 
517 	for (index = 0U; index < MAX_NR_PORTS; index++) {
518 		if (phy_info->phy_port[index].enabled != 0U) {
519 			switch (phy_info->phy_id) {
520 			case USB3H_DRDU2_PHY:
521 				status =
522 				    u3h_u2drd_phy_power_on(&phy_info->
523 							   phy_port[index]);
524 				break;
525 			default:
526 				status =
527 				    u3drd_phy_power_on(&phy_info->
528 						       phy_port[index]);
529 			}
530 		}
531 	}
532 
533 	phy_info->initialized = !status;
534 	return status;
535 }
536 
usb_phy_shutdown(usb_platform_dev * device)537 void usb_phy_shutdown(usb_platform_dev *device)
538 {
539 	usb_phy_t *phy_info;
540 	uint32_t index;
541 
542 	phy_info = (usb_phy_t *)device->pcd_id;
543 
544 	phy_info->initialized = 0U;
545 
546 	for (index = 0U; index < MAX_NR_PORTS; index++) {
547 		if (phy_info->phy_port[index].enabled != 0U) {
548 			switch (phy_info->phy_id) {
549 			case USB3H_DRDU2_PHY:
550 				u3h_u2drd_phy_power_off(&phy_info->
551 							phy_port[index]);
552 				break;
553 			case DRDU3_PHY:
554 				u3drd_phy_power_off(&phy_info->phy_port[index]);
555 				break;
556 			default:
557 				INFO("%s: invalid phy id 0x%x\n", __func__,
558 				     phy_info->phy_id);
559 			}
560 		}
561 	}
562 }
563 
usb_xhci_init(usb_platform_dev * device)564 int32_t usb_xhci_init(usb_platform_dev *device)
565 {
566 	int32_t status;
567 
568 	status = usb_phy_init(device);
569 	if (status == USB_PHY_ALREADY_STARTED) {
570 		status = 0U;
571 	}
572 
573 	return status;
574 }
575 
usb_device_init(unsigned int usb_func)576 int32_t usb_device_init(unsigned int usb_func)
577 {
578 	int32_t status;
579 	int32_t devices_initialized = 0U;
580 
581 	if ((usb_func & USB3H_USB2DRD) != 0U) {
582 		status = usb_xhci_init(
583 				&xhci_devices_configs[USB3H_USB2DRD_PHY]);
584 		if (status == 0) {
585 			devices_initialized++;
586 		} else {
587 			ERROR("%s(): USB3H_USB2DRD init failure\n", __func__);
588 		}
589 	}
590 
591 	if ((usb_func & USB3_DRD) != 0U) {
592 		status = usb_xhci_init(&xhci_devices_configs[USB3_DRD_PHY]);
593 		if (status == 0) {
594 			devices_initialized++;
595 		} else {
596 			ERROR("%s(): USB3_DRD init failure\n", __func__);
597 		}
598 	}
599 
600 	return devices_initialized;
601 }
602