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