1*49db4272SNagarjuna Kristam // SPDX-License-Identifier: GPL-2.0+ 2*49db4272SNagarjuna Kristam /* 3*49db4272SNagarjuna Kristam * NVIDIA Tegra XUSB device mode controller 4*49db4272SNagarjuna Kristam * 5*49db4272SNagarjuna Kristam * Copyright (c) 2013-2019, NVIDIA CORPORATION. All rights reserved. 6*49db4272SNagarjuna Kristam * Copyright (c) 2015, Google Inc. 7*49db4272SNagarjuna Kristam */ 8*49db4272SNagarjuna Kristam 9*49db4272SNagarjuna Kristam #include <linux/clk.h> 10*49db4272SNagarjuna Kristam #include <linux/completion.h> 11*49db4272SNagarjuna Kristam #include <linux/delay.h> 12*49db4272SNagarjuna Kristam #include <linux/dma-mapping.h> 13*49db4272SNagarjuna Kristam #include <linux/dmapool.h> 14*49db4272SNagarjuna Kristam #include <linux/interrupt.h> 15*49db4272SNagarjuna Kristam #include <linux/iopoll.h> 16*49db4272SNagarjuna Kristam #include <linux/kernel.h> 17*49db4272SNagarjuna Kristam #include <linux/module.h> 18*49db4272SNagarjuna Kristam #include <linux/of.h> 19*49db4272SNagarjuna Kristam #include <linux/of_device.h> 20*49db4272SNagarjuna Kristam #include <linux/phy/phy.h> 21*49db4272SNagarjuna Kristam #include <linux/phy/tegra/xusb.h> 22*49db4272SNagarjuna Kristam #include <linux/pm_domain.h> 23*49db4272SNagarjuna Kristam #include <linux/platform_device.h> 24*49db4272SNagarjuna Kristam #include <linux/pm_runtime.h> 25*49db4272SNagarjuna Kristam #include <linux/regulator/consumer.h> 26*49db4272SNagarjuna Kristam #include <linux/reset.h> 27*49db4272SNagarjuna Kristam #include <linux/usb/ch9.h> 28*49db4272SNagarjuna Kristam #include <linux/usb/gadget.h> 29*49db4272SNagarjuna Kristam #include <linux/usb/role.h> 30*49db4272SNagarjuna Kristam #include <linux/workqueue.h> 31*49db4272SNagarjuna Kristam 32*49db4272SNagarjuna Kristam /* XUSB_DEV registers */ 33*49db4272SNagarjuna Kristam #define SPARAM 0x000 34*49db4272SNagarjuna Kristam #define SPARAM_ERSTMAX_MASK GENMASK(20, 16) 35*49db4272SNagarjuna Kristam #define SPARAM_ERSTMAX(x) (((x) << 16) & SPARAM_ERSTMAX_MASK) 36*49db4272SNagarjuna Kristam #define DB 0x004 37*49db4272SNagarjuna Kristam #define DB_TARGET_MASK GENMASK(15, 8) 38*49db4272SNagarjuna Kristam #define DB_TARGET(x) (((x) << 8) & DB_TARGET_MASK) 39*49db4272SNagarjuna Kristam #define DB_STREAMID_MASK GENMASK(31, 16) 40*49db4272SNagarjuna Kristam #define DB_STREAMID(x) (((x) << 16) & DB_STREAMID_MASK) 41*49db4272SNagarjuna Kristam #define ERSTSZ 0x008 42*49db4272SNagarjuna Kristam #define ERSTSZ_ERSTXSZ_SHIFT(x) ((x) * 16) 43*49db4272SNagarjuna Kristam #define ERSTSZ_ERSTXSZ_MASK GENMASK(15, 0) 44*49db4272SNagarjuna Kristam #define ERSTXBALO(x) (0x010 + 8 * (x)) 45*49db4272SNagarjuna Kristam #define ERSTXBAHI(x) (0x014 + 8 * (x)) 46*49db4272SNagarjuna Kristam #define ERDPLO 0x020 47*49db4272SNagarjuna Kristam #define ERDPLO_EHB BIT(3) 48*49db4272SNagarjuna Kristam #define ERDPHI 0x024 49*49db4272SNagarjuna Kristam #define EREPLO 0x028 50*49db4272SNagarjuna Kristam #define EREPLO_ECS BIT(0) 51*49db4272SNagarjuna Kristam #define EREPLO_SEGI BIT(1) 52*49db4272SNagarjuna Kristam #define EREPHI 0x02c 53*49db4272SNagarjuna Kristam #define CTRL 0x030 54*49db4272SNagarjuna Kristam #define CTRL_RUN BIT(0) 55*49db4272SNagarjuna Kristam #define CTRL_LSE BIT(1) 56*49db4272SNagarjuna Kristam #define CTRL_IE BIT(4) 57*49db4272SNagarjuna Kristam #define CTRL_SMI_EVT BIT(5) 58*49db4272SNagarjuna Kristam #define CTRL_SMI_DSE BIT(6) 59*49db4272SNagarjuna Kristam #define CTRL_EWE BIT(7) 60*49db4272SNagarjuna Kristam #define CTRL_DEVADDR_MASK GENMASK(30, 24) 61*49db4272SNagarjuna Kristam #define CTRL_DEVADDR(x) (((x) << 24) & CTRL_DEVADDR_MASK) 62*49db4272SNagarjuna Kristam #define CTRL_ENABLE BIT(31) 63*49db4272SNagarjuna Kristam #define ST 0x034 64*49db4272SNagarjuna Kristam #define ST_RC BIT(0) 65*49db4272SNagarjuna Kristam #define ST_IP BIT(4) 66*49db4272SNagarjuna Kristam #define RT_IMOD 0x038 67*49db4272SNagarjuna Kristam #define RT_IMOD_IMODI_MASK GENMASK(15, 0) 68*49db4272SNagarjuna Kristam #define RT_IMOD_IMODI(x) ((x) & RT_IMOD_IMODI_MASK) 69*49db4272SNagarjuna Kristam #define RT_IMOD_IMODC_MASK GENMASK(31, 16) 70*49db4272SNagarjuna Kristam #define RT_IMOD_IMODC(x) (((x) << 16) & RT_IMOD_IMODC_MASK) 71*49db4272SNagarjuna Kristam #define PORTSC 0x03c 72*49db4272SNagarjuna Kristam #define PORTSC_CCS BIT(0) 73*49db4272SNagarjuna Kristam #define PORTSC_PED BIT(1) 74*49db4272SNagarjuna Kristam #define PORTSC_PR BIT(4) 75*49db4272SNagarjuna Kristam #define PORTSC_PLS_SHIFT 5 76*49db4272SNagarjuna Kristam #define PORTSC_PLS_MASK GENMASK(8, 5) 77*49db4272SNagarjuna Kristam #define PORTSC_PLS_U0 0x0 78*49db4272SNagarjuna Kristam #define PORTSC_PLS_U2 0x2 79*49db4272SNagarjuna Kristam #define PORTSC_PLS_U3 0x3 80*49db4272SNagarjuna Kristam #define PORTSC_PLS_DISABLED 0x4 81*49db4272SNagarjuna Kristam #define PORTSC_PLS_RXDETECT 0x5 82*49db4272SNagarjuna Kristam #define PORTSC_PLS_INACTIVE 0x6 83*49db4272SNagarjuna Kristam #define PORTSC_PLS_RESUME 0xf 84*49db4272SNagarjuna Kristam #define PORTSC_PLS(x) (((x) << PORTSC_PLS_SHIFT) & PORTSC_PLS_MASK) 85*49db4272SNagarjuna Kristam #define PORTSC_PS_SHIFT 10 86*49db4272SNagarjuna Kristam #define PORTSC_PS_MASK GENMASK(13, 10) 87*49db4272SNagarjuna Kristam #define PORTSC_PS_UNDEFINED 0x0 88*49db4272SNagarjuna Kristam #define PORTSC_PS_FS 0x1 89*49db4272SNagarjuna Kristam #define PORTSC_PS_LS 0x2 90*49db4272SNagarjuna Kristam #define PORTSC_PS_HS 0x3 91*49db4272SNagarjuna Kristam #define PORTSC_PS_SS 0x4 92*49db4272SNagarjuna Kristam #define PORTSC_LWS BIT(16) 93*49db4272SNagarjuna Kristam #define PORTSC_CSC BIT(17) 94*49db4272SNagarjuna Kristam #define PORTSC_WRC BIT(19) 95*49db4272SNagarjuna Kristam #define PORTSC_PRC BIT(21) 96*49db4272SNagarjuna Kristam #define PORTSC_PLC BIT(22) 97*49db4272SNagarjuna Kristam #define PORTSC_CEC BIT(23) 98*49db4272SNagarjuna Kristam #define PORTSC_WPR BIT(30) 99*49db4272SNagarjuna Kristam #define PORTSC_CHANGE_MASK (PORTSC_CSC | PORTSC_WRC | PORTSC_PRC | \ 100*49db4272SNagarjuna Kristam PORTSC_PLC | PORTSC_CEC) 101*49db4272SNagarjuna Kristam #define ECPLO 0x040 102*49db4272SNagarjuna Kristam #define ECPHI 0x044 103*49db4272SNagarjuna Kristam #define MFINDEX 0x048 104*49db4272SNagarjuna Kristam #define MFINDEX_FRAME_SHIFT 3 105*49db4272SNagarjuna Kristam #define MFINDEX_FRAME_MASK GENMASK(13, 3) 106*49db4272SNagarjuna Kristam #define PORTPM 0x04c 107*49db4272SNagarjuna Kristam #define PORTPM_L1S_MASK GENMASK(1, 0) 108*49db4272SNagarjuna Kristam #define PORTPM_L1S_DROP 0x0 109*49db4272SNagarjuna Kristam #define PORTPM_L1S_ACCEPT 0x1 110*49db4272SNagarjuna Kristam #define PORTPM_L1S_NYET 0x2 111*49db4272SNagarjuna Kristam #define PORTPM_L1S_STALL 0x3 112*49db4272SNagarjuna Kristam #define PORTPM_L1S(x) ((x) & PORTPM_L1S_MASK) 113*49db4272SNagarjuna Kristam #define PORTPM_RWE BIT(3) 114*49db4272SNagarjuna Kristam #define PORTPM_U2TIMEOUT_MASK GENMASK(15, 8) 115*49db4272SNagarjuna Kristam #define PORTPM_U1TIMEOUT_MASK GENMASK(23, 16) 116*49db4272SNagarjuna Kristam #define PORTPM_FLA BIT(24) 117*49db4272SNagarjuna Kristam #define PORTPM_VBA BIT(25) 118*49db4272SNagarjuna Kristam #define PORTPM_WOC BIT(26) 119*49db4272SNagarjuna Kristam #define PORTPM_WOD BIT(27) 120*49db4272SNagarjuna Kristam #define PORTPM_U1E BIT(28) 121*49db4272SNagarjuna Kristam #define PORTPM_U2E BIT(29) 122*49db4272SNagarjuna Kristam #define PORTPM_FRWE BIT(30) 123*49db4272SNagarjuna Kristam #define PORTPM_PNG_CYA BIT(31) 124*49db4272SNagarjuna Kristam #define EP_HALT 0x050 125*49db4272SNagarjuna Kristam #define EP_PAUSE 0x054 126*49db4272SNagarjuna Kristam #define EP_RELOAD 0x058 127*49db4272SNagarjuna Kristam #define EP_STCHG 0x05c 128*49db4272SNagarjuna Kristam #define DEVNOTIF_LO 0x064 129*49db4272SNagarjuna Kristam #define DEVNOTIF_LO_TRIG BIT(0) 130*49db4272SNagarjuna Kristam #define DEVNOTIF_LO_TYPE_MASK GENMASK(7, 4) 131*49db4272SNagarjuna Kristam #define DEVNOTIF_LO_TYPE(x) (((x) << 4) & DEVNOTIF_LO_TYPE_MASK) 132*49db4272SNagarjuna Kristam #define DEVNOTIF_LO_TYPE_FUNCTION_WAKE 0x1 133*49db4272SNagarjuna Kristam #define DEVNOTIF_HI 0x068 134*49db4272SNagarjuna Kristam #define PORTHALT 0x06c 135*49db4272SNagarjuna Kristam #define PORTHALT_HALT_LTSSM BIT(0) 136*49db4272SNagarjuna Kristam #define PORTHALT_HALT_REJECT BIT(1) 137*49db4272SNagarjuna Kristam #define PORTHALT_STCHG_REQ BIT(20) 138*49db4272SNagarjuna Kristam #define PORTHALT_STCHG_INTR_EN BIT(24) 139*49db4272SNagarjuna Kristam #define PORT_TM 0x070 140*49db4272SNagarjuna Kristam #define EP_THREAD_ACTIVE 0x074 141*49db4272SNagarjuna Kristam #define EP_STOPPED 0x078 142*49db4272SNagarjuna Kristam #define HSFSPI_COUNT0 0x100 143*49db4272SNagarjuna Kristam #define HSFSPI_COUNT13 0x134 144*49db4272SNagarjuna Kristam #define HSFSPI_COUNT13_U2_RESUME_K_DURATION_MASK GENMASK(29, 0) 145*49db4272SNagarjuna Kristam #define HSFSPI_COUNT13_U2_RESUME_K_DURATION(x) ((x) & \ 146*49db4272SNagarjuna Kristam HSFSPI_COUNT13_U2_RESUME_K_DURATION_MASK) 147*49db4272SNagarjuna Kristam #define BLCG 0x840 148*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT0 0x610 149*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT0_PING_TBURST_MASK GENMASK(7, 0) 150*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT0_PING_TBURST(x) ((x) & SSPX_CORE_CNT0_PING_TBURST_MASK) 151*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT30 0x688 152*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT30_LMPITP_TIMER_MASK GENMASK(19, 0) 153*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT30_LMPITP_TIMER(x) ((x) & \ 154*49db4272SNagarjuna Kristam SSPX_CORE_CNT30_LMPITP_TIMER_MASK) 155*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT32 0x690 156*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT32_POLL_TBURST_MAX_MASK GENMASK(7, 0) 157*49db4272SNagarjuna Kristam #define SSPX_CORE_CNT32_POLL_TBURST_MAX(x) ((x) & \ 158*49db4272SNagarjuna Kristam SSPX_CORE_CNT32_POLL_TBURST_MAX_MASK) 159*49db4272SNagarjuna Kristam #define SSPX_CORE_PADCTL4 0x750 160*49db4272SNagarjuna Kristam #define SSPX_CORE_PADCTL4_RXDAT_VLD_TIMEOUT_U3_MASK GENMASK(19, 0) 161*49db4272SNagarjuna Kristam #define SSPX_CORE_PADCTL4_RXDAT_VLD_TIMEOUT_U3(x) ((x) & \ 162*49db4272SNagarjuna Kristam SSPX_CORE_PADCTL4_RXDAT_VLD_TIMEOUT_U3_MASK) 163*49db4272SNagarjuna Kristam #define BLCG_DFPCI BIT(0) 164*49db4272SNagarjuna Kristam #define BLCG_UFPCI BIT(1) 165*49db4272SNagarjuna Kristam #define BLCG_FE BIT(2) 166*49db4272SNagarjuna Kristam #define BLCG_COREPLL_PWRDN BIT(8) 167*49db4272SNagarjuna Kristam #define BLCG_IOPLL_0_PWRDN BIT(9) 168*49db4272SNagarjuna Kristam #define BLCG_IOPLL_1_PWRDN BIT(10) 169*49db4272SNagarjuna Kristam #define BLCG_IOPLL_2_PWRDN BIT(11) 170*49db4272SNagarjuna Kristam #define BLCG_ALL 0x1ff 171*49db4272SNagarjuna Kristam #define CFG_DEV_SSPI_XFER 0x858 172*49db4272SNagarjuna Kristam #define CFG_DEV_SSPI_XFER_ACKTIMEOUT_MASK GENMASK(31, 0) 173*49db4272SNagarjuna Kristam #define CFG_DEV_SSPI_XFER_ACKTIMEOUT(x) ((x) & \ 174*49db4272SNagarjuna Kristam CFG_DEV_SSPI_XFER_ACKTIMEOUT_MASK) 175*49db4272SNagarjuna Kristam #define CFG_DEV_FE 0x85c 176*49db4272SNagarjuna Kristam #define CFG_DEV_FE_PORTREGSEL_MASK GENMASK(1, 0) 177*49db4272SNagarjuna Kristam #define CFG_DEV_FE_PORTREGSEL_SS_PI 1 178*49db4272SNagarjuna Kristam #define CFG_DEV_FE_PORTREGSEL_HSFS_PI 2 179*49db4272SNagarjuna Kristam #define CFG_DEV_FE_PORTREGSEL(x) ((x) & CFG_DEV_FE_PORTREGSEL_MASK) 180*49db4272SNagarjuna Kristam #define CFG_DEV_FE_INFINITE_SS_RETRY BIT(29) 181*49db4272SNagarjuna Kristam 182*49db4272SNagarjuna Kristam /* FPCI registers */ 183*49db4272SNagarjuna Kristam #define XUSB_DEV_CFG_1 0x004 184*49db4272SNagarjuna Kristam #define XUSB_DEV_CFG_1_IO_SPACE_EN BIT(0) 185*49db4272SNagarjuna Kristam #define XUSB_DEV_CFG_1_MEMORY_SPACE_EN BIT(1) 186*49db4272SNagarjuna Kristam #define XUSB_DEV_CFG_1_BUS_MASTER_EN BIT(2) 187*49db4272SNagarjuna Kristam #define XUSB_DEV_CFG_4 0x010 188*49db4272SNagarjuna Kristam #define XUSB_DEV_CFG_4_BASE_ADDR_MASK GENMASK(31, 15) 189*49db4272SNagarjuna Kristam #define XUSB_DEV_CFG_5 0x014 190*49db4272SNagarjuna Kristam 191*49db4272SNagarjuna Kristam /* IPFS registers */ 192*49db4272SNagarjuna Kristam #define XUSB_DEV_CONFIGURATION_0 0x180 193*49db4272SNagarjuna Kristam #define XUSB_DEV_CONFIGURATION_0_EN_FPCI BIT(0) 194*49db4272SNagarjuna Kristam #define XUSB_DEV_INTR_MASK_0 0x188 195*49db4272SNagarjuna Kristam #define XUSB_DEV_INTR_MASK_0_IP_INT_MASK BIT(16) 196*49db4272SNagarjuna Kristam 197*49db4272SNagarjuna Kristam struct tegra_xudc_ep_context { 198*49db4272SNagarjuna Kristam __le32 info0; 199*49db4272SNagarjuna Kristam __le32 info1; 200*49db4272SNagarjuna Kristam __le32 deq_lo; 201*49db4272SNagarjuna Kristam __le32 deq_hi; 202*49db4272SNagarjuna Kristam __le32 tx_info; 203*49db4272SNagarjuna Kristam __le32 rsvd[11]; 204*49db4272SNagarjuna Kristam }; 205*49db4272SNagarjuna Kristam 206*49db4272SNagarjuna Kristam #define EP_STATE_DISABLED 0 207*49db4272SNagarjuna Kristam #define EP_STATE_RUNNING 1 208*49db4272SNagarjuna Kristam #define EP_STATE_HALTED 2 209*49db4272SNagarjuna Kristam #define EP_STATE_STOPPED 3 210*49db4272SNagarjuna Kristam #define EP_STATE_ERROR 4 211*49db4272SNagarjuna Kristam 212*49db4272SNagarjuna Kristam #define EP_TYPE_INVALID 0 213*49db4272SNagarjuna Kristam #define EP_TYPE_ISOCH_OUT 1 214*49db4272SNagarjuna Kristam #define EP_TYPE_BULK_OUT 2 215*49db4272SNagarjuna Kristam #define EP_TYPE_INTERRUPT_OUT 3 216*49db4272SNagarjuna Kristam #define EP_TYPE_CONTROL 4 217*49db4272SNagarjuna Kristam #define EP_TYPE_ISCOH_IN 5 218*49db4272SNagarjuna Kristam #define EP_TYPE_BULK_IN 6 219*49db4272SNagarjuna Kristam #define EP_TYPE_INTERRUPT_IN 7 220*49db4272SNagarjuna Kristam 221*49db4272SNagarjuna Kristam #define BUILD_EP_CONTEXT_RW(name, member, shift, mask) \ 222*49db4272SNagarjuna Kristam static inline u32 ep_ctx_read_##name(struct tegra_xudc_ep_context *ctx) \ 223*49db4272SNagarjuna Kristam { \ 224*49db4272SNagarjuna Kristam return (le32_to_cpu(ctx->member) >> (shift)) & (mask); \ 225*49db4272SNagarjuna Kristam } \ 226*49db4272SNagarjuna Kristam static inline void \ 227*49db4272SNagarjuna Kristam ep_ctx_write_##name(struct tegra_xudc_ep_context *ctx, u32 val) \ 228*49db4272SNagarjuna Kristam { \ 229*49db4272SNagarjuna Kristam u32 tmp; \ 230*49db4272SNagarjuna Kristam \ 231*49db4272SNagarjuna Kristam tmp = le32_to_cpu(ctx->member) & ~((mask) << (shift)); \ 232*49db4272SNagarjuna Kristam tmp |= (val & (mask)) << (shift); \ 233*49db4272SNagarjuna Kristam ctx->member = cpu_to_le32(tmp); \ 234*49db4272SNagarjuna Kristam } 235*49db4272SNagarjuna Kristam 236*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(state, info0, 0, 0x7) 237*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(mult, info0, 8, 0x3) 238*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(max_pstreams, info0, 10, 0x1f) 239*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(lsa, info0, 15, 0x1) 240*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(interval, info0, 16, 0xff) 241*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(cerr, info1, 1, 0x3) 242*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(type, info1, 3, 0x7) 243*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(hid, info1, 7, 0x1) 244*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(max_burst_size, info1, 8, 0xff) 245*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(max_packet_size, info1, 16, 0xffff) 246*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(dcs, deq_lo, 0, 0x1) 247*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(deq_lo, deq_lo, 4, 0xfffffff) 248*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(deq_hi, deq_hi, 0, 0xffffffff) 249*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(avg_trb_len, tx_info, 0, 0xffff) 250*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(max_esit_payload, tx_info, 16, 0xffff) 251*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(edtla, rsvd[0], 0, 0xffffff) 252*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(seq_num, rsvd[0], 24, 0xff) 253*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(partial_td, rsvd[0], 25, 0x1) 254*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(cerrcnt, rsvd[1], 18, 0x3) 255*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(data_offset, rsvd[2], 0, 0x1ffff) 256*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(numtrbs, rsvd[2], 22, 0x1f) 257*49db4272SNagarjuna Kristam BUILD_EP_CONTEXT_RW(devaddr, rsvd[6], 0, 0x7f) 258*49db4272SNagarjuna Kristam 259*49db4272SNagarjuna Kristam static inline u64 ep_ctx_read_deq_ptr(struct tegra_xudc_ep_context *ctx) 260*49db4272SNagarjuna Kristam { 261*49db4272SNagarjuna Kristam return ((u64)ep_ctx_read_deq_hi(ctx) << 32) | 262*49db4272SNagarjuna Kristam (ep_ctx_read_deq_lo(ctx) << 4); 263*49db4272SNagarjuna Kristam } 264*49db4272SNagarjuna Kristam 265*49db4272SNagarjuna Kristam static inline void 266*49db4272SNagarjuna Kristam ep_ctx_write_deq_ptr(struct tegra_xudc_ep_context *ctx, u64 addr) 267*49db4272SNagarjuna Kristam { 268*49db4272SNagarjuna Kristam ep_ctx_write_deq_lo(ctx, lower_32_bits(addr) >> 4); 269*49db4272SNagarjuna Kristam ep_ctx_write_deq_hi(ctx, upper_32_bits(addr)); 270*49db4272SNagarjuna Kristam } 271*49db4272SNagarjuna Kristam 272*49db4272SNagarjuna Kristam struct tegra_xudc_trb { 273*49db4272SNagarjuna Kristam __le32 data_lo; 274*49db4272SNagarjuna Kristam __le32 data_hi; 275*49db4272SNagarjuna Kristam __le32 status; 276*49db4272SNagarjuna Kristam __le32 control; 277*49db4272SNagarjuna Kristam }; 278*49db4272SNagarjuna Kristam 279*49db4272SNagarjuna Kristam #define TRB_TYPE_RSVD 0 280*49db4272SNagarjuna Kristam #define TRB_TYPE_NORMAL 1 281*49db4272SNagarjuna Kristam #define TRB_TYPE_SETUP_STAGE 2 282*49db4272SNagarjuna Kristam #define TRB_TYPE_DATA_STAGE 3 283*49db4272SNagarjuna Kristam #define TRB_TYPE_STATUS_STAGE 4 284*49db4272SNagarjuna Kristam #define TRB_TYPE_ISOCH 5 285*49db4272SNagarjuna Kristam #define TRB_TYPE_LINK 6 286*49db4272SNagarjuna Kristam #define TRB_TYPE_TRANSFER_EVENT 32 287*49db4272SNagarjuna Kristam #define TRB_TYPE_PORT_STATUS_CHANGE_EVENT 34 288*49db4272SNagarjuna Kristam #define TRB_TYPE_STREAM 48 289*49db4272SNagarjuna Kristam #define TRB_TYPE_SETUP_PACKET_EVENT 63 290*49db4272SNagarjuna Kristam 291*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_INVALID 0 292*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_SUCCESS 1 293*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_DATA_BUFFER_ERR 2 294*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_BABBLE_DETECTED_ERR 3 295*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_USB_TRANS_ERR 4 296*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_TRB_ERR 5 297*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_STALL 6 298*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_INVALID_STREAM_TYPE_ERR 10 299*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_SHORT_PACKET 13 300*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_RING_UNDERRUN 14 301*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_RING_OVERRUN 15 302*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_EVENT_RING_FULL_ERR 21 303*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_STOPPED 26 304*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_ISOCH_BUFFER_OVERRUN 31 305*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_STREAM_NUMP_ERROR 219 306*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_PRIME_PIPE_RECEIVED 220 307*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_HOST_REJECTED 221 308*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_CTRL_DIR_ERR 222 309*49db4272SNagarjuna Kristam #define TRB_CMPL_CODE_CTRL_SEQNUM_ERR 223 310*49db4272SNagarjuna Kristam 311*49db4272SNagarjuna Kristam #define BUILD_TRB_RW(name, member, shift, mask) \ 312*49db4272SNagarjuna Kristam static inline u32 trb_read_##name(struct tegra_xudc_trb *trb) \ 313*49db4272SNagarjuna Kristam { \ 314*49db4272SNagarjuna Kristam return (le32_to_cpu(trb->member) >> (shift)) & (mask); \ 315*49db4272SNagarjuna Kristam } \ 316*49db4272SNagarjuna Kristam static inline void \ 317*49db4272SNagarjuna Kristam trb_write_##name(struct tegra_xudc_trb *trb, u32 val) \ 318*49db4272SNagarjuna Kristam { \ 319*49db4272SNagarjuna Kristam u32 tmp; \ 320*49db4272SNagarjuna Kristam \ 321*49db4272SNagarjuna Kristam tmp = le32_to_cpu(trb->member) & ~((mask) << (shift)); \ 322*49db4272SNagarjuna Kristam tmp |= (val & (mask)) << (shift); \ 323*49db4272SNagarjuna Kristam trb->member = cpu_to_le32(tmp); \ 324*49db4272SNagarjuna Kristam } 325*49db4272SNagarjuna Kristam 326*49db4272SNagarjuna Kristam BUILD_TRB_RW(data_lo, data_lo, 0, 0xffffffff) 327*49db4272SNagarjuna Kristam BUILD_TRB_RW(data_hi, data_hi, 0, 0xffffffff) 328*49db4272SNagarjuna Kristam BUILD_TRB_RW(seq_num, status, 0, 0xffff) 329*49db4272SNagarjuna Kristam BUILD_TRB_RW(transfer_len, status, 0, 0xffffff) 330*49db4272SNagarjuna Kristam BUILD_TRB_RW(td_size, status, 17, 0x1f) 331*49db4272SNagarjuna Kristam BUILD_TRB_RW(cmpl_code, status, 24, 0xff) 332*49db4272SNagarjuna Kristam BUILD_TRB_RW(cycle, control, 0, 0x1) 333*49db4272SNagarjuna Kristam BUILD_TRB_RW(toggle_cycle, control, 1, 0x1) 334*49db4272SNagarjuna Kristam BUILD_TRB_RW(isp, control, 2, 0x1) 335*49db4272SNagarjuna Kristam BUILD_TRB_RW(chain, control, 4, 0x1) 336*49db4272SNagarjuna Kristam BUILD_TRB_RW(ioc, control, 5, 0x1) 337*49db4272SNagarjuna Kristam BUILD_TRB_RW(type, control, 10, 0x3f) 338*49db4272SNagarjuna Kristam BUILD_TRB_RW(stream_id, control, 16, 0xffff) 339*49db4272SNagarjuna Kristam BUILD_TRB_RW(endpoint_id, control, 16, 0x1f) 340*49db4272SNagarjuna Kristam BUILD_TRB_RW(tlbpc, control, 16, 0xf) 341*49db4272SNagarjuna Kristam BUILD_TRB_RW(data_stage_dir, control, 16, 0x1) 342*49db4272SNagarjuna Kristam BUILD_TRB_RW(frame_id, control, 20, 0x7ff) 343*49db4272SNagarjuna Kristam BUILD_TRB_RW(sia, control, 31, 0x1) 344*49db4272SNagarjuna Kristam 345*49db4272SNagarjuna Kristam static inline u64 trb_read_data_ptr(struct tegra_xudc_trb *trb) 346*49db4272SNagarjuna Kristam { 347*49db4272SNagarjuna Kristam return ((u64)trb_read_data_hi(trb) << 32) | 348*49db4272SNagarjuna Kristam trb_read_data_lo(trb); 349*49db4272SNagarjuna Kristam } 350*49db4272SNagarjuna Kristam 351*49db4272SNagarjuna Kristam static inline void trb_write_data_ptr(struct tegra_xudc_trb *trb, u64 addr) 352*49db4272SNagarjuna Kristam { 353*49db4272SNagarjuna Kristam trb_write_data_lo(trb, lower_32_bits(addr)); 354*49db4272SNagarjuna Kristam trb_write_data_hi(trb, upper_32_bits(addr)); 355*49db4272SNagarjuna Kristam } 356*49db4272SNagarjuna Kristam 357*49db4272SNagarjuna Kristam struct tegra_xudc_request { 358*49db4272SNagarjuna Kristam struct usb_request usb_req; 359*49db4272SNagarjuna Kristam 360*49db4272SNagarjuna Kristam size_t buf_queued; 361*49db4272SNagarjuna Kristam unsigned int trbs_queued; 362*49db4272SNagarjuna Kristam unsigned int trbs_needed; 363*49db4272SNagarjuna Kristam bool need_zlp; 364*49db4272SNagarjuna Kristam 365*49db4272SNagarjuna Kristam struct tegra_xudc_trb *first_trb; 366*49db4272SNagarjuna Kristam struct tegra_xudc_trb *last_trb; 367*49db4272SNagarjuna Kristam 368*49db4272SNagarjuna Kristam struct list_head list; 369*49db4272SNagarjuna Kristam }; 370*49db4272SNagarjuna Kristam 371*49db4272SNagarjuna Kristam struct tegra_xudc_ep { 372*49db4272SNagarjuna Kristam struct tegra_xudc *xudc; 373*49db4272SNagarjuna Kristam struct usb_ep usb_ep; 374*49db4272SNagarjuna Kristam unsigned int index; 375*49db4272SNagarjuna Kristam char name[8]; 376*49db4272SNagarjuna Kristam 377*49db4272SNagarjuna Kristam struct tegra_xudc_ep_context *context; 378*49db4272SNagarjuna Kristam 379*49db4272SNagarjuna Kristam #define XUDC_TRANSFER_RING_SIZE 64 380*49db4272SNagarjuna Kristam struct tegra_xudc_trb *transfer_ring; 381*49db4272SNagarjuna Kristam dma_addr_t transfer_ring_phys; 382*49db4272SNagarjuna Kristam 383*49db4272SNagarjuna Kristam unsigned int enq_ptr; 384*49db4272SNagarjuna Kristam unsigned int deq_ptr; 385*49db4272SNagarjuna Kristam bool pcs; 386*49db4272SNagarjuna Kristam bool ring_full; 387*49db4272SNagarjuna Kristam bool stream_rejected; 388*49db4272SNagarjuna Kristam 389*49db4272SNagarjuna Kristam struct list_head queue; 390*49db4272SNagarjuna Kristam const struct usb_endpoint_descriptor *desc; 391*49db4272SNagarjuna Kristam const struct usb_ss_ep_comp_descriptor *comp_desc; 392*49db4272SNagarjuna Kristam }; 393*49db4272SNagarjuna Kristam 394*49db4272SNagarjuna Kristam struct tegra_xudc_sel_timing { 395*49db4272SNagarjuna Kristam __u8 u1sel; 396*49db4272SNagarjuna Kristam __u8 u1pel; 397*49db4272SNagarjuna Kristam __le16 u2sel; 398*49db4272SNagarjuna Kristam __le16 u2pel; 399*49db4272SNagarjuna Kristam }; 400*49db4272SNagarjuna Kristam 401*49db4272SNagarjuna Kristam enum tegra_xudc_setup_state { 402*49db4272SNagarjuna Kristam WAIT_FOR_SETUP, 403*49db4272SNagarjuna Kristam DATA_STAGE_XFER, 404*49db4272SNagarjuna Kristam DATA_STAGE_RECV, 405*49db4272SNagarjuna Kristam STATUS_STAGE_XFER, 406*49db4272SNagarjuna Kristam STATUS_STAGE_RECV, 407*49db4272SNagarjuna Kristam }; 408*49db4272SNagarjuna Kristam 409*49db4272SNagarjuna Kristam struct tegra_xudc_setup_packet { 410*49db4272SNagarjuna Kristam struct usb_ctrlrequest ctrl_req; 411*49db4272SNagarjuna Kristam unsigned int seq_num; 412*49db4272SNagarjuna Kristam }; 413*49db4272SNagarjuna Kristam 414*49db4272SNagarjuna Kristam struct tegra_xudc_save_regs { 415*49db4272SNagarjuna Kristam u32 ctrl; 416*49db4272SNagarjuna Kristam u32 portpm; 417*49db4272SNagarjuna Kristam }; 418*49db4272SNagarjuna Kristam 419*49db4272SNagarjuna Kristam struct tegra_xudc { 420*49db4272SNagarjuna Kristam struct device *dev; 421*49db4272SNagarjuna Kristam const struct tegra_xudc_soc *soc; 422*49db4272SNagarjuna Kristam struct tegra_xusb_padctl *padctl; 423*49db4272SNagarjuna Kristam 424*49db4272SNagarjuna Kristam spinlock_t lock; 425*49db4272SNagarjuna Kristam 426*49db4272SNagarjuna Kristam struct usb_gadget gadget; 427*49db4272SNagarjuna Kristam struct usb_gadget_driver *driver; 428*49db4272SNagarjuna Kristam 429*49db4272SNagarjuna Kristam #define XUDC_NR_EVENT_RINGS 2 430*49db4272SNagarjuna Kristam #define XUDC_EVENT_RING_SIZE 4096 431*49db4272SNagarjuna Kristam struct tegra_xudc_trb *event_ring[XUDC_NR_EVENT_RINGS]; 432*49db4272SNagarjuna Kristam dma_addr_t event_ring_phys[XUDC_NR_EVENT_RINGS]; 433*49db4272SNagarjuna Kristam unsigned int event_ring_index; 434*49db4272SNagarjuna Kristam unsigned int event_ring_deq_ptr; 435*49db4272SNagarjuna Kristam bool ccs; 436*49db4272SNagarjuna Kristam 437*49db4272SNagarjuna Kristam #define XUDC_NR_EPS 32 438*49db4272SNagarjuna Kristam struct tegra_xudc_ep ep[XUDC_NR_EPS]; 439*49db4272SNagarjuna Kristam struct tegra_xudc_ep_context *ep_context; 440*49db4272SNagarjuna Kristam dma_addr_t ep_context_phys; 441*49db4272SNagarjuna Kristam 442*49db4272SNagarjuna Kristam struct device *genpd_dev_device; 443*49db4272SNagarjuna Kristam struct device *genpd_dev_ss; 444*49db4272SNagarjuna Kristam struct device_link *genpd_dl_device; 445*49db4272SNagarjuna Kristam struct device_link *genpd_dl_ss; 446*49db4272SNagarjuna Kristam 447*49db4272SNagarjuna Kristam struct dma_pool *transfer_ring_pool; 448*49db4272SNagarjuna Kristam 449*49db4272SNagarjuna Kristam bool queued_setup_packet; 450*49db4272SNagarjuna Kristam struct tegra_xudc_setup_packet setup_packet; 451*49db4272SNagarjuna Kristam enum tegra_xudc_setup_state setup_state; 452*49db4272SNagarjuna Kristam u16 setup_seq_num; 453*49db4272SNagarjuna Kristam 454*49db4272SNagarjuna Kristam u16 dev_addr; 455*49db4272SNagarjuna Kristam u16 isoch_delay; 456*49db4272SNagarjuna Kristam struct tegra_xudc_sel_timing sel_timing; 457*49db4272SNagarjuna Kristam u8 test_mode_pattern; 458*49db4272SNagarjuna Kristam u16 status_buf; 459*49db4272SNagarjuna Kristam struct tegra_xudc_request *ep0_req; 460*49db4272SNagarjuna Kristam 461*49db4272SNagarjuna Kristam bool pullup; 462*49db4272SNagarjuna Kristam 463*49db4272SNagarjuna Kristam unsigned int nr_enabled_eps; 464*49db4272SNagarjuna Kristam unsigned int nr_isoch_eps; 465*49db4272SNagarjuna Kristam 466*49db4272SNagarjuna Kristam unsigned int device_state; 467*49db4272SNagarjuna Kristam unsigned int resume_state; 468*49db4272SNagarjuna Kristam 469*49db4272SNagarjuna Kristam int irq; 470*49db4272SNagarjuna Kristam 471*49db4272SNagarjuna Kristam void __iomem *base; 472*49db4272SNagarjuna Kristam resource_size_t phys_base; 473*49db4272SNagarjuna Kristam void __iomem *ipfs; 474*49db4272SNagarjuna Kristam void __iomem *fpci; 475*49db4272SNagarjuna Kristam 476*49db4272SNagarjuna Kristam struct regulator_bulk_data *supplies; 477*49db4272SNagarjuna Kristam 478*49db4272SNagarjuna Kristam struct clk_bulk_data *clks; 479*49db4272SNagarjuna Kristam 480*49db4272SNagarjuna Kristam enum usb_role device_mode; 481*49db4272SNagarjuna Kristam struct usb_role_switch *usb_role_sw; 482*49db4272SNagarjuna Kristam struct work_struct usb_role_sw_work; 483*49db4272SNagarjuna Kristam 484*49db4272SNagarjuna Kristam struct phy *usb3_phy; 485*49db4272SNagarjuna Kristam struct phy *utmi_phy; 486*49db4272SNagarjuna Kristam 487*49db4272SNagarjuna Kristam struct tegra_xudc_save_regs saved_regs; 488*49db4272SNagarjuna Kristam bool suspended; 489*49db4272SNagarjuna Kristam bool powergated; 490*49db4272SNagarjuna Kristam 491*49db4272SNagarjuna Kristam struct completion disconnect_complete; 492*49db4272SNagarjuna Kristam 493*49db4272SNagarjuna Kristam bool selfpowered; 494*49db4272SNagarjuna Kristam 495*49db4272SNagarjuna Kristam #define TOGGLE_VBUS_WAIT_MS 100 496*49db4272SNagarjuna Kristam struct delayed_work plc_reset_work; 497*49db4272SNagarjuna Kristam bool wait_csc; 498*49db4272SNagarjuna Kristam 499*49db4272SNagarjuna Kristam struct delayed_work port_reset_war_work; 500*49db4272SNagarjuna Kristam bool wait_for_sec_prc; 501*49db4272SNagarjuna Kristam }; 502*49db4272SNagarjuna Kristam 503*49db4272SNagarjuna Kristam #define XUDC_TRB_MAX_BUFFER_SIZE 65536 504*49db4272SNagarjuna Kristam #define XUDC_MAX_ISOCH_EPS 4 505*49db4272SNagarjuna Kristam #define XUDC_INTERRUPT_MODERATION_US 0 506*49db4272SNagarjuna Kristam 507*49db4272SNagarjuna Kristam static struct usb_endpoint_descriptor tegra_xudc_ep0_desc = { 508*49db4272SNagarjuna Kristam .bLength = USB_DT_ENDPOINT_SIZE, 509*49db4272SNagarjuna Kristam .bDescriptorType = USB_DT_ENDPOINT, 510*49db4272SNagarjuna Kristam .bEndpointAddress = 0, 511*49db4272SNagarjuna Kristam .bmAttributes = USB_ENDPOINT_XFER_CONTROL, 512*49db4272SNagarjuna Kristam .wMaxPacketSize = cpu_to_le16(64), 513*49db4272SNagarjuna Kristam }; 514*49db4272SNagarjuna Kristam 515*49db4272SNagarjuna Kristam struct tegra_xudc_soc { 516*49db4272SNagarjuna Kristam const char * const *supply_names; 517*49db4272SNagarjuna Kristam unsigned int num_supplies; 518*49db4272SNagarjuna Kristam const char * const *clock_names; 519*49db4272SNagarjuna Kristam unsigned int num_clks; 520*49db4272SNagarjuna Kristam bool u1_enable; 521*49db4272SNagarjuna Kristam bool u2_enable; 522*49db4272SNagarjuna Kristam bool lpm_enable; 523*49db4272SNagarjuna Kristam bool invalid_seq_num; 524*49db4272SNagarjuna Kristam bool pls_quirk; 525*49db4272SNagarjuna Kristam bool port_reset_quirk; 526*49db4272SNagarjuna Kristam bool has_ipfs; 527*49db4272SNagarjuna Kristam }; 528*49db4272SNagarjuna Kristam 529*49db4272SNagarjuna Kristam static inline u32 fpci_readl(struct tegra_xudc *xudc, unsigned int offset) 530*49db4272SNagarjuna Kristam { 531*49db4272SNagarjuna Kristam return readl(xudc->fpci + offset); 532*49db4272SNagarjuna Kristam } 533*49db4272SNagarjuna Kristam 534*49db4272SNagarjuna Kristam static inline void fpci_writel(struct tegra_xudc *xudc, u32 val, 535*49db4272SNagarjuna Kristam unsigned int offset) 536*49db4272SNagarjuna Kristam { 537*49db4272SNagarjuna Kristam writel(val, xudc->fpci + offset); 538*49db4272SNagarjuna Kristam } 539*49db4272SNagarjuna Kristam 540*49db4272SNagarjuna Kristam static inline u32 ipfs_readl(struct tegra_xudc *xudc, unsigned int offset) 541*49db4272SNagarjuna Kristam { 542*49db4272SNagarjuna Kristam return readl(xudc->ipfs + offset); 543*49db4272SNagarjuna Kristam } 544*49db4272SNagarjuna Kristam 545*49db4272SNagarjuna Kristam static inline void ipfs_writel(struct tegra_xudc *xudc, u32 val, 546*49db4272SNagarjuna Kristam unsigned int offset) 547*49db4272SNagarjuna Kristam { 548*49db4272SNagarjuna Kristam writel(val, xudc->ipfs + offset); 549*49db4272SNagarjuna Kristam } 550*49db4272SNagarjuna Kristam 551*49db4272SNagarjuna Kristam static inline u32 xudc_readl(struct tegra_xudc *xudc, unsigned int offset) 552*49db4272SNagarjuna Kristam { 553*49db4272SNagarjuna Kristam return readl(xudc->base + offset); 554*49db4272SNagarjuna Kristam } 555*49db4272SNagarjuna Kristam 556*49db4272SNagarjuna Kristam static inline void xudc_writel(struct tegra_xudc *xudc, u32 val, 557*49db4272SNagarjuna Kristam unsigned int offset) 558*49db4272SNagarjuna Kristam { 559*49db4272SNagarjuna Kristam writel(val, xudc->base + offset); 560*49db4272SNagarjuna Kristam } 561*49db4272SNagarjuna Kristam 562*49db4272SNagarjuna Kristam static inline int xudc_readl_poll(struct tegra_xudc *xudc, 563*49db4272SNagarjuna Kristam unsigned int offset, u32 mask, u32 val) 564*49db4272SNagarjuna Kristam { 565*49db4272SNagarjuna Kristam u32 regval; 566*49db4272SNagarjuna Kristam 567*49db4272SNagarjuna Kristam return readl_poll_timeout_atomic(xudc->base + offset, regval, 568*49db4272SNagarjuna Kristam (regval & mask) == val, 1, 100); 569*49db4272SNagarjuna Kristam } 570*49db4272SNagarjuna Kristam 571*49db4272SNagarjuna Kristam static inline struct tegra_xudc *to_xudc(struct usb_gadget *gadget) 572*49db4272SNagarjuna Kristam { 573*49db4272SNagarjuna Kristam return container_of(gadget, struct tegra_xudc, gadget); 574*49db4272SNagarjuna Kristam } 575*49db4272SNagarjuna Kristam 576*49db4272SNagarjuna Kristam static inline struct tegra_xudc_ep *to_xudc_ep(struct usb_ep *ep) 577*49db4272SNagarjuna Kristam { 578*49db4272SNagarjuna Kristam return container_of(ep, struct tegra_xudc_ep, usb_ep); 579*49db4272SNagarjuna Kristam } 580*49db4272SNagarjuna Kristam 581*49db4272SNagarjuna Kristam static inline struct tegra_xudc_request *to_xudc_req(struct usb_request *req) 582*49db4272SNagarjuna Kristam { 583*49db4272SNagarjuna Kristam return container_of(req, struct tegra_xudc_request, usb_req); 584*49db4272SNagarjuna Kristam } 585*49db4272SNagarjuna Kristam 586*49db4272SNagarjuna Kristam static inline void dump_trb(struct tegra_xudc *xudc, const char *type, 587*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb) 588*49db4272SNagarjuna Kristam { 589*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, 590*49db4272SNagarjuna Kristam "%s: %p, lo = %#x, hi = %#x, status = %#x, control = %#x\n", 591*49db4272SNagarjuna Kristam type, trb, trb->data_lo, trb->data_hi, trb->status, 592*49db4272SNagarjuna Kristam trb->control); 593*49db4272SNagarjuna Kristam } 594*49db4272SNagarjuna Kristam 595*49db4272SNagarjuna Kristam static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc) 596*49db4272SNagarjuna Kristam { 597*49db4272SNagarjuna Kristam int err; 598*49db4272SNagarjuna Kristam 599*49db4272SNagarjuna Kristam pm_runtime_get_sync(xudc->dev); 600*49db4272SNagarjuna Kristam 601*49db4272SNagarjuna Kristam err = phy_power_on(xudc->utmi_phy); 602*49db4272SNagarjuna Kristam if (err < 0) 603*49db4272SNagarjuna Kristam dev_err(xudc->dev, "utmi power on failed %d\n", err); 604*49db4272SNagarjuna Kristam 605*49db4272SNagarjuna Kristam err = phy_power_on(xudc->usb3_phy); 606*49db4272SNagarjuna Kristam if (err < 0) 607*49db4272SNagarjuna Kristam dev_err(xudc->dev, "usb3 phy power on failed %d\n", err); 608*49db4272SNagarjuna Kristam 609*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "device mode on\n"); 610*49db4272SNagarjuna Kristam 611*49db4272SNagarjuna Kristam tegra_xusb_padctl_set_vbus_override(xudc->padctl, true); 612*49db4272SNagarjuna Kristam 613*49db4272SNagarjuna Kristam xudc->device_mode = USB_ROLE_DEVICE; 614*49db4272SNagarjuna Kristam } 615*49db4272SNagarjuna Kristam 616*49db4272SNagarjuna Kristam static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc) 617*49db4272SNagarjuna Kristam { 618*49db4272SNagarjuna Kristam bool connected = false; 619*49db4272SNagarjuna Kristam u32 pls, val; 620*49db4272SNagarjuna Kristam int err; 621*49db4272SNagarjuna Kristam 622*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "device mode off\n"); 623*49db4272SNagarjuna Kristam 624*49db4272SNagarjuna Kristam connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS); 625*49db4272SNagarjuna Kristam 626*49db4272SNagarjuna Kristam reinit_completion(&xudc->disconnect_complete); 627*49db4272SNagarjuna Kristam 628*49db4272SNagarjuna Kristam tegra_xusb_padctl_set_vbus_override(xudc->padctl, false); 629*49db4272SNagarjuna Kristam 630*49db4272SNagarjuna Kristam pls = (xudc_readl(xudc, PORTSC) & PORTSC_PLS_MASK) >> 631*49db4272SNagarjuna Kristam PORTSC_PLS_SHIFT; 632*49db4272SNagarjuna Kristam 633*49db4272SNagarjuna Kristam /* Direct link to U0 if disconnected in RESUME or U2. */ 634*49db4272SNagarjuna Kristam if (xudc->soc->pls_quirk && xudc->gadget.speed == USB_SPEED_SUPER && 635*49db4272SNagarjuna Kristam (pls == PORTSC_PLS_RESUME || pls == PORTSC_PLS_U2)) { 636*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 637*49db4272SNagarjuna Kristam val |= PORTPM_FRWE; 638*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTPM); 639*49db4272SNagarjuna Kristam 640*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTSC); 641*49db4272SNagarjuna Kristam val &= ~(PORTSC_CHANGE_MASK | PORTSC_PLS_MASK); 642*49db4272SNagarjuna Kristam val |= PORTSC_LWS | PORTSC_PLS(PORTSC_PLS_U0); 643*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTSC); 644*49db4272SNagarjuna Kristam } 645*49db4272SNagarjuna Kristam 646*49db4272SNagarjuna Kristam xudc->device_mode = USB_ROLE_NONE; 647*49db4272SNagarjuna Kristam 648*49db4272SNagarjuna Kristam /* Wait for disconnect event. */ 649*49db4272SNagarjuna Kristam if (connected) 650*49db4272SNagarjuna Kristam wait_for_completion(&xudc->disconnect_complete); 651*49db4272SNagarjuna Kristam 652*49db4272SNagarjuna Kristam /* Make sure interrupt handler has completed before powergating. */ 653*49db4272SNagarjuna Kristam synchronize_irq(xudc->irq); 654*49db4272SNagarjuna Kristam 655*49db4272SNagarjuna Kristam err = phy_power_off(xudc->utmi_phy); 656*49db4272SNagarjuna Kristam if (err < 0) 657*49db4272SNagarjuna Kristam dev_err(xudc->dev, "utmi_phy power off failed %d\n", err); 658*49db4272SNagarjuna Kristam 659*49db4272SNagarjuna Kristam err = phy_power_off(xudc->usb3_phy); 660*49db4272SNagarjuna Kristam if (err < 0) 661*49db4272SNagarjuna Kristam dev_err(xudc->dev, "usb3_phy power off failed %d\n", err); 662*49db4272SNagarjuna Kristam 663*49db4272SNagarjuna Kristam pm_runtime_put(xudc->dev); 664*49db4272SNagarjuna Kristam } 665*49db4272SNagarjuna Kristam 666*49db4272SNagarjuna Kristam static void tegra_xudc_usb_role_sw_work(struct work_struct *work) 667*49db4272SNagarjuna Kristam { 668*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = container_of(work, struct tegra_xudc, 669*49db4272SNagarjuna Kristam usb_role_sw_work); 670*49db4272SNagarjuna Kristam 671*49db4272SNagarjuna Kristam if (!xudc->usb_role_sw || 672*49db4272SNagarjuna Kristam usb_role_switch_get_role(xudc->usb_role_sw) == USB_ROLE_DEVICE) 673*49db4272SNagarjuna Kristam tegra_xudc_device_mode_on(xudc); 674*49db4272SNagarjuna Kristam else 675*49db4272SNagarjuna Kristam tegra_xudc_device_mode_off(xudc); 676*49db4272SNagarjuna Kristam 677*49db4272SNagarjuna Kristam } 678*49db4272SNagarjuna Kristam 679*49db4272SNagarjuna Kristam static int tegra_xudc_usb_role_sw_set(struct device *dev, enum usb_role role) 680*49db4272SNagarjuna Kristam { 681*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = dev_get_drvdata(dev); 682*49db4272SNagarjuna Kristam unsigned long flags; 683*49db4272SNagarjuna Kristam 684*49db4272SNagarjuna Kristam dev_dbg(dev, "%s role is %d\n", __func__, role); 685*49db4272SNagarjuna Kristam 686*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 687*49db4272SNagarjuna Kristam 688*49db4272SNagarjuna Kristam if (!xudc->suspended) 689*49db4272SNagarjuna Kristam schedule_work(&xudc->usb_role_sw_work); 690*49db4272SNagarjuna Kristam 691*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 692*49db4272SNagarjuna Kristam 693*49db4272SNagarjuna Kristam return 0; 694*49db4272SNagarjuna Kristam } 695*49db4272SNagarjuna Kristam 696*49db4272SNagarjuna Kristam static void tegra_xudc_plc_reset_work(struct work_struct *work) 697*49db4272SNagarjuna Kristam { 698*49db4272SNagarjuna Kristam struct delayed_work *dwork = to_delayed_work(work); 699*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = container_of(dwork, struct tegra_xudc, 700*49db4272SNagarjuna Kristam plc_reset_work); 701*49db4272SNagarjuna Kristam unsigned long flags; 702*49db4272SNagarjuna Kristam 703*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 704*49db4272SNagarjuna Kristam 705*49db4272SNagarjuna Kristam if (xudc->wait_csc) { 706*49db4272SNagarjuna Kristam u32 pls = (xudc_readl(xudc, PORTSC) & PORTSC_PLS_MASK) >> 707*49db4272SNagarjuna Kristam PORTSC_PLS_SHIFT; 708*49db4272SNagarjuna Kristam 709*49db4272SNagarjuna Kristam if (pls == PORTSC_PLS_INACTIVE) { 710*49db4272SNagarjuna Kristam dev_info(xudc->dev, "PLS = Inactive. Toggle VBUS\n"); 711*49db4272SNagarjuna Kristam tegra_xusb_padctl_set_vbus_override(xudc->padctl, 712*49db4272SNagarjuna Kristam false); 713*49db4272SNagarjuna Kristam tegra_xusb_padctl_set_vbus_override(xudc->padctl, true); 714*49db4272SNagarjuna Kristam xudc->wait_csc = false; 715*49db4272SNagarjuna Kristam } 716*49db4272SNagarjuna Kristam } 717*49db4272SNagarjuna Kristam 718*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 719*49db4272SNagarjuna Kristam } 720*49db4272SNagarjuna Kristam 721*49db4272SNagarjuna Kristam static void tegra_xudc_port_reset_war_work(struct work_struct *work) 722*49db4272SNagarjuna Kristam { 723*49db4272SNagarjuna Kristam struct delayed_work *dwork = to_delayed_work(work); 724*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = 725*49db4272SNagarjuna Kristam container_of(dwork, struct tegra_xudc, port_reset_war_work); 726*49db4272SNagarjuna Kristam unsigned long flags; 727*49db4272SNagarjuna Kristam u32 pls; 728*49db4272SNagarjuna Kristam int ret; 729*49db4272SNagarjuna Kristam 730*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 731*49db4272SNagarjuna Kristam 732*49db4272SNagarjuna Kristam if ((xudc->device_mode == USB_ROLE_DEVICE) 733*49db4272SNagarjuna Kristam && xudc->wait_for_sec_prc) { 734*49db4272SNagarjuna Kristam pls = (xudc_readl(xudc, PORTSC) & PORTSC_PLS_MASK) >> 735*49db4272SNagarjuna Kristam PORTSC_PLS_SHIFT; 736*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "pls = %x\n", pls); 737*49db4272SNagarjuna Kristam 738*49db4272SNagarjuna Kristam if (pls == PORTSC_PLS_DISABLED) { 739*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "toggle vbus\n"); 740*49db4272SNagarjuna Kristam /* PRC doesn't complete in 100ms, toggle the vbus */ 741*49db4272SNagarjuna Kristam ret = tegra_phy_xusb_utmi_port_reset(xudc->utmi_phy); 742*49db4272SNagarjuna Kristam if (ret == 1) 743*49db4272SNagarjuna Kristam xudc->wait_for_sec_prc = 0; 744*49db4272SNagarjuna Kristam } 745*49db4272SNagarjuna Kristam } 746*49db4272SNagarjuna Kristam 747*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 748*49db4272SNagarjuna Kristam } 749*49db4272SNagarjuna Kristam 750*49db4272SNagarjuna Kristam static dma_addr_t trb_virt_to_phys(struct tegra_xudc_ep *ep, 751*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb) 752*49db4272SNagarjuna Kristam { 753*49db4272SNagarjuna Kristam unsigned int index; 754*49db4272SNagarjuna Kristam 755*49db4272SNagarjuna Kristam index = trb - ep->transfer_ring; 756*49db4272SNagarjuna Kristam 757*49db4272SNagarjuna Kristam if (WARN_ON(index >= XUDC_TRANSFER_RING_SIZE)) 758*49db4272SNagarjuna Kristam return 0; 759*49db4272SNagarjuna Kristam 760*49db4272SNagarjuna Kristam return (ep->transfer_ring_phys + index * sizeof(*trb)); 761*49db4272SNagarjuna Kristam } 762*49db4272SNagarjuna Kristam 763*49db4272SNagarjuna Kristam static struct tegra_xudc_trb *trb_phys_to_virt(struct tegra_xudc_ep *ep, 764*49db4272SNagarjuna Kristam dma_addr_t addr) 765*49db4272SNagarjuna Kristam { 766*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb; 767*49db4272SNagarjuna Kristam unsigned int index; 768*49db4272SNagarjuna Kristam 769*49db4272SNagarjuna Kristam index = (addr - ep->transfer_ring_phys) / sizeof(*trb); 770*49db4272SNagarjuna Kristam 771*49db4272SNagarjuna Kristam if (WARN_ON(index >= XUDC_TRANSFER_RING_SIZE)) 772*49db4272SNagarjuna Kristam return NULL; 773*49db4272SNagarjuna Kristam 774*49db4272SNagarjuna Kristam trb = &ep->transfer_ring[index]; 775*49db4272SNagarjuna Kristam 776*49db4272SNagarjuna Kristam return trb; 777*49db4272SNagarjuna Kristam } 778*49db4272SNagarjuna Kristam 779*49db4272SNagarjuna Kristam static void ep_reload(struct tegra_xudc *xudc, unsigned int ep) 780*49db4272SNagarjuna Kristam { 781*49db4272SNagarjuna Kristam xudc_writel(xudc, BIT(ep), EP_RELOAD); 782*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_RELOAD, BIT(ep), 0); 783*49db4272SNagarjuna Kristam } 784*49db4272SNagarjuna Kristam 785*49db4272SNagarjuna Kristam static void ep_pause(struct tegra_xudc *xudc, unsigned int ep) 786*49db4272SNagarjuna Kristam { 787*49db4272SNagarjuna Kristam u32 val; 788*49db4272SNagarjuna Kristam 789*49db4272SNagarjuna Kristam val = xudc_readl(xudc, EP_PAUSE); 790*49db4272SNagarjuna Kristam if (val & BIT(ep)) 791*49db4272SNagarjuna Kristam return; 792*49db4272SNagarjuna Kristam val |= BIT(ep); 793*49db4272SNagarjuna Kristam 794*49db4272SNagarjuna Kristam xudc_writel(xudc, val, EP_PAUSE); 795*49db4272SNagarjuna Kristam 796*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_STCHG, BIT(ep), BIT(ep)); 797*49db4272SNagarjuna Kristam 798*49db4272SNagarjuna Kristam xudc_writel(xudc, BIT(ep), EP_STCHG); 799*49db4272SNagarjuna Kristam } 800*49db4272SNagarjuna Kristam 801*49db4272SNagarjuna Kristam static void ep_unpause(struct tegra_xudc *xudc, unsigned int ep) 802*49db4272SNagarjuna Kristam { 803*49db4272SNagarjuna Kristam u32 val; 804*49db4272SNagarjuna Kristam 805*49db4272SNagarjuna Kristam val = xudc_readl(xudc, EP_PAUSE); 806*49db4272SNagarjuna Kristam if (!(val & BIT(ep))) 807*49db4272SNagarjuna Kristam return; 808*49db4272SNagarjuna Kristam val &= ~BIT(ep); 809*49db4272SNagarjuna Kristam 810*49db4272SNagarjuna Kristam xudc_writel(xudc, val, EP_PAUSE); 811*49db4272SNagarjuna Kristam 812*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_STCHG, BIT(ep), BIT(ep)); 813*49db4272SNagarjuna Kristam 814*49db4272SNagarjuna Kristam xudc_writel(xudc, BIT(ep), EP_STCHG); 815*49db4272SNagarjuna Kristam } 816*49db4272SNagarjuna Kristam 817*49db4272SNagarjuna Kristam static void ep_unpause_all(struct tegra_xudc *xudc) 818*49db4272SNagarjuna Kristam { 819*49db4272SNagarjuna Kristam u32 val; 820*49db4272SNagarjuna Kristam 821*49db4272SNagarjuna Kristam val = xudc_readl(xudc, EP_PAUSE); 822*49db4272SNagarjuna Kristam 823*49db4272SNagarjuna Kristam xudc_writel(xudc, 0, EP_PAUSE); 824*49db4272SNagarjuna Kristam 825*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_STCHG, val, val); 826*49db4272SNagarjuna Kristam 827*49db4272SNagarjuna Kristam xudc_writel(xudc, val, EP_STCHG); 828*49db4272SNagarjuna Kristam } 829*49db4272SNagarjuna Kristam 830*49db4272SNagarjuna Kristam static void ep_halt(struct tegra_xudc *xudc, unsigned int ep) 831*49db4272SNagarjuna Kristam { 832*49db4272SNagarjuna Kristam u32 val; 833*49db4272SNagarjuna Kristam 834*49db4272SNagarjuna Kristam val = xudc_readl(xudc, EP_HALT); 835*49db4272SNagarjuna Kristam if (val & BIT(ep)) 836*49db4272SNagarjuna Kristam return; 837*49db4272SNagarjuna Kristam val |= BIT(ep); 838*49db4272SNagarjuna Kristam xudc_writel(xudc, val, EP_HALT); 839*49db4272SNagarjuna Kristam 840*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_STCHG, BIT(ep), BIT(ep)); 841*49db4272SNagarjuna Kristam 842*49db4272SNagarjuna Kristam xudc_writel(xudc, BIT(ep), EP_STCHG); 843*49db4272SNagarjuna Kristam } 844*49db4272SNagarjuna Kristam 845*49db4272SNagarjuna Kristam static void ep_unhalt(struct tegra_xudc *xudc, unsigned int ep) 846*49db4272SNagarjuna Kristam { 847*49db4272SNagarjuna Kristam u32 val; 848*49db4272SNagarjuna Kristam 849*49db4272SNagarjuna Kristam val = xudc_readl(xudc, EP_HALT); 850*49db4272SNagarjuna Kristam if (!(val & BIT(ep))) 851*49db4272SNagarjuna Kristam return; 852*49db4272SNagarjuna Kristam val &= ~BIT(ep); 853*49db4272SNagarjuna Kristam xudc_writel(xudc, val, EP_HALT); 854*49db4272SNagarjuna Kristam 855*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_STCHG, BIT(ep), BIT(ep)); 856*49db4272SNagarjuna Kristam 857*49db4272SNagarjuna Kristam xudc_writel(xudc, BIT(ep), EP_STCHG); 858*49db4272SNagarjuna Kristam } 859*49db4272SNagarjuna Kristam 860*49db4272SNagarjuna Kristam static void ep_unhalt_all(struct tegra_xudc *xudc) 861*49db4272SNagarjuna Kristam { 862*49db4272SNagarjuna Kristam u32 val; 863*49db4272SNagarjuna Kristam 864*49db4272SNagarjuna Kristam val = xudc_readl(xudc, EP_HALT); 865*49db4272SNagarjuna Kristam if (!val) 866*49db4272SNagarjuna Kristam return; 867*49db4272SNagarjuna Kristam xudc_writel(xudc, 0, EP_HALT); 868*49db4272SNagarjuna Kristam 869*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_STCHG, val, val); 870*49db4272SNagarjuna Kristam 871*49db4272SNagarjuna Kristam xudc_writel(xudc, val, EP_STCHG); 872*49db4272SNagarjuna Kristam } 873*49db4272SNagarjuna Kristam 874*49db4272SNagarjuna Kristam static void ep_wait_for_stopped(struct tegra_xudc *xudc, unsigned int ep) 875*49db4272SNagarjuna Kristam { 876*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_STOPPED, BIT(ep), BIT(ep)); 877*49db4272SNagarjuna Kristam xudc_writel(xudc, BIT(ep), EP_STOPPED); 878*49db4272SNagarjuna Kristam } 879*49db4272SNagarjuna Kristam 880*49db4272SNagarjuna Kristam static void ep_wait_for_inactive(struct tegra_xudc *xudc, unsigned int ep) 881*49db4272SNagarjuna Kristam { 882*49db4272SNagarjuna Kristam xudc_readl_poll(xudc, EP_THREAD_ACTIVE, BIT(ep), 0); 883*49db4272SNagarjuna Kristam } 884*49db4272SNagarjuna Kristam 885*49db4272SNagarjuna Kristam static void tegra_xudc_req_done(struct tegra_xudc_ep *ep, 886*49db4272SNagarjuna Kristam struct tegra_xudc_request *req, int status) 887*49db4272SNagarjuna Kristam { 888*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 889*49db4272SNagarjuna Kristam 890*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "completing request %p on EP %u with status %d\n", 891*49db4272SNagarjuna Kristam req, ep->index, status); 892*49db4272SNagarjuna Kristam 893*49db4272SNagarjuna Kristam if (likely(req->usb_req.status == -EINPROGRESS)) 894*49db4272SNagarjuna Kristam req->usb_req.status = status; 895*49db4272SNagarjuna Kristam 896*49db4272SNagarjuna Kristam list_del_init(&req->list); 897*49db4272SNagarjuna Kristam 898*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_control(ep->desc)) { 899*49db4272SNagarjuna Kristam usb_gadget_unmap_request(&xudc->gadget, &req->usb_req, 900*49db4272SNagarjuna Kristam (xudc->setup_state == 901*49db4272SNagarjuna Kristam DATA_STAGE_XFER)); 902*49db4272SNagarjuna Kristam } else { 903*49db4272SNagarjuna Kristam usb_gadget_unmap_request(&xudc->gadget, &req->usb_req, 904*49db4272SNagarjuna Kristam usb_endpoint_dir_in(ep->desc)); 905*49db4272SNagarjuna Kristam } 906*49db4272SNagarjuna Kristam 907*49db4272SNagarjuna Kristam spin_unlock(&xudc->lock); 908*49db4272SNagarjuna Kristam usb_gadget_giveback_request(&ep->usb_ep, &req->usb_req); 909*49db4272SNagarjuna Kristam spin_lock(&xudc->lock); 910*49db4272SNagarjuna Kristam } 911*49db4272SNagarjuna Kristam 912*49db4272SNagarjuna Kristam static void tegra_xudc_ep_nuke(struct tegra_xudc_ep *ep, int status) 913*49db4272SNagarjuna Kristam { 914*49db4272SNagarjuna Kristam struct tegra_xudc_request *req; 915*49db4272SNagarjuna Kristam 916*49db4272SNagarjuna Kristam while (!list_empty(&ep->queue)) { 917*49db4272SNagarjuna Kristam req = list_first_entry(&ep->queue, struct tegra_xudc_request, 918*49db4272SNagarjuna Kristam list); 919*49db4272SNagarjuna Kristam tegra_xudc_req_done(ep, req, status); 920*49db4272SNagarjuna Kristam } 921*49db4272SNagarjuna Kristam } 922*49db4272SNagarjuna Kristam 923*49db4272SNagarjuna Kristam static unsigned int ep_available_trbs(struct tegra_xudc_ep *ep) 924*49db4272SNagarjuna Kristam { 925*49db4272SNagarjuna Kristam if (ep->ring_full) 926*49db4272SNagarjuna Kristam return 0; 927*49db4272SNagarjuna Kristam 928*49db4272SNagarjuna Kristam if (ep->deq_ptr > ep->enq_ptr) 929*49db4272SNagarjuna Kristam return ep->deq_ptr - ep->enq_ptr - 1; 930*49db4272SNagarjuna Kristam 931*49db4272SNagarjuna Kristam return XUDC_TRANSFER_RING_SIZE - (ep->enq_ptr - ep->deq_ptr) - 2; 932*49db4272SNagarjuna Kristam } 933*49db4272SNagarjuna Kristam 934*49db4272SNagarjuna Kristam static void tegra_xudc_queue_one_trb(struct tegra_xudc_ep *ep, 935*49db4272SNagarjuna Kristam struct tegra_xudc_request *req, 936*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb, 937*49db4272SNagarjuna Kristam bool ioc) 938*49db4272SNagarjuna Kristam { 939*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 940*49db4272SNagarjuna Kristam dma_addr_t buf_addr; 941*49db4272SNagarjuna Kristam size_t len; 942*49db4272SNagarjuna Kristam 943*49db4272SNagarjuna Kristam len = min_t(size_t, XUDC_TRB_MAX_BUFFER_SIZE, req->usb_req.length - 944*49db4272SNagarjuna Kristam req->buf_queued); 945*49db4272SNagarjuna Kristam if (len > 0) 946*49db4272SNagarjuna Kristam buf_addr = req->usb_req.dma + req->buf_queued; 947*49db4272SNagarjuna Kristam else 948*49db4272SNagarjuna Kristam buf_addr = 0; 949*49db4272SNagarjuna Kristam 950*49db4272SNagarjuna Kristam trb_write_data_ptr(trb, buf_addr); 951*49db4272SNagarjuna Kristam 952*49db4272SNagarjuna Kristam trb_write_transfer_len(trb, len); 953*49db4272SNagarjuna Kristam trb_write_td_size(trb, req->trbs_needed - req->trbs_queued - 1); 954*49db4272SNagarjuna Kristam 955*49db4272SNagarjuna Kristam if (req->trbs_queued == req->trbs_needed - 1 || 956*49db4272SNagarjuna Kristam (req->need_zlp && req->trbs_queued == req->trbs_needed - 2)) 957*49db4272SNagarjuna Kristam trb_write_chain(trb, 0); 958*49db4272SNagarjuna Kristam else 959*49db4272SNagarjuna Kristam trb_write_chain(trb, 1); 960*49db4272SNagarjuna Kristam 961*49db4272SNagarjuna Kristam trb_write_ioc(trb, ioc); 962*49db4272SNagarjuna Kristam 963*49db4272SNagarjuna Kristam if (usb_endpoint_dir_out(ep->desc) || 964*49db4272SNagarjuna Kristam (usb_endpoint_xfer_control(ep->desc) && 965*49db4272SNagarjuna Kristam (xudc->setup_state == DATA_STAGE_RECV))) 966*49db4272SNagarjuna Kristam trb_write_isp(trb, 1); 967*49db4272SNagarjuna Kristam else 968*49db4272SNagarjuna Kristam trb_write_isp(trb, 0); 969*49db4272SNagarjuna Kristam 970*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_control(ep->desc)) { 971*49db4272SNagarjuna Kristam if (xudc->setup_state == DATA_STAGE_XFER || 972*49db4272SNagarjuna Kristam xudc->setup_state == DATA_STAGE_RECV) 973*49db4272SNagarjuna Kristam trb_write_type(trb, TRB_TYPE_DATA_STAGE); 974*49db4272SNagarjuna Kristam else 975*49db4272SNagarjuna Kristam trb_write_type(trb, TRB_TYPE_STATUS_STAGE); 976*49db4272SNagarjuna Kristam 977*49db4272SNagarjuna Kristam if (xudc->setup_state == DATA_STAGE_XFER || 978*49db4272SNagarjuna Kristam xudc->setup_state == STATUS_STAGE_XFER) 979*49db4272SNagarjuna Kristam trb_write_data_stage_dir(trb, 1); 980*49db4272SNagarjuna Kristam else 981*49db4272SNagarjuna Kristam trb_write_data_stage_dir(trb, 0); 982*49db4272SNagarjuna Kristam } else if (usb_endpoint_xfer_isoc(ep->desc)) { 983*49db4272SNagarjuna Kristam trb_write_type(trb, TRB_TYPE_ISOCH); 984*49db4272SNagarjuna Kristam trb_write_sia(trb, 1); 985*49db4272SNagarjuna Kristam trb_write_frame_id(trb, 0); 986*49db4272SNagarjuna Kristam trb_write_tlbpc(trb, 0); 987*49db4272SNagarjuna Kristam } else if (usb_ss_max_streams(ep->comp_desc)) { 988*49db4272SNagarjuna Kristam trb_write_type(trb, TRB_TYPE_STREAM); 989*49db4272SNagarjuna Kristam trb_write_stream_id(trb, req->usb_req.stream_id); 990*49db4272SNagarjuna Kristam } else { 991*49db4272SNagarjuna Kristam trb_write_type(trb, TRB_TYPE_NORMAL); 992*49db4272SNagarjuna Kristam trb_write_stream_id(trb, 0); 993*49db4272SNagarjuna Kristam } 994*49db4272SNagarjuna Kristam 995*49db4272SNagarjuna Kristam trb_write_cycle(trb, ep->pcs); 996*49db4272SNagarjuna Kristam 997*49db4272SNagarjuna Kristam req->trbs_queued++; 998*49db4272SNagarjuna Kristam req->buf_queued += len; 999*49db4272SNagarjuna Kristam 1000*49db4272SNagarjuna Kristam dump_trb(xudc, "TRANSFER", trb); 1001*49db4272SNagarjuna Kristam } 1002*49db4272SNagarjuna Kristam 1003*49db4272SNagarjuna Kristam static unsigned int tegra_xudc_queue_trbs(struct tegra_xudc_ep *ep, 1004*49db4272SNagarjuna Kristam struct tegra_xudc_request *req) 1005*49db4272SNagarjuna Kristam { 1006*49db4272SNagarjuna Kristam unsigned int i, count, available; 1007*49db4272SNagarjuna Kristam bool wait_td = false; 1008*49db4272SNagarjuna Kristam 1009*49db4272SNagarjuna Kristam available = ep_available_trbs(ep); 1010*49db4272SNagarjuna Kristam count = req->trbs_needed - req->trbs_queued; 1011*49db4272SNagarjuna Kristam if (available < count) { 1012*49db4272SNagarjuna Kristam count = available; 1013*49db4272SNagarjuna Kristam ep->ring_full = true; 1014*49db4272SNagarjuna Kristam } 1015*49db4272SNagarjuna Kristam 1016*49db4272SNagarjuna Kristam /* 1017*49db4272SNagarjuna Kristam * To generate zero-length packet on USB bus, SW needs schedule a 1018*49db4272SNagarjuna Kristam * standalone zero-length TD. According to HW's behavior, SW needs 1019*49db4272SNagarjuna Kristam * to schedule TDs in different ways for different endpoint types. 1020*49db4272SNagarjuna Kristam * 1021*49db4272SNagarjuna Kristam * For control endpoint: 1022*49db4272SNagarjuna Kristam * - Data stage TD (IOC = 1, CH = 0) 1023*49db4272SNagarjuna Kristam * - Ring doorbell and wait transfer event 1024*49db4272SNagarjuna Kristam * - Data stage TD for ZLP (IOC = 1, CH = 0) 1025*49db4272SNagarjuna Kristam * - Ring doorbell 1026*49db4272SNagarjuna Kristam * 1027*49db4272SNagarjuna Kristam * For bulk and interrupt endpoints: 1028*49db4272SNagarjuna Kristam * - Normal transfer TD (IOC = 0, CH = 0) 1029*49db4272SNagarjuna Kristam * - Normal transfer TD for ZLP (IOC = 1, CH = 0) 1030*49db4272SNagarjuna Kristam * - Ring doorbell 1031*49db4272SNagarjuna Kristam */ 1032*49db4272SNagarjuna Kristam 1033*49db4272SNagarjuna Kristam if (req->need_zlp && usb_endpoint_xfer_control(ep->desc) && count > 1) 1034*49db4272SNagarjuna Kristam wait_td = true; 1035*49db4272SNagarjuna Kristam 1036*49db4272SNagarjuna Kristam if (!req->first_trb) 1037*49db4272SNagarjuna Kristam req->first_trb = &ep->transfer_ring[ep->enq_ptr]; 1038*49db4272SNagarjuna Kristam 1039*49db4272SNagarjuna Kristam for (i = 0; i < count; i++) { 1040*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb = &ep->transfer_ring[ep->enq_ptr]; 1041*49db4272SNagarjuna Kristam bool ioc = false; 1042*49db4272SNagarjuna Kristam 1043*49db4272SNagarjuna Kristam if ((i == count - 1) || (wait_td && i == count - 2)) 1044*49db4272SNagarjuna Kristam ioc = true; 1045*49db4272SNagarjuna Kristam 1046*49db4272SNagarjuna Kristam tegra_xudc_queue_one_trb(ep, req, trb, ioc); 1047*49db4272SNagarjuna Kristam req->last_trb = trb; 1048*49db4272SNagarjuna Kristam 1049*49db4272SNagarjuna Kristam ep->enq_ptr++; 1050*49db4272SNagarjuna Kristam if (ep->enq_ptr == XUDC_TRANSFER_RING_SIZE - 1) { 1051*49db4272SNagarjuna Kristam trb = &ep->transfer_ring[ep->enq_ptr]; 1052*49db4272SNagarjuna Kristam trb_write_cycle(trb, ep->pcs); 1053*49db4272SNagarjuna Kristam ep->pcs = !ep->pcs; 1054*49db4272SNagarjuna Kristam ep->enq_ptr = 0; 1055*49db4272SNagarjuna Kristam } 1056*49db4272SNagarjuna Kristam 1057*49db4272SNagarjuna Kristam if (ioc) 1058*49db4272SNagarjuna Kristam break; 1059*49db4272SNagarjuna Kristam } 1060*49db4272SNagarjuna Kristam 1061*49db4272SNagarjuna Kristam return count; 1062*49db4272SNagarjuna Kristam } 1063*49db4272SNagarjuna Kristam 1064*49db4272SNagarjuna Kristam static void tegra_xudc_ep_ring_doorbell(struct tegra_xudc_ep *ep) 1065*49db4272SNagarjuna Kristam { 1066*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 1067*49db4272SNagarjuna Kristam u32 val; 1068*49db4272SNagarjuna Kristam 1069*49db4272SNagarjuna Kristam if (list_empty(&ep->queue)) 1070*49db4272SNagarjuna Kristam return; 1071*49db4272SNagarjuna Kristam 1072*49db4272SNagarjuna Kristam val = DB_TARGET(ep->index); 1073*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_control(ep->desc)) { 1074*49db4272SNagarjuna Kristam val |= DB_STREAMID(xudc->setup_seq_num); 1075*49db4272SNagarjuna Kristam } else if (usb_ss_max_streams(ep->comp_desc) > 0) { 1076*49db4272SNagarjuna Kristam struct tegra_xudc_request *req; 1077*49db4272SNagarjuna Kristam 1078*49db4272SNagarjuna Kristam /* Don't ring doorbell if the stream has been rejected. */ 1079*49db4272SNagarjuna Kristam if (ep->stream_rejected) 1080*49db4272SNagarjuna Kristam return; 1081*49db4272SNagarjuna Kristam 1082*49db4272SNagarjuna Kristam req = list_first_entry(&ep->queue, struct tegra_xudc_request, 1083*49db4272SNagarjuna Kristam list); 1084*49db4272SNagarjuna Kristam val |= DB_STREAMID(req->usb_req.stream_id); 1085*49db4272SNagarjuna Kristam } 1086*49db4272SNagarjuna Kristam 1087*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "ring doorbell: %#x\n", val); 1088*49db4272SNagarjuna Kristam xudc_writel(xudc, val, DB); 1089*49db4272SNagarjuna Kristam } 1090*49db4272SNagarjuna Kristam 1091*49db4272SNagarjuna Kristam static void tegra_xudc_ep_kick_queue(struct tegra_xudc_ep *ep) 1092*49db4272SNagarjuna Kristam { 1093*49db4272SNagarjuna Kristam struct tegra_xudc_request *req; 1094*49db4272SNagarjuna Kristam bool trbs_queued = false; 1095*49db4272SNagarjuna Kristam 1096*49db4272SNagarjuna Kristam list_for_each_entry(req, &ep->queue, list) { 1097*49db4272SNagarjuna Kristam if (ep->ring_full) 1098*49db4272SNagarjuna Kristam break; 1099*49db4272SNagarjuna Kristam 1100*49db4272SNagarjuna Kristam if (tegra_xudc_queue_trbs(ep, req) > 0) 1101*49db4272SNagarjuna Kristam trbs_queued = true; 1102*49db4272SNagarjuna Kristam } 1103*49db4272SNagarjuna Kristam 1104*49db4272SNagarjuna Kristam if (trbs_queued) 1105*49db4272SNagarjuna Kristam tegra_xudc_ep_ring_doorbell(ep); 1106*49db4272SNagarjuna Kristam } 1107*49db4272SNagarjuna Kristam 1108*49db4272SNagarjuna Kristam static int 1109*49db4272SNagarjuna Kristam __tegra_xudc_ep_queue(struct tegra_xudc_ep *ep, struct tegra_xudc_request *req) 1110*49db4272SNagarjuna Kristam { 1111*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 1112*49db4272SNagarjuna Kristam int err; 1113*49db4272SNagarjuna Kristam 1114*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_control(ep->desc) && !list_empty(&ep->queue)) { 1115*49db4272SNagarjuna Kristam dev_err(xudc->dev, "control EP has pending transfers\n"); 1116*49db4272SNagarjuna Kristam return -EINVAL; 1117*49db4272SNagarjuna Kristam } 1118*49db4272SNagarjuna Kristam 1119*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_control(ep->desc)) { 1120*49db4272SNagarjuna Kristam err = usb_gadget_map_request(&xudc->gadget, &req->usb_req, 1121*49db4272SNagarjuna Kristam (xudc->setup_state == 1122*49db4272SNagarjuna Kristam DATA_STAGE_XFER)); 1123*49db4272SNagarjuna Kristam } else { 1124*49db4272SNagarjuna Kristam err = usb_gadget_map_request(&xudc->gadget, &req->usb_req, 1125*49db4272SNagarjuna Kristam usb_endpoint_dir_in(ep->desc)); 1126*49db4272SNagarjuna Kristam } 1127*49db4272SNagarjuna Kristam 1128*49db4272SNagarjuna Kristam if (err < 0) { 1129*49db4272SNagarjuna Kristam dev_err(xudc->dev, "failed to map request: %d\n", err); 1130*49db4272SNagarjuna Kristam return err; 1131*49db4272SNagarjuna Kristam } 1132*49db4272SNagarjuna Kristam 1133*49db4272SNagarjuna Kristam req->first_trb = NULL; 1134*49db4272SNagarjuna Kristam req->last_trb = NULL; 1135*49db4272SNagarjuna Kristam req->buf_queued = 0; 1136*49db4272SNagarjuna Kristam req->trbs_queued = 0; 1137*49db4272SNagarjuna Kristam req->need_zlp = false; 1138*49db4272SNagarjuna Kristam req->trbs_needed = DIV_ROUND_UP(req->usb_req.length, 1139*49db4272SNagarjuna Kristam XUDC_TRB_MAX_BUFFER_SIZE); 1140*49db4272SNagarjuna Kristam if (req->usb_req.length == 0) 1141*49db4272SNagarjuna Kristam req->trbs_needed++; 1142*49db4272SNagarjuna Kristam 1143*49db4272SNagarjuna Kristam if (!usb_endpoint_xfer_isoc(ep->desc) && 1144*49db4272SNagarjuna Kristam req->usb_req.zero && req->usb_req.length && 1145*49db4272SNagarjuna Kristam ((req->usb_req.length % ep->usb_ep.maxpacket) == 0)) { 1146*49db4272SNagarjuna Kristam req->trbs_needed++; 1147*49db4272SNagarjuna Kristam req->need_zlp = true; 1148*49db4272SNagarjuna Kristam } 1149*49db4272SNagarjuna Kristam 1150*49db4272SNagarjuna Kristam req->usb_req.status = -EINPROGRESS; 1151*49db4272SNagarjuna Kristam req->usb_req.actual = 0; 1152*49db4272SNagarjuna Kristam 1153*49db4272SNagarjuna Kristam list_add_tail(&req->list, &ep->queue); 1154*49db4272SNagarjuna Kristam 1155*49db4272SNagarjuna Kristam tegra_xudc_ep_kick_queue(ep); 1156*49db4272SNagarjuna Kristam 1157*49db4272SNagarjuna Kristam return 0; 1158*49db4272SNagarjuna Kristam } 1159*49db4272SNagarjuna Kristam 1160*49db4272SNagarjuna Kristam static int 1161*49db4272SNagarjuna Kristam tegra_xudc_ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req, 1162*49db4272SNagarjuna Kristam gfp_t gfp) 1163*49db4272SNagarjuna Kristam { 1164*49db4272SNagarjuna Kristam struct tegra_xudc_request *req; 1165*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep; 1166*49db4272SNagarjuna Kristam struct tegra_xudc *xudc; 1167*49db4272SNagarjuna Kristam unsigned long flags; 1168*49db4272SNagarjuna Kristam int ret; 1169*49db4272SNagarjuna Kristam 1170*49db4272SNagarjuna Kristam if (!usb_ep || !usb_req) 1171*49db4272SNagarjuna Kristam return -EINVAL; 1172*49db4272SNagarjuna Kristam 1173*49db4272SNagarjuna Kristam ep = to_xudc_ep(usb_ep); 1174*49db4272SNagarjuna Kristam req = to_xudc_req(usb_req); 1175*49db4272SNagarjuna Kristam xudc = ep->xudc; 1176*49db4272SNagarjuna Kristam 1177*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1178*49db4272SNagarjuna Kristam if (xudc->powergated || !ep->desc) { 1179*49db4272SNagarjuna Kristam ret = -ESHUTDOWN; 1180*49db4272SNagarjuna Kristam goto unlock; 1181*49db4272SNagarjuna Kristam } 1182*49db4272SNagarjuna Kristam 1183*49db4272SNagarjuna Kristam ret = __tegra_xudc_ep_queue(ep, req); 1184*49db4272SNagarjuna Kristam unlock: 1185*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1186*49db4272SNagarjuna Kristam 1187*49db4272SNagarjuna Kristam return ret; 1188*49db4272SNagarjuna Kristam } 1189*49db4272SNagarjuna Kristam 1190*49db4272SNagarjuna Kristam static void squeeze_transfer_ring(struct tegra_xudc_ep *ep, 1191*49db4272SNagarjuna Kristam struct tegra_xudc_request *req) 1192*49db4272SNagarjuna Kristam { 1193*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb = req->first_trb; 1194*49db4272SNagarjuna Kristam bool pcs_enq = trb_read_cycle(trb); 1195*49db4272SNagarjuna Kristam bool pcs; 1196*49db4272SNagarjuna Kristam 1197*49db4272SNagarjuna Kristam /* 1198*49db4272SNagarjuna Kristam * Clear out all the TRBs part of or after the cancelled request, 1199*49db4272SNagarjuna Kristam * and must correct trb cycle bit to the last un-enqueued state. 1200*49db4272SNagarjuna Kristam */ 1201*49db4272SNagarjuna Kristam while (trb != &ep->transfer_ring[ep->enq_ptr]) { 1202*49db4272SNagarjuna Kristam pcs = trb_read_cycle(trb); 1203*49db4272SNagarjuna Kristam memset(trb, 0, sizeof(*trb)); 1204*49db4272SNagarjuna Kristam trb_write_cycle(trb, !pcs); 1205*49db4272SNagarjuna Kristam trb++; 1206*49db4272SNagarjuna Kristam 1207*49db4272SNagarjuna Kristam if (trb_read_type(trb) == TRB_TYPE_LINK) 1208*49db4272SNagarjuna Kristam trb = ep->transfer_ring; 1209*49db4272SNagarjuna Kristam } 1210*49db4272SNagarjuna Kristam 1211*49db4272SNagarjuna Kristam /* Requests will be re-queued at the start of the cancelled request. */ 1212*49db4272SNagarjuna Kristam ep->enq_ptr = req->first_trb - ep->transfer_ring; 1213*49db4272SNagarjuna Kristam /* 1214*49db4272SNagarjuna Kristam * Retrieve the correct cycle bit state from the first trb of 1215*49db4272SNagarjuna Kristam * the cancelled request. 1216*49db4272SNagarjuna Kristam */ 1217*49db4272SNagarjuna Kristam ep->pcs = pcs_enq; 1218*49db4272SNagarjuna Kristam ep->ring_full = false; 1219*49db4272SNagarjuna Kristam list_for_each_entry_continue(req, &ep->queue, list) { 1220*49db4272SNagarjuna Kristam req->usb_req.status = -EINPROGRESS; 1221*49db4272SNagarjuna Kristam req->usb_req.actual = 0; 1222*49db4272SNagarjuna Kristam 1223*49db4272SNagarjuna Kristam req->first_trb = NULL; 1224*49db4272SNagarjuna Kristam req->last_trb = NULL; 1225*49db4272SNagarjuna Kristam req->buf_queued = 0; 1226*49db4272SNagarjuna Kristam req->trbs_queued = 0; 1227*49db4272SNagarjuna Kristam } 1228*49db4272SNagarjuna Kristam } 1229*49db4272SNagarjuna Kristam 1230*49db4272SNagarjuna Kristam /* 1231*49db4272SNagarjuna Kristam * Determine if the given TRB is in the range [first trb, last trb] for the 1232*49db4272SNagarjuna Kristam * given request. 1233*49db4272SNagarjuna Kristam */ 1234*49db4272SNagarjuna Kristam static bool trb_in_request(struct tegra_xudc_ep *ep, 1235*49db4272SNagarjuna Kristam struct tegra_xudc_request *req, 1236*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb) 1237*49db4272SNagarjuna Kristam { 1238*49db4272SNagarjuna Kristam dev_dbg(ep->xudc->dev, "%s: request %p -> %p; trb %p\n", __func__, 1239*49db4272SNagarjuna Kristam req->first_trb, req->last_trb, trb); 1240*49db4272SNagarjuna Kristam 1241*49db4272SNagarjuna Kristam if (trb >= req->first_trb && (trb <= req->last_trb || 1242*49db4272SNagarjuna Kristam req->last_trb < req->first_trb)) 1243*49db4272SNagarjuna Kristam return true; 1244*49db4272SNagarjuna Kristam 1245*49db4272SNagarjuna Kristam if (trb < req->first_trb && trb <= req->last_trb && 1246*49db4272SNagarjuna Kristam req->last_trb < req->first_trb) 1247*49db4272SNagarjuna Kristam return true; 1248*49db4272SNagarjuna Kristam 1249*49db4272SNagarjuna Kristam return false; 1250*49db4272SNagarjuna Kristam } 1251*49db4272SNagarjuna Kristam 1252*49db4272SNagarjuna Kristam /* 1253*49db4272SNagarjuna Kristam * Determine if the given TRB is in the range [EP enqueue pointer, first TRB) 1254*49db4272SNagarjuna Kristam * for the given endpoint and request. 1255*49db4272SNagarjuna Kristam */ 1256*49db4272SNagarjuna Kristam static bool trb_before_request(struct tegra_xudc_ep *ep, 1257*49db4272SNagarjuna Kristam struct tegra_xudc_request *req, 1258*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb) 1259*49db4272SNagarjuna Kristam { 1260*49db4272SNagarjuna Kristam struct tegra_xudc_trb *enq_trb = &ep->transfer_ring[ep->enq_ptr]; 1261*49db4272SNagarjuna Kristam 1262*49db4272SNagarjuna Kristam dev_dbg(ep->xudc->dev, "%s: request %p -> %p; enq ptr: %p; trb %p\n", 1263*49db4272SNagarjuna Kristam __func__, req->first_trb, req->last_trb, enq_trb, trb); 1264*49db4272SNagarjuna Kristam 1265*49db4272SNagarjuna Kristam if (trb < req->first_trb && (enq_trb <= trb || 1266*49db4272SNagarjuna Kristam req->first_trb < enq_trb)) 1267*49db4272SNagarjuna Kristam return true; 1268*49db4272SNagarjuna Kristam 1269*49db4272SNagarjuna Kristam if (trb > req->first_trb && req->first_trb < enq_trb && enq_trb <= trb) 1270*49db4272SNagarjuna Kristam return true; 1271*49db4272SNagarjuna Kristam 1272*49db4272SNagarjuna Kristam return false; 1273*49db4272SNagarjuna Kristam } 1274*49db4272SNagarjuna Kristam 1275*49db4272SNagarjuna Kristam static int 1276*49db4272SNagarjuna Kristam __tegra_xudc_ep_dequeue(struct tegra_xudc_ep *ep, 1277*49db4272SNagarjuna Kristam struct tegra_xudc_request *req) 1278*49db4272SNagarjuna Kristam { 1279*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 1280*49db4272SNagarjuna Kristam struct tegra_xudc_request *r; 1281*49db4272SNagarjuna Kristam struct tegra_xudc_trb *deq_trb; 1282*49db4272SNagarjuna Kristam bool busy, kick_queue = false; 1283*49db4272SNagarjuna Kristam int ret = 0; 1284*49db4272SNagarjuna Kristam 1285*49db4272SNagarjuna Kristam /* Make sure the request is actually queued to this endpoint. */ 1286*49db4272SNagarjuna Kristam list_for_each_entry(r, &ep->queue, list) { 1287*49db4272SNagarjuna Kristam if (r == req) 1288*49db4272SNagarjuna Kristam break; 1289*49db4272SNagarjuna Kristam } 1290*49db4272SNagarjuna Kristam 1291*49db4272SNagarjuna Kristam if (r != req) 1292*49db4272SNagarjuna Kristam return -EINVAL; 1293*49db4272SNagarjuna Kristam 1294*49db4272SNagarjuna Kristam /* Request hasn't been queued in the transfer ring yet. */ 1295*49db4272SNagarjuna Kristam if (!req->trbs_queued) { 1296*49db4272SNagarjuna Kristam tegra_xudc_req_done(ep, req, -ECONNRESET); 1297*49db4272SNagarjuna Kristam return 0; 1298*49db4272SNagarjuna Kristam } 1299*49db4272SNagarjuna Kristam 1300*49db4272SNagarjuna Kristam /* Halt DMA for this endpiont. */ 1301*49db4272SNagarjuna Kristam if (ep_ctx_read_state(ep->context) == EP_STATE_RUNNING) { 1302*49db4272SNagarjuna Kristam ep_pause(xudc, ep->index); 1303*49db4272SNagarjuna Kristam ep_wait_for_inactive(xudc, ep->index); 1304*49db4272SNagarjuna Kristam } 1305*49db4272SNagarjuna Kristam 1306*49db4272SNagarjuna Kristam deq_trb = trb_phys_to_virt(ep, ep_ctx_read_deq_ptr(ep->context)); 1307*49db4272SNagarjuna Kristam /* Is the hardware processing the TRB at the dequeue pointer? */ 1308*49db4272SNagarjuna Kristam busy = (trb_read_cycle(deq_trb) == ep_ctx_read_dcs(ep->context)); 1309*49db4272SNagarjuna Kristam 1310*49db4272SNagarjuna Kristam if (trb_in_request(ep, req, deq_trb) && busy) { 1311*49db4272SNagarjuna Kristam /* 1312*49db4272SNagarjuna Kristam * Request has been partially completed or it hasn't 1313*49db4272SNagarjuna Kristam * started processing yet. 1314*49db4272SNagarjuna Kristam */ 1315*49db4272SNagarjuna Kristam dma_addr_t deq_ptr; 1316*49db4272SNagarjuna Kristam 1317*49db4272SNagarjuna Kristam squeeze_transfer_ring(ep, req); 1318*49db4272SNagarjuna Kristam 1319*49db4272SNagarjuna Kristam req->usb_req.actual = ep_ctx_read_edtla(ep->context); 1320*49db4272SNagarjuna Kristam tegra_xudc_req_done(ep, req, -ECONNRESET); 1321*49db4272SNagarjuna Kristam kick_queue = true; 1322*49db4272SNagarjuna Kristam 1323*49db4272SNagarjuna Kristam /* EDTLA is > 0: request has been partially completed */ 1324*49db4272SNagarjuna Kristam if (req->usb_req.actual > 0) { 1325*49db4272SNagarjuna Kristam /* 1326*49db4272SNagarjuna Kristam * Abort the pending transfer and update the dequeue 1327*49db4272SNagarjuna Kristam * pointer 1328*49db4272SNagarjuna Kristam */ 1329*49db4272SNagarjuna Kristam ep_ctx_write_edtla(ep->context, 0); 1330*49db4272SNagarjuna Kristam ep_ctx_write_partial_td(ep->context, 0); 1331*49db4272SNagarjuna Kristam ep_ctx_write_data_offset(ep->context, 0); 1332*49db4272SNagarjuna Kristam 1333*49db4272SNagarjuna Kristam deq_ptr = trb_virt_to_phys(ep, 1334*49db4272SNagarjuna Kristam &ep->transfer_ring[ep->enq_ptr]); 1335*49db4272SNagarjuna Kristam 1336*49db4272SNagarjuna Kristam if (dma_mapping_error(xudc->dev, deq_ptr)) { 1337*49db4272SNagarjuna Kristam ret = -EINVAL; 1338*49db4272SNagarjuna Kristam } else { 1339*49db4272SNagarjuna Kristam ep_ctx_write_deq_ptr(ep->context, deq_ptr); 1340*49db4272SNagarjuna Kristam ep_ctx_write_dcs(ep->context, ep->pcs); 1341*49db4272SNagarjuna Kristam ep_reload(xudc, ep->index); 1342*49db4272SNagarjuna Kristam } 1343*49db4272SNagarjuna Kristam } 1344*49db4272SNagarjuna Kristam } else if (trb_before_request(ep, req, deq_trb) && busy) { 1345*49db4272SNagarjuna Kristam /* Request hasn't started processing yet. */ 1346*49db4272SNagarjuna Kristam squeeze_transfer_ring(ep, req); 1347*49db4272SNagarjuna Kristam 1348*49db4272SNagarjuna Kristam tegra_xudc_req_done(ep, req, -ECONNRESET); 1349*49db4272SNagarjuna Kristam kick_queue = true; 1350*49db4272SNagarjuna Kristam } else { 1351*49db4272SNagarjuna Kristam /* 1352*49db4272SNagarjuna Kristam * Request has completed, but we haven't processed the 1353*49db4272SNagarjuna Kristam * completion event yet. 1354*49db4272SNagarjuna Kristam */ 1355*49db4272SNagarjuna Kristam tegra_xudc_req_done(ep, req, -ECONNRESET); 1356*49db4272SNagarjuna Kristam ret = -EINVAL; 1357*49db4272SNagarjuna Kristam } 1358*49db4272SNagarjuna Kristam 1359*49db4272SNagarjuna Kristam /* Resume the endpoint. */ 1360*49db4272SNagarjuna Kristam ep_unpause(xudc, ep->index); 1361*49db4272SNagarjuna Kristam 1362*49db4272SNagarjuna Kristam if (kick_queue) 1363*49db4272SNagarjuna Kristam tegra_xudc_ep_kick_queue(ep); 1364*49db4272SNagarjuna Kristam 1365*49db4272SNagarjuna Kristam return ret; 1366*49db4272SNagarjuna Kristam } 1367*49db4272SNagarjuna Kristam 1368*49db4272SNagarjuna Kristam static int 1369*49db4272SNagarjuna Kristam tegra_xudc_ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req) 1370*49db4272SNagarjuna Kristam { 1371*49db4272SNagarjuna Kristam struct tegra_xudc_request *req; 1372*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep; 1373*49db4272SNagarjuna Kristam struct tegra_xudc *xudc; 1374*49db4272SNagarjuna Kristam unsigned long flags; 1375*49db4272SNagarjuna Kristam int ret; 1376*49db4272SNagarjuna Kristam 1377*49db4272SNagarjuna Kristam if (!usb_ep || !usb_req) 1378*49db4272SNagarjuna Kristam return -EINVAL; 1379*49db4272SNagarjuna Kristam 1380*49db4272SNagarjuna Kristam ep = to_xudc_ep(usb_ep); 1381*49db4272SNagarjuna Kristam req = to_xudc_req(usb_req); 1382*49db4272SNagarjuna Kristam xudc = ep->xudc; 1383*49db4272SNagarjuna Kristam 1384*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1385*49db4272SNagarjuna Kristam 1386*49db4272SNagarjuna Kristam if (xudc->powergated || !ep->desc) { 1387*49db4272SNagarjuna Kristam ret = -ESHUTDOWN; 1388*49db4272SNagarjuna Kristam goto unlock; 1389*49db4272SNagarjuna Kristam } 1390*49db4272SNagarjuna Kristam 1391*49db4272SNagarjuna Kristam ret = __tegra_xudc_ep_dequeue(ep, req); 1392*49db4272SNagarjuna Kristam unlock: 1393*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1394*49db4272SNagarjuna Kristam 1395*49db4272SNagarjuna Kristam return ret; 1396*49db4272SNagarjuna Kristam } 1397*49db4272SNagarjuna Kristam 1398*49db4272SNagarjuna Kristam static int __tegra_xudc_ep_set_halt(struct tegra_xudc_ep *ep, bool halt) 1399*49db4272SNagarjuna Kristam { 1400*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 1401*49db4272SNagarjuna Kristam 1402*49db4272SNagarjuna Kristam if (!ep->desc) 1403*49db4272SNagarjuna Kristam return -EINVAL; 1404*49db4272SNagarjuna Kristam 1405*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_isoc(ep->desc)) { 1406*49db4272SNagarjuna Kristam dev_err(xudc->dev, "can't halt isoc EP\n"); 1407*49db4272SNagarjuna Kristam return -ENOTSUPP; 1408*49db4272SNagarjuna Kristam } 1409*49db4272SNagarjuna Kristam 1410*49db4272SNagarjuna Kristam if (!!(xudc_readl(xudc, EP_HALT) & BIT(ep->index)) == halt) { 1411*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "EP %u already %s\n", ep->index, 1412*49db4272SNagarjuna Kristam halt ? "halted" : "not halted"); 1413*49db4272SNagarjuna Kristam return 0; 1414*49db4272SNagarjuna Kristam } 1415*49db4272SNagarjuna Kristam 1416*49db4272SNagarjuna Kristam if (halt) { 1417*49db4272SNagarjuna Kristam ep_halt(xudc, ep->index); 1418*49db4272SNagarjuna Kristam } else { 1419*49db4272SNagarjuna Kristam ep_ctx_write_state(ep->context, EP_STATE_DISABLED); 1420*49db4272SNagarjuna Kristam 1421*49db4272SNagarjuna Kristam ep_reload(xudc, ep->index); 1422*49db4272SNagarjuna Kristam 1423*49db4272SNagarjuna Kristam ep_ctx_write_state(ep->context, EP_STATE_RUNNING); 1424*49db4272SNagarjuna Kristam ep_ctx_write_seq_num(ep->context, 0); 1425*49db4272SNagarjuna Kristam 1426*49db4272SNagarjuna Kristam ep_reload(xudc, ep->index); 1427*49db4272SNagarjuna Kristam ep_unpause(xudc, ep->index); 1428*49db4272SNagarjuna Kristam ep_unhalt(xudc, ep->index); 1429*49db4272SNagarjuna Kristam 1430*49db4272SNagarjuna Kristam tegra_xudc_ep_ring_doorbell(ep); 1431*49db4272SNagarjuna Kristam } 1432*49db4272SNagarjuna Kristam 1433*49db4272SNagarjuna Kristam return 0; 1434*49db4272SNagarjuna Kristam } 1435*49db4272SNagarjuna Kristam 1436*49db4272SNagarjuna Kristam static int tegra_xudc_ep_set_halt(struct usb_ep *usb_ep, int value) 1437*49db4272SNagarjuna Kristam { 1438*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep; 1439*49db4272SNagarjuna Kristam struct tegra_xudc *xudc; 1440*49db4272SNagarjuna Kristam unsigned long flags; 1441*49db4272SNagarjuna Kristam int ret; 1442*49db4272SNagarjuna Kristam 1443*49db4272SNagarjuna Kristam if (!usb_ep) 1444*49db4272SNagarjuna Kristam return -EINVAL; 1445*49db4272SNagarjuna Kristam 1446*49db4272SNagarjuna Kristam ep = to_xudc_ep(usb_ep); 1447*49db4272SNagarjuna Kristam xudc = ep->xudc; 1448*49db4272SNagarjuna Kristam 1449*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1450*49db4272SNagarjuna Kristam if (xudc->powergated) { 1451*49db4272SNagarjuna Kristam ret = -ESHUTDOWN; 1452*49db4272SNagarjuna Kristam goto unlock; 1453*49db4272SNagarjuna Kristam } 1454*49db4272SNagarjuna Kristam 1455*49db4272SNagarjuna Kristam if (value && usb_endpoint_dir_in(ep->desc) && 1456*49db4272SNagarjuna Kristam !list_empty(&ep->queue)) { 1457*49db4272SNagarjuna Kristam dev_err(xudc->dev, "can't halt EP with requests pending\n"); 1458*49db4272SNagarjuna Kristam ret = -EAGAIN; 1459*49db4272SNagarjuna Kristam goto unlock; 1460*49db4272SNagarjuna Kristam } 1461*49db4272SNagarjuna Kristam 1462*49db4272SNagarjuna Kristam ret = __tegra_xudc_ep_set_halt(ep, value); 1463*49db4272SNagarjuna Kristam unlock: 1464*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1465*49db4272SNagarjuna Kristam 1466*49db4272SNagarjuna Kristam return ret; 1467*49db4272SNagarjuna Kristam } 1468*49db4272SNagarjuna Kristam 1469*49db4272SNagarjuna Kristam static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep) 1470*49db4272SNagarjuna Kristam { 1471*49db4272SNagarjuna Kristam const struct usb_endpoint_descriptor *desc = ep->desc; 1472*49db4272SNagarjuna Kristam const struct usb_ss_ep_comp_descriptor *comp_desc = ep->comp_desc; 1473*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 1474*49db4272SNagarjuna Kristam u16 maxpacket, maxburst = 0, esit = 0; 1475*49db4272SNagarjuna Kristam u32 val; 1476*49db4272SNagarjuna Kristam 1477*49db4272SNagarjuna Kristam maxpacket = usb_endpoint_maxp(desc) & 0x7ff; 1478*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_SUPER) { 1479*49db4272SNagarjuna Kristam if (!usb_endpoint_xfer_control(desc)) 1480*49db4272SNagarjuna Kristam maxburst = comp_desc->bMaxBurst; 1481*49db4272SNagarjuna Kristam 1482*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) 1483*49db4272SNagarjuna Kristam esit = le16_to_cpu(comp_desc->wBytesPerInterval); 1484*49db4272SNagarjuna Kristam } else if ((xudc->gadget.speed < USB_SPEED_SUPER) && 1485*49db4272SNagarjuna Kristam (usb_endpoint_xfer_int(desc) || 1486*49db4272SNagarjuna Kristam usb_endpoint_xfer_isoc(desc))) { 1487*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_HIGH) { 1488*49db4272SNagarjuna Kristam maxburst = (usb_endpoint_maxp(desc) >> 11) & 0x3; 1489*49db4272SNagarjuna Kristam if (maxburst == 0x3) { 1490*49db4272SNagarjuna Kristam dev_warn(xudc->dev, 1491*49db4272SNagarjuna Kristam "invalid endpoint maxburst\n"); 1492*49db4272SNagarjuna Kristam maxburst = 0x2; 1493*49db4272SNagarjuna Kristam } 1494*49db4272SNagarjuna Kristam } 1495*49db4272SNagarjuna Kristam esit = maxpacket * (maxburst + 1); 1496*49db4272SNagarjuna Kristam } 1497*49db4272SNagarjuna Kristam 1498*49db4272SNagarjuna Kristam memset(ep->context, 0, sizeof(*ep->context)); 1499*49db4272SNagarjuna Kristam 1500*49db4272SNagarjuna Kristam ep_ctx_write_state(ep->context, EP_STATE_RUNNING); 1501*49db4272SNagarjuna Kristam ep_ctx_write_interval(ep->context, desc->bInterval); 1502*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_SUPER) { 1503*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_isoc(desc)) { 1504*49db4272SNagarjuna Kristam ep_ctx_write_mult(ep->context, 1505*49db4272SNagarjuna Kristam comp_desc->bmAttributes & 0x3); 1506*49db4272SNagarjuna Kristam } 1507*49db4272SNagarjuna Kristam 1508*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_bulk(desc)) { 1509*49db4272SNagarjuna Kristam ep_ctx_write_max_pstreams(ep->context, 1510*49db4272SNagarjuna Kristam comp_desc->bmAttributes & 1511*49db4272SNagarjuna Kristam 0x1f); 1512*49db4272SNagarjuna Kristam ep_ctx_write_lsa(ep->context, 1); 1513*49db4272SNagarjuna Kristam } 1514*49db4272SNagarjuna Kristam } 1515*49db4272SNagarjuna Kristam 1516*49db4272SNagarjuna Kristam if (!usb_endpoint_xfer_control(desc) && usb_endpoint_dir_out(desc)) 1517*49db4272SNagarjuna Kristam val = usb_endpoint_type(desc); 1518*49db4272SNagarjuna Kristam else 1519*49db4272SNagarjuna Kristam val = usb_endpoint_type(desc) + EP_TYPE_CONTROL; 1520*49db4272SNagarjuna Kristam 1521*49db4272SNagarjuna Kristam ep_ctx_write_type(ep->context, val); 1522*49db4272SNagarjuna Kristam ep_ctx_write_cerr(ep->context, 0x3); 1523*49db4272SNagarjuna Kristam ep_ctx_write_max_packet_size(ep->context, maxpacket); 1524*49db4272SNagarjuna Kristam ep_ctx_write_max_burst_size(ep->context, maxburst); 1525*49db4272SNagarjuna Kristam 1526*49db4272SNagarjuna Kristam ep_ctx_write_deq_ptr(ep->context, ep->transfer_ring_phys); 1527*49db4272SNagarjuna Kristam ep_ctx_write_dcs(ep->context, ep->pcs); 1528*49db4272SNagarjuna Kristam 1529*49db4272SNagarjuna Kristam /* Select a reasonable average TRB length based on endpoint type. */ 1530*49db4272SNagarjuna Kristam switch (usb_endpoint_type(desc)) { 1531*49db4272SNagarjuna Kristam case USB_ENDPOINT_XFER_CONTROL: 1532*49db4272SNagarjuna Kristam val = 8; 1533*49db4272SNagarjuna Kristam break; 1534*49db4272SNagarjuna Kristam case USB_ENDPOINT_XFER_INT: 1535*49db4272SNagarjuna Kristam val = 1024; 1536*49db4272SNagarjuna Kristam break; 1537*49db4272SNagarjuna Kristam case USB_ENDPOINT_XFER_BULK: 1538*49db4272SNagarjuna Kristam case USB_ENDPOINT_XFER_ISOC: 1539*49db4272SNagarjuna Kristam default: 1540*49db4272SNagarjuna Kristam val = 3072; 1541*49db4272SNagarjuna Kristam break; 1542*49db4272SNagarjuna Kristam } 1543*49db4272SNagarjuna Kristam 1544*49db4272SNagarjuna Kristam ep_ctx_write_avg_trb_len(ep->context, val); 1545*49db4272SNagarjuna Kristam ep_ctx_write_max_esit_payload(ep->context, esit); 1546*49db4272SNagarjuna Kristam 1547*49db4272SNagarjuna Kristam ep_ctx_write_cerrcnt(ep->context, 0x3); 1548*49db4272SNagarjuna Kristam } 1549*49db4272SNagarjuna Kristam 1550*49db4272SNagarjuna Kristam static void setup_link_trb(struct tegra_xudc_ep *ep, 1551*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb) 1552*49db4272SNagarjuna Kristam { 1553*49db4272SNagarjuna Kristam trb_write_data_ptr(trb, ep->transfer_ring_phys); 1554*49db4272SNagarjuna Kristam trb_write_type(trb, TRB_TYPE_LINK); 1555*49db4272SNagarjuna Kristam trb_write_toggle_cycle(trb, 1); 1556*49db4272SNagarjuna Kristam } 1557*49db4272SNagarjuna Kristam 1558*49db4272SNagarjuna Kristam static int __tegra_xudc_ep_disable(struct tegra_xudc_ep *ep) 1559*49db4272SNagarjuna Kristam { 1560*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 1561*49db4272SNagarjuna Kristam 1562*49db4272SNagarjuna Kristam if (ep_ctx_read_state(ep->context) == EP_STATE_DISABLED) { 1563*49db4272SNagarjuna Kristam dev_err(xudc->dev, "endpoint %u already disabled\n", 1564*49db4272SNagarjuna Kristam ep->index); 1565*49db4272SNagarjuna Kristam return -EINVAL; 1566*49db4272SNagarjuna Kristam } 1567*49db4272SNagarjuna Kristam 1568*49db4272SNagarjuna Kristam ep_ctx_write_state(ep->context, EP_STATE_DISABLED); 1569*49db4272SNagarjuna Kristam 1570*49db4272SNagarjuna Kristam ep_reload(xudc, ep->index); 1571*49db4272SNagarjuna Kristam 1572*49db4272SNagarjuna Kristam tegra_xudc_ep_nuke(ep, -ESHUTDOWN); 1573*49db4272SNagarjuna Kristam 1574*49db4272SNagarjuna Kristam xudc->nr_enabled_eps--; 1575*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_isoc(ep->desc)) 1576*49db4272SNagarjuna Kristam xudc->nr_isoch_eps--; 1577*49db4272SNagarjuna Kristam 1578*49db4272SNagarjuna Kristam ep->desc = NULL; 1579*49db4272SNagarjuna Kristam ep->comp_desc = NULL; 1580*49db4272SNagarjuna Kristam 1581*49db4272SNagarjuna Kristam memset(ep->context, 0, sizeof(*ep->context)); 1582*49db4272SNagarjuna Kristam 1583*49db4272SNagarjuna Kristam ep_unpause(xudc, ep->index); 1584*49db4272SNagarjuna Kristam ep_unhalt(xudc, ep->index); 1585*49db4272SNagarjuna Kristam if (xudc_readl(xudc, EP_STOPPED) & BIT(ep->index)) 1586*49db4272SNagarjuna Kristam xudc_writel(xudc, BIT(ep->index), EP_STOPPED); 1587*49db4272SNagarjuna Kristam 1588*49db4272SNagarjuna Kristam /* 1589*49db4272SNagarjuna Kristam * If this is the last endpoint disabled in a de-configure request, 1590*49db4272SNagarjuna Kristam * switch back to address state. 1591*49db4272SNagarjuna Kristam */ 1592*49db4272SNagarjuna Kristam if ((xudc->device_state == USB_STATE_CONFIGURED) && 1593*49db4272SNagarjuna Kristam (xudc->nr_enabled_eps == 1)) { 1594*49db4272SNagarjuna Kristam u32 val; 1595*49db4272SNagarjuna Kristam 1596*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_ADDRESS; 1597*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 1598*49db4272SNagarjuna Kristam 1599*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CTRL); 1600*49db4272SNagarjuna Kristam val &= ~CTRL_RUN; 1601*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CTRL); 1602*49db4272SNagarjuna Kristam } 1603*49db4272SNagarjuna Kristam 1604*49db4272SNagarjuna Kristam dev_info(xudc->dev, "ep %u disabled\n", ep->index); 1605*49db4272SNagarjuna Kristam 1606*49db4272SNagarjuna Kristam return 0; 1607*49db4272SNagarjuna Kristam } 1608*49db4272SNagarjuna Kristam 1609*49db4272SNagarjuna Kristam static int tegra_xudc_ep_disable(struct usb_ep *usb_ep) 1610*49db4272SNagarjuna Kristam { 1611*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep; 1612*49db4272SNagarjuna Kristam struct tegra_xudc *xudc; 1613*49db4272SNagarjuna Kristam unsigned long flags; 1614*49db4272SNagarjuna Kristam int ret; 1615*49db4272SNagarjuna Kristam 1616*49db4272SNagarjuna Kristam if (!usb_ep) 1617*49db4272SNagarjuna Kristam return -EINVAL; 1618*49db4272SNagarjuna Kristam 1619*49db4272SNagarjuna Kristam ep = to_xudc_ep(usb_ep); 1620*49db4272SNagarjuna Kristam xudc = ep->xudc; 1621*49db4272SNagarjuna Kristam 1622*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1623*49db4272SNagarjuna Kristam if (xudc->powergated) { 1624*49db4272SNagarjuna Kristam ret = -ESHUTDOWN; 1625*49db4272SNagarjuna Kristam goto unlock; 1626*49db4272SNagarjuna Kristam } 1627*49db4272SNagarjuna Kristam 1628*49db4272SNagarjuna Kristam ret = __tegra_xudc_ep_disable(ep); 1629*49db4272SNagarjuna Kristam unlock: 1630*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1631*49db4272SNagarjuna Kristam 1632*49db4272SNagarjuna Kristam return ret; 1633*49db4272SNagarjuna Kristam } 1634*49db4272SNagarjuna Kristam 1635*49db4272SNagarjuna Kristam static int __tegra_xudc_ep_enable(struct tegra_xudc_ep *ep, 1636*49db4272SNagarjuna Kristam const struct usb_endpoint_descriptor *desc) 1637*49db4272SNagarjuna Kristam { 1638*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = ep->xudc; 1639*49db4272SNagarjuna Kristam unsigned int i; 1640*49db4272SNagarjuna Kristam u32 val; 1641*49db4272SNagarjuna Kristam 1642*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_SUPER && 1643*49db4272SNagarjuna Kristam !usb_endpoint_xfer_control(desc) && !ep->usb_ep.comp_desc) 1644*49db4272SNagarjuna Kristam return -EINVAL; 1645*49db4272SNagarjuna Kristam 1646*49db4272SNagarjuna Kristam /* Disable the EP if it is not disabled */ 1647*49db4272SNagarjuna Kristam if (ep_ctx_read_state(ep->context) != EP_STATE_DISABLED) 1648*49db4272SNagarjuna Kristam __tegra_xudc_ep_disable(ep); 1649*49db4272SNagarjuna Kristam 1650*49db4272SNagarjuna Kristam ep->desc = desc; 1651*49db4272SNagarjuna Kristam ep->comp_desc = ep->usb_ep.comp_desc; 1652*49db4272SNagarjuna Kristam 1653*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_isoc(desc)) { 1654*49db4272SNagarjuna Kristam if (xudc->nr_isoch_eps > XUDC_MAX_ISOCH_EPS) { 1655*49db4272SNagarjuna Kristam dev_err(xudc->dev, "too many isoch endpoints\n"); 1656*49db4272SNagarjuna Kristam return -EBUSY; 1657*49db4272SNagarjuna Kristam } 1658*49db4272SNagarjuna Kristam xudc->nr_isoch_eps++; 1659*49db4272SNagarjuna Kristam } 1660*49db4272SNagarjuna Kristam 1661*49db4272SNagarjuna Kristam memset(ep->transfer_ring, 0, XUDC_TRANSFER_RING_SIZE * 1662*49db4272SNagarjuna Kristam sizeof(*ep->transfer_ring)); 1663*49db4272SNagarjuna Kristam setup_link_trb(ep, &ep->transfer_ring[XUDC_TRANSFER_RING_SIZE - 1]); 1664*49db4272SNagarjuna Kristam 1665*49db4272SNagarjuna Kristam ep->enq_ptr = 0; 1666*49db4272SNagarjuna Kristam ep->deq_ptr = 0; 1667*49db4272SNagarjuna Kristam ep->pcs = true; 1668*49db4272SNagarjuna Kristam ep->ring_full = false; 1669*49db4272SNagarjuna Kristam xudc->nr_enabled_eps++; 1670*49db4272SNagarjuna Kristam 1671*49db4272SNagarjuna Kristam tegra_xudc_ep_context_setup(ep); 1672*49db4272SNagarjuna Kristam 1673*49db4272SNagarjuna Kristam /* 1674*49db4272SNagarjuna Kristam * No need to reload and un-halt EP0. This will be done automatically 1675*49db4272SNagarjuna Kristam * once a valid SETUP packet is received. 1676*49db4272SNagarjuna Kristam */ 1677*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_control(desc)) 1678*49db4272SNagarjuna Kristam goto out; 1679*49db4272SNagarjuna Kristam 1680*49db4272SNagarjuna Kristam /* 1681*49db4272SNagarjuna Kristam * Transition to configured state once the first non-control 1682*49db4272SNagarjuna Kristam * endpoint is enabled. 1683*49db4272SNagarjuna Kristam */ 1684*49db4272SNagarjuna Kristam if (xudc->device_state == USB_STATE_ADDRESS) { 1685*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CTRL); 1686*49db4272SNagarjuna Kristam val |= CTRL_RUN; 1687*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CTRL); 1688*49db4272SNagarjuna Kristam 1689*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_CONFIGURED; 1690*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 1691*49db4272SNagarjuna Kristam } 1692*49db4272SNagarjuna Kristam 1693*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_isoc(desc)) { 1694*49db4272SNagarjuna Kristam /* 1695*49db4272SNagarjuna Kristam * Pause all bulk endpoints when enabling an isoch endpoint 1696*49db4272SNagarjuna Kristam * to ensure the isoch endpoint is allocated enough bandwidth. 1697*49db4272SNagarjuna Kristam */ 1698*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->ep); i++) { 1699*49db4272SNagarjuna Kristam if (xudc->ep[i].desc && 1700*49db4272SNagarjuna Kristam usb_endpoint_xfer_bulk(xudc->ep[i].desc)) 1701*49db4272SNagarjuna Kristam ep_pause(xudc, i); 1702*49db4272SNagarjuna Kristam } 1703*49db4272SNagarjuna Kristam } 1704*49db4272SNagarjuna Kristam 1705*49db4272SNagarjuna Kristam ep_reload(xudc, ep->index); 1706*49db4272SNagarjuna Kristam ep_unpause(xudc, ep->index); 1707*49db4272SNagarjuna Kristam ep_unhalt(xudc, ep->index); 1708*49db4272SNagarjuna Kristam 1709*49db4272SNagarjuna Kristam if (usb_endpoint_xfer_isoc(desc)) { 1710*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->ep); i++) { 1711*49db4272SNagarjuna Kristam if (xudc->ep[i].desc && 1712*49db4272SNagarjuna Kristam usb_endpoint_xfer_bulk(xudc->ep[i].desc)) 1713*49db4272SNagarjuna Kristam ep_unpause(xudc, i); 1714*49db4272SNagarjuna Kristam } 1715*49db4272SNagarjuna Kristam } 1716*49db4272SNagarjuna Kristam 1717*49db4272SNagarjuna Kristam out: 1718*49db4272SNagarjuna Kristam dev_info(xudc->dev, "EP %u (type: %s, dir: %s) enabled\n", ep->index, 1719*49db4272SNagarjuna Kristam usb_ep_type_string(usb_endpoint_type(ep->desc)), 1720*49db4272SNagarjuna Kristam usb_endpoint_dir_in(ep->desc) ? "in" : "out"); 1721*49db4272SNagarjuna Kristam 1722*49db4272SNagarjuna Kristam return 0; 1723*49db4272SNagarjuna Kristam } 1724*49db4272SNagarjuna Kristam 1725*49db4272SNagarjuna Kristam static int tegra_xudc_ep_enable(struct usb_ep *usb_ep, 1726*49db4272SNagarjuna Kristam const struct usb_endpoint_descriptor *desc) 1727*49db4272SNagarjuna Kristam { 1728*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep; 1729*49db4272SNagarjuna Kristam struct tegra_xudc *xudc; 1730*49db4272SNagarjuna Kristam unsigned long flags; 1731*49db4272SNagarjuna Kristam int ret; 1732*49db4272SNagarjuna Kristam 1733*49db4272SNagarjuna Kristam if (!usb_ep || !desc || (desc->bDescriptorType != USB_DT_ENDPOINT)) 1734*49db4272SNagarjuna Kristam return -EINVAL; 1735*49db4272SNagarjuna Kristam 1736*49db4272SNagarjuna Kristam ep = to_xudc_ep(usb_ep); 1737*49db4272SNagarjuna Kristam xudc = ep->xudc; 1738*49db4272SNagarjuna Kristam 1739*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1740*49db4272SNagarjuna Kristam if (xudc->powergated) { 1741*49db4272SNagarjuna Kristam ret = -ESHUTDOWN; 1742*49db4272SNagarjuna Kristam goto unlock; 1743*49db4272SNagarjuna Kristam } 1744*49db4272SNagarjuna Kristam 1745*49db4272SNagarjuna Kristam ret = __tegra_xudc_ep_enable(ep, desc); 1746*49db4272SNagarjuna Kristam unlock: 1747*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1748*49db4272SNagarjuna Kristam 1749*49db4272SNagarjuna Kristam return ret; 1750*49db4272SNagarjuna Kristam } 1751*49db4272SNagarjuna Kristam 1752*49db4272SNagarjuna Kristam static struct usb_request * 1753*49db4272SNagarjuna Kristam tegra_xudc_ep_alloc_request(struct usb_ep *usb_ep, gfp_t gfp) 1754*49db4272SNagarjuna Kristam { 1755*49db4272SNagarjuna Kristam struct tegra_xudc_request *req; 1756*49db4272SNagarjuna Kristam 1757*49db4272SNagarjuna Kristam req = kzalloc(sizeof(*req), gfp); 1758*49db4272SNagarjuna Kristam if (!req) 1759*49db4272SNagarjuna Kristam return NULL; 1760*49db4272SNagarjuna Kristam 1761*49db4272SNagarjuna Kristam INIT_LIST_HEAD(&req->list); 1762*49db4272SNagarjuna Kristam 1763*49db4272SNagarjuna Kristam return &req->usb_req; 1764*49db4272SNagarjuna Kristam } 1765*49db4272SNagarjuna Kristam 1766*49db4272SNagarjuna Kristam static void tegra_xudc_ep_free_request(struct usb_ep *usb_ep, 1767*49db4272SNagarjuna Kristam struct usb_request *usb_req) 1768*49db4272SNagarjuna Kristam { 1769*49db4272SNagarjuna Kristam struct tegra_xudc_request *req = to_xudc_req(usb_req); 1770*49db4272SNagarjuna Kristam 1771*49db4272SNagarjuna Kristam kfree(req); 1772*49db4272SNagarjuna Kristam } 1773*49db4272SNagarjuna Kristam 1774*49db4272SNagarjuna Kristam static struct usb_ep_ops tegra_xudc_ep_ops = { 1775*49db4272SNagarjuna Kristam .enable = tegra_xudc_ep_enable, 1776*49db4272SNagarjuna Kristam .disable = tegra_xudc_ep_disable, 1777*49db4272SNagarjuna Kristam .alloc_request = tegra_xudc_ep_alloc_request, 1778*49db4272SNagarjuna Kristam .free_request = tegra_xudc_ep_free_request, 1779*49db4272SNagarjuna Kristam .queue = tegra_xudc_ep_queue, 1780*49db4272SNagarjuna Kristam .dequeue = tegra_xudc_ep_dequeue, 1781*49db4272SNagarjuna Kristam .set_halt = tegra_xudc_ep_set_halt, 1782*49db4272SNagarjuna Kristam }; 1783*49db4272SNagarjuna Kristam 1784*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_enable(struct usb_ep *usb_ep, 1785*49db4272SNagarjuna Kristam const struct usb_endpoint_descriptor *desc) 1786*49db4272SNagarjuna Kristam { 1787*49db4272SNagarjuna Kristam return -EBUSY; 1788*49db4272SNagarjuna Kristam } 1789*49db4272SNagarjuna Kristam 1790*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_disable(struct usb_ep *usb_ep) 1791*49db4272SNagarjuna Kristam { 1792*49db4272SNagarjuna Kristam return -EBUSY; 1793*49db4272SNagarjuna Kristam } 1794*49db4272SNagarjuna Kristam 1795*49db4272SNagarjuna Kristam static struct usb_ep_ops tegra_xudc_ep0_ops = { 1796*49db4272SNagarjuna Kristam .enable = tegra_xudc_ep0_enable, 1797*49db4272SNagarjuna Kristam .disable = tegra_xudc_ep0_disable, 1798*49db4272SNagarjuna Kristam .alloc_request = tegra_xudc_ep_alloc_request, 1799*49db4272SNagarjuna Kristam .free_request = tegra_xudc_ep_free_request, 1800*49db4272SNagarjuna Kristam .queue = tegra_xudc_ep_queue, 1801*49db4272SNagarjuna Kristam .dequeue = tegra_xudc_ep_dequeue, 1802*49db4272SNagarjuna Kristam .set_halt = tegra_xudc_ep_set_halt, 1803*49db4272SNagarjuna Kristam }; 1804*49db4272SNagarjuna Kristam 1805*49db4272SNagarjuna Kristam static int tegra_xudc_gadget_get_frame(struct usb_gadget *gadget) 1806*49db4272SNagarjuna Kristam { 1807*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = to_xudc(gadget); 1808*49db4272SNagarjuna Kristam unsigned long flags; 1809*49db4272SNagarjuna Kristam int ret; 1810*49db4272SNagarjuna Kristam 1811*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1812*49db4272SNagarjuna Kristam if (xudc->powergated) { 1813*49db4272SNagarjuna Kristam ret = -ESHUTDOWN; 1814*49db4272SNagarjuna Kristam goto unlock; 1815*49db4272SNagarjuna Kristam } 1816*49db4272SNagarjuna Kristam 1817*49db4272SNagarjuna Kristam ret = (xudc_readl(xudc, MFINDEX) & MFINDEX_FRAME_MASK) >> 1818*49db4272SNagarjuna Kristam MFINDEX_FRAME_SHIFT; 1819*49db4272SNagarjuna Kristam unlock: 1820*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1821*49db4272SNagarjuna Kristam 1822*49db4272SNagarjuna Kristam return ret; 1823*49db4272SNagarjuna Kristam } 1824*49db4272SNagarjuna Kristam 1825*49db4272SNagarjuna Kristam static void tegra_xudc_resume_device_state(struct tegra_xudc *xudc) 1826*49db4272SNagarjuna Kristam { 1827*49db4272SNagarjuna Kristam unsigned int i; 1828*49db4272SNagarjuna Kristam u32 val; 1829*49db4272SNagarjuna Kristam 1830*49db4272SNagarjuna Kristam ep_unpause_all(xudc); 1831*49db4272SNagarjuna Kristam 1832*49db4272SNagarjuna Kristam /* Direct link to U0. */ 1833*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTSC); 1834*49db4272SNagarjuna Kristam if (((val & PORTSC_PLS_MASK) >> PORTSC_PLS_SHIFT) != PORTSC_PLS_U0) { 1835*49db4272SNagarjuna Kristam val &= ~(PORTSC_CHANGE_MASK | PORTSC_PLS_MASK); 1836*49db4272SNagarjuna Kristam val |= PORTSC_LWS | PORTSC_PLS(PORTSC_PLS_U0); 1837*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTSC); 1838*49db4272SNagarjuna Kristam } 1839*49db4272SNagarjuna Kristam 1840*49db4272SNagarjuna Kristam if (xudc->device_state == USB_STATE_SUSPENDED) { 1841*49db4272SNagarjuna Kristam xudc->device_state = xudc->resume_state; 1842*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 1843*49db4272SNagarjuna Kristam xudc->resume_state = 0; 1844*49db4272SNagarjuna Kristam } 1845*49db4272SNagarjuna Kristam 1846*49db4272SNagarjuna Kristam /* 1847*49db4272SNagarjuna Kristam * Doorbells may be dropped if they are sent too soon (< ~200ns) 1848*49db4272SNagarjuna Kristam * after unpausing the endpoint. Wait for 500ns just to be safe. 1849*49db4272SNagarjuna Kristam */ 1850*49db4272SNagarjuna Kristam ndelay(500); 1851*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->ep); i++) 1852*49db4272SNagarjuna Kristam tegra_xudc_ep_ring_doorbell(&xudc->ep[i]); 1853*49db4272SNagarjuna Kristam } 1854*49db4272SNagarjuna Kristam 1855*49db4272SNagarjuna Kristam static int tegra_xudc_gadget_wakeup(struct usb_gadget *gadget) 1856*49db4272SNagarjuna Kristam { 1857*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = to_xudc(gadget); 1858*49db4272SNagarjuna Kristam unsigned long flags; 1859*49db4272SNagarjuna Kristam int ret = 0; 1860*49db4272SNagarjuna Kristam u32 val; 1861*49db4272SNagarjuna Kristam 1862*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1863*49db4272SNagarjuna Kristam 1864*49db4272SNagarjuna Kristam if (xudc->powergated) { 1865*49db4272SNagarjuna Kristam ret = -ESHUTDOWN; 1866*49db4272SNagarjuna Kristam goto unlock; 1867*49db4272SNagarjuna Kristam } 1868*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 1869*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "%s: PORTPM=%#x, speed=%x\n", __func__, 1870*49db4272SNagarjuna Kristam val, gadget->speed); 1871*49db4272SNagarjuna Kristam 1872*49db4272SNagarjuna Kristam if (((xudc->gadget.speed <= USB_SPEED_HIGH) && 1873*49db4272SNagarjuna Kristam (val & PORTPM_RWE)) || 1874*49db4272SNagarjuna Kristam ((xudc->gadget.speed == USB_SPEED_SUPER) && 1875*49db4272SNagarjuna Kristam (val & PORTPM_FRWE))) { 1876*49db4272SNagarjuna Kristam tegra_xudc_resume_device_state(xudc); 1877*49db4272SNagarjuna Kristam 1878*49db4272SNagarjuna Kristam /* Send Device Notification packet. */ 1879*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_SUPER) { 1880*49db4272SNagarjuna Kristam val = DEVNOTIF_LO_TYPE(DEVNOTIF_LO_TYPE_FUNCTION_WAKE) 1881*49db4272SNagarjuna Kristam | DEVNOTIF_LO_TRIG; 1882*49db4272SNagarjuna Kristam xudc_writel(xudc, 0, DEVNOTIF_HI); 1883*49db4272SNagarjuna Kristam xudc_writel(xudc, val, DEVNOTIF_LO); 1884*49db4272SNagarjuna Kristam } 1885*49db4272SNagarjuna Kristam } 1886*49db4272SNagarjuna Kristam 1887*49db4272SNagarjuna Kristam unlock: 1888*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "%s: ret value is %d", __func__, ret); 1889*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1890*49db4272SNagarjuna Kristam 1891*49db4272SNagarjuna Kristam return ret; 1892*49db4272SNagarjuna Kristam } 1893*49db4272SNagarjuna Kristam 1894*49db4272SNagarjuna Kristam static int tegra_xudc_gadget_pullup(struct usb_gadget *gadget, int is_on) 1895*49db4272SNagarjuna Kristam { 1896*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = to_xudc(gadget); 1897*49db4272SNagarjuna Kristam unsigned long flags; 1898*49db4272SNagarjuna Kristam u32 val; 1899*49db4272SNagarjuna Kristam 1900*49db4272SNagarjuna Kristam pm_runtime_get_sync(xudc->dev); 1901*49db4272SNagarjuna Kristam 1902*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1903*49db4272SNagarjuna Kristam 1904*49db4272SNagarjuna Kristam if (is_on != xudc->pullup) { 1905*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CTRL); 1906*49db4272SNagarjuna Kristam if (is_on) 1907*49db4272SNagarjuna Kristam val |= CTRL_ENABLE; 1908*49db4272SNagarjuna Kristam else 1909*49db4272SNagarjuna Kristam val &= ~CTRL_ENABLE; 1910*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CTRL); 1911*49db4272SNagarjuna Kristam } 1912*49db4272SNagarjuna Kristam 1913*49db4272SNagarjuna Kristam xudc->pullup = is_on; 1914*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "%s: pullup:%d", __func__, is_on); 1915*49db4272SNagarjuna Kristam 1916*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1917*49db4272SNagarjuna Kristam 1918*49db4272SNagarjuna Kristam pm_runtime_put(xudc->dev); 1919*49db4272SNagarjuna Kristam 1920*49db4272SNagarjuna Kristam return 0; 1921*49db4272SNagarjuna Kristam } 1922*49db4272SNagarjuna Kristam 1923*49db4272SNagarjuna Kristam static int tegra_xudc_gadget_start(struct usb_gadget *gadget, 1924*49db4272SNagarjuna Kristam struct usb_gadget_driver *driver) 1925*49db4272SNagarjuna Kristam { 1926*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = to_xudc(gadget); 1927*49db4272SNagarjuna Kristam unsigned long flags; 1928*49db4272SNagarjuna Kristam u32 val; 1929*49db4272SNagarjuna Kristam int ret; 1930*49db4272SNagarjuna Kristam 1931*49db4272SNagarjuna Kristam if (!driver) 1932*49db4272SNagarjuna Kristam return -EINVAL; 1933*49db4272SNagarjuna Kristam 1934*49db4272SNagarjuna Kristam pm_runtime_get_sync(xudc->dev); 1935*49db4272SNagarjuna Kristam 1936*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1937*49db4272SNagarjuna Kristam 1938*49db4272SNagarjuna Kristam if (xudc->driver) { 1939*49db4272SNagarjuna Kristam ret = -EBUSY; 1940*49db4272SNagarjuna Kristam goto unlock; 1941*49db4272SNagarjuna Kristam } 1942*49db4272SNagarjuna Kristam 1943*49db4272SNagarjuna Kristam xudc->setup_state = WAIT_FOR_SETUP; 1944*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_DEFAULT; 1945*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 1946*49db4272SNagarjuna Kristam 1947*49db4272SNagarjuna Kristam ret = __tegra_xudc_ep_enable(&xudc->ep[0], &tegra_xudc_ep0_desc); 1948*49db4272SNagarjuna Kristam if (ret < 0) 1949*49db4272SNagarjuna Kristam goto unlock; 1950*49db4272SNagarjuna Kristam 1951*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CTRL); 1952*49db4272SNagarjuna Kristam val |= CTRL_IE | CTRL_LSE; 1953*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CTRL); 1954*49db4272SNagarjuna Kristam 1955*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTHALT); 1956*49db4272SNagarjuna Kristam val |= PORTHALT_STCHG_INTR_EN; 1957*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTHALT); 1958*49db4272SNagarjuna Kristam 1959*49db4272SNagarjuna Kristam if (xudc->pullup) { 1960*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CTRL); 1961*49db4272SNagarjuna Kristam val |= CTRL_ENABLE; 1962*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CTRL); 1963*49db4272SNagarjuna Kristam } 1964*49db4272SNagarjuna Kristam 1965*49db4272SNagarjuna Kristam xudc->driver = driver; 1966*49db4272SNagarjuna Kristam unlock: 1967*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "%s: ret value is %d", __func__, ret); 1968*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1969*49db4272SNagarjuna Kristam 1970*49db4272SNagarjuna Kristam pm_runtime_put(xudc->dev); 1971*49db4272SNagarjuna Kristam 1972*49db4272SNagarjuna Kristam return ret; 1973*49db4272SNagarjuna Kristam } 1974*49db4272SNagarjuna Kristam 1975*49db4272SNagarjuna Kristam static int tegra_xudc_gadget_stop(struct usb_gadget *gadget) 1976*49db4272SNagarjuna Kristam { 1977*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = to_xudc(gadget); 1978*49db4272SNagarjuna Kristam unsigned long flags; 1979*49db4272SNagarjuna Kristam u32 val; 1980*49db4272SNagarjuna Kristam 1981*49db4272SNagarjuna Kristam pm_runtime_get_sync(xudc->dev); 1982*49db4272SNagarjuna Kristam 1983*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 1984*49db4272SNagarjuna Kristam 1985*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CTRL); 1986*49db4272SNagarjuna Kristam val &= ~(CTRL_IE | CTRL_ENABLE); 1987*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CTRL); 1988*49db4272SNagarjuna Kristam 1989*49db4272SNagarjuna Kristam __tegra_xudc_ep_disable(&xudc->ep[0]); 1990*49db4272SNagarjuna Kristam 1991*49db4272SNagarjuna Kristam xudc->driver = NULL; 1992*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "Gadget stopped"); 1993*49db4272SNagarjuna Kristam 1994*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 1995*49db4272SNagarjuna Kristam 1996*49db4272SNagarjuna Kristam pm_runtime_put(xudc->dev); 1997*49db4272SNagarjuna Kristam 1998*49db4272SNagarjuna Kristam return 0; 1999*49db4272SNagarjuna Kristam } 2000*49db4272SNagarjuna Kristam 2001*49db4272SNagarjuna Kristam static int tegra_xudc_set_selfpowered(struct usb_gadget *gadget, int is_on) 2002*49db4272SNagarjuna Kristam { 2003*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = to_xudc(gadget); 2004*49db4272SNagarjuna Kristam 2005*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "%s: %d\n", __func__, is_on); 2006*49db4272SNagarjuna Kristam xudc->selfpowered = !!is_on; 2007*49db4272SNagarjuna Kristam 2008*49db4272SNagarjuna Kristam return 0; 2009*49db4272SNagarjuna Kristam } 2010*49db4272SNagarjuna Kristam 2011*49db4272SNagarjuna Kristam static struct usb_gadget_ops tegra_xudc_gadget_ops = { 2012*49db4272SNagarjuna Kristam .get_frame = tegra_xudc_gadget_get_frame, 2013*49db4272SNagarjuna Kristam .wakeup = tegra_xudc_gadget_wakeup, 2014*49db4272SNagarjuna Kristam .pullup = tegra_xudc_gadget_pullup, 2015*49db4272SNagarjuna Kristam .udc_start = tegra_xudc_gadget_start, 2016*49db4272SNagarjuna Kristam .udc_stop = tegra_xudc_gadget_stop, 2017*49db4272SNagarjuna Kristam .set_selfpowered = tegra_xudc_set_selfpowered, 2018*49db4272SNagarjuna Kristam }; 2019*49db4272SNagarjuna Kristam 2020*49db4272SNagarjuna Kristam static void no_op_complete(struct usb_ep *ep, struct usb_request *req) 2021*49db4272SNagarjuna Kristam { 2022*49db4272SNagarjuna Kristam } 2023*49db4272SNagarjuna Kristam 2024*49db4272SNagarjuna Kristam static int 2025*49db4272SNagarjuna Kristam tegra_xudc_ep0_queue_status(struct tegra_xudc *xudc, 2026*49db4272SNagarjuna Kristam void (*cmpl)(struct usb_ep *, struct usb_request *)) 2027*49db4272SNagarjuna Kristam { 2028*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.buf = NULL; 2029*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.dma = 0; 2030*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.length = 0; 2031*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.complete = cmpl; 2032*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.context = xudc; 2033*49db4272SNagarjuna Kristam 2034*49db4272SNagarjuna Kristam return __tegra_xudc_ep_queue(&xudc->ep[0], xudc->ep0_req); 2035*49db4272SNagarjuna Kristam } 2036*49db4272SNagarjuna Kristam 2037*49db4272SNagarjuna Kristam static int 2038*49db4272SNagarjuna Kristam tegra_xudc_ep0_queue_data(struct tegra_xudc *xudc, void *buf, size_t len, 2039*49db4272SNagarjuna Kristam void (*cmpl)(struct usb_ep *, struct usb_request *)) 2040*49db4272SNagarjuna Kristam { 2041*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.buf = buf; 2042*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.length = len; 2043*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.complete = cmpl; 2044*49db4272SNagarjuna Kristam xudc->ep0_req->usb_req.context = xudc; 2045*49db4272SNagarjuna Kristam 2046*49db4272SNagarjuna Kristam return __tegra_xudc_ep_queue(&xudc->ep[0], xudc->ep0_req); 2047*49db4272SNagarjuna Kristam } 2048*49db4272SNagarjuna Kristam 2049*49db4272SNagarjuna Kristam static void tegra_xudc_ep0_req_done(struct tegra_xudc *xudc) 2050*49db4272SNagarjuna Kristam { 2051*49db4272SNagarjuna Kristam switch (xudc->setup_state) { 2052*49db4272SNagarjuna Kristam case DATA_STAGE_XFER: 2053*49db4272SNagarjuna Kristam xudc->setup_state = STATUS_STAGE_RECV; 2054*49db4272SNagarjuna Kristam tegra_xudc_ep0_queue_status(xudc, no_op_complete); 2055*49db4272SNagarjuna Kristam break; 2056*49db4272SNagarjuna Kristam case DATA_STAGE_RECV: 2057*49db4272SNagarjuna Kristam xudc->setup_state = STATUS_STAGE_XFER; 2058*49db4272SNagarjuna Kristam tegra_xudc_ep0_queue_status(xudc, no_op_complete); 2059*49db4272SNagarjuna Kristam break; 2060*49db4272SNagarjuna Kristam default: 2061*49db4272SNagarjuna Kristam xudc->setup_state = WAIT_FOR_SETUP; 2062*49db4272SNagarjuna Kristam break; 2063*49db4272SNagarjuna Kristam } 2064*49db4272SNagarjuna Kristam } 2065*49db4272SNagarjuna Kristam 2066*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_delegate_req(struct tegra_xudc *xudc, 2067*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl) 2068*49db4272SNagarjuna Kristam { 2069*49db4272SNagarjuna Kristam int ret; 2070*49db4272SNagarjuna Kristam 2071*49db4272SNagarjuna Kristam spin_unlock(&xudc->lock); 2072*49db4272SNagarjuna Kristam ret = xudc->driver->setup(&xudc->gadget, ctrl); 2073*49db4272SNagarjuna Kristam spin_lock(&xudc->lock); 2074*49db4272SNagarjuna Kristam 2075*49db4272SNagarjuna Kristam return ret; 2076*49db4272SNagarjuna Kristam } 2077*49db4272SNagarjuna Kristam 2078*49db4272SNagarjuna Kristam static void set_feature_complete(struct usb_ep *ep, struct usb_request *req) 2079*49db4272SNagarjuna Kristam { 2080*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = req->context; 2081*49db4272SNagarjuna Kristam 2082*49db4272SNagarjuna Kristam if (xudc->test_mode_pattern) { 2083*49db4272SNagarjuna Kristam xudc_writel(xudc, xudc->test_mode_pattern, PORT_TM); 2084*49db4272SNagarjuna Kristam xudc->test_mode_pattern = 0; 2085*49db4272SNagarjuna Kristam } 2086*49db4272SNagarjuna Kristam } 2087*49db4272SNagarjuna Kristam 2088*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_set_feature(struct tegra_xudc *xudc, 2089*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl) 2090*49db4272SNagarjuna Kristam { 2091*49db4272SNagarjuna Kristam bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); 2092*49db4272SNagarjuna Kristam u32 feature = le16_to_cpu(ctrl->wValue); 2093*49db4272SNagarjuna Kristam u32 index = le16_to_cpu(ctrl->wIndex); 2094*49db4272SNagarjuna Kristam u32 val, ep; 2095*49db4272SNagarjuna Kristam int ret; 2096*49db4272SNagarjuna Kristam 2097*49db4272SNagarjuna Kristam if (le16_to_cpu(ctrl->wLength) != 0) 2098*49db4272SNagarjuna Kristam return -EINVAL; 2099*49db4272SNagarjuna Kristam 2100*49db4272SNagarjuna Kristam switch (ctrl->bRequestType & USB_RECIP_MASK) { 2101*49db4272SNagarjuna Kristam case USB_RECIP_DEVICE: 2102*49db4272SNagarjuna Kristam switch (feature) { 2103*49db4272SNagarjuna Kristam case USB_DEVICE_REMOTE_WAKEUP: 2104*49db4272SNagarjuna Kristam if ((xudc->gadget.speed == USB_SPEED_SUPER) || 2105*49db4272SNagarjuna Kristam (xudc->device_state == USB_STATE_DEFAULT)) 2106*49db4272SNagarjuna Kristam return -EINVAL; 2107*49db4272SNagarjuna Kristam 2108*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 2109*49db4272SNagarjuna Kristam if (set) 2110*49db4272SNagarjuna Kristam val |= PORTPM_RWE; 2111*49db4272SNagarjuna Kristam else 2112*49db4272SNagarjuna Kristam val &= ~PORTPM_RWE; 2113*49db4272SNagarjuna Kristam 2114*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTPM); 2115*49db4272SNagarjuna Kristam break; 2116*49db4272SNagarjuna Kristam case USB_DEVICE_U1_ENABLE: 2117*49db4272SNagarjuna Kristam case USB_DEVICE_U2_ENABLE: 2118*49db4272SNagarjuna Kristam if ((xudc->device_state != USB_STATE_CONFIGURED) || 2119*49db4272SNagarjuna Kristam (xudc->gadget.speed != USB_SPEED_SUPER)) 2120*49db4272SNagarjuna Kristam return -EINVAL; 2121*49db4272SNagarjuna Kristam 2122*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 2123*49db4272SNagarjuna Kristam if ((feature == USB_DEVICE_U1_ENABLE) && 2124*49db4272SNagarjuna Kristam xudc->soc->u1_enable) { 2125*49db4272SNagarjuna Kristam if (set) 2126*49db4272SNagarjuna Kristam val |= PORTPM_U1E; 2127*49db4272SNagarjuna Kristam else 2128*49db4272SNagarjuna Kristam val &= ~PORTPM_U1E; 2129*49db4272SNagarjuna Kristam } 2130*49db4272SNagarjuna Kristam 2131*49db4272SNagarjuna Kristam if ((feature == USB_DEVICE_U2_ENABLE) && 2132*49db4272SNagarjuna Kristam xudc->soc->u2_enable) { 2133*49db4272SNagarjuna Kristam if (set) 2134*49db4272SNagarjuna Kristam val |= PORTPM_U2E; 2135*49db4272SNagarjuna Kristam else 2136*49db4272SNagarjuna Kristam val &= ~PORTPM_U2E; 2137*49db4272SNagarjuna Kristam } 2138*49db4272SNagarjuna Kristam 2139*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTPM); 2140*49db4272SNagarjuna Kristam break; 2141*49db4272SNagarjuna Kristam case USB_DEVICE_TEST_MODE: 2142*49db4272SNagarjuna Kristam if (xudc->gadget.speed != USB_SPEED_HIGH) 2143*49db4272SNagarjuna Kristam return -EINVAL; 2144*49db4272SNagarjuna Kristam 2145*49db4272SNagarjuna Kristam if (!set) 2146*49db4272SNagarjuna Kristam return -EINVAL; 2147*49db4272SNagarjuna Kristam 2148*49db4272SNagarjuna Kristam xudc->test_mode_pattern = index >> 8; 2149*49db4272SNagarjuna Kristam break; 2150*49db4272SNagarjuna Kristam default: 2151*49db4272SNagarjuna Kristam return -EINVAL; 2152*49db4272SNagarjuna Kristam } 2153*49db4272SNagarjuna Kristam 2154*49db4272SNagarjuna Kristam break; 2155*49db4272SNagarjuna Kristam case USB_RECIP_INTERFACE: 2156*49db4272SNagarjuna Kristam if (xudc->device_state != USB_STATE_CONFIGURED) 2157*49db4272SNagarjuna Kristam return -EINVAL; 2158*49db4272SNagarjuna Kristam 2159*49db4272SNagarjuna Kristam switch (feature) { 2160*49db4272SNagarjuna Kristam case USB_INTRF_FUNC_SUSPEND: 2161*49db4272SNagarjuna Kristam if (set) { 2162*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 2163*49db4272SNagarjuna Kristam 2164*49db4272SNagarjuna Kristam if (index & USB_INTRF_FUNC_SUSPEND_RW) 2165*49db4272SNagarjuna Kristam val |= PORTPM_FRWE; 2166*49db4272SNagarjuna Kristam else 2167*49db4272SNagarjuna Kristam val &= ~PORTPM_FRWE; 2168*49db4272SNagarjuna Kristam 2169*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTPM); 2170*49db4272SNagarjuna Kristam } 2171*49db4272SNagarjuna Kristam 2172*49db4272SNagarjuna Kristam return tegra_xudc_ep0_delegate_req(xudc, ctrl); 2173*49db4272SNagarjuna Kristam default: 2174*49db4272SNagarjuna Kristam return -EINVAL; 2175*49db4272SNagarjuna Kristam } 2176*49db4272SNagarjuna Kristam 2177*49db4272SNagarjuna Kristam break; 2178*49db4272SNagarjuna Kristam case USB_RECIP_ENDPOINT: 2179*49db4272SNagarjuna Kristam ep = (index & USB_ENDPOINT_NUMBER_MASK) * 2 + 2180*49db4272SNagarjuna Kristam ((index & USB_DIR_IN) ? 1 : 0); 2181*49db4272SNagarjuna Kristam 2182*49db4272SNagarjuna Kristam if ((xudc->device_state == USB_STATE_DEFAULT) || 2183*49db4272SNagarjuna Kristam ((xudc->device_state == USB_STATE_ADDRESS) && 2184*49db4272SNagarjuna Kristam (index != 0))) 2185*49db4272SNagarjuna Kristam return -EINVAL; 2186*49db4272SNagarjuna Kristam 2187*49db4272SNagarjuna Kristam ret = __tegra_xudc_ep_set_halt(&xudc->ep[ep], set); 2188*49db4272SNagarjuna Kristam if (ret < 0) 2189*49db4272SNagarjuna Kristam return ret; 2190*49db4272SNagarjuna Kristam break; 2191*49db4272SNagarjuna Kristam default: 2192*49db4272SNagarjuna Kristam return -EINVAL; 2193*49db4272SNagarjuna Kristam } 2194*49db4272SNagarjuna Kristam 2195*49db4272SNagarjuna Kristam return tegra_xudc_ep0_queue_status(xudc, set_feature_complete); 2196*49db4272SNagarjuna Kristam } 2197*49db4272SNagarjuna Kristam 2198*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_get_status(struct tegra_xudc *xudc, 2199*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl) 2200*49db4272SNagarjuna Kristam { 2201*49db4272SNagarjuna Kristam struct tegra_xudc_ep_context *ep_ctx; 2202*49db4272SNagarjuna Kristam u32 val, ep, index = le16_to_cpu(ctrl->wIndex); 2203*49db4272SNagarjuna Kristam u16 status = 0; 2204*49db4272SNagarjuna Kristam 2205*49db4272SNagarjuna Kristam if (!(ctrl->bRequestType & USB_DIR_IN)) 2206*49db4272SNagarjuna Kristam return -EINVAL; 2207*49db4272SNagarjuna Kristam 2208*49db4272SNagarjuna Kristam if ((le16_to_cpu(ctrl->wValue) != 0) || 2209*49db4272SNagarjuna Kristam (le16_to_cpu(ctrl->wLength) != 2)) 2210*49db4272SNagarjuna Kristam return -EINVAL; 2211*49db4272SNagarjuna Kristam 2212*49db4272SNagarjuna Kristam switch (ctrl->bRequestType & USB_RECIP_MASK) { 2213*49db4272SNagarjuna Kristam case USB_RECIP_DEVICE: 2214*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 2215*49db4272SNagarjuna Kristam 2216*49db4272SNagarjuna Kristam if (xudc->selfpowered) 2217*49db4272SNagarjuna Kristam status |= BIT(USB_DEVICE_SELF_POWERED); 2218*49db4272SNagarjuna Kristam 2219*49db4272SNagarjuna Kristam if ((xudc->gadget.speed < USB_SPEED_SUPER) && 2220*49db4272SNagarjuna Kristam (val & PORTPM_RWE)) 2221*49db4272SNagarjuna Kristam status |= BIT(USB_DEVICE_REMOTE_WAKEUP); 2222*49db4272SNagarjuna Kristam 2223*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_SUPER) { 2224*49db4272SNagarjuna Kristam if (val & PORTPM_U1E) 2225*49db4272SNagarjuna Kristam status |= BIT(USB_DEV_STAT_U1_ENABLED); 2226*49db4272SNagarjuna Kristam if (val & PORTPM_U2E) 2227*49db4272SNagarjuna Kristam status |= BIT(USB_DEV_STAT_U2_ENABLED); 2228*49db4272SNagarjuna Kristam } 2229*49db4272SNagarjuna Kristam break; 2230*49db4272SNagarjuna Kristam case USB_RECIP_INTERFACE: 2231*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_SUPER) { 2232*49db4272SNagarjuna Kristam status |= USB_INTRF_STAT_FUNC_RW_CAP; 2233*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 2234*49db4272SNagarjuna Kristam if (val & PORTPM_FRWE) 2235*49db4272SNagarjuna Kristam status |= USB_INTRF_STAT_FUNC_RW; 2236*49db4272SNagarjuna Kristam } 2237*49db4272SNagarjuna Kristam break; 2238*49db4272SNagarjuna Kristam case USB_RECIP_ENDPOINT: 2239*49db4272SNagarjuna Kristam ep = (index & USB_ENDPOINT_NUMBER_MASK) * 2 + 2240*49db4272SNagarjuna Kristam ((index & USB_DIR_IN) ? 1 : 0); 2241*49db4272SNagarjuna Kristam ep_ctx = &xudc->ep_context[ep]; 2242*49db4272SNagarjuna Kristam 2243*49db4272SNagarjuna Kristam if ((xudc->device_state != USB_STATE_CONFIGURED) && 2244*49db4272SNagarjuna Kristam ((xudc->device_state != USB_STATE_ADDRESS) || (ep != 0))) 2245*49db4272SNagarjuna Kristam return -EINVAL; 2246*49db4272SNagarjuna Kristam 2247*49db4272SNagarjuna Kristam if (ep_ctx_read_state(ep_ctx) == EP_STATE_DISABLED) 2248*49db4272SNagarjuna Kristam return -EINVAL; 2249*49db4272SNagarjuna Kristam 2250*49db4272SNagarjuna Kristam if (xudc_readl(xudc, EP_HALT) & BIT(ep)) 2251*49db4272SNagarjuna Kristam status |= BIT(USB_ENDPOINT_HALT); 2252*49db4272SNagarjuna Kristam break; 2253*49db4272SNagarjuna Kristam default: 2254*49db4272SNagarjuna Kristam return -EINVAL; 2255*49db4272SNagarjuna Kristam } 2256*49db4272SNagarjuna Kristam 2257*49db4272SNagarjuna Kristam xudc->status_buf = cpu_to_le16(status); 2258*49db4272SNagarjuna Kristam return tegra_xudc_ep0_queue_data(xudc, &xudc->status_buf, 2259*49db4272SNagarjuna Kristam sizeof(xudc->status_buf), 2260*49db4272SNagarjuna Kristam no_op_complete); 2261*49db4272SNagarjuna Kristam } 2262*49db4272SNagarjuna Kristam 2263*49db4272SNagarjuna Kristam static void set_sel_complete(struct usb_ep *ep, struct usb_request *req) 2264*49db4272SNagarjuna Kristam { 2265*49db4272SNagarjuna Kristam /* Nothing to do with SEL values */ 2266*49db4272SNagarjuna Kristam } 2267*49db4272SNagarjuna Kristam 2268*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_set_sel(struct tegra_xudc *xudc, 2269*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl) 2270*49db4272SNagarjuna Kristam { 2271*49db4272SNagarjuna Kristam if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE | 2272*49db4272SNagarjuna Kristam USB_TYPE_STANDARD)) 2273*49db4272SNagarjuna Kristam return -EINVAL; 2274*49db4272SNagarjuna Kristam 2275*49db4272SNagarjuna Kristam if (xudc->device_state == USB_STATE_DEFAULT) 2276*49db4272SNagarjuna Kristam return -EINVAL; 2277*49db4272SNagarjuna Kristam 2278*49db4272SNagarjuna Kristam if ((le16_to_cpu(ctrl->wIndex) != 0) || 2279*49db4272SNagarjuna Kristam (le16_to_cpu(ctrl->wValue) != 0) || 2280*49db4272SNagarjuna Kristam (le16_to_cpu(ctrl->wLength) != 6)) 2281*49db4272SNagarjuna Kristam return -EINVAL; 2282*49db4272SNagarjuna Kristam 2283*49db4272SNagarjuna Kristam return tegra_xudc_ep0_queue_data(xudc, &xudc->sel_timing, 2284*49db4272SNagarjuna Kristam sizeof(xudc->sel_timing), 2285*49db4272SNagarjuna Kristam set_sel_complete); 2286*49db4272SNagarjuna Kristam } 2287*49db4272SNagarjuna Kristam 2288*49db4272SNagarjuna Kristam static void set_isoch_delay_complete(struct usb_ep *ep, struct usb_request *req) 2289*49db4272SNagarjuna Kristam { 2290*49db4272SNagarjuna Kristam /* Nothing to do with isoch delay */ 2291*49db4272SNagarjuna Kristam } 2292*49db4272SNagarjuna Kristam 2293*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_set_isoch_delay(struct tegra_xudc *xudc, 2294*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl) 2295*49db4272SNagarjuna Kristam { 2296*49db4272SNagarjuna Kristam u32 delay = le16_to_cpu(ctrl->wValue); 2297*49db4272SNagarjuna Kristam 2298*49db4272SNagarjuna Kristam if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE | 2299*49db4272SNagarjuna Kristam USB_TYPE_STANDARD)) 2300*49db4272SNagarjuna Kristam return -EINVAL; 2301*49db4272SNagarjuna Kristam 2302*49db4272SNagarjuna Kristam if ((delay > 65535) || (le16_to_cpu(ctrl->wIndex) != 0) || 2303*49db4272SNagarjuna Kristam (le16_to_cpu(ctrl->wLength) != 0)) 2304*49db4272SNagarjuna Kristam return -EINVAL; 2305*49db4272SNagarjuna Kristam 2306*49db4272SNagarjuna Kristam xudc->isoch_delay = delay; 2307*49db4272SNagarjuna Kristam 2308*49db4272SNagarjuna Kristam return tegra_xudc_ep0_queue_status(xudc, set_isoch_delay_complete); 2309*49db4272SNagarjuna Kristam } 2310*49db4272SNagarjuna Kristam 2311*49db4272SNagarjuna Kristam static void set_address_complete(struct usb_ep *ep, struct usb_request *req) 2312*49db4272SNagarjuna Kristam { 2313*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = req->context; 2314*49db4272SNagarjuna Kristam 2315*49db4272SNagarjuna Kristam if ((xudc->device_state == USB_STATE_DEFAULT) && 2316*49db4272SNagarjuna Kristam (xudc->dev_addr != 0)) { 2317*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_ADDRESS; 2318*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 2319*49db4272SNagarjuna Kristam } else if ((xudc->device_state == USB_STATE_ADDRESS) && 2320*49db4272SNagarjuna Kristam (xudc->dev_addr == 0)) { 2321*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_DEFAULT; 2322*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 2323*49db4272SNagarjuna Kristam } 2324*49db4272SNagarjuna Kristam } 2325*49db4272SNagarjuna Kristam 2326*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_set_address(struct tegra_xudc *xudc, 2327*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl) 2328*49db4272SNagarjuna Kristam { 2329*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep0 = &xudc->ep[0]; 2330*49db4272SNagarjuna Kristam u32 val, addr = le16_to_cpu(ctrl->wValue); 2331*49db4272SNagarjuna Kristam 2332*49db4272SNagarjuna Kristam if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE | 2333*49db4272SNagarjuna Kristam USB_TYPE_STANDARD)) 2334*49db4272SNagarjuna Kristam return -EINVAL; 2335*49db4272SNagarjuna Kristam 2336*49db4272SNagarjuna Kristam if ((addr > 127) || (le16_to_cpu(ctrl->wIndex) != 0) || 2337*49db4272SNagarjuna Kristam (le16_to_cpu(ctrl->wLength) != 0)) 2338*49db4272SNagarjuna Kristam return -EINVAL; 2339*49db4272SNagarjuna Kristam 2340*49db4272SNagarjuna Kristam if (xudc->device_state == USB_STATE_CONFIGURED) 2341*49db4272SNagarjuna Kristam return -EINVAL; 2342*49db4272SNagarjuna Kristam 2343*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "set address: %u\n", addr); 2344*49db4272SNagarjuna Kristam 2345*49db4272SNagarjuna Kristam xudc->dev_addr = addr; 2346*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CTRL); 2347*49db4272SNagarjuna Kristam val &= ~(CTRL_DEVADDR_MASK); 2348*49db4272SNagarjuna Kristam val |= CTRL_DEVADDR(addr); 2349*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CTRL); 2350*49db4272SNagarjuna Kristam 2351*49db4272SNagarjuna Kristam ep_ctx_write_devaddr(ep0->context, addr); 2352*49db4272SNagarjuna Kristam 2353*49db4272SNagarjuna Kristam return tegra_xudc_ep0_queue_status(xudc, set_address_complete); 2354*49db4272SNagarjuna Kristam } 2355*49db4272SNagarjuna Kristam 2356*49db4272SNagarjuna Kristam static int tegra_xudc_ep0_standard_req(struct tegra_xudc *xudc, 2357*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl) 2358*49db4272SNagarjuna Kristam { 2359*49db4272SNagarjuna Kristam int ret; 2360*49db4272SNagarjuna Kristam 2361*49db4272SNagarjuna Kristam switch (ctrl->bRequest) { 2362*49db4272SNagarjuna Kristam case USB_REQ_GET_STATUS: 2363*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "USB_REQ_GET_STATUS\n"); 2364*49db4272SNagarjuna Kristam ret = tegra_xudc_ep0_get_status(xudc, ctrl); 2365*49db4272SNagarjuna Kristam break; 2366*49db4272SNagarjuna Kristam case USB_REQ_SET_ADDRESS: 2367*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "USB_REQ_SET_ADDRESS\n"); 2368*49db4272SNagarjuna Kristam ret = tegra_xudc_ep0_set_address(xudc, ctrl); 2369*49db4272SNagarjuna Kristam break; 2370*49db4272SNagarjuna Kristam case USB_REQ_SET_SEL: 2371*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "USB_REQ_SET_SEL\n"); 2372*49db4272SNagarjuna Kristam ret = tegra_xudc_ep0_set_sel(xudc, ctrl); 2373*49db4272SNagarjuna Kristam break; 2374*49db4272SNagarjuna Kristam case USB_REQ_SET_ISOCH_DELAY: 2375*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "USB_REQ_SET_ISOCH_DELAY\n"); 2376*49db4272SNagarjuna Kristam ret = tegra_xudc_ep0_set_isoch_delay(xudc, ctrl); 2377*49db4272SNagarjuna Kristam break; 2378*49db4272SNagarjuna Kristam case USB_REQ_CLEAR_FEATURE: 2379*49db4272SNagarjuna Kristam case USB_REQ_SET_FEATURE: 2380*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "USB_REQ_CLEAR/SET_FEATURE\n"); 2381*49db4272SNagarjuna Kristam ret = tegra_xudc_ep0_set_feature(xudc, ctrl); 2382*49db4272SNagarjuna Kristam break; 2383*49db4272SNagarjuna Kristam case USB_REQ_SET_CONFIGURATION: 2384*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "USB_REQ_SET_CONFIGURATION\n"); 2385*49db4272SNagarjuna Kristam /* 2386*49db4272SNagarjuna Kristam * In theory we need to clear RUN bit before status stage of 2387*49db4272SNagarjuna Kristam * deconfig request sent, but this seems to be causing problems. 2388*49db4272SNagarjuna Kristam * Clear RUN once all endpoints are disabled instead. 2389*49db4272SNagarjuna Kristam */ 2390*49db4272SNagarjuna Kristam fallthrough; 2391*49db4272SNagarjuna Kristam default: 2392*49db4272SNagarjuna Kristam ret = tegra_xudc_ep0_delegate_req(xudc, ctrl); 2393*49db4272SNagarjuna Kristam break; 2394*49db4272SNagarjuna Kristam } 2395*49db4272SNagarjuna Kristam 2396*49db4272SNagarjuna Kristam return ret; 2397*49db4272SNagarjuna Kristam } 2398*49db4272SNagarjuna Kristam 2399*49db4272SNagarjuna Kristam static void tegra_xudc_handle_ep0_setup_packet(struct tegra_xudc *xudc, 2400*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl, 2401*49db4272SNagarjuna Kristam u16 seq_num) 2402*49db4272SNagarjuna Kristam { 2403*49db4272SNagarjuna Kristam int ret; 2404*49db4272SNagarjuna Kristam 2405*49db4272SNagarjuna Kristam xudc->setup_seq_num = seq_num; 2406*49db4272SNagarjuna Kristam 2407*49db4272SNagarjuna Kristam /* Ensure EP0 is unhalted. */ 2408*49db4272SNagarjuna Kristam ep_unhalt(xudc, 0); 2409*49db4272SNagarjuna Kristam 2410*49db4272SNagarjuna Kristam /* 2411*49db4272SNagarjuna Kristam * On Tegra210, setup packets with sequence numbers 0xfffe or 0xffff 2412*49db4272SNagarjuna Kristam * are invalid. Halt EP0 until we get a valid packet. 2413*49db4272SNagarjuna Kristam */ 2414*49db4272SNagarjuna Kristam if (xudc->soc->invalid_seq_num && 2415*49db4272SNagarjuna Kristam (seq_num == 0xfffe || seq_num == 0xffff)) { 2416*49db4272SNagarjuna Kristam dev_warn(xudc->dev, "invalid sequence number detected\n"); 2417*49db4272SNagarjuna Kristam ep_halt(xudc, 0); 2418*49db4272SNagarjuna Kristam return; 2419*49db4272SNagarjuna Kristam } 2420*49db4272SNagarjuna Kristam 2421*49db4272SNagarjuna Kristam if (ctrl->wLength) 2422*49db4272SNagarjuna Kristam xudc->setup_state = (ctrl->bRequestType & USB_DIR_IN) ? 2423*49db4272SNagarjuna Kristam DATA_STAGE_XFER : DATA_STAGE_RECV; 2424*49db4272SNagarjuna Kristam else 2425*49db4272SNagarjuna Kristam xudc->setup_state = STATUS_STAGE_XFER; 2426*49db4272SNagarjuna Kristam 2427*49db4272SNagarjuna Kristam if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) 2428*49db4272SNagarjuna Kristam ret = tegra_xudc_ep0_standard_req(xudc, ctrl); 2429*49db4272SNagarjuna Kristam else 2430*49db4272SNagarjuna Kristam ret = tegra_xudc_ep0_delegate_req(xudc, ctrl); 2431*49db4272SNagarjuna Kristam 2432*49db4272SNagarjuna Kristam if (ret < 0) { 2433*49db4272SNagarjuna Kristam dev_warn(xudc->dev, "setup request failed: %d\n", ret); 2434*49db4272SNagarjuna Kristam xudc->setup_state = WAIT_FOR_SETUP; 2435*49db4272SNagarjuna Kristam ep_halt(xudc, 0); 2436*49db4272SNagarjuna Kristam } 2437*49db4272SNagarjuna Kristam } 2438*49db4272SNagarjuna Kristam 2439*49db4272SNagarjuna Kristam static void tegra_xudc_handle_ep0_event(struct tegra_xudc *xudc, 2440*49db4272SNagarjuna Kristam struct tegra_xudc_trb *event) 2441*49db4272SNagarjuna Kristam { 2442*49db4272SNagarjuna Kristam struct usb_ctrlrequest *ctrl = (struct usb_ctrlrequest *)event; 2443*49db4272SNagarjuna Kristam u16 seq_num = trb_read_seq_num(event); 2444*49db4272SNagarjuna Kristam 2445*49db4272SNagarjuna Kristam if (xudc->setup_state != WAIT_FOR_SETUP) { 2446*49db4272SNagarjuna Kristam /* 2447*49db4272SNagarjuna Kristam * The controller is in the process of handling another 2448*49db4272SNagarjuna Kristam * setup request. Queue subsequent requests and handle 2449*49db4272SNagarjuna Kristam * the last one once the controller reports a sequence 2450*49db4272SNagarjuna Kristam * number error. 2451*49db4272SNagarjuna Kristam */ 2452*49db4272SNagarjuna Kristam memcpy(&xudc->setup_packet.ctrl_req, ctrl, sizeof(*ctrl)); 2453*49db4272SNagarjuna Kristam xudc->setup_packet.seq_num = seq_num; 2454*49db4272SNagarjuna Kristam xudc->queued_setup_packet = true; 2455*49db4272SNagarjuna Kristam } else { 2456*49db4272SNagarjuna Kristam tegra_xudc_handle_ep0_setup_packet(xudc, ctrl, seq_num); 2457*49db4272SNagarjuna Kristam } 2458*49db4272SNagarjuna Kristam } 2459*49db4272SNagarjuna Kristam 2460*49db4272SNagarjuna Kristam static struct tegra_xudc_request * 2461*49db4272SNagarjuna Kristam trb_to_request(struct tegra_xudc_ep *ep, struct tegra_xudc_trb *trb) 2462*49db4272SNagarjuna Kristam { 2463*49db4272SNagarjuna Kristam struct tegra_xudc_request *req; 2464*49db4272SNagarjuna Kristam 2465*49db4272SNagarjuna Kristam list_for_each_entry(req, &ep->queue, list) { 2466*49db4272SNagarjuna Kristam if (!req->trbs_queued) 2467*49db4272SNagarjuna Kristam break; 2468*49db4272SNagarjuna Kristam 2469*49db4272SNagarjuna Kristam if (trb_in_request(ep, req, trb)) 2470*49db4272SNagarjuna Kristam return req; 2471*49db4272SNagarjuna Kristam } 2472*49db4272SNagarjuna Kristam 2473*49db4272SNagarjuna Kristam return NULL; 2474*49db4272SNagarjuna Kristam } 2475*49db4272SNagarjuna Kristam 2476*49db4272SNagarjuna Kristam static void tegra_xudc_handle_transfer_completion(struct tegra_xudc *xudc, 2477*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep, 2478*49db4272SNagarjuna Kristam struct tegra_xudc_trb *event) 2479*49db4272SNagarjuna Kristam { 2480*49db4272SNagarjuna Kristam struct tegra_xudc_request *req; 2481*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb; 2482*49db4272SNagarjuna Kristam bool short_packet; 2483*49db4272SNagarjuna Kristam 2484*49db4272SNagarjuna Kristam short_packet = (trb_read_cmpl_code(event) == 2485*49db4272SNagarjuna Kristam TRB_CMPL_CODE_SHORT_PACKET); 2486*49db4272SNagarjuna Kristam 2487*49db4272SNagarjuna Kristam trb = trb_phys_to_virt(ep, trb_read_data_ptr(event)); 2488*49db4272SNagarjuna Kristam req = trb_to_request(ep, trb); 2489*49db4272SNagarjuna Kristam 2490*49db4272SNagarjuna Kristam /* 2491*49db4272SNagarjuna Kristam * TDs are complete on short packet or when the completed TRB is the 2492*49db4272SNagarjuna Kristam * last TRB in the TD (the CHAIN bit is unset). 2493*49db4272SNagarjuna Kristam */ 2494*49db4272SNagarjuna Kristam if (req && (short_packet || (!trb_read_chain(trb) && 2495*49db4272SNagarjuna Kristam (req->trbs_needed == req->trbs_queued)))) { 2496*49db4272SNagarjuna Kristam struct tegra_xudc_trb *last = req->last_trb; 2497*49db4272SNagarjuna Kristam unsigned int residual; 2498*49db4272SNagarjuna Kristam 2499*49db4272SNagarjuna Kristam residual = trb_read_transfer_len(event); 2500*49db4272SNagarjuna Kristam req->usb_req.actual = req->usb_req.length - residual; 2501*49db4272SNagarjuna Kristam 2502*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "bytes transferred %u / %u\n", 2503*49db4272SNagarjuna Kristam req->usb_req.actual, req->usb_req.length); 2504*49db4272SNagarjuna Kristam 2505*49db4272SNagarjuna Kristam tegra_xudc_req_done(ep, req, 0); 2506*49db4272SNagarjuna Kristam 2507*49db4272SNagarjuna Kristam if (ep->desc && usb_endpoint_xfer_control(ep->desc)) 2508*49db4272SNagarjuna Kristam tegra_xudc_ep0_req_done(xudc); 2509*49db4272SNagarjuna Kristam 2510*49db4272SNagarjuna Kristam /* 2511*49db4272SNagarjuna Kristam * Advance the dequeue pointer past the end of the current TD 2512*49db4272SNagarjuna Kristam * on short packet completion. 2513*49db4272SNagarjuna Kristam */ 2514*49db4272SNagarjuna Kristam if (short_packet) { 2515*49db4272SNagarjuna Kristam ep->deq_ptr = (last - ep->transfer_ring) + 1; 2516*49db4272SNagarjuna Kristam if (ep->deq_ptr == XUDC_TRANSFER_RING_SIZE - 1) 2517*49db4272SNagarjuna Kristam ep->deq_ptr = 0; 2518*49db4272SNagarjuna Kristam } 2519*49db4272SNagarjuna Kristam } else if (!req) { 2520*49db4272SNagarjuna Kristam dev_warn(xudc->dev, "transfer event on dequeued request\n"); 2521*49db4272SNagarjuna Kristam } 2522*49db4272SNagarjuna Kristam 2523*49db4272SNagarjuna Kristam if (ep->desc) 2524*49db4272SNagarjuna Kristam tegra_xudc_ep_kick_queue(ep); 2525*49db4272SNagarjuna Kristam } 2526*49db4272SNagarjuna Kristam 2527*49db4272SNagarjuna Kristam static void tegra_xudc_handle_transfer_event(struct tegra_xudc *xudc, 2528*49db4272SNagarjuna Kristam struct tegra_xudc_trb *event) 2529*49db4272SNagarjuna Kristam { 2530*49db4272SNagarjuna Kristam unsigned int ep_index = trb_read_endpoint_id(event); 2531*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep = &xudc->ep[ep_index]; 2532*49db4272SNagarjuna Kristam struct tegra_xudc_trb *trb; 2533*49db4272SNagarjuna Kristam u16 comp_code; 2534*49db4272SNagarjuna Kristam 2535*49db4272SNagarjuna Kristam if (ep_ctx_read_state(ep->context) == EP_STATE_DISABLED) { 2536*49db4272SNagarjuna Kristam dev_warn(xudc->dev, "transfer event on disabled EP %u\n", 2537*49db4272SNagarjuna Kristam ep_index); 2538*49db4272SNagarjuna Kristam return; 2539*49db4272SNagarjuna Kristam } 2540*49db4272SNagarjuna Kristam 2541*49db4272SNagarjuna Kristam /* Update transfer ring dequeue pointer. */ 2542*49db4272SNagarjuna Kristam trb = trb_phys_to_virt(ep, trb_read_data_ptr(event)); 2543*49db4272SNagarjuna Kristam comp_code = trb_read_cmpl_code(event); 2544*49db4272SNagarjuna Kristam if (comp_code != TRB_CMPL_CODE_BABBLE_DETECTED_ERR) { 2545*49db4272SNagarjuna Kristam ep->deq_ptr = (trb - ep->transfer_ring) + 1; 2546*49db4272SNagarjuna Kristam 2547*49db4272SNagarjuna Kristam if (ep->deq_ptr == XUDC_TRANSFER_RING_SIZE - 1) 2548*49db4272SNagarjuna Kristam ep->deq_ptr = 0; 2549*49db4272SNagarjuna Kristam ep->ring_full = false; 2550*49db4272SNagarjuna Kristam } 2551*49db4272SNagarjuna Kristam 2552*49db4272SNagarjuna Kristam switch (comp_code) { 2553*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_SUCCESS: 2554*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_SHORT_PACKET: 2555*49db4272SNagarjuna Kristam tegra_xudc_handle_transfer_completion(xudc, ep, event); 2556*49db4272SNagarjuna Kristam break; 2557*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_HOST_REJECTED: 2558*49db4272SNagarjuna Kristam dev_info(xudc->dev, "stream rejected on EP %u\n", ep_index); 2559*49db4272SNagarjuna Kristam 2560*49db4272SNagarjuna Kristam ep->stream_rejected = true; 2561*49db4272SNagarjuna Kristam break; 2562*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_PRIME_PIPE_RECEIVED: 2563*49db4272SNagarjuna Kristam dev_info(xudc->dev, "prime pipe received on EP %u\n", ep_index); 2564*49db4272SNagarjuna Kristam 2565*49db4272SNagarjuna Kristam if (ep->stream_rejected) { 2566*49db4272SNagarjuna Kristam ep->stream_rejected = false; 2567*49db4272SNagarjuna Kristam /* 2568*49db4272SNagarjuna Kristam * An EP is stopped when a stream is rejected. Wait 2569*49db4272SNagarjuna Kristam * for the EP to report that it is stopped and then 2570*49db4272SNagarjuna Kristam * un-stop it. 2571*49db4272SNagarjuna Kristam */ 2572*49db4272SNagarjuna Kristam ep_wait_for_stopped(xudc, ep_index); 2573*49db4272SNagarjuna Kristam } 2574*49db4272SNagarjuna Kristam tegra_xudc_ep_ring_doorbell(ep); 2575*49db4272SNagarjuna Kristam break; 2576*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_BABBLE_DETECTED_ERR: 2577*49db4272SNagarjuna Kristam /* 2578*49db4272SNagarjuna Kristam * Wait for the EP to be stopped so the controller stops 2579*49db4272SNagarjuna Kristam * processing doorbells. 2580*49db4272SNagarjuna Kristam */ 2581*49db4272SNagarjuna Kristam ep_wait_for_stopped(xudc, ep_index); 2582*49db4272SNagarjuna Kristam ep->enq_ptr = ep->deq_ptr; 2583*49db4272SNagarjuna Kristam tegra_xudc_ep_nuke(ep, -EIO); 2584*49db4272SNagarjuna Kristam /* FALLTHROUGH */ 2585*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_STREAM_NUMP_ERROR: 2586*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_CTRL_DIR_ERR: 2587*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_INVALID_STREAM_TYPE_ERR: 2588*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_RING_UNDERRUN: 2589*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_RING_OVERRUN: 2590*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_ISOCH_BUFFER_OVERRUN: 2591*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_USB_TRANS_ERR: 2592*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_TRB_ERR: 2593*49db4272SNagarjuna Kristam dev_err(xudc->dev, "completion error %#x on EP %u\n", 2594*49db4272SNagarjuna Kristam comp_code, ep_index); 2595*49db4272SNagarjuna Kristam 2596*49db4272SNagarjuna Kristam ep_halt(xudc, ep_index); 2597*49db4272SNagarjuna Kristam break; 2598*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_CTRL_SEQNUM_ERR: 2599*49db4272SNagarjuna Kristam dev_info(xudc->dev, "sequence number error\n"); 2600*49db4272SNagarjuna Kristam 2601*49db4272SNagarjuna Kristam /* 2602*49db4272SNagarjuna Kristam * Kill any queued control request and skip to the last 2603*49db4272SNagarjuna Kristam * setup packet we received. 2604*49db4272SNagarjuna Kristam */ 2605*49db4272SNagarjuna Kristam tegra_xudc_ep_nuke(ep, -EINVAL); 2606*49db4272SNagarjuna Kristam xudc->setup_state = WAIT_FOR_SETUP; 2607*49db4272SNagarjuna Kristam if (!xudc->queued_setup_packet) 2608*49db4272SNagarjuna Kristam break; 2609*49db4272SNagarjuna Kristam 2610*49db4272SNagarjuna Kristam tegra_xudc_handle_ep0_setup_packet(xudc, 2611*49db4272SNagarjuna Kristam &xudc->setup_packet.ctrl_req, 2612*49db4272SNagarjuna Kristam xudc->setup_packet.seq_num); 2613*49db4272SNagarjuna Kristam xudc->queued_setup_packet = false; 2614*49db4272SNagarjuna Kristam break; 2615*49db4272SNagarjuna Kristam case TRB_CMPL_CODE_STOPPED: 2616*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "stop completion code on EP %u\n", 2617*49db4272SNagarjuna Kristam ep_index); 2618*49db4272SNagarjuna Kristam 2619*49db4272SNagarjuna Kristam /* Disconnected. */ 2620*49db4272SNagarjuna Kristam tegra_xudc_ep_nuke(ep, -ECONNREFUSED); 2621*49db4272SNagarjuna Kristam break; 2622*49db4272SNagarjuna Kristam default: 2623*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "completion event %#x on EP %u\n", 2624*49db4272SNagarjuna Kristam comp_code, ep_index); 2625*49db4272SNagarjuna Kristam break; 2626*49db4272SNagarjuna Kristam } 2627*49db4272SNagarjuna Kristam } 2628*49db4272SNagarjuna Kristam 2629*49db4272SNagarjuna Kristam static void tegra_xudc_reset(struct tegra_xudc *xudc) 2630*49db4272SNagarjuna Kristam { 2631*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep0 = &xudc->ep[0]; 2632*49db4272SNagarjuna Kristam dma_addr_t deq_ptr; 2633*49db4272SNagarjuna Kristam unsigned int i; 2634*49db4272SNagarjuna Kristam 2635*49db4272SNagarjuna Kristam xudc->setup_state = WAIT_FOR_SETUP; 2636*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_DEFAULT; 2637*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 2638*49db4272SNagarjuna Kristam 2639*49db4272SNagarjuna Kristam ep_unpause_all(xudc); 2640*49db4272SNagarjuna Kristam 2641*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->ep); i++) 2642*49db4272SNagarjuna Kristam tegra_xudc_ep_nuke(&xudc->ep[i], -ESHUTDOWN); 2643*49db4272SNagarjuna Kristam 2644*49db4272SNagarjuna Kristam /* 2645*49db4272SNagarjuna Kristam * Reset sequence number and dequeue pointer to flush the transfer 2646*49db4272SNagarjuna Kristam * ring. 2647*49db4272SNagarjuna Kristam */ 2648*49db4272SNagarjuna Kristam ep0->deq_ptr = ep0->enq_ptr; 2649*49db4272SNagarjuna Kristam ep0->ring_full = false; 2650*49db4272SNagarjuna Kristam 2651*49db4272SNagarjuna Kristam xudc->setup_seq_num = 0; 2652*49db4272SNagarjuna Kristam xudc->queued_setup_packet = false; 2653*49db4272SNagarjuna Kristam 2654*49db4272SNagarjuna Kristam ep_ctx_write_seq_num(ep0->context, xudc->setup_seq_num); 2655*49db4272SNagarjuna Kristam 2656*49db4272SNagarjuna Kristam deq_ptr = trb_virt_to_phys(ep0, &ep0->transfer_ring[ep0->deq_ptr]); 2657*49db4272SNagarjuna Kristam 2658*49db4272SNagarjuna Kristam if (!dma_mapping_error(xudc->dev, deq_ptr)) { 2659*49db4272SNagarjuna Kristam ep_ctx_write_deq_ptr(ep0->context, deq_ptr); 2660*49db4272SNagarjuna Kristam ep_ctx_write_dcs(ep0->context, ep0->pcs); 2661*49db4272SNagarjuna Kristam } 2662*49db4272SNagarjuna Kristam 2663*49db4272SNagarjuna Kristam ep_unhalt_all(xudc); 2664*49db4272SNagarjuna Kristam ep_reload(xudc, 0); 2665*49db4272SNagarjuna Kristam ep_unpause(xudc, 0); 2666*49db4272SNagarjuna Kristam } 2667*49db4272SNagarjuna Kristam 2668*49db4272SNagarjuna Kristam static void tegra_xudc_port_connect(struct tegra_xudc *xudc) 2669*49db4272SNagarjuna Kristam { 2670*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep0 = &xudc->ep[0]; 2671*49db4272SNagarjuna Kristam u16 maxpacket; 2672*49db4272SNagarjuna Kristam u32 val; 2673*49db4272SNagarjuna Kristam 2674*49db4272SNagarjuna Kristam val = (xudc_readl(xudc, PORTSC) & PORTSC_PS_MASK) >> PORTSC_PS_SHIFT; 2675*49db4272SNagarjuna Kristam switch (val) { 2676*49db4272SNagarjuna Kristam case PORTSC_PS_LS: 2677*49db4272SNagarjuna Kristam xudc->gadget.speed = USB_SPEED_LOW; 2678*49db4272SNagarjuna Kristam break; 2679*49db4272SNagarjuna Kristam case PORTSC_PS_FS: 2680*49db4272SNagarjuna Kristam xudc->gadget.speed = USB_SPEED_FULL; 2681*49db4272SNagarjuna Kristam break; 2682*49db4272SNagarjuna Kristam case PORTSC_PS_HS: 2683*49db4272SNagarjuna Kristam xudc->gadget.speed = USB_SPEED_HIGH; 2684*49db4272SNagarjuna Kristam break; 2685*49db4272SNagarjuna Kristam case PORTSC_PS_SS: 2686*49db4272SNagarjuna Kristam xudc->gadget.speed = USB_SPEED_SUPER; 2687*49db4272SNagarjuna Kristam break; 2688*49db4272SNagarjuna Kristam default: 2689*49db4272SNagarjuna Kristam xudc->gadget.speed = USB_SPEED_UNKNOWN; 2690*49db4272SNagarjuna Kristam break; 2691*49db4272SNagarjuna Kristam } 2692*49db4272SNagarjuna Kristam 2693*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_DEFAULT; 2694*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 2695*49db4272SNagarjuna Kristam 2696*49db4272SNagarjuna Kristam xudc->setup_state = WAIT_FOR_SETUP; 2697*49db4272SNagarjuna Kristam 2698*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_SUPER) 2699*49db4272SNagarjuna Kristam maxpacket = 512; 2700*49db4272SNagarjuna Kristam else 2701*49db4272SNagarjuna Kristam maxpacket = 64; 2702*49db4272SNagarjuna Kristam 2703*49db4272SNagarjuna Kristam ep_ctx_write_max_packet_size(ep0->context, maxpacket); 2704*49db4272SNagarjuna Kristam tegra_xudc_ep0_desc.wMaxPacketSize = cpu_to_le16(maxpacket); 2705*49db4272SNagarjuna Kristam usb_ep_set_maxpacket_limit(&ep0->usb_ep, maxpacket); 2706*49db4272SNagarjuna Kristam 2707*49db4272SNagarjuna Kristam if (!xudc->soc->u1_enable) { 2708*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 2709*49db4272SNagarjuna Kristam val &= ~(PORTPM_U1TIMEOUT_MASK); 2710*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTPM); 2711*49db4272SNagarjuna Kristam } 2712*49db4272SNagarjuna Kristam 2713*49db4272SNagarjuna Kristam if (!xudc->soc->u2_enable) { 2714*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 2715*49db4272SNagarjuna Kristam val &= ~(PORTPM_U2TIMEOUT_MASK); 2716*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTPM); 2717*49db4272SNagarjuna Kristam } 2718*49db4272SNagarjuna Kristam 2719*49db4272SNagarjuna Kristam if (xudc->gadget.speed <= USB_SPEED_HIGH) { 2720*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTPM); 2721*49db4272SNagarjuna Kristam val &= ~(PORTPM_L1S_MASK); 2722*49db4272SNagarjuna Kristam if (xudc->soc->lpm_enable) 2723*49db4272SNagarjuna Kristam val |= PORTPM_L1S(PORTPM_L1S_ACCEPT); 2724*49db4272SNagarjuna Kristam else 2725*49db4272SNagarjuna Kristam val |= PORTPM_L1S(PORTPM_L1S_NYET); 2726*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTPM); 2727*49db4272SNagarjuna Kristam } 2728*49db4272SNagarjuna Kristam 2729*49db4272SNagarjuna Kristam val = xudc_readl(xudc, ST); 2730*49db4272SNagarjuna Kristam if (val & ST_RC) 2731*49db4272SNagarjuna Kristam xudc_writel(xudc, ST_RC, ST); 2732*49db4272SNagarjuna Kristam } 2733*49db4272SNagarjuna Kristam 2734*49db4272SNagarjuna Kristam static void tegra_xudc_port_disconnect(struct tegra_xudc *xudc) 2735*49db4272SNagarjuna Kristam { 2736*49db4272SNagarjuna Kristam tegra_xudc_reset(xudc); 2737*49db4272SNagarjuna Kristam 2738*49db4272SNagarjuna Kristam if (xudc->driver && xudc->driver->disconnect) { 2739*49db4272SNagarjuna Kristam spin_unlock(&xudc->lock); 2740*49db4272SNagarjuna Kristam xudc->driver->disconnect(&xudc->gadget); 2741*49db4272SNagarjuna Kristam spin_lock(&xudc->lock); 2742*49db4272SNagarjuna Kristam } 2743*49db4272SNagarjuna Kristam 2744*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_NOTATTACHED; 2745*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 2746*49db4272SNagarjuna Kristam 2747*49db4272SNagarjuna Kristam complete(&xudc->disconnect_complete); 2748*49db4272SNagarjuna Kristam } 2749*49db4272SNagarjuna Kristam 2750*49db4272SNagarjuna Kristam static void tegra_xudc_port_reset(struct tegra_xudc *xudc) 2751*49db4272SNagarjuna Kristam { 2752*49db4272SNagarjuna Kristam tegra_xudc_reset(xudc); 2753*49db4272SNagarjuna Kristam 2754*49db4272SNagarjuna Kristam if (xudc->driver) { 2755*49db4272SNagarjuna Kristam spin_unlock(&xudc->lock); 2756*49db4272SNagarjuna Kristam usb_gadget_udc_reset(&xudc->gadget, xudc->driver); 2757*49db4272SNagarjuna Kristam spin_lock(&xudc->lock); 2758*49db4272SNagarjuna Kristam } 2759*49db4272SNagarjuna Kristam 2760*49db4272SNagarjuna Kristam tegra_xudc_port_connect(xudc); 2761*49db4272SNagarjuna Kristam } 2762*49db4272SNagarjuna Kristam 2763*49db4272SNagarjuna Kristam static void tegra_xudc_port_suspend(struct tegra_xudc *xudc) 2764*49db4272SNagarjuna Kristam { 2765*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "port suspend\n"); 2766*49db4272SNagarjuna Kristam 2767*49db4272SNagarjuna Kristam xudc->resume_state = xudc->device_state; 2768*49db4272SNagarjuna Kristam xudc->device_state = USB_STATE_SUSPENDED; 2769*49db4272SNagarjuna Kristam usb_gadget_set_state(&xudc->gadget, xudc->device_state); 2770*49db4272SNagarjuna Kristam 2771*49db4272SNagarjuna Kristam if (xudc->driver->suspend) { 2772*49db4272SNagarjuna Kristam spin_unlock(&xudc->lock); 2773*49db4272SNagarjuna Kristam xudc->driver->suspend(&xudc->gadget); 2774*49db4272SNagarjuna Kristam spin_lock(&xudc->lock); 2775*49db4272SNagarjuna Kristam } 2776*49db4272SNagarjuna Kristam } 2777*49db4272SNagarjuna Kristam 2778*49db4272SNagarjuna Kristam static void tegra_xudc_port_resume(struct tegra_xudc *xudc) 2779*49db4272SNagarjuna Kristam { 2780*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "port resume\n"); 2781*49db4272SNagarjuna Kristam 2782*49db4272SNagarjuna Kristam tegra_xudc_resume_device_state(xudc); 2783*49db4272SNagarjuna Kristam 2784*49db4272SNagarjuna Kristam if (xudc->driver->resume) { 2785*49db4272SNagarjuna Kristam spin_unlock(&xudc->lock); 2786*49db4272SNagarjuna Kristam xudc->driver->resume(&xudc->gadget); 2787*49db4272SNagarjuna Kristam spin_lock(&xudc->lock); 2788*49db4272SNagarjuna Kristam } 2789*49db4272SNagarjuna Kristam } 2790*49db4272SNagarjuna Kristam 2791*49db4272SNagarjuna Kristam static inline void clear_port_change(struct tegra_xudc *xudc, u32 flag) 2792*49db4272SNagarjuna Kristam { 2793*49db4272SNagarjuna Kristam u32 val; 2794*49db4272SNagarjuna Kristam 2795*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTSC); 2796*49db4272SNagarjuna Kristam val &= ~PORTSC_CHANGE_MASK; 2797*49db4272SNagarjuna Kristam val |= flag; 2798*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTSC); 2799*49db4272SNagarjuna Kristam } 2800*49db4272SNagarjuna Kristam 2801*49db4272SNagarjuna Kristam static void __tegra_xudc_handle_port_status(struct tegra_xudc *xudc) 2802*49db4272SNagarjuna Kristam { 2803*49db4272SNagarjuna Kristam u32 portsc, porthalt; 2804*49db4272SNagarjuna Kristam 2805*49db4272SNagarjuna Kristam porthalt = xudc_readl(xudc, PORTHALT); 2806*49db4272SNagarjuna Kristam if ((porthalt & PORTHALT_STCHG_REQ) && 2807*49db4272SNagarjuna Kristam (porthalt & PORTHALT_HALT_LTSSM)) { 2808*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "STCHG_REQ, PORTHALT = %#x\n", porthalt); 2809*49db4272SNagarjuna Kristam porthalt &= ~PORTHALT_HALT_LTSSM; 2810*49db4272SNagarjuna Kristam xudc_writel(xudc, porthalt, PORTHALT); 2811*49db4272SNagarjuna Kristam } 2812*49db4272SNagarjuna Kristam 2813*49db4272SNagarjuna Kristam portsc = xudc_readl(xudc, PORTSC); 2814*49db4272SNagarjuna Kristam if ((portsc & PORTSC_PRC) && (portsc & PORTSC_PR)) { 2815*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "PRC, PR, PORTSC = %#x\n", portsc); 2816*49db4272SNagarjuna Kristam clear_port_change(xudc, PORTSC_PRC | PORTSC_PED); 2817*49db4272SNagarjuna Kristam #define TOGGLE_VBUS_WAIT_MS 100 2818*49db4272SNagarjuna Kristam if (xudc->soc->port_reset_quirk) { 2819*49db4272SNagarjuna Kristam schedule_delayed_work(&xudc->port_reset_war_work, 2820*49db4272SNagarjuna Kristam msecs_to_jiffies(TOGGLE_VBUS_WAIT_MS)); 2821*49db4272SNagarjuna Kristam xudc->wait_for_sec_prc = 1; 2822*49db4272SNagarjuna Kristam } 2823*49db4272SNagarjuna Kristam } 2824*49db4272SNagarjuna Kristam 2825*49db4272SNagarjuna Kristam if ((portsc & PORTSC_PRC) && !(portsc & PORTSC_PR)) { 2826*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "PRC, Not PR, PORTSC = %#x\n", portsc); 2827*49db4272SNagarjuna Kristam clear_port_change(xudc, PORTSC_PRC | PORTSC_PED); 2828*49db4272SNagarjuna Kristam tegra_xudc_port_reset(xudc); 2829*49db4272SNagarjuna Kristam cancel_delayed_work(&xudc->port_reset_war_work); 2830*49db4272SNagarjuna Kristam xudc->wait_for_sec_prc = 0; 2831*49db4272SNagarjuna Kristam } 2832*49db4272SNagarjuna Kristam 2833*49db4272SNagarjuna Kristam portsc = xudc_readl(xudc, PORTSC); 2834*49db4272SNagarjuna Kristam if (portsc & PORTSC_WRC) { 2835*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "WRC, PORTSC = %#x\n", portsc); 2836*49db4272SNagarjuna Kristam clear_port_change(xudc, PORTSC_WRC | PORTSC_PED); 2837*49db4272SNagarjuna Kristam if (!(xudc_readl(xudc, PORTSC) & PORTSC_WPR)) 2838*49db4272SNagarjuna Kristam tegra_xudc_port_reset(xudc); 2839*49db4272SNagarjuna Kristam } 2840*49db4272SNagarjuna Kristam 2841*49db4272SNagarjuna Kristam portsc = xudc_readl(xudc, PORTSC); 2842*49db4272SNagarjuna Kristam if (portsc & PORTSC_CSC) { 2843*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "CSC, PORTSC = %#x\n", portsc); 2844*49db4272SNagarjuna Kristam clear_port_change(xudc, PORTSC_CSC); 2845*49db4272SNagarjuna Kristam 2846*49db4272SNagarjuna Kristam if (portsc & PORTSC_CCS) 2847*49db4272SNagarjuna Kristam tegra_xudc_port_connect(xudc); 2848*49db4272SNagarjuna Kristam else 2849*49db4272SNagarjuna Kristam tegra_xudc_port_disconnect(xudc); 2850*49db4272SNagarjuna Kristam 2851*49db4272SNagarjuna Kristam if (xudc->wait_csc) { 2852*49db4272SNagarjuna Kristam cancel_delayed_work(&xudc->plc_reset_work); 2853*49db4272SNagarjuna Kristam xudc->wait_csc = false; 2854*49db4272SNagarjuna Kristam } 2855*49db4272SNagarjuna Kristam } 2856*49db4272SNagarjuna Kristam 2857*49db4272SNagarjuna Kristam portsc = xudc_readl(xudc, PORTSC); 2858*49db4272SNagarjuna Kristam if (portsc & PORTSC_PLC) { 2859*49db4272SNagarjuna Kristam u32 pls = (portsc & PORTSC_PLS_MASK) >> PORTSC_PLS_SHIFT; 2860*49db4272SNagarjuna Kristam 2861*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "PLC, PORTSC = %#x\n", portsc); 2862*49db4272SNagarjuna Kristam clear_port_change(xudc, PORTSC_PLC); 2863*49db4272SNagarjuna Kristam switch (pls) { 2864*49db4272SNagarjuna Kristam case PORTSC_PLS_U3: 2865*49db4272SNagarjuna Kristam tegra_xudc_port_suspend(xudc); 2866*49db4272SNagarjuna Kristam break; 2867*49db4272SNagarjuna Kristam case PORTSC_PLS_U0: 2868*49db4272SNagarjuna Kristam if (xudc->gadget.speed < USB_SPEED_SUPER) 2869*49db4272SNagarjuna Kristam tegra_xudc_port_resume(xudc); 2870*49db4272SNagarjuna Kristam break; 2871*49db4272SNagarjuna Kristam case PORTSC_PLS_RESUME: 2872*49db4272SNagarjuna Kristam if (xudc->gadget.speed == USB_SPEED_SUPER) 2873*49db4272SNagarjuna Kristam tegra_xudc_port_resume(xudc); 2874*49db4272SNagarjuna Kristam break; 2875*49db4272SNagarjuna Kristam case PORTSC_PLS_INACTIVE: 2876*49db4272SNagarjuna Kristam schedule_delayed_work(&xudc->plc_reset_work, 2877*49db4272SNagarjuna Kristam msecs_to_jiffies(TOGGLE_VBUS_WAIT_MS)); 2878*49db4272SNagarjuna Kristam xudc->wait_csc = true; 2879*49db4272SNagarjuna Kristam break; 2880*49db4272SNagarjuna Kristam default: 2881*49db4272SNagarjuna Kristam break; 2882*49db4272SNagarjuna Kristam } 2883*49db4272SNagarjuna Kristam } 2884*49db4272SNagarjuna Kristam 2885*49db4272SNagarjuna Kristam if (portsc & PORTSC_CEC) { 2886*49db4272SNagarjuna Kristam dev_warn(xudc->dev, "CEC, PORTSC = %#x\n", portsc); 2887*49db4272SNagarjuna Kristam clear_port_change(xudc, PORTSC_CEC); 2888*49db4272SNagarjuna Kristam } 2889*49db4272SNagarjuna Kristam 2890*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "PORTSC = %#x\n", xudc_readl(xudc, PORTSC)); 2891*49db4272SNagarjuna Kristam } 2892*49db4272SNagarjuna Kristam 2893*49db4272SNagarjuna Kristam static void tegra_xudc_handle_port_status(struct tegra_xudc *xudc) 2894*49db4272SNagarjuna Kristam { 2895*49db4272SNagarjuna Kristam while ((xudc_readl(xudc, PORTSC) & PORTSC_CHANGE_MASK) || 2896*49db4272SNagarjuna Kristam (xudc_readl(xudc, PORTHALT) & PORTHALT_STCHG_REQ)) 2897*49db4272SNagarjuna Kristam __tegra_xudc_handle_port_status(xudc); 2898*49db4272SNagarjuna Kristam } 2899*49db4272SNagarjuna Kristam 2900*49db4272SNagarjuna Kristam static void tegra_xudc_handle_event(struct tegra_xudc *xudc, 2901*49db4272SNagarjuna Kristam struct tegra_xudc_trb *event) 2902*49db4272SNagarjuna Kristam { 2903*49db4272SNagarjuna Kristam u32 type = trb_read_type(event); 2904*49db4272SNagarjuna Kristam 2905*49db4272SNagarjuna Kristam dump_trb(xudc, "EVENT", event); 2906*49db4272SNagarjuna Kristam 2907*49db4272SNagarjuna Kristam switch (type) { 2908*49db4272SNagarjuna Kristam case TRB_TYPE_PORT_STATUS_CHANGE_EVENT: 2909*49db4272SNagarjuna Kristam tegra_xudc_handle_port_status(xudc); 2910*49db4272SNagarjuna Kristam break; 2911*49db4272SNagarjuna Kristam case TRB_TYPE_TRANSFER_EVENT: 2912*49db4272SNagarjuna Kristam tegra_xudc_handle_transfer_event(xudc, event); 2913*49db4272SNagarjuna Kristam break; 2914*49db4272SNagarjuna Kristam case TRB_TYPE_SETUP_PACKET_EVENT: 2915*49db4272SNagarjuna Kristam tegra_xudc_handle_ep0_event(xudc, event); 2916*49db4272SNagarjuna Kristam break; 2917*49db4272SNagarjuna Kristam default: 2918*49db4272SNagarjuna Kristam dev_info(xudc->dev, "Unrecognized TRB type = %#x\n", type); 2919*49db4272SNagarjuna Kristam break; 2920*49db4272SNagarjuna Kristam } 2921*49db4272SNagarjuna Kristam } 2922*49db4272SNagarjuna Kristam 2923*49db4272SNagarjuna Kristam static void tegra_xudc_process_event_ring(struct tegra_xudc *xudc) 2924*49db4272SNagarjuna Kristam { 2925*49db4272SNagarjuna Kristam struct tegra_xudc_trb *event; 2926*49db4272SNagarjuna Kristam dma_addr_t erdp; 2927*49db4272SNagarjuna Kristam 2928*49db4272SNagarjuna Kristam while (true) { 2929*49db4272SNagarjuna Kristam event = xudc->event_ring[xudc->event_ring_index] + 2930*49db4272SNagarjuna Kristam xudc->event_ring_deq_ptr; 2931*49db4272SNagarjuna Kristam 2932*49db4272SNagarjuna Kristam if (trb_read_cycle(event) != xudc->ccs) 2933*49db4272SNagarjuna Kristam break; 2934*49db4272SNagarjuna Kristam 2935*49db4272SNagarjuna Kristam tegra_xudc_handle_event(xudc, event); 2936*49db4272SNagarjuna Kristam 2937*49db4272SNagarjuna Kristam xudc->event_ring_deq_ptr++; 2938*49db4272SNagarjuna Kristam if (xudc->event_ring_deq_ptr == XUDC_EVENT_RING_SIZE) { 2939*49db4272SNagarjuna Kristam xudc->event_ring_deq_ptr = 0; 2940*49db4272SNagarjuna Kristam xudc->event_ring_index++; 2941*49db4272SNagarjuna Kristam } 2942*49db4272SNagarjuna Kristam 2943*49db4272SNagarjuna Kristam if (xudc->event_ring_index == XUDC_NR_EVENT_RINGS) { 2944*49db4272SNagarjuna Kristam xudc->event_ring_index = 0; 2945*49db4272SNagarjuna Kristam xudc->ccs = !xudc->ccs; 2946*49db4272SNagarjuna Kristam } 2947*49db4272SNagarjuna Kristam } 2948*49db4272SNagarjuna Kristam 2949*49db4272SNagarjuna Kristam erdp = xudc->event_ring_phys[xudc->event_ring_index] + 2950*49db4272SNagarjuna Kristam xudc->event_ring_deq_ptr * sizeof(*event); 2951*49db4272SNagarjuna Kristam 2952*49db4272SNagarjuna Kristam xudc_writel(xudc, upper_32_bits(erdp), ERDPHI); 2953*49db4272SNagarjuna Kristam xudc_writel(xudc, lower_32_bits(erdp) | ERDPLO_EHB, ERDPLO); 2954*49db4272SNagarjuna Kristam } 2955*49db4272SNagarjuna Kristam 2956*49db4272SNagarjuna Kristam static irqreturn_t tegra_xudc_irq(int irq, void *data) 2957*49db4272SNagarjuna Kristam { 2958*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = data; 2959*49db4272SNagarjuna Kristam unsigned long flags; 2960*49db4272SNagarjuna Kristam u32 val; 2961*49db4272SNagarjuna Kristam 2962*49db4272SNagarjuna Kristam val = xudc_readl(xudc, ST); 2963*49db4272SNagarjuna Kristam if (!(val & ST_IP)) 2964*49db4272SNagarjuna Kristam return IRQ_NONE; 2965*49db4272SNagarjuna Kristam xudc_writel(xudc, ST_IP, ST); 2966*49db4272SNagarjuna Kristam 2967*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 2968*49db4272SNagarjuna Kristam tegra_xudc_process_event_ring(xudc); 2969*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 2970*49db4272SNagarjuna Kristam 2971*49db4272SNagarjuna Kristam return IRQ_HANDLED; 2972*49db4272SNagarjuna Kristam } 2973*49db4272SNagarjuna Kristam 2974*49db4272SNagarjuna Kristam static int tegra_xudc_alloc_ep(struct tegra_xudc *xudc, unsigned int index) 2975*49db4272SNagarjuna Kristam { 2976*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep = &xudc->ep[index]; 2977*49db4272SNagarjuna Kristam 2978*49db4272SNagarjuna Kristam ep->xudc = xudc; 2979*49db4272SNagarjuna Kristam ep->index = index; 2980*49db4272SNagarjuna Kristam ep->context = &xudc->ep_context[index]; 2981*49db4272SNagarjuna Kristam INIT_LIST_HEAD(&ep->queue); 2982*49db4272SNagarjuna Kristam 2983*49db4272SNagarjuna Kristam /* 2984*49db4272SNagarjuna Kristam * EP1 would be the input endpoint corresponding to EP0, but since 2985*49db4272SNagarjuna Kristam * EP0 is bi-directional, EP1 is unused. 2986*49db4272SNagarjuna Kristam */ 2987*49db4272SNagarjuna Kristam if (index == 1) 2988*49db4272SNagarjuna Kristam return 0; 2989*49db4272SNagarjuna Kristam 2990*49db4272SNagarjuna Kristam ep->transfer_ring = dma_pool_alloc(xudc->transfer_ring_pool, 2991*49db4272SNagarjuna Kristam GFP_KERNEL, 2992*49db4272SNagarjuna Kristam &ep->transfer_ring_phys); 2993*49db4272SNagarjuna Kristam if (!ep->transfer_ring) 2994*49db4272SNagarjuna Kristam return -ENOMEM; 2995*49db4272SNagarjuna Kristam 2996*49db4272SNagarjuna Kristam if (index) { 2997*49db4272SNagarjuna Kristam snprintf(ep->name, sizeof(ep->name), "ep%u%s", index / 2, 2998*49db4272SNagarjuna Kristam (index % 2 == 0) ? "out" : "in"); 2999*49db4272SNagarjuna Kristam ep->usb_ep.name = ep->name; 3000*49db4272SNagarjuna Kristam usb_ep_set_maxpacket_limit(&ep->usb_ep, 1024); 3001*49db4272SNagarjuna Kristam ep->usb_ep.max_streams = 16; 3002*49db4272SNagarjuna Kristam ep->usb_ep.ops = &tegra_xudc_ep_ops; 3003*49db4272SNagarjuna Kristam ep->usb_ep.caps.type_bulk = true; 3004*49db4272SNagarjuna Kristam ep->usb_ep.caps.type_int = true; 3005*49db4272SNagarjuna Kristam if (index & 1) 3006*49db4272SNagarjuna Kristam ep->usb_ep.caps.dir_in = true; 3007*49db4272SNagarjuna Kristam else 3008*49db4272SNagarjuna Kristam ep->usb_ep.caps.dir_out = true; 3009*49db4272SNagarjuna Kristam list_add_tail(&ep->usb_ep.ep_list, &xudc->gadget.ep_list); 3010*49db4272SNagarjuna Kristam } else { 3011*49db4272SNagarjuna Kristam strscpy(ep->name, "ep0", 3); 3012*49db4272SNagarjuna Kristam ep->usb_ep.name = ep->name; 3013*49db4272SNagarjuna Kristam usb_ep_set_maxpacket_limit(&ep->usb_ep, 512); 3014*49db4272SNagarjuna Kristam ep->usb_ep.ops = &tegra_xudc_ep0_ops; 3015*49db4272SNagarjuna Kristam ep->usb_ep.caps.type_control = true; 3016*49db4272SNagarjuna Kristam ep->usb_ep.caps.dir_in = true; 3017*49db4272SNagarjuna Kristam ep->usb_ep.caps.dir_out = true; 3018*49db4272SNagarjuna Kristam } 3019*49db4272SNagarjuna Kristam 3020*49db4272SNagarjuna Kristam return 0; 3021*49db4272SNagarjuna Kristam } 3022*49db4272SNagarjuna Kristam 3023*49db4272SNagarjuna Kristam static void tegra_xudc_free_ep(struct tegra_xudc *xudc, unsigned int index) 3024*49db4272SNagarjuna Kristam { 3025*49db4272SNagarjuna Kristam struct tegra_xudc_ep *ep = &xudc->ep[index]; 3026*49db4272SNagarjuna Kristam 3027*49db4272SNagarjuna Kristam /* 3028*49db4272SNagarjuna Kristam * EP1 would be the input endpoint corresponding to EP0, but since 3029*49db4272SNagarjuna Kristam * EP0 is bi-directional, EP1 is unused. 3030*49db4272SNagarjuna Kristam */ 3031*49db4272SNagarjuna Kristam if (index == 1) 3032*49db4272SNagarjuna Kristam return; 3033*49db4272SNagarjuna Kristam 3034*49db4272SNagarjuna Kristam dma_pool_free(xudc->transfer_ring_pool, ep->transfer_ring, 3035*49db4272SNagarjuna Kristam ep->transfer_ring_phys); 3036*49db4272SNagarjuna Kristam } 3037*49db4272SNagarjuna Kristam 3038*49db4272SNagarjuna Kristam static int tegra_xudc_alloc_eps(struct tegra_xudc *xudc) 3039*49db4272SNagarjuna Kristam { 3040*49db4272SNagarjuna Kristam struct usb_request *req; 3041*49db4272SNagarjuna Kristam unsigned int i; 3042*49db4272SNagarjuna Kristam int err; 3043*49db4272SNagarjuna Kristam 3044*49db4272SNagarjuna Kristam xudc->ep_context = 3045*49db4272SNagarjuna Kristam dma_alloc_coherent(xudc->dev, XUDC_NR_EPS * 3046*49db4272SNagarjuna Kristam sizeof(*xudc->ep_context), 3047*49db4272SNagarjuna Kristam &xudc->ep_context_phys, GFP_KERNEL); 3048*49db4272SNagarjuna Kristam if (!xudc->ep_context) 3049*49db4272SNagarjuna Kristam return -ENOMEM; 3050*49db4272SNagarjuna Kristam 3051*49db4272SNagarjuna Kristam xudc->transfer_ring_pool = 3052*49db4272SNagarjuna Kristam dmam_pool_create(dev_name(xudc->dev), xudc->dev, 3053*49db4272SNagarjuna Kristam XUDC_TRANSFER_RING_SIZE * 3054*49db4272SNagarjuna Kristam sizeof(struct tegra_xudc_trb), 3055*49db4272SNagarjuna Kristam sizeof(struct tegra_xudc_trb), 0); 3056*49db4272SNagarjuna Kristam if (!xudc->transfer_ring_pool) { 3057*49db4272SNagarjuna Kristam err = -ENOMEM; 3058*49db4272SNagarjuna Kristam goto free_ep_context; 3059*49db4272SNagarjuna Kristam } 3060*49db4272SNagarjuna Kristam 3061*49db4272SNagarjuna Kristam INIT_LIST_HEAD(&xudc->gadget.ep_list); 3062*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->ep); i++) { 3063*49db4272SNagarjuna Kristam err = tegra_xudc_alloc_ep(xudc, i); 3064*49db4272SNagarjuna Kristam if (err < 0) 3065*49db4272SNagarjuna Kristam goto free_eps; 3066*49db4272SNagarjuna Kristam } 3067*49db4272SNagarjuna Kristam 3068*49db4272SNagarjuna Kristam req = tegra_xudc_ep_alloc_request(&xudc->ep[0].usb_ep, GFP_KERNEL); 3069*49db4272SNagarjuna Kristam if (!req) { 3070*49db4272SNagarjuna Kristam err = -ENOMEM; 3071*49db4272SNagarjuna Kristam goto free_eps; 3072*49db4272SNagarjuna Kristam } 3073*49db4272SNagarjuna Kristam xudc->ep0_req = to_xudc_req(req); 3074*49db4272SNagarjuna Kristam 3075*49db4272SNagarjuna Kristam return 0; 3076*49db4272SNagarjuna Kristam 3077*49db4272SNagarjuna Kristam free_eps: 3078*49db4272SNagarjuna Kristam for (; i > 0; i--) 3079*49db4272SNagarjuna Kristam tegra_xudc_free_ep(xudc, i - 1); 3080*49db4272SNagarjuna Kristam free_ep_context: 3081*49db4272SNagarjuna Kristam dma_free_coherent(xudc->dev, XUDC_NR_EPS * sizeof(*xudc->ep_context), 3082*49db4272SNagarjuna Kristam xudc->ep_context, xudc->ep_context_phys); 3083*49db4272SNagarjuna Kristam return err; 3084*49db4272SNagarjuna Kristam } 3085*49db4272SNagarjuna Kristam 3086*49db4272SNagarjuna Kristam static void tegra_xudc_init_eps(struct tegra_xudc *xudc) 3087*49db4272SNagarjuna Kristam { 3088*49db4272SNagarjuna Kristam xudc_writel(xudc, lower_32_bits(xudc->ep_context_phys), ECPLO); 3089*49db4272SNagarjuna Kristam xudc_writel(xudc, upper_32_bits(xudc->ep_context_phys), ECPHI); 3090*49db4272SNagarjuna Kristam } 3091*49db4272SNagarjuna Kristam 3092*49db4272SNagarjuna Kristam static void tegra_xudc_free_eps(struct tegra_xudc *xudc) 3093*49db4272SNagarjuna Kristam { 3094*49db4272SNagarjuna Kristam unsigned int i; 3095*49db4272SNagarjuna Kristam 3096*49db4272SNagarjuna Kristam tegra_xudc_ep_free_request(&xudc->ep[0].usb_ep, 3097*49db4272SNagarjuna Kristam &xudc->ep0_req->usb_req); 3098*49db4272SNagarjuna Kristam 3099*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->ep); i++) 3100*49db4272SNagarjuna Kristam tegra_xudc_free_ep(xudc, i); 3101*49db4272SNagarjuna Kristam 3102*49db4272SNagarjuna Kristam dma_free_coherent(xudc->dev, XUDC_NR_EPS * sizeof(*xudc->ep_context), 3103*49db4272SNagarjuna Kristam xudc->ep_context, xudc->ep_context_phys); 3104*49db4272SNagarjuna Kristam } 3105*49db4272SNagarjuna Kristam 3106*49db4272SNagarjuna Kristam static int tegra_xudc_alloc_event_ring(struct tegra_xudc *xudc) 3107*49db4272SNagarjuna Kristam { 3108*49db4272SNagarjuna Kristam unsigned int i; 3109*49db4272SNagarjuna Kristam 3110*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->event_ring); i++) { 3111*49db4272SNagarjuna Kristam xudc->event_ring[i] = 3112*49db4272SNagarjuna Kristam dma_alloc_coherent(xudc->dev, XUDC_EVENT_RING_SIZE * 3113*49db4272SNagarjuna Kristam sizeof(*xudc->event_ring[i]), 3114*49db4272SNagarjuna Kristam &xudc->event_ring_phys[i], 3115*49db4272SNagarjuna Kristam GFP_KERNEL); 3116*49db4272SNagarjuna Kristam if (!xudc->event_ring[i]) 3117*49db4272SNagarjuna Kristam goto free_dma; 3118*49db4272SNagarjuna Kristam } 3119*49db4272SNagarjuna Kristam 3120*49db4272SNagarjuna Kristam return 0; 3121*49db4272SNagarjuna Kristam 3122*49db4272SNagarjuna Kristam free_dma: 3123*49db4272SNagarjuna Kristam for (; i > 0; i--) { 3124*49db4272SNagarjuna Kristam dma_free_coherent(xudc->dev, XUDC_EVENT_RING_SIZE * 3125*49db4272SNagarjuna Kristam sizeof(*xudc->event_ring[i - 1]), 3126*49db4272SNagarjuna Kristam xudc->event_ring[i - 1], 3127*49db4272SNagarjuna Kristam xudc->event_ring_phys[i - 1]); 3128*49db4272SNagarjuna Kristam } 3129*49db4272SNagarjuna Kristam return -ENOMEM; 3130*49db4272SNagarjuna Kristam } 3131*49db4272SNagarjuna Kristam 3132*49db4272SNagarjuna Kristam static void tegra_xudc_init_event_ring(struct tegra_xudc *xudc) 3133*49db4272SNagarjuna Kristam { 3134*49db4272SNagarjuna Kristam unsigned int i; 3135*49db4272SNagarjuna Kristam u32 val; 3136*49db4272SNagarjuna Kristam 3137*49db4272SNagarjuna Kristam val = xudc_readl(xudc, SPARAM); 3138*49db4272SNagarjuna Kristam val &= ~(SPARAM_ERSTMAX_MASK); 3139*49db4272SNagarjuna Kristam val |= SPARAM_ERSTMAX(XUDC_NR_EVENT_RINGS); 3140*49db4272SNagarjuna Kristam xudc_writel(xudc, val, SPARAM); 3141*49db4272SNagarjuna Kristam 3142*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->event_ring); i++) { 3143*49db4272SNagarjuna Kristam memset(xudc->event_ring[i], 0, XUDC_EVENT_RING_SIZE * 3144*49db4272SNagarjuna Kristam sizeof(*xudc->event_ring[i])); 3145*49db4272SNagarjuna Kristam 3146*49db4272SNagarjuna Kristam val = xudc_readl(xudc, ERSTSZ); 3147*49db4272SNagarjuna Kristam val &= ~(ERSTSZ_ERSTXSZ_MASK << ERSTSZ_ERSTXSZ_SHIFT(i)); 3148*49db4272SNagarjuna Kristam val |= XUDC_EVENT_RING_SIZE << ERSTSZ_ERSTXSZ_SHIFT(i); 3149*49db4272SNagarjuna Kristam xudc_writel(xudc, val, ERSTSZ); 3150*49db4272SNagarjuna Kristam 3151*49db4272SNagarjuna Kristam xudc_writel(xudc, lower_32_bits(xudc->event_ring_phys[i]), 3152*49db4272SNagarjuna Kristam ERSTXBALO(i)); 3153*49db4272SNagarjuna Kristam xudc_writel(xudc, upper_32_bits(xudc->event_ring_phys[i]), 3154*49db4272SNagarjuna Kristam ERSTXBAHI(i)); 3155*49db4272SNagarjuna Kristam } 3156*49db4272SNagarjuna Kristam 3157*49db4272SNagarjuna Kristam val = lower_32_bits(xudc->event_ring_phys[0]); 3158*49db4272SNagarjuna Kristam xudc_writel(xudc, val, ERDPLO); 3159*49db4272SNagarjuna Kristam val |= EREPLO_ECS; 3160*49db4272SNagarjuna Kristam xudc_writel(xudc, val, EREPLO); 3161*49db4272SNagarjuna Kristam 3162*49db4272SNagarjuna Kristam val = upper_32_bits(xudc->event_ring_phys[0]); 3163*49db4272SNagarjuna Kristam xudc_writel(xudc, val, ERDPHI); 3164*49db4272SNagarjuna Kristam xudc_writel(xudc, val, EREPHI); 3165*49db4272SNagarjuna Kristam 3166*49db4272SNagarjuna Kristam xudc->ccs = true; 3167*49db4272SNagarjuna Kristam xudc->event_ring_index = 0; 3168*49db4272SNagarjuna Kristam xudc->event_ring_deq_ptr = 0; 3169*49db4272SNagarjuna Kristam } 3170*49db4272SNagarjuna Kristam 3171*49db4272SNagarjuna Kristam static void tegra_xudc_free_event_ring(struct tegra_xudc *xudc) 3172*49db4272SNagarjuna Kristam { 3173*49db4272SNagarjuna Kristam unsigned int i; 3174*49db4272SNagarjuna Kristam 3175*49db4272SNagarjuna Kristam for (i = 0; i < ARRAY_SIZE(xudc->event_ring); i++) { 3176*49db4272SNagarjuna Kristam dma_free_coherent(xudc->dev, XUDC_EVENT_RING_SIZE * 3177*49db4272SNagarjuna Kristam sizeof(*xudc->event_ring[i]), 3178*49db4272SNagarjuna Kristam xudc->event_ring[i], 3179*49db4272SNagarjuna Kristam xudc->event_ring_phys[i]); 3180*49db4272SNagarjuna Kristam } 3181*49db4272SNagarjuna Kristam } 3182*49db4272SNagarjuna Kristam 3183*49db4272SNagarjuna Kristam static void tegra_xudc_fpci_ipfs_init(struct tegra_xudc *xudc) 3184*49db4272SNagarjuna Kristam { 3185*49db4272SNagarjuna Kristam u32 val; 3186*49db4272SNagarjuna Kristam 3187*49db4272SNagarjuna Kristam if (xudc->soc->has_ipfs) { 3188*49db4272SNagarjuna Kristam val = ipfs_readl(xudc, XUSB_DEV_CONFIGURATION_0); 3189*49db4272SNagarjuna Kristam val |= XUSB_DEV_CONFIGURATION_0_EN_FPCI; 3190*49db4272SNagarjuna Kristam ipfs_writel(xudc, val, XUSB_DEV_CONFIGURATION_0); 3191*49db4272SNagarjuna Kristam usleep_range(10, 15); 3192*49db4272SNagarjuna Kristam } 3193*49db4272SNagarjuna Kristam 3194*49db4272SNagarjuna Kristam /* Enable bus master */ 3195*49db4272SNagarjuna Kristam val = XUSB_DEV_CFG_1_IO_SPACE_EN | XUSB_DEV_CFG_1_MEMORY_SPACE_EN | 3196*49db4272SNagarjuna Kristam XUSB_DEV_CFG_1_BUS_MASTER_EN; 3197*49db4272SNagarjuna Kristam fpci_writel(xudc, val, XUSB_DEV_CFG_1); 3198*49db4272SNagarjuna Kristam 3199*49db4272SNagarjuna Kristam /* Program BAR0 space */ 3200*49db4272SNagarjuna Kristam val = fpci_readl(xudc, XUSB_DEV_CFG_4); 3201*49db4272SNagarjuna Kristam val &= ~(XUSB_DEV_CFG_4_BASE_ADDR_MASK); 3202*49db4272SNagarjuna Kristam val |= xudc->phys_base & (XUSB_DEV_CFG_4_BASE_ADDR_MASK); 3203*49db4272SNagarjuna Kristam 3204*49db4272SNagarjuna Kristam fpci_writel(xudc, val, XUSB_DEV_CFG_4); 3205*49db4272SNagarjuna Kristam fpci_writel(xudc, upper_32_bits(xudc->phys_base), XUSB_DEV_CFG_5); 3206*49db4272SNagarjuna Kristam 3207*49db4272SNagarjuna Kristam usleep_range(100, 200); 3208*49db4272SNagarjuna Kristam 3209*49db4272SNagarjuna Kristam if (xudc->soc->has_ipfs) { 3210*49db4272SNagarjuna Kristam /* Enable interrupt assertion */ 3211*49db4272SNagarjuna Kristam val = ipfs_readl(xudc, XUSB_DEV_INTR_MASK_0); 3212*49db4272SNagarjuna Kristam val |= XUSB_DEV_INTR_MASK_0_IP_INT_MASK; 3213*49db4272SNagarjuna Kristam ipfs_writel(xudc, val, XUSB_DEV_INTR_MASK_0); 3214*49db4272SNagarjuna Kristam } 3215*49db4272SNagarjuna Kristam } 3216*49db4272SNagarjuna Kristam 3217*49db4272SNagarjuna Kristam static void tegra_xudc_device_params_init(struct tegra_xudc *xudc) 3218*49db4272SNagarjuna Kristam { 3219*49db4272SNagarjuna Kristam u32 val, imod; 3220*49db4272SNagarjuna Kristam 3221*49db4272SNagarjuna Kristam if (xudc->soc->has_ipfs) { 3222*49db4272SNagarjuna Kristam val = xudc_readl(xudc, BLCG); 3223*49db4272SNagarjuna Kristam val |= BLCG_ALL; 3224*49db4272SNagarjuna Kristam val &= ~(BLCG_DFPCI | BLCG_UFPCI | BLCG_FE | 3225*49db4272SNagarjuna Kristam BLCG_COREPLL_PWRDN); 3226*49db4272SNagarjuna Kristam val |= BLCG_IOPLL_0_PWRDN; 3227*49db4272SNagarjuna Kristam val |= BLCG_IOPLL_1_PWRDN; 3228*49db4272SNagarjuna Kristam val |= BLCG_IOPLL_2_PWRDN; 3229*49db4272SNagarjuna Kristam 3230*49db4272SNagarjuna Kristam xudc_writel(xudc, val, BLCG); 3231*49db4272SNagarjuna Kristam } 3232*49db4272SNagarjuna Kristam 3233*49db4272SNagarjuna Kristam /* Set a reasonable U3 exit timer value. */ 3234*49db4272SNagarjuna Kristam val = xudc_readl(xudc, SSPX_CORE_PADCTL4); 3235*49db4272SNagarjuna Kristam val &= ~(SSPX_CORE_PADCTL4_RXDAT_VLD_TIMEOUT_U3_MASK); 3236*49db4272SNagarjuna Kristam val |= SSPX_CORE_PADCTL4_RXDAT_VLD_TIMEOUT_U3(0x5dc0); 3237*49db4272SNagarjuna Kristam xudc_writel(xudc, val, SSPX_CORE_PADCTL4); 3238*49db4272SNagarjuna Kristam 3239*49db4272SNagarjuna Kristam /* Default ping LFPS tBurst is too large. */ 3240*49db4272SNagarjuna Kristam val = xudc_readl(xudc, SSPX_CORE_CNT0); 3241*49db4272SNagarjuna Kristam val &= ~(SSPX_CORE_CNT0_PING_TBURST_MASK); 3242*49db4272SNagarjuna Kristam val |= SSPX_CORE_CNT0_PING_TBURST(0xa); 3243*49db4272SNagarjuna Kristam xudc_writel(xudc, val, SSPX_CORE_CNT0); 3244*49db4272SNagarjuna Kristam 3245*49db4272SNagarjuna Kristam /* Default tPortConfiguration timeout is too small. */ 3246*49db4272SNagarjuna Kristam val = xudc_readl(xudc, SSPX_CORE_CNT30); 3247*49db4272SNagarjuna Kristam val &= ~(SSPX_CORE_CNT30_LMPITP_TIMER_MASK); 3248*49db4272SNagarjuna Kristam val |= SSPX_CORE_CNT30_LMPITP_TIMER(0x978); 3249*49db4272SNagarjuna Kristam xudc_writel(xudc, val, SSPX_CORE_CNT30); 3250*49db4272SNagarjuna Kristam 3251*49db4272SNagarjuna Kristam if (xudc->soc->lpm_enable) { 3252*49db4272SNagarjuna Kristam /* Set L1 resume duration to 95 us. */ 3253*49db4272SNagarjuna Kristam val = xudc_readl(xudc, HSFSPI_COUNT13); 3254*49db4272SNagarjuna Kristam val &= ~(HSFSPI_COUNT13_U2_RESUME_K_DURATION_MASK); 3255*49db4272SNagarjuna Kristam val |= HSFSPI_COUNT13_U2_RESUME_K_DURATION(0x2c88); 3256*49db4272SNagarjuna Kristam xudc_writel(xudc, val, HSFSPI_COUNT13); 3257*49db4272SNagarjuna Kristam } 3258*49db4272SNagarjuna Kristam 3259*49db4272SNagarjuna Kristam /* 3260*49db4272SNagarjuna Kristam * Compliacne suite appears to be violating polling LFPS tBurst max 3261*49db4272SNagarjuna Kristam * of 1.4us. Send 1.45us instead. 3262*49db4272SNagarjuna Kristam */ 3263*49db4272SNagarjuna Kristam val = xudc_readl(xudc, SSPX_CORE_CNT32); 3264*49db4272SNagarjuna Kristam val &= ~(SSPX_CORE_CNT32_POLL_TBURST_MAX_MASK); 3265*49db4272SNagarjuna Kristam val |= SSPX_CORE_CNT32_POLL_TBURST_MAX(0xb0); 3266*49db4272SNagarjuna Kristam xudc_writel(xudc, val, SSPX_CORE_CNT32); 3267*49db4272SNagarjuna Kristam 3268*49db4272SNagarjuna Kristam /* Direct HS/FS port instance to RxDetect. */ 3269*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CFG_DEV_FE); 3270*49db4272SNagarjuna Kristam val &= ~(CFG_DEV_FE_PORTREGSEL_MASK); 3271*49db4272SNagarjuna Kristam val |= CFG_DEV_FE_PORTREGSEL(CFG_DEV_FE_PORTREGSEL_HSFS_PI); 3272*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CFG_DEV_FE); 3273*49db4272SNagarjuna Kristam 3274*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTSC); 3275*49db4272SNagarjuna Kristam val &= ~(PORTSC_CHANGE_MASK | PORTSC_PLS_MASK); 3276*49db4272SNagarjuna Kristam val |= PORTSC_LWS | PORTSC_PLS(PORTSC_PLS_RXDETECT); 3277*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTSC); 3278*49db4272SNagarjuna Kristam 3279*49db4272SNagarjuna Kristam /* Direct SS port instance to RxDetect. */ 3280*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CFG_DEV_FE); 3281*49db4272SNagarjuna Kristam val &= ~(CFG_DEV_FE_PORTREGSEL_MASK); 3282*49db4272SNagarjuna Kristam val |= CFG_DEV_FE_PORTREGSEL_SS_PI & CFG_DEV_FE_PORTREGSEL_MASK; 3283*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CFG_DEV_FE); 3284*49db4272SNagarjuna Kristam 3285*49db4272SNagarjuna Kristam val = xudc_readl(xudc, PORTSC); 3286*49db4272SNagarjuna Kristam val &= ~(PORTSC_CHANGE_MASK | PORTSC_PLS_MASK); 3287*49db4272SNagarjuna Kristam val |= PORTSC_LWS | PORTSC_PLS(PORTSC_PLS_RXDETECT); 3288*49db4272SNagarjuna Kristam xudc_writel(xudc, val, PORTSC); 3289*49db4272SNagarjuna Kristam 3290*49db4272SNagarjuna Kristam /* Restore port instance. */ 3291*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CFG_DEV_FE); 3292*49db4272SNagarjuna Kristam val &= ~(CFG_DEV_FE_PORTREGSEL_MASK); 3293*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CFG_DEV_FE); 3294*49db4272SNagarjuna Kristam 3295*49db4272SNagarjuna Kristam /* 3296*49db4272SNagarjuna Kristam * Enable INFINITE_SS_RETRY to prevent device from entering 3297*49db4272SNagarjuna Kristam * Disabled.Error when attached to buggy SuperSpeed hubs. 3298*49db4272SNagarjuna Kristam */ 3299*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CFG_DEV_FE); 3300*49db4272SNagarjuna Kristam val |= CFG_DEV_FE_INFINITE_SS_RETRY; 3301*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CFG_DEV_FE); 3302*49db4272SNagarjuna Kristam 3303*49db4272SNagarjuna Kristam /* Set interrupt moderation. */ 3304*49db4272SNagarjuna Kristam imod = XUDC_INTERRUPT_MODERATION_US * 4; 3305*49db4272SNagarjuna Kristam val = xudc_readl(xudc, RT_IMOD); 3306*49db4272SNagarjuna Kristam val &= ~((RT_IMOD_IMODI_MASK) | (RT_IMOD_IMODC_MASK)); 3307*49db4272SNagarjuna Kristam val |= (RT_IMOD_IMODI(imod) | RT_IMOD_IMODC(imod)); 3308*49db4272SNagarjuna Kristam xudc_writel(xudc, val, RT_IMOD); 3309*49db4272SNagarjuna Kristam 3310*49db4272SNagarjuna Kristam /* increase SSPI transaction timeout from 32us to 512us */ 3311*49db4272SNagarjuna Kristam val = xudc_readl(xudc, CFG_DEV_SSPI_XFER); 3312*49db4272SNagarjuna Kristam val &= ~(CFG_DEV_SSPI_XFER_ACKTIMEOUT_MASK); 3313*49db4272SNagarjuna Kristam val |= CFG_DEV_SSPI_XFER_ACKTIMEOUT(0xf000); 3314*49db4272SNagarjuna Kristam xudc_writel(xudc, val, CFG_DEV_SSPI_XFER); 3315*49db4272SNagarjuna Kristam } 3316*49db4272SNagarjuna Kristam 3317*49db4272SNagarjuna Kristam static int tegra_xudc_phy_init(struct tegra_xudc *xudc) 3318*49db4272SNagarjuna Kristam { 3319*49db4272SNagarjuna Kristam int err; 3320*49db4272SNagarjuna Kristam 3321*49db4272SNagarjuna Kristam err = phy_init(xudc->utmi_phy); 3322*49db4272SNagarjuna Kristam if (err < 0) { 3323*49db4272SNagarjuna Kristam dev_err(xudc->dev, "utmi phy init failed: %d\n", err); 3324*49db4272SNagarjuna Kristam return err; 3325*49db4272SNagarjuna Kristam } 3326*49db4272SNagarjuna Kristam 3327*49db4272SNagarjuna Kristam err = phy_init(xudc->usb3_phy); 3328*49db4272SNagarjuna Kristam if (err < 0) { 3329*49db4272SNagarjuna Kristam dev_err(xudc->dev, "usb3 phy init failed: %d\n", err); 3330*49db4272SNagarjuna Kristam goto exit_utmi_phy; 3331*49db4272SNagarjuna Kristam } 3332*49db4272SNagarjuna Kristam 3333*49db4272SNagarjuna Kristam return 0; 3334*49db4272SNagarjuna Kristam 3335*49db4272SNagarjuna Kristam exit_utmi_phy: 3336*49db4272SNagarjuna Kristam phy_exit(xudc->utmi_phy); 3337*49db4272SNagarjuna Kristam return err; 3338*49db4272SNagarjuna Kristam } 3339*49db4272SNagarjuna Kristam 3340*49db4272SNagarjuna Kristam static void tegra_xudc_phy_exit(struct tegra_xudc *xudc) 3341*49db4272SNagarjuna Kristam { 3342*49db4272SNagarjuna Kristam phy_exit(xudc->usb3_phy); 3343*49db4272SNagarjuna Kristam phy_exit(xudc->utmi_phy); 3344*49db4272SNagarjuna Kristam } 3345*49db4272SNagarjuna Kristam 3346*49db4272SNagarjuna Kristam static const char * const tegra210_xudc_supply_names[] = { 3347*49db4272SNagarjuna Kristam "hvdd-usb", 3348*49db4272SNagarjuna Kristam "avddio-usb", 3349*49db4272SNagarjuna Kristam }; 3350*49db4272SNagarjuna Kristam 3351*49db4272SNagarjuna Kristam static const char * const tegra210_xudc_clock_names[] = { 3352*49db4272SNagarjuna Kristam "dev", 3353*49db4272SNagarjuna Kristam "ss", 3354*49db4272SNagarjuna Kristam "ss_src", 3355*49db4272SNagarjuna Kristam "hs_src", 3356*49db4272SNagarjuna Kristam "fs_src", 3357*49db4272SNagarjuna Kristam }; 3358*49db4272SNagarjuna Kristam 3359*49db4272SNagarjuna Kristam static const char * const tegra186_xudc_clock_names[] = { 3360*49db4272SNagarjuna Kristam "dev", 3361*49db4272SNagarjuna Kristam "ss", 3362*49db4272SNagarjuna Kristam "ss_src", 3363*49db4272SNagarjuna Kristam "fs_src", 3364*49db4272SNagarjuna Kristam }; 3365*49db4272SNagarjuna Kristam 3366*49db4272SNagarjuna Kristam static struct tegra_xudc_soc tegra210_xudc_soc_data = { 3367*49db4272SNagarjuna Kristam .supply_names = tegra210_xudc_supply_names, 3368*49db4272SNagarjuna Kristam .num_supplies = ARRAY_SIZE(tegra210_xudc_supply_names), 3369*49db4272SNagarjuna Kristam .clock_names = tegra210_xudc_clock_names, 3370*49db4272SNagarjuna Kristam .num_clks = ARRAY_SIZE(tegra210_xudc_clock_names), 3371*49db4272SNagarjuna Kristam .u1_enable = false, 3372*49db4272SNagarjuna Kristam .u2_enable = true, 3373*49db4272SNagarjuna Kristam .lpm_enable = false, 3374*49db4272SNagarjuna Kristam .invalid_seq_num = true, 3375*49db4272SNagarjuna Kristam .pls_quirk = true, 3376*49db4272SNagarjuna Kristam .port_reset_quirk = true, 3377*49db4272SNagarjuna Kristam .has_ipfs = true, 3378*49db4272SNagarjuna Kristam }; 3379*49db4272SNagarjuna Kristam 3380*49db4272SNagarjuna Kristam static struct tegra_xudc_soc tegra186_xudc_soc_data = { 3381*49db4272SNagarjuna Kristam .clock_names = tegra186_xudc_clock_names, 3382*49db4272SNagarjuna Kristam .num_clks = ARRAY_SIZE(tegra186_xudc_clock_names), 3383*49db4272SNagarjuna Kristam .u1_enable = true, 3384*49db4272SNagarjuna Kristam .u2_enable = true, 3385*49db4272SNagarjuna Kristam .lpm_enable = false, 3386*49db4272SNagarjuna Kristam .invalid_seq_num = false, 3387*49db4272SNagarjuna Kristam .pls_quirk = false, 3388*49db4272SNagarjuna Kristam .port_reset_quirk = false, 3389*49db4272SNagarjuna Kristam .has_ipfs = false, 3390*49db4272SNagarjuna Kristam }; 3391*49db4272SNagarjuna Kristam 3392*49db4272SNagarjuna Kristam static const struct of_device_id tegra_xudc_of_match[] = { 3393*49db4272SNagarjuna Kristam { 3394*49db4272SNagarjuna Kristam .compatible = "nvidia,tegra210-xudc", 3395*49db4272SNagarjuna Kristam .data = &tegra210_xudc_soc_data 3396*49db4272SNagarjuna Kristam }, 3397*49db4272SNagarjuna Kristam { 3398*49db4272SNagarjuna Kristam .compatible = "nvidia,tegra186-xudc", 3399*49db4272SNagarjuna Kristam .data = &tegra186_xudc_soc_data 3400*49db4272SNagarjuna Kristam }, 3401*49db4272SNagarjuna Kristam { } 3402*49db4272SNagarjuna Kristam }; 3403*49db4272SNagarjuna Kristam MODULE_DEVICE_TABLE(of, tegra_xudc_of_match); 3404*49db4272SNagarjuna Kristam 3405*49db4272SNagarjuna Kristam static void tegra_xudc_powerdomain_remove(struct tegra_xudc *xudc) 3406*49db4272SNagarjuna Kristam { 3407*49db4272SNagarjuna Kristam if (xudc->genpd_dl_ss) 3408*49db4272SNagarjuna Kristam device_link_del(xudc->genpd_dl_ss); 3409*49db4272SNagarjuna Kristam if (xudc->genpd_dl_device) 3410*49db4272SNagarjuna Kristam device_link_del(xudc->genpd_dl_device); 3411*49db4272SNagarjuna Kristam if (xudc->genpd_dev_ss) 3412*49db4272SNagarjuna Kristam dev_pm_domain_detach(xudc->genpd_dev_ss, true); 3413*49db4272SNagarjuna Kristam if (xudc->genpd_dev_device) 3414*49db4272SNagarjuna Kristam dev_pm_domain_detach(xudc->genpd_dev_device, true); 3415*49db4272SNagarjuna Kristam } 3416*49db4272SNagarjuna Kristam 3417*49db4272SNagarjuna Kristam static int tegra_xudc_powerdomain_init(struct tegra_xudc *xudc) 3418*49db4272SNagarjuna Kristam { 3419*49db4272SNagarjuna Kristam struct device *dev = xudc->dev; 3420*49db4272SNagarjuna Kristam int err; 3421*49db4272SNagarjuna Kristam 3422*49db4272SNagarjuna Kristam xudc->genpd_dev_device = dev_pm_domain_attach_by_name(dev, 3423*49db4272SNagarjuna Kristam "dev"); 3424*49db4272SNagarjuna Kristam if (IS_ERR(xudc->genpd_dev_device)) { 3425*49db4272SNagarjuna Kristam err = PTR_ERR(xudc->genpd_dev_device); 3426*49db4272SNagarjuna Kristam dev_err(dev, "failed to get dev pm-domain: %d\n", err); 3427*49db4272SNagarjuna Kristam return err; 3428*49db4272SNagarjuna Kristam } 3429*49db4272SNagarjuna Kristam 3430*49db4272SNagarjuna Kristam xudc->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "ss"); 3431*49db4272SNagarjuna Kristam if (IS_ERR(xudc->genpd_dev_ss)) { 3432*49db4272SNagarjuna Kristam err = PTR_ERR(xudc->genpd_dev_ss); 3433*49db4272SNagarjuna Kristam dev_err(dev, "failed to get superspeed pm-domain: %d\n", err); 3434*49db4272SNagarjuna Kristam return err; 3435*49db4272SNagarjuna Kristam } 3436*49db4272SNagarjuna Kristam 3437*49db4272SNagarjuna Kristam xudc->genpd_dl_device = device_link_add(dev, xudc->genpd_dev_device, 3438*49db4272SNagarjuna Kristam DL_FLAG_PM_RUNTIME | 3439*49db4272SNagarjuna Kristam DL_FLAG_STATELESS); 3440*49db4272SNagarjuna Kristam if (!xudc->genpd_dl_device) { 3441*49db4272SNagarjuna Kristam dev_err(dev, "adding usb device device link failed!\n"); 3442*49db4272SNagarjuna Kristam return -ENODEV; 3443*49db4272SNagarjuna Kristam } 3444*49db4272SNagarjuna Kristam 3445*49db4272SNagarjuna Kristam xudc->genpd_dl_ss = device_link_add(dev, xudc->genpd_dev_ss, 3446*49db4272SNagarjuna Kristam DL_FLAG_PM_RUNTIME | 3447*49db4272SNagarjuna Kristam DL_FLAG_STATELESS); 3448*49db4272SNagarjuna Kristam if (!xudc->genpd_dl_ss) { 3449*49db4272SNagarjuna Kristam dev_err(dev, "adding superspeed device link failed!\n"); 3450*49db4272SNagarjuna Kristam return -ENODEV; 3451*49db4272SNagarjuna Kristam } 3452*49db4272SNagarjuna Kristam 3453*49db4272SNagarjuna Kristam return 0; 3454*49db4272SNagarjuna Kristam } 3455*49db4272SNagarjuna Kristam 3456*49db4272SNagarjuna Kristam static int tegra_xudc_probe(struct platform_device *pdev) 3457*49db4272SNagarjuna Kristam { 3458*49db4272SNagarjuna Kristam struct tegra_xudc *xudc; 3459*49db4272SNagarjuna Kristam struct resource *res; 3460*49db4272SNagarjuna Kristam struct usb_role_switch_desc role_sx_desc = { 0 }; 3461*49db4272SNagarjuna Kristam unsigned int i; 3462*49db4272SNagarjuna Kristam int err; 3463*49db4272SNagarjuna Kristam 3464*49db4272SNagarjuna Kristam xudc = devm_kzalloc(&pdev->dev, sizeof(*xudc), GFP_ATOMIC); 3465*49db4272SNagarjuna Kristam if (!xudc) 3466*49db4272SNagarjuna Kristam return -ENOMEM; 3467*49db4272SNagarjuna Kristam 3468*49db4272SNagarjuna Kristam xudc->dev = &pdev->dev; 3469*49db4272SNagarjuna Kristam platform_set_drvdata(pdev, xudc); 3470*49db4272SNagarjuna Kristam 3471*49db4272SNagarjuna Kristam xudc->soc = of_device_get_match_data(&pdev->dev); 3472*49db4272SNagarjuna Kristam if (!xudc->soc) 3473*49db4272SNagarjuna Kristam return -ENODEV; 3474*49db4272SNagarjuna Kristam 3475*49db4272SNagarjuna Kristam res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base"); 3476*49db4272SNagarjuna Kristam xudc->base = devm_ioremap_resource(&pdev->dev, res); 3477*49db4272SNagarjuna Kristam if (IS_ERR(xudc->base)) 3478*49db4272SNagarjuna Kristam return PTR_ERR(xudc->base); 3479*49db4272SNagarjuna Kristam xudc->phys_base = res->start; 3480*49db4272SNagarjuna Kristam 3481*49db4272SNagarjuna Kristam res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fpci"); 3482*49db4272SNagarjuna Kristam xudc->fpci = devm_ioremap_resource(&pdev->dev, res); 3483*49db4272SNagarjuna Kristam if (IS_ERR(xudc->fpci)) 3484*49db4272SNagarjuna Kristam return PTR_ERR(xudc->fpci); 3485*49db4272SNagarjuna Kristam 3486*49db4272SNagarjuna Kristam if (xudc->soc->has_ipfs) { 3487*49db4272SNagarjuna Kristam res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 3488*49db4272SNagarjuna Kristam "ipfs"); 3489*49db4272SNagarjuna Kristam xudc->ipfs = devm_ioremap_resource(&pdev->dev, res); 3490*49db4272SNagarjuna Kristam if (IS_ERR(xudc->ipfs)) 3491*49db4272SNagarjuna Kristam return PTR_ERR(xudc->ipfs); 3492*49db4272SNagarjuna Kristam } 3493*49db4272SNagarjuna Kristam 3494*49db4272SNagarjuna Kristam xudc->irq = platform_get_irq(pdev, 0); 3495*49db4272SNagarjuna Kristam if (xudc->irq < 0) { 3496*49db4272SNagarjuna Kristam dev_err(xudc->dev, "failed to get IRQ: %d\n", 3497*49db4272SNagarjuna Kristam xudc->irq); 3498*49db4272SNagarjuna Kristam return xudc->irq; 3499*49db4272SNagarjuna Kristam } 3500*49db4272SNagarjuna Kristam 3501*49db4272SNagarjuna Kristam err = devm_request_irq(&pdev->dev, xudc->irq, tegra_xudc_irq, 0, 3502*49db4272SNagarjuna Kristam dev_name(&pdev->dev), xudc); 3503*49db4272SNagarjuna Kristam if (err < 0) { 3504*49db4272SNagarjuna Kristam dev_err(xudc->dev, "failed to claim IRQ#%u: %d\n", xudc->irq, 3505*49db4272SNagarjuna Kristam err); 3506*49db4272SNagarjuna Kristam return err; 3507*49db4272SNagarjuna Kristam } 3508*49db4272SNagarjuna Kristam 3509*49db4272SNagarjuna Kristam xudc->clks = devm_kcalloc(&pdev->dev, xudc->soc->num_clks, 3510*49db4272SNagarjuna Kristam sizeof(*xudc->clks), GFP_KERNEL); 3511*49db4272SNagarjuna Kristam if (!xudc->clks) 3512*49db4272SNagarjuna Kristam return -ENOMEM; 3513*49db4272SNagarjuna Kristam 3514*49db4272SNagarjuna Kristam for (i = 0; i < xudc->soc->num_clks; i++) 3515*49db4272SNagarjuna Kristam xudc->clks[i].id = xudc->soc->clock_names[i]; 3516*49db4272SNagarjuna Kristam 3517*49db4272SNagarjuna Kristam err = devm_clk_bulk_get(&pdev->dev, xudc->soc->num_clks, 3518*49db4272SNagarjuna Kristam xudc->clks); 3519*49db4272SNagarjuna Kristam if (err) { 3520*49db4272SNagarjuna Kristam dev_err(xudc->dev, "failed to request clks %d\n", err); 3521*49db4272SNagarjuna Kristam return err; 3522*49db4272SNagarjuna Kristam } 3523*49db4272SNagarjuna Kristam 3524*49db4272SNagarjuna Kristam xudc->supplies = devm_kcalloc(&pdev->dev, xudc->soc->num_supplies, 3525*49db4272SNagarjuna Kristam sizeof(*xudc->supplies), GFP_KERNEL); 3526*49db4272SNagarjuna Kristam if (!xudc->supplies) 3527*49db4272SNagarjuna Kristam return -ENOMEM; 3528*49db4272SNagarjuna Kristam 3529*49db4272SNagarjuna Kristam for (i = 0; i < xudc->soc->num_supplies; i++) 3530*49db4272SNagarjuna Kristam xudc->supplies[i].supply = xudc->soc->supply_names[i]; 3531*49db4272SNagarjuna Kristam 3532*49db4272SNagarjuna Kristam err = devm_regulator_bulk_get(&pdev->dev, xudc->soc->num_supplies, 3533*49db4272SNagarjuna Kristam xudc->supplies); 3534*49db4272SNagarjuna Kristam if (err) { 3535*49db4272SNagarjuna Kristam dev_err(xudc->dev, "failed to request regulators %d\n", err); 3536*49db4272SNagarjuna Kristam return err; 3537*49db4272SNagarjuna Kristam } 3538*49db4272SNagarjuna Kristam 3539*49db4272SNagarjuna Kristam xudc->padctl = tegra_xusb_padctl_get(&pdev->dev); 3540*49db4272SNagarjuna Kristam if (IS_ERR(xudc->padctl)) 3541*49db4272SNagarjuna Kristam return PTR_ERR(xudc->padctl); 3542*49db4272SNagarjuna Kristam 3543*49db4272SNagarjuna Kristam err = regulator_bulk_enable(xudc->soc->num_supplies, xudc->supplies); 3544*49db4272SNagarjuna Kristam if (err) { 3545*49db4272SNagarjuna Kristam dev_err(xudc->dev, "failed to enable regulators %d\n", err); 3546*49db4272SNagarjuna Kristam goto put_padctl; 3547*49db4272SNagarjuna Kristam } 3548*49db4272SNagarjuna Kristam 3549*49db4272SNagarjuna Kristam xudc->usb3_phy = devm_phy_optional_get(&pdev->dev, "usb3"); 3550*49db4272SNagarjuna Kristam if (IS_ERR(xudc->usb3_phy)) { 3551*49db4272SNagarjuna Kristam err = PTR_ERR(xudc->usb3_phy); 3552*49db4272SNagarjuna Kristam dev_err(xudc->dev, "failed to get usb3 phy: %d\n", err); 3553*49db4272SNagarjuna Kristam goto disable_regulator; 3554*49db4272SNagarjuna Kristam } 3555*49db4272SNagarjuna Kristam 3556*49db4272SNagarjuna Kristam xudc->utmi_phy = devm_phy_optional_get(&pdev->dev, "usb2"); 3557*49db4272SNagarjuna Kristam if (IS_ERR(xudc->utmi_phy)) { 3558*49db4272SNagarjuna Kristam err = PTR_ERR(xudc->utmi_phy); 3559*49db4272SNagarjuna Kristam dev_err(xudc->dev, "failed to get usb2 phy: %d\n", err); 3560*49db4272SNagarjuna Kristam goto disable_regulator; 3561*49db4272SNagarjuna Kristam } 3562*49db4272SNagarjuna Kristam 3563*49db4272SNagarjuna Kristam err = tegra_xudc_powerdomain_init(xudc); 3564*49db4272SNagarjuna Kristam if (err) 3565*49db4272SNagarjuna Kristam goto put_powerdomains; 3566*49db4272SNagarjuna Kristam 3567*49db4272SNagarjuna Kristam err = tegra_xudc_phy_init(xudc); 3568*49db4272SNagarjuna Kristam if (err) 3569*49db4272SNagarjuna Kristam goto put_powerdomains; 3570*49db4272SNagarjuna Kristam 3571*49db4272SNagarjuna Kristam err = tegra_xudc_alloc_event_ring(xudc); 3572*49db4272SNagarjuna Kristam if (err) 3573*49db4272SNagarjuna Kristam goto disable_phy; 3574*49db4272SNagarjuna Kristam 3575*49db4272SNagarjuna Kristam err = tegra_xudc_alloc_eps(xudc); 3576*49db4272SNagarjuna Kristam if (err) 3577*49db4272SNagarjuna Kristam goto free_event_ring; 3578*49db4272SNagarjuna Kristam 3579*49db4272SNagarjuna Kristam spin_lock_init(&xudc->lock); 3580*49db4272SNagarjuna Kristam 3581*49db4272SNagarjuna Kristam init_completion(&xudc->disconnect_complete); 3582*49db4272SNagarjuna Kristam 3583*49db4272SNagarjuna Kristam INIT_WORK(&xudc->usb_role_sw_work, tegra_xudc_usb_role_sw_work); 3584*49db4272SNagarjuna Kristam 3585*49db4272SNagarjuna Kristam INIT_DELAYED_WORK(&xudc->plc_reset_work, tegra_xudc_plc_reset_work); 3586*49db4272SNagarjuna Kristam 3587*49db4272SNagarjuna Kristam INIT_DELAYED_WORK(&xudc->port_reset_war_work, 3588*49db4272SNagarjuna Kristam tegra_xudc_port_reset_war_work); 3589*49db4272SNagarjuna Kristam 3590*49db4272SNagarjuna Kristam if (of_property_read_bool(xudc->dev->of_node, "usb-role-switch")) { 3591*49db4272SNagarjuna Kristam role_sx_desc.set = tegra_xudc_usb_role_sw_set; 3592*49db4272SNagarjuna Kristam role_sx_desc.fwnode = dev_fwnode(xudc->dev); 3593*49db4272SNagarjuna Kristam 3594*49db4272SNagarjuna Kristam xudc->usb_role_sw = usb_role_switch_register(xudc->dev, 3595*49db4272SNagarjuna Kristam &role_sx_desc); 3596*49db4272SNagarjuna Kristam if (IS_ERR(xudc->usb_role_sw)) { 3597*49db4272SNagarjuna Kristam err = PTR_ERR(xudc->usb_role_sw); 3598*49db4272SNagarjuna Kristam dev_err(xudc->dev, "Failed to register USB role SW: %d", 3599*49db4272SNagarjuna Kristam err); 3600*49db4272SNagarjuna Kristam goto free_eps; 3601*49db4272SNagarjuna Kristam } 3602*49db4272SNagarjuna Kristam } else { 3603*49db4272SNagarjuna Kristam /* Set the mode as device mode and this keeps phy always ON */ 3604*49db4272SNagarjuna Kristam dev_info(xudc->dev, "Set usb role to device mode always"); 3605*49db4272SNagarjuna Kristam schedule_work(&xudc->usb_role_sw_work); 3606*49db4272SNagarjuna Kristam } 3607*49db4272SNagarjuna Kristam 3608*49db4272SNagarjuna Kristam pm_runtime_enable(&pdev->dev); 3609*49db4272SNagarjuna Kristam 3610*49db4272SNagarjuna Kristam xudc->gadget.ops = &tegra_xudc_gadget_ops; 3611*49db4272SNagarjuna Kristam xudc->gadget.ep0 = &xudc->ep[0].usb_ep; 3612*49db4272SNagarjuna Kristam xudc->gadget.name = "tegra-xudc"; 3613*49db4272SNagarjuna Kristam xudc->gadget.max_speed = USB_SPEED_SUPER; 3614*49db4272SNagarjuna Kristam 3615*49db4272SNagarjuna Kristam err = usb_add_gadget_udc(&pdev->dev, &xudc->gadget); 3616*49db4272SNagarjuna Kristam if (err) { 3617*49db4272SNagarjuna Kristam dev_err(&pdev->dev, "failed to add USB gadget: %d\n", err); 3618*49db4272SNagarjuna Kristam goto free_eps; 3619*49db4272SNagarjuna Kristam } 3620*49db4272SNagarjuna Kristam 3621*49db4272SNagarjuna Kristam return 0; 3622*49db4272SNagarjuna Kristam 3623*49db4272SNagarjuna Kristam free_eps: 3624*49db4272SNagarjuna Kristam tegra_xudc_free_eps(xudc); 3625*49db4272SNagarjuna Kristam free_event_ring: 3626*49db4272SNagarjuna Kristam tegra_xudc_free_event_ring(xudc); 3627*49db4272SNagarjuna Kristam disable_phy: 3628*49db4272SNagarjuna Kristam tegra_xudc_phy_exit(xudc); 3629*49db4272SNagarjuna Kristam put_powerdomains: 3630*49db4272SNagarjuna Kristam tegra_xudc_powerdomain_remove(xudc); 3631*49db4272SNagarjuna Kristam disable_regulator: 3632*49db4272SNagarjuna Kristam regulator_bulk_disable(xudc->soc->num_supplies, xudc->supplies); 3633*49db4272SNagarjuna Kristam put_padctl: 3634*49db4272SNagarjuna Kristam tegra_xusb_padctl_put(xudc->padctl); 3635*49db4272SNagarjuna Kristam 3636*49db4272SNagarjuna Kristam return err; 3637*49db4272SNagarjuna Kristam } 3638*49db4272SNagarjuna Kristam 3639*49db4272SNagarjuna Kristam static int tegra_xudc_remove(struct platform_device *pdev) 3640*49db4272SNagarjuna Kristam { 3641*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = platform_get_drvdata(pdev); 3642*49db4272SNagarjuna Kristam 3643*49db4272SNagarjuna Kristam pm_runtime_get_sync(xudc->dev); 3644*49db4272SNagarjuna Kristam 3645*49db4272SNagarjuna Kristam cancel_delayed_work(&xudc->plc_reset_work); 3646*49db4272SNagarjuna Kristam 3647*49db4272SNagarjuna Kristam if (xudc->usb_role_sw) { 3648*49db4272SNagarjuna Kristam usb_role_switch_unregister(xudc->usb_role_sw); 3649*49db4272SNagarjuna Kristam cancel_work_sync(&xudc->usb_role_sw_work); 3650*49db4272SNagarjuna Kristam } 3651*49db4272SNagarjuna Kristam 3652*49db4272SNagarjuna Kristam usb_del_gadget_udc(&xudc->gadget); 3653*49db4272SNagarjuna Kristam 3654*49db4272SNagarjuna Kristam tegra_xudc_free_eps(xudc); 3655*49db4272SNagarjuna Kristam tegra_xudc_free_event_ring(xudc); 3656*49db4272SNagarjuna Kristam 3657*49db4272SNagarjuna Kristam tegra_xudc_powerdomain_remove(xudc); 3658*49db4272SNagarjuna Kristam 3659*49db4272SNagarjuna Kristam regulator_bulk_disable(xudc->soc->num_supplies, xudc->supplies); 3660*49db4272SNagarjuna Kristam 3661*49db4272SNagarjuna Kristam phy_power_off(xudc->utmi_phy); 3662*49db4272SNagarjuna Kristam phy_power_off(xudc->usb3_phy); 3663*49db4272SNagarjuna Kristam 3664*49db4272SNagarjuna Kristam tegra_xudc_phy_exit(xudc); 3665*49db4272SNagarjuna Kristam 3666*49db4272SNagarjuna Kristam pm_runtime_disable(xudc->dev); 3667*49db4272SNagarjuna Kristam pm_runtime_put(xudc->dev); 3668*49db4272SNagarjuna Kristam 3669*49db4272SNagarjuna Kristam tegra_xusb_padctl_put(xudc->padctl); 3670*49db4272SNagarjuna Kristam 3671*49db4272SNagarjuna Kristam return 0; 3672*49db4272SNagarjuna Kristam } 3673*49db4272SNagarjuna Kristam 3674*49db4272SNagarjuna Kristam static int __maybe_unused tegra_xudc_powergate(struct tegra_xudc *xudc) 3675*49db4272SNagarjuna Kristam { 3676*49db4272SNagarjuna Kristam unsigned long flags; 3677*49db4272SNagarjuna Kristam 3678*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "entering ELPG\n"); 3679*49db4272SNagarjuna Kristam 3680*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 3681*49db4272SNagarjuna Kristam 3682*49db4272SNagarjuna Kristam xudc->powergated = true; 3683*49db4272SNagarjuna Kristam xudc->saved_regs.ctrl = xudc_readl(xudc, CTRL); 3684*49db4272SNagarjuna Kristam xudc->saved_regs.portpm = xudc_readl(xudc, PORTPM); 3685*49db4272SNagarjuna Kristam xudc_writel(xudc, 0, CTRL); 3686*49db4272SNagarjuna Kristam 3687*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 3688*49db4272SNagarjuna Kristam 3689*49db4272SNagarjuna Kristam clk_bulk_disable_unprepare(xudc->soc->num_clks, xudc->clks); 3690*49db4272SNagarjuna Kristam 3691*49db4272SNagarjuna Kristam regulator_bulk_disable(xudc->soc->num_supplies, xudc->supplies); 3692*49db4272SNagarjuna Kristam 3693*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "entering ELPG done\n"); 3694*49db4272SNagarjuna Kristam return 0; 3695*49db4272SNagarjuna Kristam } 3696*49db4272SNagarjuna Kristam 3697*49db4272SNagarjuna Kristam static int __maybe_unused tegra_xudc_unpowergate(struct tegra_xudc *xudc) 3698*49db4272SNagarjuna Kristam { 3699*49db4272SNagarjuna Kristam unsigned long flags; 3700*49db4272SNagarjuna Kristam int err; 3701*49db4272SNagarjuna Kristam 3702*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "exiting ELPG\n"); 3703*49db4272SNagarjuna Kristam 3704*49db4272SNagarjuna Kristam err = regulator_bulk_enable(xudc->soc->num_supplies, 3705*49db4272SNagarjuna Kristam xudc->supplies); 3706*49db4272SNagarjuna Kristam if (err < 0) 3707*49db4272SNagarjuna Kristam return err; 3708*49db4272SNagarjuna Kristam 3709*49db4272SNagarjuna Kristam err = clk_bulk_prepare_enable(xudc->soc->num_clks, xudc->clks); 3710*49db4272SNagarjuna Kristam if (err < 0) 3711*49db4272SNagarjuna Kristam return err; 3712*49db4272SNagarjuna Kristam 3713*49db4272SNagarjuna Kristam tegra_xudc_fpci_ipfs_init(xudc); 3714*49db4272SNagarjuna Kristam 3715*49db4272SNagarjuna Kristam tegra_xudc_device_params_init(xudc); 3716*49db4272SNagarjuna Kristam 3717*49db4272SNagarjuna Kristam tegra_xudc_init_event_ring(xudc); 3718*49db4272SNagarjuna Kristam 3719*49db4272SNagarjuna Kristam tegra_xudc_init_eps(xudc); 3720*49db4272SNagarjuna Kristam 3721*49db4272SNagarjuna Kristam xudc_writel(xudc, xudc->saved_regs.portpm, PORTPM); 3722*49db4272SNagarjuna Kristam xudc_writel(xudc, xudc->saved_regs.ctrl, CTRL); 3723*49db4272SNagarjuna Kristam 3724*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 3725*49db4272SNagarjuna Kristam xudc->powergated = false; 3726*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 3727*49db4272SNagarjuna Kristam 3728*49db4272SNagarjuna Kristam dev_dbg(xudc->dev, "exiting ELPG done\n"); 3729*49db4272SNagarjuna Kristam return 0; 3730*49db4272SNagarjuna Kristam } 3731*49db4272SNagarjuna Kristam 3732*49db4272SNagarjuna Kristam static int __maybe_unused tegra_xudc_suspend(struct device *dev) 3733*49db4272SNagarjuna Kristam { 3734*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = dev_get_drvdata(dev); 3735*49db4272SNagarjuna Kristam unsigned long flags; 3736*49db4272SNagarjuna Kristam 3737*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 3738*49db4272SNagarjuna Kristam xudc->suspended = true; 3739*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 3740*49db4272SNagarjuna Kristam 3741*49db4272SNagarjuna Kristam flush_work(&xudc->usb_role_sw_work); 3742*49db4272SNagarjuna Kristam 3743*49db4272SNagarjuna Kristam /* Forcibly disconnect before powergating. */ 3744*49db4272SNagarjuna Kristam tegra_xudc_device_mode_off(xudc); 3745*49db4272SNagarjuna Kristam 3746*49db4272SNagarjuna Kristam if (!pm_runtime_status_suspended(dev)) 3747*49db4272SNagarjuna Kristam tegra_xudc_powergate(xudc); 3748*49db4272SNagarjuna Kristam 3749*49db4272SNagarjuna Kristam pm_runtime_disable(dev); 3750*49db4272SNagarjuna Kristam 3751*49db4272SNagarjuna Kristam return 0; 3752*49db4272SNagarjuna Kristam } 3753*49db4272SNagarjuna Kristam 3754*49db4272SNagarjuna Kristam static int __maybe_unused tegra_xudc_resume(struct device *dev) 3755*49db4272SNagarjuna Kristam { 3756*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = dev_get_drvdata(dev); 3757*49db4272SNagarjuna Kristam unsigned long flags; 3758*49db4272SNagarjuna Kristam int err; 3759*49db4272SNagarjuna Kristam 3760*49db4272SNagarjuna Kristam err = tegra_xudc_unpowergate(xudc); 3761*49db4272SNagarjuna Kristam if (err < 0) 3762*49db4272SNagarjuna Kristam return err; 3763*49db4272SNagarjuna Kristam 3764*49db4272SNagarjuna Kristam spin_lock_irqsave(&xudc->lock, flags); 3765*49db4272SNagarjuna Kristam xudc->suspended = false; 3766*49db4272SNagarjuna Kristam spin_unlock_irqrestore(&xudc->lock, flags); 3767*49db4272SNagarjuna Kristam 3768*49db4272SNagarjuna Kristam schedule_work(&xudc->usb_role_sw_work); 3769*49db4272SNagarjuna Kristam 3770*49db4272SNagarjuna Kristam pm_runtime_enable(dev); 3771*49db4272SNagarjuna Kristam 3772*49db4272SNagarjuna Kristam return 0; 3773*49db4272SNagarjuna Kristam } 3774*49db4272SNagarjuna Kristam 3775*49db4272SNagarjuna Kristam static int __maybe_unused tegra_xudc_runtime_suspend(struct device *dev) 3776*49db4272SNagarjuna Kristam { 3777*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = dev_get_drvdata(dev); 3778*49db4272SNagarjuna Kristam 3779*49db4272SNagarjuna Kristam return tegra_xudc_powergate(xudc); 3780*49db4272SNagarjuna Kristam } 3781*49db4272SNagarjuna Kristam 3782*49db4272SNagarjuna Kristam static int __maybe_unused tegra_xudc_runtime_resume(struct device *dev) 3783*49db4272SNagarjuna Kristam { 3784*49db4272SNagarjuna Kristam struct tegra_xudc *xudc = dev_get_drvdata(dev); 3785*49db4272SNagarjuna Kristam 3786*49db4272SNagarjuna Kristam return tegra_xudc_unpowergate(xudc); 3787*49db4272SNagarjuna Kristam } 3788*49db4272SNagarjuna Kristam 3789*49db4272SNagarjuna Kristam static const struct dev_pm_ops tegra_xudc_pm_ops = { 3790*49db4272SNagarjuna Kristam SET_SYSTEM_SLEEP_PM_OPS(tegra_xudc_suspend, tegra_xudc_resume) 3791*49db4272SNagarjuna Kristam SET_RUNTIME_PM_OPS(tegra_xudc_runtime_suspend, 3792*49db4272SNagarjuna Kristam tegra_xudc_runtime_resume, NULL) 3793*49db4272SNagarjuna Kristam }; 3794*49db4272SNagarjuna Kristam 3795*49db4272SNagarjuna Kristam static struct platform_driver tegra_xudc_driver = { 3796*49db4272SNagarjuna Kristam .probe = tegra_xudc_probe, 3797*49db4272SNagarjuna Kristam .remove = tegra_xudc_remove, 3798*49db4272SNagarjuna Kristam .driver = { 3799*49db4272SNagarjuna Kristam .name = "tegra-xudc", 3800*49db4272SNagarjuna Kristam .pm = &tegra_xudc_pm_ops, 3801*49db4272SNagarjuna Kristam .of_match_table = tegra_xudc_of_match, 3802*49db4272SNagarjuna Kristam }, 3803*49db4272SNagarjuna Kristam }; 3804*49db4272SNagarjuna Kristam module_platform_driver(tegra_xudc_driver); 3805*49db4272SNagarjuna Kristam 3806*49db4272SNagarjuna Kristam MODULE_DESCRIPTION("NVIDIA Tegra XUSB Device Controller"); 3807*49db4272SNagarjuna Kristam MODULE_AUTHOR("Andrew Bresticker <abrestic@chromium.org>"); 3808*49db4272SNagarjuna Kristam MODULE_AUTHOR("Hui Fu <hfu@nvidia.com>"); 3809*49db4272SNagarjuna Kristam MODULE_AUTHOR("Nagarjuna Kristam <nkristam@nvidia.com>"); 3810*49db4272SNagarjuna Kristam MODULE_LICENSE("GPL v2"); 3811