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