xref: /rk3399_ARM-atf/drivers/st/usb_dwc3/usb_dwc3.c (revision 867cd155f5bc062a480a7dbcadcf8adc9ca1d66a)
1*867cd155SPankaj Dev /*
2*867cd155SPankaj Dev  * Copyright (c) 2015-2025, STMicroelectronics - All Rights Reserved
3*867cd155SPankaj Dev  *
4*867cd155SPankaj Dev  * SPDX-License-Identifier: BSD-3-Clause
5*867cd155SPankaj Dev  */
6*867cd155SPankaj Dev 
7*867cd155SPankaj Dev #include <assert.h>
8*867cd155SPankaj Dev #include <stdint.h>
9*867cd155SPankaj Dev 
10*867cd155SPankaj Dev #include <arch_helpers.h>
11*867cd155SPankaj Dev #include <common/debug.h>
12*867cd155SPankaj Dev #include <drivers/delay_timer.h>
13*867cd155SPankaj Dev #include <drivers/st/usb_dwc3.h>
14*867cd155SPankaj Dev #include <lib/mmio.h>
15*867cd155SPankaj Dev #include <lib/utils.h>
16*867cd155SPankaj Dev #include <lib/xlat_tables/xlat_tables_v2.h>
17*867cd155SPankaj Dev 
18*867cd155SPankaj Dev #include "usb_dwc3_regs.h"
19*867cd155SPankaj Dev 
20*867cd155SPankaj Dev /*
21*867cd155SPankaj Dev  * @brief USB EP Type
22*867cd155SPankaj Dev  */
23*867cd155SPankaj Dev #define EP_TYPE_CTRL	0U
24*867cd155SPankaj Dev #define EP_TYPE_ISOC	1U
25*867cd155SPankaj Dev #define EP_TYPE_BULK	2U
26*867cd155SPankaj Dev #define EP_TYPE_INTR	3U
27*867cd155SPankaj Dev #define EP_TYPE_MSK	3U
28*867cd155SPankaj Dev 
29*867cd155SPankaj Dev #define USB_DWC3_GLOBAL_BASE	0xc100
30*867cd155SPankaj Dev #define USB_DWC3_DEVICE_BASE	0xc700
31*867cd155SPankaj Dev 
32*867cd155SPankaj Dev /* Global Registers */
33*867cd155SPankaj Dev #define DWC3_GSBUSCFG0	_DWC3_GSBUSCFG0
34*867cd155SPankaj Dev #define DWC3_GSBUSCFG1	_DWC3_GSBUSCFG1
35*867cd155SPankaj Dev #define DWC3_GTXTHRCFG	_DWC3_GTXTHRCFG
36*867cd155SPankaj Dev #define DWC3_GRXTHRCFG	_DWC3_GRXTHRCFG
37*867cd155SPankaj Dev #define DWC3_GCTL	_DWC3_GCTL
38*867cd155SPankaj Dev #define DWC3_GEVTEN	_DWC3_GEVTEN
39*867cd155SPankaj Dev #define DWC3_GSTS	_DWC3_GSTS
40*867cd155SPankaj Dev #define DWC3_GUCTL1	_DWC3_GUCTL1
41*867cd155SPankaj Dev #define DWC3_GSNPSID	_DWC3_GSNPSID
42*867cd155SPankaj Dev #define DWC3_GGPIO	_DWC3_GGPIO
43*867cd155SPankaj Dev #define DWC3_GUID	_DWC3_GUID
44*867cd155SPankaj Dev #define DWC3_GUCTL	_DWC3_GUCTL
45*867cd155SPankaj Dev #define DWC3_GBUSERRADDR0	_DWC3_GBUSERRADDRLO
46*867cd155SPankaj Dev #define DWC3_GBUSERRADDR1	_DWC3_GBUSERRADDRHI
47*867cd155SPankaj Dev #define DWC3_GPRTBIMAP0	_DWC3_GPRTBIMAPLO
48*867cd155SPankaj Dev #define DWC3_GPRTBIMAP1	_DWC3_GPRTBIMAPHI
49*867cd155SPankaj Dev #define DWC3_GHWPARAMS0	_DWC3_GHWPARAMS0
50*867cd155SPankaj Dev #define DWC3_GHWPARAMS1	_DWC3_GHWPARAMS1
51*867cd155SPankaj Dev #define DWC3_GHWPARAMS2	_DWC3_GHWPARAMS2
52*867cd155SPankaj Dev #define DWC3_GHWPARAMS3	_DWC3_GHWPARAMS3
53*867cd155SPankaj Dev #define DWC3_GHWPARAMS4	_DWC3_GHWPARAMS4
54*867cd155SPankaj Dev #define DWC3_GHWPARAMS5	_DWC3_GHWPARAMS5
55*867cd155SPankaj Dev #define DWC3_GHWPARAMS6	_DWC3_GHWPARAMS6
56*867cd155SPankaj Dev #define DWC3_GHWPARAMS7	_DWC3_GHWPARAMS7
57*867cd155SPankaj Dev #define DWC3_GDBGFIFOSPACE	_DWC3_GDBGFIFOSPACE
58*867cd155SPankaj Dev #define DWC3_GDBGLTSSM	_DWC3_GDBGLTSSM
59*867cd155SPankaj Dev #define DWC3_GPRTBIMAP_HS0	_DWC3_GPRTBIMAP_HSLO
60*867cd155SPankaj Dev #define DWC3_GPRTBIMAP_HS1	_DWC3_GPRTBIMAP_HSHI
61*867cd155SPankaj Dev #define DWC3_GPRTBIMAP_FS0	_DWC3_GPRTBIMAP_FSLO
62*867cd155SPankaj Dev #define DWC3_GPRTBIMAP_FS1	_DWC3_GPRTBIMAP_FSHI
63*867cd155SPankaj Dev #define DWC3_GUCTL2	_DWC3_GUCTL2
64*867cd155SPankaj Dev 
65*867cd155SPankaj Dev #define DWC3_GUSB2PHYCFG(n)	(_DWC3_GUSB2PHYCFG + (4UL * (n)))
66*867cd155SPankaj Dev #define DWC3_GUSB2I2CCTL(n)	(_DWC3_GUSB2I2CCTL + (4UL * (n)))
67*867cd155SPankaj Dev 
68*867cd155SPankaj Dev #define DWC3_GUSB2PHYACC(n)	(_DWC3_GUSB2PHYACC + (4UL * (n)))
69*867cd155SPankaj Dev 
70*867cd155SPankaj Dev #define DWC3_GUSB3PIPECTL(n)	(_DWC3_GUSB3PIPECTL + (4UL * (n)))
71*867cd155SPankaj Dev 
72*867cd155SPankaj Dev #define DWC3_GTXFIFOSIZ(n)	(_DWC3_GTXFIFOSIZ0 + (4UL * (n)))
73*867cd155SPankaj Dev #define DWC3_GRXFIFOSIZ(n)	(_DWC3_GRXFIFOSIZ0 + (4UL * (n)))
74*867cd155SPankaj Dev 
75*867cd155SPankaj Dev #define DWC3_GEVNTADRLO(n)	(_DWC3_GEVNTADRLO + (16UL * (n)))
76*867cd155SPankaj Dev #define DWC3_GEVNTADRHI(n)	(_DWC3_GEVNTADRHI + (16UL * (n)))
77*867cd155SPankaj Dev #define DWC3_GEVNTSIZ(n)	(_DWC3_GEVNTSIZ + (16UL * (n)))
78*867cd155SPankaj Dev #define DWC3_GEVNTCOUNT(n)	(_DWC3_GEVNTCOUNT + (16UL * (n)))
79*867cd155SPankaj Dev 
80*867cd155SPankaj Dev #define DWC3_GUSB2PHYACC_ADDR(n)	((n) << USB3_GUSB2PHYACC_ULPI_REGADDR_POS)
81*867cd155SPankaj Dev #define DWC3_GUSB2PHYACC_EXTEND_ADDR(n)	((n) << USB3_GUSB2PHYACC_ULPI_EXTREGADDR_POS)
82*867cd155SPankaj Dev #define DWC3_GUSB2PHYACC_DATA(n)	((n) & USB3_GUSB2PHYACC_ULPI_REGDATA_MSK)
83*867cd155SPankaj Dev 
84*867cd155SPankaj Dev #define DWC3_GUCTL2_RST_ACTBITLATER	_DWC3_GUCTL2_RST_ACTBITLATER
85*867cd155SPankaj Dev 
86*867cd155SPankaj Dev /* Device Registers */
87*867cd155SPankaj Dev #define DWC3_DCFG	_DWC3_DCFG
88*867cd155SPankaj Dev #define DWC3_DCTL	_DWC3_DCTL
89*867cd155SPankaj Dev #define DWC3_DEVTEN	_DWC3_DEVTEN
90*867cd155SPankaj Dev #define DWC3_DSTS	_DWC3_DSTS
91*867cd155SPankaj Dev #define DWC3_DGCMDPAR	_DWC3_DGCMDPAR
92*867cd155SPankaj Dev #define DWC3_DGCMD	_DWC3_DGCMD
93*867cd155SPankaj Dev #define DWC3_DALEPENA	_DWC3_DALEPENA
94*867cd155SPankaj Dev #define DWC3_DEPCMDPAR2(n)	(_DWC3_DEPCMDPAR2 + (16UL * (n)))
95*867cd155SPankaj Dev #define DWC3_DEPCMDPAR1(n)	(_DWC3_DEPCMDPAR1 + (16UL * (n)))
96*867cd155SPankaj Dev #define DWC3_DEPCMDPAR0(n)	(_DWC3_DEPCMDPAR0 + (16UL * (n)))
97*867cd155SPankaj Dev #define DWC3_DEPCMD(n)	(_DWC3_DEPCMD + (16UL * (n)))
98*867cd155SPankaj Dev 
99*867cd155SPankaj Dev /* The EP number goes 0..31 so ep0 is always out and ep1 is always in */
100*867cd155SPankaj Dev #define DWC3_DALEPENA_EP(n)	(1UL << (n))
101*867cd155SPankaj Dev 
102*867cd155SPankaj Dev /*
103*867cd155SPankaj Dev  * @brief USB EP Type
104*867cd155SPankaj Dev  */
105*867cd155SPankaj Dev #define EP_TYPE_CTRL	0U
106*867cd155SPankaj Dev #define EP_TYPE_ISOC	1U
107*867cd155SPankaj Dev #define EP_TYPE_BULK	2U
108*867cd155SPankaj Dev #define EP_TYPE_INTR	3U
109*867cd155SPankaj Dev #define EP_TYPE_MSK	3U
110*867cd155SPankaj Dev 
111*867cd155SPankaj Dev /* Event Size */
112*867cd155SPankaj Dev #define USB_DWC3_EVENT_SIZE	4U
113*867cd155SPankaj Dev 
114*867cd155SPankaj Dev /* USB_ExecuteDevEPCmd::USB_DWC3_EPCmd */
115*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_DEPSTARTCFG	(0x09UL << USB3_DEPCMD_CMDTYP_POS)
116*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_ENDTRANSFER	(0x08UL << USB3_DEPCMD_CMDTYP_POS)
117*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_UPDATETRANSFER	(0x07UL << USB3_DEPCMD_CMDTYP_POS)
118*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_STARTTRANSFER	(0x06UL << USB3_DEPCMD_CMDTYP_POS)
119*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_CLEARSTALL	(0x05UL << USB3_DEPCMD_CMDTYP_POS)
120*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_SETSTALL	(0x04UL << USB3_DEPCMD_CMDTYP_POS)
121*867cd155SPankaj Dev /* This applies for core versions 1.94a and later */
122*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_GETEPSTATE	(0x03UL << USB3_DEPCMD_CMDTYP_POS)
123*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_SETTRANSFRESOURCE	(0x02UL << USB3_DEPCMD_CMDTYP_POS)
124*867cd155SPankaj Dev #define USB_DWC3_DEPCMD_SETEPCONFIG	(0x01UL << USB3_DEPCMD_CMDTYP_POS)
125*867cd155SPankaj Dev 
126*867cd155SPankaj Dev /* USB_ConfigureEP::action */
127*867cd155SPankaj Dev #define USB_DWC3_DEPCFG_ACTION_INIT	0
128*867cd155SPankaj Dev #define USB_DWC3_DEPCFG_ACTION_RESTORE	1
129*867cd155SPankaj Dev #define USB_DWC3_DEPCFG_ACTION_MODIFY	2
130*867cd155SPankaj Dev 
131*867cd155SPankaj Dev /* USB_ReadEndpointEventType @return EPEventType */
132*867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERCOMPLETE	0x01
133*867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERINPROGRESS	0x02
134*867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERNOTREADY	0x03
135*867cd155SPankaj Dev #define USB_DWC3_DEPEVT_RXTXFIFOEVT	0x04
136*867cd155SPankaj Dev #define USB_DWC3_DEPEVT_STREAMEVT	0x06
137*867cd155SPankaj Dev #define USB_DWC3_DEPEVT_EPCMDCMPLT	0x07
138*867cd155SPankaj Dev 
139*867cd155SPankaj Dev /* USB_ReadEndpointEventStatus @return EPEventStatus */
140*867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_DATA	0x01
141*867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_STATUS	0x02
142*867cd155SPankaj Dev 
143*867cd155SPankaj Dev /* USB_ReadDeviceEventType @return DevEventType */
144*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_DISCONNECT	0
145*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_RESET	1
146*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_CONNECT_DONE	2
147*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE	3
148*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_WAKEUP	4
149*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_HIBER_REQ	5
150*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_EOPF	6
151*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_SOF	7
152*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_L1SUSPEND	8
153*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_ERRATIC_ERROR	9
154*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_CMD_CMPL	10
155*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_OVERFLOW	11
156*867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_L1WAKEUP	14
157*867cd155SPankaj Dev 
158*867cd155SPankaj Dev #define USB_DWC3_TRBSTS_OK	0
159*867cd155SPankaj Dev #define USB_DWC3_TRBSTS_MISSED_ISOC	1
160*867cd155SPankaj Dev #define USB_DWC3_TRBSTS_SETUP_PENDING	2
161*867cd155SPankaj Dev #define USB_DWC3_TRBSTS_XFER_IN_PROG	4
162*867cd155SPankaj Dev 
163*867cd155SPankaj Dev #define USB_DWC3_SPEED_SUPER	0U
164*867cd155SPankaj Dev #define USB_DWC3_SPEED_HIGH	1U
165*867cd155SPankaj Dev #define USB_DWC3_SPEED_FULL_48	2U
166*867cd155SPankaj Dev #define USB_DWC3_SPEED_FULL	3U
167*867cd155SPankaj Dev #define USB_DWC3_SPEED_LOW	4U
168*867cd155SPankaj Dev #define USB_DWC3_SPEED_INVALID	15U
169*867cd155SPankaj Dev 
170*867cd155SPankaj Dev #define DWC3_DEPCMD_TYPE_CONTROL	0
171*867cd155SPankaj Dev #define DWC3_DEPCMD_TYPE_ISOC	1
172*867cd155SPankaj Dev #define DWC3_DEPCMD_TYPE_BULK	2
173*867cd155SPankaj Dev #define DWC3_DEPCMD_TYPE_INTR	3
174*867cd155SPankaj Dev 
175*867cd155SPankaj Dev #define DWC3_GCTL_PRTCAP(n)	(((n) & USB3_GCTL_PRTCAPDIR_MSK) >> USB3_GCTL_PRTCAPDIR_POS)
176*867cd155SPankaj Dev #define DWC3_GCTL_PRTCAPDIR(n)	((n) << USB3_GCTL_PRTCAPDIR_POS)
177*867cd155SPankaj Dev #define DWC3_GCTL_PRTCAP_HOST	1
178*867cd155SPankaj Dev #define DWC3_GCTL_PRTCAP_DEVICE	2
179*867cd155SPankaj Dev #define DWC3_GCTL_PRTCAP_OTG	3
180*867cd155SPankaj Dev 
181*867cd155SPankaj Dev #define DWC3_DSTS_SUPERSPEED	(4U << USB3_DSTS_CONNECTSPD_POS)
182*867cd155SPankaj Dev #define DWC3_DSTS_HIGHSPEED	(0U << USB3_DSTS_CONNECTSPD_POS)
183*867cd155SPankaj Dev #define DWC3_DSTS_FULLSPEED2	BIT(USB3_DSTS_CONNECTSPD_POS)
184*867cd155SPankaj Dev #define DWC3_DSTS_LOWSPEED	(2U << USB3_DSTS_CONNECTSPD_POS)
185*867cd155SPankaj Dev #define DWC3_DSTS_FULLSPEED1	(3U << USB3_DSTS_CONNECTSPD_POS)
186*867cd155SPankaj Dev 
187*867cd155SPankaj Dev #define DWC3_GEVNTCOUNT_MASK	0xfffcU
188*867cd155SPankaj Dev #define DWC3_GSNPSID_MASK	0xffff0000
189*867cd155SPankaj Dev #define DWC3_GSNPSREV_MASK	0xffff
190*867cd155SPankaj Dev 
191*867cd155SPankaj Dev #define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
192*867cd155SPankaj Dev 
193*867cd155SPankaj Dev #define DWC3_EVENT_TYPE_DEV	0
194*867cd155SPankaj Dev #define DWC3_EVENT_TYPE_CARKIT	3
195*867cd155SPankaj Dev #define DWC3_EVENT_TYPE_I2C	4
196*867cd155SPankaj Dev 
197*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_DISCONNECT	0
198*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_RESET	1
199*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_CONNECT_DONE	2
200*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE	3
201*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_WAKEUP	4
202*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_HIBER_REQ	5
203*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_EOPF	6
204*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_SOF	7
205*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_ERRATIC_ERROR	9
206*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_CMD_CMPL	10
207*867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_OVERFLOW	11
208*867cd155SPankaj Dev 
209*867cd155SPankaj Dev /* DEPCFG parameter 1 */
210*867cd155SPankaj Dev #define DWC3_DEPCFG_INT_NUM(n)	(((n) & 0x1f) << 0)
211*867cd155SPankaj Dev #define DWC3_DEPCFG_XFER_COMPLETE_EN	BIT(8)
212*867cd155SPankaj Dev #define DWC3_DEPCFG_XFER_IN_PROGRESS_EN	BIT(9)
213*867cd155SPankaj Dev #define DWC3_DEPCFG_XFER_NOT_READY_EN	BIT(10)
214*867cd155SPankaj Dev #define DWC3_DEPCFG_FIFO_ERROR_EN	BIT(11)
215*867cd155SPankaj Dev #define DWC3_DEPCFG_STREAM_EVENT_EN	BIT(13)
216*867cd155SPankaj Dev #define DWC3_DEPCFG_BINTERVAL_M1(n)	(((n) & 0xffU) << 16)
217*867cd155SPankaj Dev #define DWC3_DEPCFG_STREAM_CAPABLE	BIT(24)
218*867cd155SPankaj Dev #define DWC3_DEPCFG_EP_NUMBER(n)	(((n) & 0x1fUL) << 25)
219*867cd155SPankaj Dev #define DWC3_DEPCFG_BULK_BASED	BIT(30)
220*867cd155SPankaj Dev #define DWC3_DEPCFG_FIFO_BASED	BIT(31)
221*867cd155SPankaj Dev 
222*867cd155SPankaj Dev /* DEPCFG parameter 0 */
223*867cd155SPankaj Dev #define DWC3_DEPCFG_EP_TYPE(n)	(((n) & 0x3UL) << 1)
224*867cd155SPankaj Dev #define DWC3_DEPCFG_MAX_PACKET_SIZE(n)	(((n) & 0x7ffU) << 3)
225*867cd155SPankaj Dev #define DWC3_DEPCFG_FIFO_NUMBER(n)	(((n) & 0x1fUL) << 17)
226*867cd155SPankaj Dev #define DWC3_DEPCFG_BURST_SIZE(n)	(((n) & 0xf) << 22)
227*867cd155SPankaj Dev #define DWC3_DEPCFG_DATA_SEQ_NUM(n)	((n) << 26)
228*867cd155SPankaj Dev /* DEPCFG parameter 1 */
229*867cd155SPankaj Dev #define DWC3_DEPCFG_EP_INTR_NUM(n)	((n) & 0x1fUL)
230*867cd155SPankaj Dev /* This applies for core versions earlier than 1.94a */
231*867cd155SPankaj Dev #define DWC3_DEPCFG_IGN_SEQ_NUM	BIT(31)
232*867cd155SPankaj Dev /* These apply for core versions 1.94a and later */
233*867cd155SPankaj Dev #define DWC3_DEPCFG_ACTION_INIT	(0U << 30)
234*867cd155SPankaj Dev #define DWC3_DEPCFG_ACTION_RESTORE	BIT(30)
235*867cd155SPankaj Dev #define DWC3_DEPCFG_ACTION_MODIFY	(2U << 30)
236*867cd155SPankaj Dev #define DWC3_DEPCFG_ACTION_VALUE(n)	(((n) & 0x3) << 30)
237*867cd155SPankaj Dev 
238*867cd155SPankaj Dev /* DEPXFERCFG parameter 0 */
239*867cd155SPankaj Dev #define DWC3_DEPXFERCFG_NUM_XFER_RES(n)	((n) & 0xffffU)
240*867cd155SPankaj Dev 
241*867cd155SPankaj Dev #define DWC3_DEPCMD_GET_RSC_IDX(x)	(((x) >> USB3_DEPCMD_COMMANDPARAM_POS) & 0x7fU)
242*867cd155SPankaj Dev #define DWC3_DEPCMD_STATUS(x)	(((x) & USB3_DEPCMD_CMDSTATUS_MSK) >> 12)
243*867cd155SPankaj Dev #define DWC3_DGCMD_STATUS(n)	(((n) & USB3_DGCMD_CMDSTATUS_MSK) >> USB3_DGCMD_CMDSTATUS_POS)
244*867cd155SPankaj Dev 
245*867cd155SPankaj Dev #define DWC3_DEPCMD_PARAM(x)	((x) << USB3_DEPCMD_COMMANDPARAM_POS)
246*867cd155SPankaj Dev 
247*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_U0	0x00 /* in HS, means ON */
248*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_U1	0x01
249*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_U2	0x02 /* in HS, means SLEEP */
250*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_U3	0x03 /* in HS, means SUSPEND */
251*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_DIS	0x04 /* Default State */
252*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_RX_DET	0x05 /* in HS, means Early Suspend */
253*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_INACT	0x06
254*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_POLL	0x07
255*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_RECOV	0x08
256*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_HRESET	0x09
257*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_CMPLY	0x0a
258*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_LPBK	0x0b
259*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_RESET	0x0e
260*867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_RESUME	0x0f
261*867cd155SPankaj Dev 
262*867cd155SPankaj Dev #define DWC3_LINK_STATE_ON	0x00U /* in HS, means ON */
263*867cd155SPankaj Dev #define DWC3_LINK_STATE_L1	0x02U /* in HS, means SLEEP */
264*867cd155SPankaj Dev #define DWC3_LINK_STATE_L2	0x03U /* in HS, means SUSPEND */
265*867cd155SPankaj Dev #define DWC3_LINK_STATE_DIS	0x04U /* Default State */
266*867cd155SPankaj Dev #define DWC3_LINK_STATE_EARLY_SUS	0x05U /* in HS, means Early Suspend */
267*867cd155SPankaj Dev #define DWC3_LINK_STATE_RESET	0x0eU
268*867cd155SPankaj Dev #define DWC3_LINK_STATE_RESUME	0x0fU
269*867cd155SPankaj Dev 
270*867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_NO_ACTION	0
271*867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_SS_DISABLED	4
272*867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_RX_DETECT	5
273*867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_SS_INACTIVE	6
274*867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_RECOVERY	8
275*867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_COMPLIANCE	10
276*867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_LOOPBACK	11
277*867cd155SPankaj Dev 
278*867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNGREQ(n)	(((n) << USB3_DCTL_ULSTCHNGREQ_POS) & \
279*867cd155SPankaj Dev 					USB3_DCTL_ULSTCHNGREQ_MSK)
280*867cd155SPankaj Dev 
281*867cd155SPankaj Dev #define DWC3_DSTS_USBLNKST(n)	(((n) & USB3_DSTS_USBLNKST_MSK) >> USB3_DSTS_USBLNKST_POS)
282*867cd155SPankaj Dev 
283*867cd155SPankaj Dev /* TRB Length, PCM and Status */
284*867cd155SPankaj Dev #define DWC3_TRB_SIZE_MASK	(0x00ffffffU)
285*867cd155SPankaj Dev #define DWC3_TRB_SIZE_LENGTH(n)	((n) & DWC3_TRB_SIZE_MASK)
286*867cd155SPankaj Dev #define DWC3_TRB_SIZE_PCM1(n)	(((n) & 0x03) << 24)
287*867cd155SPankaj Dev #define DWC3_TRB_SIZE_TRBSTS(n)	(((n) & (0x0fU << 28)) >> 28)
288*867cd155SPankaj Dev 
289*867cd155SPankaj Dev #define DWC3_TRBSTS_OK	0
290*867cd155SPankaj Dev #define DWC3_TRBSTS_MISSED_ISOC	1
291*867cd155SPankaj Dev #define DWC3_TRBSTS_SETUP_PENDING	2
292*867cd155SPankaj Dev #define DWC3_TRBSTS_XFER_IN_PROG	4
293*867cd155SPankaj Dev 
294*867cd155SPankaj Dev /* TRB Control */
295*867cd155SPankaj Dev #define DWC3_TRB_CTRL_HWO	BIT(0)
296*867cd155SPankaj Dev #define DWC3_TRB_CTRL_LST	BIT(1)
297*867cd155SPankaj Dev #define DWC3_TRB_CTRL_CHN	BIT(2)
298*867cd155SPankaj Dev #define DWC3_TRB_CTRL_CSP	BIT(3)
299*867cd155SPankaj Dev #define DWC3_TRB_CTRL_TRBCTL(n)	(((n) & 0x3fU) << 4)
300*867cd155SPankaj Dev #define DWC3_TRB_CTRL_ISP_IMI	BIT(10)
301*867cd155SPankaj Dev #define DWC3_TRB_CTRL_IOC	BIT(11)
302*867cd155SPankaj Dev #define DWC3_TRB_CTRL_SID_SOFN(n)	(((n) & 0xffffU) << 14)
303*867cd155SPankaj Dev 
304*867cd155SPankaj Dev #define DWC3_TRBCTL_NORMAL	DWC3_TRB_CTRL_TRBCTL(1U)
305*867cd155SPankaj Dev #define DWC3_TRBCTL_CONTROL_SETUP	DWC3_TRB_CTRL_TRBCTL(2U)
306*867cd155SPankaj Dev #define DWC3_TRBCTL_CONTROL_STATUS2	DWC3_TRB_CTRL_TRBCTL(3U)
307*867cd155SPankaj Dev #define DWC3_TRBCTL_CONTROL_STATUS3	DWC3_TRB_CTRL_TRBCTL(4U)
308*867cd155SPankaj Dev #define DWC3_TRBCTL_CONTROL_DATA	DWC3_TRB_CTRL_TRBCTL(5U)
309*867cd155SPankaj Dev #define DWC3_TRBCTL_ISOCHRONOUS_FIRST	DWC3_TRB_CTRL_TRBCTL(6U)
310*867cd155SPankaj Dev #define DWC3_TRBCTL_ISOCHRONOUS	DWC3_TRB_CTRL_TRBCTL(7U)
311*867cd155SPankaj Dev #define DWC3_TRBCTL_LINK_TRB	DWC3_TRB_CTRL_TRBCTL(8U)
312*867cd155SPankaj Dev 
313*867cd155SPankaj Dev #define _MASK(len, pos)	GENMASK_32((len-1) + pos, pos)
314*867cd155SPankaj Dev 
315*867cd155SPankaj Dev /* event */
316*867cd155SPankaj Dev #define DWC3_EVT_TYPE_EP	0x0U
317*867cd155SPankaj Dev #define DWC3_EVT_TYPE_LEN	0x1
318*867cd155SPankaj Dev #define DWC3_EVT_TYPE_BITPOS	0x0
319*867cd155SPankaj Dev #define DWC3_EVT_TYPE_MASK	_MASK(DWC3_EVT_TYPE_LEN, DWC3_EVT_TYPE_BITPOS)
320*867cd155SPankaj Dev #define DWC3_EVT_TYPE_DEVSPEC	0x1U
321*867cd155SPankaj Dev #define DWC3_EVT_TYPE_NEP_TYPE_BITPOS	1
322*867cd155SPankaj Dev #define DWC3_EVT_TYPE_NEP_TYPE_LEN	7
323*867cd155SPankaj Dev #define DWC3_EVT_TYPE_NEP_TYPE_MASK	_MASK(DWC3_EVT_TYPE_NEP_TYPE_LEN, \
324*867cd155SPankaj Dev 					      DWC3_EVT_TYPE_NEP_TYPE_BITPOS)
325*867cd155SPankaj Dev 
326*867cd155SPankaj Dev #define DWC3_DEPEVT_XFERCOMPLETE	0x01
327*867cd155SPankaj Dev #define DWC3_DEPEVT_XFERINPROGRESS	0x02
328*867cd155SPankaj Dev #define DWC3_DEPEVT_XFERNOTREADY	0x03
329*867cd155SPankaj Dev #define DWC3_DEPEVT_RXTXFIFOEVT	0x04
330*867cd155SPankaj Dev #define DWC3_DEPEVT_STREAMEVT	0x06
331*867cd155SPankaj Dev #define DWC3_DEPEVT_EPCMDCMPLT	0x07
332*867cd155SPankaj Dev 
333*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_TYPE_BITPOS	6
334*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_TYPE_LEN	4
335*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_TYPE_MASK	_MASK(DWC3_EVT_DEPEVT_TYPE_LEN, DWC3_EVT_DEPEVT_TYPE_BITPOS)
336*867cd155SPankaj Dev 
337*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_EPNUM_BITPOS	1
338*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_EPNUM_LEN	5
339*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_EPNUM_MASK	_MASK(DWC3_EVT_DEPEVT_EPNUM_LEN, \
340*867cd155SPankaj Dev 					      DWC3_EVT_DEPEVT_EPNUM_BITPOS)
341*867cd155SPankaj Dev 
342*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_BITPOS	12
343*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_LEN	4
344*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_MASK	_MASK(DWC3_EVT_DEPEVT_STATUS_LEN, \
345*867cd155SPankaj Dev 					      DWC3_EVT_DEPEVT_STATUS_BITPOS)
346*867cd155SPankaj Dev 
347*867cd155SPankaj Dev /* Control-only Status */
348*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_CONTROL_DATA	1
349*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_CONTROL_STATUS	2
350*867cd155SPankaj Dev 
351*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_PARAM_BITPOS	16
352*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_PARAM_LEN	16
353*867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_PARAM_MASK	_MASK(DWC3_EVT_DEPEVT_PARAM_LEN, \
354*867cd155SPankaj Dev 					      DWC3_EVT_DEPEVT_PARAM_BITPOS)
355*867cd155SPankaj Dev 
356*867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_TYPE_BITPOS	8
357*867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_TYPE_LEN	4
358*867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_TYPE_MASK	_MASK(DWC3_EVT_DEVEVT_TYPE_LEN, DWC3_EVT_DEVEVT_TYPE_BITPOS)
359*867cd155SPankaj Dev 
360*867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_LNKSTS_BITPOS	16
361*867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_LNKSTS_LEN	4
362*867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_LNKSTS_MASK	_MASK(DWC3_EVT_DEVEVT_LNKSTS_LEN, \
363*867cd155SPankaj Dev 					DWC3_EVT_DEVEVT_LNKSTS_BITPOS)
364*867cd155SPankaj Dev 
365*867cd155SPankaj Dev /* Bit fields for USB3_GCTL register */
366*867cd155SPankaj Dev #define USB3_GCTL_CORESOFTRESET	_DWC3_GCTL_CORESOFTRESET
367*867cd155SPankaj Dev #define USB3_GCTL_PRTCAPDIR_POS	_DWC3_GCTL_PRTCAPDIR_SHIFT
368*867cd155SPankaj Dev #define USB3_GCTL_PRTCAPDIR_MSK	_DWC3_GCTL_PRTCAPDIR_MASK
369*867cd155SPankaj Dev 
370*867cd155SPankaj Dev /* Bit fields for USB3_GUSB2PHYCFG register */
371*867cd155SPankaj Dev #define USB3_GUSB2PHYCFG_ULPI_UTMI_SEL	_DWC3_GUSB2PHYCFG_ULPI_UTMI_SEL
372*867cd155SPankaj Dev #define USB3_GUSB2PHYCFG_PHYSOFTRST	_DWC3_GUSB2PHYCFG_PHYSOFTRST
373*867cd155SPankaj Dev 
374*867cd155SPankaj Dev /* Bit fields for USB3_GUSB3PIPECTL register */
375*867cd155SPankaj Dev #define USB3_GUSB3PIPECTL_PHYSOFTRST	_DWC3_GUSB3PIPECTL_PHYSOFTRST
376*867cd155SPankaj Dev 
377*867cd155SPankaj Dev /* Bit fields for USB3_GEVNTSIZ register */
378*867cd155SPankaj Dev #define USB3_GEVNTSIZ_EVNTINTRPTMASK_MSK	_DWC3_GEVNTSIZ_EVNTINTRPTMASK
379*867cd155SPankaj Dev 
380*867cd155SPankaj Dev /* Bit fields for USB3_DCFG register */
381*867cd155SPankaj Dev #define USB3_DCFG_DEVSPD_POS	_DWC3_DCFG_DEVSPD_SHIFT
382*867cd155SPankaj Dev #define USB3_DCFG_DEVSPD_MSK	_DWC3_DCFG_DEVSPD_MASK
383*867cd155SPankaj Dev #define USB3_DCFG_DEVADDR_POS	_DWC3_DCFG_DEVADDR_SHIFT
384*867cd155SPankaj Dev #define USB3_DCFG_DEVADDR_MSK	_DWC3_DCFG_DEVADDR_MASK
385*867cd155SPankaj Dev #define USB3_DCFG_INTRNUM_POS	_DWC3_DCFG_INTRNUM_SHIFT
386*867cd155SPankaj Dev #define USB3_DCFG_INTRNUM_MSK	_DWC3_DCFG_INTRNUM_MASK
387*867cd155SPankaj Dev #define USB3_DCFG_NUMP_POS	_DWC3_DCFG_NUMP_SHIFT
388*867cd155SPankaj Dev #define USB3_DCFG_NUMP_MSK	_DWC3_DCFG_NUMP_MASK
389*867cd155SPankaj Dev #define USB3_DCFG_LPMCAP	_DWC3_DCFG_LPMCAP
390*867cd155SPankaj Dev #define USB3_DCFG_IGNSTRMPP	_DWC3_DCFG_IGNSTRMPP
391*867cd155SPankaj Dev 
392*867cd155SPankaj Dev /* Bit fields for USB3_DCTL register */
393*867cd155SPankaj Dev #define USB3_DCTL_TSTCTL_POS	_DWC3_DCTL_TSTCTL_SHIFT
394*867cd155SPankaj Dev #define USB3_DCTL_TSTCTL_MSK	_DWC3_DCTL_TSTCTL_MASK
395*867cd155SPankaj Dev #define USB3_DCTL_ULSTCHNGREQ_POS	_DWC3_DCTL_ULSTCHNGREQ_SHIFT
396*867cd155SPankaj Dev #define USB3_DCTL_ULSTCHNGREQ_MSK	_DWC3_DCTL_ULSTCHNGREQ_MASK
397*867cd155SPankaj Dev #define USB3_DCTL_ACCEPTU1ENA	_DWC3_DCTL_ACCEPTU1ENA
398*867cd155SPankaj Dev #define USB3_DCTL_INITU1ENA	_DWC3_DCTL_INITU1ENA
399*867cd155SPankaj Dev #define USB3_DCTL_ACCEPTU2ENA	_DWC3_DCTL_ACCEPTU2ENA
400*867cd155SPankaj Dev #define USB3_DCTL_INITU2ENA	_DWC3_DCTL_INITU2ENA
401*867cd155SPankaj Dev #define USB3_DCTL_CSS	_DWC3_DCTL_CSS
402*867cd155SPankaj Dev #define USB3_DCTL_CRS	_DWC3_DCTL_CRS
403*867cd155SPankaj Dev #define USB3_DCTL_L1HIBERNATIONEN	_DWC3_DCTL_L1HIBERNATIONEN
404*867cd155SPankaj Dev #define USB3_DCTL_KEEPCONNECT	_DWC3_DCTL_KEEPCONNECT
405*867cd155SPankaj Dev #define USB3_DCTL_LPM_NYET_THRES_POS	_DWC3_DCTL_LPM_NYET_THRES_SHIFT
406*867cd155SPankaj Dev #define USB3_DCTL_LPM_NYET_THRES_MSK	_DWC3_DCTL_LPM_NYET_THRES_MASK
407*867cd155SPankaj Dev #define USB3_DCTL_HIRDTHRES_POS	_DWC3_DCTL_HIRDTHRES_SHIFT
408*867cd155SPankaj Dev #define USB3_DCTL_HIRDTHRES_MSK	_DWC3_DCTL_HIRDTHRES_MASK
409*867cd155SPankaj Dev #define USB3_DCTL_CSFTRST	_DWC3_DCTL_CSFTRST
410*867cd155SPankaj Dev #define USB3_DCTL_RUN_STOP	_DWC3_DCTL_RUN_STOP
411*867cd155SPankaj Dev 
412*867cd155SPankaj Dev /* Bit fields for USB3_DEVTEN register */
413*867cd155SPankaj Dev #define USB3_DEVTEN_DISSCONNEVTEN	_DWC3_DEVTEN_DISSCONNEVTEN
414*867cd155SPankaj Dev #define USB3_DEVTEN_USBRSTEVTEN	_DWC3_DEVTEN_USBRSTEVTEN
415*867cd155SPankaj Dev #define USB3_DEVTEN_CONNECTDONEEVTEN	_DWC3_DEVTEN_CONNECTDONEEVTEN
416*867cd155SPankaj Dev #define USB3_DEVTEN_ULSTCNGEN	_DWC3_DEVTEN_ULSTCNGEN
417*867cd155SPankaj Dev #define USB3_DEVTEN_WKUPEVTEN	_DWC3_DEVTEN_WKUPEVTEN
418*867cd155SPankaj Dev #define USB3_DEVTEN_HIBERNATIONREQEVTEN	_DWC3_DEVTEN_HIBERNATIONREQEVTEN
419*867cd155SPankaj Dev #define USB3_DEVTEN_U3L2L1SUSPEN	_DWC3_DEVTEN_U3L2L1SUSPEN
420*867cd155SPankaj Dev #define USB3_DEVTEN_SOFTEVTEN	_DWC3_DEVTEN_SOFTEVTEN
421*867cd155SPankaj Dev #define USB3_DEVTEN_L1SUSPEN	_DWC3_DEVTEN_L1SUSPEN
422*867cd155SPankaj Dev #define USB3_DEVTEN_ERRTICERREVTEN	_DWC3_DEVTEN_ERRTICERREVTEN
423*867cd155SPankaj Dev #define USB3_DEVTEN_CMDCMPLTEN	_DWC3_DEVTEN_CMDCMPLTEN
424*867cd155SPankaj Dev #define USB3_DEVTEN_EVNTOVERFLOWEN	_DWC3_DEVTEN_EVNTOVERFLOWEN
425*867cd155SPankaj Dev #define USB3_DEVTEN_VENDEVTSTRCVDEN	_DWC3_DEVTEN_VENDEVTSTRCVDEN
426*867cd155SPankaj Dev #define USB3_DEVTEN_L1WKUPEVTEN	_DWC3_DEVTEN_L1WKUPEVTEN
427*867cd155SPankaj Dev #define USB3_DEVTEN_ECCERREN	_DWC3_DEVTEN_ECCERREN
428*867cd155SPankaj Dev 
429*867cd155SPankaj Dev /* Bit fields for USB3_DSTS register */
430*867cd155SPankaj Dev #define USB3_DSTS_CONNECTSPD_POS	_DWC3_DSTS_CONNECTSPD_SHIFT
431*867cd155SPankaj Dev #define USB3_DSTS_CONNECTSPD_MSK	_DWC3_DSTS_CONNECTSPD_MASK
432*867cd155SPankaj Dev #define USB3_DSTS_CONNECTSPD	_DWC3_DSTS_CONNECTSPD_MASK
433*867cd155SPankaj Dev #define USB3_DSTS_SOFFN_POS	_DWC3_DSTS_SOFFN_SHIFT
434*867cd155SPankaj Dev #define USB3_DSTS_SOFFN_MSK	_DWC3_DSTS_SOFFN_MASK
435*867cd155SPankaj Dev #define USB3_DSTS_RXFIFOEMPTY	_DWC3_DSTS_RXFIFOEMPTY
436*867cd155SPankaj Dev #define USB3_DSTS_USBLNKST_POS	_DWC3_DSTS_USBLNKST_SHIFT
437*867cd155SPankaj Dev #define USB3_DSTS_USBLNKST_MSK	_DWC3_DSTS_USBLNKST_MASK
438*867cd155SPankaj Dev #define USB3_DSTS_DEVCTRLHLT	_DWC3_DSTS_DEVCTRLHLT
439*867cd155SPankaj Dev #define USB3_DSTS_COREIDLE	_DWC3_DSTS_COREIDLE
440*867cd155SPankaj Dev #define USB3_DSTS_SSS	_DWC3_DSTS_SSS
441*867cd155SPankaj Dev #define USB3_DSTS_RSS	_DWC3_DSTS_RSS
442*867cd155SPankaj Dev #define USB3_DSTS_SRE	_DWC3_DSTS_SRE
443*867cd155SPankaj Dev #define USB3_DSTS_DCNRD	_DWC3_DSTS_DCNRD
444*867cd155SPankaj Dev 
445*867cd155SPankaj Dev /* Bit fields for USB3_DGCMD register */
446*867cd155SPankaj Dev #define USB3_DGCMD_CMDTYP_POS	_DWC3_DEPCMD_CMDTYP_SHIFT
447*867cd155SPankaj Dev #define USB3_DGCMD_CMDTYP_MSK	_DWC3_DEPCMD_CMDTYP_MASK
448*867cd155SPankaj Dev #define USB3_DGCMD_CMDIOC	_DWC3_DGCMD_CMDIOC
449*867cd155SPankaj Dev #define USB3_DGCMD_CMDACT	_DWC3_DGCMD_CMDACT
450*867cd155SPankaj Dev #define USB3_DGCMD_CMDSTATUS_POS	_DWC3_DGCMD_CMDSTATUS_SHIFT
451*867cd155SPankaj Dev #define USB3_DGCMD_CMDSTATUS_MSK	_DWC3_DGCMD_CMDSTATUS_MASK
452*867cd155SPankaj Dev 
453*867cd155SPankaj Dev /* Bit fields for USB3_DEPCMD register */
454*867cd155SPankaj Dev #define USB3_DEPCMD_CMDTYP_POS	_DWC3_DEPCMD_CMDTYP_SHIFT
455*867cd155SPankaj Dev #define USB3_DEPCMD_CMDTYP_MSK	_DWC3_DEPCMD_CMDTYP_MASK
456*867cd155SPankaj Dev #define USB3_DEPCMD_CMDTYP	_DWC3_DEPCMD_CMDTYP_MASK
457*867cd155SPankaj Dev #define USB3_DEPCMD_CMDIOC	_DWC3_DEPCMD_CMDIOC
458*867cd155SPankaj Dev #define USB3_DEPCMD_CMDACT	_DWC3_DEPCMD_CMDACT
459*867cd155SPankaj Dev #define USB3_DEPCMD_HIPRI_FORCERM	_DWC3_DEPCMD_HIPRI_FORCERM
460*867cd155SPankaj Dev #define USB3_DEPCMD_CMDSTATUS_POS	_DWC3_DEPCMD_CMDSTATUS_SHIFT
461*867cd155SPankaj Dev #define USB3_DEPCMD_CMDSTATUS_MSK	_DWC3_DEPCMD_CMDSTATUS_MASK
462*867cd155SPankaj Dev #define USB3_DEPCMD_COMMANDPARAM_POS	_DWC3_DEPCMD_COMMANDPARAM_SHIFT
463*867cd155SPankaj Dev #define USB3_DEPCMD_COMMANDPARAM_MSK	_DWC3_DEPCMD_COMMANDPARAM_MASK
464*867cd155SPankaj Dev 
465*867cd155SPankaj Dev /* Bit fields for USB3_DEV_IMOD register */
466*867cd155SPankaj Dev #define USB3_DEV_IMOD_DEVICE_IMODI_POS	_DWC3_DEV_IMOD_DEVICE_IMODI_SHIFT
467*867cd155SPankaj Dev #define USB3_DEV_IMOD_DEVICE_IMODI_MSK	_DWC3_DEV_IMOD_DEVICE_IMODI_MASK
468*867cd155SPankaj Dev #define USB3_DEV_IMOD_DEVICE_IMODC_POS	_DWC3_DEV_IMOD_DEVICE_IMODC_SHIFT
469*867cd155SPankaj Dev #define USB3_DEV_IMOD_DEVICE_IMODC_MSK	_DWC3_DEV_IMOD_DEVICE_IMODC_MASK
470*867cd155SPankaj Dev 
471*867cd155SPankaj Dev #define IS_MULTIPLE(x, a)	(((x) % (a)) == 0U)
472*867cd155SPankaj Dev #define ALIGN_MULTIPLE(x, a)	((a) * (((x) / (a)) + ((((x) % (a)) != 0U) ? 1U : 0U)))
473*867cd155SPankaj Dev #define PAGE_ALIGN(addr, mask)	((addr) & ~(mask))
474*867cd155SPankaj Dev 
475*867cd155SPankaj Dev #define upper_32_bits(n)	((uint32_t)(((n) >> 16) >> 16))
476*867cd155SPankaj Dev #define lower_32_bits(n)	((uint32_t)(n))
477*867cd155SPankaj Dev 
478*867cd155SPankaj Dev /* DWC3 IP Parameter */
479*867cd155SPankaj Dev #define DWC3_IP_DEVICE_NUM_INT	2
480*867cd155SPankaj Dev #define DWC3_IP_NUM_EPS	32U
481*867cd155SPankaj Dev #define DWC3_IP_NUM_IN_EPS	16
482*867cd155SPankaj Dev 
483*867cd155SPankaj Dev /* HAL_PCD defines */
484*867cd155SPankaj Dev #define __HAL_PCD_ENABLE_INTR(__HANDLE__, intr)	usb_dwc3_enable_eventint(__HANDLE__, intr)
485*867cd155SPankaj Dev #define __HAL_PCD_DISABLE_INTR(__HANDLE__, intr)	usb_dwc3_disable_eventint(__HANDLE__, intr)
486*867cd155SPankaj Dev 
487*867cd155SPankaj Dev #define __HAL_PCD_SETUP_REQ_LEN(addr)	(((uint16_t)(*((uint8_t *)(addr) + 6))) + \
488*867cd155SPankaj Dev 						(((uint16_t)(*((uint8_t *)(addr) + 7))) << 8))
489*867cd155SPankaj Dev 
490*867cd155SPankaj Dev #define __HAL_PCD_SETUP_REQ_DATA_DIR_IN(addr)	((*(uint8_t *)(addr)) & EP_DIR_IN)
491*867cd155SPankaj Dev 
492*867cd155SPankaj Dev #define __HAL_PCD_INCR_EVENT_POS(__HANDLE__, intr, incr) \
493*867cd155SPankaj Dev 						(__HANDLE__)->intbuffers.evtbufferpos[intr] = \
494*867cd155SPankaj Dev 						((__HANDLE__)->intbuffers.evtbufferpos[intr] + \
495*867cd155SPankaj Dev 						 (incr)) % USB_DWC3_EVENT_BUFFER_SIZE
496*867cd155SPankaj Dev #define __HAL_PCD_READ_EVENT(__HANDLE__, intr)	*(volatile uint32_t *)&((__HANDLE__)->\
497*867cd155SPankaj Dev 						intbuffers.evtbuffer_addr[intr][(__HANDLE__)->\
498*867cd155SPankaj Dev 						intbuffers.evtbufferpos[intr]])
499*867cd155SPankaj Dev 
500*867cd155SPankaj Dev #define __HAL_PCD_EPADDR_TO_PHYEPNUM(ep_addr)	((2U * ((ep_addr) & ADDRESS_MASK)) + \
501*867cd155SPankaj Dev 						((((ep_addr) & EP_DIR_MASK) != 0U) ? 1U : 0U))
502*867cd155SPankaj Dev #define __HAL_PCD_PHYEPNUM_TO_EPADDR(phy_epnum)	(((phy_epnum) / 2U) | \
503*867cd155SPankaj Dev 						((((phy_epnum) & 0x1U) != 0U) ? EP_DIR_IN : 0U))
504*867cd155SPankaj Dev 
505*867cd155SPankaj Dev #define PCD_DEV_EVENTS_INTR	0 /* Interrupt to use for device events */
506*867cd155SPankaj Dev 
507*867cd155SPankaj Dev #define GET_DWC3EP_FROM_USBEP(__HANDLE__, usb_ep)	*(volatile uint32_t *)&((__HANDLE__)->\
508*867cd155SPankaj Dev 						intbuffers.evtbuffer_addr[intr][(__HANDLE__)->\
509*867cd155SPankaj Dev 						intbuffers.evtbufferpos[intr]])
510*867cd155SPankaj Dev 
511*867cd155SPankaj Dev typedef uint32_t dwc3_epcmd_t;
512*867cd155SPankaj Dev typedef struct {
513*867cd155SPankaj Dev 	uint32_t  param2;
514*867cd155SPankaj Dev 	uint32_t  param1;
515*867cd155SPankaj Dev 	uint32_t  param0;
516*867cd155SPankaj Dev } dwc3_epcmd_params_t;
517*867cd155SPankaj Dev 
518*867cd155SPankaj Dev static uint32_t DWC3_regread(void *base, uint32_t offset)
519*867cd155SPankaj Dev {
520*867cd155SPankaj Dev 	return mmio_read_32((uintptr_t)base + offset);
521*867cd155SPankaj Dev }
522*867cd155SPankaj Dev 
523*867cd155SPankaj Dev static void DWC3_regwrite(void *base, uint32_t offset, uint32_t value)
524*867cd155SPankaj Dev {
525*867cd155SPankaj Dev 	mmio_write_32((uintptr_t)base + offset, value);
526*867cd155SPankaj Dev }
527*867cd155SPankaj Dev 
528*867cd155SPankaj Dev static void DWC3_regupdateset(void *base, uint32_t offset, uint32_t set_mask)
529*867cd155SPankaj Dev {
530*867cd155SPankaj Dev 	mmio_setbits_32((uintptr_t)base + offset, set_mask);
531*867cd155SPankaj Dev }
532*867cd155SPankaj Dev 
533*867cd155SPankaj Dev static void DWC3_regupdateclr(void *base, uint32_t offset, uint32_t clr_mask)
534*867cd155SPankaj Dev {
535*867cd155SPankaj Dev 	mmio_clrbits_32((uintptr_t)base + offset, clr_mask);
536*867cd155SPankaj Dev }
537*867cd155SPankaj Dev 
538*867cd155SPankaj Dev static void usb_dwc3_enable_eventint(dwc3_handle_t *handle, uint8_t intr_num)
539*867cd155SPankaj Dev {
540*867cd155SPankaj Dev 	DWC3_regupdateclr(handle->usb_global, DWC3_GEVNTSIZ(intr_num),
541*867cd155SPankaj Dev 			  USB3_GEVNTSIZ_EVNTINTRPTMASK_MSK);
542*867cd155SPankaj Dev }
543*867cd155SPankaj Dev 
544*867cd155SPankaj Dev static void usb_dwc3_disable_eventint(dwc3_handle_t *handle, uint8_t intr_num)
545*867cd155SPankaj Dev {
546*867cd155SPankaj Dev 	DWC3_regupdateset(handle->usb_global, DWC3_GEVNTSIZ(intr_num),
547*867cd155SPankaj Dev 			  USB3_GEVNTSIZ_EVNTINTRPTMASK_MSK);
548*867cd155SPankaj Dev }
549*867cd155SPankaj Dev 
550*867cd155SPankaj Dev static uintptr_t api_mapdmaaddr(uint8_t buf[], uint32_t size, uint8_t to_device)
551*867cd155SPankaj Dev {
552*867cd155SPankaj Dev 	if (to_device) {
553*867cd155SPankaj Dev 		clean_dcache_range((uintptr_t)buf, size);
554*867cd155SPankaj Dev 	} else {
555*867cd155SPankaj Dev 		inv_dcache_range((uintptr_t)buf, size);
556*867cd155SPankaj Dev 	}
557*867cd155SPankaj Dev 
558*867cd155SPankaj Dev 	return (uintptr_t)buf;
559*867cd155SPankaj Dev }
560*867cd155SPankaj Dev 
561*867cd155SPankaj Dev static void api_unmapdmaaddr(uintptr_t dma_addr __unused, uint32_t size __unused,
562*867cd155SPankaj Dev 			     uint8_t to_device __unused)
563*867cd155SPankaj Dev {
564*867cd155SPankaj Dev }
565*867cd155SPankaj Dev 
566*867cd155SPankaj Dev static uintptr_t api_getdmaaddr(uint8_t buf[], uint32_t size __unused, uint8_t to_device __unused)
567*867cd155SPankaj Dev {
568*867cd155SPankaj Dev 	return (uintptr_t)buf;
569*867cd155SPankaj Dev }
570*867cd155SPankaj Dev 
571*867cd155SPankaj Dev __unused static void api_putdmaaddr(uintptr_t dma_addr __unused, uint32_t size __unused,
572*867cd155SPankaj Dev 				    uint8_t to_device __unused)
573*867cd155SPankaj Dev {
574*867cd155SPankaj Dev }
575*867cd155SPankaj Dev 
576*867cd155SPankaj Dev static void api_memcpy(void *dest, const void *src, uint32_t n)
577*867cd155SPankaj Dev {
578*867cd155SPankaj Dev #ifdef AVOID_COMPILER_MEMCPY
579*867cd155SPankaj Dev 	uint8_t *pcdst = (uint8_t *)dest;
580*867cd155SPankaj Dev 	uint8_t const *pcsrc = (uint8_t const *)src;
581*867cd155SPankaj Dev 
582*867cd155SPankaj Dev 	while (n--) {
583*867cd155SPankaj Dev 		*pcdst++ = *pcsrc++;
584*867cd155SPankaj Dev 	}
585*867cd155SPankaj Dev #else
586*867cd155SPankaj Dev 	(void)memcpy(dest, src, n);
587*867cd155SPankaj Dev #endif
588*867cd155SPankaj Dev }
589*867cd155SPankaj Dev 
590*867cd155SPankaj Dev static uint32_t dwc3_get_trb_ctltype(uint32_t trb_type)
591*867cd155SPankaj Dev {
592*867cd155SPankaj Dev 	uint32_t ret;
593*867cd155SPankaj Dev 
594*867cd155SPankaj Dev 	switch (trb_type) {
595*867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_NORMAL:
596*867cd155SPankaj Dev 		ret = DWC3_TRBCTL_NORMAL;
597*867cd155SPankaj Dev 		break;
598*867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_CONTROL_SETUP:
599*867cd155SPankaj Dev 		ret = DWC3_TRBCTL_CONTROL_SETUP;
600*867cd155SPankaj Dev 		break;
601*867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_CONTROL_STATUS2:
602*867cd155SPankaj Dev 		ret = DWC3_TRBCTL_CONTROL_STATUS2;
603*867cd155SPankaj Dev 		break;
604*867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_CONTROL_STATUS3:
605*867cd155SPankaj Dev 		ret = DWC3_TRBCTL_CONTROL_STATUS3;
606*867cd155SPankaj Dev 		break;
607*867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_CONTROL_DATA:
608*867cd155SPankaj Dev 		ret = DWC3_TRBCTL_CONTROL_DATA;
609*867cd155SPankaj Dev 		break;
610*867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_ISOCHRONOUS_FIRST:
611*867cd155SPankaj Dev 		ret = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
612*867cd155SPankaj Dev 		break;
613*867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_ISOCHRONOUS:
614*867cd155SPankaj Dev 		ret = DWC3_TRBCTL_ISOCHRONOUS;
615*867cd155SPankaj Dev 		break;
616*867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_LINK_TRB:
617*867cd155SPankaj Dev 		ret = DWC3_TRBCTL_LINK_TRB;
618*867cd155SPankaj Dev 		break;
619*867cd155SPankaj Dev 	default:
620*867cd155SPankaj Dev 		ret = 0U;
621*867cd155SPankaj Dev 		break;
622*867cd155SPankaj Dev 	}
623*867cd155SPankaj Dev 
624*867cd155SPankaj Dev 	return ret;
625*867cd155SPankaj Dev }
626*867cd155SPankaj Dev 
627*867cd155SPankaj Dev static inline const char *dwc3_get_ep_cmd_str(uint32_t cmd)
628*867cd155SPankaj Dev {
629*867cd155SPankaj Dev 	const char *ret;
630*867cd155SPankaj Dev 
631*867cd155SPankaj Dev 	switch (cmd & USB3_DEPCMD_CMDTYP_MSK) {
632*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_DEPSTARTCFG:
633*867cd155SPankaj Dev 		ret = "Start New Configuration";
634*867cd155SPankaj Dev 		break;
635*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_ENDTRANSFER:
636*867cd155SPankaj Dev 		ret = "End Transfer";
637*867cd155SPankaj Dev 		break;
638*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_UPDATETRANSFER:
639*867cd155SPankaj Dev 		ret = "Update Transfer";
640*867cd155SPankaj Dev 		break;
641*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_STARTTRANSFER:
642*867cd155SPankaj Dev 		ret = "Start Transfer";
643*867cd155SPankaj Dev 		break;
644*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_CLEARSTALL:
645*867cd155SPankaj Dev 		ret = "Clear Stall";
646*867cd155SPankaj Dev 		break;
647*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_SETSTALL:
648*867cd155SPankaj Dev 		ret = "Set Stall";
649*867cd155SPankaj Dev 		break;
650*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_GETEPSTATE:
651*867cd155SPankaj Dev 		ret = "Get Endpoint State";
652*867cd155SPankaj Dev 		break;
653*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_SETTRANSFRESOURCE:
654*867cd155SPankaj Dev 		ret = "Set Endpoint Transfer Resource";
655*867cd155SPankaj Dev 		break;
656*867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_SETEPCONFIG:
657*867cd155SPankaj Dev 		ret = "Set Endpoint Configuration";
658*867cd155SPankaj Dev 		break;
659*867cd155SPankaj Dev 	default:
660*867cd155SPankaj Dev 		ret = "UNKNOWN command";
661*867cd155SPankaj Dev 		break;
662*867cd155SPankaj Dev 	}
663*867cd155SPankaj Dev 
664*867cd155SPankaj Dev 	return ret;
665*867cd155SPankaj Dev }
666*867cd155SPankaj Dev 
667*867cd155SPankaj Dev static enum usb_status dwc3_execute_dep_cmd(dwc3_handle_t *dwc3_handle, uint8_t phy_epnum,
668*867cd155SPankaj Dev 					    dwc3_epcmd_t cmd, dwc3_epcmd_params_t *params)
669*867cd155SPankaj Dev {
670*867cd155SPankaj Dev 	uint32_t reg;
671*867cd155SPankaj Dev 	uint64_t timeout;
672*867cd155SPankaj Dev 
673*867cd155SPankaj Dev 	VERBOSE("PHYEP%d: cmd '%s' %08x params %08x %08x %08x\n", phy_epnum,
674*867cd155SPankaj Dev 		   dwc3_get_ep_cmd_str(cmd), (uint32_t)cmd, (uint32_t)params->param0,
675*867cd155SPankaj Dev 		   (uint32_t)params->param1, (uint32_t)params->param2);
676*867cd155SPankaj Dev 
677*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DEPCMDPAR0(phy_epnum), params->param0);
678*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DEPCMDPAR1(phy_epnum), params->param1);
679*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DEPCMDPAR2(phy_epnum), params->param2);
680*867cd155SPankaj Dev 
681*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DEPCMD(phy_epnum), cmd | USB3_DEPCMD_CMDACT);
682*867cd155SPankaj Dev 
683*867cd155SPankaj Dev 	timeout = timeout_init_us(500); /* usec */
684*867cd155SPankaj Dev 	do {
685*867cd155SPankaj Dev 		reg = DWC3_regread(dwc3_handle->usb_device, DWC3_DEPCMD(phy_epnum));
686*867cd155SPankaj Dev 		/* "Command Complete" */
687*867cd155SPankaj Dev 		if ((reg & USB3_DEPCMD_CMDACT) == 0U) {
688*867cd155SPankaj Dev 			VERBOSE("Command Complete --> %u PHYEP%u %x\n", DWC3_DEPCMD_STATUS(reg),
689*867cd155SPankaj Dev 				   phy_epnum, reg);
690*867cd155SPankaj Dev 			if (DWC3_DEPCMD_STATUS(reg) != 0U) {
691*867cd155SPankaj Dev 				return USBD_FAIL;
692*867cd155SPankaj Dev 			}
693*867cd155SPankaj Dev 			return USBD_OK;
694*867cd155SPankaj Dev 		}
695*867cd155SPankaj Dev 
696*867cd155SPankaj Dev 		/* Can be called from interrupt context hence cannot wait for Tick */
697*867cd155SPankaj Dev 		if (timeout_elapsed(timeout)) {
698*867cd155SPankaj Dev 			ERROR("TIMEOUT Command Complete --> %u PHYEP%lu %x\n",
699*867cd155SPankaj Dev 				   DWC3_DEPCMD_STATUS(reg), phy_epnum, reg);
700*867cd155SPankaj Dev 			/* "Command Timed Out" */
701*867cd155SPankaj Dev 			return USBD_TIMEOUT;
702*867cd155SPankaj Dev 		}
703*867cd155SPankaj Dev 	} while (true);
704*867cd155SPankaj Dev 
705*867cd155SPankaj Dev 	return USBD_OK;
706*867cd155SPankaj Dev }
707*867cd155SPankaj Dev 
708*867cd155SPankaj Dev static bool dwc3_is_ep_enabled(dwc3_handle_t *dwc3_handle, uint8_t phy_epnum)
709*867cd155SPankaj Dev {
710*867cd155SPankaj Dev 	if ((DWC3_regread(dwc3_handle->usb_device,
711*867cd155SPankaj Dev 			  DWC3_DALEPENA) & DWC3_DALEPENA_EP(phy_epnum)) != 0U) {
712*867cd155SPankaj Dev 		return true;
713*867cd155SPankaj Dev 	}
714*867cd155SPankaj Dev 
715*867cd155SPankaj Dev 	return false;
716*867cd155SPankaj Dev }
717*867cd155SPankaj Dev 
718*867cd155SPankaj Dev static enum usb_status dwc3_ep_start_xfer(dwc3_handle_t *dwc3_handle, struct usbd_ep *ep)
719*867cd155SPankaj Dev {
720*867cd155SPankaj Dev 	enum usb_status ret;
721*867cd155SPankaj Dev 	dwc3_epcmd_t cmd;
722*867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
723*867cd155SPankaj Dev 
724*867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep = ((ep->is_in) ? &dwc3_handle->IN_ep[ep->num] :
725*867cd155SPankaj Dev 					&dwc3_handle->OUT_ep[ep->num]);
726*867cd155SPankaj Dev 
727*867cd155SPankaj Dev 	VERBOSE("%s PHYEP%d %x\n", __func__, dwc3_ep->phy_epnum, dwc3_ep->flags);
728*867cd155SPankaj Dev 
729*867cd155SPankaj Dev 	/* Wait for XferNotReady to get the uF interval to srat ISOC transfers */
730*867cd155SPankaj Dev 	if ((ep->type == EP_TYPE_ISOC) &&
731*867cd155SPankaj Dev 	    ((dwc3_ep->flags & USB_DWC3_EP_ISOC_START_PENDING) == 0U) &&
732*867cd155SPankaj Dev 	    ((dwc3_ep->flags & USB_DWC3_EP_ISOC_STARTED) == 0U)) {
733*867cd155SPankaj Dev 		dwc3_ep->flags |= USB_DWC3_EP_ISOC_START_PENDING;
734*867cd155SPankaj Dev 		VERBOSE("INSIDE IF\n");
735*867cd155SPankaj Dev 		return USBD_OK;
736*867cd155SPankaj Dev 	}
737*867cd155SPankaj Dev 
738*867cd155SPankaj Dev 	if ((ep->type == EP_TYPE_ISOC) &&
739*867cd155SPankaj Dev 	    ((dwc3_ep->flags & USB_DWC3_EP_ISOC_START_PENDING) != 0U)) {
740*867cd155SPankaj Dev 		dwc3_ep->flags &= ~USB_DWC3_EP_ISOC_START_PENDING;
741*867cd155SPankaj Dev 	}
742*867cd155SPankaj Dev 
743*867cd155SPankaj Dev 	dwc3_ep->trb_addr->bpl = lower_32_bits(dwc3_ep->dma_addr);
744*867cd155SPankaj Dev 	dwc3_ep->trb_addr->bph = upper_32_bits(dwc3_ep->dma_addr);
745*867cd155SPankaj Dev 	dwc3_ep->trb_addr->size = DWC3_TRB_SIZE_LENGTH(ep->xfer_len);
746*867cd155SPankaj Dev 	/* also initializes other bits to 0 */
747*867cd155SPankaj Dev 	dwc3_ep->trb_addr->ctrl = dwc3_get_trb_ctltype(dwc3_ep->trb_flag & USB_DWC3_TRBCTL_MASK);
748*867cd155SPankaj Dev 
749*867cd155SPankaj Dev 	dwc3_ep->trb_addr->ctrl |= ((ep->num == 0U) ? DWC3_TRB_CTRL_ISP_IMI : 0U);
750*867cd155SPankaj Dev 
751*867cd155SPankaj Dev 	dwc3_ep->trb_addr->ctrl |= DWC3_TRB_CTRL_IOC;
752*867cd155SPankaj Dev 
753*867cd155SPankaj Dev 	if ((ep->type == EP_TYPE_ISOC) && ((dwc3_ep->flags & USB_DWC3_EP_ISOC_STARTED) != 0U)) {
754*867cd155SPankaj Dev 		cmd = USB_DWC3_DEPCMD_UPDATETRANSFER;
755*867cd155SPankaj Dev 	} else {
756*867cd155SPankaj Dev 		cmd = USB_DWC3_DEPCMD_STARTTRANSFER;
757*867cd155SPankaj Dev 	}
758*867cd155SPankaj Dev 
759*867cd155SPankaj Dev 	if (ep->type != EP_TYPE_ISOC) {
760*867cd155SPankaj Dev 		dwc3_ep->trb_addr->ctrl |= DWC3_TRB_CTRL_LST;
761*867cd155SPankaj Dev 	}
762*867cd155SPankaj Dev 
763*867cd155SPankaj Dev 	dwc3_ep->trb_addr->ctrl |= DWC3_TRB_CTRL_HWO;
764*867cd155SPankaj Dev 
765*867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
766*867cd155SPankaj Dev 
767*867cd155SPankaj Dev 	if ((cmd & USB3_DEPCMD_CMDTYP_MSK) == USB_DWC3_DEPCMD_STARTTRANSFER) {
768*867cd155SPankaj Dev 		params.param0 = upper_32_bits(dwc3_ep->trb_dma_addr);
769*867cd155SPankaj Dev 		params.param1 = lower_32_bits(dwc3_ep->trb_dma_addr);
770*867cd155SPankaj Dev 	}
771*867cd155SPankaj Dev 
772*867cd155SPankaj Dev 	dwc3_ep->flags |= USB_DWC3_EP_REQ_QUEUED;
773*867cd155SPankaj Dev 	if ((ep->type == EP_TYPE_ISOC) &&
774*867cd155SPankaj Dev 	    ((cmd & USB3_DEPCMD_CMDTYP_MSK) == USB_DWC3_DEPCMD_STARTTRANSFER)) {
775*867cd155SPankaj Dev 		dwc3_ep->flags |= USB_DWC3_EP_ISOC_STARTED;
776*867cd155SPankaj Dev 	}
777*867cd155SPankaj Dev 
778*867cd155SPankaj Dev 	VERBOSE("EP%d%s: trb %p:%08x:%08x:%08x:%08x length %u %d\n",
779*867cd155SPankaj Dev 		   ep->num, ep->is_in ? "IN" : "OUT", dwc3_ep->trb_addr,
780*867cd155SPankaj Dev 		   (uint32_t)dwc3_ep->trb_addr->bph, (uint32_t)dwc3_ep->trb_addr->bpl,
781*867cd155SPankaj Dev 		   (uint32_t)dwc3_ep->trb_addr->size, (uint32_t)dwc3_ep->trb_addr->ctrl,
782*867cd155SPankaj Dev 		   ep->xfer_len, dwc3_ep->flags);
783*867cd155SPankaj Dev 
784*867cd155SPankaj Dev 	ret = dwc3_execute_dep_cmd(dwc3_handle, dwc3_ep->phy_epnum, cmd, &params);
785*867cd155SPankaj Dev 	if (ret != USBD_OK) {
786*867cd155SPankaj Dev 		dwc3_ep->flags &= ~USB_DWC3_EP_REQ_QUEUED;
787*867cd155SPankaj Dev 		if ((ep->type == EP_TYPE_ISOC) &&
788*867cd155SPankaj Dev 		    ((cmd & USB3_DEPCMD_CMDTYP_MSK) == USB_DWC3_DEPCMD_STARTTRANSFER)) {
789*867cd155SPankaj Dev 			dwc3_ep->flags &= ~USB_DWC3_EP_ISOC_STARTED;
790*867cd155SPankaj Dev 		}
791*867cd155SPankaj Dev 		return ret;
792*867cd155SPankaj Dev 	}
793*867cd155SPankaj Dev 
794*867cd155SPankaj Dev 	if ((cmd & USB3_DEPCMD_CMDTYP_MSK) == USB_DWC3_DEPCMD_STARTTRANSFER) {
795*867cd155SPankaj Dev 		dwc3_ep->resc_idx =
796*867cd155SPankaj Dev 		(uint8_t)DWC3_DEPCMD_GET_RSC_IDX(DWC3_regread(dwc3_handle->usb_device,
797*867cd155SPankaj Dev 							      DWC3_DEPCMD(dwc3_ep->phy_epnum)));
798*867cd155SPankaj Dev 	}
799*867cd155SPankaj Dev 
800*867cd155SPankaj Dev 	return ret;
801*867cd155SPankaj Dev }
802*867cd155SPankaj Dev 
803*867cd155SPankaj Dev static enum usb_status usb_dwc3_ep_start_xfer(void *handle, struct usbd_ep *ep)
804*867cd155SPankaj Dev {
805*867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
806*867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep = ((ep->is_in) ? &dwc3_handle->IN_ep[ep->num] :
807*867cd155SPankaj Dev 					&dwc3_handle->OUT_ep[ep->num]);
808*867cd155SPankaj Dev 	uint32_t len = ep->xfer_len;
809*867cd155SPankaj Dev 
810*867cd155SPankaj Dev 	if (!dwc3_is_ep_enabled(dwc3_handle, dwc3_ep->phy_epnum) && ep->num != 0U) {
811*867cd155SPankaj Dev 		return USBD_FAIL;
812*867cd155SPankaj Dev 	}
813*867cd155SPankaj Dev 
814*867cd155SPankaj Dev 	if (!ep->is_in) {
815*867cd155SPankaj Dev 		if ((len > ep->maxpacket) && !IS_MULTIPLE(len, ep->maxpacket)) {
816*867cd155SPankaj Dev 			VERBOSE("Packet size exceeds Max_packet and is not an multiple of it\n");
817*867cd155SPankaj Dev 		}
818*867cd155SPankaj Dev 
819*867cd155SPankaj Dev 		/*setup and start the Xfer */
820*867cd155SPankaj Dev 		if ((len != 0U) && (len < ep->maxpacket)) {
821*867cd155SPankaj Dev 			dwc3_ep->xfer_dest_buff = ep->xfer_buff;
822*867cd155SPankaj Dev 			dwc3_ep->xfer_dest_len = ep->xfer_len;
823*867cd155SPankaj Dev 			ep->xfer_buff = dwc3_ep->bounce_buf;
824*867cd155SPankaj Dev 			ep->xfer_len = ALIGN_MULTIPLE(len, ep->maxpacket);
825*867cd155SPankaj Dev 		} else {
826*867cd155SPankaj Dev //			ep->xfer_buff = pBuf;
827*867cd155SPankaj Dev 			ep->xfer_len = ALIGN_MULTIPLE(len, ep->maxpacket);
828*867cd155SPankaj Dev 		}
829*867cd155SPankaj Dev 	}
830*867cd155SPankaj Dev 
831*867cd155SPankaj Dev 	dwc3_ep->dma_addr = ((ep->xfer_buff != 0) ?
832*867cd155SPankaj Dev 			     api_mapdmaaddr(ep->xfer_buff, ep->xfer_len, ep->is_in ? 1 : 0) :
833*867cd155SPankaj Dev 			     0x0U);
834*867cd155SPankaj Dev 
835*867cd155SPankaj Dev 	if (ep->num == 0U) {
836*867cd155SPankaj Dev 		/* For Status ZLP packet */
837*867cd155SPankaj Dev 		if (len == 0U) {
838*867cd155SPankaj Dev 			/* 2-stage/3-stage control transfer */
839*867cd155SPankaj Dev 			if (__HAL_PCD_SETUP_REQ_LEN(dwc3_handle->setup_addr) == 0U) {
840*867cd155SPankaj Dev 				dwc3_ep->trb_flag = USB_DWC3_TRBCTL_CONTROL_STATUS2;
841*867cd155SPankaj Dev 			} else {
842*867cd155SPankaj Dev 				dwc3_ep->trb_flag = USB_DWC3_TRBCTL_CONTROL_STATUS3;
843*867cd155SPankaj Dev 			}
844*867cd155SPankaj Dev 			//udelay(10);
845*867cd155SPankaj Dev 		} else {
846*867cd155SPankaj Dev 			dwc3_ep->trb_flag = USB_DWC3_TRBCTL_CONTROL_DATA;
847*867cd155SPankaj Dev 		}
848*867cd155SPankaj Dev 	} else {
849*867cd155SPankaj Dev 		if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK)) {
850*867cd155SPankaj Dev 			dwc3_ep->trb_flag = USB_DWC3_TRBCTL_NORMAL;
851*867cd155SPankaj Dev 		} else {
852*867cd155SPankaj Dev 			dwc3_ep->trb_flag = USB_DWC3_TRBCTL_ISOCHRONOUS_FIRST;
853*867cd155SPankaj Dev 		}
854*867cd155SPankaj Dev 	}
855*867cd155SPankaj Dev 
856*867cd155SPankaj Dev 	return dwc3_ep_start_xfer(dwc3_handle, ep);
857*867cd155SPankaj Dev }
858*867cd155SPankaj Dev 
859*867cd155SPankaj Dev static enum usb_status dwc3_ep0_out_start(dwc3_handle_t *dwc3_handle, uintptr_t setup_buf_dma_addr)
860*867cd155SPankaj Dev {
861*867cd155SPankaj Dev 	dwc3_handle->OUT_ep[0].dma_addr = setup_buf_dma_addr;
862*867cd155SPankaj Dev 	dwc3_handle->pcd_handle->out_ep[0].xfer_len = 8;
863*867cd155SPankaj Dev 	dwc3_handle->OUT_ep[0].trb_flag = USB_DWC3_TRBCTL_CONTROL_SETUP;
864*867cd155SPankaj Dev 
865*867cd155SPankaj Dev 	return dwc3_ep_start_xfer(dwc3_handle, &dwc3_handle->pcd_handle->out_ep[0]);
866*867cd155SPankaj Dev }
867*867cd155SPankaj Dev 
868*867cd155SPankaj Dev static enum usb_status usb_dwc3_ep0_out_start(void *handle)
869*867cd155SPankaj Dev {
870*867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
871*867cd155SPankaj Dev 
872*867cd155SPankaj Dev 	dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
873*867cd155SPankaj Dev 	return dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
874*867cd155SPankaj Dev }
875*867cd155SPankaj Dev 
876*867cd155SPankaj Dev static enum usb_status usb_dwc3_start_device(void *handle)
877*867cd155SPankaj Dev {
878*867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
879*867cd155SPankaj Dev 	enum usb_status ret;
880*867cd155SPankaj Dev 
881*867cd155SPankaj Dev 	if (dwc3_handle->EP0_State != HAL_PCD_EP0_SETUP_QUEUED) {
882*867cd155SPankaj Dev 		dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
883*867cd155SPankaj Dev 
884*867cd155SPankaj Dev 		ret = dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
885*867cd155SPankaj Dev 		if (ret != USBD_OK) {
886*867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
887*867cd155SPankaj Dev 			return ret;
888*867cd155SPankaj Dev 		}
889*867cd155SPankaj Dev 	}
890*867cd155SPankaj Dev 
891*867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_device, DWC3_DCTL, USB3_DCTL_RUN_STOP);
892*867cd155SPankaj Dev 
893*867cd155SPankaj Dev 	return USBD_OK;
894*867cd155SPankaj Dev }
895*867cd155SPankaj Dev 
896*867cd155SPankaj Dev static inline void dwc3_ack_evt_count(dwc3_handle_t *dwc3_handle, uint8_t intr_num,
897*867cd155SPankaj Dev 				      uint32_t evt_count)
898*867cd155SPankaj Dev {
899*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTCOUNT(intr_num), evt_count);
900*867cd155SPankaj Dev }
901*867cd155SPankaj Dev 
902*867cd155SPankaj Dev static inline uint32_t dwc3_read_intr_count(dwc3_handle_t *dwc3_handle, uint8_t intr_num)
903*867cd155SPankaj Dev {
904*867cd155SPankaj Dev 	return DWC3_regread(dwc3_handle->usb_global, DWC3_GEVNTCOUNT(intr_num)) &
905*867cd155SPankaj Dev 	       DWC3_GEVNTCOUNT_MASK;
906*867cd155SPankaj Dev }
907*867cd155SPankaj Dev 
908*867cd155SPankaj Dev static enum usb_status dwc3_ep_stop_xfer(dwc3_handle_t *dwc3_handle, struct usbd_ep *ep)
909*867cd155SPankaj Dev {
910*867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep = ((ep->is_in) ? &dwc3_handle->IN_ep[ep->num] :
911*867cd155SPankaj Dev 					&dwc3_handle->OUT_ep[ep->num]);
912*867cd155SPankaj Dev 	enum usb_status ret;
913*867cd155SPankaj Dev 	dwc3_epcmd_t cmd;
914*867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
915*867cd155SPankaj Dev 
916*867cd155SPankaj Dev 	VERBOSE("%s PHYEP%d %x\n", __func__, dwc3_ep->phy_epnum, dwc3_ep->flags);
917*867cd155SPankaj Dev 
918*867cd155SPankaj Dev 	/* Reset ISOC flags */
919*867cd155SPankaj Dev 	if (ep->type == EP_TYPE_ISOC) {
920*867cd155SPankaj Dev 		dwc3_ep->flags &= ~(USB_DWC3_EP_ISOC_START_PENDING | USB_DWC3_EP_ISOC_STARTED);
921*867cd155SPankaj Dev 	}
922*867cd155SPankaj Dev 
923*867cd155SPankaj Dev 	if ((dwc3_ep->flags & USB_DWC3_EP_REQ_QUEUED) == 0U) {
924*867cd155SPankaj Dev 		return USBD_FAIL;
925*867cd155SPankaj Dev 	}
926*867cd155SPankaj Dev 
927*867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
928*867cd155SPankaj Dev 	cmd = USB_DWC3_DEPCMD_ENDTRANSFER | USB3_DEPCMD_HIPRI_FORCERM | USB3_DEPCMD_CMDIOC |
929*867cd155SPankaj Dev 	      DWC3_DEPCMD_PARAM((uint32_t)dwc3_ep->resc_idx);
930*867cd155SPankaj Dev 
931*867cd155SPankaj Dev 	ret = dwc3_execute_dep_cmd(dwc3_handle, dwc3_ep->phy_epnum, cmd, &params);
932*867cd155SPankaj Dev 	/* Need Delay 100us as mentioned in Linux Driver */
933*867cd155SPankaj Dev 	udelay(100);
934*867cd155SPankaj Dev 
935*867cd155SPankaj Dev 	ep->xfer_count = ep->xfer_len - (dwc3_ep->trb_addr->size & DWC3_TRB_SIZE_MASK);
936*867cd155SPankaj Dev 
937*867cd155SPankaj Dev 	dwc3_ep->flags &= ~USB_DWC3_EP_REQ_QUEUED;
938*867cd155SPankaj Dev 
939*867cd155SPankaj Dev 	if ((!ep->is_in) && (ep->num == 0U)) {
940*867cd155SPankaj Dev 		dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_COMPLETED;
941*867cd155SPankaj Dev 	}
942*867cd155SPankaj Dev 
943*867cd155SPankaj Dev 	return ret;
944*867cd155SPankaj Dev }
945*867cd155SPankaj Dev 
946*867cd155SPankaj Dev static enum usb_status dwc3_ep_set_stall(dwc3_handle_t *dwc3_handle,
947*867cd155SPankaj Dev 					 const usb_dwc3_endpoint_t *dwc3_ep)
948*867cd155SPankaj Dev {
949*867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
950*867cd155SPankaj Dev 
951*867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
952*867cd155SPankaj Dev 
953*867cd155SPankaj Dev 	return dwc3_execute_dep_cmd(dwc3_handle, dwc3_ep->phy_epnum, USB_DWC3_DEPCMD_SETSTALL,
954*867cd155SPankaj Dev 				    &params);
955*867cd155SPankaj Dev }
956*867cd155SPankaj Dev 
957*867cd155SPankaj Dev static enum usb_status usb_dwc3_stop_device(void *handle)
958*867cd155SPankaj Dev {
959*867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
960*867cd155SPankaj Dev 	uint64_t timeout;
961*867cd155SPankaj Dev 	uint8_t i;
962*867cd155SPankaj Dev 	uint32_t evtcnt;
963*867cd155SPankaj Dev 	enum usb_status ret;
964*867cd155SPankaj Dev 
965*867cd155SPankaj Dev 	/*
966*867cd155SPankaj Dev 	 * Stop transfers for all(USB_DWC3_NUM_IN_EPS) EP
967*867cd155SPankaj Dev 	 * except EP0IN k = USB_DWC3_NUM_IN_EP
968*867cd155SPankaj Dev 	 */
969*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_NUM_IN_EP; i++) {
970*867cd155SPankaj Dev 		dwc3_ep_stop_xfer(dwc3_handle, &dwc3_handle->pcd_handle->in_ep[i]);
971*867cd155SPankaj Dev 	}
972*867cd155SPankaj Dev 
973*867cd155SPankaj Dev 	/* Stop transfers for all EP except EP0OUT k = USB_DWC3_NUM_OUT_EP */
974*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_NUM_OUT_EP; i++) {
975*867cd155SPankaj Dev 		dwc3_ep_stop_xfer(dwc3_handle, &dwc3_handle->pcd_handle->out_ep[i]);
976*867cd155SPankaj Dev 	}
977*867cd155SPankaj Dev 
978*867cd155SPankaj Dev 	/* Issue SetStall on EP0 to reset Ctrl-EP state machine */
979*867cd155SPankaj Dev 	ret = dwc3_ep_set_stall(dwc3_handle, &dwc3_handle->OUT_ep[0]);
980*867cd155SPankaj Dev 	if (ret != USBD_OK) {
981*867cd155SPankaj Dev 		ERROR("%s: EP0 stall failed %u\n", __func__, ret);
982*867cd155SPankaj Dev 	}
983*867cd155SPankaj Dev 
984*867cd155SPankaj Dev 	/*
985*867cd155SPankaj Dev 	 * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
986*867cd155SPankaj Dev 	 * Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the
987*867cd155SPankaj Dev 	 * "software needs to acknowledge the events that are generated
988*867cd155SPankaj Dev 	 * (by writing to GEVNTCOUNTn) while it is waiting for this bit
989*867cd155SPankaj Dev 	 * to be set to '1'."
990*867cd155SPankaj Dev 	 */
991*867cd155SPankaj Dev 
992*867cd155SPankaj Dev 	/* Check for all Event Buffer interrupt k = USB_DWC3_INT_INUSE */
993*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
994*867cd155SPankaj Dev 		evtcnt = dwc3_read_intr_count(dwc3_handle, i);
995*867cd155SPankaj Dev 
996*867cd155SPankaj Dev 		if (!evtcnt) {
997*867cd155SPankaj Dev 			continue;
998*867cd155SPankaj Dev 		}
999*867cd155SPankaj Dev 
1000*867cd155SPankaj Dev 		__HAL_PCD_INCR_EVENT_POS(dwc3_handle, i, evtcnt);
1001*867cd155SPankaj Dev 
1002*867cd155SPankaj Dev 		dwc3_ack_evt_count(dwc3_handle, i, evtcnt);
1003*867cd155SPankaj Dev 	}
1004*867cd155SPankaj Dev 
1005*867cd155SPankaj Dev 
1006*867cd155SPankaj Dev 	DWC3_regupdateclr(dwc3_handle->usb_device, DWC3_DCTL, USB3_DCTL_RUN_STOP);
1007*867cd155SPankaj Dev 
1008*867cd155SPankaj Dev 	timeout = timeout_init_us(500); /* usec */
1009*867cd155SPankaj Dev 
1010*867cd155SPankaj Dev 	while ((DWC3_regread(dwc3_handle->usb_device, DWC3_DSTS) &
1011*867cd155SPankaj Dev 		     USB3_DSTS_DEVCTRLHLT) == 0U) {
1012*867cd155SPankaj Dev 		/* Can be called from interrupt context hence cannot wait for Tick */
1013*867cd155SPankaj Dev 		if (timeout_elapsed(timeout)) { /* "Reset Timed Out" */
1014*867cd155SPankaj Dev 			ERROR("TIMEOUT Stop Device\n");
1015*867cd155SPankaj Dev 			return USBD_TIMEOUT;
1016*867cd155SPankaj Dev 		}
1017*867cd155SPankaj Dev 	}
1018*867cd155SPankaj Dev 
1019*867cd155SPankaj Dev 	// "Halt Complete"
1020*867cd155SPankaj Dev 
1021*867cd155SPankaj Dev 	return USBD_OK;
1022*867cd155SPankaj Dev }
1023*867cd155SPankaj Dev 
1024*867cd155SPankaj Dev static enum usb_status usb_dwc3_set_address(void *handle, uint8_t address)
1025*867cd155SPankaj Dev {
1026*867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
1027*867cd155SPankaj Dev 
1028*867cd155SPankaj Dev 	VERBOSE("%s: %d\n", __func__, address);
1029*867cd155SPankaj Dev 
1030*867cd155SPankaj Dev 	/* set device address */
1031*867cd155SPankaj Dev 	DWC3_regupdateclr(dwc3_handle->usb_device, DWC3_DCFG, USB3_DCFG_DEVADDR_MSK);
1032*867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_device, DWC3_DCFG, DWC3_DCFG_DEVADDR((uint32_t)address));
1033*867cd155SPankaj Dev 
1034*867cd155SPankaj Dev 	return USBD_OK;
1035*867cd155SPankaj Dev }
1036*867cd155SPankaj Dev 
1037*867cd155SPankaj Dev static enum usb_status usb_dwc3_ep0_start_xfer(void *handle, struct usbd_ep *ep)
1038*867cd155SPankaj Dev {
1039*867cd155SPankaj Dev 	return usb_dwc3_ep_start_xfer(handle, ep);
1040*867cd155SPankaj Dev }
1041*867cd155SPankaj Dev 
1042*867cd155SPankaj Dev static enum usb_status usb_dwc3_ep_set_stall(void *handle, struct usbd_ep *ep)
1043*867cd155SPankaj Dev {
1044*867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
1045*867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep = ((ep->is_in) ? &dwc3_handle->IN_ep[ep->num] :
1046*867cd155SPankaj Dev 					&dwc3_handle->OUT_ep[ep->num]);
1047*867cd155SPankaj Dev 
1048*867cd155SPankaj Dev 	if (dwc3_ep->is_stall) {
1049*867cd155SPankaj Dev 		return USBD_OK;
1050*867cd155SPankaj Dev 	}
1051*867cd155SPankaj Dev 
1052*867cd155SPankaj Dev 	dwc3_ep->is_stall = true;
1053*867cd155SPankaj Dev 
1054*867cd155SPankaj Dev 	return dwc3_ep_set_stall(dwc3_handle, dwc3_ep);
1055*867cd155SPankaj Dev }
1056*867cd155SPankaj Dev 
1057*867cd155SPankaj Dev static uint8_t dwc3_read_ep_evt_type(uint32_t event)
1058*867cd155SPankaj Dev {
1059*867cd155SPankaj Dev 	uint8_t ret;
1060*867cd155SPankaj Dev 
1061*867cd155SPankaj Dev 	switch ((event & DWC3_EVT_DEPEVT_TYPE_MASK) >> DWC3_EVT_DEPEVT_TYPE_BITPOS) {
1062*867cd155SPankaj Dev 	case DWC3_DEPEVT_XFERCOMPLETE:
1063*867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_XFERCOMPLETE;
1064*867cd155SPankaj Dev 		break;
1065*867cd155SPankaj Dev 	case DWC3_DEPEVT_XFERINPROGRESS:
1066*867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_XFERINPROGRESS;
1067*867cd155SPankaj Dev 		break;
1068*867cd155SPankaj Dev 	case DWC3_DEPEVT_XFERNOTREADY:
1069*867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_XFERNOTREADY;
1070*867cd155SPankaj Dev 		break;
1071*867cd155SPankaj Dev 	case DWC3_DEPEVT_RXTXFIFOEVT:
1072*867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_RXTXFIFOEVT;
1073*867cd155SPankaj Dev 		break;
1074*867cd155SPankaj Dev 	case DWC3_DEPEVT_STREAMEVT:
1075*867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_STREAMEVT;
1076*867cd155SPankaj Dev 		break;
1077*867cd155SPankaj Dev 	case DWC3_DEPEVT_EPCMDCMPLT:
1078*867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_EPCMDCMPLT;
1079*867cd155SPankaj Dev 		break;
1080*867cd155SPankaj Dev 	default:
1081*867cd155SPankaj Dev 		ret = (event & DWC3_EVT_DEPEVT_TYPE_MASK) >> DWC3_EVT_DEPEVT_TYPE_BITPOS;
1082*867cd155SPankaj Dev 		break;
1083*867cd155SPankaj Dev 	}
1084*867cd155SPankaj Dev 
1085*867cd155SPankaj Dev 	return ret;
1086*867cd155SPankaj Dev }
1087*867cd155SPankaj Dev 
1088*867cd155SPankaj Dev static uint8_t dwc3_read_ep_evt_epnum(uint32_t event)
1089*867cd155SPankaj Dev {
1090*867cd155SPankaj Dev 	return (uint8_t)((event & DWC3_EVT_DEPEVT_EPNUM_MASK) >> DWC3_EVT_DEPEVT_EPNUM_BITPOS);
1091*867cd155SPankaj Dev }
1092*867cd155SPankaj Dev 
1093*867cd155SPankaj Dev static uint8_t dwc3_read_ep_evt_status(uint32_t event)
1094*867cd155SPankaj Dev {
1095*867cd155SPankaj Dev 	uint8_t ret;
1096*867cd155SPankaj Dev 
1097*867cd155SPankaj Dev 	switch ((event & DWC3_EVT_DEPEVT_STATUS_MASK) >> DWC3_EVT_DEPEVT_STATUS_BITPOS) {
1098*867cd155SPankaj Dev 	case DWC3_EVT_DEPEVT_STATUS_CONTROL_DATA:
1099*867cd155SPankaj Dev 		ret = USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_DATA;
1100*867cd155SPankaj Dev 		break;
1101*867cd155SPankaj Dev 	case DWC3_EVT_DEPEVT_STATUS_CONTROL_STATUS:
1102*867cd155SPankaj Dev 		ret = USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_STATUS;
1103*867cd155SPankaj Dev 		break;
1104*867cd155SPankaj Dev 	default:
1105*867cd155SPankaj Dev 		ret = (event & DWC3_EVT_DEPEVT_STATUS_MASK) >> DWC3_EVT_DEPEVT_STATUS_BITPOS;
1106*867cd155SPankaj Dev 		break;
1107*867cd155SPankaj Dev 	}
1108*867cd155SPankaj Dev 
1109*867cd155SPankaj Dev 	return ret;
1110*867cd155SPankaj Dev }
1111*867cd155SPankaj Dev 
1112*867cd155SPankaj Dev static enum usb_status dwc3_epaddr_set_stall(dwc3_handle_t *dwc3_handle, uint8_t ep_addr)
1113*867cd155SPankaj Dev {
1114*867cd155SPankaj Dev 	struct usbd_ep *ep;
1115*867cd155SPankaj Dev 	enum usb_status ret;
1116*867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep;
1117*867cd155SPankaj Dev 
1118*867cd155SPankaj Dev 	if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {
1119*867cd155SPankaj Dev 		ep = &dwc3_handle->pcd_handle->in_ep[ep_addr & ADDRESS_MASK];
1120*867cd155SPankaj Dev 		dwc3_ep = &dwc3_handle->IN_ep[ep_addr & ADDRESS_MASK];
1121*867cd155SPankaj Dev 	} else {
1122*867cd155SPankaj Dev 		ep = &dwc3_handle->pcd_handle->out_ep[ep_addr];
1123*867cd155SPankaj Dev 		dwc3_ep = &dwc3_handle->OUT_ep[ep_addr];
1124*867cd155SPankaj Dev 	}
1125*867cd155SPankaj Dev 
1126*867cd155SPankaj Dev 	/* For control endpoints, the application issues only the Set Stall command, and only on the
1127*867cd155SPankaj Dev 	 * OUT direction of the control endpoint. The controller automatically clears the STALL when
1128*867cd155SPankaj Dev 	 * it receives a SETUP token for the endpoint. The application must not issue the Clear
1129*867cd155SPankaj Dev 	 * Stall command on a control endpoint
1130*867cd155SPankaj Dev 	 */
1131*867cd155SPankaj Dev 	if (ep_addr == EP0_IN) {
1132*867cd155SPankaj Dev 		return USBD_OK;
1133*867cd155SPankaj Dev 	}
1134*867cd155SPankaj Dev 
1135*867cd155SPankaj Dev 	if (dwc3_ep->is_stall) {
1136*867cd155SPankaj Dev 		return USBD_OK;
1137*867cd155SPankaj Dev 	}
1138*867cd155SPankaj Dev 
1139*867cd155SPankaj Dev 	dwc3_ep->is_stall = true;
1140*867cd155SPankaj Dev 	ep->num   = ep_addr & ADDRESS_MASK;
1141*867cd155SPankaj Dev 	ep->is_in = ((ep_addr & EP_DIR_MASK) == EP_DIR_IN);
1142*867cd155SPankaj Dev 
1143*867cd155SPankaj Dev 	ret = dwc3_ep_set_stall(dwc3_handle, dwc3_ep);
1144*867cd155SPankaj Dev 	if (ret != USBD_OK) {
1145*867cd155SPankaj Dev 		return ret;
1146*867cd155SPankaj Dev 	}
1147*867cd155SPankaj Dev 
1148*867cd155SPankaj Dev 	if ((ep_addr & ADDRESS_MASK) == 0U) {
1149*867cd155SPankaj Dev 		dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
1150*867cd155SPankaj Dev 		ret = dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
1151*867cd155SPankaj Dev 	}
1152*867cd155SPankaj Dev 
1153*867cd155SPankaj Dev 	return ret;
1154*867cd155SPankaj Dev }
1155*867cd155SPankaj Dev 
1156*867cd155SPankaj Dev static uint32_t dwc3_get_ep_trblen(usb_dwc3_endpoint_t *ep)
1157*867cd155SPankaj Dev {
1158*867cd155SPankaj Dev 	return DWC3_TRB_SIZE_LENGTH(ep->trb_addr->size);
1159*867cd155SPankaj Dev }
1160*867cd155SPankaj Dev 
1161*867cd155SPankaj Dev static uint32_t dwc3_get_ep_trbstatus(usb_dwc3_endpoint_t *ep)
1162*867cd155SPankaj Dev {
1163*867cd155SPankaj Dev 	return DWC3_TRB_SIZE_TRBSTS(ep->trb_addr->size);
1164*867cd155SPankaj Dev }
1165*867cd155SPankaj Dev 
1166*867cd155SPankaj Dev static enum usb_action dwc3_handle_ep0_xfernotready_event(dwc3_handle_t *dwc3_handle,
1167*867cd155SPankaj Dev 							  uint32_t event, uint32_t *param)
1168*867cd155SPankaj Dev {
1169*867cd155SPankaj Dev 	enum usb_action action = USB_NOTHING;
1170*867cd155SPankaj Dev 	uint8_t phy_epnum = dwc3_read_ep_evt_epnum(event);
1171*867cd155SPankaj Dev 	struct pcd_handle *pcd_handle = dwc3_handle->pcd_handle;
1172*867cd155SPankaj Dev 	uint8_t status = dwc3_read_ep_evt_status(event);
1173*867cd155SPankaj Dev 	uint8_t ep_addr, ep_num;
1174*867cd155SPankaj Dev 	enum usb_status ret;
1175*867cd155SPankaj Dev 
1176*867cd155SPankaj Dev 	ep_addr = __HAL_PCD_PHYEPNUM_TO_EPADDR(phy_epnum);
1177*867cd155SPankaj Dev 	ep_num = ep_addr & ADDRESS_MASK;
1178*867cd155SPankaj Dev 
1179*867cd155SPankaj Dev 	if (__HAL_PCD_SETUP_REQ_LEN(dwc3_handle->setup_addr) == 0U) {
1180*867cd155SPankaj Dev 		switch (status) {
1181*867cd155SPankaj Dev 		case USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_STATUS:
1182*867cd155SPankaj Dev 			api_memcpy(dwc3_handle->pcd_handle->setup,
1183*867cd155SPankaj Dev 				   dwc3_handle->setup_addr,
1184*867cd155SPankaj Dev 				   sizeof(dwc3_handle->pcd_handle->setup));
1185*867cd155SPankaj Dev 			action = USB_SETUP;
1186*867cd155SPankaj Dev 			break;
1187*867cd155SPankaj Dev 		case USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_DATA:
1188*867cd155SPankaj Dev 			ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num); // OUT EP0
1189*867cd155SPankaj Dev 			if (ret != USBD_OK) {
1190*867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1191*867cd155SPankaj Dev 			}
1192*867cd155SPankaj Dev 			break;
1193*867cd155SPankaj Dev 		default:
1194*867cd155SPankaj Dev 			VERBOSE("Invalid Status %d: %s: %d\n", status, __func__, __LINE__);
1195*867cd155SPankaj Dev 			break;
1196*867cd155SPankaj Dev 		}
1197*867cd155SPankaj Dev 	} else {
1198*867cd155SPankaj Dev 		switch (status) {
1199*867cd155SPankaj Dev 		case USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_STATUS:
1200*867cd155SPankaj Dev 			if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {
1201*867cd155SPankaj Dev 				*param = ep_num;
1202*867cd155SPankaj Dev 				action = USB_DATA_OUT;
1203*867cd155SPankaj Dev 			} else {
1204*867cd155SPankaj Dev 				*param = ep_num;
1205*867cd155SPankaj Dev 				action = USB_DATA_IN;
1206*867cd155SPankaj Dev 			}
1207*867cd155SPankaj Dev 			break;
1208*867cd155SPankaj Dev 		case USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_DATA:
1209*867cd155SPankaj Dev 			if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {
1210*867cd155SPankaj Dev 				/* if wrong direction */
1211*867cd155SPankaj Dev 				if (__HAL_PCD_SETUP_REQ_DATA_DIR_IN(dwc3_handle->setup_addr) ==
1212*867cd155SPankaj Dev 				    0U) {
1213*867cd155SPankaj Dev 					ret = dwc3_ep_stop_xfer(dwc3_handle,
1214*867cd155SPankaj Dev 								&pcd_handle->out_ep[0]);
1215*867cd155SPankaj Dev 					if (ret != USBD_OK) {
1216*867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1217*867cd155SPankaj Dev 					}
1218*867cd155SPankaj Dev 					ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num); // OUT EP0
1219*867cd155SPankaj Dev 					if (ret != USBD_OK) {
1220*867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1221*867cd155SPankaj Dev 					}
1222*867cd155SPankaj Dev 				}
1223*867cd155SPankaj Dev 				/*
1224*867cd155SPankaj Dev 				 * last packet is MPS multiple, so send ZLP packet,
1225*867cd155SPankaj Dev 				 * handled by USBD_core.c
1226*867cd155SPankaj Dev 				 */
1227*867cd155SPankaj Dev 			} else {
1228*867cd155SPankaj Dev 				/* if wrong direction */
1229*867cd155SPankaj Dev 				if (__HAL_PCD_SETUP_REQ_DATA_DIR_IN(dwc3_handle->setup_addr) !=
1230*867cd155SPankaj Dev 				    0U) {
1231*867cd155SPankaj Dev 					ret = dwc3_ep_stop_xfer(dwc3_handle,
1232*867cd155SPankaj Dev 								&pcd_handle->in_ep[0]);
1233*867cd155SPankaj Dev 					if (ret != USBD_OK) {
1234*867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1235*867cd155SPankaj Dev 					}
1236*867cd155SPankaj Dev 					ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num); // OUT EP0
1237*867cd155SPankaj Dev 					if (ret != USBD_OK) {
1238*867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1239*867cd155SPankaj Dev 					}
1240*867cd155SPankaj Dev 				}
1241*867cd155SPankaj Dev 			}
1242*867cd155SPankaj Dev 			break;
1243*867cd155SPankaj Dev 		default:
1244*867cd155SPankaj Dev 			VERBOSE("Invalid Status %d: %s: %d\n", status, __func__, __LINE__);
1245*867cd155SPankaj Dev 			break;
1246*867cd155SPankaj Dev 		}
1247*867cd155SPankaj Dev 	}
1248*867cd155SPankaj Dev 
1249*867cd155SPankaj Dev 	return action;
1250*867cd155SPankaj Dev }
1251*867cd155SPankaj Dev 
1252*867cd155SPankaj Dev static enum usb_action dwc3_handle_ep_event(dwc3_handle_t *dwc3_handle, uint32_t event,
1253*867cd155SPankaj Dev 					    uint32_t *param)
1254*867cd155SPankaj Dev {
1255*867cd155SPankaj Dev 	enum usb_action action = USB_NOTHING;
1256*867cd155SPankaj Dev 	uint8_t type = dwc3_read_ep_evt_type(event);
1257*867cd155SPankaj Dev 	uint8_t phy_epnum = dwc3_read_ep_evt_epnum(event);
1258*867cd155SPankaj Dev 	uint8_t ep_addr, ep_num;
1259*867cd155SPankaj Dev 	struct usbd_ep *ep;
1260*867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep;
1261*867cd155SPankaj Dev 	enum usb_status ret;
1262*867cd155SPankaj Dev 
1263*867cd155SPankaj Dev 	ep_addr = __HAL_PCD_PHYEPNUM_TO_EPADDR(phy_epnum);
1264*867cd155SPankaj Dev 	ep_num = ep_addr & ADDRESS_MASK;
1265*867cd155SPankaj Dev 
1266*867cd155SPankaj Dev 	if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {
1267*867cd155SPankaj Dev 		ep = &dwc3_handle->pcd_handle->in_ep[ep_num];
1268*867cd155SPankaj Dev 		dwc3_ep = &dwc3_handle->IN_ep[ep_num];
1269*867cd155SPankaj Dev 	} else {
1270*867cd155SPankaj Dev 		ep = &dwc3_handle->pcd_handle->out_ep[ep_num];
1271*867cd155SPankaj Dev 		dwc3_ep = &dwc3_handle->OUT_ep[ep_num];
1272*867cd155SPankaj Dev 	}
1273*867cd155SPankaj Dev 
1274*867cd155SPankaj Dev 	switch (type) {
1275*867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_XFERCOMPLETE:
1276*867cd155SPankaj Dev 		VERBOSE("EP%d%s: Transfer Complete Event=%x\n", ep_num,
1277*867cd155SPankaj Dev 			   ep->is_in ? "IN" : "OUT", event);
1278*867cd155SPankaj Dev 
1279*867cd155SPankaj Dev 		if (ep->type == EP_TYPE_ISOC) {
1280*867cd155SPankaj Dev 			VERBOSE("EP%d%s is an Isochronous endpoint\n", ep_num,
1281*867cd155SPankaj Dev 				   ep->is_in ? "IN" : "OUT");
1282*867cd155SPankaj Dev 			break;
1283*867cd155SPankaj Dev 		}
1284*867cd155SPankaj Dev 
1285*867cd155SPankaj Dev 		/* Just forr Log, since ctrl expects sw to follow the whole control
1286*867cd155SPankaj Dev 		 * programming sequence, as also mentioned in Linux driver
1287*867cd155SPankaj Dev 		 */
1288*867cd155SPankaj Dev 		if ((ep_num == 0U) &&
1289*867cd155SPankaj Dev 		    (dwc3_get_ep_trbstatus(dwc3_ep) == USB_DWC3_TRBSTS_SETUP_PENDING)) {
1290*867cd155SPankaj Dev 			VERBOSE("EP%d%s Setup Pending received\n", ep_num,
1291*867cd155SPankaj Dev 				   ep->is_in ? "IN" : "OUT");
1292*867cd155SPankaj Dev 		}
1293*867cd155SPankaj Dev 
1294*867cd155SPankaj Dev 		VERBOSE("EP%d%s: Transfer Complete trb %p:%08x:%08x:%08x:%08x TRB-Status %u\n",
1295*867cd155SPankaj Dev 			   ep_num, ep->is_in ? "IN" : "OUT", dwc3_ep->trb_addr,
1296*867cd155SPankaj Dev 			   (uint32_t)dwc3_ep->trb_addr->bph, (uint32_t)dwc3_ep->trb_addr->bpl,
1297*867cd155SPankaj Dev 			   (uint32_t)dwc3_ep->trb_addr->size, (uint32_t)dwc3_ep->trb_addr->ctrl,
1298*867cd155SPankaj Dev 			   dwc3_get_ep_trbstatus(dwc3_ep));
1299*867cd155SPankaj Dev 
1300*867cd155SPankaj Dev 		if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {  /* IN EP */
1301*867cd155SPankaj Dev 			ep->xfer_count = ep->xfer_len - dwc3_get_ep_trblen(dwc3_ep);
1302*867cd155SPankaj Dev 
1303*867cd155SPankaj Dev 			dwc3_ep->flags &= ~USB_DWC3_EP_REQ_QUEUED;
1304*867cd155SPankaj Dev 
1305*867cd155SPankaj Dev 			if (ep->xfer_buff != NULL) {
1306*867cd155SPankaj Dev 				api_unmapdmaaddr(dwc3_ep->dma_addr, ep->xfer_len, 1);
1307*867cd155SPankaj Dev 			}
1308*867cd155SPankaj Dev 
1309*867cd155SPankaj Dev 			/*
1310*867cd155SPankaj Dev 			 * For EP0IN, if packet is not sent completely,
1311*867cd155SPankaj Dev 			 * then error, as done in Linux driver
1312*867cd155SPankaj Dev 			 */
1313*867cd155SPankaj Dev 			if ((ep_num == 0U) && (ep->xfer_len != ep->xfer_count)) {
1314*867cd155SPankaj Dev 				ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num); // OUT EP0
1315*867cd155SPankaj Dev 				if (ret != USBD_OK) {
1316*867cd155SPankaj Dev 					ERROR("%s: %d\n", __func__, __LINE__);
1317*867cd155SPankaj Dev 				}
1318*867cd155SPankaj Dev 			}
1319*867cd155SPankaj Dev 
1320*867cd155SPankaj Dev 			/*
1321*867cd155SPankaj Dev 			 * if 3-stage then wait for XFERNOTREADY(control-status) before
1322*867cd155SPankaj Dev 			 * sending data to upper layer
1323*867cd155SPankaj Dev 			 */
1324*867cd155SPankaj Dev 			if ((ep_num != 0U) || (ep->xfer_len == 0U)) {
1325*867cd155SPankaj Dev 				*param = ep_num;
1326*867cd155SPankaj Dev 				action = USB_DATA_IN;
1327*867cd155SPankaj Dev 			}
1328*867cd155SPankaj Dev 
1329*867cd155SPankaj Dev 			/* For EP0, this is ZLP, so prepare EP0 for next setup */
1330*867cd155SPankaj Dev 			if ((ep_num == 0U) && (ep->xfer_len == 0U)) {
1331*867cd155SPankaj Dev 				/* prepare to rx more setup packets */
1332*867cd155SPankaj Dev 				dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
1333*867cd155SPankaj Dev 
1334*867cd155SPankaj Dev 				ret = dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
1335*867cd155SPankaj Dev 				if (ret != USBD_OK) {
1336*867cd155SPankaj Dev 					ERROR("%s: %d\n", __func__, __LINE__);
1337*867cd155SPankaj Dev 					return action;
1338*867cd155SPankaj Dev 				}
1339*867cd155SPankaj Dev 			}
1340*867cd155SPankaj Dev 		} else {
1341*867cd155SPankaj Dev 			ep->xfer_count = ep->xfer_len - dwc3_get_ep_trblen(dwc3_ep);
1342*867cd155SPankaj Dev 
1343*867cd155SPankaj Dev 			dwc3_ep->flags &= ~USB_DWC3_EP_REQ_QUEUED;
1344*867cd155SPankaj Dev 
1345*867cd155SPankaj Dev 			/* For EP0OUT */
1346*867cd155SPankaj Dev 			if ((ep_addr == 0U) &&
1347*867cd155SPankaj Dev 			    (dwc3_handle->EP0_State == HAL_PCD_EP0_SETUP_QUEUED)) {
1348*867cd155SPankaj Dev 
1349*867cd155SPankaj Dev 				dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_COMPLETED;
1350*867cd155SPankaj Dev 				dwc3_ep->is_stall = false;
1351*867cd155SPankaj Dev 				VERBOSE("EP%d%s: SetupData %02x%02x%02x%02x:%02x%02x%02x%02x\n",
1352*867cd155SPankaj Dev 					   ep_num, ep->is_in ? "IN" : "OUT",
1353*867cd155SPankaj Dev 					   dwc3_handle->setup_addr[0], dwc3_handle->setup_addr[1],
1354*867cd155SPankaj Dev 					   dwc3_handle->setup_addr[2], dwc3_handle->setup_addr[3],
1355*867cd155SPankaj Dev 					   dwc3_handle->setup_addr[4], dwc3_handle->setup_addr[5],
1356*867cd155SPankaj Dev 					   dwc3_handle->setup_addr[6], dwc3_handle->setup_addr[7]);
1357*867cd155SPankaj Dev 
1358*867cd155SPankaj Dev 				// if 2-stage then wait for the XFERNOTREADY(control-status)
1359*867cd155SPankaj Dev 				if (__HAL_PCD_SETUP_REQ_LEN(dwc3_handle->setup_addr) != 0U) {
1360*867cd155SPankaj Dev 					api_memcpy(dwc3_handle->pcd_handle->setup,
1361*867cd155SPankaj Dev 						   dwc3_handle->setup_addr,
1362*867cd155SPankaj Dev 						   sizeof(dwc3_handle->pcd_handle->setup));
1363*867cd155SPankaj Dev 					action = USB_SETUP;
1364*867cd155SPankaj Dev 				}
1365*867cd155SPankaj Dev 			} else {
1366*867cd155SPankaj Dev 
1367*867cd155SPankaj Dev 				if (ep->xfer_buff != NULL) {
1368*867cd155SPankaj Dev 					api_unmapdmaaddr(dwc3_ep->dma_addr, ep->xfer_len, 0);
1369*867cd155SPankaj Dev 				}
1370*867cd155SPankaj Dev 
1371*867cd155SPankaj Dev 				if (ep->xfer_buff == dwc3_ep->bounce_buf) {
1372*867cd155SPankaj Dev 					api_memcpy(dwc3_ep->xfer_dest_buff, ep->xfer_buff,
1373*867cd155SPankaj Dev 						   ep->xfer_count);
1374*867cd155SPankaj Dev 					ep->xfer_buff = dwc3_ep->xfer_dest_buff;
1375*867cd155SPankaj Dev 				}
1376*867cd155SPankaj Dev 
1377*867cd155SPankaj Dev 				/*
1378*867cd155SPankaj Dev 				 * if 3-stage then wait for XFERNOTREADY(control-status) before
1379*867cd155SPankaj Dev 				 * sending data to upper layer
1380*867cd155SPankaj Dev 				 */
1381*867cd155SPankaj Dev 				if ((ep_num != 0U) || (ep->xfer_len == 0U)) {
1382*867cd155SPankaj Dev 					*param = ep_num;
1383*867cd155SPankaj Dev 					action = USB_DATA_OUT;
1384*867cd155SPankaj Dev 				}
1385*867cd155SPankaj Dev 
1386*867cd155SPankaj Dev 				/* For EP0, this is ZLP, so prepare EP0 for next setup */
1387*867cd155SPankaj Dev 				if ((ep_num == 0U) && (ep->xfer_len == 0U)) {
1388*867cd155SPankaj Dev 					/* prepare to rx more setup packets */
1389*867cd155SPankaj Dev 					dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
1390*867cd155SPankaj Dev 
1391*867cd155SPankaj Dev 					ret = dwc3_ep0_out_start(dwc3_handle,
1392*867cd155SPankaj Dev 								 dwc3_handle->setup_dma_addr);
1393*867cd155SPankaj Dev 					if (ret != USBD_OK) {
1394*867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1395*867cd155SPankaj Dev 						return action;
1396*867cd155SPankaj Dev 					}
1397*867cd155SPankaj Dev 				}
1398*867cd155SPankaj Dev 			}
1399*867cd155SPankaj Dev 		}
1400*867cd155SPankaj Dev 
1401*867cd155SPankaj Dev 		break;
1402*867cd155SPankaj Dev 
1403*867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_XFERINPROGRESS:
1404*867cd155SPankaj Dev 		VERBOSE("EP%d%s: Transfer In-Progress %u Event=%x\n", ep_num,
1405*867cd155SPankaj Dev 			   ep->is_in ? "IN" : "OUT", dwc3_handle->intbuffers.evtbufferpos[0],
1406*867cd155SPankaj Dev 			   event);
1407*867cd155SPankaj Dev 
1408*867cd155SPankaj Dev 		if (ep_num == 0U) { // ***ToCheck
1409*867cd155SPankaj Dev 			break;
1410*867cd155SPankaj Dev 		}
1411*867cd155SPankaj Dev 
1412*867cd155SPankaj Dev 		/*
1413*867cd155SPankaj Dev 		 * currently not planned to issue multiple TRB transfer, hence there shouldn't
1414*867cd155SPankaj Dev 		 * be any event like this
1415*867cd155SPankaj Dev 		 */
1416*867cd155SPankaj Dev 
1417*867cd155SPankaj Dev 		/*
1418*867cd155SPankaj Dev 		 * But for isoc transfers we need get it since transfer started with
1419*867cd155SPankaj Dev 		 * loop(link) trb
1420*867cd155SPankaj Dev 		 */
1421*867cd155SPankaj Dev 		if (ep->type != EP_TYPE_ISOC) {
1422*867cd155SPankaj Dev 			break;
1423*867cd155SPankaj Dev 		}
1424*867cd155SPankaj Dev 
1425*867cd155SPankaj Dev 		break;
1426*867cd155SPankaj Dev 
1427*867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_XFERNOTREADY:
1428*867cd155SPankaj Dev 		VERBOSE("EP%d%s: Transfer Not Ready Event=%x\n", ep_num,
1429*867cd155SPankaj Dev 			   ep->is_in ? "IN" : "OUT", event);
1430*867cd155SPankaj Dev 		/* For EP0IN or EP0OUT, currently no plan to use xfernotready interrupt */
1431*867cd155SPankaj Dev 
1432*867cd155SPankaj Dev 		//active = PCD_READ_DEPEVT_STATUS(event);
1433*867cd155SPankaj Dev 
1434*867cd155SPankaj Dev 		if (ep_num == 0U) {
1435*867cd155SPankaj Dev 
1436*867cd155SPankaj Dev 			if (dwc3_handle->EP0_State == HAL_PCD_EP0_SETUP_QUEUED) {
1437*867cd155SPankaj Dev 				ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num);  // OUT EP0
1438*867cd155SPankaj Dev 				if (ret != USBD_OK) {
1439*867cd155SPankaj Dev 					ERROR("%s: %d\n", __func__, __LINE__);
1440*867cd155SPankaj Dev 					return action;
1441*867cd155SPankaj Dev 				}
1442*867cd155SPankaj Dev 			} else {
1443*867cd155SPankaj Dev 				action = dwc3_handle_ep0_xfernotready_event(dwc3_handle, event,
1444*867cd155SPankaj Dev 									    param);
1445*867cd155SPankaj Dev 			}
1446*867cd155SPankaj Dev 		}
1447*867cd155SPankaj Dev 
1448*867cd155SPankaj Dev 		/*
1449*867cd155SPankaj Dev 		 * Currently we dont implement provide request queue to support On-demand transfers
1450*867cd155SPankaj Dev 		 * for non-isoc EP, it only supports preset transfers so this event will not be
1451*867cd155SPankaj Dev 		 * used, Section 9.2.4 "Transfer Setup Recommendations"
1452*867cd155SPankaj Dev 		 */
1453*867cd155SPankaj Dev 
1454*867cd155SPankaj Dev 		/*
1455*867cd155SPankaj Dev 		 * But for isoc transfers we need to issue the request from here using the
1456*867cd155SPankaj Dev 		 * micro-frame number
1457*867cd155SPankaj Dev 		 */
1458*867cd155SPankaj Dev 		if (ep->type != EP_TYPE_ISOC) {
1459*867cd155SPankaj Dev 			break;
1460*867cd155SPankaj Dev 		}
1461*867cd155SPankaj Dev 
1462*867cd155SPankaj Dev 		break;
1463*867cd155SPankaj Dev 
1464*867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_STREAMEVT: /* Stream event, Not used */
1465*867cd155SPankaj Dev 		break;
1466*867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_RXTXFIFOEVT: /* FIFO Overrun */
1467*867cd155SPankaj Dev 		break;
1468*867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_EPCMDCMPLT: /* Endpoint Command Complete */
1469*867cd155SPankaj Dev 		VERBOSE("EP%d%s: Endpoint Command Complete Event=%x\n", ep_num,
1470*867cd155SPankaj Dev 			   ep->is_in ? "IN" : "OUT", event);
1471*867cd155SPankaj Dev 		break;
1472*867cd155SPankaj Dev 	default:
1473*867cd155SPankaj Dev 		VERBOSE("Invalid type %d: %s: %d\n", type, __func__, __LINE__);
1474*867cd155SPankaj Dev 		break;
1475*867cd155SPankaj Dev 	}
1476*867cd155SPankaj Dev 
1477*867cd155SPankaj Dev 	return action;
1478*867cd155SPankaj Dev }
1479*867cd155SPankaj Dev 
1480*867cd155SPankaj Dev static uint8_t dwc3_read_dev_evt_type(uint32_t event)
1481*867cd155SPankaj Dev {
1482*867cd155SPankaj Dev 	uint8_t ret;
1483*867cd155SPankaj Dev 
1484*867cd155SPankaj Dev 	switch ((event & DWC3_EVT_DEVEVT_TYPE_MASK) >> DWC3_EVT_DEVEVT_TYPE_BITPOS) {
1485*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_DISCONNECT:
1486*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_DISCONNECT;
1487*867cd155SPankaj Dev 		break;
1488*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_RESET:
1489*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_RESET;
1490*867cd155SPankaj Dev 		break;
1491*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_CONNECT_DONE:
1492*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_CONNECT_DONE;
1493*867cd155SPankaj Dev 		break;
1494*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
1495*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE;
1496*867cd155SPankaj Dev 		break;
1497*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_WAKEUP:
1498*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_WAKEUP;
1499*867cd155SPankaj Dev 		break;
1500*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_HIBER_REQ:
1501*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_HIBER_REQ;
1502*867cd155SPankaj Dev 		break;
1503*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_EOPF:
1504*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_EOPF;
1505*867cd155SPankaj Dev 		break;
1506*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_SOF:
1507*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_SOF;
1508*867cd155SPankaj Dev 		break;
1509*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
1510*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_ERRATIC_ERROR;
1511*867cd155SPankaj Dev 		break;
1512*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_CMD_CMPL:
1513*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_CMD_CMPL;
1514*867cd155SPankaj Dev 		break;
1515*867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_OVERFLOW:
1516*867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_OVERFLOW;
1517*867cd155SPankaj Dev 		break;
1518*867cd155SPankaj Dev 	default:
1519*867cd155SPankaj Dev 		ret = 0;
1520*867cd155SPankaj Dev 		break;
1521*867cd155SPankaj Dev 	}
1522*867cd155SPankaj Dev 
1523*867cd155SPankaj Dev 	return ret;
1524*867cd155SPankaj Dev }
1525*867cd155SPankaj Dev 
1526*867cd155SPankaj Dev static enum usb_status dwc3_ep_clear_stall(dwc3_handle_t *dwc3_handle, usb_dwc3_endpoint_t *dwc3_ep)
1527*867cd155SPankaj Dev {
1528*867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
1529*867cd155SPankaj Dev 
1530*867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
1531*867cd155SPankaj Dev 
1532*867cd155SPankaj Dev 	return dwc3_execute_dep_cmd(dwc3_handle, dwc3_ep->phy_epnum, USB_DWC3_DEPCMD_CLEARSTALL,
1533*867cd155SPankaj Dev 				    &params);
1534*867cd155SPankaj Dev }
1535*867cd155SPankaj Dev 
1536*867cd155SPankaj Dev static uint8_t dwc3_get_dev_speed(dwc3_handle_t *dwc3_handle)
1537*867cd155SPankaj Dev {
1538*867cd155SPankaj Dev 	uint32_t reg;
1539*867cd155SPankaj Dev 	uint8_t ret;
1540*867cd155SPankaj Dev 
1541*867cd155SPankaj Dev 	reg = DWC3_regread(dwc3_handle->usb_device, DWC3_DSTS) & USB3_DSTS_CONNECTSPD;
1542*867cd155SPankaj Dev 
1543*867cd155SPankaj Dev 	switch (reg) {
1544*867cd155SPankaj Dev 	case DWC3_DSTS_SUPERSPEED:
1545*867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_SUPER;
1546*867cd155SPankaj Dev 		INFO("%s = SuperSpeed\n", __func__);
1547*867cd155SPankaj Dev 		break;
1548*867cd155SPankaj Dev 	case DWC3_DSTS_HIGHSPEED:
1549*867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_HIGH;
1550*867cd155SPankaj Dev 		INFO("%s = HighSpeed\n", __func__);
1551*867cd155SPankaj Dev 		break;
1552*867cd155SPankaj Dev 	case DWC3_DSTS_FULLSPEED1:
1553*867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_FULL_48;
1554*867cd155SPankaj Dev 		INFO("%s = FullSpeed_48M\n", __func__);
1555*867cd155SPankaj Dev 		break;
1556*867cd155SPankaj Dev 	case DWC3_DSTS_FULLSPEED2:
1557*867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_FULL;
1558*867cd155SPankaj Dev 		INFO("%s = FullSpeed\n", __func__);
1559*867cd155SPankaj Dev 		break;
1560*867cd155SPankaj Dev 	case DWC3_DSTS_LOWSPEED:
1561*867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_LOW;
1562*867cd155SPankaj Dev 		INFO("%s = LowSpeed\n", __func__);
1563*867cd155SPankaj Dev 		break;
1564*867cd155SPankaj Dev 	default: /* Invalid */
1565*867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_INVALID;
1566*867cd155SPankaj Dev 		INFO("%s = Invalid\n", __func__);
1567*867cd155SPankaj Dev 		break;
1568*867cd155SPankaj Dev 	}
1569*867cd155SPankaj Dev 
1570*867cd155SPankaj Dev 	return ret;
1571*867cd155SPankaj Dev }
1572*867cd155SPankaj Dev 
1573*867cd155SPankaj Dev static uint32_t dwc3_get_epcfg_action(uint8_t action)
1574*867cd155SPankaj Dev {
1575*867cd155SPankaj Dev 	uint32_t ret;
1576*867cd155SPankaj Dev 
1577*867cd155SPankaj Dev 	switch (action) {
1578*867cd155SPankaj Dev 	case USB_DWC3_DEPCFG_ACTION_INIT:
1579*867cd155SPankaj Dev 		ret = DWC3_DEPCFG_ACTION_INIT;
1580*867cd155SPankaj Dev 		break;
1581*867cd155SPankaj Dev 	case USB_DWC3_DEPCFG_ACTION_RESTORE:
1582*867cd155SPankaj Dev 		ret = DWC3_DEPCFG_ACTION_RESTORE;
1583*867cd155SPankaj Dev 		break;
1584*867cd155SPankaj Dev 	case USB_DWC3_DEPCFG_ACTION_MODIFY:
1585*867cd155SPankaj Dev 		ret = DWC3_DEPCFG_ACTION_MODIFY;
1586*867cd155SPankaj Dev 		break;
1587*867cd155SPankaj Dev 	default:
1588*867cd155SPankaj Dev 		ret = 0U;
1589*867cd155SPankaj Dev 		break;
1590*867cd155SPankaj Dev 	}
1591*867cd155SPankaj Dev 
1592*867cd155SPankaj Dev 	return ret;
1593*867cd155SPankaj Dev }
1594*867cd155SPankaj Dev 
1595*867cd155SPankaj Dev static enum usb_status dwc3_ep_configure(dwc3_handle_t *dwc3_handle, uint8_t epnum, bool is_in,
1596*867cd155SPankaj Dev 					 uint8_t type, uint32_t max_packet, uint8_t tx_fifo,
1597*867cd155SPankaj Dev 					 uint16_t binterval, uint8_t phy_epnum, uint8_t intr_num,
1598*867cd155SPankaj Dev 					 uint8_t action)
1599*867cd155SPankaj Dev {
1600*867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
1601*867cd155SPankaj Dev 
1602*867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
1603*867cd155SPankaj Dev 	params.param0 = DWC3_DEPCFG_EP_TYPE(type) | DWC3_DEPCFG_MAX_PACKET_SIZE(max_packet);
1604*867cd155SPankaj Dev 
1605*867cd155SPankaj Dev 	/* Burst size is only needed in SuperSpeed mode */
1606*867cd155SPankaj Dev 	//params.param0 |= DWC3_DEPCFG_BURST_SIZE(0);
1607*867cd155SPankaj Dev 
1608*867cd155SPankaj Dev 	params.param0 |= dwc3_get_epcfg_action(action);
1609*867cd155SPankaj Dev 
1610*867cd155SPankaj Dev 	params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN | DWC3_DEPCFG_XFER_NOT_READY_EN;
1611*867cd155SPankaj Dev 	if (type == EP_TYPE_ISOC) {
1612*867cd155SPankaj Dev 		params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN;
1613*867cd155SPankaj Dev 	}
1614*867cd155SPankaj Dev 
1615*867cd155SPankaj Dev 	params.param1 |= DWC3_DEPCFG_EP_NUMBER(((uint32_t)epnum << 1) + (is_in ? 1UL : 0UL));
1616*867cd155SPankaj Dev 
1617*867cd155SPankaj Dev 	params.param1 |= DWC3_DEPCFG_EP_INTR_NUM(intr_num);
1618*867cd155SPankaj Dev 
1619*867cd155SPankaj Dev 	if (is_in) {
1620*867cd155SPankaj Dev 		params.param0 |= DWC3_DEPCFG_FIFO_NUMBER(tx_fifo);
1621*867cd155SPankaj Dev 	}
1622*867cd155SPankaj Dev 
1623*867cd155SPankaj Dev 	if (binterval != 0U) {
1624*867cd155SPankaj Dev 		params.param1 |= DWC3_DEPCFG_BINTERVAL_M1(binterval - 1UL);
1625*867cd155SPankaj Dev 	}
1626*867cd155SPankaj Dev 
1627*867cd155SPankaj Dev 	return dwc3_execute_dep_cmd(dwc3_handle, phy_epnum, USB_DWC3_DEPCMD_SETEPCONFIG, &params);
1628*867cd155SPankaj Dev }
1629*867cd155SPankaj Dev 
1630*867cd155SPankaj Dev static inline uint8_t dwc3_read_dev_evt_linkstate(uint32_t event)
1631*867cd155SPankaj Dev {
1632*867cd155SPankaj Dev 	return (uint8_t)((event & DWC3_EVT_DEVEVT_LNKSTS_MASK) >> DWC3_EVT_DEVEVT_LNKSTS_BITPOS);
1633*867cd155SPankaj Dev }
1634*867cd155SPankaj Dev 
1635*867cd155SPankaj Dev static inline const char *dwc3_get_linkstate_str(uint8_t state)
1636*867cd155SPankaj Dev {
1637*867cd155SPankaj Dev 	const char *ret;
1638*867cd155SPankaj Dev 
1639*867cd155SPankaj Dev 	switch (state) {
1640*867cd155SPankaj Dev 	case DWC3_LINK_STATE_ON:
1641*867cd155SPankaj Dev 		ret = "ON";
1642*867cd155SPankaj Dev 		break;
1643*867cd155SPankaj Dev 	case DWC3_LINK_STATE_L1:
1644*867cd155SPankaj Dev 		ret = "L1";
1645*867cd155SPankaj Dev 		break;
1646*867cd155SPankaj Dev 	case DWC3_LINK_STATE_L2:
1647*867cd155SPankaj Dev 		ret = "L2";
1648*867cd155SPankaj Dev 		break;
1649*867cd155SPankaj Dev 	case DWC3_LINK_STATE_DIS:
1650*867cd155SPankaj Dev 		ret = "Disconnect";
1651*867cd155SPankaj Dev 		break;
1652*867cd155SPankaj Dev 	case DWC3_LINK_STATE_EARLY_SUS:
1653*867cd155SPankaj Dev 		ret = "Early Suspend";
1654*867cd155SPankaj Dev 		break;
1655*867cd155SPankaj Dev 	case DWC3_LINK_STATE_RESET:
1656*867cd155SPankaj Dev 		ret = "Reset";
1657*867cd155SPankaj Dev 		break;
1658*867cd155SPankaj Dev 	case DWC3_LINK_STATE_RESUME:
1659*867cd155SPankaj Dev 		ret = "Resume";
1660*867cd155SPankaj Dev 		break;
1661*867cd155SPankaj Dev 	default:
1662*867cd155SPankaj Dev 		ret = "UNKNOWN state";
1663*867cd155SPankaj Dev 		break;
1664*867cd155SPankaj Dev 	}
1665*867cd155SPankaj Dev 
1666*867cd155SPankaj Dev 	return ret;
1667*867cd155SPankaj Dev }
1668*867cd155SPankaj Dev 
1669*867cd155SPankaj Dev static enum usb_action dwc3_handle_dev_event(dwc3_handle_t *dwc3_handle, uint32_t event,
1670*867cd155SPankaj Dev 					     uint32_t *param)
1671*867cd155SPankaj Dev {
1672*867cd155SPankaj Dev 	enum usb_action action = USB_NOTHING;
1673*867cd155SPankaj Dev 	uint8_t type = dwc3_read_dev_evt_type(event);
1674*867cd155SPankaj Dev 	uint8_t i, speed;
1675*867cd155SPankaj Dev 	usb_dwc3_endpoint_t *ep;
1676*867cd155SPankaj Dev 	enum usb_status ret;
1677*867cd155SPankaj Dev 	uint32_t ep0_mps = USB3_MAX_PACKET_SIZE;
1678*867cd155SPankaj Dev 
1679*867cd155SPankaj Dev 	switch (type) {
1680*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_DISCONNECT:
1681*867cd155SPankaj Dev 		INFO("Event: Device Disconnect\n");
1682*867cd155SPankaj Dev 		/* For SuperSpeed, set DCTL[8:5] to 5*/
1683*867cd155SPankaj Dev 
1684*867cd155SPankaj Dev 		action = USB_DISCONNECT;
1685*867cd155SPankaj Dev 		break;
1686*867cd155SPankaj Dev 
1687*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_RESET:
1688*867cd155SPankaj Dev 		INFO("Event: Device Reset\n");
1689*867cd155SPankaj Dev 		/*
1690*867cd155SPankaj Dev 		 * Spec says, Wait till EP0 finishes current transfer and reaches Setup-Stage.
1691*867cd155SPankaj Dev 		 * But there is no wait in Linux driver which means that Host will take care while
1692*867cd155SPankaj Dev 		 * issuing a reset. Also its tricky to implement since we can't wait here
1693*867cd155SPankaj Dev 		 * (in interrupt context) for further control EP interrupts
1694*867cd155SPankaj Dev 		 */
1695*867cd155SPankaj Dev 
1696*867cd155SPankaj Dev 		if (dwc3_handle->EP0_State != HAL_PCD_EP0_SETUP_QUEUED) {
1697*867cd155SPankaj Dev 			ret = dwc3_ep_stop_xfer(dwc3_handle, &dwc3_handle->pcd_handle->out_ep[0]);
1698*867cd155SPankaj Dev 			if (ret != USBD_OK) {
1699*867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1700*867cd155SPankaj Dev 			}
1701*867cd155SPankaj Dev 			ret = dwc3_epaddr_set_stall(dwc3_handle, EP0_OUT); // OUT EP0
1702*867cd155SPankaj Dev 			if (ret != USBD_OK) {
1703*867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1704*867cd155SPankaj Dev 			}
1705*867cd155SPankaj Dev 		}
1706*867cd155SPankaj Dev 
1707*867cd155SPankaj Dev 		/*
1708*867cd155SPankaj Dev 		 * Stop transfers for all(USB_DWC3_NUM_IN_EPS) EP
1709*867cd155SPankaj Dev 		 * except EP0IN k = USB_DWC3_NUM_IN_EP
1710*867cd155SPankaj Dev 		 */
1711*867cd155SPankaj Dev 		for (i = 0; i < USB_DWC3_NUM_IN_EP; i++) {
1712*867cd155SPankaj Dev 			dwc3_ep_stop_xfer(dwc3_handle,
1713*867cd155SPankaj Dev 					      &dwc3_handle->pcd_handle->in_ep[i]);
1714*867cd155SPankaj Dev 		}
1715*867cd155SPankaj Dev 
1716*867cd155SPankaj Dev 		/* Stop transfers for all EP except EP0OUT k = USB_DWC3_NUM_OUT_EP */
1717*867cd155SPankaj Dev 		for (i = 1; i < USB_DWC3_NUM_OUT_EP; i++) {
1718*867cd155SPankaj Dev 			dwc3_ep_stop_xfer(dwc3_handle,
1719*867cd155SPankaj Dev 					      &dwc3_handle->pcd_handle->out_ep[i]);
1720*867cd155SPankaj Dev 		}
1721*867cd155SPankaj Dev 
1722*867cd155SPankaj Dev 		/* Clear Stall for all EP except EP0IN k = USB_DWC3_NUM_IN_EP */
1723*867cd155SPankaj Dev 		for (i = 1; i < USB_DWC3_NUM_IN_EP; i++) {
1724*867cd155SPankaj Dev 			ep = &dwc3_handle->IN_ep[i];
1725*867cd155SPankaj Dev 
1726*867cd155SPankaj Dev 			if (!ep->is_stall) {
1727*867cd155SPankaj Dev 				continue;
1728*867cd155SPankaj Dev 			}
1729*867cd155SPankaj Dev 
1730*867cd155SPankaj Dev 			ep->is_stall = false;
1731*867cd155SPankaj Dev 
1732*867cd155SPankaj Dev 			ret = dwc3_ep_clear_stall(dwc3_handle, ep);
1733*867cd155SPankaj Dev 			if (ret != USBD_OK) {
1734*867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1735*867cd155SPankaj Dev 				return action;
1736*867cd155SPankaj Dev 			}
1737*867cd155SPankaj Dev 		}
1738*867cd155SPankaj Dev 
1739*867cd155SPankaj Dev 		/* Clear Stall for all EP except EP0OUT k = USB_DWC3_NUM_OUT_EP */
1740*867cd155SPankaj Dev 		for (i = 1; i < USB_DWC3_NUM_OUT_EP; i++) {
1741*867cd155SPankaj Dev 			ep = &dwc3_handle->OUT_ep[i];
1742*867cd155SPankaj Dev 
1743*867cd155SPankaj Dev 			if (!ep->is_stall) {
1744*867cd155SPankaj Dev 				continue;
1745*867cd155SPankaj Dev 			}
1746*867cd155SPankaj Dev 
1747*867cd155SPankaj Dev 			ep->is_stall = false;
1748*867cd155SPankaj Dev 			//ep->num   = ep_addr & ADDRESS_MASK;
1749*867cd155SPankaj Dev 			//ep->is_in = ((ep_addr & 0x80) == 0x80);
1750*867cd155SPankaj Dev 
1751*867cd155SPankaj Dev 			ret = dwc3_ep_clear_stall(dwc3_handle, ep);
1752*867cd155SPankaj Dev 			if (ret != USBD_OK) {
1753*867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1754*867cd155SPankaj Dev 				return action;
1755*867cd155SPankaj Dev 			}
1756*867cd155SPankaj Dev 		}
1757*867cd155SPankaj Dev 
1758*867cd155SPankaj Dev 		/* Reset device address to zero */
1759*867cd155SPankaj Dev 		ret = usb_dwc3_set_address(dwc3_handle, 0);
1760*867cd155SPankaj Dev 		if (ret != USBD_OK) {
1761*867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
1762*867cd155SPankaj Dev 			return action;
1763*867cd155SPankaj Dev 		}
1764*867cd155SPankaj Dev 
1765*867cd155SPankaj Dev 		action = USB_RESET;
1766*867cd155SPankaj Dev 
1767*867cd155SPankaj Dev 		break;
1768*867cd155SPankaj Dev 
1769*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_CONNECT_DONE:
1770*867cd155SPankaj Dev 		INFO("Event: Device Connection Done\n");
1771*867cd155SPankaj Dev 
1772*867cd155SPankaj Dev 		/*
1773*867cd155SPankaj Dev 		 * hpcd->Init.ep0_mps = MaxPacketSize to 512 (SuperSpeed), 64 (High-Speed),
1774*867cd155SPankaj Dev 		 * 8/16/32/64 (Full-Speed), or 8 (Low-Speed).
1775*867cd155SPankaj Dev 		 */
1776*867cd155SPankaj Dev 		speed = dwc3_get_dev_speed(dwc3_handle);
1777*867cd155SPankaj Dev 		switch (speed) {
1778*867cd155SPankaj Dev 		case USB_DWC3_SPEED_SUPER:
1779*867cd155SPankaj Dev 			ep0_mps = 512;
1780*867cd155SPankaj Dev 			break;
1781*867cd155SPankaj Dev 		case USB_DWC3_SPEED_HIGH:
1782*867cd155SPankaj Dev 			ep0_mps = 64;
1783*867cd155SPankaj Dev 			break;
1784*867cd155SPankaj Dev 		case USB_DWC3_SPEED_FULL_48:
1785*867cd155SPankaj Dev 		case USB_DWC3_SPEED_FULL:
1786*867cd155SPankaj Dev 			ep0_mps = 64;
1787*867cd155SPankaj Dev 			break;
1788*867cd155SPankaj Dev 		case USB_DWC3_SPEED_LOW:
1789*867cd155SPankaj Dev 			ep0_mps = 8;
1790*867cd155SPankaj Dev 			break;
1791*867cd155SPankaj Dev 		default:
1792*867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
1793*867cd155SPankaj Dev 			break;
1794*867cd155SPankaj Dev 		}
1795*867cd155SPankaj Dev 
1796*867cd155SPankaj Dev 		/* Update DWC3_GCTL_RAMCLKSEL, but only for Superspeed */
1797*867cd155SPankaj Dev 
1798*867cd155SPankaj Dev 		/* Modify max packet size for EP 0 & 1 */
1799*867cd155SPankaj Dev 		ret = dwc3_ep_configure(dwc3_handle, 0, false, EP_TYPE_CTRL, ep0_mps, 0, 0, 0,
1800*867cd155SPankaj Dev 					dwc3_handle->OUT_ep[0].intr_num,
1801*867cd155SPankaj Dev 					USB_DWC3_DEPCFG_ACTION_MODIFY);
1802*867cd155SPankaj Dev 		if (ret != USBD_OK) {
1803*867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
1804*867cd155SPankaj Dev 			return action;
1805*867cd155SPankaj Dev 		}
1806*867cd155SPankaj Dev 		ret = dwc3_ep_configure(dwc3_handle, 0, true, EP_TYPE_CTRL, ep0_mps, 0, 0, 1,
1807*867cd155SPankaj Dev 					dwc3_handle->IN_ep[0].intr_num,
1808*867cd155SPankaj Dev 					USB_DWC3_DEPCFG_ACTION_MODIFY);
1809*867cd155SPankaj Dev 		if (ret != USBD_OK) {
1810*867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
1811*867cd155SPankaj Dev 			return action;
1812*867cd155SPankaj Dev 		}
1813*867cd155SPankaj Dev 
1814*867cd155SPankaj Dev 		dwc3_handle->pcd_handle->out_ep[0].maxpacket = ep0_mps;
1815*867cd155SPankaj Dev 		dwc3_handle->pcd_handle->in_ep[0].maxpacket = ep0_mps;
1816*867cd155SPankaj Dev 
1817*867cd155SPankaj Dev 		/*
1818*867cd155SPankaj Dev 		 * Depending on the connected speed, write to the other
1819*867cd155SPankaj Dev 		 * PHY's control register to suspend it.
1820*867cd155SPankaj Dev 		 */
1821*867cd155SPankaj Dev 
1822*867cd155SPankaj Dev 		/* Use default values for GTXFIFOSIZn and GRXFIFOSIZ0 */
1823*867cd155SPankaj Dev 
1824*867cd155SPankaj Dev 		action = USB_ENUM_DONE;
1825*867cd155SPankaj Dev 
1826*867cd155SPankaj Dev 		break;
1827*867cd155SPankaj Dev 
1828*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
1829*867cd155SPankaj Dev 		INFO("Event: Link Status Change : %s(%d)\n",
1830*867cd155SPankaj Dev 			   dwc3_get_linkstate_str(dwc3_read_dev_evt_linkstate(event)),
1831*867cd155SPankaj Dev 			   dwc3_read_dev_evt_linkstate(event));
1832*867cd155SPankaj Dev 		/* Handle link state changes, U0,U1,U2,U3 with suspend/resume functions */
1833*867cd155SPankaj Dev 
1834*867cd155SPankaj Dev 		break;
1835*867cd155SPankaj Dev 
1836*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_WAKEUP:
1837*867cd155SPankaj Dev 		INFO("Event: Wake-UP\n");
1838*867cd155SPankaj Dev 		// resume function
1839*867cd155SPankaj Dev 		action = USB_RESUME;
1840*867cd155SPankaj Dev 		break;
1841*867cd155SPankaj Dev 
1842*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_HIBER_REQ:
1843*867cd155SPankaj Dev 		INFO("Event: Hibernation Request\n");
1844*867cd155SPankaj Dev 		/* hibernation function */
1845*867cd155SPankaj Dev 		break;
1846*867cd155SPankaj Dev 
1847*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_EOPF: /* End of Periodic Frame */
1848*867cd155SPankaj Dev 		INFO("Event: Suspend\n");
1849*867cd155SPankaj Dev 		action = USB_SUSPEND;
1850*867cd155SPankaj Dev 		break;
1851*867cd155SPankaj Dev 
1852*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_SOF: /* Start of Periodic Frame */
1853*867cd155SPankaj Dev 		INFO("Event: Start of Periodic Frame\n");
1854*867cd155SPankaj Dev 		break;
1855*867cd155SPankaj Dev 
1856*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_L1SUSPEND:
1857*867cd155SPankaj Dev 		INFO("Event: L1 Suspend\n");
1858*867cd155SPankaj Dev 		action = USB_LPM;
1859*867cd155SPankaj Dev 		break;
1860*867cd155SPankaj Dev 
1861*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_ERRATIC_ERROR: /* Erratic Error */
1862*867cd155SPankaj Dev 		INFO("Event: Erratic Error\n");
1863*867cd155SPankaj Dev 		break;
1864*867cd155SPankaj Dev 
1865*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_CMD_CMPL: /* Command Complete */
1866*867cd155SPankaj Dev 		INFO("Event: Command Complete\n");
1867*867cd155SPankaj Dev 		break;
1868*867cd155SPankaj Dev 
1869*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_OVERFLOW: /* Overflow */
1870*867cd155SPankaj Dev 		INFO("Event: Overflow\n");
1871*867cd155SPankaj Dev 		break;
1872*867cd155SPankaj Dev 
1873*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_L1WAKEUP:
1874*867cd155SPankaj Dev 		INFO("Event: L1 Wake-UP\n");
1875*867cd155SPankaj Dev 		// resume function
1876*867cd155SPankaj Dev 		action = USB_RESUME;
1877*867cd155SPankaj Dev 		break;
1878*867cd155SPankaj Dev 
1879*867cd155SPankaj Dev 	default:  /* UNKNOWN IRQ type */
1880*867cd155SPankaj Dev 		break;
1881*867cd155SPankaj Dev 	}
1882*867cd155SPankaj Dev 
1883*867cd155SPankaj Dev 	return action;
1884*867cd155SPankaj Dev }
1885*867cd155SPankaj Dev 
1886*867cd155SPankaj Dev static inline bool dwc3_is_ep_event(uint32_t event)
1887*867cd155SPankaj Dev {
1888*867cd155SPankaj Dev 	return ((event & DWC3_EVT_TYPE_MASK) == (DWC3_EVT_TYPE_EP << DWC3_EVT_TYPE_BITPOS));
1889*867cd155SPankaj Dev }
1890*867cd155SPankaj Dev 
1891*867cd155SPankaj Dev static inline bool dwc3_is_dev_event(uint32_t event)
1892*867cd155SPankaj Dev {
1893*867cd155SPankaj Dev 	return ((event & DWC3_EVT_TYPE_MASK) == (DWC3_EVT_TYPE_DEVSPEC << DWC3_EVT_TYPE_BITPOS));
1894*867cd155SPankaj Dev }
1895*867cd155SPankaj Dev 
1896*867cd155SPankaj Dev static enum usb_action usb_dwc3_it_handler(void *handle, uint32_t *param)
1897*867cd155SPankaj Dev {
1898*867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
1899*867cd155SPankaj Dev 	enum usb_action action = USB_NOTHING;
1900*867cd155SPankaj Dev 	uint32_t evtcnt, evt;
1901*867cd155SPankaj Dev 	uint8_t i;
1902*867cd155SPankaj Dev 
1903*867cd155SPankaj Dev 	/* Use same handler for all the Evt-Buf IRQs */
1904*867cd155SPankaj Dev 
1905*867cd155SPankaj Dev 	/* Check for all Event Buffer interrupt k = USB_DWC3_INT_INUSE */
1906*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
1907*867cd155SPankaj Dev 		evtcnt = dwc3_read_intr_count(dwc3_handle, i);
1908*867cd155SPankaj Dev 
1909*867cd155SPankaj Dev 		if (!evtcnt) {
1910*867cd155SPankaj Dev 			continue;
1911*867cd155SPankaj Dev 		}
1912*867cd155SPankaj Dev 
1913*867cd155SPankaj Dev 		VERBOSE("Interrupt Count %u\n", evtcnt);
1914*867cd155SPankaj Dev 
1915*867cd155SPankaj Dev 		evt = __HAL_PCD_READ_EVENT(dwc3_handle, i);
1916*867cd155SPankaj Dev 		VERBOSE("Event %08x\n", evt);
1917*867cd155SPankaj Dev 
1918*867cd155SPankaj Dev 		if (dwc3_is_ep_event(evt)) {   /* EP event */
1919*867cd155SPankaj Dev 			action = dwc3_handle_ep_event(dwc3_handle, evt, param);
1920*867cd155SPankaj Dev 		} else {     /* NON-EP event */
1921*867cd155SPankaj Dev 			if (dwc3_is_dev_event(evt)) {  /* Device specific event */
1922*867cd155SPankaj Dev 				action = dwc3_handle_dev_event(dwc3_handle, evt, param);
1923*867cd155SPankaj Dev 			} else {
1924*867cd155SPankaj Dev 			  /* Error, non supported events */
1925*867cd155SPankaj Dev 			}
1926*867cd155SPankaj Dev 		}
1927*867cd155SPankaj Dev 
1928*867cd155SPankaj Dev 		__HAL_PCD_INCR_EVENT_POS(dwc3_handle, i, USB_DWC3_EVENT_SIZE);
1929*867cd155SPankaj Dev 
1930*867cd155SPankaj Dev 		dwc3_ack_evt_count(dwc3_handle, i, USB_DWC3_EVENT_SIZE);
1931*867cd155SPankaj Dev 	}
1932*867cd155SPankaj Dev 
1933*867cd155SPankaj Dev 	return action;
1934*867cd155SPankaj Dev }
1935*867cd155SPankaj Dev 
1936*867cd155SPankaj Dev static enum usb_status usb_dwc3_write_packet(void *handle __unused, uint8_t *src __unused,
1937*867cd155SPankaj Dev 					     uint8_t ch_ep_num __unused, uint16_t len __unused)
1938*867cd155SPankaj Dev {
1939*867cd155SPankaj Dev 	return USBD_OK;
1940*867cd155SPankaj Dev }
1941*867cd155SPankaj Dev 
1942*867cd155SPankaj Dev static void *usb_dwc3_read_packet(void *handle __unused, uint8_t *dest __unused,
1943*867cd155SPankaj Dev 				  uint16_t len __unused)
1944*867cd155SPankaj Dev {
1945*867cd155SPankaj Dev 	return NULL;
1946*867cd155SPankaj Dev }
1947*867cd155SPankaj Dev 
1948*867cd155SPankaj Dev static enum usb_status usb_dwc3_write_empty_tx_fifo(void *handle __unused, uint32_t epnum,
1949*867cd155SPankaj Dev 						    uint32_t xfer_len __unused,
1950*867cd155SPankaj Dev 						    uint32_t *xfer_count __unused,
1951*867cd155SPankaj Dev 						    uint32_t maxpacket __unused,
1952*867cd155SPankaj Dev 						    uint8_t **xfer_buff __unused)
1953*867cd155SPankaj Dev {
1954*867cd155SPankaj Dev 	return USBD_OK;
1955*867cd155SPankaj Dev }
1956*867cd155SPankaj Dev 
1957*867cd155SPankaj Dev static const struct usb_driver usb_dwc3driver = {
1958*867cd155SPankaj Dev 	.ep0_out_start = usb_dwc3_ep0_out_start,
1959*867cd155SPankaj Dev 	.ep_start_xfer = usb_dwc3_ep_start_xfer,
1960*867cd155SPankaj Dev 	.ep0_start_xfer = usb_dwc3_ep0_start_xfer,
1961*867cd155SPankaj Dev 	.write_packet = usb_dwc3_write_packet,
1962*867cd155SPankaj Dev 	.read_packet = usb_dwc3_read_packet,
1963*867cd155SPankaj Dev 	.ep_set_stall = usb_dwc3_ep_set_stall,
1964*867cd155SPankaj Dev 	.start_device = usb_dwc3_start_device,
1965*867cd155SPankaj Dev 	.stop_device = usb_dwc3_stop_device,
1966*867cd155SPankaj Dev 	.set_address = usb_dwc3_set_address,
1967*867cd155SPankaj Dev 	.write_empty_tx_fifo = usb_dwc3_write_empty_tx_fifo,
1968*867cd155SPankaj Dev 	.it_handler = usb_dwc3_it_handler
1969*867cd155SPankaj Dev };
1970*867cd155SPankaj Dev 
1971*867cd155SPankaj Dev /* USB2 PHY Mask 0xf */
1972*867cd155SPankaj Dev #define USBPHY_ULPI	1U
1973*867cd155SPankaj Dev #define USBPHY_UTMI	2U
1974*867cd155SPankaj Dev #define USBPHY_EMBEDDED_USB2	8U
1975*867cd155SPankaj Dev #define USB2PHY_MASK	15U
1976*867cd155SPankaj Dev /* USB3 PHY Mask (0xf << 4) */
1977*867cd155SPankaj Dev #define USBPHY_PIPE3	16U
1978*867cd155SPankaj Dev #define USBPHY_EMBEDDED_USB3	128U
1979*867cd155SPankaj Dev #define USB3PHY_MASK	(15U << 4)
1980*867cd155SPankaj Dev 
1981*867cd155SPankaj Dev static enum usb_status dwc3_soft_reset(dwc3_handle_t *dwc3_handle)
1982*867cd155SPankaj Dev {
1983*867cd155SPankaj Dev 	uint64_t timeout;
1984*867cd155SPankaj Dev 
1985*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCTL, USB3_DCTL_CSFTRST);
1986*867cd155SPankaj Dev 
1987*867cd155SPankaj Dev 	timeout = timeout_init_us(500*1000); /* msec */
1988*867cd155SPankaj Dev 
1989*867cd155SPankaj Dev 	while (DWC3_regread(dwc3_handle->usb_device, DWC3_DCTL) & USB3_DCTL_CSFTRST) {
1990*867cd155SPankaj Dev 
1991*867cd155SPankaj Dev 		if (timeout_elapsed(timeout)) { /* "Reset Timed Out" */
1992*867cd155SPankaj Dev 			return USBD_TIMEOUT;
1993*867cd155SPankaj Dev 		}
1994*867cd155SPankaj Dev 	}
1995*867cd155SPankaj Dev 
1996*867cd155SPankaj Dev 	return USBD_OK;
1997*867cd155SPankaj Dev }
1998*867cd155SPankaj Dev 
1999*867cd155SPankaj Dev static enum usb_status dwc3_core_init(dwc3_handle_t *dwc3_handle, uint32_t phy_itface)
2000*867cd155SPankaj Dev {
2001*867cd155SPankaj Dev 	enum usb_status ret;
2002*867cd155SPankaj Dev 
2003*867cd155SPankaj Dev 	VERBOSE("Core ID %08x\n", (uint32_t)DWC3_regread(dwc3_handle->usb_global, DWC3_GSNPSID));
2004*867cd155SPankaj Dev 
2005*867cd155SPankaj Dev 	/* Set GUSB3PIPECTL for all USB3 ports (1-n), currently doing only for 0 */
2006*867cd155SPankaj Dev 	if ((phy_itface & USB3PHY_MASK) != 0U) {
2007*867cd155SPankaj Dev 		/* Relying on default value */
2008*867cd155SPankaj Dev 	}
2009*867cd155SPankaj Dev 
2010*867cd155SPankaj Dev 	/* Set GUSB2PHYCFG for all USB2 ports (1-m), currently doing only for 0 */
2011*867cd155SPankaj Dev 	if ((phy_itface & USB2PHY_MASK) != 0U) {
2012*867cd155SPankaj Dev 		switch (phy_itface) {
2013*867cd155SPankaj Dev 		case USBPHY_UTMI:
2014*867cd155SPankaj Dev 			DWC3_regupdateclr(dwc3_handle->usb_global, DWC3_GUSB2PHYCFG(0UL),
2015*867cd155SPankaj Dev 					  USB3_GUSB2PHYCFG_ULPI_UTMI_SEL);
2016*867cd155SPankaj Dev 			break;
2017*867cd155SPankaj Dev 		case USBPHY_ULPI:
2018*867cd155SPankaj Dev 			DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GUSB2PHYCFG(0UL),
2019*867cd155SPankaj Dev 					  USB3_GUSB2PHYCFG_ULPI_UTMI_SEL);
2020*867cd155SPankaj Dev 			break;
2021*867cd155SPankaj Dev 		default:
2022*867cd155SPankaj Dev 			/* Relying on default value. */
2023*867cd155SPankaj Dev 			break;
2024*867cd155SPankaj Dev 		}
2025*867cd155SPankaj Dev 	}
2026*867cd155SPankaj Dev 
2027*867cd155SPankaj Dev 	/* issue device SoftReset */
2028*867cd155SPankaj Dev 	ret = dwc3_soft_reset(dwc3_handle);
2029*867cd155SPankaj Dev 	if (ret != USBD_OK) {
2030*867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2031*867cd155SPankaj Dev 		return ret;
2032*867cd155SPankaj Dev 	}
2033*867cd155SPankaj Dev 
2034*867cd155SPankaj Dev 	/* Put PHYs in reset */
2035*867cd155SPankaj Dev 	/* Before Resetting PHY, put Core in Reset */
2036*867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GCTL, USB3_GCTL_CORESOFTRESET);
2037*867cd155SPankaj Dev 
2038*867cd155SPankaj Dev 	/* Assert USB3 PHY reset for all USB3 ports (1-n), currently doing only for 0 */
2039*867cd155SPankaj Dev 	if ((phy_itface & USB3PHY_MASK) != 0U) {
2040*867cd155SPankaj Dev 		DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GUSB3PIPECTL(0UL),
2041*867cd155SPankaj Dev 				  USB3_GUSB3PIPECTL_PHYSOFTRST);
2042*867cd155SPankaj Dev 	}
2043*867cd155SPankaj Dev 
2044*867cd155SPankaj Dev 	/* Assert USB2 PHY reset for all USB2 ports (1-m), currently doing only for 0 */
2045*867cd155SPankaj Dev 	if ((phy_itface & USB2PHY_MASK) != 0U) {
2046*867cd155SPankaj Dev 		DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GUSB2PHYCFG(0UL),
2047*867cd155SPankaj Dev 				  USB3_GUSB2PHYCFG_PHYSOFTRST);
2048*867cd155SPankaj Dev 	}
2049*867cd155SPankaj Dev 
2050*867cd155SPankaj Dev 	// Program PHY signals - PHY specific
2051*867cd155SPankaj Dev 
2052*867cd155SPankaj Dev 
2053*867cd155SPankaj Dev 	// Phy Init not needed since will be done by bootrom
2054*867cd155SPankaj Dev 
2055*867cd155SPankaj Dev 	/* Release PHY out of reset */
2056*867cd155SPankaj Dev 
2057*867cd155SPankaj Dev 	/* Clear USB3 PHY reset for all USB3 ports (1-n), currently doing only for 0 */
2058*867cd155SPankaj Dev 	if ((phy_itface & USB3PHY_MASK) != 0U) {
2059*867cd155SPankaj Dev 		DWC3_regupdateclr(dwc3_handle->usb_global, DWC3_GUSB3PIPECTL(0UL),
2060*867cd155SPankaj Dev 				  USB3_GUSB3PIPECTL_PHYSOFTRST);
2061*867cd155SPankaj Dev 	}
2062*867cd155SPankaj Dev 
2063*867cd155SPankaj Dev 	/* Clear USB2 PHY reset */
2064*867cd155SPankaj Dev 	if ((phy_itface & USB2PHY_MASK) != 0U) {
2065*867cd155SPankaj Dev 		DWC3_regupdateclr(dwc3_handle->usb_global, DWC3_GUSB2PHYCFG(0UL),
2066*867cd155SPankaj Dev 				  USB3_GUSB2PHYCFG_PHYSOFTRST);
2067*867cd155SPankaj Dev 	}
2068*867cd155SPankaj Dev 
2069*867cd155SPankaj Dev 	// delay needed for phy reset
2070*867cd155SPankaj Dev 	mdelay(100); // 100ms
2071*867cd155SPankaj Dev 
2072*867cd155SPankaj Dev 	/* After PHYs are stable we can take Core out of reset state */
2073*867cd155SPankaj Dev 	DWC3_regupdateclr(dwc3_handle->usb_global, DWC3_GCTL, USB3_GCTL_CORESOFTRESET);
2074*867cd155SPankaj Dev 
2075*867cd155SPankaj Dev 	/* Disable Scale down mode - check if disabled by default */
2076*867cd155SPankaj Dev 	//DWC3_regupdateclr(USBx, DWC3_GCTL, DWC3_GCTL_SCALEDOWN_MASK); ***ToCheck
2077*867cd155SPankaj Dev 
2078*867cd155SPankaj Dev 	/* Alloc and Setup Scratch buffers for hibernation */
2079*867cd155SPankaj Dev 	// ***ToCheck
2080*867cd155SPankaj Dev 
2081*867cd155SPankaj Dev 	// From Linux Driver
2082*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_global, DWC3_GSBUSCFG0, 0xe);
2083*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_global, DWC3_GSBUSCFG1, 0xf00);
2084*867cd155SPankaj Dev 
2085*867cd155SPankaj Dev 	/* Use default values for GTXFIFOSIZn and GRXFIFOSIZ0 */
2086*867cd155SPankaj Dev 
2087*867cd155SPankaj Dev 	return USBD_OK;
2088*867cd155SPankaj Dev }
2089*867cd155SPankaj Dev 
2090*867cd155SPankaj Dev typedef enum {
2091*867cd155SPankaj Dev 	USB_DWC3_DEVICE_MODE  = 0U,
2092*867cd155SPankaj Dev 	USB_DWC3_HOST_MODE    = 1U,
2093*867cd155SPankaj Dev 	USB_DWC3_DRD_MODE     = 2U,
2094*867cd155SPankaj Dev 	USB_DWC3_INVALID_MODE = 0xFU
2095*867cd155SPankaj Dev } USB_DWC3_modetypedef;
2096*867cd155SPankaj Dev 
2097*867cd155SPankaj Dev static enum usb_status dwc3_set_current_mode(dwc3_handle_t *dwc3_handle, USB_DWC3_modetypedef mode)
2098*867cd155SPankaj Dev {
2099*867cd155SPankaj Dev 	uint32_t reg;
2100*867cd155SPankaj Dev 	enum usb_status ret = USBD_OK;
2101*867cd155SPankaj Dev 
2102*867cd155SPankaj Dev 	reg = DWC3_regread(dwc3_handle->usb_global, DWC3_GCTL) & ~USB3_GCTL_PRTCAPDIR_MSK;
2103*867cd155SPankaj Dev 
2104*867cd155SPankaj Dev 	switch (mode) {
2105*867cd155SPankaj Dev 	case USB_DWC3_DEVICE_MODE:
2106*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GCTL, reg |
2107*867cd155SPankaj Dev 			      DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE));
2108*867cd155SPankaj Dev 		break;
2109*867cd155SPankaj Dev 	case USB_DWC3_HOST_MODE:
2110*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GCTL, reg |
2111*867cd155SPankaj Dev 			      DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST));
2112*867cd155SPankaj Dev 		break;
2113*867cd155SPankaj Dev 	case USB_DWC3_DRD_MODE:
2114*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GCTL, reg |
2115*867cd155SPankaj Dev 			      DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
2116*867cd155SPankaj Dev 		break;
2117*867cd155SPankaj Dev 	default:
2118*867cd155SPankaj Dev 		ret = USBD_FAIL;
2119*867cd155SPankaj Dev 		break;
2120*867cd155SPankaj Dev 	}
2121*867cd155SPankaj Dev 
2122*867cd155SPankaj Dev 	return ret;
2123*867cd155SPankaj Dev }
2124*867cd155SPankaj Dev 
2125*867cd155SPankaj Dev static enum usb_status dwc3_set_dev_speed(dwc3_handle_t *dwc3_handle, uint8_t speed)
2126*867cd155SPankaj Dev {
2127*867cd155SPankaj Dev 	uint32_t reg;
2128*867cd155SPankaj Dev 	enum usb_status ret = USBD_OK;
2129*867cd155SPankaj Dev 
2130*867cd155SPankaj Dev 	reg = DWC3_regread(dwc3_handle->usb_device, DWC3_DCFG) & ~USB3_DCFG_DEVSPD_MSK;
2131*867cd155SPankaj Dev 
2132*867cd155SPankaj Dev 	switch (speed) {
2133*867cd155SPankaj Dev 	case USB_DWC3_SPEED_SUPER:
2134*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg | DWC3_DSTS_SUPERSPEED);
2135*867cd155SPankaj Dev 		INFO("%s = SuperSpeed\n", __func__);
2136*867cd155SPankaj Dev 		break;
2137*867cd155SPankaj Dev 	case USB_DWC3_SPEED_HIGH:
2138*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |  DWC3_DSTS_HIGHSPEED);
2139*867cd155SPankaj Dev 		INFO("%s = HighSpeed\n", __func__);
2140*867cd155SPankaj Dev 		break;
2141*867cd155SPankaj Dev 	case USB_DWC3_SPEED_FULL_48:
2142*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |  DWC3_DSTS_FULLSPEED1);
2143*867cd155SPankaj Dev 		INFO("%s = FullSpeed_48M\n", __func__);
2144*867cd155SPankaj Dev 		break;
2145*867cd155SPankaj Dev 	case USB_DWC3_SPEED_FULL:
2146*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |  DWC3_DSTS_FULLSPEED2);
2147*867cd155SPankaj Dev 		INFO("%s = FullSpeed\n", __func__);
2148*867cd155SPankaj Dev 		break;
2149*867cd155SPankaj Dev 	case USB_DWC3_SPEED_LOW:
2150*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |  DWC3_DSTS_LOWSPEED);
2151*867cd155SPankaj Dev 		INFO("%s = LowSpeed\n", __func__);
2152*867cd155SPankaj Dev 		break;
2153*867cd155SPankaj Dev 	default:
2154*867cd155SPankaj Dev 		ret = USBD_FAIL;
2155*867cd155SPankaj Dev 		break;
2156*867cd155SPankaj Dev 	}
2157*867cd155SPankaj Dev 
2158*867cd155SPankaj Dev 	return ret;
2159*867cd155SPankaj Dev }
2160*867cd155SPankaj Dev 
2161*867cd155SPankaj Dev /*
2162*867cd155SPankaj Dev  * @brief  USB_DevInit : Initializes the USB3 controller registers
2163*867cd155SPankaj Dev  *         for device mode
2164*867cd155SPankaj Dev  * @param  USBx  Selected device
2165*867cd155SPankaj Dev  * @param  cfg   pointer to a USB_DWC3_CfgTypeDef structure that contains
2166*867cd155SPankaj Dev  *         the configuration information for the specified USBx peripheral.
2167*867cd155SPankaj Dev  * @retval HAL status
2168*867cd155SPankaj Dev  */
2169*867cd155SPankaj Dev enum usb_status dwc3_dev_init(dwc3_handle_t *dwc3_handle, uint8_t speed, uint8_t intr_dev)
2170*867cd155SPankaj Dev {
2171*867cd155SPankaj Dev 	uint32_t reg;
2172*867cd155SPankaj Dev 	uint8_t i;
2173*867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
2174*867cd155SPankaj Dev 	enum usb_status ret;
2175*867cd155SPankaj Dev 
2176*867cd155SPankaj Dev 	/* Setup event buffers k = USB_DWC3_INT_INUSE */
2177*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
2178*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTADRLO(i),
2179*867cd155SPankaj Dev 			      lower_32_bits(dwc3_handle->intbuffers.evtbuffer_dma_addr[i]));
2180*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTADRHI(i),
2181*867cd155SPankaj Dev 			      upper_32_bits(dwc3_handle->intbuffers.evtbuffer_dma_addr[i]));
2182*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTSIZ(i),
2183*867cd155SPankaj Dev 			      USB_DWC3_EVENT_BUFFER_SIZE);
2184*867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTCOUNT(i), 0);
2185*867cd155SPankaj Dev 
2186*867cd155SPankaj Dev 		/* EvtBufferPos[i] = 0;  Implicit since static done in HAL */
2187*867cd155SPankaj Dev 	}
2188*867cd155SPankaj Dev 
2189*867cd155SPankaj Dev 	/*
2190*867cd155SPankaj Dev 	 * Need to set GUCTL2 RST_ACTBITLATER, so the driver can poll for CMDACT bit
2191*867cd155SPankaj Dev 	 * when issuing the ENDTRANSFER command.
2192*867cd155SPankaj Dev 	 */
2193*867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GUCTL2, DWC3_GUCTL2_RST_ACTBITLATER);
2194*867cd155SPankaj Dev 
2195*867cd155SPankaj Dev 	ret = dwc3_set_current_mode(dwc3_handle, USB_DWC3_DEVICE_MODE);
2196*867cd155SPankaj Dev 	if (ret != USBD_OK) {
2197*867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2198*867cd155SPankaj Dev 		return ret;
2199*867cd155SPankaj Dev 	}
2200*867cd155SPankaj Dev 
2201*867cd155SPankaj Dev 	ret = dwc3_set_dev_speed(dwc3_handle, speed);
2202*867cd155SPankaj Dev 	if (ret != USBD_OK) {
2203*867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2204*867cd155SPankaj Dev 		return ret;
2205*867cd155SPankaj Dev 	}
2206*867cd155SPankaj Dev 
2207*867cd155SPankaj Dev 	/* Issue a DEPSTARTCFG command with DEPCMD0.XferRscIdx set to 0,
2208*867cd155SPankaj Dev 	 * to initialize the transfer resource allocation
2209*867cd155SPankaj Dev 	 */
2210*867cd155SPankaj Dev 	zeromem(&params, sizeof(params));
2211*867cd155SPankaj Dev 	ret = dwc3_execute_dep_cmd(dwc3_handle, 0, DWC3_DEPCMD_PARAM(0) |
2212*867cd155SPankaj Dev 				   USB_DWC3_DEPCMD_DEPSTARTCFG, &params);
2213*867cd155SPankaj Dev 	if (ret != USBD_OK) {
2214*867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2215*867cd155SPankaj Dev 		return ret;
2216*867cd155SPankaj Dev 	}
2217*867cd155SPankaj Dev 
2218*867cd155SPankaj Dev 	/* Configure Control EP 0 & 1 mapped to physical EP 0 & 1*/
2219*867cd155SPankaj Dev 	ret = dwc3_ep_configure(dwc3_handle, 0, false, EP_TYPE_CTRL,
2220*867cd155SPankaj Dev 				dwc3_handle->pcd_handle->out_ep[0].maxpacket, 0, 0, 0,
2221*867cd155SPankaj Dev 				dwc3_handle->OUT_ep[0].intr_num, USB_DWC3_DEPCFG_ACTION_INIT);
2222*867cd155SPankaj Dev 	if (ret != USBD_OK) {
2223*867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2224*867cd155SPankaj Dev 		return ret;
2225*867cd155SPankaj Dev 	}
2226*867cd155SPankaj Dev 	ret = dwc3_ep_configure(dwc3_handle, 0, true, EP_TYPE_CTRL,
2227*867cd155SPankaj Dev 				dwc3_handle->pcd_handle->in_ep[0].maxpacket, 0, 0, 1,
2228*867cd155SPankaj Dev 				dwc3_handle->IN_ep[0].intr_num, USB_DWC3_DEPCFG_ACTION_INIT);
2229*867cd155SPankaj Dev 	if (ret != USBD_OK) {
2230*867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2231*867cd155SPankaj Dev 		return ret;
2232*867cd155SPankaj Dev 	}
2233*867cd155SPankaj Dev 
2234*867cd155SPankaj Dev 	/* Transfer Resource for Control EP 0 & 1*/
2235*867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
2236*867cd155SPankaj Dev 	params.param0 = DWC3_DEPXFERCFG_NUM_XFER_RES(1U);
2237*867cd155SPankaj Dev 	/* As per databook, "Issue a DEPSTARTCFG command with DEPCMD0.XferRscIdx set to 2 to
2238*867cd155SPankaj Dev 	 * re-initialize the transfer resource allocation on SetConfiguration or SetInterface
2239*867cd155SPankaj Dev 	 * Request", value is 2 since the EP0 & EP1 take up the transfer resource 1 & 2, hence
2240*867cd155SPankaj Dev 	 * further EPs will take resources 2,3,&up.. But in HAL we are not decoding the
2241*867cd155SPankaj Dev 	 * Setup-packet requests, this should ideally come from USB-MW core.
2242*867cd155SPankaj Dev 	 * Instead we follow the same method as Linux dwc3-gadget controller driver, All hardware
2243*867cd155SPankaj Dev 	 * endpoints can be assigned a transfer resource and this setting will stay persistent
2244*867cd155SPankaj Dev 	 * until either a core reset or hibernation. So whenever we do a DEPSTARTCFG(0) we can go
2245*867cd155SPankaj Dev 	 * ahead and do DEPXFERCFG for every hardware endpoint as well.
2246*867cd155SPankaj Dev 	 * For all k = DWC3_IP_NUM_EPS
2247*867cd155SPankaj Dev 	 */
2248*867cd155SPankaj Dev 	for (i = 0; i < DWC3_IP_NUM_EPS; i++) {
2249*867cd155SPankaj Dev 		ret = dwc3_execute_dep_cmd(dwc3_handle, i, USB_DWC3_DEPCMD_SETTRANSFRESOURCE,
2250*867cd155SPankaj Dev 					   &params);
2251*867cd155SPankaj Dev 		if (ret != USBD_OK) {
2252*867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
2253*867cd155SPankaj Dev 			return ret;
2254*867cd155SPankaj Dev 		}
2255*867cd155SPankaj Dev 	}
2256*867cd155SPankaj Dev 
2257*867cd155SPankaj Dev 	/* setup EP0 to receive SETUP packets */
2258*867cd155SPankaj Dev 	ret = dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
2259*867cd155SPankaj Dev 	if (ret != USBD_OK) {
2260*867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2261*867cd155SPankaj Dev 		return ret;
2262*867cd155SPankaj Dev 	}
2263*867cd155SPankaj Dev 
2264*867cd155SPankaj Dev 	/* Enable EP 0 & 1 */
2265*867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_device, DWC3_DALEPENA, DWC3_DALEPENA_EP(0) |
2266*867cd155SPankaj Dev 			  DWC3_DALEPENA_EP(1));
2267*867cd155SPankaj Dev 
2268*867cd155SPankaj Dev 	/*
2269*867cd155SPankaj Dev 	 * Set interrupt/EventQ number on which non-endpoint-specific device-related
2270*867cd155SPankaj Dev 	 * interrupts are generated
2271*867cd155SPankaj Dev 	 */
2272*867cd155SPankaj Dev 	reg = DWC3_regread(dwc3_handle->usb_device, DWC3_DCFG) & ~USB3_DCFG_INTRNUM_MSK;
2273*867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |
2274*867cd155SPankaj Dev 		      ((uint32_t)intr_dev << USB3_DCFG_INTRNUM_POS));
2275*867cd155SPankaj Dev 
2276*867cd155SPankaj Dev 	/* Enable all events but Start and End of Frame IRQs */
2277*867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_device, DWC3_DEVTEN, USB3_DEVTEN_VENDEVTSTRCVDEN |
2278*867cd155SPankaj Dev 			  USB3_DEVTEN_EVNTOVERFLOWEN | USB3_DEVTEN_CMDCMPLTEN |
2279*867cd155SPankaj Dev 			  USB3_DEVTEN_ERRTICERREVTEN | USB3_DEVTEN_U3L2L1SUSPEN |
2280*867cd155SPankaj Dev 			  USB3_DEVTEN_HIBERNATIONREQEVTEN | USB3_DEVTEN_WKUPEVTEN |
2281*867cd155SPankaj Dev 			  USB3_DEVTEN_ULSTCNGEN | USB3_DEVTEN_CONNECTDONEEVTEN |
2282*867cd155SPankaj Dev 			  USB3_DEVTEN_USBRSTEVTEN | USB3_DEVTEN_DISSCONNEVTEN |
2283*867cd155SPankaj Dev 			  USB3_DEVTEN_L1SUSPEN | USB3_DEVTEN_L1WKUPEVTEN
2284*867cd155SPankaj Dev 			  /* | USB3_DEVTEN_SOFTEVTEN*/);
2285*867cd155SPankaj Dev 
2286*867cd155SPankaj Dev 	/* Enable Event Buffer interrupt k = USB_DWC3_INT_INUSE */
2287*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
2288*867cd155SPankaj Dev 		__HAL_PCD_ENABLE_INTR(dwc3_handle, i);
2289*867cd155SPankaj Dev 	}
2290*867cd155SPankaj Dev 
2291*867cd155SPankaj Dev 	return USBD_OK;
2292*867cd155SPankaj Dev }
2293*867cd155SPankaj Dev 
2294*867cd155SPankaj Dev void usb_dwc3_init_driver(struct usb_handle *usb_core_handle, struct pcd_handle *pcd_handle,
2295*867cd155SPankaj Dev 			  dwc3_handle_t *dwc3_handle, void *base_addr)
2296*867cd155SPankaj Dev {
2297*867cd155SPankaj Dev 	uint32_t i = 0;
2298*867cd155SPankaj Dev 	enum usb_status ret;
2299*867cd155SPankaj Dev 	uintptr_t base = (uintptr_t)base_addr;
2300*867cd155SPankaj Dev 
2301*867cd155SPankaj Dev 	dwc3_handle->usb_global = (usb_dwc3_global_t *)
2302*867cd155SPankaj Dev 					(base + USB_DWC3_GLOBAL_BASE);
2303*867cd155SPankaj Dev 
2304*867cd155SPankaj Dev 	dwc3_handle->usb_device = (usb_dwc3_device_t *)
2305*867cd155SPankaj Dev 					(base + USB_DWC3_DEVICE_BASE);
2306*867cd155SPankaj Dev 
2307*867cd155SPankaj Dev 	dwc3_handle->pcd_handle = pcd_handle;
2308*867cd155SPankaj Dev 
2309*867cd155SPankaj Dev 	/* Check hpcd->State is HAL_PCD_STATE_RESET, otherwise error */
2310*867cd155SPankaj Dev 	assert(dwc3_handle->State == HAL_PCD_STATE_RESET);
2311*867cd155SPankaj Dev 
2312*867cd155SPankaj Dev 	dwc3_handle->State = HAL_PCD_STATE_BUSY;
2313*867cd155SPankaj Dev 
2314*867cd155SPankaj Dev 	/* Disable the Interrupts */
2315*867cd155SPankaj Dev 	// Not required since USB device and EP interrupts are disabled at boot, ***ToCheck
2316*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
2317*867cd155SPankaj Dev 		__HAL_PCD_DISABLE_INTR(dwc3_handle, i);
2318*867cd155SPankaj Dev 	}
2319*867cd155SPankaj Dev 
2320*867cd155SPankaj Dev 	/* Init the Core (common init.) */
2321*867cd155SPankaj Dev 	ret = dwc3_core_init(dwc3_handle, USBPHY_UTMI);
2322*867cd155SPankaj Dev 	if (ret != USBD_OK) {
2323*867cd155SPankaj Dev 		panic();
2324*867cd155SPankaj Dev 	}
2325*867cd155SPankaj Dev 
2326*867cd155SPankaj Dev 	/* Init endpoints structures */
2327*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_NUM_IN_EP ; i++) {
2328*867cd155SPankaj Dev 		/* Init ep structure */
2329*867cd155SPankaj Dev 		pcd_handle->in_ep[i].is_in = true;
2330*867cd155SPankaj Dev 		pcd_handle->in_ep[i].num = i;
2331*867cd155SPankaj Dev 		dwc3_handle->IN_ep[i].tx_fifo_num = i;
2332*867cd155SPankaj Dev 		/* Control until ep is activated */
2333*867cd155SPankaj Dev 		pcd_handle->in_ep[i].type = EP_TYPE_CTRL;
2334*867cd155SPankaj Dev 
2335*867cd155SPankaj Dev 		/*
2336*867cd155SPankaj Dev 		 * We are doing 1:1 alternate mapping for endpoints, meaning
2337*867cd155SPankaj Dev 		 * IN Endpoint X maps to Physical Endpoint 2*X +1 and
2338*867cd155SPankaj Dev 		 * OUT Endpoint X maps to Physical Endpoint 2*X.
2339*867cd155SPankaj Dev 		 * So USB endpoint 0x81 is 0x03.
2340*867cd155SPankaj Dev 		 */
2341*867cd155SPankaj Dev 		dwc3_handle->IN_ep[i].phy_epnum = __HAL_PCD_EPADDR_TO_PHYEPNUM(i | EP_DIR_IN);
2342*867cd155SPankaj Dev 
2343*867cd155SPankaj Dev 		dwc3_handle->IN_ep[i].intr_num = PCD_DEV_EVENTS_INTR;
2344*867cd155SPankaj Dev 	}
2345*867cd155SPankaj Dev 
2346*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_NUM_OUT_EP ; i++) {
2347*867cd155SPankaj Dev 		/* Init ep structure */
2348*867cd155SPankaj Dev 		pcd_handle->out_ep[i].is_in = false;
2349*867cd155SPankaj Dev 		pcd_handle->out_ep[i].num = i;
2350*867cd155SPankaj Dev 		dwc3_handle->OUT_ep[i].tx_fifo_num = i;
2351*867cd155SPankaj Dev 		/* Control until ep is activated */
2352*867cd155SPankaj Dev 		pcd_handle->out_ep[i].type = EP_TYPE_CTRL;
2353*867cd155SPankaj Dev 
2354*867cd155SPankaj Dev 		/*
2355*867cd155SPankaj Dev 		 * We are doing 1:1 alternate mapping for endpoints, meaning
2356*867cd155SPankaj Dev 		 * IN Endpoint X maps to Physical Endpoint 2*X +1 and
2357*867cd155SPankaj Dev 		 * OUT Endpoint X maps to Physical Endpoint 2*X.
2358*867cd155SPankaj Dev 		 * So USB endpoint 0x81 is 0x03.
2359*867cd155SPankaj Dev 		 */
2360*867cd155SPankaj Dev 		dwc3_handle->OUT_ep[i].phy_epnum = __HAL_PCD_EPADDR_TO_PHYEPNUM(i);
2361*867cd155SPankaj Dev 
2362*867cd155SPankaj Dev 		dwc3_handle->OUT_ep[i].intr_num = PCD_DEV_EVENTS_INTR;
2363*867cd155SPankaj Dev 
2364*867cd155SPankaj Dev 		dwc3_handle->OUT_ep[i].bounce_buf = dwc3_handle->bounce_bufs[i].bounce_buf;
2365*867cd155SPankaj Dev 	}
2366*867cd155SPankaj Dev 
2367*867cd155SPankaj Dev #define PHYS_AREA	STM32MP_USB_DWC3_BASE
2368*867cd155SPankaj Dev 
2369*867cd155SPankaj Dev #define EVTBUF_AREA_OFFSET	0U
2370*867cd155SPankaj Dev #define TRB_OUT_AREA_OFFSET	(EVTBUF_AREA_OFFSET + USB_DWC3_EVENT_BUFFER_SIZE)
2371*867cd155SPankaj Dev #define TRB_IN_AREA_OFFSET	(TRB_OUT_AREA_OFFSET + sizeof(usb_dwc3_trb_t))
2372*867cd155SPankaj Dev #define SETUP_AREA_OFFSET	(TRB_IN_AREA_OFFSET + sizeof(usb_dwc3_trb_t))
2373*867cd155SPankaj Dev 
2374*867cd155SPankaj Dev 	void *coh_area = (void *)(uintptr_t)PHYS_AREA;
2375*867cd155SPankaj Dev 
2376*867cd155SPankaj Dev #define EVTBUF_AREA	(coh_area + EVTBUF_AREA_OFFSET)
2377*867cd155SPankaj Dev #define TRB_OUT_AREA	(coh_area + TRB_OUT_AREA_OFFSET)
2378*867cd155SPankaj Dev #define TRB_IN_AREA	(coh_area + TRB_IN_AREA_OFFSET)
2379*867cd155SPankaj Dev #define SETUP_AREA	(coh_area + SETUP_AREA_OFFSET)
2380*867cd155SPankaj Dev 
2381*867cd155SPankaj Dev 	dwc3_handle->setup_dma_addr = (uintptr_t)api_getdmaaddr((void *)SETUP_AREA,
2382*867cd155SPankaj Dev 								USB_SETUP_PACKET_SIZE, 1);
2383*867cd155SPankaj Dev 	assert(dwc3_handle->setup_dma_addr != 0U);
2384*867cd155SPankaj Dev 
2385*867cd155SPankaj Dev 	dwc3_handle->setup_addr = SETUP_AREA;
2386*867cd155SPankaj Dev 	assert(dwc3_handle->setup_addr != NULL);
2387*867cd155SPankaj Dev 
2388*867cd155SPankaj Dev 	/* Map DMA and Coherent address for event buffers k = USB_DWC3_INT_INUSE */
2389*867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
2390*867cd155SPankaj Dev 		dwc3_handle->intbuffers.evtbuffer_dma_addr[i] =
2391*867cd155SPankaj Dev 			api_getdmaaddr((void *)EVTBUF_AREA, USB_DWC3_EVENT_BUFFER_SIZE, 1);
2392*867cd155SPankaj Dev 		assert(dwc3_handle->intbuffers.evtbuffer_dma_addr[i] != 0U);
2393*867cd155SPankaj Dev 
2394*867cd155SPankaj Dev 		dwc3_handle->intbuffers.evtbuffer_addr[i] = EVTBUF_AREA;
2395*867cd155SPankaj Dev 		assert(dwc3_handle->intbuffers.evtbuffer_addr[i] != NULL);
2396*867cd155SPankaj Dev 
2397*867cd155SPankaj Dev 		dwc3_handle->intbuffers.evtbufferpos[i] = 0;
2398*867cd155SPankaj Dev 
2399*867cd155SPankaj Dev 		INFO("EventBuffer%u: BuffArea=%lx DmaAddr=%08x CoherentMapAddr=%p\n", i,
2400*867cd155SPankaj Dev 			   (PHYS_AREA + EVTBUF_AREA_OFFSET),
2401*867cd155SPankaj Dev 			   (uint32_t)dwc3_handle->intbuffers.evtbuffer_dma_addr[i],
2402*867cd155SPankaj Dev 			   dwc3_handle->intbuffers.evtbuffer_addr[i]);
2403*867cd155SPankaj Dev 	}
2404*867cd155SPankaj Dev 
2405*867cd155SPankaj Dev 	/* MAP TRB Coherent and DMA address for EP0IN and EP0OUT */
2406*867cd155SPankaj Dev 	dwc3_handle->IN_ep[0].trb_dma_addr = (uint32_t)api_getdmaaddr((void *)TRB_IN_AREA,
2407*867cd155SPankaj Dev 								      sizeof(usb_dwc3_trb_t), 1);
2408*867cd155SPankaj Dev 	assert(dwc3_handle->IN_ep[0].trb_dma_addr != 0U);
2409*867cd155SPankaj Dev 
2410*867cd155SPankaj Dev 	dwc3_handle->IN_ep[0].trb_addr = (usb_dwc3_trb_t *)TRB_IN_AREA;
2411*867cd155SPankaj Dev 	assert(dwc3_handle->IN_ep[0].trb_addr != NULL);
2412*867cd155SPankaj Dev 
2413*867cd155SPankaj Dev 	dwc3_handle->OUT_ep[0].trb_dma_addr = (uint32_t)api_getdmaaddr((void *)TRB_OUT_AREA,
2414*867cd155SPankaj Dev 								       sizeof(usb_dwc3_trb_t),
2415*867cd155SPankaj Dev 								       1);
2416*867cd155SPankaj Dev 	assert(dwc3_handle->OUT_ep[0].trb_dma_addr != 0U);
2417*867cd155SPankaj Dev 
2418*867cd155SPankaj Dev 	dwc3_handle->OUT_ep[0].trb_addr = (usb_dwc3_trb_t *)TRB_OUT_AREA;
2419*867cd155SPankaj Dev 	assert(dwc3_handle->OUT_ep[0].trb_addr != NULL);
2420*867cd155SPankaj Dev 
2421*867cd155SPankaj Dev 	/* Init Device */
2422*867cd155SPankaj Dev 	dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
2423*867cd155SPankaj Dev 
2424*867cd155SPankaj Dev 	ret = dwc3_dev_init(dwc3_handle, USB_DWC3_SPEED_HIGH, PCD_DEV_EVENTS_INTR);
2425*867cd155SPankaj Dev 	assert(ret == USBD_OK);
2426*867cd155SPankaj Dev 
2427*867cd155SPankaj Dev 	dwc3_handle->State = HAL_PCD_STATE_READY;
2428*867cd155SPankaj Dev 
2429*867cd155SPankaj Dev 	register_usb_driver(usb_core_handle, pcd_handle, &usb_dwc3driver,
2430*867cd155SPankaj Dev 			    dwc3_handle);
2431*867cd155SPankaj Dev }
2432