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