xref: /rk3399_ARM-atf/drivers/st/usb_dwc3/usb_dwc3.c (revision c79a2739ac81af3e7ea89a53de44e6b4e78099bb)
1867cd155SPankaj Dev /*
2867cd155SPankaj Dev  * Copyright (c) 2015-2025, STMicroelectronics - All Rights Reserved
3867cd155SPankaj Dev  *
4867cd155SPankaj Dev  * SPDX-License-Identifier: BSD-3-Clause
5867cd155SPankaj Dev  */
6867cd155SPankaj Dev 
7867cd155SPankaj Dev #include <assert.h>
8867cd155SPankaj Dev #include <stdint.h>
9867cd155SPankaj Dev 
10867cd155SPankaj Dev #include <arch_helpers.h>
11867cd155SPankaj Dev #include <common/debug.h>
12867cd155SPankaj Dev #include <drivers/delay_timer.h>
13867cd155SPankaj Dev #include <drivers/st/usb_dwc3.h>
14867cd155SPankaj Dev #include <lib/mmio.h>
15867cd155SPankaj Dev #include <lib/utils.h>
16867cd155SPankaj Dev #include <lib/xlat_tables/xlat_tables_v2.h>
17867cd155SPankaj Dev 
18867cd155SPankaj Dev #include "usb_dwc3_regs.h"
19867cd155SPankaj Dev 
20867cd155SPankaj Dev /*
21867cd155SPankaj Dev  * @brief USB EP Type
22867cd155SPankaj Dev  */
23867cd155SPankaj Dev #define EP_TYPE_CTRL	0U
24867cd155SPankaj Dev #define EP_TYPE_ISOC	1U
25867cd155SPankaj Dev #define EP_TYPE_BULK	2U
26867cd155SPankaj Dev #define EP_TYPE_INTR	3U
27867cd155SPankaj Dev #define EP_TYPE_MSK	3U
28867cd155SPankaj Dev 
29867cd155SPankaj Dev #define USB_DWC3_GLOBAL_BASE	0xc100
30867cd155SPankaj Dev #define USB_DWC3_DEVICE_BASE	0xc700
31867cd155SPankaj Dev 
32867cd155SPankaj Dev /* Global Registers */
33867cd155SPankaj Dev #define DWC3_GSBUSCFG0	_DWC3_GSBUSCFG0
34867cd155SPankaj Dev #define DWC3_GSBUSCFG1	_DWC3_GSBUSCFG1
35867cd155SPankaj Dev #define DWC3_GTXTHRCFG	_DWC3_GTXTHRCFG
36867cd155SPankaj Dev #define DWC3_GRXTHRCFG	_DWC3_GRXTHRCFG
37867cd155SPankaj Dev #define DWC3_GCTL	_DWC3_GCTL
38867cd155SPankaj Dev #define DWC3_GEVTEN	_DWC3_GEVTEN
39867cd155SPankaj Dev #define DWC3_GSTS	_DWC3_GSTS
40867cd155SPankaj Dev #define DWC3_GUCTL1	_DWC3_GUCTL1
41867cd155SPankaj Dev #define DWC3_GSNPSID	_DWC3_GSNPSID
42867cd155SPankaj Dev #define DWC3_GGPIO	_DWC3_GGPIO
43867cd155SPankaj Dev #define DWC3_GUID	_DWC3_GUID
44867cd155SPankaj Dev #define DWC3_GUCTL	_DWC3_GUCTL
45867cd155SPankaj Dev #define DWC3_GBUSERRADDR0	_DWC3_GBUSERRADDRLO
46867cd155SPankaj Dev #define DWC3_GBUSERRADDR1	_DWC3_GBUSERRADDRHI
47867cd155SPankaj Dev #define DWC3_GPRTBIMAP0	_DWC3_GPRTBIMAPLO
48867cd155SPankaj Dev #define DWC3_GPRTBIMAP1	_DWC3_GPRTBIMAPHI
49867cd155SPankaj Dev #define DWC3_GHWPARAMS0	_DWC3_GHWPARAMS0
50867cd155SPankaj Dev #define DWC3_GHWPARAMS1	_DWC3_GHWPARAMS1
51867cd155SPankaj Dev #define DWC3_GHWPARAMS2	_DWC3_GHWPARAMS2
52867cd155SPankaj Dev #define DWC3_GHWPARAMS3	_DWC3_GHWPARAMS3
53867cd155SPankaj Dev #define DWC3_GHWPARAMS4	_DWC3_GHWPARAMS4
54867cd155SPankaj Dev #define DWC3_GHWPARAMS5	_DWC3_GHWPARAMS5
55867cd155SPankaj Dev #define DWC3_GHWPARAMS6	_DWC3_GHWPARAMS6
56867cd155SPankaj Dev #define DWC3_GHWPARAMS7	_DWC3_GHWPARAMS7
57867cd155SPankaj Dev #define DWC3_GDBGFIFOSPACE	_DWC3_GDBGFIFOSPACE
58867cd155SPankaj Dev #define DWC3_GDBGLTSSM	_DWC3_GDBGLTSSM
59867cd155SPankaj Dev #define DWC3_GPRTBIMAP_HS0	_DWC3_GPRTBIMAP_HSLO
60867cd155SPankaj Dev #define DWC3_GPRTBIMAP_HS1	_DWC3_GPRTBIMAP_HSHI
61867cd155SPankaj Dev #define DWC3_GPRTBIMAP_FS0	_DWC3_GPRTBIMAP_FSLO
62867cd155SPankaj Dev #define DWC3_GPRTBIMAP_FS1	_DWC3_GPRTBIMAP_FSHI
63867cd155SPankaj Dev #define DWC3_GUCTL2	_DWC3_GUCTL2
64867cd155SPankaj Dev 
65867cd155SPankaj Dev #define DWC3_GUSB2PHYCFG(n)	(_DWC3_GUSB2PHYCFG + (4UL * (n)))
66867cd155SPankaj Dev #define DWC3_GUSB2I2CCTL(n)	(_DWC3_GUSB2I2CCTL + (4UL * (n)))
67867cd155SPankaj Dev 
68867cd155SPankaj Dev #define DWC3_GUSB2PHYACC(n)	(_DWC3_GUSB2PHYACC + (4UL * (n)))
69867cd155SPankaj Dev 
70867cd155SPankaj Dev #define DWC3_GUSB3PIPECTL(n)	(_DWC3_GUSB3PIPECTL + (4UL * (n)))
71867cd155SPankaj Dev 
72867cd155SPankaj Dev #define DWC3_GTXFIFOSIZ(n)	(_DWC3_GTXFIFOSIZ0 + (4UL * (n)))
73867cd155SPankaj Dev #define DWC3_GRXFIFOSIZ(n)	(_DWC3_GRXFIFOSIZ0 + (4UL * (n)))
74867cd155SPankaj Dev 
75867cd155SPankaj Dev #define DWC3_GEVNTADRLO(n)	(_DWC3_GEVNTADRLO + (16UL * (n)))
76867cd155SPankaj Dev #define DWC3_GEVNTADRHI(n)	(_DWC3_GEVNTADRHI + (16UL * (n)))
77867cd155SPankaj Dev #define DWC3_GEVNTSIZ(n)	(_DWC3_GEVNTSIZ + (16UL * (n)))
78867cd155SPankaj Dev #define DWC3_GEVNTCOUNT(n)	(_DWC3_GEVNTCOUNT + (16UL * (n)))
79867cd155SPankaj Dev 
80867cd155SPankaj Dev #define DWC3_GUSB2PHYACC_ADDR(n)	((n) << USB3_GUSB2PHYACC_ULPI_REGADDR_POS)
81867cd155SPankaj Dev #define DWC3_GUSB2PHYACC_EXTEND_ADDR(n)	((n) << USB3_GUSB2PHYACC_ULPI_EXTREGADDR_POS)
82867cd155SPankaj Dev #define DWC3_GUSB2PHYACC_DATA(n)	((n) & USB3_GUSB2PHYACC_ULPI_REGDATA_MSK)
83867cd155SPankaj Dev 
84867cd155SPankaj Dev #define DWC3_GUCTL2_RST_ACTBITLATER	_DWC3_GUCTL2_RST_ACTBITLATER
85867cd155SPankaj Dev 
86867cd155SPankaj Dev /* Device Registers */
87867cd155SPankaj Dev #define DWC3_DCFG	_DWC3_DCFG
88867cd155SPankaj Dev #define DWC3_DCTL	_DWC3_DCTL
89867cd155SPankaj Dev #define DWC3_DEVTEN	_DWC3_DEVTEN
90867cd155SPankaj Dev #define DWC3_DSTS	_DWC3_DSTS
91867cd155SPankaj Dev #define DWC3_DGCMDPAR	_DWC3_DGCMDPAR
92867cd155SPankaj Dev #define DWC3_DGCMD	_DWC3_DGCMD
93867cd155SPankaj Dev #define DWC3_DALEPENA	_DWC3_DALEPENA
94867cd155SPankaj Dev #define DWC3_DEPCMDPAR2(n)	(_DWC3_DEPCMDPAR2 + (16UL * (n)))
95867cd155SPankaj Dev #define DWC3_DEPCMDPAR1(n)	(_DWC3_DEPCMDPAR1 + (16UL * (n)))
96867cd155SPankaj Dev #define DWC3_DEPCMDPAR0(n)	(_DWC3_DEPCMDPAR0 + (16UL * (n)))
97867cd155SPankaj Dev #define DWC3_DEPCMD(n)	(_DWC3_DEPCMD + (16UL * (n)))
98867cd155SPankaj Dev 
99867cd155SPankaj Dev /* The EP number goes 0..31 so ep0 is always out and ep1 is always in */
100867cd155SPankaj Dev #define DWC3_DALEPENA_EP(n)	(1UL << (n))
101867cd155SPankaj Dev 
102867cd155SPankaj Dev /*
103867cd155SPankaj Dev  * @brief USB EP Type
104867cd155SPankaj Dev  */
105867cd155SPankaj Dev #define EP_TYPE_CTRL	0U
106867cd155SPankaj Dev #define EP_TYPE_ISOC	1U
107867cd155SPankaj Dev #define EP_TYPE_BULK	2U
108867cd155SPankaj Dev #define EP_TYPE_INTR	3U
109867cd155SPankaj Dev #define EP_TYPE_MSK	3U
110867cd155SPankaj Dev 
111867cd155SPankaj Dev /* Event Size */
112867cd155SPankaj Dev #define USB_DWC3_EVENT_SIZE	4U
113867cd155SPankaj Dev 
114867cd155SPankaj Dev /* USB_ExecuteDevEPCmd::USB_DWC3_EPCmd */
115867cd155SPankaj Dev #define USB_DWC3_DEPCMD_DEPSTARTCFG	(0x09UL << USB3_DEPCMD_CMDTYP_POS)
116867cd155SPankaj Dev #define USB_DWC3_DEPCMD_ENDTRANSFER	(0x08UL << USB3_DEPCMD_CMDTYP_POS)
117867cd155SPankaj Dev #define USB_DWC3_DEPCMD_UPDATETRANSFER	(0x07UL << USB3_DEPCMD_CMDTYP_POS)
118867cd155SPankaj Dev #define USB_DWC3_DEPCMD_STARTTRANSFER	(0x06UL << USB3_DEPCMD_CMDTYP_POS)
119867cd155SPankaj Dev #define USB_DWC3_DEPCMD_CLEARSTALL	(0x05UL << USB3_DEPCMD_CMDTYP_POS)
120867cd155SPankaj Dev #define USB_DWC3_DEPCMD_SETSTALL	(0x04UL << USB3_DEPCMD_CMDTYP_POS)
121867cd155SPankaj Dev /* This applies for core versions 1.94a and later */
122867cd155SPankaj Dev #define USB_DWC3_DEPCMD_GETEPSTATE	(0x03UL << USB3_DEPCMD_CMDTYP_POS)
123867cd155SPankaj Dev #define USB_DWC3_DEPCMD_SETTRANSFRESOURCE	(0x02UL << USB3_DEPCMD_CMDTYP_POS)
124867cd155SPankaj Dev #define USB_DWC3_DEPCMD_SETEPCONFIG	(0x01UL << USB3_DEPCMD_CMDTYP_POS)
125867cd155SPankaj Dev 
126867cd155SPankaj Dev /* USB_ConfigureEP::action */
127867cd155SPankaj Dev #define USB_DWC3_DEPCFG_ACTION_INIT	0
128867cd155SPankaj Dev #define USB_DWC3_DEPCFG_ACTION_RESTORE	1
129867cd155SPankaj Dev #define USB_DWC3_DEPCFG_ACTION_MODIFY	2
130867cd155SPankaj Dev 
131867cd155SPankaj Dev /* USB_ReadEndpointEventType @return EPEventType */
132867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERCOMPLETE	0x01
133867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERINPROGRESS	0x02
134867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERNOTREADY	0x03
135867cd155SPankaj Dev #define USB_DWC3_DEPEVT_RXTXFIFOEVT	0x04
136867cd155SPankaj Dev #define USB_DWC3_DEPEVT_STREAMEVT	0x06
137867cd155SPankaj Dev #define USB_DWC3_DEPEVT_EPCMDCMPLT	0x07
138867cd155SPankaj Dev 
139867cd155SPankaj Dev /* USB_ReadEndpointEventStatus @return EPEventStatus */
140867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_DATA	0x01
141867cd155SPankaj Dev #define USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_STATUS	0x02
142867cd155SPankaj Dev 
143867cd155SPankaj Dev /* USB_ReadDeviceEventType @return DevEventType */
144867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_DISCONNECT	0
145867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_RESET	1
146867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_CONNECT_DONE	2
147867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE	3
148867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_WAKEUP	4
149867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_HIBER_REQ	5
150867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_EOPF	6
151867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_SOF	7
152867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_L1SUSPEND	8
153867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_ERRATIC_ERROR	9
154867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_CMD_CMPL	10
155867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_OVERFLOW	11
156867cd155SPankaj Dev #define USB_DWC3_DEVICE_EVENT_L1WAKEUP	14
157867cd155SPankaj Dev 
158867cd155SPankaj Dev #define USB_DWC3_TRBSTS_OK	0
159867cd155SPankaj Dev #define USB_DWC3_TRBSTS_MISSED_ISOC	1
160867cd155SPankaj Dev #define USB_DWC3_TRBSTS_SETUP_PENDING	2
161867cd155SPankaj Dev #define USB_DWC3_TRBSTS_XFER_IN_PROG	4
162867cd155SPankaj Dev 
163867cd155SPankaj Dev #define USB_DWC3_SPEED_SUPER	0U
164867cd155SPankaj Dev #define USB_DWC3_SPEED_HIGH	1U
165867cd155SPankaj Dev #define USB_DWC3_SPEED_FULL_48	2U
166867cd155SPankaj Dev #define USB_DWC3_SPEED_FULL	3U
167867cd155SPankaj Dev #define USB_DWC3_SPEED_LOW	4U
168867cd155SPankaj Dev #define USB_DWC3_SPEED_INVALID	15U
169867cd155SPankaj Dev 
170867cd155SPankaj Dev #define DWC3_DEPCMD_TYPE_CONTROL	0
171867cd155SPankaj Dev #define DWC3_DEPCMD_TYPE_ISOC	1
172867cd155SPankaj Dev #define DWC3_DEPCMD_TYPE_BULK	2
173867cd155SPankaj Dev #define DWC3_DEPCMD_TYPE_INTR	3
174867cd155SPankaj Dev 
175867cd155SPankaj Dev #define DWC3_GCTL_PRTCAP(n)	(((n) & USB3_GCTL_PRTCAPDIR_MSK) >> USB3_GCTL_PRTCAPDIR_POS)
176867cd155SPankaj Dev #define DWC3_GCTL_PRTCAPDIR(n)	((n) << USB3_GCTL_PRTCAPDIR_POS)
177867cd155SPankaj Dev #define DWC3_GCTL_PRTCAP_HOST	1
178867cd155SPankaj Dev #define DWC3_GCTL_PRTCAP_DEVICE	2
179867cd155SPankaj Dev #define DWC3_GCTL_PRTCAP_OTG	3
180867cd155SPankaj Dev 
181867cd155SPankaj Dev #define DWC3_DSTS_SUPERSPEED	(4U << USB3_DSTS_CONNECTSPD_POS)
182867cd155SPankaj Dev #define DWC3_DSTS_HIGHSPEED	(0U << USB3_DSTS_CONNECTSPD_POS)
183867cd155SPankaj Dev #define DWC3_DSTS_FULLSPEED2	BIT(USB3_DSTS_CONNECTSPD_POS)
184867cd155SPankaj Dev #define DWC3_DSTS_LOWSPEED	(2U << USB3_DSTS_CONNECTSPD_POS)
185867cd155SPankaj Dev #define DWC3_DSTS_FULLSPEED1	(3U << USB3_DSTS_CONNECTSPD_POS)
186867cd155SPankaj Dev 
187867cd155SPankaj Dev #define DWC3_GEVNTCOUNT_MASK	0xfffcU
188867cd155SPankaj Dev #define DWC3_GSNPSID_MASK	0xffff0000
189867cd155SPankaj Dev #define DWC3_GSNPSREV_MASK	0xffff
190867cd155SPankaj Dev 
191867cd155SPankaj Dev #define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
192867cd155SPankaj Dev 
193867cd155SPankaj Dev #define DWC3_EVENT_TYPE_DEV	0
194867cd155SPankaj Dev #define DWC3_EVENT_TYPE_CARKIT	3
195867cd155SPankaj Dev #define DWC3_EVENT_TYPE_I2C	4
196867cd155SPankaj Dev 
197867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_DISCONNECT	0
198867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_RESET	1
199867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_CONNECT_DONE	2
200867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE	3
201867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_WAKEUP	4
202867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_HIBER_REQ	5
203867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_EOPF	6
204867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_SOF	7
205867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_ERRATIC_ERROR	9
206867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_CMD_CMPL	10
207867cd155SPankaj Dev #define DWC3_DEVICE_EVENT_OVERFLOW	11
208867cd155SPankaj Dev 
209867cd155SPankaj Dev /* DEPCFG parameter 1 */
210867cd155SPankaj Dev #define DWC3_DEPCFG_INT_NUM(n)	(((n) & 0x1f) << 0)
211867cd155SPankaj Dev #define DWC3_DEPCFG_XFER_COMPLETE_EN	BIT(8)
212867cd155SPankaj Dev #define DWC3_DEPCFG_XFER_IN_PROGRESS_EN	BIT(9)
213867cd155SPankaj Dev #define DWC3_DEPCFG_XFER_NOT_READY_EN	BIT(10)
214867cd155SPankaj Dev #define DWC3_DEPCFG_FIFO_ERROR_EN	BIT(11)
215867cd155SPankaj Dev #define DWC3_DEPCFG_STREAM_EVENT_EN	BIT(13)
216867cd155SPankaj Dev #define DWC3_DEPCFG_BINTERVAL_M1(n)	(((n) & 0xffU) << 16)
217867cd155SPankaj Dev #define DWC3_DEPCFG_STREAM_CAPABLE	BIT(24)
218867cd155SPankaj Dev #define DWC3_DEPCFG_EP_NUMBER(n)	(((n) & 0x1fUL) << 25)
219867cd155SPankaj Dev #define DWC3_DEPCFG_BULK_BASED	BIT(30)
220867cd155SPankaj Dev #define DWC3_DEPCFG_FIFO_BASED	BIT(31)
221867cd155SPankaj Dev 
222867cd155SPankaj Dev /* DEPCFG parameter 0 */
223867cd155SPankaj Dev #define DWC3_DEPCFG_EP_TYPE(n)	(((n) & 0x3UL) << 1)
224867cd155SPankaj Dev #define DWC3_DEPCFG_MAX_PACKET_SIZE(n)	(((n) & 0x7ffU) << 3)
225867cd155SPankaj Dev #define DWC3_DEPCFG_FIFO_NUMBER(n)	(((n) & 0x1fUL) << 17)
226867cd155SPankaj Dev #define DWC3_DEPCFG_BURST_SIZE(n)	(((n) & 0xf) << 22)
227867cd155SPankaj Dev #define DWC3_DEPCFG_DATA_SEQ_NUM(n)	((n) << 26)
228867cd155SPankaj Dev /* DEPCFG parameter 1 */
229867cd155SPankaj Dev #define DWC3_DEPCFG_EP_INTR_NUM(n)	((n) & 0x1fUL)
230867cd155SPankaj Dev /* This applies for core versions earlier than 1.94a */
231867cd155SPankaj Dev #define DWC3_DEPCFG_IGN_SEQ_NUM	BIT(31)
232867cd155SPankaj Dev /* These apply for core versions 1.94a and later */
233867cd155SPankaj Dev #define DWC3_DEPCFG_ACTION_INIT	(0U << 30)
234867cd155SPankaj Dev #define DWC3_DEPCFG_ACTION_RESTORE	BIT(30)
235867cd155SPankaj Dev #define DWC3_DEPCFG_ACTION_MODIFY	(2U << 30)
236867cd155SPankaj Dev #define DWC3_DEPCFG_ACTION_VALUE(n)	(((n) & 0x3) << 30)
237867cd155SPankaj Dev 
238867cd155SPankaj Dev /* DEPXFERCFG parameter 0 */
239867cd155SPankaj Dev #define DWC3_DEPXFERCFG_NUM_XFER_RES(n)	((n) & 0xffffU)
240867cd155SPankaj Dev 
241867cd155SPankaj Dev #define DWC3_DEPCMD_GET_RSC_IDX(x)	(((x) >> USB3_DEPCMD_COMMANDPARAM_POS) & 0x7fU)
242867cd155SPankaj Dev #define DWC3_DEPCMD_STATUS(x)	(((x) & USB3_DEPCMD_CMDSTATUS_MSK) >> 12)
243867cd155SPankaj Dev #define DWC3_DGCMD_STATUS(n)	(((n) & USB3_DGCMD_CMDSTATUS_MSK) >> USB3_DGCMD_CMDSTATUS_POS)
244867cd155SPankaj Dev 
245867cd155SPankaj Dev #define DWC3_DEPCMD_PARAM(x)	((x) << USB3_DEPCMD_COMMANDPARAM_POS)
246867cd155SPankaj Dev 
247867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_U0	0x00 /* in HS, means ON */
248867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_U1	0x01
249867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_U2	0x02 /* in HS, means SLEEP */
250867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_U3	0x03 /* in HS, means SUSPEND */
251867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_DIS	0x04 /* Default State */
252867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_RX_DET	0x05 /* in HS, means Early Suspend */
253867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_INACT	0x06
254867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_POLL	0x07
255867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_RECOV	0x08
256867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_HRESET	0x09
257867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_CMPLY	0x0a
258867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_LPBK	0x0b
259867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_RESET	0x0e
260867cd155SPankaj Dev #define DWC3_LINK_STATE_SS_RESUME	0x0f
261867cd155SPankaj Dev 
262867cd155SPankaj Dev #define DWC3_LINK_STATE_ON	0x00U /* in HS, means ON */
263867cd155SPankaj Dev #define DWC3_LINK_STATE_L1	0x02U /* in HS, means SLEEP */
264867cd155SPankaj Dev #define DWC3_LINK_STATE_L2	0x03U /* in HS, means SUSPEND */
265867cd155SPankaj Dev #define DWC3_LINK_STATE_DIS	0x04U /* Default State */
266867cd155SPankaj Dev #define DWC3_LINK_STATE_EARLY_SUS	0x05U /* in HS, means Early Suspend */
267867cd155SPankaj Dev #define DWC3_LINK_STATE_RESET	0x0eU
268867cd155SPankaj Dev #define DWC3_LINK_STATE_RESUME	0x0fU
269867cd155SPankaj Dev 
270867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_NO_ACTION	0
271867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_SS_DISABLED	4
272867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_RX_DETECT	5
273867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_SS_INACTIVE	6
274867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_RECOVERY	8
275867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_COMPLIANCE	10
276867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNG_LOOPBACK	11
277867cd155SPankaj Dev 
278867cd155SPankaj Dev #define DWC3_DCTL_ULSTCHNGREQ(n)	(((n) << USB3_DCTL_ULSTCHNGREQ_POS) & \
279867cd155SPankaj Dev 					USB3_DCTL_ULSTCHNGREQ_MSK)
280867cd155SPankaj Dev 
281867cd155SPankaj Dev #define DWC3_DSTS_USBLNKST(n)	(((n) & USB3_DSTS_USBLNKST_MSK) >> USB3_DSTS_USBLNKST_POS)
282867cd155SPankaj Dev 
283867cd155SPankaj Dev /* TRB Length, PCM and Status */
284867cd155SPankaj Dev #define DWC3_TRB_SIZE_MASK	(0x00ffffffU)
285867cd155SPankaj Dev #define DWC3_TRB_SIZE_LENGTH(n)	((n) & DWC3_TRB_SIZE_MASK)
286867cd155SPankaj Dev #define DWC3_TRB_SIZE_PCM1(n)	(((n) & 0x03) << 24)
287867cd155SPankaj Dev #define DWC3_TRB_SIZE_TRBSTS(n)	(((n) & (0x0fU << 28)) >> 28)
288867cd155SPankaj Dev 
289867cd155SPankaj Dev #define DWC3_TRBSTS_OK	0
290867cd155SPankaj Dev #define DWC3_TRBSTS_MISSED_ISOC	1
291867cd155SPankaj Dev #define DWC3_TRBSTS_SETUP_PENDING	2
292867cd155SPankaj Dev #define DWC3_TRBSTS_XFER_IN_PROG	4
293867cd155SPankaj Dev 
294867cd155SPankaj Dev /* TRB Control */
295867cd155SPankaj Dev #define DWC3_TRB_CTRL_HWO	BIT(0)
296867cd155SPankaj Dev #define DWC3_TRB_CTRL_LST	BIT(1)
297867cd155SPankaj Dev #define DWC3_TRB_CTRL_CHN	BIT(2)
298867cd155SPankaj Dev #define DWC3_TRB_CTRL_CSP	BIT(3)
299867cd155SPankaj Dev #define DWC3_TRB_CTRL_TRBCTL(n)	(((n) & 0x3fU) << 4)
300867cd155SPankaj Dev #define DWC3_TRB_CTRL_ISP_IMI	BIT(10)
301867cd155SPankaj Dev #define DWC3_TRB_CTRL_IOC	BIT(11)
302867cd155SPankaj Dev #define DWC3_TRB_CTRL_SID_SOFN(n)	(((n) & 0xffffU) << 14)
303867cd155SPankaj Dev 
304867cd155SPankaj Dev #define DWC3_TRBCTL_NORMAL	DWC3_TRB_CTRL_TRBCTL(1U)
305867cd155SPankaj Dev #define DWC3_TRBCTL_CONTROL_SETUP	DWC3_TRB_CTRL_TRBCTL(2U)
306867cd155SPankaj Dev #define DWC3_TRBCTL_CONTROL_STATUS2	DWC3_TRB_CTRL_TRBCTL(3U)
307867cd155SPankaj Dev #define DWC3_TRBCTL_CONTROL_STATUS3	DWC3_TRB_CTRL_TRBCTL(4U)
308867cd155SPankaj Dev #define DWC3_TRBCTL_CONTROL_DATA	DWC3_TRB_CTRL_TRBCTL(5U)
309867cd155SPankaj Dev #define DWC3_TRBCTL_ISOCHRONOUS_FIRST	DWC3_TRB_CTRL_TRBCTL(6U)
310867cd155SPankaj Dev #define DWC3_TRBCTL_ISOCHRONOUS	DWC3_TRB_CTRL_TRBCTL(7U)
311867cd155SPankaj Dev #define DWC3_TRBCTL_LINK_TRB	DWC3_TRB_CTRL_TRBCTL(8U)
312867cd155SPankaj Dev 
313867cd155SPankaj Dev #define _MASK(len, pos)	GENMASK_32((len-1) + pos, pos)
314867cd155SPankaj Dev 
315867cd155SPankaj Dev /* event */
316867cd155SPankaj Dev #define DWC3_EVT_TYPE_EP	0x0U
317867cd155SPankaj Dev #define DWC3_EVT_TYPE_LEN	0x1
318867cd155SPankaj Dev #define DWC3_EVT_TYPE_BITPOS	0x0
319867cd155SPankaj Dev #define DWC3_EVT_TYPE_MASK	_MASK(DWC3_EVT_TYPE_LEN, DWC3_EVT_TYPE_BITPOS)
320867cd155SPankaj Dev #define DWC3_EVT_TYPE_DEVSPEC	0x1U
321867cd155SPankaj Dev #define DWC3_EVT_TYPE_NEP_TYPE_BITPOS	1
322867cd155SPankaj Dev #define DWC3_EVT_TYPE_NEP_TYPE_LEN	7
323867cd155SPankaj Dev #define DWC3_EVT_TYPE_NEP_TYPE_MASK	_MASK(DWC3_EVT_TYPE_NEP_TYPE_LEN, \
324867cd155SPankaj Dev 					      DWC3_EVT_TYPE_NEP_TYPE_BITPOS)
325867cd155SPankaj Dev 
326867cd155SPankaj Dev #define DWC3_DEPEVT_XFERCOMPLETE	0x01
327867cd155SPankaj Dev #define DWC3_DEPEVT_XFERINPROGRESS	0x02
328867cd155SPankaj Dev #define DWC3_DEPEVT_XFERNOTREADY	0x03
329867cd155SPankaj Dev #define DWC3_DEPEVT_RXTXFIFOEVT	0x04
330867cd155SPankaj Dev #define DWC3_DEPEVT_STREAMEVT	0x06
331867cd155SPankaj Dev #define DWC3_DEPEVT_EPCMDCMPLT	0x07
332867cd155SPankaj Dev 
333867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_TYPE_BITPOS	6
334867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_TYPE_LEN	4
335867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_TYPE_MASK	_MASK(DWC3_EVT_DEPEVT_TYPE_LEN, DWC3_EVT_DEPEVT_TYPE_BITPOS)
336867cd155SPankaj Dev 
337867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_EPNUM_BITPOS	1
338867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_EPNUM_LEN	5
339867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_EPNUM_MASK	_MASK(DWC3_EVT_DEPEVT_EPNUM_LEN, \
340867cd155SPankaj Dev 					      DWC3_EVT_DEPEVT_EPNUM_BITPOS)
341867cd155SPankaj Dev 
342867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_BITPOS	12
343867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_LEN	4
344867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_MASK	_MASK(DWC3_EVT_DEPEVT_STATUS_LEN, \
345867cd155SPankaj Dev 					      DWC3_EVT_DEPEVT_STATUS_BITPOS)
346867cd155SPankaj Dev 
347867cd155SPankaj Dev /* Control-only Status */
348867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_CONTROL_DATA	1
349867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_STATUS_CONTROL_STATUS	2
350867cd155SPankaj Dev 
351867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_PARAM_BITPOS	16
352867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_PARAM_LEN	16
353867cd155SPankaj Dev #define DWC3_EVT_DEPEVT_PARAM_MASK	_MASK(DWC3_EVT_DEPEVT_PARAM_LEN, \
354867cd155SPankaj Dev 					      DWC3_EVT_DEPEVT_PARAM_BITPOS)
355867cd155SPankaj Dev 
356867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_TYPE_BITPOS	8
357867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_TYPE_LEN	4
358867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_TYPE_MASK	_MASK(DWC3_EVT_DEVEVT_TYPE_LEN, DWC3_EVT_DEVEVT_TYPE_BITPOS)
359867cd155SPankaj Dev 
360867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_LNKSTS_BITPOS	16
361867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_LNKSTS_LEN	4
362867cd155SPankaj Dev #define DWC3_EVT_DEVEVT_LNKSTS_MASK	_MASK(DWC3_EVT_DEVEVT_LNKSTS_LEN, \
363867cd155SPankaj Dev 					DWC3_EVT_DEVEVT_LNKSTS_BITPOS)
364867cd155SPankaj Dev 
365867cd155SPankaj Dev /* Bit fields for USB3_GCTL register */
366867cd155SPankaj Dev #define USB3_GCTL_CORESOFTRESET	_DWC3_GCTL_CORESOFTRESET
367867cd155SPankaj Dev #define USB3_GCTL_PRTCAPDIR_POS	_DWC3_GCTL_PRTCAPDIR_SHIFT
368867cd155SPankaj Dev #define USB3_GCTL_PRTCAPDIR_MSK	_DWC3_GCTL_PRTCAPDIR_MASK
369867cd155SPankaj Dev 
370867cd155SPankaj Dev /* Bit fields for USB3_GUSB2PHYCFG register */
371867cd155SPankaj Dev #define USB3_GUSB2PHYCFG_ULPI_UTMI_SEL	_DWC3_GUSB2PHYCFG_ULPI_UTMI_SEL
372867cd155SPankaj Dev #define USB3_GUSB2PHYCFG_PHYSOFTRST	_DWC3_GUSB2PHYCFG_PHYSOFTRST
373867cd155SPankaj Dev 
374867cd155SPankaj Dev /* Bit fields for USB3_GUSB3PIPECTL register */
375867cd155SPankaj Dev #define USB3_GUSB3PIPECTL_PHYSOFTRST	_DWC3_GUSB3PIPECTL_PHYSOFTRST
376867cd155SPankaj Dev 
377867cd155SPankaj Dev /* Bit fields for USB3_GEVNTSIZ register */
378867cd155SPankaj Dev #define USB3_GEVNTSIZ_EVNTINTRPTMASK_MSK	_DWC3_GEVNTSIZ_EVNTINTRPTMASK
379867cd155SPankaj Dev 
380867cd155SPankaj Dev /* Bit fields for USB3_DCFG register */
381867cd155SPankaj Dev #define USB3_DCFG_DEVSPD_POS	_DWC3_DCFG_DEVSPD_SHIFT
382867cd155SPankaj Dev #define USB3_DCFG_DEVSPD_MSK	_DWC3_DCFG_DEVSPD_MASK
383867cd155SPankaj Dev #define USB3_DCFG_DEVADDR_POS	_DWC3_DCFG_DEVADDR_SHIFT
384867cd155SPankaj Dev #define USB3_DCFG_DEVADDR_MSK	_DWC3_DCFG_DEVADDR_MASK
385867cd155SPankaj Dev #define USB3_DCFG_INTRNUM_POS	_DWC3_DCFG_INTRNUM_SHIFT
386867cd155SPankaj Dev #define USB3_DCFG_INTRNUM_MSK	_DWC3_DCFG_INTRNUM_MASK
387867cd155SPankaj Dev #define USB3_DCFG_NUMP_POS	_DWC3_DCFG_NUMP_SHIFT
388867cd155SPankaj Dev #define USB3_DCFG_NUMP_MSK	_DWC3_DCFG_NUMP_MASK
389867cd155SPankaj Dev #define USB3_DCFG_LPMCAP	_DWC3_DCFG_LPMCAP
390867cd155SPankaj Dev #define USB3_DCFG_IGNSTRMPP	_DWC3_DCFG_IGNSTRMPP
391867cd155SPankaj Dev 
392867cd155SPankaj Dev /* Bit fields for USB3_DCTL register */
393867cd155SPankaj Dev #define USB3_DCTL_TSTCTL_POS	_DWC3_DCTL_TSTCTL_SHIFT
394867cd155SPankaj Dev #define USB3_DCTL_TSTCTL_MSK	_DWC3_DCTL_TSTCTL_MASK
395867cd155SPankaj Dev #define USB3_DCTL_ULSTCHNGREQ_POS	_DWC3_DCTL_ULSTCHNGREQ_SHIFT
396867cd155SPankaj Dev #define USB3_DCTL_ULSTCHNGREQ_MSK	_DWC3_DCTL_ULSTCHNGREQ_MASK
397867cd155SPankaj Dev #define USB3_DCTL_ACCEPTU1ENA	_DWC3_DCTL_ACCEPTU1ENA
398867cd155SPankaj Dev #define USB3_DCTL_INITU1ENA	_DWC3_DCTL_INITU1ENA
399867cd155SPankaj Dev #define USB3_DCTL_ACCEPTU2ENA	_DWC3_DCTL_ACCEPTU2ENA
400867cd155SPankaj Dev #define USB3_DCTL_INITU2ENA	_DWC3_DCTL_INITU2ENA
401867cd155SPankaj Dev #define USB3_DCTL_CSS	_DWC3_DCTL_CSS
402867cd155SPankaj Dev #define USB3_DCTL_CRS	_DWC3_DCTL_CRS
403867cd155SPankaj Dev #define USB3_DCTL_L1HIBERNATIONEN	_DWC3_DCTL_L1HIBERNATIONEN
404867cd155SPankaj Dev #define USB3_DCTL_KEEPCONNECT	_DWC3_DCTL_KEEPCONNECT
405867cd155SPankaj Dev #define USB3_DCTL_LPM_NYET_THRES_POS	_DWC3_DCTL_LPM_NYET_THRES_SHIFT
406867cd155SPankaj Dev #define USB3_DCTL_LPM_NYET_THRES_MSK	_DWC3_DCTL_LPM_NYET_THRES_MASK
407867cd155SPankaj Dev #define USB3_DCTL_HIRDTHRES_POS	_DWC3_DCTL_HIRDTHRES_SHIFT
408867cd155SPankaj Dev #define USB3_DCTL_HIRDTHRES_MSK	_DWC3_DCTL_HIRDTHRES_MASK
409867cd155SPankaj Dev #define USB3_DCTL_CSFTRST	_DWC3_DCTL_CSFTRST
410867cd155SPankaj Dev #define USB3_DCTL_RUN_STOP	_DWC3_DCTL_RUN_STOP
411867cd155SPankaj Dev 
412867cd155SPankaj Dev /* Bit fields for USB3_DEVTEN register */
413867cd155SPankaj Dev #define USB3_DEVTEN_DISSCONNEVTEN	_DWC3_DEVTEN_DISSCONNEVTEN
414867cd155SPankaj Dev #define USB3_DEVTEN_USBRSTEVTEN	_DWC3_DEVTEN_USBRSTEVTEN
415867cd155SPankaj Dev #define USB3_DEVTEN_CONNECTDONEEVTEN	_DWC3_DEVTEN_CONNECTDONEEVTEN
416867cd155SPankaj Dev #define USB3_DEVTEN_ULSTCNGEN	_DWC3_DEVTEN_ULSTCNGEN
417867cd155SPankaj Dev #define USB3_DEVTEN_WKUPEVTEN	_DWC3_DEVTEN_WKUPEVTEN
418867cd155SPankaj Dev #define USB3_DEVTEN_HIBERNATIONREQEVTEN	_DWC3_DEVTEN_HIBERNATIONREQEVTEN
419867cd155SPankaj Dev #define USB3_DEVTEN_U3L2L1SUSPEN	_DWC3_DEVTEN_U3L2L1SUSPEN
420867cd155SPankaj Dev #define USB3_DEVTEN_SOFTEVTEN	_DWC3_DEVTEN_SOFTEVTEN
421867cd155SPankaj Dev #define USB3_DEVTEN_L1SUSPEN	_DWC3_DEVTEN_L1SUSPEN
422867cd155SPankaj Dev #define USB3_DEVTEN_ERRTICERREVTEN	_DWC3_DEVTEN_ERRTICERREVTEN
423867cd155SPankaj Dev #define USB3_DEVTEN_CMDCMPLTEN	_DWC3_DEVTEN_CMDCMPLTEN
424867cd155SPankaj Dev #define USB3_DEVTEN_EVNTOVERFLOWEN	_DWC3_DEVTEN_EVNTOVERFLOWEN
425867cd155SPankaj Dev #define USB3_DEVTEN_VENDEVTSTRCVDEN	_DWC3_DEVTEN_VENDEVTSTRCVDEN
426867cd155SPankaj Dev #define USB3_DEVTEN_L1WKUPEVTEN	_DWC3_DEVTEN_L1WKUPEVTEN
427867cd155SPankaj Dev #define USB3_DEVTEN_ECCERREN	_DWC3_DEVTEN_ECCERREN
428867cd155SPankaj Dev 
429867cd155SPankaj Dev /* Bit fields for USB3_DSTS register */
430867cd155SPankaj Dev #define USB3_DSTS_CONNECTSPD_POS	_DWC3_DSTS_CONNECTSPD_SHIFT
431867cd155SPankaj Dev #define USB3_DSTS_CONNECTSPD_MSK	_DWC3_DSTS_CONNECTSPD_MASK
432867cd155SPankaj Dev #define USB3_DSTS_CONNECTSPD	_DWC3_DSTS_CONNECTSPD_MASK
433867cd155SPankaj Dev #define USB3_DSTS_SOFFN_POS	_DWC3_DSTS_SOFFN_SHIFT
434867cd155SPankaj Dev #define USB3_DSTS_SOFFN_MSK	_DWC3_DSTS_SOFFN_MASK
435867cd155SPankaj Dev #define USB3_DSTS_RXFIFOEMPTY	_DWC3_DSTS_RXFIFOEMPTY
436867cd155SPankaj Dev #define USB3_DSTS_USBLNKST_POS	_DWC3_DSTS_USBLNKST_SHIFT
437867cd155SPankaj Dev #define USB3_DSTS_USBLNKST_MSK	_DWC3_DSTS_USBLNKST_MASK
438867cd155SPankaj Dev #define USB3_DSTS_DEVCTRLHLT	_DWC3_DSTS_DEVCTRLHLT
439867cd155SPankaj Dev #define USB3_DSTS_COREIDLE	_DWC3_DSTS_COREIDLE
440867cd155SPankaj Dev #define USB3_DSTS_SSS	_DWC3_DSTS_SSS
441867cd155SPankaj Dev #define USB3_DSTS_RSS	_DWC3_DSTS_RSS
442867cd155SPankaj Dev #define USB3_DSTS_SRE	_DWC3_DSTS_SRE
443867cd155SPankaj Dev #define USB3_DSTS_DCNRD	_DWC3_DSTS_DCNRD
444867cd155SPankaj Dev 
445867cd155SPankaj Dev /* Bit fields for USB3_DGCMD register */
446867cd155SPankaj Dev #define USB3_DGCMD_CMDTYP_POS	_DWC3_DEPCMD_CMDTYP_SHIFT
447867cd155SPankaj Dev #define USB3_DGCMD_CMDTYP_MSK	_DWC3_DEPCMD_CMDTYP_MASK
448867cd155SPankaj Dev #define USB3_DGCMD_CMDIOC	_DWC3_DGCMD_CMDIOC
449867cd155SPankaj Dev #define USB3_DGCMD_CMDACT	_DWC3_DGCMD_CMDACT
450867cd155SPankaj Dev #define USB3_DGCMD_CMDSTATUS_POS	_DWC3_DGCMD_CMDSTATUS_SHIFT
451867cd155SPankaj Dev #define USB3_DGCMD_CMDSTATUS_MSK	_DWC3_DGCMD_CMDSTATUS_MASK
452867cd155SPankaj Dev 
453867cd155SPankaj Dev /* Bit fields for USB3_DEPCMD register */
454867cd155SPankaj Dev #define USB3_DEPCMD_CMDTYP_POS	_DWC3_DEPCMD_CMDTYP_SHIFT
455867cd155SPankaj Dev #define USB3_DEPCMD_CMDTYP_MSK	_DWC3_DEPCMD_CMDTYP_MASK
456867cd155SPankaj Dev #define USB3_DEPCMD_CMDTYP	_DWC3_DEPCMD_CMDTYP_MASK
457867cd155SPankaj Dev #define USB3_DEPCMD_CMDIOC	_DWC3_DEPCMD_CMDIOC
458867cd155SPankaj Dev #define USB3_DEPCMD_CMDACT	_DWC3_DEPCMD_CMDACT
459867cd155SPankaj Dev #define USB3_DEPCMD_HIPRI_FORCERM	_DWC3_DEPCMD_HIPRI_FORCERM
460867cd155SPankaj Dev #define USB3_DEPCMD_CMDSTATUS_POS	_DWC3_DEPCMD_CMDSTATUS_SHIFT
461867cd155SPankaj Dev #define USB3_DEPCMD_CMDSTATUS_MSK	_DWC3_DEPCMD_CMDSTATUS_MASK
462867cd155SPankaj Dev #define USB3_DEPCMD_COMMANDPARAM_POS	_DWC3_DEPCMD_COMMANDPARAM_SHIFT
463867cd155SPankaj Dev #define USB3_DEPCMD_COMMANDPARAM_MSK	_DWC3_DEPCMD_COMMANDPARAM_MASK
464867cd155SPankaj Dev 
465867cd155SPankaj Dev /* Bit fields for USB3_DEV_IMOD register */
466867cd155SPankaj Dev #define USB3_DEV_IMOD_DEVICE_IMODI_POS	_DWC3_DEV_IMOD_DEVICE_IMODI_SHIFT
467867cd155SPankaj Dev #define USB3_DEV_IMOD_DEVICE_IMODI_MSK	_DWC3_DEV_IMOD_DEVICE_IMODI_MASK
468867cd155SPankaj Dev #define USB3_DEV_IMOD_DEVICE_IMODC_POS	_DWC3_DEV_IMOD_DEVICE_IMODC_SHIFT
469867cd155SPankaj Dev #define USB3_DEV_IMOD_DEVICE_IMODC_MSK	_DWC3_DEV_IMOD_DEVICE_IMODC_MASK
470867cd155SPankaj Dev 
471867cd155SPankaj Dev #define IS_MULTIPLE(x, a)	(((x) % (a)) == 0U)
472867cd155SPankaj Dev #define ALIGN_MULTIPLE(x, a)	((a) * (((x) / (a)) + ((((x) % (a)) != 0U) ? 1U : 0U)))
473867cd155SPankaj Dev #define PAGE_ALIGN(addr, mask)	((addr) & ~(mask))
474867cd155SPankaj Dev 
475867cd155SPankaj Dev #define upper_32_bits(n)	((uint32_t)(((n) >> 16) >> 16))
476867cd155SPankaj Dev #define lower_32_bits(n)	((uint32_t)(n))
477867cd155SPankaj Dev 
478867cd155SPankaj Dev /* DWC3 IP Parameter */
479867cd155SPankaj Dev #define DWC3_IP_DEVICE_NUM_INT	2
480867cd155SPankaj Dev #define DWC3_IP_NUM_EPS	32U
481867cd155SPankaj Dev #define DWC3_IP_NUM_IN_EPS	16
482867cd155SPankaj Dev 
483867cd155SPankaj Dev /* HAL_PCD defines */
484867cd155SPankaj Dev #define __HAL_PCD_ENABLE_INTR(__HANDLE__, intr)	usb_dwc3_enable_eventint(__HANDLE__, intr)
485867cd155SPankaj Dev #define __HAL_PCD_DISABLE_INTR(__HANDLE__, intr)	usb_dwc3_disable_eventint(__HANDLE__, intr)
486867cd155SPankaj Dev 
487867cd155SPankaj Dev #define __HAL_PCD_SETUP_REQ_LEN(addr)	(((uint16_t)(*((uint8_t *)(addr) + 6))) + \
488867cd155SPankaj Dev 						(((uint16_t)(*((uint8_t *)(addr) + 7))) << 8))
489867cd155SPankaj Dev 
490867cd155SPankaj Dev #define __HAL_PCD_SETUP_REQ_DATA_DIR_IN(addr)	((*(uint8_t *)(addr)) & EP_DIR_IN)
491867cd155SPankaj Dev 
492867cd155SPankaj Dev #define __HAL_PCD_INCR_EVENT_POS(__HANDLE__, intr, incr) \
493867cd155SPankaj Dev 						(__HANDLE__)->intbuffers.evtbufferpos[intr] = \
494867cd155SPankaj Dev 						((__HANDLE__)->intbuffers.evtbufferpos[intr] + \
495867cd155SPankaj Dev 						 (incr)) % USB_DWC3_EVENT_BUFFER_SIZE
496867cd155SPankaj Dev #define __HAL_PCD_READ_EVENT(__HANDLE__, intr)	*(volatile uint32_t *)&((__HANDLE__)->\
497867cd155SPankaj Dev 						intbuffers.evtbuffer_addr[intr][(__HANDLE__)->\
498867cd155SPankaj Dev 						intbuffers.evtbufferpos[intr]])
499867cd155SPankaj Dev 
500867cd155SPankaj Dev #define __HAL_PCD_EPADDR_TO_PHYEPNUM(ep_addr)	((2U * ((ep_addr) & ADDRESS_MASK)) + \
501867cd155SPankaj Dev 						((((ep_addr) & EP_DIR_MASK) != 0U) ? 1U : 0U))
502867cd155SPankaj Dev #define __HAL_PCD_PHYEPNUM_TO_EPADDR(phy_epnum)	(((phy_epnum) / 2U) | \
503867cd155SPankaj Dev 						((((phy_epnum) & 0x1U) != 0U) ? EP_DIR_IN : 0U))
504867cd155SPankaj Dev 
505867cd155SPankaj Dev #define PCD_DEV_EVENTS_INTR	0 /* Interrupt to use for device events */
506867cd155SPankaj Dev 
507867cd155SPankaj Dev #define GET_DWC3EP_FROM_USBEP(__HANDLE__, usb_ep)	*(volatile uint32_t *)&((__HANDLE__)->\
508867cd155SPankaj Dev 						intbuffers.evtbuffer_addr[intr][(__HANDLE__)->\
509867cd155SPankaj Dev 						intbuffers.evtbufferpos[intr]])
510867cd155SPankaj Dev 
511867cd155SPankaj Dev typedef uint32_t dwc3_epcmd_t;
512867cd155SPankaj Dev typedef struct {
513867cd155SPankaj Dev 	uint32_t  param2;
514867cd155SPankaj Dev 	uint32_t  param1;
515867cd155SPankaj Dev 	uint32_t  param0;
516867cd155SPankaj Dev } dwc3_epcmd_params_t;
517867cd155SPankaj Dev 
DWC3_regread(void * base,uint32_t offset)518867cd155SPankaj Dev static uint32_t DWC3_regread(void *base, uint32_t offset)
519867cd155SPankaj Dev {
520867cd155SPankaj Dev 	return mmio_read_32((uintptr_t)base + offset);
521867cd155SPankaj Dev }
522867cd155SPankaj Dev 
DWC3_regwrite(void * base,uint32_t offset,uint32_t value)523867cd155SPankaj Dev static void DWC3_regwrite(void *base, uint32_t offset, uint32_t value)
524867cd155SPankaj Dev {
525867cd155SPankaj Dev 	mmio_write_32((uintptr_t)base + offset, value);
526867cd155SPankaj Dev }
527867cd155SPankaj Dev 
DWC3_regupdateset(void * base,uint32_t offset,uint32_t set_mask)528867cd155SPankaj Dev static void DWC3_regupdateset(void *base, uint32_t offset, uint32_t set_mask)
529867cd155SPankaj Dev {
530867cd155SPankaj Dev 	mmio_setbits_32((uintptr_t)base + offset, set_mask);
531867cd155SPankaj Dev }
532867cd155SPankaj Dev 
DWC3_regupdateclr(void * base,uint32_t offset,uint32_t clr_mask)533867cd155SPankaj Dev static void DWC3_regupdateclr(void *base, uint32_t offset, uint32_t clr_mask)
534867cd155SPankaj Dev {
535867cd155SPankaj Dev 	mmio_clrbits_32((uintptr_t)base + offset, clr_mask);
536867cd155SPankaj Dev }
537867cd155SPankaj Dev 
usb_dwc3_enable_eventint(dwc3_handle_t * handle,uint8_t intr_num)538867cd155SPankaj Dev static void usb_dwc3_enable_eventint(dwc3_handle_t *handle, uint8_t intr_num)
539867cd155SPankaj Dev {
540867cd155SPankaj Dev 	DWC3_regupdateclr(handle->usb_global, DWC3_GEVNTSIZ(intr_num),
541867cd155SPankaj Dev 			  USB3_GEVNTSIZ_EVNTINTRPTMASK_MSK);
542867cd155SPankaj Dev }
543867cd155SPankaj Dev 
usb_dwc3_disable_eventint(dwc3_handle_t * handle,uint8_t intr_num)544867cd155SPankaj Dev static void usb_dwc3_disable_eventint(dwc3_handle_t *handle, uint8_t intr_num)
545867cd155SPankaj Dev {
546867cd155SPankaj Dev 	DWC3_regupdateset(handle->usb_global, DWC3_GEVNTSIZ(intr_num),
547867cd155SPankaj Dev 			  USB3_GEVNTSIZ_EVNTINTRPTMASK_MSK);
548867cd155SPankaj Dev }
549867cd155SPankaj Dev 
api_mapdmaaddr(uint8_t buf[],uint32_t size,uint8_t to_device)550867cd155SPankaj Dev static uintptr_t api_mapdmaaddr(uint8_t buf[], uint32_t size, uint8_t to_device)
551867cd155SPankaj Dev {
552867cd155SPankaj Dev 	if (to_device) {
553867cd155SPankaj Dev 		clean_dcache_range((uintptr_t)buf, size);
554867cd155SPankaj Dev 	} else {
555867cd155SPankaj Dev 		inv_dcache_range((uintptr_t)buf, size);
556867cd155SPankaj Dev 	}
557867cd155SPankaj Dev 
558867cd155SPankaj Dev 	return (uintptr_t)buf;
559867cd155SPankaj Dev }
560867cd155SPankaj Dev 
api_unmapdmaaddr(uintptr_t dma_addr __unused,uint32_t size __unused,uint8_t to_device __unused)561867cd155SPankaj Dev static void api_unmapdmaaddr(uintptr_t dma_addr __unused, uint32_t size __unused,
562867cd155SPankaj Dev 			     uint8_t to_device __unused)
563867cd155SPankaj Dev {
564867cd155SPankaj Dev }
565867cd155SPankaj Dev 
api_getdmaaddr(uint8_t buf[],uint32_t size __unused,uint8_t to_device __unused)566867cd155SPankaj Dev static uintptr_t api_getdmaaddr(uint8_t buf[], uint32_t size __unused, uint8_t to_device __unused)
567867cd155SPankaj Dev {
568867cd155SPankaj Dev 	return (uintptr_t)buf;
569867cd155SPankaj Dev }
570867cd155SPankaj Dev 
api_putdmaaddr(uintptr_t dma_addr __unused,uint32_t size __unused,uint8_t to_device __unused)571867cd155SPankaj Dev __unused static void api_putdmaaddr(uintptr_t dma_addr __unused, uint32_t size __unused,
572867cd155SPankaj Dev 				    uint8_t to_device __unused)
573867cd155SPankaj Dev {
574867cd155SPankaj Dev }
575867cd155SPankaj Dev 
api_memcpy(void * dest,const void * src,uint32_t n)576867cd155SPankaj Dev static void api_memcpy(void *dest, const void *src, uint32_t n)
577867cd155SPankaj Dev {
578867cd155SPankaj Dev #ifdef AVOID_COMPILER_MEMCPY
579867cd155SPankaj Dev 	uint8_t *pcdst = (uint8_t *)dest;
580867cd155SPankaj Dev 	uint8_t const *pcsrc = (uint8_t const *)src;
581867cd155SPankaj Dev 
582867cd155SPankaj Dev 	while (n--) {
583867cd155SPankaj Dev 		*pcdst++ = *pcsrc++;
584867cd155SPankaj Dev 	}
585867cd155SPankaj Dev #else
586867cd155SPankaj Dev 	(void)memcpy(dest, src, n);
587867cd155SPankaj Dev #endif
588867cd155SPankaj Dev }
589867cd155SPankaj Dev 
dwc3_get_trb_ctltype(uint32_t trb_type)590867cd155SPankaj Dev static uint32_t dwc3_get_trb_ctltype(uint32_t trb_type)
591867cd155SPankaj Dev {
592867cd155SPankaj Dev 	uint32_t ret;
593867cd155SPankaj Dev 
594867cd155SPankaj Dev 	switch (trb_type) {
595867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_NORMAL:
596867cd155SPankaj Dev 		ret = DWC3_TRBCTL_NORMAL;
597867cd155SPankaj Dev 		break;
598867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_CONTROL_SETUP:
599867cd155SPankaj Dev 		ret = DWC3_TRBCTL_CONTROL_SETUP;
600867cd155SPankaj Dev 		break;
601867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_CONTROL_STATUS2:
602867cd155SPankaj Dev 		ret = DWC3_TRBCTL_CONTROL_STATUS2;
603867cd155SPankaj Dev 		break;
604867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_CONTROL_STATUS3:
605867cd155SPankaj Dev 		ret = DWC3_TRBCTL_CONTROL_STATUS3;
606867cd155SPankaj Dev 		break;
607867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_CONTROL_DATA:
608867cd155SPankaj Dev 		ret = DWC3_TRBCTL_CONTROL_DATA;
609867cd155SPankaj Dev 		break;
610867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_ISOCHRONOUS_FIRST:
611867cd155SPankaj Dev 		ret = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
612867cd155SPankaj Dev 		break;
613867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_ISOCHRONOUS:
614867cd155SPankaj Dev 		ret = DWC3_TRBCTL_ISOCHRONOUS;
615867cd155SPankaj Dev 		break;
616867cd155SPankaj Dev 	case USB_DWC3_TRBCTL_LINK_TRB:
617867cd155SPankaj Dev 		ret = DWC3_TRBCTL_LINK_TRB;
618867cd155SPankaj Dev 		break;
619867cd155SPankaj Dev 	default:
620867cd155SPankaj Dev 		ret = 0U;
621867cd155SPankaj Dev 		break;
622867cd155SPankaj Dev 	}
623867cd155SPankaj Dev 
624867cd155SPankaj Dev 	return ret;
625867cd155SPankaj Dev }
626867cd155SPankaj Dev 
dwc3_get_ep_cmd_str(uint32_t cmd)627867cd155SPankaj Dev static inline const char *dwc3_get_ep_cmd_str(uint32_t cmd)
628867cd155SPankaj Dev {
629867cd155SPankaj Dev 	const char *ret;
630867cd155SPankaj Dev 
631867cd155SPankaj Dev 	switch (cmd & USB3_DEPCMD_CMDTYP_MSK) {
632867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_DEPSTARTCFG:
633867cd155SPankaj Dev 		ret = "Start New Configuration";
634867cd155SPankaj Dev 		break;
635867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_ENDTRANSFER:
636867cd155SPankaj Dev 		ret = "End Transfer";
637867cd155SPankaj Dev 		break;
638867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_UPDATETRANSFER:
639867cd155SPankaj Dev 		ret = "Update Transfer";
640867cd155SPankaj Dev 		break;
641867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_STARTTRANSFER:
642867cd155SPankaj Dev 		ret = "Start Transfer";
643867cd155SPankaj Dev 		break;
644867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_CLEARSTALL:
645867cd155SPankaj Dev 		ret = "Clear Stall";
646867cd155SPankaj Dev 		break;
647867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_SETSTALL:
648867cd155SPankaj Dev 		ret = "Set Stall";
649867cd155SPankaj Dev 		break;
650867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_GETEPSTATE:
651867cd155SPankaj Dev 		ret = "Get Endpoint State";
652867cd155SPankaj Dev 		break;
653867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_SETTRANSFRESOURCE:
654867cd155SPankaj Dev 		ret = "Set Endpoint Transfer Resource";
655867cd155SPankaj Dev 		break;
656867cd155SPankaj Dev 	case USB_DWC3_DEPCMD_SETEPCONFIG:
657867cd155SPankaj Dev 		ret = "Set Endpoint Configuration";
658867cd155SPankaj Dev 		break;
659867cd155SPankaj Dev 	default:
660867cd155SPankaj Dev 		ret = "UNKNOWN command";
661867cd155SPankaj Dev 		break;
662867cd155SPankaj Dev 	}
663867cd155SPankaj Dev 
664867cd155SPankaj Dev 	return ret;
665867cd155SPankaj Dev }
666867cd155SPankaj Dev 
dwc3_execute_dep_cmd(dwc3_handle_t * dwc3_handle,uint8_t phy_epnum,dwc3_epcmd_t cmd,dwc3_epcmd_params_t * params)667867cd155SPankaj Dev static enum usb_status dwc3_execute_dep_cmd(dwc3_handle_t *dwc3_handle, uint8_t phy_epnum,
668867cd155SPankaj Dev 					    dwc3_epcmd_t cmd, dwc3_epcmd_params_t *params)
669867cd155SPankaj Dev {
670867cd155SPankaj Dev 	uint32_t reg;
671867cd155SPankaj Dev 	uint64_t timeout;
672867cd155SPankaj Dev 
673867cd155SPankaj Dev 	VERBOSE("PHYEP%d: cmd '%s' %08x params %08x %08x %08x\n", phy_epnum,
674867cd155SPankaj Dev 		   dwc3_get_ep_cmd_str(cmd), (uint32_t)cmd, (uint32_t)params->param0,
675867cd155SPankaj Dev 		   (uint32_t)params->param1, (uint32_t)params->param2);
676867cd155SPankaj Dev 
677867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DEPCMDPAR0(phy_epnum), params->param0);
678867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DEPCMDPAR1(phy_epnum), params->param1);
679867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DEPCMDPAR2(phy_epnum), params->param2);
680867cd155SPankaj Dev 
681867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DEPCMD(phy_epnum), cmd | USB3_DEPCMD_CMDACT);
682867cd155SPankaj Dev 
683867cd155SPankaj Dev 	timeout = timeout_init_us(500); /* usec */
684867cd155SPankaj Dev 	do {
685867cd155SPankaj Dev 		reg = DWC3_regread(dwc3_handle->usb_device, DWC3_DEPCMD(phy_epnum));
686867cd155SPankaj Dev 		/* "Command Complete" */
687867cd155SPankaj Dev 		if ((reg & USB3_DEPCMD_CMDACT) == 0U) {
688867cd155SPankaj Dev 			VERBOSE("Command Complete --> %u PHYEP%u %x\n", DWC3_DEPCMD_STATUS(reg),
689867cd155SPankaj Dev 				   phy_epnum, reg);
690867cd155SPankaj Dev 			if (DWC3_DEPCMD_STATUS(reg) != 0U) {
691867cd155SPankaj Dev 				return USBD_FAIL;
692867cd155SPankaj Dev 			}
693867cd155SPankaj Dev 			return USBD_OK;
694867cd155SPankaj Dev 		}
695867cd155SPankaj Dev 
696867cd155SPankaj Dev 		/* Can be called from interrupt context hence cannot wait for Tick */
697867cd155SPankaj Dev 		if (timeout_elapsed(timeout)) {
6988defd6feSYann Gautier 			ERROR("TIMEOUT Command Complete --> %u PHYEP%u %x\n",
699867cd155SPankaj Dev 				   DWC3_DEPCMD_STATUS(reg), phy_epnum, reg);
700867cd155SPankaj Dev 			/* "Command Timed Out" */
701867cd155SPankaj Dev 			return USBD_TIMEOUT;
702867cd155SPankaj Dev 		}
703867cd155SPankaj Dev 	} while (true);
704867cd155SPankaj Dev 
705867cd155SPankaj Dev 	return USBD_OK;
706867cd155SPankaj Dev }
707867cd155SPankaj Dev 
dwc3_is_ep_enabled(dwc3_handle_t * dwc3_handle,uint8_t phy_epnum)708867cd155SPankaj Dev static bool dwc3_is_ep_enabled(dwc3_handle_t *dwc3_handle, uint8_t phy_epnum)
709867cd155SPankaj Dev {
710867cd155SPankaj Dev 	if ((DWC3_regread(dwc3_handle->usb_device,
711867cd155SPankaj Dev 			  DWC3_DALEPENA) & DWC3_DALEPENA_EP(phy_epnum)) != 0U) {
712867cd155SPankaj Dev 		return true;
713867cd155SPankaj Dev 	}
714867cd155SPankaj Dev 
715867cd155SPankaj Dev 	return false;
716867cd155SPankaj Dev }
717867cd155SPankaj Dev 
dwc3_ep_start_xfer(dwc3_handle_t * dwc3_handle,struct usbd_ep * ep)718867cd155SPankaj Dev static enum usb_status dwc3_ep_start_xfer(dwc3_handle_t *dwc3_handle, struct usbd_ep *ep)
719867cd155SPankaj Dev {
720867cd155SPankaj Dev 	enum usb_status ret;
721867cd155SPankaj Dev 	dwc3_epcmd_t cmd;
722867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
723867cd155SPankaj Dev 
724867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep = ((ep->is_in) ? &dwc3_handle->IN_ep[ep->num] :
725867cd155SPankaj Dev 					&dwc3_handle->OUT_ep[ep->num]);
726867cd155SPankaj Dev 
727867cd155SPankaj Dev 	VERBOSE("%s PHYEP%d %x\n", __func__, dwc3_ep->phy_epnum, dwc3_ep->flags);
728867cd155SPankaj Dev 
729867cd155SPankaj Dev 	/* Wait for XferNotReady to get the uF interval to srat ISOC transfers */
730867cd155SPankaj Dev 	if ((ep->type == EP_TYPE_ISOC) &&
731867cd155SPankaj Dev 	    ((dwc3_ep->flags & USB_DWC3_EP_ISOC_START_PENDING) == 0U) &&
732867cd155SPankaj Dev 	    ((dwc3_ep->flags & USB_DWC3_EP_ISOC_STARTED) == 0U)) {
733867cd155SPankaj Dev 		dwc3_ep->flags |= USB_DWC3_EP_ISOC_START_PENDING;
734867cd155SPankaj Dev 		VERBOSE("INSIDE IF\n");
735867cd155SPankaj Dev 		return USBD_OK;
736867cd155SPankaj Dev 	}
737867cd155SPankaj Dev 
738867cd155SPankaj Dev 	if ((ep->type == EP_TYPE_ISOC) &&
739867cd155SPankaj Dev 	    ((dwc3_ep->flags & USB_DWC3_EP_ISOC_START_PENDING) != 0U)) {
740867cd155SPankaj Dev 		dwc3_ep->flags &= ~USB_DWC3_EP_ISOC_START_PENDING;
741867cd155SPankaj Dev 	}
742867cd155SPankaj Dev 
743867cd155SPankaj Dev 	dwc3_ep->trb_addr->bpl = lower_32_bits(dwc3_ep->dma_addr);
744867cd155SPankaj Dev 	dwc3_ep->trb_addr->bph = upper_32_bits(dwc3_ep->dma_addr);
745867cd155SPankaj Dev 	dwc3_ep->trb_addr->size = DWC3_TRB_SIZE_LENGTH(ep->xfer_len);
746867cd155SPankaj Dev 	/* also initializes other bits to 0 */
747867cd155SPankaj Dev 	dwc3_ep->trb_addr->ctrl = dwc3_get_trb_ctltype(dwc3_ep->trb_flag & USB_DWC3_TRBCTL_MASK);
748867cd155SPankaj Dev 
749867cd155SPankaj Dev 	dwc3_ep->trb_addr->ctrl |= ((ep->num == 0U) ? DWC3_TRB_CTRL_ISP_IMI : 0U);
750867cd155SPankaj Dev 
751867cd155SPankaj Dev 	dwc3_ep->trb_addr->ctrl |= DWC3_TRB_CTRL_IOC;
752867cd155SPankaj Dev 
753867cd155SPankaj Dev 	if ((ep->type == EP_TYPE_ISOC) && ((dwc3_ep->flags & USB_DWC3_EP_ISOC_STARTED) != 0U)) {
754867cd155SPankaj Dev 		cmd = USB_DWC3_DEPCMD_UPDATETRANSFER;
755867cd155SPankaj Dev 	} else {
756867cd155SPankaj Dev 		cmd = USB_DWC3_DEPCMD_STARTTRANSFER;
757867cd155SPankaj Dev 	}
758867cd155SPankaj Dev 
759867cd155SPankaj Dev 	if (ep->type != EP_TYPE_ISOC) {
760867cd155SPankaj Dev 		dwc3_ep->trb_addr->ctrl |= DWC3_TRB_CTRL_LST;
761867cd155SPankaj Dev 	}
762867cd155SPankaj Dev 
763867cd155SPankaj Dev 	dwc3_ep->trb_addr->ctrl |= DWC3_TRB_CTRL_HWO;
764867cd155SPankaj Dev 
765867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
766867cd155SPankaj Dev 
767867cd155SPankaj Dev 	if ((cmd & USB3_DEPCMD_CMDTYP_MSK) == USB_DWC3_DEPCMD_STARTTRANSFER) {
768867cd155SPankaj Dev 		params.param0 = upper_32_bits(dwc3_ep->trb_dma_addr);
769867cd155SPankaj Dev 		params.param1 = lower_32_bits(dwc3_ep->trb_dma_addr);
770867cd155SPankaj Dev 	}
771867cd155SPankaj Dev 
772867cd155SPankaj Dev 	dwc3_ep->flags |= USB_DWC3_EP_REQ_QUEUED;
773867cd155SPankaj Dev 	if ((ep->type == EP_TYPE_ISOC) &&
774867cd155SPankaj Dev 	    ((cmd & USB3_DEPCMD_CMDTYP_MSK) == USB_DWC3_DEPCMD_STARTTRANSFER)) {
775867cd155SPankaj Dev 		dwc3_ep->flags |= USB_DWC3_EP_ISOC_STARTED;
776867cd155SPankaj Dev 	}
777867cd155SPankaj Dev 
778867cd155SPankaj Dev 	VERBOSE("EP%d%s: trb %p:%08x:%08x:%08x:%08x length %u %d\n",
779867cd155SPankaj Dev 		   ep->num, ep->is_in ? "IN" : "OUT", dwc3_ep->trb_addr,
780867cd155SPankaj Dev 		   (uint32_t)dwc3_ep->trb_addr->bph, (uint32_t)dwc3_ep->trb_addr->bpl,
781867cd155SPankaj Dev 		   (uint32_t)dwc3_ep->trb_addr->size, (uint32_t)dwc3_ep->trb_addr->ctrl,
782867cd155SPankaj Dev 		   ep->xfer_len, dwc3_ep->flags);
783867cd155SPankaj Dev 
784867cd155SPankaj Dev 	ret = dwc3_execute_dep_cmd(dwc3_handle, dwc3_ep->phy_epnum, cmd, &params);
785867cd155SPankaj Dev 	if (ret != USBD_OK) {
786867cd155SPankaj Dev 		dwc3_ep->flags &= ~USB_DWC3_EP_REQ_QUEUED;
787867cd155SPankaj Dev 		if ((ep->type == EP_TYPE_ISOC) &&
788867cd155SPankaj Dev 		    ((cmd & USB3_DEPCMD_CMDTYP_MSK) == USB_DWC3_DEPCMD_STARTTRANSFER)) {
789867cd155SPankaj Dev 			dwc3_ep->flags &= ~USB_DWC3_EP_ISOC_STARTED;
790867cd155SPankaj Dev 		}
791867cd155SPankaj Dev 		return ret;
792867cd155SPankaj Dev 	}
793867cd155SPankaj Dev 
794867cd155SPankaj Dev 	if ((cmd & USB3_DEPCMD_CMDTYP_MSK) == USB_DWC3_DEPCMD_STARTTRANSFER) {
795867cd155SPankaj Dev 		dwc3_ep->resc_idx =
796867cd155SPankaj Dev 		(uint8_t)DWC3_DEPCMD_GET_RSC_IDX(DWC3_regread(dwc3_handle->usb_device,
797867cd155SPankaj Dev 							      DWC3_DEPCMD(dwc3_ep->phy_epnum)));
798867cd155SPankaj Dev 	}
799867cd155SPankaj Dev 
800867cd155SPankaj Dev 	return ret;
801867cd155SPankaj Dev }
802867cd155SPankaj Dev 
usb_dwc3_ep_start_xfer(void * handle,struct usbd_ep * ep)803867cd155SPankaj Dev static enum usb_status usb_dwc3_ep_start_xfer(void *handle, struct usbd_ep *ep)
804867cd155SPankaj Dev {
805867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
806867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep = ((ep->is_in) ? &dwc3_handle->IN_ep[ep->num] :
807867cd155SPankaj Dev 					&dwc3_handle->OUT_ep[ep->num]);
808867cd155SPankaj Dev 	uint32_t len = ep->xfer_len;
809867cd155SPankaj Dev 
810867cd155SPankaj Dev 	if (!dwc3_is_ep_enabled(dwc3_handle, dwc3_ep->phy_epnum) && ep->num != 0U) {
811867cd155SPankaj Dev 		return USBD_FAIL;
812867cd155SPankaj Dev 	}
813867cd155SPankaj Dev 
814867cd155SPankaj Dev 	if (!ep->is_in) {
815867cd155SPankaj Dev 		if ((len > ep->maxpacket) && !IS_MULTIPLE(len, ep->maxpacket)) {
816867cd155SPankaj Dev 			VERBOSE("Packet size exceeds Max_packet and is not an multiple of it\n");
817867cd155SPankaj Dev 		}
818867cd155SPankaj Dev 
819867cd155SPankaj Dev 		/*setup and start the Xfer */
820867cd155SPankaj Dev 		if ((len != 0U) && (len < ep->maxpacket)) {
821867cd155SPankaj Dev 			dwc3_ep->xfer_dest_buff = ep->xfer_buff;
822867cd155SPankaj Dev 			dwc3_ep->xfer_dest_len = ep->xfer_len;
823867cd155SPankaj Dev 			ep->xfer_buff = dwc3_ep->bounce_buf;
824867cd155SPankaj Dev 			ep->xfer_len = ALIGN_MULTIPLE(len, ep->maxpacket);
825867cd155SPankaj Dev 		} else {
826867cd155SPankaj Dev //			ep->xfer_buff = pBuf;
827867cd155SPankaj Dev 			ep->xfer_len = ALIGN_MULTIPLE(len, ep->maxpacket);
828867cd155SPankaj Dev 		}
829867cd155SPankaj Dev 	}
830867cd155SPankaj Dev 
831867cd155SPankaj Dev 	dwc3_ep->dma_addr = ((ep->xfer_buff != 0) ?
832867cd155SPankaj Dev 			     api_mapdmaaddr(ep->xfer_buff, ep->xfer_len, ep->is_in ? 1 : 0) :
833867cd155SPankaj Dev 			     0x0U);
834867cd155SPankaj Dev 
835867cd155SPankaj Dev 	if (ep->num == 0U) {
836867cd155SPankaj Dev 		/* For Status ZLP packet */
837867cd155SPankaj Dev 		if (len == 0U) {
838867cd155SPankaj Dev 			/* 2-stage/3-stage control transfer */
839867cd155SPankaj Dev 			if (__HAL_PCD_SETUP_REQ_LEN(dwc3_handle->setup_addr) == 0U) {
840867cd155SPankaj Dev 				dwc3_ep->trb_flag = USB_DWC3_TRBCTL_CONTROL_STATUS2;
841867cd155SPankaj Dev 			} else {
842867cd155SPankaj Dev 				dwc3_ep->trb_flag = USB_DWC3_TRBCTL_CONTROL_STATUS3;
843867cd155SPankaj Dev 			}
844867cd155SPankaj Dev 			//udelay(10);
845867cd155SPankaj Dev 		} else {
846867cd155SPankaj Dev 			dwc3_ep->trb_flag = USB_DWC3_TRBCTL_CONTROL_DATA;
847867cd155SPankaj Dev 		}
848867cd155SPankaj Dev 	} else {
849867cd155SPankaj Dev 		if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK)) {
850867cd155SPankaj Dev 			dwc3_ep->trb_flag = USB_DWC3_TRBCTL_NORMAL;
851867cd155SPankaj Dev 		} else {
852867cd155SPankaj Dev 			dwc3_ep->trb_flag = USB_DWC3_TRBCTL_ISOCHRONOUS_FIRST;
853867cd155SPankaj Dev 		}
854867cd155SPankaj Dev 	}
855867cd155SPankaj Dev 
856867cd155SPankaj Dev 	return dwc3_ep_start_xfer(dwc3_handle, ep);
857867cd155SPankaj Dev }
858867cd155SPankaj Dev 
dwc3_ep0_out_start(dwc3_handle_t * dwc3_handle,uintptr_t setup_buf_dma_addr)859867cd155SPankaj Dev static enum usb_status dwc3_ep0_out_start(dwc3_handle_t *dwc3_handle, uintptr_t setup_buf_dma_addr)
860867cd155SPankaj Dev {
861867cd155SPankaj Dev 	dwc3_handle->OUT_ep[0].dma_addr = setup_buf_dma_addr;
862867cd155SPankaj Dev 	dwc3_handle->pcd_handle->out_ep[0].xfer_len = 8;
863867cd155SPankaj Dev 	dwc3_handle->OUT_ep[0].trb_flag = USB_DWC3_TRBCTL_CONTROL_SETUP;
864867cd155SPankaj Dev 
865867cd155SPankaj Dev 	return dwc3_ep_start_xfer(dwc3_handle, &dwc3_handle->pcd_handle->out_ep[0]);
866867cd155SPankaj Dev }
867867cd155SPankaj Dev 
usb_dwc3_ep0_out_start(void * handle)868867cd155SPankaj Dev static enum usb_status usb_dwc3_ep0_out_start(void *handle)
869867cd155SPankaj Dev {
870867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
871867cd155SPankaj Dev 
872867cd155SPankaj Dev 	dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
873867cd155SPankaj Dev 	return dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
874867cd155SPankaj Dev }
875867cd155SPankaj Dev 
usb_dwc3_start_device(void * handle)876867cd155SPankaj Dev static enum usb_status usb_dwc3_start_device(void *handle)
877867cd155SPankaj Dev {
878867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
879867cd155SPankaj Dev 	enum usb_status ret;
880867cd155SPankaj Dev 
881867cd155SPankaj Dev 	if (dwc3_handle->EP0_State != HAL_PCD_EP0_SETUP_QUEUED) {
882867cd155SPankaj Dev 		dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
883867cd155SPankaj Dev 
884867cd155SPankaj Dev 		ret = dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
885867cd155SPankaj Dev 		if (ret != USBD_OK) {
886867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
887867cd155SPankaj Dev 			return ret;
888867cd155SPankaj Dev 		}
889867cd155SPankaj Dev 	}
890867cd155SPankaj Dev 
891867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_device, DWC3_DCTL, USB3_DCTL_RUN_STOP);
892867cd155SPankaj Dev 
893867cd155SPankaj Dev 	return USBD_OK;
894867cd155SPankaj Dev }
895867cd155SPankaj Dev 
dwc3_ack_evt_count(dwc3_handle_t * dwc3_handle,uint8_t intr_num,uint32_t evt_count)896867cd155SPankaj Dev static inline void dwc3_ack_evt_count(dwc3_handle_t *dwc3_handle, uint8_t intr_num,
897867cd155SPankaj Dev 				      uint32_t evt_count)
898867cd155SPankaj Dev {
899867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTCOUNT(intr_num), evt_count);
900867cd155SPankaj Dev }
901867cd155SPankaj Dev 
dwc3_read_intr_count(dwc3_handle_t * dwc3_handle,uint8_t intr_num)902867cd155SPankaj Dev static inline uint32_t dwc3_read_intr_count(dwc3_handle_t *dwc3_handle, uint8_t intr_num)
903867cd155SPankaj Dev {
904867cd155SPankaj Dev 	return DWC3_regread(dwc3_handle->usb_global, DWC3_GEVNTCOUNT(intr_num)) &
905867cd155SPankaj Dev 	       DWC3_GEVNTCOUNT_MASK;
906867cd155SPankaj Dev }
907867cd155SPankaj Dev 
dwc3_ep_stop_xfer(dwc3_handle_t * dwc3_handle,struct usbd_ep * ep)908867cd155SPankaj Dev static enum usb_status dwc3_ep_stop_xfer(dwc3_handle_t *dwc3_handle, struct usbd_ep *ep)
909867cd155SPankaj Dev {
910867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep = ((ep->is_in) ? &dwc3_handle->IN_ep[ep->num] :
911867cd155SPankaj Dev 					&dwc3_handle->OUT_ep[ep->num]);
912867cd155SPankaj Dev 	enum usb_status ret;
913867cd155SPankaj Dev 	dwc3_epcmd_t cmd;
914867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
915867cd155SPankaj Dev 
916867cd155SPankaj Dev 	VERBOSE("%s PHYEP%d %x\n", __func__, dwc3_ep->phy_epnum, dwc3_ep->flags);
917867cd155SPankaj Dev 
918867cd155SPankaj Dev 	/* Reset ISOC flags */
919867cd155SPankaj Dev 	if (ep->type == EP_TYPE_ISOC) {
920867cd155SPankaj Dev 		dwc3_ep->flags &= ~(USB_DWC3_EP_ISOC_START_PENDING | USB_DWC3_EP_ISOC_STARTED);
921867cd155SPankaj Dev 	}
922867cd155SPankaj Dev 
923867cd155SPankaj Dev 	if ((dwc3_ep->flags & USB_DWC3_EP_REQ_QUEUED) == 0U) {
924867cd155SPankaj Dev 		return USBD_FAIL;
925867cd155SPankaj Dev 	}
926867cd155SPankaj Dev 
927867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
928867cd155SPankaj Dev 	cmd = USB_DWC3_DEPCMD_ENDTRANSFER | USB3_DEPCMD_HIPRI_FORCERM | USB3_DEPCMD_CMDIOC |
929867cd155SPankaj Dev 	      DWC3_DEPCMD_PARAM((uint32_t)dwc3_ep->resc_idx);
930867cd155SPankaj Dev 
931867cd155SPankaj Dev 	ret = dwc3_execute_dep_cmd(dwc3_handle, dwc3_ep->phy_epnum, cmd, &params);
932867cd155SPankaj Dev 	/* Need Delay 100us as mentioned in Linux Driver */
933867cd155SPankaj Dev 	udelay(100);
934867cd155SPankaj Dev 
935867cd155SPankaj Dev 	ep->xfer_count = ep->xfer_len - (dwc3_ep->trb_addr->size & DWC3_TRB_SIZE_MASK);
936867cd155SPankaj Dev 
937867cd155SPankaj Dev 	dwc3_ep->flags &= ~USB_DWC3_EP_REQ_QUEUED;
938867cd155SPankaj Dev 
939867cd155SPankaj Dev 	if ((!ep->is_in) && (ep->num == 0U)) {
940867cd155SPankaj Dev 		dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_COMPLETED;
941867cd155SPankaj Dev 	}
942867cd155SPankaj Dev 
943867cd155SPankaj Dev 	return ret;
944867cd155SPankaj Dev }
945867cd155SPankaj Dev 
dwc3_ep_set_stall(dwc3_handle_t * dwc3_handle,const usb_dwc3_endpoint_t * dwc3_ep)946867cd155SPankaj Dev static enum usb_status dwc3_ep_set_stall(dwc3_handle_t *dwc3_handle,
947867cd155SPankaj Dev 					 const usb_dwc3_endpoint_t *dwc3_ep)
948867cd155SPankaj Dev {
949867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
950867cd155SPankaj Dev 
951867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
952867cd155SPankaj Dev 
953867cd155SPankaj Dev 	return dwc3_execute_dep_cmd(dwc3_handle, dwc3_ep->phy_epnum, USB_DWC3_DEPCMD_SETSTALL,
954867cd155SPankaj Dev 				    &params);
955867cd155SPankaj Dev }
956867cd155SPankaj Dev 
usb_dwc3_stop_device(void * handle)957867cd155SPankaj Dev static enum usb_status usb_dwc3_stop_device(void *handle)
958867cd155SPankaj Dev {
959867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
960867cd155SPankaj Dev 	uint64_t timeout;
961867cd155SPankaj Dev 	uint8_t i;
962867cd155SPankaj Dev 	uint32_t evtcnt;
963867cd155SPankaj Dev 	enum usb_status ret;
964867cd155SPankaj Dev 
965867cd155SPankaj Dev 	/*
966867cd155SPankaj Dev 	 * Stop transfers for all(USB_DWC3_NUM_IN_EPS) EP
967867cd155SPankaj Dev 	 * except EP0IN k = USB_DWC3_NUM_IN_EP
968867cd155SPankaj Dev 	 */
969867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_NUM_IN_EP; i++) {
970867cd155SPankaj Dev 		dwc3_ep_stop_xfer(dwc3_handle, &dwc3_handle->pcd_handle->in_ep[i]);
971867cd155SPankaj Dev 	}
972867cd155SPankaj Dev 
973867cd155SPankaj Dev 	/* Stop transfers for all EP except EP0OUT k = USB_DWC3_NUM_OUT_EP */
974867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_NUM_OUT_EP; i++) {
975867cd155SPankaj Dev 		dwc3_ep_stop_xfer(dwc3_handle, &dwc3_handle->pcd_handle->out_ep[i]);
976867cd155SPankaj Dev 	}
977867cd155SPankaj Dev 
978867cd155SPankaj Dev 	/* Issue SetStall on EP0 to reset Ctrl-EP state machine */
979867cd155SPankaj Dev 	ret = dwc3_ep_set_stall(dwc3_handle, &dwc3_handle->OUT_ep[0]);
980867cd155SPankaj Dev 	if (ret != USBD_OK) {
981867cd155SPankaj Dev 		ERROR("%s: EP0 stall failed %u\n", __func__, ret);
982867cd155SPankaj Dev 	}
983867cd155SPankaj Dev 
984867cd155SPankaj Dev 	/*
985867cd155SPankaj Dev 	 * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
986867cd155SPankaj Dev 	 * Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the
987867cd155SPankaj Dev 	 * "software needs to acknowledge the events that are generated
988867cd155SPankaj Dev 	 * (by writing to GEVNTCOUNTn) while it is waiting for this bit
989867cd155SPankaj Dev 	 * to be set to '1'."
990867cd155SPankaj Dev 	 */
991867cd155SPankaj Dev 
992867cd155SPankaj Dev 	/* Check for all Event Buffer interrupt k = USB_DWC3_INT_INUSE */
993867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
994867cd155SPankaj Dev 		evtcnt = dwc3_read_intr_count(dwc3_handle, i);
995867cd155SPankaj Dev 
996867cd155SPankaj Dev 		if (!evtcnt) {
997867cd155SPankaj Dev 			continue;
998867cd155SPankaj Dev 		}
999867cd155SPankaj Dev 
1000867cd155SPankaj Dev 		__HAL_PCD_INCR_EVENT_POS(dwc3_handle, i, evtcnt);
1001867cd155SPankaj Dev 
1002867cd155SPankaj Dev 		dwc3_ack_evt_count(dwc3_handle, i, evtcnt);
1003867cd155SPankaj Dev 	}
1004867cd155SPankaj Dev 
1005867cd155SPankaj Dev 
1006867cd155SPankaj Dev 	DWC3_regupdateclr(dwc3_handle->usb_device, DWC3_DCTL, USB3_DCTL_RUN_STOP);
1007867cd155SPankaj Dev 
1008867cd155SPankaj Dev 	timeout = timeout_init_us(500); /* usec */
1009867cd155SPankaj Dev 
1010867cd155SPankaj Dev 	while ((DWC3_regread(dwc3_handle->usb_device, DWC3_DSTS) &
1011867cd155SPankaj Dev 		     USB3_DSTS_DEVCTRLHLT) == 0U) {
1012867cd155SPankaj Dev 		/* Can be called from interrupt context hence cannot wait for Tick */
1013867cd155SPankaj Dev 		if (timeout_elapsed(timeout)) { /* "Reset Timed Out" */
1014867cd155SPankaj Dev 			ERROR("TIMEOUT Stop Device\n");
1015867cd155SPankaj Dev 			return USBD_TIMEOUT;
1016867cd155SPankaj Dev 		}
1017867cd155SPankaj Dev 	}
1018867cd155SPankaj Dev 
1019867cd155SPankaj Dev 	// "Halt Complete"
1020867cd155SPankaj Dev 
1021867cd155SPankaj Dev 	return USBD_OK;
1022867cd155SPankaj Dev }
1023867cd155SPankaj Dev 
usb_dwc3_set_address(void * handle,uint8_t address)1024867cd155SPankaj Dev static enum usb_status usb_dwc3_set_address(void *handle, uint8_t address)
1025867cd155SPankaj Dev {
1026867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
1027867cd155SPankaj Dev 
1028867cd155SPankaj Dev 	VERBOSE("%s: %d\n", __func__, address);
1029867cd155SPankaj Dev 
1030867cd155SPankaj Dev 	/* set device address */
1031867cd155SPankaj Dev 	DWC3_regupdateclr(dwc3_handle->usb_device, DWC3_DCFG, USB3_DCFG_DEVADDR_MSK);
1032867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_device, DWC3_DCFG, DWC3_DCFG_DEVADDR((uint32_t)address));
1033867cd155SPankaj Dev 
1034867cd155SPankaj Dev 	return USBD_OK;
1035867cd155SPankaj Dev }
1036867cd155SPankaj Dev 
usb_dwc3_ep0_start_xfer(void * handle,struct usbd_ep * ep)1037867cd155SPankaj Dev static enum usb_status usb_dwc3_ep0_start_xfer(void *handle, struct usbd_ep *ep)
1038867cd155SPankaj Dev {
1039867cd155SPankaj Dev 	return usb_dwc3_ep_start_xfer(handle, ep);
1040867cd155SPankaj Dev }
1041867cd155SPankaj Dev 
usb_dwc3_ep_set_stall(void * handle,struct usbd_ep * ep)1042867cd155SPankaj Dev static enum usb_status usb_dwc3_ep_set_stall(void *handle, struct usbd_ep *ep)
1043867cd155SPankaj Dev {
1044867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
1045867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep = ((ep->is_in) ? &dwc3_handle->IN_ep[ep->num] :
1046867cd155SPankaj Dev 					&dwc3_handle->OUT_ep[ep->num]);
1047867cd155SPankaj Dev 
1048867cd155SPankaj Dev 	if (dwc3_ep->is_stall) {
1049867cd155SPankaj Dev 		return USBD_OK;
1050867cd155SPankaj Dev 	}
1051867cd155SPankaj Dev 
1052867cd155SPankaj Dev 	dwc3_ep->is_stall = true;
1053867cd155SPankaj Dev 
1054867cd155SPankaj Dev 	return dwc3_ep_set_stall(dwc3_handle, dwc3_ep);
1055867cd155SPankaj Dev }
1056867cd155SPankaj Dev 
dwc3_read_ep_evt_type(uint32_t event)1057867cd155SPankaj Dev static uint8_t dwc3_read_ep_evt_type(uint32_t event)
1058867cd155SPankaj Dev {
1059867cd155SPankaj Dev 	uint8_t ret;
1060867cd155SPankaj Dev 
1061867cd155SPankaj Dev 	switch ((event & DWC3_EVT_DEPEVT_TYPE_MASK) >> DWC3_EVT_DEPEVT_TYPE_BITPOS) {
1062867cd155SPankaj Dev 	case DWC3_DEPEVT_XFERCOMPLETE:
1063867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_XFERCOMPLETE;
1064867cd155SPankaj Dev 		break;
1065867cd155SPankaj Dev 	case DWC3_DEPEVT_XFERINPROGRESS:
1066867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_XFERINPROGRESS;
1067867cd155SPankaj Dev 		break;
1068867cd155SPankaj Dev 	case DWC3_DEPEVT_XFERNOTREADY:
1069867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_XFERNOTREADY;
1070867cd155SPankaj Dev 		break;
1071867cd155SPankaj Dev 	case DWC3_DEPEVT_RXTXFIFOEVT:
1072867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_RXTXFIFOEVT;
1073867cd155SPankaj Dev 		break;
1074867cd155SPankaj Dev 	case DWC3_DEPEVT_STREAMEVT:
1075867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_STREAMEVT;
1076867cd155SPankaj Dev 		break;
1077867cd155SPankaj Dev 	case DWC3_DEPEVT_EPCMDCMPLT:
1078867cd155SPankaj Dev 		ret =  USB_DWC3_DEPEVT_EPCMDCMPLT;
1079867cd155SPankaj Dev 		break;
1080867cd155SPankaj Dev 	default:
1081867cd155SPankaj Dev 		ret = (event & DWC3_EVT_DEPEVT_TYPE_MASK) >> DWC3_EVT_DEPEVT_TYPE_BITPOS;
1082867cd155SPankaj Dev 		break;
1083867cd155SPankaj Dev 	}
1084867cd155SPankaj Dev 
1085867cd155SPankaj Dev 	return ret;
1086867cd155SPankaj Dev }
1087867cd155SPankaj Dev 
dwc3_read_ep_evt_epnum(uint32_t event)1088867cd155SPankaj Dev static uint8_t dwc3_read_ep_evt_epnum(uint32_t event)
1089867cd155SPankaj Dev {
1090867cd155SPankaj Dev 	return (uint8_t)((event & DWC3_EVT_DEPEVT_EPNUM_MASK) >> DWC3_EVT_DEPEVT_EPNUM_BITPOS);
1091867cd155SPankaj Dev }
1092867cd155SPankaj Dev 
dwc3_read_ep_evt_status(uint32_t event)1093867cd155SPankaj Dev static uint8_t dwc3_read_ep_evt_status(uint32_t event)
1094867cd155SPankaj Dev {
1095867cd155SPankaj Dev 	uint8_t ret;
1096867cd155SPankaj Dev 
1097867cd155SPankaj Dev 	switch ((event & DWC3_EVT_DEPEVT_STATUS_MASK) >> DWC3_EVT_DEPEVT_STATUS_BITPOS) {
1098867cd155SPankaj Dev 	case DWC3_EVT_DEPEVT_STATUS_CONTROL_DATA:
1099867cd155SPankaj Dev 		ret = USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_DATA;
1100867cd155SPankaj Dev 		break;
1101867cd155SPankaj Dev 	case DWC3_EVT_DEPEVT_STATUS_CONTROL_STATUS:
1102867cd155SPankaj Dev 		ret = USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_STATUS;
1103867cd155SPankaj Dev 		break;
1104867cd155SPankaj Dev 	default:
1105867cd155SPankaj Dev 		ret = (event & DWC3_EVT_DEPEVT_STATUS_MASK) >> DWC3_EVT_DEPEVT_STATUS_BITPOS;
1106867cd155SPankaj Dev 		break;
1107867cd155SPankaj Dev 	}
1108867cd155SPankaj Dev 
1109867cd155SPankaj Dev 	return ret;
1110867cd155SPankaj Dev }
1111867cd155SPankaj Dev 
dwc3_epaddr_set_stall(dwc3_handle_t * dwc3_handle,uint8_t ep_addr)1112867cd155SPankaj Dev static enum usb_status dwc3_epaddr_set_stall(dwc3_handle_t *dwc3_handle, uint8_t ep_addr)
1113867cd155SPankaj Dev {
1114867cd155SPankaj Dev 	struct usbd_ep *ep;
1115867cd155SPankaj Dev 	enum usb_status ret;
1116867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep;
1117867cd155SPankaj Dev 
1118867cd155SPankaj Dev 	if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {
1119867cd155SPankaj Dev 		ep = &dwc3_handle->pcd_handle->in_ep[ep_addr & ADDRESS_MASK];
1120867cd155SPankaj Dev 		dwc3_ep = &dwc3_handle->IN_ep[ep_addr & ADDRESS_MASK];
1121867cd155SPankaj Dev 	} else {
1122867cd155SPankaj Dev 		ep = &dwc3_handle->pcd_handle->out_ep[ep_addr];
1123867cd155SPankaj Dev 		dwc3_ep = &dwc3_handle->OUT_ep[ep_addr];
1124867cd155SPankaj Dev 	}
1125867cd155SPankaj Dev 
1126867cd155SPankaj Dev 	/* For control endpoints, the application issues only the Set Stall command, and only on the
1127867cd155SPankaj Dev 	 * OUT direction of the control endpoint. The controller automatically clears the STALL when
1128867cd155SPankaj Dev 	 * it receives a SETUP token for the endpoint. The application must not issue the Clear
1129867cd155SPankaj Dev 	 * Stall command on a control endpoint
1130867cd155SPankaj Dev 	 */
1131867cd155SPankaj Dev 	if (ep_addr == EP0_IN) {
1132867cd155SPankaj Dev 		return USBD_OK;
1133867cd155SPankaj Dev 	}
1134867cd155SPankaj Dev 
1135867cd155SPankaj Dev 	if (dwc3_ep->is_stall) {
1136867cd155SPankaj Dev 		return USBD_OK;
1137867cd155SPankaj Dev 	}
1138867cd155SPankaj Dev 
1139867cd155SPankaj Dev 	dwc3_ep->is_stall = true;
1140867cd155SPankaj Dev 	ep->num   = ep_addr & ADDRESS_MASK;
1141867cd155SPankaj Dev 	ep->is_in = ((ep_addr & EP_DIR_MASK) == EP_DIR_IN);
1142867cd155SPankaj Dev 
1143867cd155SPankaj Dev 	ret = dwc3_ep_set_stall(dwc3_handle, dwc3_ep);
1144867cd155SPankaj Dev 	if (ret != USBD_OK) {
1145867cd155SPankaj Dev 		return ret;
1146867cd155SPankaj Dev 	}
1147867cd155SPankaj Dev 
1148867cd155SPankaj Dev 	if ((ep_addr & ADDRESS_MASK) == 0U) {
1149867cd155SPankaj Dev 		dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
1150867cd155SPankaj Dev 		ret = dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
1151867cd155SPankaj Dev 	}
1152867cd155SPankaj Dev 
1153867cd155SPankaj Dev 	return ret;
1154867cd155SPankaj Dev }
1155867cd155SPankaj Dev 
dwc3_get_ep_trblen(usb_dwc3_endpoint_t * ep)1156867cd155SPankaj Dev static uint32_t dwc3_get_ep_trblen(usb_dwc3_endpoint_t *ep)
1157867cd155SPankaj Dev {
1158867cd155SPankaj Dev 	return DWC3_TRB_SIZE_LENGTH(ep->trb_addr->size);
1159867cd155SPankaj Dev }
1160867cd155SPankaj Dev 
dwc3_get_ep_trbstatus(usb_dwc3_endpoint_t * ep)1161867cd155SPankaj Dev static uint32_t dwc3_get_ep_trbstatus(usb_dwc3_endpoint_t *ep)
1162867cd155SPankaj Dev {
1163867cd155SPankaj Dev 	return DWC3_TRB_SIZE_TRBSTS(ep->trb_addr->size);
1164867cd155SPankaj Dev }
1165867cd155SPankaj Dev 
dwc3_handle_ep0_xfernotready_event(dwc3_handle_t * dwc3_handle,uint32_t event,uint32_t * param)1166867cd155SPankaj Dev static enum usb_action dwc3_handle_ep0_xfernotready_event(dwc3_handle_t *dwc3_handle,
1167867cd155SPankaj Dev 							  uint32_t event, uint32_t *param)
1168867cd155SPankaj Dev {
1169867cd155SPankaj Dev 	enum usb_action action = USB_NOTHING;
1170867cd155SPankaj Dev 	uint8_t phy_epnum = dwc3_read_ep_evt_epnum(event);
1171867cd155SPankaj Dev 	struct pcd_handle *pcd_handle = dwc3_handle->pcd_handle;
1172867cd155SPankaj Dev 	uint8_t status = dwc3_read_ep_evt_status(event);
1173867cd155SPankaj Dev 	uint8_t ep_addr, ep_num;
1174867cd155SPankaj Dev 	enum usb_status ret;
1175867cd155SPankaj Dev 
1176867cd155SPankaj Dev 	ep_addr = __HAL_PCD_PHYEPNUM_TO_EPADDR(phy_epnum);
1177867cd155SPankaj Dev 	ep_num = ep_addr & ADDRESS_MASK;
1178867cd155SPankaj Dev 
1179867cd155SPankaj Dev 	if (__HAL_PCD_SETUP_REQ_LEN(dwc3_handle->setup_addr) == 0U) {
1180867cd155SPankaj Dev 		switch (status) {
1181867cd155SPankaj Dev 		case USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_STATUS:
1182867cd155SPankaj Dev 			api_memcpy(dwc3_handle->pcd_handle->setup,
1183867cd155SPankaj Dev 				   dwc3_handle->setup_addr,
1184867cd155SPankaj Dev 				   sizeof(dwc3_handle->pcd_handle->setup));
1185867cd155SPankaj Dev 			action = USB_SETUP;
1186867cd155SPankaj Dev 			break;
1187867cd155SPankaj Dev 		case USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_DATA:
1188867cd155SPankaj Dev 			ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num); // OUT EP0
1189867cd155SPankaj Dev 			if (ret != USBD_OK) {
1190867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1191867cd155SPankaj Dev 			}
1192867cd155SPankaj Dev 			break;
1193867cd155SPankaj Dev 		default:
1194867cd155SPankaj Dev 			VERBOSE("Invalid Status %d: %s: %d\n", status, __func__, __LINE__);
1195867cd155SPankaj Dev 			break;
1196867cd155SPankaj Dev 		}
1197867cd155SPankaj Dev 	} else {
1198867cd155SPankaj Dev 		switch (status) {
1199867cd155SPankaj Dev 		case USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_STATUS:
1200867cd155SPankaj Dev 			if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {
1201867cd155SPankaj Dev 				*param = ep_num;
1202867cd155SPankaj Dev 				action = USB_DATA_OUT;
1203867cd155SPankaj Dev 			} else {
1204867cd155SPankaj Dev 				*param = ep_num;
1205867cd155SPankaj Dev 				action = USB_DATA_IN;
1206867cd155SPankaj Dev 			}
1207867cd155SPankaj Dev 			break;
1208867cd155SPankaj Dev 		case USB_DWC3_DEPEVT_XFERNOTREADY_STATUS_CTRL_DATA:
1209867cd155SPankaj Dev 			if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {
1210867cd155SPankaj Dev 				/* if wrong direction */
1211867cd155SPankaj Dev 				if (__HAL_PCD_SETUP_REQ_DATA_DIR_IN(dwc3_handle->setup_addr) ==
1212867cd155SPankaj Dev 				    0U) {
1213867cd155SPankaj Dev 					ret = dwc3_ep_stop_xfer(dwc3_handle,
1214867cd155SPankaj Dev 								&pcd_handle->out_ep[0]);
1215867cd155SPankaj Dev 					if (ret != USBD_OK) {
1216867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1217867cd155SPankaj Dev 					}
1218867cd155SPankaj Dev 					ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num); // OUT EP0
1219867cd155SPankaj Dev 					if (ret != USBD_OK) {
1220867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1221867cd155SPankaj Dev 					}
1222867cd155SPankaj Dev 				}
1223867cd155SPankaj Dev 				/*
1224867cd155SPankaj Dev 				 * last packet is MPS multiple, so send ZLP packet,
1225867cd155SPankaj Dev 				 * handled by USBD_core.c
1226867cd155SPankaj Dev 				 */
1227867cd155SPankaj Dev 			} else {
1228867cd155SPankaj Dev 				/* if wrong direction */
1229867cd155SPankaj Dev 				if (__HAL_PCD_SETUP_REQ_DATA_DIR_IN(dwc3_handle->setup_addr) !=
1230867cd155SPankaj Dev 				    0U) {
1231867cd155SPankaj Dev 					ret = dwc3_ep_stop_xfer(dwc3_handle,
1232867cd155SPankaj Dev 								&pcd_handle->in_ep[0]);
1233867cd155SPankaj Dev 					if (ret != USBD_OK) {
1234867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1235867cd155SPankaj Dev 					}
1236867cd155SPankaj Dev 					ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num); // OUT EP0
1237867cd155SPankaj Dev 					if (ret != USBD_OK) {
1238867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1239867cd155SPankaj Dev 					}
1240867cd155SPankaj Dev 				}
1241867cd155SPankaj Dev 			}
1242867cd155SPankaj Dev 			break;
1243867cd155SPankaj Dev 		default:
1244867cd155SPankaj Dev 			VERBOSE("Invalid Status %d: %s: %d\n", status, __func__, __LINE__);
1245867cd155SPankaj Dev 			break;
1246867cd155SPankaj Dev 		}
1247867cd155SPankaj Dev 	}
1248867cd155SPankaj Dev 
1249867cd155SPankaj Dev 	return action;
1250867cd155SPankaj Dev }
1251867cd155SPankaj Dev 
dwc3_handle_ep_event(dwc3_handle_t * dwc3_handle,uint32_t event,uint32_t * param)1252867cd155SPankaj Dev static enum usb_action dwc3_handle_ep_event(dwc3_handle_t *dwc3_handle, uint32_t event,
1253867cd155SPankaj Dev 					    uint32_t *param)
1254867cd155SPankaj Dev {
1255867cd155SPankaj Dev 	enum usb_action action = USB_NOTHING;
1256867cd155SPankaj Dev 	uint8_t type = dwc3_read_ep_evt_type(event);
1257867cd155SPankaj Dev 	uint8_t phy_epnum = dwc3_read_ep_evt_epnum(event);
1258867cd155SPankaj Dev 	uint8_t ep_addr, ep_num;
1259867cd155SPankaj Dev 	struct usbd_ep *ep;
1260867cd155SPankaj Dev 	usb_dwc3_endpoint_t *dwc3_ep;
1261867cd155SPankaj Dev 	enum usb_status ret;
1262867cd155SPankaj Dev 
1263867cd155SPankaj Dev 	ep_addr = __HAL_PCD_PHYEPNUM_TO_EPADDR(phy_epnum);
1264867cd155SPankaj Dev 	ep_num = ep_addr & ADDRESS_MASK;
1265867cd155SPankaj Dev 
1266867cd155SPankaj Dev 	if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {
1267867cd155SPankaj Dev 		ep = &dwc3_handle->pcd_handle->in_ep[ep_num];
1268867cd155SPankaj Dev 		dwc3_ep = &dwc3_handle->IN_ep[ep_num];
1269867cd155SPankaj Dev 	} else {
1270867cd155SPankaj Dev 		ep = &dwc3_handle->pcd_handle->out_ep[ep_num];
1271867cd155SPankaj Dev 		dwc3_ep = &dwc3_handle->OUT_ep[ep_num];
1272867cd155SPankaj Dev 	}
1273867cd155SPankaj Dev 
1274867cd155SPankaj Dev 	switch (type) {
1275867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_XFERCOMPLETE:
1276867cd155SPankaj Dev 		VERBOSE("EP%d%s: Transfer Complete Event=%x\n", ep_num,
1277867cd155SPankaj Dev 			   ep->is_in ? "IN" : "OUT", event);
1278867cd155SPankaj Dev 
1279867cd155SPankaj Dev 		if (ep->type == EP_TYPE_ISOC) {
1280867cd155SPankaj Dev 			VERBOSE("EP%d%s is an Isochronous endpoint\n", ep_num,
1281867cd155SPankaj Dev 				   ep->is_in ? "IN" : "OUT");
1282867cd155SPankaj Dev 			break;
1283867cd155SPankaj Dev 		}
1284867cd155SPankaj Dev 
1285867cd155SPankaj Dev 		/* Just forr Log, since ctrl expects sw to follow the whole control
1286867cd155SPankaj Dev 		 * programming sequence, as also mentioned in Linux driver
1287867cd155SPankaj Dev 		 */
1288867cd155SPankaj Dev 		if ((ep_num == 0U) &&
1289867cd155SPankaj Dev 		    (dwc3_get_ep_trbstatus(dwc3_ep) == USB_DWC3_TRBSTS_SETUP_PENDING)) {
1290867cd155SPankaj Dev 			VERBOSE("EP%d%s Setup Pending received\n", ep_num,
1291867cd155SPankaj Dev 				   ep->is_in ? "IN" : "OUT");
1292867cd155SPankaj Dev 		}
1293867cd155SPankaj Dev 
1294867cd155SPankaj Dev 		VERBOSE("EP%d%s: Transfer Complete trb %p:%08x:%08x:%08x:%08x TRB-Status %u\n",
1295867cd155SPankaj Dev 			   ep_num, ep->is_in ? "IN" : "OUT", dwc3_ep->trb_addr,
1296867cd155SPankaj Dev 			   (uint32_t)dwc3_ep->trb_addr->bph, (uint32_t)dwc3_ep->trb_addr->bpl,
1297867cd155SPankaj Dev 			   (uint32_t)dwc3_ep->trb_addr->size, (uint32_t)dwc3_ep->trb_addr->ctrl,
1298867cd155SPankaj Dev 			   dwc3_get_ep_trbstatus(dwc3_ep));
1299867cd155SPankaj Dev 
1300867cd155SPankaj Dev 		if ((ep_addr & EP_DIR_MASK) == EP_DIR_IN) {  /* IN EP */
1301867cd155SPankaj Dev 			ep->xfer_count = ep->xfer_len - dwc3_get_ep_trblen(dwc3_ep);
1302867cd155SPankaj Dev 
1303867cd155SPankaj Dev 			dwc3_ep->flags &= ~USB_DWC3_EP_REQ_QUEUED;
1304867cd155SPankaj Dev 
1305867cd155SPankaj Dev 			if (ep->xfer_buff != NULL) {
1306867cd155SPankaj Dev 				api_unmapdmaaddr(dwc3_ep->dma_addr, ep->xfer_len, 1);
1307867cd155SPankaj Dev 			}
1308867cd155SPankaj Dev 
1309867cd155SPankaj Dev 			/*
1310867cd155SPankaj Dev 			 * For EP0IN, if packet is not sent completely,
1311867cd155SPankaj Dev 			 * then error, as done in Linux driver
1312867cd155SPankaj Dev 			 */
1313867cd155SPankaj Dev 			if ((ep_num == 0U) && (ep->xfer_len != ep->xfer_count)) {
1314867cd155SPankaj Dev 				ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num); // OUT EP0
1315867cd155SPankaj Dev 				if (ret != USBD_OK) {
1316867cd155SPankaj Dev 					ERROR("%s: %d\n", __func__, __LINE__);
1317867cd155SPankaj Dev 				}
1318867cd155SPankaj Dev 			}
1319867cd155SPankaj Dev 
1320867cd155SPankaj Dev 			/*
1321867cd155SPankaj Dev 			 * if 3-stage then wait for XFERNOTREADY(control-status) before
1322867cd155SPankaj Dev 			 * sending data to upper layer
1323867cd155SPankaj Dev 			 */
1324867cd155SPankaj Dev 			if ((ep_num != 0U) || (ep->xfer_len == 0U)) {
1325867cd155SPankaj Dev 				*param = ep_num;
1326867cd155SPankaj Dev 				action = USB_DATA_IN;
1327867cd155SPankaj Dev 			}
1328867cd155SPankaj Dev 
1329867cd155SPankaj Dev 			/* For EP0, this is ZLP, so prepare EP0 for next setup */
1330867cd155SPankaj Dev 			if ((ep_num == 0U) && (ep->xfer_len == 0U)) {
1331867cd155SPankaj Dev 				/* prepare to rx more setup packets */
1332867cd155SPankaj Dev 				dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
1333867cd155SPankaj Dev 
1334867cd155SPankaj Dev 				ret = dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
1335867cd155SPankaj Dev 				if (ret != USBD_OK) {
1336867cd155SPankaj Dev 					ERROR("%s: %d\n", __func__, __LINE__);
1337867cd155SPankaj Dev 					return action;
1338867cd155SPankaj Dev 				}
1339867cd155SPankaj Dev 			}
1340867cd155SPankaj Dev 		} else {
1341867cd155SPankaj Dev 			ep->xfer_count = ep->xfer_len - dwc3_get_ep_trblen(dwc3_ep);
1342867cd155SPankaj Dev 
1343867cd155SPankaj Dev 			dwc3_ep->flags &= ~USB_DWC3_EP_REQ_QUEUED;
1344867cd155SPankaj Dev 
1345867cd155SPankaj Dev 			/* For EP0OUT */
1346867cd155SPankaj Dev 			if ((ep_addr == 0U) &&
1347867cd155SPankaj Dev 			    (dwc3_handle->EP0_State == HAL_PCD_EP0_SETUP_QUEUED)) {
1348867cd155SPankaj Dev 
1349867cd155SPankaj Dev 				dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_COMPLETED;
1350867cd155SPankaj Dev 				dwc3_ep->is_stall = false;
1351867cd155SPankaj Dev 				VERBOSE("EP%d%s: SetupData %02x%02x%02x%02x:%02x%02x%02x%02x\n",
1352867cd155SPankaj Dev 					   ep_num, ep->is_in ? "IN" : "OUT",
1353867cd155SPankaj Dev 					   dwc3_handle->setup_addr[0], dwc3_handle->setup_addr[1],
1354867cd155SPankaj Dev 					   dwc3_handle->setup_addr[2], dwc3_handle->setup_addr[3],
1355867cd155SPankaj Dev 					   dwc3_handle->setup_addr[4], dwc3_handle->setup_addr[5],
1356867cd155SPankaj Dev 					   dwc3_handle->setup_addr[6], dwc3_handle->setup_addr[7]);
1357867cd155SPankaj Dev 
1358867cd155SPankaj Dev 				// if 2-stage then wait for the XFERNOTREADY(control-status)
1359867cd155SPankaj Dev 				if (__HAL_PCD_SETUP_REQ_LEN(dwc3_handle->setup_addr) != 0U) {
1360867cd155SPankaj Dev 					api_memcpy(dwc3_handle->pcd_handle->setup,
1361867cd155SPankaj Dev 						   dwc3_handle->setup_addr,
1362867cd155SPankaj Dev 						   sizeof(dwc3_handle->pcd_handle->setup));
1363867cd155SPankaj Dev 					action = USB_SETUP;
1364867cd155SPankaj Dev 				}
1365867cd155SPankaj Dev 			} else {
1366867cd155SPankaj Dev 
1367867cd155SPankaj Dev 				if (ep->xfer_buff != NULL) {
1368867cd155SPankaj Dev 					api_unmapdmaaddr(dwc3_ep->dma_addr, ep->xfer_len, 0);
1369867cd155SPankaj Dev 				}
1370867cd155SPankaj Dev 
1371867cd155SPankaj Dev 				if (ep->xfer_buff == dwc3_ep->bounce_buf) {
1372867cd155SPankaj Dev 					api_memcpy(dwc3_ep->xfer_dest_buff, ep->xfer_buff,
1373867cd155SPankaj Dev 						   ep->xfer_count);
1374867cd155SPankaj Dev 					ep->xfer_buff = dwc3_ep->xfer_dest_buff;
1375867cd155SPankaj Dev 				}
1376867cd155SPankaj Dev 
1377867cd155SPankaj Dev 				/*
1378867cd155SPankaj Dev 				 * if 3-stage then wait for XFERNOTREADY(control-status) before
1379867cd155SPankaj Dev 				 * sending data to upper layer
1380867cd155SPankaj Dev 				 */
1381867cd155SPankaj Dev 				if ((ep_num != 0U) || (ep->xfer_len == 0U)) {
1382867cd155SPankaj Dev 					*param = ep_num;
1383867cd155SPankaj Dev 					action = USB_DATA_OUT;
1384867cd155SPankaj Dev 				}
1385867cd155SPankaj Dev 
1386867cd155SPankaj Dev 				/* For EP0, this is ZLP, so prepare EP0 for next setup */
1387867cd155SPankaj Dev 				if ((ep_num == 0U) && (ep->xfer_len == 0U)) {
1388867cd155SPankaj Dev 					/* prepare to rx more setup packets */
1389867cd155SPankaj Dev 					dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
1390867cd155SPankaj Dev 
1391867cd155SPankaj Dev 					ret = dwc3_ep0_out_start(dwc3_handle,
1392867cd155SPankaj Dev 								 dwc3_handle->setup_dma_addr);
1393867cd155SPankaj Dev 					if (ret != USBD_OK) {
1394867cd155SPankaj Dev 						ERROR("%s: %d\n", __func__, __LINE__);
1395867cd155SPankaj Dev 						return action;
1396867cd155SPankaj Dev 					}
1397867cd155SPankaj Dev 				}
1398867cd155SPankaj Dev 			}
1399867cd155SPankaj Dev 		}
1400867cd155SPankaj Dev 
1401867cd155SPankaj Dev 		break;
1402867cd155SPankaj Dev 
1403867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_XFERINPROGRESS:
1404867cd155SPankaj Dev 		VERBOSE("EP%d%s: Transfer In-Progress %u Event=%x\n", ep_num,
1405867cd155SPankaj Dev 			   ep->is_in ? "IN" : "OUT", dwc3_handle->intbuffers.evtbufferpos[0],
1406867cd155SPankaj Dev 			   event);
1407867cd155SPankaj Dev 
1408867cd155SPankaj Dev 		if (ep_num == 0U) { // ***ToCheck
1409867cd155SPankaj Dev 			break;
1410867cd155SPankaj Dev 		}
1411867cd155SPankaj Dev 
1412867cd155SPankaj Dev 		/*
1413867cd155SPankaj Dev 		 * currently not planned to issue multiple TRB transfer, hence there shouldn't
1414867cd155SPankaj Dev 		 * be any event like this
1415867cd155SPankaj Dev 		 */
1416867cd155SPankaj Dev 
1417867cd155SPankaj Dev 		/*
1418867cd155SPankaj Dev 		 * But for isoc transfers we need get it since transfer started with
1419867cd155SPankaj Dev 		 * loop(link) trb
1420867cd155SPankaj Dev 		 */
1421867cd155SPankaj Dev 		if (ep->type != EP_TYPE_ISOC) {
1422867cd155SPankaj Dev 			break;
1423867cd155SPankaj Dev 		}
1424867cd155SPankaj Dev 
1425867cd155SPankaj Dev 		break;
1426867cd155SPankaj Dev 
1427867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_XFERNOTREADY:
1428867cd155SPankaj Dev 		VERBOSE("EP%d%s: Transfer Not Ready Event=%x\n", ep_num,
1429867cd155SPankaj Dev 			   ep->is_in ? "IN" : "OUT", event);
1430867cd155SPankaj Dev 		/* For EP0IN or EP0OUT, currently no plan to use xfernotready interrupt */
1431867cd155SPankaj Dev 
1432867cd155SPankaj Dev 		//active = PCD_READ_DEPEVT_STATUS(event);
1433867cd155SPankaj Dev 
1434867cd155SPankaj Dev 		if (ep_num == 0U) {
1435867cd155SPankaj Dev 
1436867cd155SPankaj Dev 			if (dwc3_handle->EP0_State == HAL_PCD_EP0_SETUP_QUEUED) {
1437867cd155SPankaj Dev 				ret = dwc3_epaddr_set_stall(dwc3_handle, ep_num);  // OUT EP0
1438867cd155SPankaj Dev 				if (ret != USBD_OK) {
1439867cd155SPankaj Dev 					ERROR("%s: %d\n", __func__, __LINE__);
1440867cd155SPankaj Dev 					return action;
1441867cd155SPankaj Dev 				}
1442867cd155SPankaj Dev 			} else {
1443867cd155SPankaj Dev 				action = dwc3_handle_ep0_xfernotready_event(dwc3_handle, event,
1444867cd155SPankaj Dev 									    param);
1445867cd155SPankaj Dev 			}
1446867cd155SPankaj Dev 		}
1447867cd155SPankaj Dev 
1448867cd155SPankaj Dev 		/*
1449867cd155SPankaj Dev 		 * Currently we dont implement provide request queue to support On-demand transfers
1450867cd155SPankaj Dev 		 * for non-isoc EP, it only supports preset transfers so this event will not be
1451867cd155SPankaj Dev 		 * used, Section 9.2.4 "Transfer Setup Recommendations"
1452867cd155SPankaj Dev 		 */
1453867cd155SPankaj Dev 
1454867cd155SPankaj Dev 		/*
1455867cd155SPankaj Dev 		 * But for isoc transfers we need to issue the request from here using the
1456867cd155SPankaj Dev 		 * micro-frame number
1457867cd155SPankaj Dev 		 */
1458867cd155SPankaj Dev 		if (ep->type != EP_TYPE_ISOC) {
1459867cd155SPankaj Dev 			break;
1460867cd155SPankaj Dev 		}
1461867cd155SPankaj Dev 
1462867cd155SPankaj Dev 		break;
1463867cd155SPankaj Dev 
1464867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_STREAMEVT: /* Stream event, Not used */
1465867cd155SPankaj Dev 		break;
1466867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_RXTXFIFOEVT: /* FIFO Overrun */
1467867cd155SPankaj Dev 		break;
1468867cd155SPankaj Dev 	case USB_DWC3_DEPEVT_EPCMDCMPLT: /* Endpoint Command Complete */
1469867cd155SPankaj Dev 		VERBOSE("EP%d%s: Endpoint Command Complete Event=%x\n", ep_num,
1470867cd155SPankaj Dev 			   ep->is_in ? "IN" : "OUT", event);
1471867cd155SPankaj Dev 		break;
1472867cd155SPankaj Dev 	default:
1473867cd155SPankaj Dev 		VERBOSE("Invalid type %d: %s: %d\n", type, __func__, __LINE__);
1474867cd155SPankaj Dev 		break;
1475867cd155SPankaj Dev 	}
1476867cd155SPankaj Dev 
1477867cd155SPankaj Dev 	return action;
1478867cd155SPankaj Dev }
1479867cd155SPankaj Dev 
dwc3_read_dev_evt_type(uint32_t event)1480867cd155SPankaj Dev static uint8_t dwc3_read_dev_evt_type(uint32_t event)
1481867cd155SPankaj Dev {
1482867cd155SPankaj Dev 	uint8_t ret;
1483867cd155SPankaj Dev 
1484867cd155SPankaj Dev 	switch ((event & DWC3_EVT_DEVEVT_TYPE_MASK) >> DWC3_EVT_DEVEVT_TYPE_BITPOS) {
1485867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_DISCONNECT:
1486867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_DISCONNECT;
1487867cd155SPankaj Dev 		break;
1488867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_RESET:
1489867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_RESET;
1490867cd155SPankaj Dev 		break;
1491867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_CONNECT_DONE:
1492867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_CONNECT_DONE;
1493867cd155SPankaj Dev 		break;
1494867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
1495867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE;
1496867cd155SPankaj Dev 		break;
1497867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_WAKEUP:
1498867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_WAKEUP;
1499867cd155SPankaj Dev 		break;
1500867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_HIBER_REQ:
1501867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_HIBER_REQ;
1502867cd155SPankaj Dev 		break;
1503867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_EOPF:
1504867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_EOPF;
1505867cd155SPankaj Dev 		break;
1506867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_SOF:
1507867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_SOF;
1508867cd155SPankaj Dev 		break;
1509867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
1510867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_ERRATIC_ERROR;
1511867cd155SPankaj Dev 		break;
1512867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_CMD_CMPL:
1513867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_CMD_CMPL;
1514867cd155SPankaj Dev 		break;
1515867cd155SPankaj Dev 	case DWC3_DEVICE_EVENT_OVERFLOW:
1516867cd155SPankaj Dev 		ret = USB_DWC3_DEVICE_EVENT_OVERFLOW;
1517867cd155SPankaj Dev 		break;
1518867cd155SPankaj Dev 	default:
1519867cd155SPankaj Dev 		ret = 0;
1520867cd155SPankaj Dev 		break;
1521867cd155SPankaj Dev 	}
1522867cd155SPankaj Dev 
1523867cd155SPankaj Dev 	return ret;
1524867cd155SPankaj Dev }
1525867cd155SPankaj Dev 
1526e5bafa29SYann Gautier #if (USB_DWC3_NUM_IN_EP > 1) || (USB_DWC3_NUM_OUT_EP > 1)
dwc3_ep_clear_stall(dwc3_handle_t * dwc3_handle,usb_dwc3_endpoint_t * dwc3_ep)1527867cd155SPankaj Dev static enum usb_status dwc3_ep_clear_stall(dwc3_handle_t *dwc3_handle, usb_dwc3_endpoint_t *dwc3_ep)
1528867cd155SPankaj Dev {
1529867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
1530867cd155SPankaj Dev 
1531867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
1532867cd155SPankaj Dev 
1533867cd155SPankaj Dev 	return dwc3_execute_dep_cmd(dwc3_handle, dwc3_ep->phy_epnum, USB_DWC3_DEPCMD_CLEARSTALL,
1534867cd155SPankaj Dev 				    &params);
1535867cd155SPankaj Dev }
1536e5bafa29SYann Gautier #endif
1537867cd155SPankaj Dev 
dwc3_get_dev_speed(dwc3_handle_t * dwc3_handle)1538867cd155SPankaj Dev static uint8_t dwc3_get_dev_speed(dwc3_handle_t *dwc3_handle)
1539867cd155SPankaj Dev {
1540867cd155SPankaj Dev 	uint32_t reg;
1541867cd155SPankaj Dev 	uint8_t ret;
1542867cd155SPankaj Dev 
1543867cd155SPankaj Dev 	reg = DWC3_regread(dwc3_handle->usb_device, DWC3_DSTS) & USB3_DSTS_CONNECTSPD;
1544867cd155SPankaj Dev 
1545867cd155SPankaj Dev 	switch (reg) {
1546867cd155SPankaj Dev 	case DWC3_DSTS_SUPERSPEED:
1547867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_SUPER;
1548867cd155SPankaj Dev 		INFO("%s = SuperSpeed\n", __func__);
1549867cd155SPankaj Dev 		break;
1550867cd155SPankaj Dev 	case DWC3_DSTS_HIGHSPEED:
1551867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_HIGH;
1552867cd155SPankaj Dev 		INFO("%s = HighSpeed\n", __func__);
1553867cd155SPankaj Dev 		break;
1554867cd155SPankaj Dev 	case DWC3_DSTS_FULLSPEED1:
1555867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_FULL_48;
1556867cd155SPankaj Dev 		INFO("%s = FullSpeed_48M\n", __func__);
1557867cd155SPankaj Dev 		break;
1558867cd155SPankaj Dev 	case DWC3_DSTS_FULLSPEED2:
1559867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_FULL;
1560867cd155SPankaj Dev 		INFO("%s = FullSpeed\n", __func__);
1561867cd155SPankaj Dev 		break;
1562867cd155SPankaj Dev 	case DWC3_DSTS_LOWSPEED:
1563867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_LOW;
1564867cd155SPankaj Dev 		INFO("%s = LowSpeed\n", __func__);
1565867cd155SPankaj Dev 		break;
1566867cd155SPankaj Dev 	default: /* Invalid */
1567867cd155SPankaj Dev 		ret = USB_DWC3_SPEED_INVALID;
1568867cd155SPankaj Dev 		INFO("%s = Invalid\n", __func__);
1569867cd155SPankaj Dev 		break;
1570867cd155SPankaj Dev 	}
1571867cd155SPankaj Dev 
1572867cd155SPankaj Dev 	return ret;
1573867cd155SPankaj Dev }
1574867cd155SPankaj Dev 
dwc3_get_epcfg_action(uint8_t action)1575867cd155SPankaj Dev static uint32_t dwc3_get_epcfg_action(uint8_t action)
1576867cd155SPankaj Dev {
1577867cd155SPankaj Dev 	uint32_t ret;
1578867cd155SPankaj Dev 
1579867cd155SPankaj Dev 	switch (action) {
1580867cd155SPankaj Dev 	case USB_DWC3_DEPCFG_ACTION_INIT:
1581867cd155SPankaj Dev 		ret = DWC3_DEPCFG_ACTION_INIT;
1582867cd155SPankaj Dev 		break;
1583867cd155SPankaj Dev 	case USB_DWC3_DEPCFG_ACTION_RESTORE:
1584867cd155SPankaj Dev 		ret = DWC3_DEPCFG_ACTION_RESTORE;
1585867cd155SPankaj Dev 		break;
1586867cd155SPankaj Dev 	case USB_DWC3_DEPCFG_ACTION_MODIFY:
1587867cd155SPankaj Dev 		ret = DWC3_DEPCFG_ACTION_MODIFY;
1588867cd155SPankaj Dev 		break;
1589867cd155SPankaj Dev 	default:
1590867cd155SPankaj Dev 		ret = 0U;
1591867cd155SPankaj Dev 		break;
1592867cd155SPankaj Dev 	}
1593867cd155SPankaj Dev 
1594867cd155SPankaj Dev 	return ret;
1595867cd155SPankaj Dev }
1596867cd155SPankaj Dev 
dwc3_ep_configure(dwc3_handle_t * dwc3_handle,uint8_t epnum,bool is_in,uint8_t type,uint32_t max_packet,uint8_t tx_fifo,uint16_t binterval,uint8_t phy_epnum,uint8_t intr_num,uint8_t action)1597867cd155SPankaj Dev static enum usb_status dwc3_ep_configure(dwc3_handle_t *dwc3_handle, uint8_t epnum, bool is_in,
1598867cd155SPankaj Dev 					 uint8_t type, uint32_t max_packet, uint8_t tx_fifo,
1599867cd155SPankaj Dev 					 uint16_t binterval, uint8_t phy_epnum, uint8_t intr_num,
1600867cd155SPankaj Dev 					 uint8_t action)
1601867cd155SPankaj Dev {
1602867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
1603867cd155SPankaj Dev 
1604867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
1605867cd155SPankaj Dev 	params.param0 = DWC3_DEPCFG_EP_TYPE(type) | DWC3_DEPCFG_MAX_PACKET_SIZE(max_packet);
1606867cd155SPankaj Dev 
1607867cd155SPankaj Dev 	/* Burst size is only needed in SuperSpeed mode */
1608867cd155SPankaj Dev 	//params.param0 |= DWC3_DEPCFG_BURST_SIZE(0);
1609867cd155SPankaj Dev 
1610867cd155SPankaj Dev 	params.param0 |= dwc3_get_epcfg_action(action);
1611867cd155SPankaj Dev 
1612867cd155SPankaj Dev 	params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN | DWC3_DEPCFG_XFER_NOT_READY_EN;
1613867cd155SPankaj Dev 	if (type == EP_TYPE_ISOC) {
1614867cd155SPankaj Dev 		params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN;
1615867cd155SPankaj Dev 	}
1616867cd155SPankaj Dev 
1617867cd155SPankaj Dev 	params.param1 |= DWC3_DEPCFG_EP_NUMBER(((uint32_t)epnum << 1) + (is_in ? 1UL : 0UL));
1618867cd155SPankaj Dev 
1619867cd155SPankaj Dev 	params.param1 |= DWC3_DEPCFG_EP_INTR_NUM(intr_num);
1620867cd155SPankaj Dev 
1621867cd155SPankaj Dev 	if (is_in) {
1622867cd155SPankaj Dev 		params.param0 |= DWC3_DEPCFG_FIFO_NUMBER(tx_fifo);
1623867cd155SPankaj Dev 	}
1624867cd155SPankaj Dev 
1625867cd155SPankaj Dev 	if (binterval != 0U) {
1626867cd155SPankaj Dev 		params.param1 |= DWC3_DEPCFG_BINTERVAL_M1(binterval - 1UL);
1627867cd155SPankaj Dev 	}
1628867cd155SPankaj Dev 
1629867cd155SPankaj Dev 	return dwc3_execute_dep_cmd(dwc3_handle, phy_epnum, USB_DWC3_DEPCMD_SETEPCONFIG, &params);
1630867cd155SPankaj Dev }
1631867cd155SPankaj Dev 
dwc3_read_dev_evt_linkstate(uint32_t event)1632867cd155SPankaj Dev static inline uint8_t dwc3_read_dev_evt_linkstate(uint32_t event)
1633867cd155SPankaj Dev {
1634867cd155SPankaj Dev 	return (uint8_t)((event & DWC3_EVT_DEVEVT_LNKSTS_MASK) >> DWC3_EVT_DEVEVT_LNKSTS_BITPOS);
1635867cd155SPankaj Dev }
1636867cd155SPankaj Dev 
dwc3_get_linkstate_str(uint8_t state)1637867cd155SPankaj Dev static inline const char *dwc3_get_linkstate_str(uint8_t state)
1638867cd155SPankaj Dev {
1639867cd155SPankaj Dev 	const char *ret;
1640867cd155SPankaj Dev 
1641867cd155SPankaj Dev 	switch (state) {
1642867cd155SPankaj Dev 	case DWC3_LINK_STATE_ON:
1643867cd155SPankaj Dev 		ret = "ON";
1644867cd155SPankaj Dev 		break;
1645867cd155SPankaj Dev 	case DWC3_LINK_STATE_L1:
1646867cd155SPankaj Dev 		ret = "L1";
1647867cd155SPankaj Dev 		break;
1648867cd155SPankaj Dev 	case DWC3_LINK_STATE_L2:
1649867cd155SPankaj Dev 		ret = "L2";
1650867cd155SPankaj Dev 		break;
1651867cd155SPankaj Dev 	case DWC3_LINK_STATE_DIS:
1652867cd155SPankaj Dev 		ret = "Disconnect";
1653867cd155SPankaj Dev 		break;
1654867cd155SPankaj Dev 	case DWC3_LINK_STATE_EARLY_SUS:
1655867cd155SPankaj Dev 		ret = "Early Suspend";
1656867cd155SPankaj Dev 		break;
1657867cd155SPankaj Dev 	case DWC3_LINK_STATE_RESET:
1658867cd155SPankaj Dev 		ret = "Reset";
1659867cd155SPankaj Dev 		break;
1660867cd155SPankaj Dev 	case DWC3_LINK_STATE_RESUME:
1661867cd155SPankaj Dev 		ret = "Resume";
1662867cd155SPankaj Dev 		break;
1663867cd155SPankaj Dev 	default:
1664867cd155SPankaj Dev 		ret = "UNKNOWN state";
1665867cd155SPankaj Dev 		break;
1666867cd155SPankaj Dev 	}
1667867cd155SPankaj Dev 
1668867cd155SPankaj Dev 	return ret;
1669867cd155SPankaj Dev }
1670867cd155SPankaj Dev 
dwc3_handle_dev_event(dwc3_handle_t * dwc3_handle,uint32_t event,uint32_t * param)1671867cd155SPankaj Dev static enum usb_action dwc3_handle_dev_event(dwc3_handle_t *dwc3_handle, uint32_t event,
1672867cd155SPankaj Dev 					     uint32_t *param)
1673867cd155SPankaj Dev {
1674867cd155SPankaj Dev 	enum usb_action action = USB_NOTHING;
1675867cd155SPankaj Dev 	uint8_t type = dwc3_read_dev_evt_type(event);
1676867cd155SPankaj Dev 	uint8_t i, speed;
1677867cd155SPankaj Dev 	enum usb_status ret;
1678867cd155SPankaj Dev 	uint32_t ep0_mps = USB3_MAX_PACKET_SIZE;
1679867cd155SPankaj Dev 
1680867cd155SPankaj Dev 	switch (type) {
1681867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_DISCONNECT:
1682867cd155SPankaj Dev 		INFO("Event: Device Disconnect\n");
1683867cd155SPankaj Dev 		/* For SuperSpeed, set DCTL[8:5] to 5*/
1684867cd155SPankaj Dev 
1685867cd155SPankaj Dev 		action = USB_DISCONNECT;
1686867cd155SPankaj Dev 		break;
1687867cd155SPankaj Dev 
1688867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_RESET:
1689867cd155SPankaj Dev 		INFO("Event: Device Reset\n");
1690867cd155SPankaj Dev 		/*
1691867cd155SPankaj Dev 		 * Spec says, Wait till EP0 finishes current transfer and reaches Setup-Stage.
1692867cd155SPankaj Dev 		 * But there is no wait in Linux driver which means that Host will take care while
1693867cd155SPankaj Dev 		 * issuing a reset. Also its tricky to implement since we can't wait here
1694867cd155SPankaj Dev 		 * (in interrupt context) for further control EP interrupts
1695867cd155SPankaj Dev 		 */
1696867cd155SPankaj Dev 
1697867cd155SPankaj Dev 		if (dwc3_handle->EP0_State != HAL_PCD_EP0_SETUP_QUEUED) {
1698867cd155SPankaj Dev 			ret = dwc3_ep_stop_xfer(dwc3_handle, &dwc3_handle->pcd_handle->out_ep[0]);
1699867cd155SPankaj Dev 			if (ret != USBD_OK) {
1700867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1701867cd155SPankaj Dev 			}
1702867cd155SPankaj Dev 			ret = dwc3_epaddr_set_stall(dwc3_handle, EP0_OUT); // OUT EP0
1703867cd155SPankaj Dev 			if (ret != USBD_OK) {
1704867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1705867cd155SPankaj Dev 			}
1706867cd155SPankaj Dev 		}
1707867cd155SPankaj Dev 
1708867cd155SPankaj Dev 		/*
1709867cd155SPankaj Dev 		 * Stop transfers for all(USB_DWC3_NUM_IN_EPS) EP
1710867cd155SPankaj Dev 		 * except EP0IN k = USB_DWC3_NUM_IN_EP
1711867cd155SPankaj Dev 		 */
1712867cd155SPankaj Dev 		for (i = 0; i < USB_DWC3_NUM_IN_EP; i++) {
1713867cd155SPankaj Dev 			dwc3_ep_stop_xfer(dwc3_handle,
1714867cd155SPankaj Dev 					      &dwc3_handle->pcd_handle->in_ep[i]);
1715867cd155SPankaj Dev 		}
1716867cd155SPankaj Dev 
1717e5bafa29SYann Gautier #if USB_DWC3_NUM_OUT_EP > 1
1718867cd155SPankaj Dev 		/* Stop transfers for all EP except EP0OUT k = USB_DWC3_NUM_OUT_EP */
1719867cd155SPankaj Dev 		for (i = 1; i < USB_DWC3_NUM_OUT_EP; i++) {
1720867cd155SPankaj Dev 			dwc3_ep_stop_xfer(dwc3_handle,
1721867cd155SPankaj Dev 					      &dwc3_handle->pcd_handle->out_ep[i]);
1722867cd155SPankaj Dev 		}
1723e5bafa29SYann Gautier #endif
1724867cd155SPankaj Dev 
1725e5bafa29SYann Gautier #if USB_DWC3_NUM_IN_EP > 1
1726867cd155SPankaj Dev 		/* Clear Stall for all EP except EP0IN k = USB_DWC3_NUM_IN_EP */
1727867cd155SPankaj Dev 		for (i = 1; i < USB_DWC3_NUM_IN_EP; i++) {
1728e5bafa29SYann Gautier 			usb_dwc3_endpoint_t *ep = &dwc3_handle->IN_ep[i];
1729867cd155SPankaj Dev 
1730867cd155SPankaj Dev 			if (!ep->is_stall) {
1731867cd155SPankaj Dev 				continue;
1732867cd155SPankaj Dev 			}
1733867cd155SPankaj Dev 
1734867cd155SPankaj Dev 			ep->is_stall = false;
1735867cd155SPankaj Dev 
1736867cd155SPankaj Dev 			ret = dwc3_ep_clear_stall(dwc3_handle, ep);
1737867cd155SPankaj Dev 			if (ret != USBD_OK) {
1738867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1739867cd155SPankaj Dev 				return action;
1740867cd155SPankaj Dev 			}
1741867cd155SPankaj Dev 		}
1742e5bafa29SYann Gautier #endif
1743867cd155SPankaj Dev 
1744e5bafa29SYann Gautier #if USB_DWC3_NUM_OUT_EP > 1
1745867cd155SPankaj Dev 		/* Clear Stall for all EP except EP0OUT k = USB_DWC3_NUM_OUT_EP */
1746867cd155SPankaj Dev 		for (i = 1; i < USB_DWC3_NUM_OUT_EP; i++) {
1747e5bafa29SYann Gautier 			usb_dwc3_endpoint_t *ep = &dwc3_handle->OUT_ep[i];
1748867cd155SPankaj Dev 
1749867cd155SPankaj Dev 			if (!ep->is_stall) {
1750867cd155SPankaj Dev 				continue;
1751867cd155SPankaj Dev 			}
1752867cd155SPankaj Dev 
1753867cd155SPankaj Dev 			ep->is_stall = false;
1754867cd155SPankaj Dev 			//ep->num   = ep_addr & ADDRESS_MASK;
1755867cd155SPankaj Dev 			//ep->is_in = ((ep_addr & 0x80) == 0x80);
1756867cd155SPankaj Dev 
1757867cd155SPankaj Dev 			ret = dwc3_ep_clear_stall(dwc3_handle, ep);
1758867cd155SPankaj Dev 			if (ret != USBD_OK) {
1759867cd155SPankaj Dev 				ERROR("%s: %d\n", __func__, __LINE__);
1760867cd155SPankaj Dev 				return action;
1761867cd155SPankaj Dev 			}
1762867cd155SPankaj Dev 		}
1763e5bafa29SYann Gautier #endif
1764867cd155SPankaj Dev 
1765867cd155SPankaj Dev 		/* Reset device address to zero */
1766867cd155SPankaj Dev 		ret = usb_dwc3_set_address(dwc3_handle, 0);
1767867cd155SPankaj Dev 		if (ret != USBD_OK) {
1768867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
1769867cd155SPankaj Dev 			return action;
1770867cd155SPankaj Dev 		}
1771867cd155SPankaj Dev 
1772867cd155SPankaj Dev 		action = USB_RESET;
1773867cd155SPankaj Dev 
1774867cd155SPankaj Dev 		break;
1775867cd155SPankaj Dev 
1776867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_CONNECT_DONE:
1777867cd155SPankaj Dev 		INFO("Event: Device Connection Done\n");
1778867cd155SPankaj Dev 
1779867cd155SPankaj Dev 		/*
1780867cd155SPankaj Dev 		 * hpcd->Init.ep0_mps = MaxPacketSize to 512 (SuperSpeed), 64 (High-Speed),
1781867cd155SPankaj Dev 		 * 8/16/32/64 (Full-Speed), or 8 (Low-Speed).
1782867cd155SPankaj Dev 		 */
1783867cd155SPankaj Dev 		speed = dwc3_get_dev_speed(dwc3_handle);
1784867cd155SPankaj Dev 		switch (speed) {
1785867cd155SPankaj Dev 		case USB_DWC3_SPEED_SUPER:
1786867cd155SPankaj Dev 			ep0_mps = 512;
1787867cd155SPankaj Dev 			break;
1788867cd155SPankaj Dev 		case USB_DWC3_SPEED_HIGH:
1789867cd155SPankaj Dev 			ep0_mps = 64;
1790867cd155SPankaj Dev 			break;
1791867cd155SPankaj Dev 		case USB_DWC3_SPEED_FULL_48:
1792867cd155SPankaj Dev 		case USB_DWC3_SPEED_FULL:
1793867cd155SPankaj Dev 			ep0_mps = 64;
1794867cd155SPankaj Dev 			break;
1795867cd155SPankaj Dev 		case USB_DWC3_SPEED_LOW:
1796867cd155SPankaj Dev 			ep0_mps = 8;
1797867cd155SPankaj Dev 			break;
1798867cd155SPankaj Dev 		default:
1799867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
1800867cd155SPankaj Dev 			break;
1801867cd155SPankaj Dev 		}
1802867cd155SPankaj Dev 
1803867cd155SPankaj Dev 		/* Update DWC3_GCTL_RAMCLKSEL, but only for Superspeed */
1804867cd155SPankaj Dev 
1805867cd155SPankaj Dev 		/* Modify max packet size for EP 0 & 1 */
1806867cd155SPankaj Dev 		ret = dwc3_ep_configure(dwc3_handle, 0, false, EP_TYPE_CTRL, ep0_mps, 0, 0, 0,
1807867cd155SPankaj Dev 					dwc3_handle->OUT_ep[0].intr_num,
1808867cd155SPankaj Dev 					USB_DWC3_DEPCFG_ACTION_MODIFY);
1809867cd155SPankaj Dev 		if (ret != USBD_OK) {
1810867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
1811867cd155SPankaj Dev 			return action;
1812867cd155SPankaj Dev 		}
1813867cd155SPankaj Dev 		ret = dwc3_ep_configure(dwc3_handle, 0, true, EP_TYPE_CTRL, ep0_mps, 0, 0, 1,
1814867cd155SPankaj Dev 					dwc3_handle->IN_ep[0].intr_num,
1815867cd155SPankaj Dev 					USB_DWC3_DEPCFG_ACTION_MODIFY);
1816867cd155SPankaj Dev 		if (ret != USBD_OK) {
1817867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
1818867cd155SPankaj Dev 			return action;
1819867cd155SPankaj Dev 		}
1820867cd155SPankaj Dev 
1821867cd155SPankaj Dev 		dwc3_handle->pcd_handle->out_ep[0].maxpacket = ep0_mps;
1822867cd155SPankaj Dev 		dwc3_handle->pcd_handle->in_ep[0].maxpacket = ep0_mps;
1823867cd155SPankaj Dev 
1824867cd155SPankaj Dev 		/*
1825867cd155SPankaj Dev 		 * Depending on the connected speed, write to the other
1826867cd155SPankaj Dev 		 * PHY's control register to suspend it.
1827867cd155SPankaj Dev 		 */
1828867cd155SPankaj Dev 
1829867cd155SPankaj Dev 		/* Use default values for GTXFIFOSIZn and GRXFIFOSIZ0 */
1830867cd155SPankaj Dev 
1831867cd155SPankaj Dev 		action = USB_ENUM_DONE;
1832867cd155SPankaj Dev 
1833867cd155SPankaj Dev 		break;
1834867cd155SPankaj Dev 
1835867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
1836867cd155SPankaj Dev 		INFO("Event: Link Status Change : %s(%d)\n",
1837867cd155SPankaj Dev 			   dwc3_get_linkstate_str(dwc3_read_dev_evt_linkstate(event)),
1838867cd155SPankaj Dev 			   dwc3_read_dev_evt_linkstate(event));
1839867cd155SPankaj Dev 		/* Handle link state changes, U0,U1,U2,U3 with suspend/resume functions */
1840867cd155SPankaj Dev 
1841867cd155SPankaj Dev 		break;
1842867cd155SPankaj Dev 
1843867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_WAKEUP:
1844867cd155SPankaj Dev 		INFO("Event: Wake-UP\n");
1845867cd155SPankaj Dev 		// resume function
1846867cd155SPankaj Dev 		action = USB_RESUME;
1847867cd155SPankaj Dev 		break;
1848867cd155SPankaj Dev 
1849867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_HIBER_REQ:
1850867cd155SPankaj Dev 		INFO("Event: Hibernation Request\n");
1851867cd155SPankaj Dev 		/* hibernation function */
1852867cd155SPankaj Dev 		break;
1853867cd155SPankaj Dev 
1854867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_EOPF: /* End of Periodic Frame */
1855867cd155SPankaj Dev 		INFO("Event: Suspend\n");
1856867cd155SPankaj Dev 		action = USB_SUSPEND;
1857867cd155SPankaj Dev 		break;
1858867cd155SPankaj Dev 
1859867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_SOF: /* Start of Periodic Frame */
1860867cd155SPankaj Dev 		INFO("Event: Start of Periodic Frame\n");
1861867cd155SPankaj Dev 		break;
1862867cd155SPankaj Dev 
1863867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_L1SUSPEND:
1864867cd155SPankaj Dev 		INFO("Event: L1 Suspend\n");
1865867cd155SPankaj Dev 		action = USB_LPM;
1866867cd155SPankaj Dev 		break;
1867867cd155SPankaj Dev 
1868867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_ERRATIC_ERROR: /* Erratic Error */
1869867cd155SPankaj Dev 		INFO("Event: Erratic Error\n");
1870867cd155SPankaj Dev 		break;
1871867cd155SPankaj Dev 
1872867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_CMD_CMPL: /* Command Complete */
1873867cd155SPankaj Dev 		INFO("Event: Command Complete\n");
1874867cd155SPankaj Dev 		break;
1875867cd155SPankaj Dev 
1876867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_OVERFLOW: /* Overflow */
1877867cd155SPankaj Dev 		INFO("Event: Overflow\n");
1878867cd155SPankaj Dev 		break;
1879867cd155SPankaj Dev 
1880867cd155SPankaj Dev 	case USB_DWC3_DEVICE_EVENT_L1WAKEUP:
1881867cd155SPankaj Dev 		INFO("Event: L1 Wake-UP\n");
1882867cd155SPankaj Dev 		// resume function
1883867cd155SPankaj Dev 		action = USB_RESUME;
1884867cd155SPankaj Dev 		break;
1885867cd155SPankaj Dev 
1886867cd155SPankaj Dev 	default:  /* UNKNOWN IRQ type */
1887867cd155SPankaj Dev 		break;
1888867cd155SPankaj Dev 	}
1889867cd155SPankaj Dev 
1890867cd155SPankaj Dev 	return action;
1891867cd155SPankaj Dev }
1892867cd155SPankaj Dev 
dwc3_is_ep_event(uint32_t event)1893867cd155SPankaj Dev static inline bool dwc3_is_ep_event(uint32_t event)
1894867cd155SPankaj Dev {
1895867cd155SPankaj Dev 	return ((event & DWC3_EVT_TYPE_MASK) == (DWC3_EVT_TYPE_EP << DWC3_EVT_TYPE_BITPOS));
1896867cd155SPankaj Dev }
1897867cd155SPankaj Dev 
dwc3_is_dev_event(uint32_t event)1898867cd155SPankaj Dev static inline bool dwc3_is_dev_event(uint32_t event)
1899867cd155SPankaj Dev {
1900867cd155SPankaj Dev 	return ((event & DWC3_EVT_TYPE_MASK) == (DWC3_EVT_TYPE_DEVSPEC << DWC3_EVT_TYPE_BITPOS));
1901867cd155SPankaj Dev }
1902867cd155SPankaj Dev 
usb_dwc3_it_handler(void * handle,uint32_t * param)1903867cd155SPankaj Dev static enum usb_action usb_dwc3_it_handler(void *handle, uint32_t *param)
1904867cd155SPankaj Dev {
1905867cd155SPankaj Dev 	dwc3_handle_t *dwc3_handle = (dwc3_handle_t *)handle;
1906867cd155SPankaj Dev 	enum usb_action action = USB_NOTHING;
1907867cd155SPankaj Dev 	uint32_t evtcnt, evt;
1908867cd155SPankaj Dev 	uint8_t i;
1909867cd155SPankaj Dev 
1910867cd155SPankaj Dev 	/* Use same handler for all the Evt-Buf IRQs */
1911867cd155SPankaj Dev 
1912867cd155SPankaj Dev 	/* Check for all Event Buffer interrupt k = USB_DWC3_INT_INUSE */
1913867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
1914867cd155SPankaj Dev 		evtcnt = dwc3_read_intr_count(dwc3_handle, i);
1915867cd155SPankaj Dev 
1916867cd155SPankaj Dev 		if (!evtcnt) {
1917867cd155SPankaj Dev 			continue;
1918867cd155SPankaj Dev 		}
1919867cd155SPankaj Dev 
1920867cd155SPankaj Dev 		VERBOSE("Interrupt Count %u\n", evtcnt);
1921867cd155SPankaj Dev 
1922867cd155SPankaj Dev 		evt = __HAL_PCD_READ_EVENT(dwc3_handle, i);
1923867cd155SPankaj Dev 		VERBOSE("Event %08x\n", evt);
1924867cd155SPankaj Dev 
1925867cd155SPankaj Dev 		if (dwc3_is_ep_event(evt)) {   /* EP event */
1926867cd155SPankaj Dev 			action = dwc3_handle_ep_event(dwc3_handle, evt, param);
1927867cd155SPankaj Dev 		} else {     /* NON-EP event */
1928867cd155SPankaj Dev 			if (dwc3_is_dev_event(evt)) {  /* Device specific event */
1929867cd155SPankaj Dev 				action = dwc3_handle_dev_event(dwc3_handle, evt, param);
1930867cd155SPankaj Dev 			} else {
1931867cd155SPankaj Dev 			  /* Error, non supported events */
1932867cd155SPankaj Dev 			}
1933867cd155SPankaj Dev 		}
1934867cd155SPankaj Dev 
1935867cd155SPankaj Dev 		__HAL_PCD_INCR_EVENT_POS(dwc3_handle, i, USB_DWC3_EVENT_SIZE);
1936867cd155SPankaj Dev 
1937867cd155SPankaj Dev 		dwc3_ack_evt_count(dwc3_handle, i, USB_DWC3_EVENT_SIZE);
1938867cd155SPankaj Dev 	}
1939867cd155SPankaj Dev 
1940867cd155SPankaj Dev 	return action;
1941867cd155SPankaj Dev }
1942867cd155SPankaj Dev 
usb_dwc3_write_packet(void * handle __unused,uint8_t * src __unused,uint8_t ch_ep_num __unused,uint16_t len __unused)1943867cd155SPankaj Dev static enum usb_status usb_dwc3_write_packet(void *handle __unused, uint8_t *src __unused,
1944867cd155SPankaj Dev 					     uint8_t ch_ep_num __unused, uint16_t len __unused)
1945867cd155SPankaj Dev {
1946867cd155SPankaj Dev 	return USBD_OK;
1947867cd155SPankaj Dev }
1948867cd155SPankaj Dev 
usb_dwc3_read_packet(void * handle __unused,uint8_t * dest __unused,uint16_t len __unused)1949867cd155SPankaj Dev static void *usb_dwc3_read_packet(void *handle __unused, uint8_t *dest __unused,
1950867cd155SPankaj Dev 				  uint16_t len __unused)
1951867cd155SPankaj Dev {
1952867cd155SPankaj Dev 	return NULL;
1953867cd155SPankaj Dev }
1954867cd155SPankaj Dev 
usb_dwc3_write_empty_tx_fifo(void * handle __unused,uint32_t epnum,uint32_t xfer_len __unused,uint32_t * xfer_count __unused,uint32_t maxpacket __unused,uint8_t ** xfer_buff __unused)1955867cd155SPankaj Dev static enum usb_status usb_dwc3_write_empty_tx_fifo(void *handle __unused, uint32_t epnum,
1956867cd155SPankaj Dev 						    uint32_t xfer_len __unused,
1957867cd155SPankaj Dev 						    uint32_t *xfer_count __unused,
1958867cd155SPankaj Dev 						    uint32_t maxpacket __unused,
1959867cd155SPankaj Dev 						    uint8_t **xfer_buff __unused)
1960867cd155SPankaj Dev {
1961867cd155SPankaj Dev 	return USBD_OK;
1962867cd155SPankaj Dev }
1963867cd155SPankaj Dev 
1964867cd155SPankaj Dev static const struct usb_driver usb_dwc3driver = {
1965867cd155SPankaj Dev 	.ep0_out_start = usb_dwc3_ep0_out_start,
1966867cd155SPankaj Dev 	.ep_start_xfer = usb_dwc3_ep_start_xfer,
1967867cd155SPankaj Dev 	.ep0_start_xfer = usb_dwc3_ep0_start_xfer,
1968867cd155SPankaj Dev 	.write_packet = usb_dwc3_write_packet,
1969867cd155SPankaj Dev 	.read_packet = usb_dwc3_read_packet,
1970867cd155SPankaj Dev 	.ep_set_stall = usb_dwc3_ep_set_stall,
1971867cd155SPankaj Dev 	.start_device = usb_dwc3_start_device,
1972867cd155SPankaj Dev 	.stop_device = usb_dwc3_stop_device,
1973867cd155SPankaj Dev 	.set_address = usb_dwc3_set_address,
1974867cd155SPankaj Dev 	.write_empty_tx_fifo = usb_dwc3_write_empty_tx_fifo,
1975867cd155SPankaj Dev 	.it_handler = usb_dwc3_it_handler
1976867cd155SPankaj Dev };
1977867cd155SPankaj Dev 
1978867cd155SPankaj Dev /* USB2 PHY Mask 0xf */
1979867cd155SPankaj Dev #define USBPHY_ULPI	1U
1980867cd155SPankaj Dev #define USBPHY_UTMI	2U
1981867cd155SPankaj Dev #define USBPHY_EMBEDDED_USB2	8U
1982867cd155SPankaj Dev #define USB2PHY_MASK	15U
1983867cd155SPankaj Dev /* USB3 PHY Mask (0xf << 4) */
1984867cd155SPankaj Dev #define USBPHY_PIPE3	16U
1985867cd155SPankaj Dev #define USBPHY_EMBEDDED_USB3	128U
1986867cd155SPankaj Dev #define USB3PHY_MASK	(15U << 4)
1987867cd155SPankaj Dev 
dwc3_soft_reset(dwc3_handle_t * dwc3_handle)1988867cd155SPankaj Dev static enum usb_status dwc3_soft_reset(dwc3_handle_t *dwc3_handle)
1989867cd155SPankaj Dev {
1990867cd155SPankaj Dev 	uint64_t timeout;
1991867cd155SPankaj Dev 
1992867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCTL, USB3_DCTL_CSFTRST);
1993867cd155SPankaj Dev 
1994867cd155SPankaj Dev 	timeout = timeout_init_us(500*1000); /* msec */
1995867cd155SPankaj Dev 
1996867cd155SPankaj Dev 	while (DWC3_regread(dwc3_handle->usb_device, DWC3_DCTL) & USB3_DCTL_CSFTRST) {
1997867cd155SPankaj Dev 
1998867cd155SPankaj Dev 		if (timeout_elapsed(timeout)) { /* "Reset Timed Out" */
1999867cd155SPankaj Dev 			return USBD_TIMEOUT;
2000867cd155SPankaj Dev 		}
2001867cd155SPankaj Dev 	}
2002867cd155SPankaj Dev 
2003867cd155SPankaj Dev 	return USBD_OK;
2004867cd155SPankaj Dev }
2005867cd155SPankaj Dev 
dwc3_core_init(dwc3_handle_t * dwc3_handle,uint32_t phy_itface)2006867cd155SPankaj Dev static enum usb_status dwc3_core_init(dwc3_handle_t *dwc3_handle, uint32_t phy_itface)
2007867cd155SPankaj Dev {
2008867cd155SPankaj Dev 	enum usb_status ret;
2009867cd155SPankaj Dev 
2010867cd155SPankaj Dev 	VERBOSE("Core ID %08x\n", (uint32_t)DWC3_regread(dwc3_handle->usb_global, DWC3_GSNPSID));
2011867cd155SPankaj Dev 
2012867cd155SPankaj Dev 	/* Set GUSB3PIPECTL for all USB3 ports (1-n), currently doing only for 0 */
2013867cd155SPankaj Dev 	if ((phy_itface & USB3PHY_MASK) != 0U) {
2014867cd155SPankaj Dev 		/* Relying on default value */
2015867cd155SPankaj Dev 	}
2016867cd155SPankaj Dev 
2017867cd155SPankaj Dev 	/* Set GUSB2PHYCFG for all USB2 ports (1-m), currently doing only for 0 */
2018867cd155SPankaj Dev 	if ((phy_itface & USB2PHY_MASK) != 0U) {
2019867cd155SPankaj Dev 		switch (phy_itface) {
2020867cd155SPankaj Dev 		case USBPHY_UTMI:
2021867cd155SPankaj Dev 			DWC3_regupdateclr(dwc3_handle->usb_global, DWC3_GUSB2PHYCFG(0UL),
2022867cd155SPankaj Dev 					  USB3_GUSB2PHYCFG_ULPI_UTMI_SEL);
2023867cd155SPankaj Dev 			break;
2024867cd155SPankaj Dev 		case USBPHY_ULPI:
2025867cd155SPankaj Dev 			DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GUSB2PHYCFG(0UL),
2026867cd155SPankaj Dev 					  USB3_GUSB2PHYCFG_ULPI_UTMI_SEL);
2027867cd155SPankaj Dev 			break;
2028867cd155SPankaj Dev 		default:
2029867cd155SPankaj Dev 			/* Relying on default value. */
2030867cd155SPankaj Dev 			break;
2031867cd155SPankaj Dev 		}
2032867cd155SPankaj Dev 	}
2033867cd155SPankaj Dev 
2034867cd155SPankaj Dev 	/* issue device SoftReset */
2035867cd155SPankaj Dev 	ret = dwc3_soft_reset(dwc3_handle);
2036867cd155SPankaj Dev 	if (ret != USBD_OK) {
2037867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2038867cd155SPankaj Dev 		return ret;
2039867cd155SPankaj Dev 	}
2040867cd155SPankaj Dev 
2041867cd155SPankaj Dev 	/* Put PHYs in reset */
2042867cd155SPankaj Dev 	/* Before Resetting PHY, put Core in Reset */
2043867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GCTL, USB3_GCTL_CORESOFTRESET);
2044867cd155SPankaj Dev 
2045867cd155SPankaj Dev 	/* Assert USB3 PHY reset for all USB3 ports (1-n), currently doing only for 0 */
2046867cd155SPankaj Dev 	if ((phy_itface & USB3PHY_MASK) != 0U) {
2047867cd155SPankaj Dev 		DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GUSB3PIPECTL(0UL),
2048867cd155SPankaj Dev 				  USB3_GUSB3PIPECTL_PHYSOFTRST);
2049867cd155SPankaj Dev 	}
2050867cd155SPankaj Dev 
2051867cd155SPankaj Dev 	/* Assert USB2 PHY reset for all USB2 ports (1-m), currently doing only for 0 */
2052867cd155SPankaj Dev 	if ((phy_itface & USB2PHY_MASK) != 0U) {
2053867cd155SPankaj Dev 		DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GUSB2PHYCFG(0UL),
2054867cd155SPankaj Dev 				  USB3_GUSB2PHYCFG_PHYSOFTRST);
2055867cd155SPankaj Dev 	}
2056867cd155SPankaj Dev 
2057867cd155SPankaj Dev 	// Program PHY signals - PHY specific
2058867cd155SPankaj Dev 
2059867cd155SPankaj Dev 
2060867cd155SPankaj Dev 	// Phy Init not needed since will be done by bootrom
2061867cd155SPankaj Dev 
2062867cd155SPankaj Dev 	/* Release PHY out of reset */
2063867cd155SPankaj Dev 
2064867cd155SPankaj Dev 	/* Clear USB3 PHY reset for all USB3 ports (1-n), currently doing only for 0 */
2065867cd155SPankaj Dev 	if ((phy_itface & USB3PHY_MASK) != 0U) {
2066867cd155SPankaj Dev 		DWC3_regupdateclr(dwc3_handle->usb_global, DWC3_GUSB3PIPECTL(0UL),
2067867cd155SPankaj Dev 				  USB3_GUSB3PIPECTL_PHYSOFTRST);
2068867cd155SPankaj Dev 	}
2069867cd155SPankaj Dev 
2070867cd155SPankaj Dev 	/* Clear USB2 PHY reset */
2071867cd155SPankaj Dev 	if ((phy_itface & USB2PHY_MASK) != 0U) {
2072867cd155SPankaj Dev 		DWC3_regupdateclr(dwc3_handle->usb_global, DWC3_GUSB2PHYCFG(0UL),
2073867cd155SPankaj Dev 				  USB3_GUSB2PHYCFG_PHYSOFTRST);
2074867cd155SPankaj Dev 	}
2075867cd155SPankaj Dev 
2076867cd155SPankaj Dev 	// delay needed for phy reset
2077867cd155SPankaj Dev 	mdelay(100); // 100ms
2078867cd155SPankaj Dev 
2079867cd155SPankaj Dev 	/* After PHYs are stable we can take Core out of reset state */
2080867cd155SPankaj Dev 	DWC3_regupdateclr(dwc3_handle->usb_global, DWC3_GCTL, USB3_GCTL_CORESOFTRESET);
2081867cd155SPankaj Dev 
2082867cd155SPankaj Dev 	/* Disable Scale down mode - check if disabled by default */
2083867cd155SPankaj Dev 	//DWC3_regupdateclr(USBx, DWC3_GCTL, DWC3_GCTL_SCALEDOWN_MASK); ***ToCheck
2084867cd155SPankaj Dev 
2085867cd155SPankaj Dev 	/* Alloc and Setup Scratch buffers for hibernation */
2086867cd155SPankaj Dev 	// ***ToCheck
2087867cd155SPankaj Dev 
2088867cd155SPankaj Dev 	// From Linux Driver
2089867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_global, DWC3_GSBUSCFG0, 0xe);
2090867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_global, DWC3_GSBUSCFG1, 0xf00);
2091867cd155SPankaj Dev 
2092867cd155SPankaj Dev 	/* Use default values for GTXFIFOSIZn and GRXFIFOSIZ0 */
2093867cd155SPankaj Dev 
2094867cd155SPankaj Dev 	return USBD_OK;
2095867cd155SPankaj Dev }
2096867cd155SPankaj Dev 
2097867cd155SPankaj Dev typedef enum {
2098867cd155SPankaj Dev 	USB_DWC3_DEVICE_MODE  = 0U,
2099867cd155SPankaj Dev 	USB_DWC3_HOST_MODE    = 1U,
2100867cd155SPankaj Dev 	USB_DWC3_DRD_MODE     = 2U,
2101867cd155SPankaj Dev 	USB_DWC3_INVALID_MODE = 0xFU
2102867cd155SPankaj Dev } USB_DWC3_modetypedef;
2103867cd155SPankaj Dev 
dwc3_set_current_mode(dwc3_handle_t * dwc3_handle,USB_DWC3_modetypedef mode)2104867cd155SPankaj Dev static enum usb_status dwc3_set_current_mode(dwc3_handle_t *dwc3_handle, USB_DWC3_modetypedef mode)
2105867cd155SPankaj Dev {
2106867cd155SPankaj Dev 	uint32_t reg;
2107867cd155SPankaj Dev 	enum usb_status ret = USBD_OK;
2108867cd155SPankaj Dev 
2109867cd155SPankaj Dev 	reg = DWC3_regread(dwc3_handle->usb_global, DWC3_GCTL) & ~USB3_GCTL_PRTCAPDIR_MSK;
2110867cd155SPankaj Dev 
2111867cd155SPankaj Dev 	switch (mode) {
2112867cd155SPankaj Dev 	case USB_DWC3_DEVICE_MODE:
2113867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GCTL, reg |
2114867cd155SPankaj Dev 			      DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE));
2115867cd155SPankaj Dev 		break;
2116867cd155SPankaj Dev 	case USB_DWC3_HOST_MODE:
2117867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GCTL, reg |
2118867cd155SPankaj Dev 			      DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST));
2119867cd155SPankaj Dev 		break;
2120867cd155SPankaj Dev 	case USB_DWC3_DRD_MODE:
2121867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GCTL, reg |
2122867cd155SPankaj Dev 			      DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
2123867cd155SPankaj Dev 		break;
2124867cd155SPankaj Dev 	default:
2125867cd155SPankaj Dev 		ret = USBD_FAIL;
2126867cd155SPankaj Dev 		break;
2127867cd155SPankaj Dev 	}
2128867cd155SPankaj Dev 
2129867cd155SPankaj Dev 	return ret;
2130867cd155SPankaj Dev }
2131867cd155SPankaj Dev 
dwc3_set_dev_speed(dwc3_handle_t * dwc3_handle,uint8_t speed)2132867cd155SPankaj Dev static enum usb_status dwc3_set_dev_speed(dwc3_handle_t *dwc3_handle, uint8_t speed)
2133867cd155SPankaj Dev {
2134867cd155SPankaj Dev 	uint32_t reg;
2135867cd155SPankaj Dev 	enum usb_status ret = USBD_OK;
2136867cd155SPankaj Dev 
2137867cd155SPankaj Dev 	reg = DWC3_regread(dwc3_handle->usb_device, DWC3_DCFG) & ~USB3_DCFG_DEVSPD_MSK;
2138867cd155SPankaj Dev 
2139867cd155SPankaj Dev 	switch (speed) {
2140867cd155SPankaj Dev 	case USB_DWC3_SPEED_SUPER:
2141867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg | DWC3_DSTS_SUPERSPEED);
2142867cd155SPankaj Dev 		INFO("%s = SuperSpeed\n", __func__);
2143867cd155SPankaj Dev 		break;
2144867cd155SPankaj Dev 	case USB_DWC3_SPEED_HIGH:
2145867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |  DWC3_DSTS_HIGHSPEED);
2146867cd155SPankaj Dev 		INFO("%s = HighSpeed\n", __func__);
2147867cd155SPankaj Dev 		break;
2148867cd155SPankaj Dev 	case USB_DWC3_SPEED_FULL_48:
2149867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |  DWC3_DSTS_FULLSPEED1);
2150867cd155SPankaj Dev 		INFO("%s = FullSpeed_48M\n", __func__);
2151867cd155SPankaj Dev 		break;
2152867cd155SPankaj Dev 	case USB_DWC3_SPEED_FULL:
2153867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |  DWC3_DSTS_FULLSPEED2);
2154867cd155SPankaj Dev 		INFO("%s = FullSpeed\n", __func__);
2155867cd155SPankaj Dev 		break;
2156867cd155SPankaj Dev 	case USB_DWC3_SPEED_LOW:
2157867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |  DWC3_DSTS_LOWSPEED);
2158867cd155SPankaj Dev 		INFO("%s = LowSpeed\n", __func__);
2159867cd155SPankaj Dev 		break;
2160867cd155SPankaj Dev 	default:
2161867cd155SPankaj Dev 		ret = USBD_FAIL;
2162867cd155SPankaj Dev 		break;
2163867cd155SPankaj Dev 	}
2164867cd155SPankaj Dev 
2165867cd155SPankaj Dev 	return ret;
2166867cd155SPankaj Dev }
2167867cd155SPankaj Dev 
2168867cd155SPankaj Dev /*
2169867cd155SPankaj Dev  * @brief  USB_DevInit : Initializes the USB3 controller registers
2170867cd155SPankaj Dev  *         for device mode
2171867cd155SPankaj Dev  * @param  USBx  Selected device
2172867cd155SPankaj Dev  * @param  cfg   pointer to a USB_DWC3_CfgTypeDef structure that contains
2173867cd155SPankaj Dev  *         the configuration information for the specified USBx peripheral.
2174867cd155SPankaj Dev  * @retval HAL status
2175867cd155SPankaj Dev  */
dwc3_dev_init(dwc3_handle_t * dwc3_handle,uint8_t speed,uint8_t intr_dev)2176867cd155SPankaj Dev enum usb_status dwc3_dev_init(dwc3_handle_t *dwc3_handle, uint8_t speed, uint8_t intr_dev)
2177867cd155SPankaj Dev {
2178867cd155SPankaj Dev 	uint32_t reg;
2179867cd155SPankaj Dev 	uint8_t i;
2180867cd155SPankaj Dev 	dwc3_epcmd_params_t params;
2181867cd155SPankaj Dev 	enum usb_status ret;
2182867cd155SPankaj Dev 
2183867cd155SPankaj Dev 	/* Setup event buffers k = USB_DWC3_INT_INUSE */
2184867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
2185867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTADRLO(i),
2186867cd155SPankaj Dev 			      lower_32_bits(dwc3_handle->intbuffers.evtbuffer_dma_addr[i]));
2187867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTADRHI(i),
2188867cd155SPankaj Dev 			      upper_32_bits(dwc3_handle->intbuffers.evtbuffer_dma_addr[i]));
2189867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTSIZ(i),
2190867cd155SPankaj Dev 			      USB_DWC3_EVENT_BUFFER_SIZE);
2191867cd155SPankaj Dev 		DWC3_regwrite(dwc3_handle->usb_global, DWC3_GEVNTCOUNT(i), 0);
2192867cd155SPankaj Dev 
2193867cd155SPankaj Dev 		/* EvtBufferPos[i] = 0;  Implicit since static done in HAL */
2194867cd155SPankaj Dev 	}
2195867cd155SPankaj Dev 
2196867cd155SPankaj Dev 	/*
2197867cd155SPankaj Dev 	 * Need to set GUCTL2 RST_ACTBITLATER, so the driver can poll for CMDACT bit
2198867cd155SPankaj Dev 	 * when issuing the ENDTRANSFER command.
2199867cd155SPankaj Dev 	 */
2200867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_global, DWC3_GUCTL2, DWC3_GUCTL2_RST_ACTBITLATER);
2201867cd155SPankaj Dev 
2202867cd155SPankaj Dev 	ret = dwc3_set_current_mode(dwc3_handle, USB_DWC3_DEVICE_MODE);
2203867cd155SPankaj Dev 	if (ret != USBD_OK) {
2204867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2205867cd155SPankaj Dev 		return ret;
2206867cd155SPankaj Dev 	}
2207867cd155SPankaj Dev 
2208867cd155SPankaj Dev 	ret = dwc3_set_dev_speed(dwc3_handle, speed);
2209867cd155SPankaj Dev 	if (ret != USBD_OK) {
2210867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2211867cd155SPankaj Dev 		return ret;
2212867cd155SPankaj Dev 	}
2213867cd155SPankaj Dev 
2214867cd155SPankaj Dev 	/* Issue a DEPSTARTCFG command with DEPCMD0.XferRscIdx set to 0,
2215867cd155SPankaj Dev 	 * to initialize the transfer resource allocation
2216867cd155SPankaj Dev 	 */
2217867cd155SPankaj Dev 	zeromem(&params, sizeof(params));
2218867cd155SPankaj Dev 	ret = dwc3_execute_dep_cmd(dwc3_handle, 0, DWC3_DEPCMD_PARAM(0) |
2219867cd155SPankaj Dev 				   USB_DWC3_DEPCMD_DEPSTARTCFG, &params);
2220867cd155SPankaj Dev 	if (ret != USBD_OK) {
2221867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2222867cd155SPankaj Dev 		return ret;
2223867cd155SPankaj Dev 	}
2224867cd155SPankaj Dev 
2225867cd155SPankaj Dev 	/* Configure Control EP 0 & 1 mapped to physical EP 0 & 1*/
2226867cd155SPankaj Dev 	ret = dwc3_ep_configure(dwc3_handle, 0, false, EP_TYPE_CTRL,
2227867cd155SPankaj Dev 				dwc3_handle->pcd_handle->out_ep[0].maxpacket, 0, 0, 0,
2228867cd155SPankaj Dev 				dwc3_handle->OUT_ep[0].intr_num, USB_DWC3_DEPCFG_ACTION_INIT);
2229867cd155SPankaj Dev 	if (ret != USBD_OK) {
2230867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2231867cd155SPankaj Dev 		return ret;
2232867cd155SPankaj Dev 	}
2233867cd155SPankaj Dev 	ret = dwc3_ep_configure(dwc3_handle, 0, true, EP_TYPE_CTRL,
2234867cd155SPankaj Dev 				dwc3_handle->pcd_handle->in_ep[0].maxpacket, 0, 0, 1,
2235867cd155SPankaj Dev 				dwc3_handle->IN_ep[0].intr_num, USB_DWC3_DEPCFG_ACTION_INIT);
2236867cd155SPankaj Dev 	if (ret != USBD_OK) {
2237867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2238867cd155SPankaj Dev 		return ret;
2239867cd155SPankaj Dev 	}
2240867cd155SPankaj Dev 
2241867cd155SPankaj Dev 	/* Transfer Resource for Control EP 0 & 1*/
2242867cd155SPankaj Dev 	(void)memset(&params, 0x00, sizeof(params));
2243867cd155SPankaj Dev 	params.param0 = DWC3_DEPXFERCFG_NUM_XFER_RES(1U);
2244867cd155SPankaj Dev 	/* As per databook, "Issue a DEPSTARTCFG command with DEPCMD0.XferRscIdx set to 2 to
2245867cd155SPankaj Dev 	 * re-initialize the transfer resource allocation on SetConfiguration or SetInterface
2246867cd155SPankaj Dev 	 * Request", value is 2 since the EP0 & EP1 take up the transfer resource 1 & 2, hence
2247867cd155SPankaj Dev 	 * further EPs will take resources 2,3,&up.. But in HAL we are not decoding the
2248867cd155SPankaj Dev 	 * Setup-packet requests, this should ideally come from USB-MW core.
2249867cd155SPankaj Dev 	 * Instead we follow the same method as Linux dwc3-gadget controller driver, All hardware
2250867cd155SPankaj Dev 	 * endpoints can be assigned a transfer resource and this setting will stay persistent
2251867cd155SPankaj Dev 	 * until either a core reset or hibernation. So whenever we do a DEPSTARTCFG(0) we can go
2252867cd155SPankaj Dev 	 * ahead and do DEPXFERCFG for every hardware endpoint as well.
2253867cd155SPankaj Dev 	 * For all k = DWC3_IP_NUM_EPS
2254867cd155SPankaj Dev 	 */
2255867cd155SPankaj Dev 	for (i = 0; i < DWC3_IP_NUM_EPS; i++) {
2256867cd155SPankaj Dev 		ret = dwc3_execute_dep_cmd(dwc3_handle, i, USB_DWC3_DEPCMD_SETTRANSFRESOURCE,
2257867cd155SPankaj Dev 					   &params);
2258867cd155SPankaj Dev 		if (ret != USBD_OK) {
2259867cd155SPankaj Dev 			ERROR("%s: %d\n", __func__, __LINE__);
2260867cd155SPankaj Dev 			return ret;
2261867cd155SPankaj Dev 		}
2262867cd155SPankaj Dev 	}
2263867cd155SPankaj Dev 
2264867cd155SPankaj Dev 	/* setup EP0 to receive SETUP packets */
2265867cd155SPankaj Dev 	ret = dwc3_ep0_out_start(dwc3_handle, dwc3_handle->setup_dma_addr);
2266867cd155SPankaj Dev 	if (ret != USBD_OK) {
2267867cd155SPankaj Dev 		ERROR("%s: %d\n", __func__, __LINE__);
2268867cd155SPankaj Dev 		return ret;
2269867cd155SPankaj Dev 	}
2270867cd155SPankaj Dev 
2271867cd155SPankaj Dev 	/* Enable EP 0 & 1 */
2272867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_device, DWC3_DALEPENA, DWC3_DALEPENA_EP(0) |
2273867cd155SPankaj Dev 			  DWC3_DALEPENA_EP(1));
2274867cd155SPankaj Dev 
2275867cd155SPankaj Dev 	/*
2276867cd155SPankaj Dev 	 * Set interrupt/EventQ number on which non-endpoint-specific device-related
2277867cd155SPankaj Dev 	 * interrupts are generated
2278867cd155SPankaj Dev 	 */
2279867cd155SPankaj Dev 	reg = DWC3_regread(dwc3_handle->usb_device, DWC3_DCFG) & ~USB3_DCFG_INTRNUM_MSK;
2280867cd155SPankaj Dev 	DWC3_regwrite(dwc3_handle->usb_device, DWC3_DCFG, reg |
2281867cd155SPankaj Dev 		      ((uint32_t)intr_dev << USB3_DCFG_INTRNUM_POS));
2282867cd155SPankaj Dev 
2283867cd155SPankaj Dev 	/* Enable all events but Start and End of Frame IRQs */
2284867cd155SPankaj Dev 	DWC3_regupdateset(dwc3_handle->usb_device, DWC3_DEVTEN, USB3_DEVTEN_VENDEVTSTRCVDEN |
2285867cd155SPankaj Dev 			  USB3_DEVTEN_EVNTOVERFLOWEN | USB3_DEVTEN_CMDCMPLTEN |
2286867cd155SPankaj Dev 			  USB3_DEVTEN_ERRTICERREVTEN | USB3_DEVTEN_U3L2L1SUSPEN |
2287867cd155SPankaj Dev 			  USB3_DEVTEN_HIBERNATIONREQEVTEN | USB3_DEVTEN_WKUPEVTEN |
2288867cd155SPankaj Dev 			  USB3_DEVTEN_ULSTCNGEN | USB3_DEVTEN_CONNECTDONEEVTEN |
2289867cd155SPankaj Dev 			  USB3_DEVTEN_USBRSTEVTEN | USB3_DEVTEN_DISSCONNEVTEN |
2290867cd155SPankaj Dev 			  USB3_DEVTEN_L1SUSPEN | USB3_DEVTEN_L1WKUPEVTEN
2291867cd155SPankaj Dev 			  /* | USB3_DEVTEN_SOFTEVTEN*/);
2292867cd155SPankaj Dev 
2293867cd155SPankaj Dev 	/* Enable Event Buffer interrupt k = USB_DWC3_INT_INUSE */
2294867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
2295867cd155SPankaj Dev 		__HAL_PCD_ENABLE_INTR(dwc3_handle, i);
2296867cd155SPankaj Dev 	}
2297867cd155SPankaj Dev 
2298867cd155SPankaj Dev 	return USBD_OK;
2299867cd155SPankaj Dev }
2300867cd155SPankaj Dev 
usb_dwc3_init_driver(struct usb_handle * usb_core_handle,struct pcd_handle * pcd_handle,dwc3_handle_t * dwc3_handle,void * base_addr)2301867cd155SPankaj Dev void usb_dwc3_init_driver(struct usb_handle *usb_core_handle, struct pcd_handle *pcd_handle,
2302867cd155SPankaj Dev 			  dwc3_handle_t *dwc3_handle, void *base_addr)
2303867cd155SPankaj Dev {
2304867cd155SPankaj Dev 	uint32_t i = 0;
2305867cd155SPankaj Dev 	enum usb_status ret;
2306867cd155SPankaj Dev 	uintptr_t base = (uintptr_t)base_addr;
2307867cd155SPankaj Dev 
2308867cd155SPankaj Dev 	dwc3_handle->usb_global = (usb_dwc3_global_t *)
2309867cd155SPankaj Dev 					(base + USB_DWC3_GLOBAL_BASE);
2310867cd155SPankaj Dev 
2311867cd155SPankaj Dev 	dwc3_handle->usb_device = (usb_dwc3_device_t *)
2312867cd155SPankaj Dev 					(base + USB_DWC3_DEVICE_BASE);
2313867cd155SPankaj Dev 
2314867cd155SPankaj Dev 	dwc3_handle->pcd_handle = pcd_handle;
2315867cd155SPankaj Dev 
2316867cd155SPankaj Dev 	/* Check hpcd->State is HAL_PCD_STATE_RESET, otherwise error */
2317867cd155SPankaj Dev 	assert(dwc3_handle->State == HAL_PCD_STATE_RESET);
2318867cd155SPankaj Dev 
2319867cd155SPankaj Dev 	dwc3_handle->State = HAL_PCD_STATE_BUSY;
2320867cd155SPankaj Dev 
2321867cd155SPankaj Dev 	/* Disable the Interrupts */
2322867cd155SPankaj Dev 	// Not required since USB device and EP interrupts are disabled at boot, ***ToCheck
2323867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
2324867cd155SPankaj Dev 		__HAL_PCD_DISABLE_INTR(dwc3_handle, i);
2325867cd155SPankaj Dev 	}
2326867cd155SPankaj Dev 
2327867cd155SPankaj Dev 	/* Init the Core (common init.) */
2328867cd155SPankaj Dev 	ret = dwc3_core_init(dwc3_handle, USBPHY_UTMI);
2329867cd155SPankaj Dev 	if (ret != USBD_OK) {
2330867cd155SPankaj Dev 		panic();
2331867cd155SPankaj Dev 	}
2332867cd155SPankaj Dev 
2333867cd155SPankaj Dev 	/* Init endpoints structures */
2334867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_NUM_IN_EP ; i++) {
2335867cd155SPankaj Dev 		/* Init ep structure */
2336867cd155SPankaj Dev 		pcd_handle->in_ep[i].is_in = true;
2337867cd155SPankaj Dev 		pcd_handle->in_ep[i].num = i;
2338867cd155SPankaj Dev 		dwc3_handle->IN_ep[i].tx_fifo_num = i;
2339867cd155SPankaj Dev 		/* Control until ep is activated */
2340867cd155SPankaj Dev 		pcd_handle->in_ep[i].type = EP_TYPE_CTRL;
2341867cd155SPankaj Dev 
2342867cd155SPankaj Dev 		/*
2343867cd155SPankaj Dev 		 * We are doing 1:1 alternate mapping for endpoints, meaning
2344867cd155SPankaj Dev 		 * IN Endpoint X maps to Physical Endpoint 2*X +1 and
2345867cd155SPankaj Dev 		 * OUT Endpoint X maps to Physical Endpoint 2*X.
2346867cd155SPankaj Dev 		 * So USB endpoint 0x81 is 0x03.
2347867cd155SPankaj Dev 		 */
2348*fce36755SYann Gautier #if USB_DWC3_NUM_IN_EP > 1
2349867cd155SPankaj Dev 		dwc3_handle->IN_ep[i].phy_epnum = __HAL_PCD_EPADDR_TO_PHYEPNUM(i | EP_DIR_IN);
2350*fce36755SYann Gautier #else
2351*fce36755SYann Gautier 		dwc3_handle->IN_ep[i].phy_epnum = 1U;
2352*fce36755SYann Gautier #endif
2353867cd155SPankaj Dev 
2354867cd155SPankaj Dev 		dwc3_handle->IN_ep[i].intr_num = PCD_DEV_EVENTS_INTR;
2355867cd155SPankaj Dev 	}
2356867cd155SPankaj Dev 
2357867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_NUM_OUT_EP ; i++) {
2358867cd155SPankaj Dev 		/* Init ep structure */
2359867cd155SPankaj Dev 		pcd_handle->out_ep[i].is_in = false;
2360867cd155SPankaj Dev 		pcd_handle->out_ep[i].num = i;
2361867cd155SPankaj Dev 		dwc3_handle->OUT_ep[i].tx_fifo_num = i;
2362867cd155SPankaj Dev 		/* Control until ep is activated */
2363867cd155SPankaj Dev 		pcd_handle->out_ep[i].type = EP_TYPE_CTRL;
2364867cd155SPankaj Dev 
2365867cd155SPankaj Dev 		/*
2366867cd155SPankaj Dev 		 * We are doing 1:1 alternate mapping for endpoints, meaning
2367867cd155SPankaj Dev 		 * IN Endpoint X maps to Physical Endpoint 2*X +1 and
2368867cd155SPankaj Dev 		 * OUT Endpoint X maps to Physical Endpoint 2*X.
2369867cd155SPankaj Dev 		 * So USB endpoint 0x81 is 0x03.
2370867cd155SPankaj Dev 		 */
2371867cd155SPankaj Dev 		dwc3_handle->OUT_ep[i].phy_epnum = __HAL_PCD_EPADDR_TO_PHYEPNUM(i);
2372867cd155SPankaj Dev 
2373867cd155SPankaj Dev 		dwc3_handle->OUT_ep[i].intr_num = PCD_DEV_EVENTS_INTR;
2374867cd155SPankaj Dev 
2375867cd155SPankaj Dev 		dwc3_handle->OUT_ep[i].bounce_buf = dwc3_handle->bounce_bufs[i].bounce_buf;
2376867cd155SPankaj Dev 	}
2377867cd155SPankaj Dev 
2378867cd155SPankaj Dev #define PHYS_AREA	STM32MP_USB_DWC3_BASE
2379867cd155SPankaj Dev 
2380867cd155SPankaj Dev #define EVTBUF_AREA_OFFSET	0U
2381867cd155SPankaj Dev #define TRB_OUT_AREA_OFFSET	(EVTBUF_AREA_OFFSET + USB_DWC3_EVENT_BUFFER_SIZE)
2382867cd155SPankaj Dev #define TRB_IN_AREA_OFFSET	(TRB_OUT_AREA_OFFSET + sizeof(usb_dwc3_trb_t))
2383867cd155SPankaj Dev #define SETUP_AREA_OFFSET	(TRB_IN_AREA_OFFSET + sizeof(usb_dwc3_trb_t))
2384867cd155SPankaj Dev 
2385867cd155SPankaj Dev 	void *coh_area = (void *)(uintptr_t)PHYS_AREA;
2386867cd155SPankaj Dev 
2387867cd155SPankaj Dev #define EVTBUF_AREA	(coh_area + EVTBUF_AREA_OFFSET)
2388867cd155SPankaj Dev #define TRB_OUT_AREA	(coh_area + TRB_OUT_AREA_OFFSET)
2389867cd155SPankaj Dev #define TRB_IN_AREA	(coh_area + TRB_IN_AREA_OFFSET)
2390867cd155SPankaj Dev #define SETUP_AREA	(coh_area + SETUP_AREA_OFFSET)
2391867cd155SPankaj Dev 
2392867cd155SPankaj Dev 	dwc3_handle->setup_dma_addr = (uintptr_t)api_getdmaaddr((void *)SETUP_AREA,
2393867cd155SPankaj Dev 								USB_SETUP_PACKET_SIZE, 1);
2394867cd155SPankaj Dev 	assert(dwc3_handle->setup_dma_addr != 0U);
2395867cd155SPankaj Dev 
2396867cd155SPankaj Dev 	dwc3_handle->setup_addr = SETUP_AREA;
2397867cd155SPankaj Dev 	assert(dwc3_handle->setup_addr != NULL);
2398867cd155SPankaj Dev 
2399867cd155SPankaj Dev 	/* Map DMA and Coherent address for event buffers k = USB_DWC3_INT_INUSE */
2400867cd155SPankaj Dev 	for (i = 0; i < USB_DWC3_INT_INUSE; i++) {
2401867cd155SPankaj Dev 		dwc3_handle->intbuffers.evtbuffer_dma_addr[i] =
2402867cd155SPankaj Dev 			api_getdmaaddr((void *)EVTBUF_AREA, USB_DWC3_EVENT_BUFFER_SIZE, 1);
2403867cd155SPankaj Dev 		assert(dwc3_handle->intbuffers.evtbuffer_dma_addr[i] != 0U);
2404867cd155SPankaj Dev 
2405867cd155SPankaj Dev 		dwc3_handle->intbuffers.evtbuffer_addr[i] = EVTBUF_AREA;
2406867cd155SPankaj Dev 		assert(dwc3_handle->intbuffers.evtbuffer_addr[i] != NULL);
2407867cd155SPankaj Dev 
2408867cd155SPankaj Dev 		dwc3_handle->intbuffers.evtbufferpos[i] = 0;
2409867cd155SPankaj Dev 
2410867cd155SPankaj Dev 		INFO("EventBuffer%u: BuffArea=%lx DmaAddr=%08x CoherentMapAddr=%p\n", i,
2411867cd155SPankaj Dev 			   (PHYS_AREA + EVTBUF_AREA_OFFSET),
2412867cd155SPankaj Dev 			   (uint32_t)dwc3_handle->intbuffers.evtbuffer_dma_addr[i],
2413867cd155SPankaj Dev 			   dwc3_handle->intbuffers.evtbuffer_addr[i]);
2414867cd155SPankaj Dev 	}
2415867cd155SPankaj Dev 
2416867cd155SPankaj Dev 	/* MAP TRB Coherent and DMA address for EP0IN and EP0OUT */
2417867cd155SPankaj Dev 	dwc3_handle->IN_ep[0].trb_dma_addr = (uint32_t)api_getdmaaddr((void *)TRB_IN_AREA,
2418867cd155SPankaj Dev 								      sizeof(usb_dwc3_trb_t), 1);
2419867cd155SPankaj Dev 	assert(dwc3_handle->IN_ep[0].trb_dma_addr != 0U);
2420867cd155SPankaj Dev 
2421867cd155SPankaj Dev 	dwc3_handle->IN_ep[0].trb_addr = (usb_dwc3_trb_t *)TRB_IN_AREA;
2422867cd155SPankaj Dev 	assert(dwc3_handle->IN_ep[0].trb_addr != NULL);
2423867cd155SPankaj Dev 
2424867cd155SPankaj Dev 	dwc3_handle->OUT_ep[0].trb_dma_addr = (uint32_t)api_getdmaaddr((void *)TRB_OUT_AREA,
2425867cd155SPankaj Dev 								       sizeof(usb_dwc3_trb_t),
2426867cd155SPankaj Dev 								       1);
2427867cd155SPankaj Dev 	assert(dwc3_handle->OUT_ep[0].trb_dma_addr != 0U);
2428867cd155SPankaj Dev 
2429867cd155SPankaj Dev 	dwc3_handle->OUT_ep[0].trb_addr = (usb_dwc3_trb_t *)TRB_OUT_AREA;
2430867cd155SPankaj Dev 	assert(dwc3_handle->OUT_ep[0].trb_addr != NULL);
2431867cd155SPankaj Dev 
2432867cd155SPankaj Dev 	/* Init Device */
2433867cd155SPankaj Dev 	dwc3_handle->EP0_State = HAL_PCD_EP0_SETUP_QUEUED;
2434867cd155SPankaj Dev 
2435867cd155SPankaj Dev 	ret = dwc3_dev_init(dwc3_handle, USB_DWC3_SPEED_HIGH, PCD_DEV_EVENTS_INTR);
2436867cd155SPankaj Dev 	assert(ret == USBD_OK);
2437867cd155SPankaj Dev 
2438867cd155SPankaj Dev 	dwc3_handle->State = HAL_PCD_STATE_READY;
2439867cd155SPankaj Dev 
2440867cd155SPankaj Dev 	register_usb_driver(usb_core_handle, pcd_handle, &usb_dwc3driver,
2441867cd155SPankaj Dev 			    dwc3_handle);
2442867cd155SPankaj Dev }
2443