162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Renesas USB3.0 Peripheral driver (USB gadget) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015-2017 Renesas Electronics Corporation 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/debugfs.h> 962306a36Sopenharmony_ci#include <linux/delay.h> 1062306a36Sopenharmony_ci#include <linux/device.h> 1162306a36Sopenharmony_ci#include <linux/dma-mapping.h> 1262306a36Sopenharmony_ci#include <linux/err.h> 1362306a36Sopenharmony_ci#include <linux/extcon-provider.h> 1462306a36Sopenharmony_ci#include <linux/interrupt.h> 1562306a36Sopenharmony_ci#include <linux/io.h> 1662306a36Sopenharmony_ci#include <linux/module.h> 1762306a36Sopenharmony_ci#include <linux/of.h> 1862306a36Sopenharmony_ci#include <linux/phy/phy.h> 1962306a36Sopenharmony_ci#include <linux/platform_device.h> 2062306a36Sopenharmony_ci#include <linux/pm_runtime.h> 2162306a36Sopenharmony_ci#include <linux/reset.h> 2262306a36Sopenharmony_ci#include <linux/sizes.h> 2362306a36Sopenharmony_ci#include <linux/slab.h> 2462306a36Sopenharmony_ci#include <linux/string.h> 2562306a36Sopenharmony_ci#include <linux/uaccess.h> 2662306a36Sopenharmony_ci#include <linux/usb/ch9.h> 2762306a36Sopenharmony_ci#include <linux/usb/gadget.h> 2862306a36Sopenharmony_ci#include <linux/usb/of.h> 2962306a36Sopenharmony_ci#include <linux/usb/role.h> 3062306a36Sopenharmony_ci#include <linux/usb/rzv2m_usb3drd.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* register definitions */ 3362306a36Sopenharmony_ci#define USB3_AXI_INT_STA 0x008 3462306a36Sopenharmony_ci#define USB3_AXI_INT_ENA 0x00c 3562306a36Sopenharmony_ci#define USB3_DMA_INT_STA 0x010 3662306a36Sopenharmony_ci#define USB3_DMA_INT_ENA 0x014 3762306a36Sopenharmony_ci#define USB3_DMA_CH0_CON(n) (0x030 + ((n) - 1) * 0x10) /* n = 1 to 4 */ 3862306a36Sopenharmony_ci#define USB3_DMA_CH0_PRD_ADR(n) (0x034 + ((n) - 1) * 0x10) /* n = 1 to 4 */ 3962306a36Sopenharmony_ci#define USB3_USB_COM_CON 0x200 4062306a36Sopenharmony_ci#define USB3_USB20_CON 0x204 4162306a36Sopenharmony_ci#define USB3_USB30_CON 0x208 4262306a36Sopenharmony_ci#define USB3_USB_STA 0x210 4362306a36Sopenharmony_ci#define USB3_DRD_CON(p) ((p)->is_rzv2m ? 0x400 : 0x218) 4462306a36Sopenharmony_ci#define USB3_USB_INT_STA_1 0x220 4562306a36Sopenharmony_ci#define USB3_USB_INT_STA_2 0x224 4662306a36Sopenharmony_ci#define USB3_USB_INT_ENA_1 0x228 4762306a36Sopenharmony_ci#define USB3_USB_INT_ENA_2 0x22c 4862306a36Sopenharmony_ci#define USB3_STUP_DAT_0 0x230 4962306a36Sopenharmony_ci#define USB3_STUP_DAT_1 0x234 5062306a36Sopenharmony_ci#define USB3_USB_OTG_STA(p) ((p)->is_rzv2m ? 0x410 : 0x268) 5162306a36Sopenharmony_ci#define USB3_USB_OTG_INT_STA(p) ((p)->is_rzv2m ? 0x414 : 0x26c) 5262306a36Sopenharmony_ci#define USB3_USB_OTG_INT_ENA(p) ((p)->is_rzv2m ? 0x418 : 0x270) 5362306a36Sopenharmony_ci#define USB3_P0_MOD 0x280 5462306a36Sopenharmony_ci#define USB3_P0_CON 0x288 5562306a36Sopenharmony_ci#define USB3_P0_STA 0x28c 5662306a36Sopenharmony_ci#define USB3_P0_INT_STA 0x290 5762306a36Sopenharmony_ci#define USB3_P0_INT_ENA 0x294 5862306a36Sopenharmony_ci#define USB3_P0_LNG 0x2a0 5962306a36Sopenharmony_ci#define USB3_P0_READ 0x2a4 6062306a36Sopenharmony_ci#define USB3_P0_WRITE 0x2a8 6162306a36Sopenharmony_ci#define USB3_PIPE_COM 0x2b0 6262306a36Sopenharmony_ci#define USB3_PN_MOD 0x2c0 6362306a36Sopenharmony_ci#define USB3_PN_RAMMAP 0x2c4 6462306a36Sopenharmony_ci#define USB3_PN_CON 0x2c8 6562306a36Sopenharmony_ci#define USB3_PN_STA 0x2cc 6662306a36Sopenharmony_ci#define USB3_PN_INT_STA 0x2d0 6762306a36Sopenharmony_ci#define USB3_PN_INT_ENA 0x2d4 6862306a36Sopenharmony_ci#define USB3_PN_LNG 0x2e0 6962306a36Sopenharmony_ci#define USB3_PN_READ 0x2e4 7062306a36Sopenharmony_ci#define USB3_PN_WRITE 0x2e8 7162306a36Sopenharmony_ci#define USB3_SSIFCMD 0x340 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* AXI_INT_ENA and AXI_INT_STA */ 7462306a36Sopenharmony_ci#define AXI_INT_DMAINT BIT(31) 7562306a36Sopenharmony_ci#define AXI_INT_EPCINT BIT(30) 7662306a36Sopenharmony_ci/* PRD's n = from 1 to 4 */ 7762306a36Sopenharmony_ci#define AXI_INT_PRDEN_CLR_STA_SHIFT(n) (16 + (n) - 1) 7862306a36Sopenharmony_ci#define AXI_INT_PRDERR_STA_SHIFT(n) (0 + (n) - 1) 7962306a36Sopenharmony_ci#define AXI_INT_PRDEN_CLR_STA(n) (1 << AXI_INT_PRDEN_CLR_STA_SHIFT(n)) 8062306a36Sopenharmony_ci#define AXI_INT_PRDERR_STA(n) (1 << AXI_INT_PRDERR_STA_SHIFT(n)) 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* DMA_INT_ENA and DMA_INT_STA */ 8362306a36Sopenharmony_ci#define DMA_INT(n) BIT(n) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/* DMA_CH0_CONn */ 8662306a36Sopenharmony_ci#define DMA_CON_PIPE_DIR BIT(15) /* 1: In Transfer */ 8762306a36Sopenharmony_ci#define DMA_CON_PIPE_NO_SHIFT 8 8862306a36Sopenharmony_ci#define DMA_CON_PIPE_NO_MASK GENMASK(12, DMA_CON_PIPE_NO_SHIFT) 8962306a36Sopenharmony_ci#define DMA_COM_PIPE_NO(n) (((n) << DMA_CON_PIPE_NO_SHIFT) & \ 9062306a36Sopenharmony_ci DMA_CON_PIPE_NO_MASK) 9162306a36Sopenharmony_ci#define DMA_CON_PRD_EN BIT(0) 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci/* LCLKSEL */ 9462306a36Sopenharmony_ci#define LCLKSEL_LSEL BIT(18) 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* USB_COM_CON */ 9762306a36Sopenharmony_ci#define USB_COM_CON_CONF BIT(24) 9862306a36Sopenharmony_ci#define USB_COM_CON_PN_WDATAIF_NL BIT(23) 9962306a36Sopenharmony_ci#define USB_COM_CON_PN_RDATAIF_NL BIT(22) 10062306a36Sopenharmony_ci#define USB_COM_CON_PN_LSTTR_PP BIT(21) 10162306a36Sopenharmony_ci#define USB_COM_CON_SPD_MODE BIT(17) 10262306a36Sopenharmony_ci#define USB_COM_CON_EP0_EN BIT(16) 10362306a36Sopenharmony_ci#define USB_COM_CON_DEV_ADDR_SHIFT 8 10462306a36Sopenharmony_ci#define USB_COM_CON_DEV_ADDR_MASK GENMASK(14, USB_COM_CON_DEV_ADDR_SHIFT) 10562306a36Sopenharmony_ci#define USB_COM_CON_DEV_ADDR(n) (((n) << USB_COM_CON_DEV_ADDR_SHIFT) & \ 10662306a36Sopenharmony_ci USB_COM_CON_DEV_ADDR_MASK) 10762306a36Sopenharmony_ci#define USB_COM_CON_RX_DETECTION BIT(1) 10862306a36Sopenharmony_ci#define USB_COM_CON_PIPE_CLR BIT(0) 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/* USB20_CON */ 11162306a36Sopenharmony_ci#define USB20_CON_B2_PUE BIT(31) 11262306a36Sopenharmony_ci#define USB20_CON_B2_SUSPEND BIT(24) 11362306a36Sopenharmony_ci#define USB20_CON_B2_CONNECT BIT(17) 11462306a36Sopenharmony_ci#define USB20_CON_B2_TSTMOD_SHIFT 8 11562306a36Sopenharmony_ci#define USB20_CON_B2_TSTMOD_MASK GENMASK(10, USB20_CON_B2_TSTMOD_SHIFT) 11662306a36Sopenharmony_ci#define USB20_CON_B2_TSTMOD(n) (((n) << USB20_CON_B2_TSTMOD_SHIFT) & \ 11762306a36Sopenharmony_ci USB20_CON_B2_TSTMOD_MASK) 11862306a36Sopenharmony_ci#define USB20_CON_B2_TSTMOD_EN BIT(0) 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* USB30_CON */ 12162306a36Sopenharmony_ci#define USB30_CON_POW_SEL_SHIFT 24 12262306a36Sopenharmony_ci#define USB30_CON_POW_SEL_MASK GENMASK(26, USB30_CON_POW_SEL_SHIFT) 12362306a36Sopenharmony_ci#define USB30_CON_POW_SEL_IN_U3 BIT(26) 12462306a36Sopenharmony_ci#define USB30_CON_POW_SEL_IN_DISCON 0 12562306a36Sopenharmony_ci#define USB30_CON_POW_SEL_P2_TO_P0 BIT(25) 12662306a36Sopenharmony_ci#define USB30_CON_POW_SEL_P0_TO_P3 BIT(24) 12762306a36Sopenharmony_ci#define USB30_CON_POW_SEL_P0_TO_P2 0 12862306a36Sopenharmony_ci#define USB30_CON_B3_PLLWAKE BIT(23) 12962306a36Sopenharmony_ci#define USB30_CON_B3_CONNECT BIT(17) 13062306a36Sopenharmony_ci#define USB30_CON_B3_HOTRST_CMP BIT(1) 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci/* USB_STA */ 13362306a36Sopenharmony_ci#define USB_STA_SPEED_MASK (BIT(2) | BIT(1)) 13462306a36Sopenharmony_ci#define USB_STA_SPEED_HS BIT(2) 13562306a36Sopenharmony_ci#define USB_STA_SPEED_FS BIT(1) 13662306a36Sopenharmony_ci#define USB_STA_SPEED_SS 0 13762306a36Sopenharmony_ci#define USB_STA_VBUS_STA BIT(0) 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci/* DRD_CON */ 14062306a36Sopenharmony_ci#define DRD_CON_PERI_RST BIT(31) /* rzv2m only */ 14162306a36Sopenharmony_ci#define DRD_CON_HOST_RST BIT(30) /* rzv2m only */ 14262306a36Sopenharmony_ci#define DRD_CON_PERI_CON BIT(24) 14362306a36Sopenharmony_ci#define DRD_CON_VBOUT BIT(0) 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci/* USB_INT_ENA_1 and USB_INT_STA_1 */ 14662306a36Sopenharmony_ci#define USB_INT_1_B3_PLLWKUP BIT(31) 14762306a36Sopenharmony_ci#define USB_INT_1_B3_LUPSUCS BIT(30) 14862306a36Sopenharmony_ci#define USB_INT_1_B3_DISABLE BIT(27) 14962306a36Sopenharmony_ci#define USB_INT_1_B3_WRMRST BIT(21) 15062306a36Sopenharmony_ci#define USB_INT_1_B3_HOTRST BIT(20) 15162306a36Sopenharmony_ci#define USB_INT_1_B2_USBRST BIT(12) 15262306a36Sopenharmony_ci#define USB_INT_1_B2_L1SPND BIT(11) 15362306a36Sopenharmony_ci#define USB_INT_1_B2_SPND BIT(9) 15462306a36Sopenharmony_ci#define USB_INT_1_B2_RSUM BIT(8) 15562306a36Sopenharmony_ci#define USB_INT_1_SPEED BIT(1) 15662306a36Sopenharmony_ci#define USB_INT_1_VBUS_CNG BIT(0) 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci/* USB_INT_ENA_2 and USB_INT_STA_2 */ 15962306a36Sopenharmony_ci#define USB_INT_2_PIPE(n) BIT(n) 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* USB_OTG_STA, USB_OTG_INT_STA and USB_OTG_INT_ENA */ 16262306a36Sopenharmony_ci#define USB_OTG_IDMON(p) ((p)->is_rzv2m ? BIT(0) : BIT(4)) 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci/* P0_MOD */ 16562306a36Sopenharmony_ci#define P0_MOD_DIR BIT(6) 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/* P0_CON and PN_CON */ 16862306a36Sopenharmony_ci#define PX_CON_BYTE_EN_MASK (BIT(10) | BIT(9)) 16962306a36Sopenharmony_ci#define PX_CON_BYTE_EN_SHIFT 9 17062306a36Sopenharmony_ci#define PX_CON_BYTE_EN_BYTES(n) (((n) << PX_CON_BYTE_EN_SHIFT) & \ 17162306a36Sopenharmony_ci PX_CON_BYTE_EN_MASK) 17262306a36Sopenharmony_ci#define PX_CON_SEND BIT(8) 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci/* P0_CON */ 17562306a36Sopenharmony_ci#define P0_CON_ST_RES_MASK (BIT(27) | BIT(26)) 17662306a36Sopenharmony_ci#define P0_CON_ST_RES_FORCE_STALL BIT(27) 17762306a36Sopenharmony_ci#define P0_CON_ST_RES_NORMAL BIT(26) 17862306a36Sopenharmony_ci#define P0_CON_ST_RES_FORCE_NRDY 0 17962306a36Sopenharmony_ci#define P0_CON_OT_RES_MASK (BIT(25) | BIT(24)) 18062306a36Sopenharmony_ci#define P0_CON_OT_RES_FORCE_STALL BIT(25) 18162306a36Sopenharmony_ci#define P0_CON_OT_RES_NORMAL BIT(24) 18262306a36Sopenharmony_ci#define P0_CON_OT_RES_FORCE_NRDY 0 18362306a36Sopenharmony_ci#define P0_CON_IN_RES_MASK (BIT(17) | BIT(16)) 18462306a36Sopenharmony_ci#define P0_CON_IN_RES_FORCE_STALL BIT(17) 18562306a36Sopenharmony_ci#define P0_CON_IN_RES_NORMAL BIT(16) 18662306a36Sopenharmony_ci#define P0_CON_IN_RES_FORCE_NRDY 0 18762306a36Sopenharmony_ci#define P0_CON_RES_WEN BIT(7) 18862306a36Sopenharmony_ci#define P0_CON_BCLR BIT(1) 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/* P0_STA and PN_STA */ 19162306a36Sopenharmony_ci#define PX_STA_BUFSTS BIT(0) 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci/* P0_INT_ENA and P0_INT_STA */ 19462306a36Sopenharmony_ci#define P0_INT_STSED BIT(18) 19562306a36Sopenharmony_ci#define P0_INT_STSST BIT(17) 19662306a36Sopenharmony_ci#define P0_INT_SETUP BIT(16) 19762306a36Sopenharmony_ci#define P0_INT_RCVNL BIT(8) 19862306a36Sopenharmony_ci#define P0_INT_ERDY BIT(7) 19962306a36Sopenharmony_ci#define P0_INT_FLOW BIT(6) 20062306a36Sopenharmony_ci#define P0_INT_STALL BIT(2) 20162306a36Sopenharmony_ci#define P0_INT_NRDY BIT(1) 20262306a36Sopenharmony_ci#define P0_INT_BFRDY BIT(0) 20362306a36Sopenharmony_ci#define P0_INT_ALL_BITS (P0_INT_STSED | P0_INT_SETUP | P0_INT_BFRDY) 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci/* PN_MOD */ 20662306a36Sopenharmony_ci#define PN_MOD_DIR BIT(6) 20762306a36Sopenharmony_ci#define PN_MOD_TYPE_SHIFT 4 20862306a36Sopenharmony_ci#define PN_MOD_TYPE_MASK GENMASK(5, PN_MOD_TYPE_SHIFT) 20962306a36Sopenharmony_ci#define PN_MOD_TYPE(n) (((n) << PN_MOD_TYPE_SHIFT) & \ 21062306a36Sopenharmony_ci PN_MOD_TYPE_MASK) 21162306a36Sopenharmony_ci#define PN_MOD_EPNUM_MASK GENMASK(3, 0) 21262306a36Sopenharmony_ci#define PN_MOD_EPNUM(n) ((n) & PN_MOD_EPNUM_MASK) 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/* PN_RAMMAP */ 21562306a36Sopenharmony_ci#define PN_RAMMAP_RAMAREA_SHIFT 29 21662306a36Sopenharmony_ci#define PN_RAMMAP_RAMAREA_MASK GENMASK(31, PN_RAMMAP_RAMAREA_SHIFT) 21762306a36Sopenharmony_ci#define PN_RAMMAP_RAMAREA_16KB BIT(31) 21862306a36Sopenharmony_ci#define PN_RAMMAP_RAMAREA_8KB (BIT(30) | BIT(29)) 21962306a36Sopenharmony_ci#define PN_RAMMAP_RAMAREA_4KB BIT(30) 22062306a36Sopenharmony_ci#define PN_RAMMAP_RAMAREA_2KB BIT(29) 22162306a36Sopenharmony_ci#define PN_RAMMAP_RAMAREA_1KB 0 22262306a36Sopenharmony_ci#define PN_RAMMAP_MPKT_SHIFT 16 22362306a36Sopenharmony_ci#define PN_RAMMAP_MPKT_MASK GENMASK(26, PN_RAMMAP_MPKT_SHIFT) 22462306a36Sopenharmony_ci#define PN_RAMMAP_MPKT(n) (((n) << PN_RAMMAP_MPKT_SHIFT) & \ 22562306a36Sopenharmony_ci PN_RAMMAP_MPKT_MASK) 22662306a36Sopenharmony_ci#define PN_RAMMAP_RAMIF_SHIFT 14 22762306a36Sopenharmony_ci#define PN_RAMMAP_RAMIF_MASK GENMASK(15, PN_RAMMAP_RAMIF_SHIFT) 22862306a36Sopenharmony_ci#define PN_RAMMAP_RAMIF(n) (((n) << PN_RAMMAP_RAMIF_SHIFT) & \ 22962306a36Sopenharmony_ci PN_RAMMAP_RAMIF_MASK) 23062306a36Sopenharmony_ci#define PN_RAMMAP_BASEAD_MASK GENMASK(13, 0) 23162306a36Sopenharmony_ci#define PN_RAMMAP_BASEAD(offs) (((offs) >> 3) & PN_RAMMAP_BASEAD_MASK) 23262306a36Sopenharmony_ci#define PN_RAMMAP_DATA(area, ramif, basead) ((PN_RAMMAP_##area) | \ 23362306a36Sopenharmony_ci (PN_RAMMAP_RAMIF(ramif)) | \ 23462306a36Sopenharmony_ci (PN_RAMMAP_BASEAD(basead))) 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci/* PN_CON */ 23762306a36Sopenharmony_ci#define PN_CON_EN BIT(31) 23862306a36Sopenharmony_ci#define PN_CON_DATAIF_EN BIT(30) 23962306a36Sopenharmony_ci#define PN_CON_RES_MASK (BIT(17) | BIT(16)) 24062306a36Sopenharmony_ci#define PN_CON_RES_FORCE_STALL BIT(17) 24162306a36Sopenharmony_ci#define PN_CON_RES_NORMAL BIT(16) 24262306a36Sopenharmony_ci#define PN_CON_RES_FORCE_NRDY 0 24362306a36Sopenharmony_ci#define PN_CON_LAST BIT(11) 24462306a36Sopenharmony_ci#define PN_CON_RES_WEN BIT(7) 24562306a36Sopenharmony_ci#define PN_CON_CLR BIT(0) 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci/* PN_INT_STA and PN_INT_ENA */ 24862306a36Sopenharmony_ci#define PN_INT_LSTTR BIT(4) 24962306a36Sopenharmony_ci#define PN_INT_BFRDY BIT(0) 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/* USB3_SSIFCMD */ 25262306a36Sopenharmony_ci#define SSIFCMD_URES_U2 BIT(9) 25362306a36Sopenharmony_ci#define SSIFCMD_URES_U1 BIT(8) 25462306a36Sopenharmony_ci#define SSIFCMD_UDIR_U2 BIT(7) 25562306a36Sopenharmony_ci#define SSIFCMD_UDIR_U1 BIT(6) 25662306a36Sopenharmony_ci#define SSIFCMD_UREQ_U2 BIT(5) 25762306a36Sopenharmony_ci#define SSIFCMD_UREQ_U1 BIT(4) 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci#define USB3_EP0_SS_MAX_PACKET_SIZE 512 26062306a36Sopenharmony_ci#define USB3_EP0_HSFS_MAX_PACKET_SIZE 64 26162306a36Sopenharmony_ci#define USB3_EP0_BUF_SIZE 8 26262306a36Sopenharmony_ci#define USB3_MAX_NUM_PIPES(p) ((p)->is_rzv2m ? 16 : 6) /* This includes PIPE 0 */ 26362306a36Sopenharmony_ci#define USB3_WAIT_US 3 26462306a36Sopenharmony_ci#define USB3_DMA_NUM_SETTING_AREA 4 26562306a36Sopenharmony_ci/* 26662306a36Sopenharmony_ci * To avoid double-meaning of "0" (xferred 65536 bytes or received zlp if 26762306a36Sopenharmony_ci * buffer size is 65536), this driver uses the maximum size per a entry is 26862306a36Sopenharmony_ci * 32768 bytes. 26962306a36Sopenharmony_ci */ 27062306a36Sopenharmony_ci#define USB3_DMA_MAX_XFER_SIZE 32768 27162306a36Sopenharmony_ci#define USB3_DMA_PRD_SIZE 4096 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cistruct renesas_usb3; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci/* Physical Region Descriptor Table */ 27662306a36Sopenharmony_cistruct renesas_usb3_prd { 27762306a36Sopenharmony_ci u32 word1; 27862306a36Sopenharmony_ci#define USB3_PRD1_E BIT(30) /* the end of chain */ 27962306a36Sopenharmony_ci#define USB3_PRD1_U BIT(29) /* completion of transfer */ 28062306a36Sopenharmony_ci#define USB3_PRD1_D BIT(28) /* Error occurred */ 28162306a36Sopenharmony_ci#define USB3_PRD1_INT BIT(27) /* Interrupt occurred */ 28262306a36Sopenharmony_ci#define USB3_PRD1_LST BIT(26) /* Last Packet */ 28362306a36Sopenharmony_ci#define USB3_PRD1_B_INC BIT(24) 28462306a36Sopenharmony_ci#define USB3_PRD1_MPS_8 0 28562306a36Sopenharmony_ci#define USB3_PRD1_MPS_16 BIT(21) 28662306a36Sopenharmony_ci#define USB3_PRD1_MPS_32 BIT(22) 28762306a36Sopenharmony_ci#define USB3_PRD1_MPS_64 (BIT(22) | BIT(21)) 28862306a36Sopenharmony_ci#define USB3_PRD1_MPS_512 BIT(23) 28962306a36Sopenharmony_ci#define USB3_PRD1_MPS_1024 (BIT(23) | BIT(21)) 29062306a36Sopenharmony_ci#define USB3_PRD1_MPS_RESERVED (BIT(23) | BIT(22) | BIT(21)) 29162306a36Sopenharmony_ci#define USB3_PRD1_SIZE_MASK GENMASK(15, 0) 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci u32 bap; 29462306a36Sopenharmony_ci}; 29562306a36Sopenharmony_ci#define USB3_DMA_NUM_PRD_ENTRIES (USB3_DMA_PRD_SIZE / \ 29662306a36Sopenharmony_ci sizeof(struct renesas_usb3_prd)) 29762306a36Sopenharmony_ci#define USB3_DMA_MAX_XFER_SIZE_ALL_PRDS (USB3_DMA_PRD_SIZE / \ 29862306a36Sopenharmony_ci sizeof(struct renesas_usb3_prd) * \ 29962306a36Sopenharmony_ci USB3_DMA_MAX_XFER_SIZE) 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_cistruct renesas_usb3_dma { 30262306a36Sopenharmony_ci struct renesas_usb3_prd *prd; 30362306a36Sopenharmony_ci dma_addr_t prd_dma; 30462306a36Sopenharmony_ci int num; /* Setting area number (from 1 to 4) */ 30562306a36Sopenharmony_ci bool used; 30662306a36Sopenharmony_ci}; 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_cistruct renesas_usb3_request { 30962306a36Sopenharmony_ci struct usb_request req; 31062306a36Sopenharmony_ci struct list_head queue; 31162306a36Sopenharmony_ci}; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci#define USB3_EP_NAME_SIZE 8 31462306a36Sopenharmony_cistruct renesas_usb3_ep { 31562306a36Sopenharmony_ci struct usb_ep ep; 31662306a36Sopenharmony_ci struct renesas_usb3 *usb3; 31762306a36Sopenharmony_ci struct renesas_usb3_dma *dma; 31862306a36Sopenharmony_ci int num; 31962306a36Sopenharmony_ci char ep_name[USB3_EP_NAME_SIZE]; 32062306a36Sopenharmony_ci struct list_head queue; 32162306a36Sopenharmony_ci u32 rammap_val; 32262306a36Sopenharmony_ci bool dir_in; 32362306a36Sopenharmony_ci bool halt; 32462306a36Sopenharmony_ci bool wedge; 32562306a36Sopenharmony_ci bool started; 32662306a36Sopenharmony_ci}; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_cistruct renesas_usb3_priv { 32962306a36Sopenharmony_ci int ramsize_per_ramif; /* unit = bytes */ 33062306a36Sopenharmony_ci int num_ramif; 33162306a36Sopenharmony_ci int ramsize_per_pipe; /* unit = bytes */ 33262306a36Sopenharmony_ci bool workaround_for_vbus; /* if true, don't check vbus signal */ 33362306a36Sopenharmony_ci bool is_rzv2m; /* if true, RZ/V2M SoC */ 33462306a36Sopenharmony_ci}; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cistruct renesas_usb3 { 33762306a36Sopenharmony_ci void __iomem *reg; 33862306a36Sopenharmony_ci void __iomem *drd_reg; 33962306a36Sopenharmony_ci struct reset_control *usbp_rstc; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci struct usb_gadget gadget; 34262306a36Sopenharmony_ci struct usb_gadget_driver *driver; 34362306a36Sopenharmony_ci struct extcon_dev *extcon; 34462306a36Sopenharmony_ci struct work_struct extcon_work; 34562306a36Sopenharmony_ci struct phy *phy; 34662306a36Sopenharmony_ci struct dentry *dentry; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci struct usb_role_switch *role_sw; 34962306a36Sopenharmony_ci struct device *host_dev; 35062306a36Sopenharmony_ci struct work_struct role_work; 35162306a36Sopenharmony_ci enum usb_role role; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep; 35462306a36Sopenharmony_ci int num_usb3_eps; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci struct renesas_usb3_dma dma[USB3_DMA_NUM_SETTING_AREA]; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci spinlock_t lock; 35962306a36Sopenharmony_ci int disabled_count; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci struct usb_request *ep0_req; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci enum usb_role connection_state; 36462306a36Sopenharmony_ci u16 test_mode; 36562306a36Sopenharmony_ci u8 ep0_buf[USB3_EP0_BUF_SIZE]; 36662306a36Sopenharmony_ci bool softconnect; 36762306a36Sopenharmony_ci bool workaround_for_vbus; 36862306a36Sopenharmony_ci bool extcon_host; /* check id and set EXTCON_USB_HOST */ 36962306a36Sopenharmony_ci bool extcon_usb; /* check vbus and set EXTCON_USB */ 37062306a36Sopenharmony_ci bool forced_b_device; 37162306a36Sopenharmony_ci bool start_to_connect; 37262306a36Sopenharmony_ci bool role_sw_by_connector; 37362306a36Sopenharmony_ci bool is_rzv2m; 37462306a36Sopenharmony_ci}; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci#define gadget_to_renesas_usb3(_gadget) \ 37762306a36Sopenharmony_ci container_of(_gadget, struct renesas_usb3, gadget) 37862306a36Sopenharmony_ci#define renesas_usb3_to_gadget(renesas_usb3) (&renesas_usb3->gadget) 37962306a36Sopenharmony_ci#define usb3_to_dev(_usb3) (_usb3->gadget.dev.parent) 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci#define usb_ep_to_usb3_ep(_ep) container_of(_ep, struct renesas_usb3_ep, ep) 38262306a36Sopenharmony_ci#define usb3_ep_to_usb3(_usb3_ep) (_usb3_ep->usb3) 38362306a36Sopenharmony_ci#define usb_req_to_usb3_req(_req) container_of(_req, \ 38462306a36Sopenharmony_ci struct renesas_usb3_request, req) 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci#define usb3_get_ep(usb3, n) ((usb3)->usb3_ep + (n)) 38762306a36Sopenharmony_ci#define usb3_for_each_ep(usb3_ep, usb3, i) \ 38862306a36Sopenharmony_ci for ((i) = 0, usb3_ep = usb3_get_ep(usb3, (i)); \ 38962306a36Sopenharmony_ci (i) < (usb3)->num_usb3_eps; \ 39062306a36Sopenharmony_ci (i)++, usb3_ep = usb3_get_ep(usb3, (i))) 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci#define usb3_get_dma(usb3, i) (&(usb3)->dma[i]) 39362306a36Sopenharmony_ci#define usb3_for_each_dma(usb3, dma, i) \ 39462306a36Sopenharmony_ci for ((i) = 0, dma = usb3_get_dma((usb3), (i)); \ 39562306a36Sopenharmony_ci (i) < USB3_DMA_NUM_SETTING_AREA; \ 39662306a36Sopenharmony_ci (i)++, dma = usb3_get_dma((usb3), (i))) 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_cistatic const char udc_name[] = "renesas_usb3"; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_cistatic bool use_dma = 1; 40162306a36Sopenharmony_cimodule_param(use_dma, bool, 0644); 40262306a36Sopenharmony_ciMODULE_PARM_DESC(use_dma, "use dedicated DMAC"); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_cistatic void usb3_write(struct renesas_usb3 *usb3, u32 data, u32 offs) 40562306a36Sopenharmony_ci{ 40662306a36Sopenharmony_ci iowrite32(data, usb3->reg + offs); 40762306a36Sopenharmony_ci} 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_cistatic u32 usb3_read(struct renesas_usb3 *usb3, u32 offs) 41062306a36Sopenharmony_ci{ 41162306a36Sopenharmony_ci return ioread32(usb3->reg + offs); 41262306a36Sopenharmony_ci} 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_cistatic void usb3_set_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci u32 val = usb3_read(usb3, offs); 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci val |= bits; 41962306a36Sopenharmony_ci usb3_write(usb3, val, offs); 42062306a36Sopenharmony_ci} 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cistatic void usb3_clear_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) 42362306a36Sopenharmony_ci{ 42462306a36Sopenharmony_ci u32 val = usb3_read(usb3, offs); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci val &= ~bits; 42762306a36Sopenharmony_ci usb3_write(usb3, val, offs); 42862306a36Sopenharmony_ci} 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_cistatic void usb3_drd_write(struct renesas_usb3 *usb3, u32 data, u32 offs) 43162306a36Sopenharmony_ci{ 43262306a36Sopenharmony_ci void __iomem *reg; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci if (usb3->is_rzv2m) 43562306a36Sopenharmony_ci reg = usb3->drd_reg + offs - USB3_DRD_CON(usb3); 43662306a36Sopenharmony_ci else 43762306a36Sopenharmony_ci reg = usb3->reg + offs; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci iowrite32(data, reg); 44062306a36Sopenharmony_ci} 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_cistatic u32 usb3_drd_read(struct renesas_usb3 *usb3, u32 offs) 44362306a36Sopenharmony_ci{ 44462306a36Sopenharmony_ci void __iomem *reg; 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci if (usb3->is_rzv2m) 44762306a36Sopenharmony_ci reg = usb3->drd_reg + offs - USB3_DRD_CON(usb3); 44862306a36Sopenharmony_ci else 44962306a36Sopenharmony_ci reg = usb3->reg + offs; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci return ioread32(reg); 45262306a36Sopenharmony_ci} 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_cistatic void usb3_drd_set_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) 45562306a36Sopenharmony_ci{ 45662306a36Sopenharmony_ci u32 val = usb3_drd_read(usb3, offs); 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci val |= bits; 45962306a36Sopenharmony_ci usb3_drd_write(usb3, val, offs); 46062306a36Sopenharmony_ci} 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_cistatic void usb3_drd_clear_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci u32 val = usb3_drd_read(usb3, offs); 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci val &= ~bits; 46762306a36Sopenharmony_ci usb3_drd_write(usb3, val, offs); 46862306a36Sopenharmony_ci} 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_cistatic int usb3_wait(struct renesas_usb3 *usb3, u32 reg, u32 mask, 47162306a36Sopenharmony_ci u32 expected) 47262306a36Sopenharmony_ci{ 47362306a36Sopenharmony_ci int i; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci for (i = 0; i < USB3_WAIT_US; i++) { 47662306a36Sopenharmony_ci if ((usb3_read(usb3, reg) & mask) == expected) 47762306a36Sopenharmony_ci return 0; 47862306a36Sopenharmony_ci udelay(1); 47962306a36Sopenharmony_ci } 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci dev_dbg(usb3_to_dev(usb3), "%s: timed out (%8x, %08x, %08x)\n", 48262306a36Sopenharmony_ci __func__, reg, mask, expected); 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci return -EBUSY; 48562306a36Sopenharmony_ci} 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_cistatic void renesas_usb3_extcon_work(struct work_struct *work) 48862306a36Sopenharmony_ci{ 48962306a36Sopenharmony_ci struct renesas_usb3 *usb3 = container_of(work, struct renesas_usb3, 49062306a36Sopenharmony_ci extcon_work); 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci extcon_set_state_sync(usb3->extcon, EXTCON_USB_HOST, usb3->extcon_host); 49362306a36Sopenharmony_ci extcon_set_state_sync(usb3->extcon, EXTCON_USB, usb3->extcon_usb); 49462306a36Sopenharmony_ci} 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_cistatic void usb3_enable_irq_1(struct renesas_usb3 *usb3, u32 bits) 49762306a36Sopenharmony_ci{ 49862306a36Sopenharmony_ci usb3_set_bit(usb3, bits, USB3_USB_INT_ENA_1); 49962306a36Sopenharmony_ci} 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_cistatic void usb3_disable_irq_1(struct renesas_usb3 *usb3, u32 bits) 50262306a36Sopenharmony_ci{ 50362306a36Sopenharmony_ci usb3_clear_bit(usb3, bits, USB3_USB_INT_ENA_1); 50462306a36Sopenharmony_ci} 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistatic void usb3_enable_pipe_irq(struct renesas_usb3 *usb3, int num) 50762306a36Sopenharmony_ci{ 50862306a36Sopenharmony_ci usb3_set_bit(usb3, USB_INT_2_PIPE(num), USB3_USB_INT_ENA_2); 50962306a36Sopenharmony_ci} 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_cistatic void usb3_disable_pipe_irq(struct renesas_usb3 *usb3, int num) 51262306a36Sopenharmony_ci{ 51362306a36Sopenharmony_ci usb3_clear_bit(usb3, USB_INT_2_PIPE(num), USB3_USB_INT_ENA_2); 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cistatic bool usb3_is_host(struct renesas_usb3 *usb3) 51762306a36Sopenharmony_ci{ 51862306a36Sopenharmony_ci return !(usb3_drd_read(usb3, USB3_DRD_CON(usb3)) & DRD_CON_PERI_CON); 51962306a36Sopenharmony_ci} 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_cistatic void usb3_init_axi_bridge(struct renesas_usb3 *usb3) 52262306a36Sopenharmony_ci{ 52362306a36Sopenharmony_ci /* Set AXI_INT */ 52462306a36Sopenharmony_ci usb3_write(usb3, ~0, USB3_DMA_INT_STA); 52562306a36Sopenharmony_ci usb3_write(usb3, 0, USB3_DMA_INT_ENA); 52662306a36Sopenharmony_ci usb3_set_bit(usb3, AXI_INT_DMAINT | AXI_INT_EPCINT, USB3_AXI_INT_ENA); 52762306a36Sopenharmony_ci} 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_cistatic void usb3_init_epc_registers(struct renesas_usb3 *usb3) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci usb3_write(usb3, ~0, USB3_USB_INT_STA_1); 53262306a36Sopenharmony_ci if (!usb3->workaround_for_vbus) 53362306a36Sopenharmony_ci usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG); 53462306a36Sopenharmony_ci} 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistatic bool usb3_wakeup_usb2_phy(struct renesas_usb3 *usb3) 53762306a36Sopenharmony_ci{ 53862306a36Sopenharmony_ci if (!(usb3_read(usb3, USB3_USB20_CON) & USB20_CON_B2_SUSPEND)) 53962306a36Sopenharmony_ci return true; /* already waked it up */ 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci usb3_clear_bit(usb3, USB20_CON_B2_SUSPEND, USB3_USB20_CON); 54262306a36Sopenharmony_ci usb3_enable_irq_1(usb3, USB_INT_1_B2_RSUM); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci return false; 54562306a36Sopenharmony_ci} 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_cistatic void usb3_usb2_pullup(struct renesas_usb3 *usb3, int pullup) 54862306a36Sopenharmony_ci{ 54962306a36Sopenharmony_ci u32 bits = USB20_CON_B2_PUE | USB20_CON_B2_CONNECT; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci if (usb3->softconnect && pullup) 55262306a36Sopenharmony_ci usb3_set_bit(usb3, bits, USB3_USB20_CON); 55362306a36Sopenharmony_ci else 55462306a36Sopenharmony_ci usb3_clear_bit(usb3, bits, USB3_USB20_CON); 55562306a36Sopenharmony_ci} 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_cistatic void usb3_set_test_mode(struct renesas_usb3 *usb3) 55862306a36Sopenharmony_ci{ 55962306a36Sopenharmony_ci u32 val = usb3_read(usb3, USB3_USB20_CON); 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci val &= ~USB20_CON_B2_TSTMOD_MASK; 56262306a36Sopenharmony_ci val |= USB20_CON_B2_TSTMOD(usb3->test_mode); 56362306a36Sopenharmony_ci usb3_write(usb3, val | USB20_CON_B2_TSTMOD_EN, USB3_USB20_CON); 56462306a36Sopenharmony_ci if (!usb3->test_mode) 56562306a36Sopenharmony_ci usb3_clear_bit(usb3, USB20_CON_B2_TSTMOD_EN, USB3_USB20_CON); 56662306a36Sopenharmony_ci} 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_cistatic void usb3_start_usb2_connection(struct renesas_usb3 *usb3) 56962306a36Sopenharmony_ci{ 57062306a36Sopenharmony_ci usb3->disabled_count++; 57162306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); 57262306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_SPD_MODE, USB3_USB_COM_CON); 57362306a36Sopenharmony_ci usb3_usb2_pullup(usb3, 1); 57462306a36Sopenharmony_ci} 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_cistatic int usb3_is_usb3_phy_in_u3(struct renesas_usb3 *usb3) 57762306a36Sopenharmony_ci{ 57862306a36Sopenharmony_ci return usb3_read(usb3, USB3_USB30_CON) & USB30_CON_POW_SEL_IN_U3; 57962306a36Sopenharmony_ci} 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_cistatic bool usb3_wakeup_usb3_phy(struct renesas_usb3 *usb3) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci if (!usb3_is_usb3_phy_in_u3(usb3)) 58462306a36Sopenharmony_ci return true; /* already waked it up */ 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci usb3_set_bit(usb3, USB30_CON_B3_PLLWAKE, USB3_USB30_CON); 58762306a36Sopenharmony_ci usb3_enable_irq_1(usb3, USB_INT_1_B3_PLLWKUP); 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci return false; 59062306a36Sopenharmony_ci} 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_cistatic u16 usb3_feature_get_un_enabled(struct renesas_usb3 *usb3) 59362306a36Sopenharmony_ci{ 59462306a36Sopenharmony_ci u32 mask_u2 = SSIFCMD_UDIR_U2 | SSIFCMD_UREQ_U2; 59562306a36Sopenharmony_ci u32 mask_u1 = SSIFCMD_UDIR_U1 | SSIFCMD_UREQ_U1; 59662306a36Sopenharmony_ci u32 val = usb3_read(usb3, USB3_SSIFCMD); 59762306a36Sopenharmony_ci u16 ret = 0; 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci /* Enables {U2,U1} if the bits of UDIR and UREQ are set to 0 */ 60062306a36Sopenharmony_ci if (!(val & mask_u2)) 60162306a36Sopenharmony_ci ret |= 1 << USB_DEV_STAT_U2_ENABLED; 60262306a36Sopenharmony_ci if (!(val & mask_u1)) 60362306a36Sopenharmony_ci ret |= 1 << USB_DEV_STAT_U1_ENABLED; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci return ret; 60662306a36Sopenharmony_ci} 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_cistatic void usb3_feature_u2_enable(struct renesas_usb3 *usb3, bool enable) 60962306a36Sopenharmony_ci{ 61062306a36Sopenharmony_ci u32 bits = SSIFCMD_UDIR_U2 | SSIFCMD_UREQ_U2; 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci /* Enables U2 if the bits of UDIR and UREQ are set to 0 */ 61362306a36Sopenharmony_ci if (enable) 61462306a36Sopenharmony_ci usb3_clear_bit(usb3, bits, USB3_SSIFCMD); 61562306a36Sopenharmony_ci else 61662306a36Sopenharmony_ci usb3_set_bit(usb3, bits, USB3_SSIFCMD); 61762306a36Sopenharmony_ci} 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_cistatic void usb3_feature_u1_enable(struct renesas_usb3 *usb3, bool enable) 62062306a36Sopenharmony_ci{ 62162306a36Sopenharmony_ci u32 bits = SSIFCMD_UDIR_U1 | SSIFCMD_UREQ_U1; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci /* Enables U1 if the bits of UDIR and UREQ are set to 0 */ 62462306a36Sopenharmony_ci if (enable) 62562306a36Sopenharmony_ci usb3_clear_bit(usb3, bits, USB3_SSIFCMD); 62662306a36Sopenharmony_ci else 62762306a36Sopenharmony_ci usb3_set_bit(usb3, bits, USB3_SSIFCMD); 62862306a36Sopenharmony_ci} 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_cistatic void usb3_start_operation_for_usb3(struct renesas_usb3 *usb3) 63162306a36Sopenharmony_ci{ 63262306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); 63362306a36Sopenharmony_ci usb3_clear_bit(usb3, USB_COM_CON_SPD_MODE, USB3_USB_COM_CON); 63462306a36Sopenharmony_ci usb3_set_bit(usb3, USB30_CON_B3_CONNECT, USB3_USB30_CON); 63562306a36Sopenharmony_ci} 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_cistatic void usb3_start_usb3_connection(struct renesas_usb3 *usb3) 63862306a36Sopenharmony_ci{ 63962306a36Sopenharmony_ci usb3_start_operation_for_usb3(usb3); 64062306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_RX_DETECTION, USB3_USB_COM_CON); 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci usb3_enable_irq_1(usb3, USB_INT_1_B3_LUPSUCS | USB_INT_1_B3_DISABLE | 64362306a36Sopenharmony_ci USB_INT_1_SPEED); 64462306a36Sopenharmony_ci} 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_cistatic void usb3_stop_usb3_connection(struct renesas_usb3 *usb3) 64762306a36Sopenharmony_ci{ 64862306a36Sopenharmony_ci usb3_clear_bit(usb3, USB30_CON_B3_CONNECT, USB3_USB30_CON); 64962306a36Sopenharmony_ci} 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_cistatic void usb3_transition_to_default_state(struct renesas_usb3 *usb3, 65262306a36Sopenharmony_ci bool is_usb3) 65362306a36Sopenharmony_ci{ 65462306a36Sopenharmony_ci usb3_set_bit(usb3, USB_INT_2_PIPE(0), USB3_USB_INT_ENA_2); 65562306a36Sopenharmony_ci usb3_write(usb3, P0_INT_ALL_BITS, USB3_P0_INT_STA); 65662306a36Sopenharmony_ci usb3_set_bit(usb3, P0_INT_ALL_BITS, USB3_P0_INT_ENA); 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci if (is_usb3) 65962306a36Sopenharmony_ci usb3_enable_irq_1(usb3, USB_INT_1_B3_WRMRST | 66062306a36Sopenharmony_ci USB_INT_1_B3_HOTRST); 66162306a36Sopenharmony_ci else 66262306a36Sopenharmony_ci usb3_enable_irq_1(usb3, USB_INT_1_B2_SPND | 66362306a36Sopenharmony_ci USB_INT_1_B2_L1SPND | USB_INT_1_B2_USBRST); 66462306a36Sopenharmony_ci} 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_cistatic void usb3_connect(struct renesas_usb3 *usb3) 66762306a36Sopenharmony_ci{ 66862306a36Sopenharmony_ci if (usb3_wakeup_usb3_phy(usb3)) 66962306a36Sopenharmony_ci usb3_start_usb3_connection(usb3); 67062306a36Sopenharmony_ci} 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_cistatic void usb3_reset_epc(struct renesas_usb3 *usb3) 67362306a36Sopenharmony_ci{ 67462306a36Sopenharmony_ci usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); 67562306a36Sopenharmony_ci usb3_clear_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); 67662306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_PIPE_CLR, USB3_USB_COM_CON); 67762306a36Sopenharmony_ci usb3->test_mode = 0; 67862306a36Sopenharmony_ci usb3_set_test_mode(usb3); 67962306a36Sopenharmony_ci} 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_cistatic void usb3_disconnect(struct renesas_usb3 *usb3) 68262306a36Sopenharmony_ci{ 68362306a36Sopenharmony_ci usb3->disabled_count = 0; 68462306a36Sopenharmony_ci usb3_usb2_pullup(usb3, 0); 68562306a36Sopenharmony_ci usb3_clear_bit(usb3, USB30_CON_B3_CONNECT, USB3_USB30_CON); 68662306a36Sopenharmony_ci usb3_reset_epc(usb3); 68762306a36Sopenharmony_ci usb3_disable_irq_1(usb3, USB_INT_1_B2_RSUM | USB_INT_1_B3_PLLWKUP | 68862306a36Sopenharmony_ci USB_INT_1_B3_LUPSUCS | USB_INT_1_B3_DISABLE | 68962306a36Sopenharmony_ci USB_INT_1_SPEED | USB_INT_1_B3_WRMRST | 69062306a36Sopenharmony_ci USB_INT_1_B3_HOTRST | USB_INT_1_B2_SPND | 69162306a36Sopenharmony_ci USB_INT_1_B2_L1SPND | USB_INT_1_B2_USBRST); 69262306a36Sopenharmony_ci usb3_clear_bit(usb3, USB_COM_CON_SPD_MODE, USB3_USB_COM_CON); 69362306a36Sopenharmony_ci usb3_init_epc_registers(usb3); 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci if (usb3->driver) 69662306a36Sopenharmony_ci usb3->driver->disconnect(&usb3->gadget); 69762306a36Sopenharmony_ci} 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_cistatic void usb3_check_vbus(struct renesas_usb3 *usb3) 70062306a36Sopenharmony_ci{ 70162306a36Sopenharmony_ci if (usb3->workaround_for_vbus) { 70262306a36Sopenharmony_ci usb3_connect(usb3); 70362306a36Sopenharmony_ci } else { 70462306a36Sopenharmony_ci usb3->extcon_usb = !!(usb3_read(usb3, USB3_USB_STA) & 70562306a36Sopenharmony_ci USB_STA_VBUS_STA); 70662306a36Sopenharmony_ci if (usb3->extcon_usb) 70762306a36Sopenharmony_ci usb3_connect(usb3); 70862306a36Sopenharmony_ci else 70962306a36Sopenharmony_ci usb3_disconnect(usb3); 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci schedule_work(&usb3->extcon_work); 71262306a36Sopenharmony_ci } 71362306a36Sopenharmony_ci} 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_cistatic void renesas_usb3_role_work(struct work_struct *work) 71662306a36Sopenharmony_ci{ 71762306a36Sopenharmony_ci struct renesas_usb3 *usb3 = 71862306a36Sopenharmony_ci container_of(work, struct renesas_usb3, role_work); 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci usb_role_switch_set_role(usb3->role_sw, usb3->role); 72162306a36Sopenharmony_ci} 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_cistatic void usb3_set_mode(struct renesas_usb3 *usb3, bool host) 72462306a36Sopenharmony_ci{ 72562306a36Sopenharmony_ci if (usb3->is_rzv2m) { 72662306a36Sopenharmony_ci if (host) { 72762306a36Sopenharmony_ci usb3_drd_set_bit(usb3, DRD_CON_PERI_RST, USB3_DRD_CON(usb3)); 72862306a36Sopenharmony_ci usb3_drd_clear_bit(usb3, DRD_CON_HOST_RST, USB3_DRD_CON(usb3)); 72962306a36Sopenharmony_ci } else { 73062306a36Sopenharmony_ci usb3_drd_set_bit(usb3, DRD_CON_HOST_RST, USB3_DRD_CON(usb3)); 73162306a36Sopenharmony_ci usb3_drd_clear_bit(usb3, DRD_CON_PERI_RST, USB3_DRD_CON(usb3)); 73262306a36Sopenharmony_ci } 73362306a36Sopenharmony_ci } 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci if (host) 73662306a36Sopenharmony_ci usb3_drd_clear_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON(usb3)); 73762306a36Sopenharmony_ci else 73862306a36Sopenharmony_ci usb3_drd_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON(usb3)); 73962306a36Sopenharmony_ci} 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_cistatic void usb3_set_mode_by_role_sw(struct renesas_usb3 *usb3, bool host) 74262306a36Sopenharmony_ci{ 74362306a36Sopenharmony_ci if (usb3->role_sw) { 74462306a36Sopenharmony_ci usb3->role = host ? USB_ROLE_HOST : USB_ROLE_DEVICE; 74562306a36Sopenharmony_ci schedule_work(&usb3->role_work); 74662306a36Sopenharmony_ci } else { 74762306a36Sopenharmony_ci usb3_set_mode(usb3, host); 74862306a36Sopenharmony_ci } 74962306a36Sopenharmony_ci} 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_cistatic void usb3_vbus_out(struct renesas_usb3 *usb3, bool enable) 75262306a36Sopenharmony_ci{ 75362306a36Sopenharmony_ci if (enable) 75462306a36Sopenharmony_ci usb3_drd_set_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON(usb3)); 75562306a36Sopenharmony_ci else 75662306a36Sopenharmony_ci usb3_drd_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON(usb3)); 75762306a36Sopenharmony_ci} 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_cistatic void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) 76062306a36Sopenharmony_ci{ 76162306a36Sopenharmony_ci unsigned long flags; 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 76462306a36Sopenharmony_ci if (!usb3->role_sw_by_connector || 76562306a36Sopenharmony_ci usb3->connection_state != USB_ROLE_NONE) { 76662306a36Sopenharmony_ci usb3_set_mode_by_role_sw(usb3, host); 76762306a36Sopenharmony_ci usb3_vbus_out(usb3, a_dev); 76862306a36Sopenharmony_ci } 76962306a36Sopenharmony_ci /* for A-Peripheral or forced B-device mode */ 77062306a36Sopenharmony_ci if ((!host && a_dev) || usb3->start_to_connect) 77162306a36Sopenharmony_ci usb3_connect(usb3); 77262306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 77362306a36Sopenharmony_ci} 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_cistatic bool usb3_is_a_device(struct renesas_usb3 *usb3) 77662306a36Sopenharmony_ci{ 77762306a36Sopenharmony_ci return !(usb3_drd_read(usb3, USB3_USB_OTG_STA(usb3)) & USB_OTG_IDMON(usb3)); 77862306a36Sopenharmony_ci} 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_cistatic void usb3_check_id(struct renesas_usb3 *usb3) 78162306a36Sopenharmony_ci{ 78262306a36Sopenharmony_ci usb3->extcon_host = usb3_is_a_device(usb3); 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ci if ((!usb3->role_sw_by_connector && usb3->extcon_host && 78562306a36Sopenharmony_ci !usb3->forced_b_device) || usb3->connection_state == USB_ROLE_HOST) 78662306a36Sopenharmony_ci usb3_mode_config(usb3, true, true); 78762306a36Sopenharmony_ci else 78862306a36Sopenharmony_ci usb3_mode_config(usb3, false, false); 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci schedule_work(&usb3->extcon_work); 79162306a36Sopenharmony_ci} 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_cistatic void renesas_usb3_init_controller(struct renesas_usb3 *usb3) 79462306a36Sopenharmony_ci{ 79562306a36Sopenharmony_ci usb3_init_axi_bridge(usb3); 79662306a36Sopenharmony_ci usb3_init_epc_registers(usb3); 79762306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_PN_WDATAIF_NL | 79862306a36Sopenharmony_ci USB_COM_CON_PN_RDATAIF_NL | USB_COM_CON_PN_LSTTR_PP, 79962306a36Sopenharmony_ci USB3_USB_COM_CON); 80062306a36Sopenharmony_ci usb3_drd_write(usb3, USB_OTG_IDMON(usb3), USB3_USB_OTG_INT_STA(usb3)); 80162306a36Sopenharmony_ci usb3_drd_write(usb3, USB_OTG_IDMON(usb3), USB3_USB_OTG_INT_ENA(usb3)); 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci usb3_check_id(usb3); 80462306a36Sopenharmony_ci usb3_check_vbus(usb3); 80562306a36Sopenharmony_ci} 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_cistatic void renesas_usb3_stop_controller(struct renesas_usb3 *usb3) 80862306a36Sopenharmony_ci{ 80962306a36Sopenharmony_ci usb3_disconnect(usb3); 81062306a36Sopenharmony_ci usb3_write(usb3, 0, USB3_P0_INT_ENA); 81162306a36Sopenharmony_ci usb3_drd_write(usb3, 0, USB3_USB_OTG_INT_ENA(usb3)); 81262306a36Sopenharmony_ci usb3_write(usb3, 0, USB3_USB_INT_ENA_1); 81362306a36Sopenharmony_ci usb3_write(usb3, 0, USB3_USB_INT_ENA_2); 81462306a36Sopenharmony_ci usb3_write(usb3, 0, USB3_AXI_INT_ENA); 81562306a36Sopenharmony_ci} 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_pll_wakeup(struct renesas_usb3 *usb3) 81862306a36Sopenharmony_ci{ 81962306a36Sopenharmony_ci usb3_disable_irq_1(usb3, USB_INT_1_B3_PLLWKUP); 82062306a36Sopenharmony_ci usb3_clear_bit(usb3, USB30_CON_B3_PLLWAKE, USB3_USB30_CON); 82162306a36Sopenharmony_ci usb3_start_usb3_connection(usb3); 82262306a36Sopenharmony_ci} 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_linkup_success(struct renesas_usb3 *usb3) 82562306a36Sopenharmony_ci{ 82662306a36Sopenharmony_ci usb3_transition_to_default_state(usb3, true); 82762306a36Sopenharmony_ci} 82862306a36Sopenharmony_ci 82962306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_resume(struct renesas_usb3 *usb3) 83062306a36Sopenharmony_ci{ 83162306a36Sopenharmony_ci usb3_disable_irq_1(usb3, USB_INT_1_B2_RSUM); 83262306a36Sopenharmony_ci usb3_start_usb2_connection(usb3); 83362306a36Sopenharmony_ci usb3_transition_to_default_state(usb3, false); 83462306a36Sopenharmony_ci} 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_suspend(struct renesas_usb3 *usb3) 83762306a36Sopenharmony_ci{ 83862306a36Sopenharmony_ci usb3_disable_irq_1(usb3, USB_INT_1_B2_SPND); 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci if (usb3->gadget.speed != USB_SPEED_UNKNOWN && 84162306a36Sopenharmony_ci usb3->gadget.state != USB_STATE_NOTATTACHED) { 84262306a36Sopenharmony_ci if (usb3->driver && usb3->driver->suspend) 84362306a36Sopenharmony_ci usb3->driver->suspend(&usb3->gadget); 84462306a36Sopenharmony_ci usb_gadget_set_state(&usb3->gadget, USB_STATE_SUSPENDED); 84562306a36Sopenharmony_ci } 84662306a36Sopenharmony_ci} 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_disable(struct renesas_usb3 *usb3) 84962306a36Sopenharmony_ci{ 85062306a36Sopenharmony_ci usb3_stop_usb3_connection(usb3); 85162306a36Sopenharmony_ci if (usb3_wakeup_usb2_phy(usb3)) 85262306a36Sopenharmony_ci usb3_irq_epc_int_1_resume(usb3); 85362306a36Sopenharmony_ci} 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_bus_reset(struct renesas_usb3 *usb3) 85662306a36Sopenharmony_ci{ 85762306a36Sopenharmony_ci usb3_reset_epc(usb3); 85862306a36Sopenharmony_ci if (usb3->disabled_count < 3) 85962306a36Sopenharmony_ci usb3_start_usb3_connection(usb3); 86062306a36Sopenharmony_ci else 86162306a36Sopenharmony_ci usb3_start_usb2_connection(usb3); 86262306a36Sopenharmony_ci} 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_vbus_change(struct renesas_usb3 *usb3) 86562306a36Sopenharmony_ci{ 86662306a36Sopenharmony_ci usb3_check_vbus(usb3); 86762306a36Sopenharmony_ci} 86862306a36Sopenharmony_ci 86962306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_hot_reset(struct renesas_usb3 *usb3) 87062306a36Sopenharmony_ci{ 87162306a36Sopenharmony_ci usb3_reset_epc(usb3); 87262306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci /* This bit shall be set within 12ms from the start of HotReset */ 87562306a36Sopenharmony_ci usb3_set_bit(usb3, USB30_CON_B3_HOTRST_CMP, USB3_USB30_CON); 87662306a36Sopenharmony_ci} 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_warm_reset(struct renesas_usb3 *usb3) 87962306a36Sopenharmony_ci{ 88062306a36Sopenharmony_ci usb3_reset_epc(usb3); 88162306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_EP0_EN, USB3_USB_COM_CON); 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci usb3_start_operation_for_usb3(usb3); 88462306a36Sopenharmony_ci usb3_enable_irq_1(usb3, USB_INT_1_SPEED); 88562306a36Sopenharmony_ci} 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_cistatic void usb3_irq_epc_int_1_speed(struct renesas_usb3 *usb3) 88862306a36Sopenharmony_ci{ 88962306a36Sopenharmony_ci u32 speed = usb3_read(usb3, USB3_USB_STA) & USB_STA_SPEED_MASK; 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci switch (speed) { 89262306a36Sopenharmony_ci case USB_STA_SPEED_SS: 89362306a36Sopenharmony_ci usb3->gadget.speed = USB_SPEED_SUPER; 89462306a36Sopenharmony_ci usb3->gadget.ep0->maxpacket = USB3_EP0_SS_MAX_PACKET_SIZE; 89562306a36Sopenharmony_ci break; 89662306a36Sopenharmony_ci case USB_STA_SPEED_HS: 89762306a36Sopenharmony_ci usb3->gadget.speed = USB_SPEED_HIGH; 89862306a36Sopenharmony_ci usb3->gadget.ep0->maxpacket = USB3_EP0_HSFS_MAX_PACKET_SIZE; 89962306a36Sopenharmony_ci break; 90062306a36Sopenharmony_ci case USB_STA_SPEED_FS: 90162306a36Sopenharmony_ci usb3->gadget.speed = USB_SPEED_FULL; 90262306a36Sopenharmony_ci usb3->gadget.ep0->maxpacket = USB3_EP0_HSFS_MAX_PACKET_SIZE; 90362306a36Sopenharmony_ci break; 90462306a36Sopenharmony_ci default: 90562306a36Sopenharmony_ci usb3->gadget.speed = USB_SPEED_UNKNOWN; 90662306a36Sopenharmony_ci break; 90762306a36Sopenharmony_ci } 90862306a36Sopenharmony_ci} 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_cistatic void usb3_irq_epc_int_1(struct renesas_usb3 *usb3, u32 int_sta_1) 91162306a36Sopenharmony_ci{ 91262306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_B3_PLLWKUP) 91362306a36Sopenharmony_ci usb3_irq_epc_int_1_pll_wakeup(usb3); 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_B3_LUPSUCS) 91662306a36Sopenharmony_ci usb3_irq_epc_int_1_linkup_success(usb3); 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_B3_HOTRST) 91962306a36Sopenharmony_ci usb3_irq_epc_int_1_hot_reset(usb3); 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_B3_WRMRST) 92262306a36Sopenharmony_ci usb3_irq_epc_int_1_warm_reset(usb3); 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_B3_DISABLE) 92562306a36Sopenharmony_ci usb3_irq_epc_int_1_disable(usb3); 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_B2_USBRST) 92862306a36Sopenharmony_ci usb3_irq_epc_int_1_bus_reset(usb3); 92962306a36Sopenharmony_ci 93062306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_B2_RSUM) 93162306a36Sopenharmony_ci usb3_irq_epc_int_1_resume(usb3); 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_B2_SPND) 93462306a36Sopenharmony_ci usb3_irq_epc_int_1_suspend(usb3); 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_SPEED) 93762306a36Sopenharmony_ci usb3_irq_epc_int_1_speed(usb3); 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci if (int_sta_1 & USB_INT_1_VBUS_CNG) 94062306a36Sopenharmony_ci usb3_irq_epc_int_1_vbus_change(usb3); 94162306a36Sopenharmony_ci} 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_cistatic struct renesas_usb3_request *__usb3_get_request(struct renesas_usb3_ep 94462306a36Sopenharmony_ci *usb3_ep) 94562306a36Sopenharmony_ci{ 94662306a36Sopenharmony_ci return list_first_entry_or_null(&usb3_ep->queue, 94762306a36Sopenharmony_ci struct renesas_usb3_request, queue); 94862306a36Sopenharmony_ci} 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_cistatic struct renesas_usb3_request *usb3_get_request(struct renesas_usb3_ep 95162306a36Sopenharmony_ci *usb3_ep) 95262306a36Sopenharmony_ci{ 95362306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 95462306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req; 95562306a36Sopenharmony_ci unsigned long flags; 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 95862306a36Sopenharmony_ci usb3_req = __usb3_get_request(usb3_ep); 95962306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci return usb3_req; 96262306a36Sopenharmony_ci} 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_cistatic void __usb3_request_done(struct renesas_usb3_ep *usb3_ep, 96562306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req, 96662306a36Sopenharmony_ci int status) 96762306a36Sopenharmony_ci{ 96862306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci dev_dbg(usb3_to_dev(usb3), "giveback: ep%2d, %u, %u, %d\n", 97162306a36Sopenharmony_ci usb3_ep->num, usb3_req->req.length, usb3_req->req.actual, 97262306a36Sopenharmony_ci status); 97362306a36Sopenharmony_ci usb3_req->req.status = status; 97462306a36Sopenharmony_ci usb3_ep->started = false; 97562306a36Sopenharmony_ci list_del_init(&usb3_req->queue); 97662306a36Sopenharmony_ci spin_unlock(&usb3->lock); 97762306a36Sopenharmony_ci usb_gadget_giveback_request(&usb3_ep->ep, &usb3_req->req); 97862306a36Sopenharmony_ci spin_lock(&usb3->lock); 97962306a36Sopenharmony_ci} 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_cistatic void usb3_request_done(struct renesas_usb3_ep *usb3_ep, 98262306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req, int status) 98362306a36Sopenharmony_ci{ 98462306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 98562306a36Sopenharmony_ci unsigned long flags; 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 98862306a36Sopenharmony_ci __usb3_request_done(usb3_ep, usb3_req, status); 98962306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 99062306a36Sopenharmony_ci} 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_cistatic void usb3_irq_epc_pipe0_status_end(struct renesas_usb3 *usb3) 99362306a36Sopenharmony_ci{ 99462306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); 99562306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_ci if (usb3_req) 99862306a36Sopenharmony_ci usb3_request_done(usb3_ep, usb3_req, 0); 99962306a36Sopenharmony_ci if (usb3->test_mode) 100062306a36Sopenharmony_ci usb3_set_test_mode(usb3); 100162306a36Sopenharmony_ci} 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_cistatic void usb3_get_setup_data(struct renesas_usb3 *usb3, 100462306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl) 100562306a36Sopenharmony_ci{ 100662306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); 100762306a36Sopenharmony_ci u32 *data = (u32 *)ctrl; 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci *data++ = usb3_read(usb3, USB3_STUP_DAT_0); 101062306a36Sopenharmony_ci *data = usb3_read(usb3, USB3_STUP_DAT_1); 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci /* update this driver's flag */ 101362306a36Sopenharmony_ci usb3_ep->dir_in = !!(ctrl->bRequestType & USB_DIR_IN); 101462306a36Sopenharmony_ci} 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_cistatic void usb3_set_p0_con_update_res(struct renesas_usb3 *usb3, u32 res) 101762306a36Sopenharmony_ci{ 101862306a36Sopenharmony_ci u32 val = usb3_read(usb3, USB3_P0_CON); 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci val &= ~(P0_CON_ST_RES_MASK | P0_CON_OT_RES_MASK | P0_CON_IN_RES_MASK); 102162306a36Sopenharmony_ci val |= res | P0_CON_RES_WEN; 102262306a36Sopenharmony_ci usb3_write(usb3, val, USB3_P0_CON); 102362306a36Sopenharmony_ci} 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_cistatic void usb3_set_p0_con_for_ctrl_read_data(struct renesas_usb3 *usb3) 102662306a36Sopenharmony_ci{ 102762306a36Sopenharmony_ci usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_FORCE_NRDY | 102862306a36Sopenharmony_ci P0_CON_OT_RES_FORCE_STALL | 102962306a36Sopenharmony_ci P0_CON_IN_RES_NORMAL); 103062306a36Sopenharmony_ci} 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_cistatic void usb3_set_p0_con_for_ctrl_read_status(struct renesas_usb3 *usb3) 103362306a36Sopenharmony_ci{ 103462306a36Sopenharmony_ci usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_NORMAL | 103562306a36Sopenharmony_ci P0_CON_OT_RES_FORCE_STALL | 103662306a36Sopenharmony_ci P0_CON_IN_RES_NORMAL); 103762306a36Sopenharmony_ci} 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_cistatic void usb3_set_p0_con_for_ctrl_write_data(struct renesas_usb3 *usb3) 104062306a36Sopenharmony_ci{ 104162306a36Sopenharmony_ci usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_FORCE_NRDY | 104262306a36Sopenharmony_ci P0_CON_OT_RES_NORMAL | 104362306a36Sopenharmony_ci P0_CON_IN_RES_FORCE_STALL); 104462306a36Sopenharmony_ci} 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_cistatic void usb3_set_p0_con_for_ctrl_write_status(struct renesas_usb3 *usb3) 104762306a36Sopenharmony_ci{ 104862306a36Sopenharmony_ci usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_NORMAL | 104962306a36Sopenharmony_ci P0_CON_OT_RES_NORMAL | 105062306a36Sopenharmony_ci P0_CON_IN_RES_FORCE_STALL); 105162306a36Sopenharmony_ci} 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_cistatic void usb3_set_p0_con_for_no_data(struct renesas_usb3 *usb3) 105462306a36Sopenharmony_ci{ 105562306a36Sopenharmony_ci usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_NORMAL | 105662306a36Sopenharmony_ci P0_CON_OT_RES_FORCE_STALL | 105762306a36Sopenharmony_ci P0_CON_IN_RES_FORCE_STALL); 105862306a36Sopenharmony_ci} 105962306a36Sopenharmony_ci 106062306a36Sopenharmony_cistatic void usb3_set_p0_con_stall(struct renesas_usb3 *usb3) 106162306a36Sopenharmony_ci{ 106262306a36Sopenharmony_ci usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_FORCE_STALL | 106362306a36Sopenharmony_ci P0_CON_OT_RES_FORCE_STALL | 106462306a36Sopenharmony_ci P0_CON_IN_RES_FORCE_STALL); 106562306a36Sopenharmony_ci} 106662306a36Sopenharmony_ci 106762306a36Sopenharmony_cistatic void usb3_set_p0_con_stop(struct renesas_usb3 *usb3) 106862306a36Sopenharmony_ci{ 106962306a36Sopenharmony_ci usb3_set_p0_con_update_res(usb3, P0_CON_ST_RES_FORCE_NRDY | 107062306a36Sopenharmony_ci P0_CON_OT_RES_FORCE_NRDY | 107162306a36Sopenharmony_ci P0_CON_IN_RES_FORCE_NRDY); 107262306a36Sopenharmony_ci} 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_cistatic int usb3_pn_change(struct renesas_usb3 *usb3, int num) 107562306a36Sopenharmony_ci{ 107662306a36Sopenharmony_ci if (num == 0 || num > usb3->num_usb3_eps) 107762306a36Sopenharmony_ci return -ENXIO; 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci usb3_write(usb3, num, USB3_PIPE_COM); 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_ci return 0; 108262306a36Sopenharmony_ci} 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_cistatic void usb3_set_pn_con_update_res(struct renesas_usb3 *usb3, u32 res) 108562306a36Sopenharmony_ci{ 108662306a36Sopenharmony_ci u32 val = usb3_read(usb3, USB3_PN_CON); 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci val &= ~PN_CON_RES_MASK; 108962306a36Sopenharmony_ci val |= res & PN_CON_RES_MASK; 109062306a36Sopenharmony_ci val |= PN_CON_RES_WEN; 109162306a36Sopenharmony_ci usb3_write(usb3, val, USB3_PN_CON); 109262306a36Sopenharmony_ci} 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_cistatic void usb3_pn_start(struct renesas_usb3 *usb3) 109562306a36Sopenharmony_ci{ 109662306a36Sopenharmony_ci usb3_set_pn_con_update_res(usb3, PN_CON_RES_NORMAL); 109762306a36Sopenharmony_ci} 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_cistatic void usb3_pn_stop(struct renesas_usb3 *usb3) 110062306a36Sopenharmony_ci{ 110162306a36Sopenharmony_ci usb3_set_pn_con_update_res(usb3, PN_CON_RES_FORCE_NRDY); 110262306a36Sopenharmony_ci} 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_cistatic void usb3_pn_stall(struct renesas_usb3 *usb3) 110562306a36Sopenharmony_ci{ 110662306a36Sopenharmony_ci usb3_set_pn_con_update_res(usb3, PN_CON_RES_FORCE_STALL); 110762306a36Sopenharmony_ci} 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_cistatic int usb3_pn_con_clear(struct renesas_usb3 *usb3) 111062306a36Sopenharmony_ci{ 111162306a36Sopenharmony_ci usb3_set_bit(usb3, PN_CON_CLR, USB3_PN_CON); 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci return usb3_wait(usb3, USB3_PN_CON, PN_CON_CLR, 0); 111462306a36Sopenharmony_ci} 111562306a36Sopenharmony_ci 111662306a36Sopenharmony_cistatic bool usb3_is_transfer_complete(struct renesas_usb3_ep *usb3_ep, 111762306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 111862306a36Sopenharmony_ci{ 111962306a36Sopenharmony_ci struct usb_request *req = &usb3_req->req; 112062306a36Sopenharmony_ci 112162306a36Sopenharmony_ci if ((!req->zero && req->actual == req->length) || 112262306a36Sopenharmony_ci (req->actual % usb3_ep->ep.maxpacket) || (req->length == 0)) 112362306a36Sopenharmony_ci return true; 112462306a36Sopenharmony_ci else 112562306a36Sopenharmony_ci return false; 112662306a36Sopenharmony_ci} 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_cistatic int usb3_wait_pipe_status(struct renesas_usb3_ep *usb3_ep, u32 mask) 112962306a36Sopenharmony_ci{ 113062306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 113162306a36Sopenharmony_ci u32 sta_reg = usb3_ep->num ? USB3_PN_STA : USB3_P0_STA; 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_ci return usb3_wait(usb3, sta_reg, mask, mask); 113462306a36Sopenharmony_ci} 113562306a36Sopenharmony_ci 113662306a36Sopenharmony_cistatic void usb3_set_px_con_send(struct renesas_usb3_ep *usb3_ep, int bytes, 113762306a36Sopenharmony_ci bool last) 113862306a36Sopenharmony_ci{ 113962306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 114062306a36Sopenharmony_ci u32 con_reg = usb3_ep->num ? USB3_PN_CON : USB3_P0_CON; 114162306a36Sopenharmony_ci u32 val = usb3_read(usb3, con_reg); 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci val |= PX_CON_SEND | PX_CON_BYTE_EN_BYTES(bytes); 114462306a36Sopenharmony_ci val |= (usb3_ep->num && last) ? PN_CON_LAST : 0; 114562306a36Sopenharmony_ci usb3_write(usb3, val, con_reg); 114662306a36Sopenharmony_ci} 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_cistatic int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, 114962306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req, 115062306a36Sopenharmony_ci u32 fifo_reg) 115162306a36Sopenharmony_ci{ 115262306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 115362306a36Sopenharmony_ci int i; 115462306a36Sopenharmony_ci int len = min_t(unsigned, usb3_req->req.length - usb3_req->req.actual, 115562306a36Sopenharmony_ci usb3_ep->ep.maxpacket); 115662306a36Sopenharmony_ci u8 *buf = usb3_req->req.buf + usb3_req->req.actual; 115762306a36Sopenharmony_ci u32 tmp = 0; 115862306a36Sopenharmony_ci bool is_last = !len ? true : false; 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ci if (usb3_wait_pipe_status(usb3_ep, PX_STA_BUFSTS) < 0) 116162306a36Sopenharmony_ci return -EBUSY; 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci /* Update gadget driver parameter */ 116462306a36Sopenharmony_ci usb3_req->req.actual += len; 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci /* Write data to the register */ 116762306a36Sopenharmony_ci if (len >= 4) { 116862306a36Sopenharmony_ci iowrite32_rep(usb3->reg + fifo_reg, buf, len / 4); 116962306a36Sopenharmony_ci buf += (len / 4) * 4; 117062306a36Sopenharmony_ci len %= 4; /* update len to use usb3_set_pX_con_send() */ 117162306a36Sopenharmony_ci } 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_ci if (len) { 117462306a36Sopenharmony_ci for (i = 0; i < len; i++) 117562306a36Sopenharmony_ci tmp |= buf[i] << (8 * i); 117662306a36Sopenharmony_ci usb3_write(usb3, tmp, fifo_reg); 117762306a36Sopenharmony_ci } 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_ci if (!is_last) 118062306a36Sopenharmony_ci is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); 118162306a36Sopenharmony_ci /* Send the data */ 118262306a36Sopenharmony_ci usb3_set_px_con_send(usb3_ep, len, is_last); 118362306a36Sopenharmony_ci 118462306a36Sopenharmony_ci return is_last ? 0 : -EAGAIN; 118562306a36Sopenharmony_ci} 118662306a36Sopenharmony_ci 118762306a36Sopenharmony_cistatic u32 usb3_get_received_length(struct renesas_usb3_ep *usb3_ep) 118862306a36Sopenharmony_ci{ 118962306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 119062306a36Sopenharmony_ci u32 lng_reg = usb3_ep->num ? USB3_PN_LNG : USB3_P0_LNG; 119162306a36Sopenharmony_ci 119262306a36Sopenharmony_ci return usb3_read(usb3, lng_reg); 119362306a36Sopenharmony_ci} 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_cistatic int usb3_read_pipe(struct renesas_usb3_ep *usb3_ep, 119662306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req, u32 fifo_reg) 119762306a36Sopenharmony_ci{ 119862306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 119962306a36Sopenharmony_ci int i; 120062306a36Sopenharmony_ci int len = min_t(unsigned, usb3_req->req.length - usb3_req->req.actual, 120162306a36Sopenharmony_ci usb3_get_received_length(usb3_ep)); 120262306a36Sopenharmony_ci u8 *buf = usb3_req->req.buf + usb3_req->req.actual; 120362306a36Sopenharmony_ci u32 tmp = 0; 120462306a36Sopenharmony_ci 120562306a36Sopenharmony_ci if (!len) 120662306a36Sopenharmony_ci return 0; 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_ci /* Update gadget driver parameter */ 120962306a36Sopenharmony_ci usb3_req->req.actual += len; 121062306a36Sopenharmony_ci 121162306a36Sopenharmony_ci /* Read data from the register */ 121262306a36Sopenharmony_ci if (len >= 4) { 121362306a36Sopenharmony_ci ioread32_rep(usb3->reg + fifo_reg, buf, len / 4); 121462306a36Sopenharmony_ci buf += (len / 4) * 4; 121562306a36Sopenharmony_ci len %= 4; 121662306a36Sopenharmony_ci } 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci if (len) { 121962306a36Sopenharmony_ci tmp = usb3_read(usb3, fifo_reg); 122062306a36Sopenharmony_ci for (i = 0; i < len; i++) 122162306a36Sopenharmony_ci buf[i] = (tmp >> (8 * i)) & 0xff; 122262306a36Sopenharmony_ci } 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci return usb3_is_transfer_complete(usb3_ep, usb3_req) ? 0 : -EAGAIN; 122562306a36Sopenharmony_ci} 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_cistatic void usb3_set_status_stage(struct renesas_usb3_ep *usb3_ep, 122862306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 122962306a36Sopenharmony_ci{ 123062306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_ci if (usb3_ep->dir_in) { 123362306a36Sopenharmony_ci usb3_set_p0_con_for_ctrl_read_status(usb3); 123462306a36Sopenharmony_ci } else { 123562306a36Sopenharmony_ci if (!usb3_req->req.length) 123662306a36Sopenharmony_ci usb3_set_p0_con_for_no_data(usb3); 123762306a36Sopenharmony_ci else 123862306a36Sopenharmony_ci usb3_set_p0_con_for_ctrl_write_status(usb3); 123962306a36Sopenharmony_ci } 124062306a36Sopenharmony_ci} 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_cistatic void usb3_p0_xfer(struct renesas_usb3_ep *usb3_ep, 124362306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 124462306a36Sopenharmony_ci{ 124562306a36Sopenharmony_ci int ret; 124662306a36Sopenharmony_ci 124762306a36Sopenharmony_ci if (usb3_ep->dir_in) 124862306a36Sopenharmony_ci ret = usb3_write_pipe(usb3_ep, usb3_req, USB3_P0_WRITE); 124962306a36Sopenharmony_ci else 125062306a36Sopenharmony_ci ret = usb3_read_pipe(usb3_ep, usb3_req, USB3_P0_READ); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci if (!ret) 125362306a36Sopenharmony_ci usb3_set_status_stage(usb3_ep, usb3_req); 125462306a36Sopenharmony_ci} 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_cistatic void usb3_start_pipe0(struct renesas_usb3_ep *usb3_ep, 125762306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 125862306a36Sopenharmony_ci{ 125962306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_ci if (usb3_ep->started) 126262306a36Sopenharmony_ci return; 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_ci usb3_ep->started = true; 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_ci if (usb3_ep->dir_in) { 126762306a36Sopenharmony_ci usb3_set_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); 126862306a36Sopenharmony_ci usb3_set_p0_con_for_ctrl_read_data(usb3); 126962306a36Sopenharmony_ci } else { 127062306a36Sopenharmony_ci usb3_clear_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); 127162306a36Sopenharmony_ci if (usb3_req->req.length) 127262306a36Sopenharmony_ci usb3_set_p0_con_for_ctrl_write_data(usb3); 127362306a36Sopenharmony_ci } 127462306a36Sopenharmony_ci 127562306a36Sopenharmony_ci usb3_p0_xfer(usb3_ep, usb3_req); 127662306a36Sopenharmony_ci} 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_cistatic void usb3_enable_dma_pipen(struct renesas_usb3 *usb3) 127962306a36Sopenharmony_ci{ 128062306a36Sopenharmony_ci usb3_set_bit(usb3, PN_CON_DATAIF_EN, USB3_PN_CON); 128162306a36Sopenharmony_ci} 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_cistatic void usb3_disable_dma_pipen(struct renesas_usb3 *usb3) 128462306a36Sopenharmony_ci{ 128562306a36Sopenharmony_ci usb3_clear_bit(usb3, PN_CON_DATAIF_EN, USB3_PN_CON); 128662306a36Sopenharmony_ci} 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_cistatic void usb3_enable_dma_irq(struct renesas_usb3 *usb3, int num) 128962306a36Sopenharmony_ci{ 129062306a36Sopenharmony_ci usb3_set_bit(usb3, DMA_INT(num), USB3_DMA_INT_ENA); 129162306a36Sopenharmony_ci} 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_cistatic void usb3_disable_dma_irq(struct renesas_usb3 *usb3, int num) 129462306a36Sopenharmony_ci{ 129562306a36Sopenharmony_ci usb3_clear_bit(usb3, DMA_INT(num), USB3_DMA_INT_ENA); 129662306a36Sopenharmony_ci} 129762306a36Sopenharmony_ci 129862306a36Sopenharmony_cistatic u32 usb3_dma_mps_to_prd_word1(struct renesas_usb3_ep *usb3_ep) 129962306a36Sopenharmony_ci{ 130062306a36Sopenharmony_ci switch (usb3_ep->ep.maxpacket) { 130162306a36Sopenharmony_ci case 8: 130262306a36Sopenharmony_ci return USB3_PRD1_MPS_8; 130362306a36Sopenharmony_ci case 16: 130462306a36Sopenharmony_ci return USB3_PRD1_MPS_16; 130562306a36Sopenharmony_ci case 32: 130662306a36Sopenharmony_ci return USB3_PRD1_MPS_32; 130762306a36Sopenharmony_ci case 64: 130862306a36Sopenharmony_ci return USB3_PRD1_MPS_64; 130962306a36Sopenharmony_ci case 512: 131062306a36Sopenharmony_ci return USB3_PRD1_MPS_512; 131162306a36Sopenharmony_ci case 1024: 131262306a36Sopenharmony_ci return USB3_PRD1_MPS_1024; 131362306a36Sopenharmony_ci default: 131462306a36Sopenharmony_ci return USB3_PRD1_MPS_RESERVED; 131562306a36Sopenharmony_ci } 131662306a36Sopenharmony_ci} 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_cistatic bool usb3_dma_get_setting_area(struct renesas_usb3_ep *usb3_ep, 131962306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 132062306a36Sopenharmony_ci{ 132162306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 132262306a36Sopenharmony_ci struct renesas_usb3_dma *dma; 132362306a36Sopenharmony_ci int i; 132462306a36Sopenharmony_ci bool ret = false; 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_ci if (usb3_req->req.length > USB3_DMA_MAX_XFER_SIZE_ALL_PRDS) { 132762306a36Sopenharmony_ci dev_dbg(usb3_to_dev(usb3), "%s: the length is too big (%d)\n", 132862306a36Sopenharmony_ci __func__, usb3_req->req.length); 132962306a36Sopenharmony_ci return false; 133062306a36Sopenharmony_ci } 133162306a36Sopenharmony_ci 133262306a36Sopenharmony_ci /* The driver doesn't handle zero-length packet via dmac */ 133362306a36Sopenharmony_ci if (!usb3_req->req.length) 133462306a36Sopenharmony_ci return false; 133562306a36Sopenharmony_ci 133662306a36Sopenharmony_ci if (usb3_dma_mps_to_prd_word1(usb3_ep) == USB3_PRD1_MPS_RESERVED) 133762306a36Sopenharmony_ci return false; 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_ci usb3_for_each_dma(usb3, dma, i) { 134062306a36Sopenharmony_ci if (dma->used) 134162306a36Sopenharmony_ci continue; 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_ci if (usb_gadget_map_request(&usb3->gadget, &usb3_req->req, 134462306a36Sopenharmony_ci usb3_ep->dir_in) < 0) 134562306a36Sopenharmony_ci break; 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci dma->used = true; 134862306a36Sopenharmony_ci usb3_ep->dma = dma; 134962306a36Sopenharmony_ci ret = true; 135062306a36Sopenharmony_ci break; 135162306a36Sopenharmony_ci } 135262306a36Sopenharmony_ci 135362306a36Sopenharmony_ci return ret; 135462306a36Sopenharmony_ci} 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_cistatic void usb3_dma_put_setting_area(struct renesas_usb3_ep *usb3_ep, 135762306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 135862306a36Sopenharmony_ci{ 135962306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 136062306a36Sopenharmony_ci int i; 136162306a36Sopenharmony_ci struct renesas_usb3_dma *dma; 136262306a36Sopenharmony_ci 136362306a36Sopenharmony_ci usb3_for_each_dma(usb3, dma, i) { 136462306a36Sopenharmony_ci if (usb3_ep->dma == dma) { 136562306a36Sopenharmony_ci usb_gadget_unmap_request(&usb3->gadget, &usb3_req->req, 136662306a36Sopenharmony_ci usb3_ep->dir_in); 136762306a36Sopenharmony_ci dma->used = false; 136862306a36Sopenharmony_ci usb3_ep->dma = NULL; 136962306a36Sopenharmony_ci break; 137062306a36Sopenharmony_ci } 137162306a36Sopenharmony_ci } 137262306a36Sopenharmony_ci} 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_cistatic void usb3_dma_fill_prd(struct renesas_usb3_ep *usb3_ep, 137562306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 137662306a36Sopenharmony_ci{ 137762306a36Sopenharmony_ci struct renesas_usb3_prd *cur_prd = usb3_ep->dma->prd; 137862306a36Sopenharmony_ci u32 remain = usb3_req->req.length; 137962306a36Sopenharmony_ci u32 dma = usb3_req->req.dma; 138062306a36Sopenharmony_ci u32 len; 138162306a36Sopenharmony_ci int i = 0; 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci do { 138462306a36Sopenharmony_ci len = min_t(u32, remain, USB3_DMA_MAX_XFER_SIZE) & 138562306a36Sopenharmony_ci USB3_PRD1_SIZE_MASK; 138662306a36Sopenharmony_ci cur_prd->word1 = usb3_dma_mps_to_prd_word1(usb3_ep) | 138762306a36Sopenharmony_ci USB3_PRD1_B_INC | len; 138862306a36Sopenharmony_ci cur_prd->bap = dma; 138962306a36Sopenharmony_ci remain -= len; 139062306a36Sopenharmony_ci dma += len; 139162306a36Sopenharmony_ci if (!remain || (i + 1) < USB3_DMA_NUM_PRD_ENTRIES) 139262306a36Sopenharmony_ci break; 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci cur_prd++; 139562306a36Sopenharmony_ci i++; 139662306a36Sopenharmony_ci } while (1); 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci cur_prd->word1 |= USB3_PRD1_E | USB3_PRD1_INT; 139962306a36Sopenharmony_ci if (usb3_ep->dir_in) 140062306a36Sopenharmony_ci cur_prd->word1 |= USB3_PRD1_LST; 140162306a36Sopenharmony_ci} 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_cistatic void usb3_dma_kick_prd(struct renesas_usb3_ep *usb3_ep) 140462306a36Sopenharmony_ci{ 140562306a36Sopenharmony_ci struct renesas_usb3_dma *dma = usb3_ep->dma; 140662306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 140762306a36Sopenharmony_ci u32 dma_con = DMA_COM_PIPE_NO(usb3_ep->num) | DMA_CON_PRD_EN; 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ci if (usb3_ep->dir_in) 141062306a36Sopenharmony_ci dma_con |= DMA_CON_PIPE_DIR; 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci wmb(); /* prd entries should be in system memory here */ 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_ci usb3_write(usb3, 1 << usb3_ep->num, USB3_DMA_INT_STA); 141562306a36Sopenharmony_ci usb3_write(usb3, AXI_INT_PRDEN_CLR_STA(dma->num) | 141662306a36Sopenharmony_ci AXI_INT_PRDERR_STA(dma->num), USB3_AXI_INT_STA); 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci usb3_write(usb3, dma->prd_dma, USB3_DMA_CH0_PRD_ADR(dma->num)); 141962306a36Sopenharmony_ci usb3_write(usb3, dma_con, USB3_DMA_CH0_CON(dma->num)); 142062306a36Sopenharmony_ci usb3_enable_dma_irq(usb3, usb3_ep->num); 142162306a36Sopenharmony_ci} 142262306a36Sopenharmony_ci 142362306a36Sopenharmony_cistatic void usb3_dma_stop_prd(struct renesas_usb3_ep *usb3_ep) 142462306a36Sopenharmony_ci{ 142562306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 142662306a36Sopenharmony_ci struct renesas_usb3_dma *dma = usb3_ep->dma; 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci usb3_disable_dma_irq(usb3, usb3_ep->num); 142962306a36Sopenharmony_ci usb3_write(usb3, 0, USB3_DMA_CH0_CON(dma->num)); 143062306a36Sopenharmony_ci} 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_cistatic int usb3_dma_update_status(struct renesas_usb3_ep *usb3_ep, 143362306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 143462306a36Sopenharmony_ci{ 143562306a36Sopenharmony_ci struct renesas_usb3_prd *cur_prd = usb3_ep->dma->prd; 143662306a36Sopenharmony_ci struct usb_request *req = &usb3_req->req; 143762306a36Sopenharmony_ci u32 remain, len; 143862306a36Sopenharmony_ci int i = 0; 143962306a36Sopenharmony_ci int status = 0; 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci rmb(); /* The controller updated prd entries */ 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ci do { 144462306a36Sopenharmony_ci if (cur_prd->word1 & USB3_PRD1_D) 144562306a36Sopenharmony_ci status = -EIO; 144662306a36Sopenharmony_ci if (cur_prd->word1 & USB3_PRD1_E) 144762306a36Sopenharmony_ci len = req->length % USB3_DMA_MAX_XFER_SIZE; 144862306a36Sopenharmony_ci else 144962306a36Sopenharmony_ci len = USB3_DMA_MAX_XFER_SIZE; 145062306a36Sopenharmony_ci remain = cur_prd->word1 & USB3_PRD1_SIZE_MASK; 145162306a36Sopenharmony_ci req->actual += len - remain; 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci if (cur_prd->word1 & USB3_PRD1_E || 145462306a36Sopenharmony_ci (i + 1) < USB3_DMA_NUM_PRD_ENTRIES) 145562306a36Sopenharmony_ci break; 145662306a36Sopenharmony_ci 145762306a36Sopenharmony_ci cur_prd++; 145862306a36Sopenharmony_ci i++; 145962306a36Sopenharmony_ci } while (1); 146062306a36Sopenharmony_ci 146162306a36Sopenharmony_ci return status; 146262306a36Sopenharmony_ci} 146362306a36Sopenharmony_ci 146462306a36Sopenharmony_cistatic bool usb3_dma_try_start(struct renesas_usb3_ep *usb3_ep, 146562306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 146662306a36Sopenharmony_ci{ 146762306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 146862306a36Sopenharmony_ci 146962306a36Sopenharmony_ci if (!use_dma) 147062306a36Sopenharmony_ci return false; 147162306a36Sopenharmony_ci 147262306a36Sopenharmony_ci if (usb3_dma_get_setting_area(usb3_ep, usb3_req)) { 147362306a36Sopenharmony_ci usb3_pn_stop(usb3); 147462306a36Sopenharmony_ci usb3_enable_dma_pipen(usb3); 147562306a36Sopenharmony_ci usb3_dma_fill_prd(usb3_ep, usb3_req); 147662306a36Sopenharmony_ci usb3_dma_kick_prd(usb3_ep); 147762306a36Sopenharmony_ci usb3_pn_start(usb3); 147862306a36Sopenharmony_ci return true; 147962306a36Sopenharmony_ci } 148062306a36Sopenharmony_ci 148162306a36Sopenharmony_ci return false; 148262306a36Sopenharmony_ci} 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_cistatic int usb3_dma_try_stop(struct renesas_usb3_ep *usb3_ep, 148562306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 148662306a36Sopenharmony_ci{ 148762306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 148862306a36Sopenharmony_ci unsigned long flags; 148962306a36Sopenharmony_ci int status = 0; 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 149262306a36Sopenharmony_ci if (!usb3_ep->dma) 149362306a36Sopenharmony_ci goto out; 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ci if (!usb3_pn_change(usb3, usb3_ep->num)) 149662306a36Sopenharmony_ci usb3_disable_dma_pipen(usb3); 149762306a36Sopenharmony_ci usb3_dma_stop_prd(usb3_ep); 149862306a36Sopenharmony_ci status = usb3_dma_update_status(usb3_ep, usb3_req); 149962306a36Sopenharmony_ci usb3_dma_put_setting_area(usb3_ep, usb3_req); 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ciout: 150262306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 150362306a36Sopenharmony_ci return status; 150462306a36Sopenharmony_ci} 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_cistatic int renesas_usb3_dma_free_prd(struct renesas_usb3 *usb3, 150762306a36Sopenharmony_ci struct device *dev) 150862306a36Sopenharmony_ci{ 150962306a36Sopenharmony_ci int i; 151062306a36Sopenharmony_ci struct renesas_usb3_dma *dma; 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_ci usb3_for_each_dma(usb3, dma, i) { 151362306a36Sopenharmony_ci if (dma->prd) { 151462306a36Sopenharmony_ci dma_free_coherent(dev, USB3_DMA_PRD_SIZE, 151562306a36Sopenharmony_ci dma->prd, dma->prd_dma); 151662306a36Sopenharmony_ci dma->prd = NULL; 151762306a36Sopenharmony_ci } 151862306a36Sopenharmony_ci } 151962306a36Sopenharmony_ci 152062306a36Sopenharmony_ci return 0; 152162306a36Sopenharmony_ci} 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_cistatic int renesas_usb3_dma_alloc_prd(struct renesas_usb3 *usb3, 152462306a36Sopenharmony_ci struct device *dev) 152562306a36Sopenharmony_ci{ 152662306a36Sopenharmony_ci int i; 152762306a36Sopenharmony_ci struct renesas_usb3_dma *dma; 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci if (!use_dma) 153062306a36Sopenharmony_ci return 0; 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci usb3_for_each_dma(usb3, dma, i) { 153362306a36Sopenharmony_ci dma->prd = dma_alloc_coherent(dev, USB3_DMA_PRD_SIZE, 153462306a36Sopenharmony_ci &dma->prd_dma, GFP_KERNEL); 153562306a36Sopenharmony_ci if (!dma->prd) { 153662306a36Sopenharmony_ci renesas_usb3_dma_free_prd(usb3, dev); 153762306a36Sopenharmony_ci return -ENOMEM; 153862306a36Sopenharmony_ci } 153962306a36Sopenharmony_ci dma->num = i + 1; 154062306a36Sopenharmony_ci } 154162306a36Sopenharmony_ci 154262306a36Sopenharmony_ci return 0; 154362306a36Sopenharmony_ci} 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_cistatic void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep, 154662306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req) 154762306a36Sopenharmony_ci{ 154862306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 154962306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req_first; 155062306a36Sopenharmony_ci unsigned long flags; 155162306a36Sopenharmony_ci int ret = -EAGAIN; 155262306a36Sopenharmony_ci u32 enable_bits = 0; 155362306a36Sopenharmony_ci 155462306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 155562306a36Sopenharmony_ci if (usb3_ep->halt || usb3_ep->started) 155662306a36Sopenharmony_ci goto out; 155762306a36Sopenharmony_ci usb3_req_first = __usb3_get_request(usb3_ep); 155862306a36Sopenharmony_ci if (!usb3_req_first || usb3_req != usb3_req_first) 155962306a36Sopenharmony_ci goto out; 156062306a36Sopenharmony_ci 156162306a36Sopenharmony_ci if (usb3_pn_change(usb3, usb3_ep->num) < 0) 156262306a36Sopenharmony_ci goto out; 156362306a36Sopenharmony_ci 156462306a36Sopenharmony_ci usb3_ep->started = true; 156562306a36Sopenharmony_ci 156662306a36Sopenharmony_ci if (usb3_dma_try_start(usb3_ep, usb3_req)) 156762306a36Sopenharmony_ci goto out; 156862306a36Sopenharmony_ci 156962306a36Sopenharmony_ci usb3_pn_start(usb3); 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci if (usb3_ep->dir_in) { 157262306a36Sopenharmony_ci ret = usb3_write_pipe(usb3_ep, usb3_req, USB3_PN_WRITE); 157362306a36Sopenharmony_ci enable_bits |= PN_INT_LSTTR; 157462306a36Sopenharmony_ci } 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci if (ret < 0) 157762306a36Sopenharmony_ci enable_bits |= PN_INT_BFRDY; 157862306a36Sopenharmony_ci 157962306a36Sopenharmony_ci if (enable_bits) { 158062306a36Sopenharmony_ci usb3_set_bit(usb3, enable_bits, USB3_PN_INT_ENA); 158162306a36Sopenharmony_ci usb3_enable_pipe_irq(usb3, usb3_ep->num); 158262306a36Sopenharmony_ci } 158362306a36Sopenharmony_ciout: 158462306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 158562306a36Sopenharmony_ci} 158662306a36Sopenharmony_ci 158762306a36Sopenharmony_cistatic int renesas_usb3_ep_queue(struct usb_ep *_ep, struct usb_request *_req, 158862306a36Sopenharmony_ci gfp_t gfp_flags) 158962306a36Sopenharmony_ci{ 159062306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); 159162306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req = usb_req_to_usb3_req(_req); 159262306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 159362306a36Sopenharmony_ci unsigned long flags; 159462306a36Sopenharmony_ci 159562306a36Sopenharmony_ci dev_dbg(usb3_to_dev(usb3), "ep_queue: ep%2d, %u\n", usb3_ep->num, 159662306a36Sopenharmony_ci _req->length); 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_ci _req->status = -EINPROGRESS; 159962306a36Sopenharmony_ci _req->actual = 0; 160062306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 160162306a36Sopenharmony_ci list_add_tail(&usb3_req->queue, &usb3_ep->queue); 160262306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 160362306a36Sopenharmony_ci 160462306a36Sopenharmony_ci if (!usb3_ep->num) 160562306a36Sopenharmony_ci usb3_start_pipe0(usb3_ep, usb3_req); 160662306a36Sopenharmony_ci else 160762306a36Sopenharmony_ci usb3_start_pipen(usb3_ep, usb3_req); 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci return 0; 161062306a36Sopenharmony_ci} 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_cistatic void usb3_set_device_address(struct renesas_usb3 *usb3, u16 addr) 161362306a36Sopenharmony_ci{ 161462306a36Sopenharmony_ci /* DEV_ADDR bit field is cleared by WarmReset, HotReset and BusReset */ 161562306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_DEV_ADDR(addr), USB3_USB_COM_CON); 161662306a36Sopenharmony_ci} 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_cistatic bool usb3_std_req_set_address(struct renesas_usb3 *usb3, 161962306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl) 162062306a36Sopenharmony_ci{ 162162306a36Sopenharmony_ci if (le16_to_cpu(ctrl->wValue) >= 128) 162262306a36Sopenharmony_ci return true; /* stall */ 162362306a36Sopenharmony_ci 162462306a36Sopenharmony_ci usb3_set_device_address(usb3, le16_to_cpu(ctrl->wValue)); 162562306a36Sopenharmony_ci usb3_set_p0_con_for_no_data(usb3); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci return false; 162862306a36Sopenharmony_ci} 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_cistatic void usb3_pipe0_internal_xfer(struct renesas_usb3 *usb3, 163162306a36Sopenharmony_ci void *tx_data, size_t len, 163262306a36Sopenharmony_ci void (*complete)(struct usb_ep *ep, 163362306a36Sopenharmony_ci struct usb_request *req)) 163462306a36Sopenharmony_ci{ 163562306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci if (tx_data) 163862306a36Sopenharmony_ci memcpy(usb3->ep0_buf, tx_data, 163962306a36Sopenharmony_ci min_t(size_t, len, USB3_EP0_BUF_SIZE)); 164062306a36Sopenharmony_ci 164162306a36Sopenharmony_ci usb3->ep0_req->buf = &usb3->ep0_buf; 164262306a36Sopenharmony_ci usb3->ep0_req->length = len; 164362306a36Sopenharmony_ci usb3->ep0_req->complete = complete; 164462306a36Sopenharmony_ci renesas_usb3_ep_queue(&usb3_ep->ep, usb3->ep0_req, GFP_ATOMIC); 164562306a36Sopenharmony_ci} 164662306a36Sopenharmony_ci 164762306a36Sopenharmony_cistatic void usb3_pipe0_get_status_completion(struct usb_ep *ep, 164862306a36Sopenharmony_ci struct usb_request *req) 164962306a36Sopenharmony_ci{ 165062306a36Sopenharmony_ci} 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_cistatic bool usb3_std_req_get_status(struct renesas_usb3 *usb3, 165362306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl) 165462306a36Sopenharmony_ci{ 165562306a36Sopenharmony_ci bool stall = false; 165662306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep; 165762306a36Sopenharmony_ci int num; 165862306a36Sopenharmony_ci u16 status = 0; 165962306a36Sopenharmony_ci __le16 tx_data; 166062306a36Sopenharmony_ci 166162306a36Sopenharmony_ci switch (ctrl->bRequestType & USB_RECIP_MASK) { 166262306a36Sopenharmony_ci case USB_RECIP_DEVICE: 166362306a36Sopenharmony_ci if (usb3->gadget.is_selfpowered) 166462306a36Sopenharmony_ci status |= 1 << USB_DEVICE_SELF_POWERED; 166562306a36Sopenharmony_ci if (usb3->gadget.speed == USB_SPEED_SUPER) 166662306a36Sopenharmony_ci status |= usb3_feature_get_un_enabled(usb3); 166762306a36Sopenharmony_ci break; 166862306a36Sopenharmony_ci case USB_RECIP_INTERFACE: 166962306a36Sopenharmony_ci break; 167062306a36Sopenharmony_ci case USB_RECIP_ENDPOINT: 167162306a36Sopenharmony_ci num = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; 167262306a36Sopenharmony_ci usb3_ep = usb3_get_ep(usb3, num); 167362306a36Sopenharmony_ci if (usb3_ep->halt) 167462306a36Sopenharmony_ci status |= 1 << USB_ENDPOINT_HALT; 167562306a36Sopenharmony_ci break; 167662306a36Sopenharmony_ci default: 167762306a36Sopenharmony_ci stall = true; 167862306a36Sopenharmony_ci break; 167962306a36Sopenharmony_ci } 168062306a36Sopenharmony_ci 168162306a36Sopenharmony_ci if (!stall) { 168262306a36Sopenharmony_ci tx_data = cpu_to_le16(status); 168362306a36Sopenharmony_ci dev_dbg(usb3_to_dev(usb3), "get_status: req = %p\n", 168462306a36Sopenharmony_ci usb_req_to_usb3_req(usb3->ep0_req)); 168562306a36Sopenharmony_ci usb3_pipe0_internal_xfer(usb3, &tx_data, sizeof(tx_data), 168662306a36Sopenharmony_ci usb3_pipe0_get_status_completion); 168762306a36Sopenharmony_ci } 168862306a36Sopenharmony_ci 168962306a36Sopenharmony_ci return stall; 169062306a36Sopenharmony_ci} 169162306a36Sopenharmony_ci 169262306a36Sopenharmony_cistatic bool usb3_std_req_feature_device(struct renesas_usb3 *usb3, 169362306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl, bool set) 169462306a36Sopenharmony_ci{ 169562306a36Sopenharmony_ci bool stall = true; 169662306a36Sopenharmony_ci u16 w_value = le16_to_cpu(ctrl->wValue); 169762306a36Sopenharmony_ci 169862306a36Sopenharmony_ci switch (w_value) { 169962306a36Sopenharmony_ci case USB_DEVICE_TEST_MODE: 170062306a36Sopenharmony_ci if (!set) 170162306a36Sopenharmony_ci break; 170262306a36Sopenharmony_ci usb3->test_mode = le16_to_cpu(ctrl->wIndex) >> 8; 170362306a36Sopenharmony_ci stall = false; 170462306a36Sopenharmony_ci break; 170562306a36Sopenharmony_ci case USB_DEVICE_U1_ENABLE: 170662306a36Sopenharmony_ci case USB_DEVICE_U2_ENABLE: 170762306a36Sopenharmony_ci if (usb3->gadget.speed != USB_SPEED_SUPER) 170862306a36Sopenharmony_ci break; 170962306a36Sopenharmony_ci if (w_value == USB_DEVICE_U1_ENABLE) 171062306a36Sopenharmony_ci usb3_feature_u1_enable(usb3, set); 171162306a36Sopenharmony_ci if (w_value == USB_DEVICE_U2_ENABLE) 171262306a36Sopenharmony_ci usb3_feature_u2_enable(usb3, set); 171362306a36Sopenharmony_ci stall = false; 171462306a36Sopenharmony_ci break; 171562306a36Sopenharmony_ci default: 171662306a36Sopenharmony_ci break; 171762306a36Sopenharmony_ci } 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci return stall; 172062306a36Sopenharmony_ci} 172162306a36Sopenharmony_ci 172262306a36Sopenharmony_cistatic int usb3_set_halt_p0(struct renesas_usb3_ep *usb3_ep, bool halt) 172362306a36Sopenharmony_ci{ 172462306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ci if (unlikely(usb3_ep->num)) 172762306a36Sopenharmony_ci return -EINVAL; 172862306a36Sopenharmony_ci 172962306a36Sopenharmony_ci usb3_ep->halt = halt; 173062306a36Sopenharmony_ci if (halt) 173162306a36Sopenharmony_ci usb3_set_p0_con_stall(usb3); 173262306a36Sopenharmony_ci else 173362306a36Sopenharmony_ci usb3_set_p0_con_stop(usb3); 173462306a36Sopenharmony_ci 173562306a36Sopenharmony_ci return 0; 173662306a36Sopenharmony_ci} 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_cistatic int usb3_set_halt_pn(struct renesas_usb3_ep *usb3_ep, bool halt, 173962306a36Sopenharmony_ci bool is_clear_feature) 174062306a36Sopenharmony_ci{ 174162306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 174262306a36Sopenharmony_ci unsigned long flags; 174362306a36Sopenharmony_ci 174462306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 174562306a36Sopenharmony_ci if (!usb3_pn_change(usb3, usb3_ep->num)) { 174662306a36Sopenharmony_ci usb3_ep->halt = halt; 174762306a36Sopenharmony_ci if (halt) { 174862306a36Sopenharmony_ci usb3_pn_stall(usb3); 174962306a36Sopenharmony_ci } else if (!is_clear_feature || !usb3_ep->wedge) { 175062306a36Sopenharmony_ci usb3_pn_con_clear(usb3); 175162306a36Sopenharmony_ci usb3_set_bit(usb3, PN_CON_EN, USB3_PN_CON); 175262306a36Sopenharmony_ci usb3_pn_stop(usb3); 175362306a36Sopenharmony_ci } 175462306a36Sopenharmony_ci } 175562306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 175662306a36Sopenharmony_ci 175762306a36Sopenharmony_ci return 0; 175862306a36Sopenharmony_ci} 175962306a36Sopenharmony_ci 176062306a36Sopenharmony_cistatic int usb3_set_halt(struct renesas_usb3_ep *usb3_ep, bool halt, 176162306a36Sopenharmony_ci bool is_clear_feature) 176262306a36Sopenharmony_ci{ 176362306a36Sopenharmony_ci int ret = 0; 176462306a36Sopenharmony_ci 176562306a36Sopenharmony_ci if (halt && usb3_ep->started) 176662306a36Sopenharmony_ci return -EAGAIN; 176762306a36Sopenharmony_ci 176862306a36Sopenharmony_ci if (usb3_ep->num) 176962306a36Sopenharmony_ci ret = usb3_set_halt_pn(usb3_ep, halt, is_clear_feature); 177062306a36Sopenharmony_ci else 177162306a36Sopenharmony_ci ret = usb3_set_halt_p0(usb3_ep, halt); 177262306a36Sopenharmony_ci 177362306a36Sopenharmony_ci return ret; 177462306a36Sopenharmony_ci} 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_cistatic bool usb3_std_req_feature_endpoint(struct renesas_usb3 *usb3, 177762306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl, 177862306a36Sopenharmony_ci bool set) 177962306a36Sopenharmony_ci{ 178062306a36Sopenharmony_ci int num = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; 178162306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep; 178262306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req; 178362306a36Sopenharmony_ci 178462306a36Sopenharmony_ci if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT) 178562306a36Sopenharmony_ci return true; /* stall */ 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_ci usb3_ep = usb3_get_ep(usb3, num); 178862306a36Sopenharmony_ci usb3_set_halt(usb3_ep, set, true); 178962306a36Sopenharmony_ci 179062306a36Sopenharmony_ci /* Restarts a queue if clear feature */ 179162306a36Sopenharmony_ci if (!set) { 179262306a36Sopenharmony_ci usb3_ep->started = false; 179362306a36Sopenharmony_ci usb3_req = usb3_get_request(usb3_ep); 179462306a36Sopenharmony_ci if (usb3_req) 179562306a36Sopenharmony_ci usb3_start_pipen(usb3_ep, usb3_req); 179662306a36Sopenharmony_ci } 179762306a36Sopenharmony_ci 179862306a36Sopenharmony_ci return false; 179962306a36Sopenharmony_ci} 180062306a36Sopenharmony_ci 180162306a36Sopenharmony_cistatic bool usb3_std_req_feature(struct renesas_usb3 *usb3, 180262306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl, bool set) 180362306a36Sopenharmony_ci{ 180462306a36Sopenharmony_ci bool stall = false; 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci switch (ctrl->bRequestType & USB_RECIP_MASK) { 180762306a36Sopenharmony_ci case USB_RECIP_DEVICE: 180862306a36Sopenharmony_ci stall = usb3_std_req_feature_device(usb3, ctrl, set); 180962306a36Sopenharmony_ci break; 181062306a36Sopenharmony_ci case USB_RECIP_INTERFACE: 181162306a36Sopenharmony_ci break; 181262306a36Sopenharmony_ci case USB_RECIP_ENDPOINT: 181362306a36Sopenharmony_ci stall = usb3_std_req_feature_endpoint(usb3, ctrl, set); 181462306a36Sopenharmony_ci break; 181562306a36Sopenharmony_ci default: 181662306a36Sopenharmony_ci stall = true; 181762306a36Sopenharmony_ci break; 181862306a36Sopenharmony_ci } 181962306a36Sopenharmony_ci 182062306a36Sopenharmony_ci if (!stall) 182162306a36Sopenharmony_ci usb3_set_p0_con_for_no_data(usb3); 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci return stall; 182462306a36Sopenharmony_ci} 182562306a36Sopenharmony_ci 182662306a36Sopenharmony_cistatic void usb3_pipe0_set_sel_completion(struct usb_ep *ep, 182762306a36Sopenharmony_ci struct usb_request *req) 182862306a36Sopenharmony_ci{ 182962306a36Sopenharmony_ci /* TODO */ 183062306a36Sopenharmony_ci} 183162306a36Sopenharmony_ci 183262306a36Sopenharmony_cistatic bool usb3_std_req_set_sel(struct renesas_usb3 *usb3, 183362306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl) 183462306a36Sopenharmony_ci{ 183562306a36Sopenharmony_ci u16 w_length = le16_to_cpu(ctrl->wLength); 183662306a36Sopenharmony_ci 183762306a36Sopenharmony_ci if (w_length != 6) 183862306a36Sopenharmony_ci return true; /* stall */ 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ci dev_dbg(usb3_to_dev(usb3), "set_sel: req = %p\n", 184162306a36Sopenharmony_ci usb_req_to_usb3_req(usb3->ep0_req)); 184262306a36Sopenharmony_ci usb3_pipe0_internal_xfer(usb3, NULL, 6, usb3_pipe0_set_sel_completion); 184362306a36Sopenharmony_ci 184462306a36Sopenharmony_ci return false; 184562306a36Sopenharmony_ci} 184662306a36Sopenharmony_ci 184762306a36Sopenharmony_cistatic bool usb3_std_req_set_configuration(struct renesas_usb3 *usb3, 184862306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl) 184962306a36Sopenharmony_ci{ 185062306a36Sopenharmony_ci if (le16_to_cpu(ctrl->wValue) > 0) 185162306a36Sopenharmony_ci usb3_set_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); 185262306a36Sopenharmony_ci else 185362306a36Sopenharmony_ci usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci return false; 185662306a36Sopenharmony_ci} 185762306a36Sopenharmony_ci 185862306a36Sopenharmony_ci/** 185962306a36Sopenharmony_ci * usb3_handle_standard_request - handle some standard requests 186062306a36Sopenharmony_ci * @usb3: the renesas_usb3 pointer 186162306a36Sopenharmony_ci * @ctrl: a pointer of setup data 186262306a36Sopenharmony_ci * 186362306a36Sopenharmony_ci * Returns true if this function handled a standard request 186462306a36Sopenharmony_ci */ 186562306a36Sopenharmony_cistatic bool usb3_handle_standard_request(struct renesas_usb3 *usb3, 186662306a36Sopenharmony_ci struct usb_ctrlrequest *ctrl) 186762306a36Sopenharmony_ci{ 186862306a36Sopenharmony_ci bool ret = false; 186962306a36Sopenharmony_ci bool stall = false; 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { 187262306a36Sopenharmony_ci switch (ctrl->bRequest) { 187362306a36Sopenharmony_ci case USB_REQ_SET_ADDRESS: 187462306a36Sopenharmony_ci stall = usb3_std_req_set_address(usb3, ctrl); 187562306a36Sopenharmony_ci ret = true; 187662306a36Sopenharmony_ci break; 187762306a36Sopenharmony_ci case USB_REQ_GET_STATUS: 187862306a36Sopenharmony_ci stall = usb3_std_req_get_status(usb3, ctrl); 187962306a36Sopenharmony_ci ret = true; 188062306a36Sopenharmony_ci break; 188162306a36Sopenharmony_ci case USB_REQ_CLEAR_FEATURE: 188262306a36Sopenharmony_ci stall = usb3_std_req_feature(usb3, ctrl, false); 188362306a36Sopenharmony_ci ret = true; 188462306a36Sopenharmony_ci break; 188562306a36Sopenharmony_ci case USB_REQ_SET_FEATURE: 188662306a36Sopenharmony_ci stall = usb3_std_req_feature(usb3, ctrl, true); 188762306a36Sopenharmony_ci ret = true; 188862306a36Sopenharmony_ci break; 188962306a36Sopenharmony_ci case USB_REQ_SET_SEL: 189062306a36Sopenharmony_ci stall = usb3_std_req_set_sel(usb3, ctrl); 189162306a36Sopenharmony_ci ret = true; 189262306a36Sopenharmony_ci break; 189362306a36Sopenharmony_ci case USB_REQ_SET_ISOCH_DELAY: 189462306a36Sopenharmony_ci /* This hardware doesn't support Isochronous xfer */ 189562306a36Sopenharmony_ci stall = true; 189662306a36Sopenharmony_ci ret = true; 189762306a36Sopenharmony_ci break; 189862306a36Sopenharmony_ci case USB_REQ_SET_CONFIGURATION: 189962306a36Sopenharmony_ci usb3_std_req_set_configuration(usb3, ctrl); 190062306a36Sopenharmony_ci break; 190162306a36Sopenharmony_ci default: 190262306a36Sopenharmony_ci break; 190362306a36Sopenharmony_ci } 190462306a36Sopenharmony_ci } 190562306a36Sopenharmony_ci 190662306a36Sopenharmony_ci if (stall) 190762306a36Sopenharmony_ci usb3_set_p0_con_stall(usb3); 190862306a36Sopenharmony_ci 190962306a36Sopenharmony_ci return ret; 191062306a36Sopenharmony_ci} 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_cistatic int usb3_p0_con_clear_buffer(struct renesas_usb3 *usb3) 191362306a36Sopenharmony_ci{ 191462306a36Sopenharmony_ci usb3_set_bit(usb3, P0_CON_BCLR, USB3_P0_CON); 191562306a36Sopenharmony_ci 191662306a36Sopenharmony_ci return usb3_wait(usb3, USB3_P0_CON, P0_CON_BCLR, 0); 191762306a36Sopenharmony_ci} 191862306a36Sopenharmony_ci 191962306a36Sopenharmony_cistatic void usb3_irq_epc_pipe0_setup(struct renesas_usb3 *usb3) 192062306a36Sopenharmony_ci{ 192162306a36Sopenharmony_ci struct usb_ctrlrequest ctrl; 192262306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); 192362306a36Sopenharmony_ci 192462306a36Sopenharmony_ci /* Call giveback function if previous transfer is not completed */ 192562306a36Sopenharmony_ci if (usb3_ep->started) 192662306a36Sopenharmony_ci usb3_request_done(usb3_ep, usb3_get_request(usb3_ep), 192762306a36Sopenharmony_ci -ECONNRESET); 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci usb3_p0_con_clear_buffer(usb3); 193062306a36Sopenharmony_ci usb3_get_setup_data(usb3, &ctrl); 193162306a36Sopenharmony_ci if (!usb3_handle_standard_request(usb3, &ctrl)) 193262306a36Sopenharmony_ci if (usb3->driver->setup(&usb3->gadget, &ctrl) < 0) 193362306a36Sopenharmony_ci usb3_set_p0_con_stall(usb3); 193462306a36Sopenharmony_ci} 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_cistatic void usb3_irq_epc_pipe0_bfrdy(struct renesas_usb3 *usb3) 193762306a36Sopenharmony_ci{ 193862306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, 0); 193962306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); 194062306a36Sopenharmony_ci 194162306a36Sopenharmony_ci if (!usb3_req) 194262306a36Sopenharmony_ci return; 194362306a36Sopenharmony_ci 194462306a36Sopenharmony_ci usb3_p0_xfer(usb3_ep, usb3_req); 194562306a36Sopenharmony_ci} 194662306a36Sopenharmony_ci 194762306a36Sopenharmony_cistatic void usb3_irq_epc_pipe0(struct renesas_usb3 *usb3) 194862306a36Sopenharmony_ci{ 194962306a36Sopenharmony_ci u32 p0_int_sta = usb3_read(usb3, USB3_P0_INT_STA); 195062306a36Sopenharmony_ci 195162306a36Sopenharmony_ci p0_int_sta &= usb3_read(usb3, USB3_P0_INT_ENA); 195262306a36Sopenharmony_ci usb3_write(usb3, p0_int_sta, USB3_P0_INT_STA); 195362306a36Sopenharmony_ci if (p0_int_sta & P0_INT_STSED) 195462306a36Sopenharmony_ci usb3_irq_epc_pipe0_status_end(usb3); 195562306a36Sopenharmony_ci if (p0_int_sta & P0_INT_SETUP) 195662306a36Sopenharmony_ci usb3_irq_epc_pipe0_setup(usb3); 195762306a36Sopenharmony_ci if (p0_int_sta & P0_INT_BFRDY) 195862306a36Sopenharmony_ci usb3_irq_epc_pipe0_bfrdy(usb3); 195962306a36Sopenharmony_ci} 196062306a36Sopenharmony_ci 196162306a36Sopenharmony_cistatic void usb3_request_done_pipen(struct renesas_usb3 *usb3, 196262306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep, 196362306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req, 196462306a36Sopenharmony_ci int status) 196562306a36Sopenharmony_ci{ 196662306a36Sopenharmony_ci unsigned long flags; 196762306a36Sopenharmony_ci 196862306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 196962306a36Sopenharmony_ci if (usb3_pn_change(usb3, usb3_ep->num)) 197062306a36Sopenharmony_ci usb3_pn_stop(usb3); 197162306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 197262306a36Sopenharmony_ci 197362306a36Sopenharmony_ci usb3_disable_pipe_irq(usb3, usb3_ep->num); 197462306a36Sopenharmony_ci usb3_request_done(usb3_ep, usb3_req, status); 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_ci /* get next usb3_req */ 197762306a36Sopenharmony_ci usb3_req = usb3_get_request(usb3_ep); 197862306a36Sopenharmony_ci if (usb3_req) 197962306a36Sopenharmony_ci usb3_start_pipen(usb3_ep, usb3_req); 198062306a36Sopenharmony_ci} 198162306a36Sopenharmony_ci 198262306a36Sopenharmony_cistatic void usb3_irq_epc_pipen_lsttr(struct renesas_usb3 *usb3, int num) 198362306a36Sopenharmony_ci{ 198462306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, num); 198562306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); 198662306a36Sopenharmony_ci 198762306a36Sopenharmony_ci if (!usb3_req) 198862306a36Sopenharmony_ci return; 198962306a36Sopenharmony_ci 199062306a36Sopenharmony_ci if (usb3_ep->dir_in) { 199162306a36Sopenharmony_ci dev_dbg(usb3_to_dev(usb3), "%s: len = %u, actual = %u\n", 199262306a36Sopenharmony_ci __func__, usb3_req->req.length, usb3_req->req.actual); 199362306a36Sopenharmony_ci usb3_request_done_pipen(usb3, usb3_ep, usb3_req, 0); 199462306a36Sopenharmony_ci } 199562306a36Sopenharmony_ci} 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_cistatic void usb3_irq_epc_pipen_bfrdy(struct renesas_usb3 *usb3, int num) 199862306a36Sopenharmony_ci{ 199962306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb3_get_ep(usb3, num); 200062306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req = usb3_get_request(usb3_ep); 200162306a36Sopenharmony_ci bool done = false; 200262306a36Sopenharmony_ci 200362306a36Sopenharmony_ci if (!usb3_req) 200462306a36Sopenharmony_ci return; 200562306a36Sopenharmony_ci 200662306a36Sopenharmony_ci spin_lock(&usb3->lock); 200762306a36Sopenharmony_ci if (usb3_pn_change(usb3, num)) 200862306a36Sopenharmony_ci goto out; 200962306a36Sopenharmony_ci 201062306a36Sopenharmony_ci if (usb3_ep->dir_in) { 201162306a36Sopenharmony_ci /* Do not stop the IN pipe here to detect LSTTR interrupt */ 201262306a36Sopenharmony_ci if (!usb3_write_pipe(usb3_ep, usb3_req, USB3_PN_WRITE)) 201362306a36Sopenharmony_ci usb3_clear_bit(usb3, PN_INT_BFRDY, USB3_PN_INT_ENA); 201462306a36Sopenharmony_ci } else { 201562306a36Sopenharmony_ci if (!usb3_read_pipe(usb3_ep, usb3_req, USB3_PN_READ)) 201662306a36Sopenharmony_ci done = true; 201762306a36Sopenharmony_ci } 201862306a36Sopenharmony_ci 201962306a36Sopenharmony_ciout: 202062306a36Sopenharmony_ci /* need to unlock because usb3_request_done_pipen() locks it */ 202162306a36Sopenharmony_ci spin_unlock(&usb3->lock); 202262306a36Sopenharmony_ci 202362306a36Sopenharmony_ci if (done) 202462306a36Sopenharmony_ci usb3_request_done_pipen(usb3, usb3_ep, usb3_req, 0); 202562306a36Sopenharmony_ci} 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_cistatic void usb3_irq_epc_pipen(struct renesas_usb3 *usb3, int num) 202862306a36Sopenharmony_ci{ 202962306a36Sopenharmony_ci u32 pn_int_sta; 203062306a36Sopenharmony_ci 203162306a36Sopenharmony_ci spin_lock(&usb3->lock); 203262306a36Sopenharmony_ci if (usb3_pn_change(usb3, num) < 0) { 203362306a36Sopenharmony_ci spin_unlock(&usb3->lock); 203462306a36Sopenharmony_ci return; 203562306a36Sopenharmony_ci } 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_ci pn_int_sta = usb3_read(usb3, USB3_PN_INT_STA); 203862306a36Sopenharmony_ci pn_int_sta &= usb3_read(usb3, USB3_PN_INT_ENA); 203962306a36Sopenharmony_ci usb3_write(usb3, pn_int_sta, USB3_PN_INT_STA); 204062306a36Sopenharmony_ci spin_unlock(&usb3->lock); 204162306a36Sopenharmony_ci if (pn_int_sta & PN_INT_LSTTR) 204262306a36Sopenharmony_ci usb3_irq_epc_pipen_lsttr(usb3, num); 204362306a36Sopenharmony_ci if (pn_int_sta & PN_INT_BFRDY) 204462306a36Sopenharmony_ci usb3_irq_epc_pipen_bfrdy(usb3, num); 204562306a36Sopenharmony_ci} 204662306a36Sopenharmony_ci 204762306a36Sopenharmony_cistatic void usb3_irq_epc_int_2(struct renesas_usb3 *usb3, u32 int_sta_2) 204862306a36Sopenharmony_ci{ 204962306a36Sopenharmony_ci int i; 205062306a36Sopenharmony_ci 205162306a36Sopenharmony_ci for (i = 0; i < usb3->num_usb3_eps; i++) { 205262306a36Sopenharmony_ci if (int_sta_2 & USB_INT_2_PIPE(i)) { 205362306a36Sopenharmony_ci if (!i) 205462306a36Sopenharmony_ci usb3_irq_epc_pipe0(usb3); 205562306a36Sopenharmony_ci else 205662306a36Sopenharmony_ci usb3_irq_epc_pipen(usb3, i); 205762306a36Sopenharmony_ci } 205862306a36Sopenharmony_ci } 205962306a36Sopenharmony_ci} 206062306a36Sopenharmony_ci 206162306a36Sopenharmony_cistatic void usb3_irq_idmon_change(struct renesas_usb3 *usb3) 206262306a36Sopenharmony_ci{ 206362306a36Sopenharmony_ci usb3_check_id(usb3); 206462306a36Sopenharmony_ci} 206562306a36Sopenharmony_ci 206662306a36Sopenharmony_cistatic void usb3_irq_otg_int(struct renesas_usb3 *usb3) 206762306a36Sopenharmony_ci{ 206862306a36Sopenharmony_ci u32 otg_int_sta = usb3_drd_read(usb3, USB3_USB_OTG_INT_STA(usb3)); 206962306a36Sopenharmony_ci 207062306a36Sopenharmony_ci otg_int_sta &= usb3_drd_read(usb3, USB3_USB_OTG_INT_ENA(usb3)); 207162306a36Sopenharmony_ci if (otg_int_sta) 207262306a36Sopenharmony_ci usb3_drd_write(usb3, otg_int_sta, USB3_USB_OTG_INT_STA(usb3)); 207362306a36Sopenharmony_ci 207462306a36Sopenharmony_ci if (otg_int_sta & USB_OTG_IDMON(usb3)) 207562306a36Sopenharmony_ci usb3_irq_idmon_change(usb3); 207662306a36Sopenharmony_ci} 207762306a36Sopenharmony_ci 207862306a36Sopenharmony_cistatic void usb3_irq_epc(struct renesas_usb3 *usb3) 207962306a36Sopenharmony_ci{ 208062306a36Sopenharmony_ci u32 int_sta_1 = usb3_read(usb3, USB3_USB_INT_STA_1); 208162306a36Sopenharmony_ci u32 int_sta_2 = usb3_read(usb3, USB3_USB_INT_STA_2); 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci int_sta_1 &= usb3_read(usb3, USB3_USB_INT_ENA_1); 208462306a36Sopenharmony_ci if (int_sta_1) { 208562306a36Sopenharmony_ci usb3_write(usb3, int_sta_1, USB3_USB_INT_STA_1); 208662306a36Sopenharmony_ci usb3_irq_epc_int_1(usb3, int_sta_1); 208762306a36Sopenharmony_ci } 208862306a36Sopenharmony_ci 208962306a36Sopenharmony_ci int_sta_2 &= usb3_read(usb3, USB3_USB_INT_ENA_2); 209062306a36Sopenharmony_ci if (int_sta_2) 209162306a36Sopenharmony_ci usb3_irq_epc_int_2(usb3, int_sta_2); 209262306a36Sopenharmony_ci 209362306a36Sopenharmony_ci if (!usb3->is_rzv2m) 209462306a36Sopenharmony_ci usb3_irq_otg_int(usb3); 209562306a36Sopenharmony_ci} 209662306a36Sopenharmony_ci 209762306a36Sopenharmony_cistatic void usb3_irq_dma_int(struct renesas_usb3 *usb3, u32 dma_sta) 209862306a36Sopenharmony_ci{ 209962306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep; 210062306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req; 210162306a36Sopenharmony_ci int i, status; 210262306a36Sopenharmony_ci 210362306a36Sopenharmony_ci for (i = 0; i < usb3->num_usb3_eps; i++) { 210462306a36Sopenharmony_ci if (!(dma_sta & DMA_INT(i))) 210562306a36Sopenharmony_ci continue; 210662306a36Sopenharmony_ci 210762306a36Sopenharmony_ci usb3_ep = usb3_get_ep(usb3, i); 210862306a36Sopenharmony_ci if (!(usb3_read(usb3, USB3_AXI_INT_STA) & 210962306a36Sopenharmony_ci AXI_INT_PRDEN_CLR_STA(usb3_ep->dma->num))) 211062306a36Sopenharmony_ci continue; 211162306a36Sopenharmony_ci 211262306a36Sopenharmony_ci usb3_req = usb3_get_request(usb3_ep); 211362306a36Sopenharmony_ci status = usb3_dma_try_stop(usb3_ep, usb3_req); 211462306a36Sopenharmony_ci usb3_request_done_pipen(usb3, usb3_ep, usb3_req, status); 211562306a36Sopenharmony_ci } 211662306a36Sopenharmony_ci} 211762306a36Sopenharmony_ci 211862306a36Sopenharmony_cistatic void usb3_irq_dma(struct renesas_usb3 *usb3) 211962306a36Sopenharmony_ci{ 212062306a36Sopenharmony_ci u32 dma_sta = usb3_read(usb3, USB3_DMA_INT_STA); 212162306a36Sopenharmony_ci 212262306a36Sopenharmony_ci dma_sta &= usb3_read(usb3, USB3_DMA_INT_ENA); 212362306a36Sopenharmony_ci if (dma_sta) { 212462306a36Sopenharmony_ci usb3_write(usb3, dma_sta, USB3_DMA_INT_STA); 212562306a36Sopenharmony_ci usb3_irq_dma_int(usb3, dma_sta); 212662306a36Sopenharmony_ci } 212762306a36Sopenharmony_ci} 212862306a36Sopenharmony_ci 212962306a36Sopenharmony_cistatic irqreturn_t renesas_usb3_irq(int irq, void *_usb3) 213062306a36Sopenharmony_ci{ 213162306a36Sopenharmony_ci struct renesas_usb3 *usb3 = _usb3; 213262306a36Sopenharmony_ci irqreturn_t ret = IRQ_NONE; 213362306a36Sopenharmony_ci u32 axi_int_sta = usb3_read(usb3, USB3_AXI_INT_STA); 213462306a36Sopenharmony_ci 213562306a36Sopenharmony_ci if (axi_int_sta & AXI_INT_DMAINT) { 213662306a36Sopenharmony_ci usb3_irq_dma(usb3); 213762306a36Sopenharmony_ci ret = IRQ_HANDLED; 213862306a36Sopenharmony_ci } 213962306a36Sopenharmony_ci 214062306a36Sopenharmony_ci if (axi_int_sta & AXI_INT_EPCINT) { 214162306a36Sopenharmony_ci usb3_irq_epc(usb3); 214262306a36Sopenharmony_ci ret = IRQ_HANDLED; 214362306a36Sopenharmony_ci } 214462306a36Sopenharmony_ci 214562306a36Sopenharmony_ci return ret; 214662306a36Sopenharmony_ci} 214762306a36Sopenharmony_ci 214862306a36Sopenharmony_cistatic irqreturn_t renesas_usb3_otg_irq(int irq, void *_usb3) 214962306a36Sopenharmony_ci{ 215062306a36Sopenharmony_ci struct renesas_usb3 *usb3 = _usb3; 215162306a36Sopenharmony_ci 215262306a36Sopenharmony_ci usb3_irq_otg_int(usb3); 215362306a36Sopenharmony_ci 215462306a36Sopenharmony_ci return IRQ_HANDLED; 215562306a36Sopenharmony_ci} 215662306a36Sopenharmony_ci 215762306a36Sopenharmony_cistatic void usb3_write_pn_mod(struct renesas_usb3_ep *usb3_ep, 215862306a36Sopenharmony_ci const struct usb_endpoint_descriptor *desc) 215962306a36Sopenharmony_ci{ 216062306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 216162306a36Sopenharmony_ci u32 val = 0; 216262306a36Sopenharmony_ci 216362306a36Sopenharmony_ci val |= usb3_ep->dir_in ? PN_MOD_DIR : 0; 216462306a36Sopenharmony_ci val |= PN_MOD_TYPE(usb_endpoint_type(desc)); 216562306a36Sopenharmony_ci val |= PN_MOD_EPNUM(usb_endpoint_num(desc)); 216662306a36Sopenharmony_ci usb3_write(usb3, val, USB3_PN_MOD); 216762306a36Sopenharmony_ci} 216862306a36Sopenharmony_ci 216962306a36Sopenharmony_cistatic u32 usb3_calc_ramarea(int ram_size) 217062306a36Sopenharmony_ci{ 217162306a36Sopenharmony_ci WARN_ON(ram_size > SZ_16K); 217262306a36Sopenharmony_ci 217362306a36Sopenharmony_ci if (ram_size <= SZ_1K) 217462306a36Sopenharmony_ci return PN_RAMMAP_RAMAREA_1KB; 217562306a36Sopenharmony_ci else if (ram_size <= SZ_2K) 217662306a36Sopenharmony_ci return PN_RAMMAP_RAMAREA_2KB; 217762306a36Sopenharmony_ci else if (ram_size <= SZ_4K) 217862306a36Sopenharmony_ci return PN_RAMMAP_RAMAREA_4KB; 217962306a36Sopenharmony_ci else if (ram_size <= SZ_8K) 218062306a36Sopenharmony_ci return PN_RAMMAP_RAMAREA_8KB; 218162306a36Sopenharmony_ci else 218262306a36Sopenharmony_ci return PN_RAMMAP_RAMAREA_16KB; 218362306a36Sopenharmony_ci} 218462306a36Sopenharmony_ci 218562306a36Sopenharmony_cistatic u32 usb3_calc_rammap_val(struct renesas_usb3_ep *usb3_ep, 218662306a36Sopenharmony_ci const struct usb_endpoint_descriptor *desc) 218762306a36Sopenharmony_ci{ 218862306a36Sopenharmony_ci int i; 218962306a36Sopenharmony_ci static const u32 max_packet_array[] = {8, 16, 32, 64, 512}; 219062306a36Sopenharmony_ci u32 mpkt = PN_RAMMAP_MPKT(1024); 219162306a36Sopenharmony_ci 219262306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(max_packet_array); i++) { 219362306a36Sopenharmony_ci if (usb_endpoint_maxp(desc) <= max_packet_array[i]) 219462306a36Sopenharmony_ci mpkt = PN_RAMMAP_MPKT(max_packet_array[i]); 219562306a36Sopenharmony_ci } 219662306a36Sopenharmony_ci 219762306a36Sopenharmony_ci return usb3_ep->rammap_val | mpkt; 219862306a36Sopenharmony_ci} 219962306a36Sopenharmony_ci 220062306a36Sopenharmony_cistatic int usb3_enable_pipe_n(struct renesas_usb3_ep *usb3_ep, 220162306a36Sopenharmony_ci const struct usb_endpoint_descriptor *desc) 220262306a36Sopenharmony_ci{ 220362306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 220462306a36Sopenharmony_ci unsigned long flags; 220562306a36Sopenharmony_ci 220662306a36Sopenharmony_ci usb3_ep->dir_in = usb_endpoint_dir_in(desc); 220762306a36Sopenharmony_ci 220862306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 220962306a36Sopenharmony_ci if (!usb3_pn_change(usb3, usb3_ep->num)) { 221062306a36Sopenharmony_ci usb3_write_pn_mod(usb3_ep, desc); 221162306a36Sopenharmony_ci usb3_write(usb3, usb3_calc_rammap_val(usb3_ep, desc), 221262306a36Sopenharmony_ci USB3_PN_RAMMAP); 221362306a36Sopenharmony_ci usb3_pn_con_clear(usb3); 221462306a36Sopenharmony_ci usb3_set_bit(usb3, PN_CON_EN, USB3_PN_CON); 221562306a36Sopenharmony_ci } 221662306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 221762306a36Sopenharmony_ci 221862306a36Sopenharmony_ci return 0; 221962306a36Sopenharmony_ci} 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_cistatic int usb3_disable_pipe_n(struct renesas_usb3_ep *usb3_ep) 222262306a36Sopenharmony_ci{ 222362306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 222462306a36Sopenharmony_ci unsigned long flags; 222562306a36Sopenharmony_ci 222662306a36Sopenharmony_ci usb3_ep->halt = false; 222762306a36Sopenharmony_ci 222862306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 222962306a36Sopenharmony_ci if (!usb3_pn_change(usb3, usb3_ep->num)) { 223062306a36Sopenharmony_ci usb3_write(usb3, 0, USB3_PN_INT_ENA); 223162306a36Sopenharmony_ci usb3_write(usb3, 0, USB3_PN_RAMMAP); 223262306a36Sopenharmony_ci usb3_clear_bit(usb3, PN_CON_EN, USB3_PN_CON); 223362306a36Sopenharmony_ci } 223462306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 223562306a36Sopenharmony_ci 223662306a36Sopenharmony_ci return 0; 223762306a36Sopenharmony_ci} 223862306a36Sopenharmony_ci 223962306a36Sopenharmony_ci/*------- usb_ep_ops -----------------------------------------------------*/ 224062306a36Sopenharmony_cistatic int renesas_usb3_ep_enable(struct usb_ep *_ep, 224162306a36Sopenharmony_ci const struct usb_endpoint_descriptor *desc) 224262306a36Sopenharmony_ci{ 224362306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); 224462306a36Sopenharmony_ci 224562306a36Sopenharmony_ci return usb3_enable_pipe_n(usb3_ep, desc); 224662306a36Sopenharmony_ci} 224762306a36Sopenharmony_ci 224862306a36Sopenharmony_cistatic int renesas_usb3_ep_disable(struct usb_ep *_ep) 224962306a36Sopenharmony_ci{ 225062306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); 225162306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req; 225262306a36Sopenharmony_ci 225362306a36Sopenharmony_ci do { 225462306a36Sopenharmony_ci usb3_req = usb3_get_request(usb3_ep); 225562306a36Sopenharmony_ci if (!usb3_req) 225662306a36Sopenharmony_ci break; 225762306a36Sopenharmony_ci usb3_dma_try_stop(usb3_ep, usb3_req); 225862306a36Sopenharmony_ci usb3_request_done(usb3_ep, usb3_req, -ESHUTDOWN); 225962306a36Sopenharmony_ci } while (1); 226062306a36Sopenharmony_ci 226162306a36Sopenharmony_ci return usb3_disable_pipe_n(usb3_ep); 226262306a36Sopenharmony_ci} 226362306a36Sopenharmony_ci 226462306a36Sopenharmony_cistatic struct usb_request *__renesas_usb3_ep_alloc_request(gfp_t gfp_flags) 226562306a36Sopenharmony_ci{ 226662306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req; 226762306a36Sopenharmony_ci 226862306a36Sopenharmony_ci usb3_req = kzalloc(sizeof(struct renesas_usb3_request), gfp_flags); 226962306a36Sopenharmony_ci if (!usb3_req) 227062306a36Sopenharmony_ci return NULL; 227162306a36Sopenharmony_ci 227262306a36Sopenharmony_ci INIT_LIST_HEAD(&usb3_req->queue); 227362306a36Sopenharmony_ci 227462306a36Sopenharmony_ci return &usb3_req->req; 227562306a36Sopenharmony_ci} 227662306a36Sopenharmony_ci 227762306a36Sopenharmony_cistatic void __renesas_usb3_ep_free_request(struct usb_request *_req) 227862306a36Sopenharmony_ci{ 227962306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req = usb_req_to_usb3_req(_req); 228062306a36Sopenharmony_ci 228162306a36Sopenharmony_ci kfree(usb3_req); 228262306a36Sopenharmony_ci} 228362306a36Sopenharmony_ci 228462306a36Sopenharmony_cistatic struct usb_request *renesas_usb3_ep_alloc_request(struct usb_ep *_ep, 228562306a36Sopenharmony_ci gfp_t gfp_flags) 228662306a36Sopenharmony_ci{ 228762306a36Sopenharmony_ci return __renesas_usb3_ep_alloc_request(gfp_flags); 228862306a36Sopenharmony_ci} 228962306a36Sopenharmony_ci 229062306a36Sopenharmony_cistatic void renesas_usb3_ep_free_request(struct usb_ep *_ep, 229162306a36Sopenharmony_ci struct usb_request *_req) 229262306a36Sopenharmony_ci{ 229362306a36Sopenharmony_ci __renesas_usb3_ep_free_request(_req); 229462306a36Sopenharmony_ci} 229562306a36Sopenharmony_ci 229662306a36Sopenharmony_cistatic int renesas_usb3_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) 229762306a36Sopenharmony_ci{ 229862306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); 229962306a36Sopenharmony_ci struct renesas_usb3_request *usb3_req = usb_req_to_usb3_req(_req); 230062306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 230162306a36Sopenharmony_ci 230262306a36Sopenharmony_ci dev_dbg(usb3_to_dev(usb3), "ep_dequeue: ep%2d, %u\n", usb3_ep->num, 230362306a36Sopenharmony_ci _req->length); 230462306a36Sopenharmony_ci 230562306a36Sopenharmony_ci usb3_dma_try_stop(usb3_ep, usb3_req); 230662306a36Sopenharmony_ci usb3_request_done_pipen(usb3, usb3_ep, usb3_req, -ECONNRESET); 230762306a36Sopenharmony_ci 230862306a36Sopenharmony_ci return 0; 230962306a36Sopenharmony_ci} 231062306a36Sopenharmony_ci 231162306a36Sopenharmony_cistatic int renesas_usb3_ep_set_halt(struct usb_ep *_ep, int value) 231262306a36Sopenharmony_ci{ 231362306a36Sopenharmony_ci return usb3_set_halt(usb_ep_to_usb3_ep(_ep), !!value, false); 231462306a36Sopenharmony_ci} 231562306a36Sopenharmony_ci 231662306a36Sopenharmony_cistatic int renesas_usb3_ep_set_wedge(struct usb_ep *_ep) 231762306a36Sopenharmony_ci{ 231862306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); 231962306a36Sopenharmony_ci 232062306a36Sopenharmony_ci usb3_ep->wedge = true; 232162306a36Sopenharmony_ci return usb3_set_halt(usb3_ep, true, false); 232262306a36Sopenharmony_ci} 232362306a36Sopenharmony_ci 232462306a36Sopenharmony_cistatic void renesas_usb3_ep_fifo_flush(struct usb_ep *_ep) 232562306a36Sopenharmony_ci{ 232662306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep = usb_ep_to_usb3_ep(_ep); 232762306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); 232862306a36Sopenharmony_ci unsigned long flags; 232962306a36Sopenharmony_ci 233062306a36Sopenharmony_ci if (usb3_ep->num) { 233162306a36Sopenharmony_ci spin_lock_irqsave(&usb3->lock, flags); 233262306a36Sopenharmony_ci if (!usb3_pn_change(usb3, usb3_ep->num)) { 233362306a36Sopenharmony_ci usb3_pn_con_clear(usb3); 233462306a36Sopenharmony_ci usb3_set_bit(usb3, PN_CON_EN, USB3_PN_CON); 233562306a36Sopenharmony_ci } 233662306a36Sopenharmony_ci spin_unlock_irqrestore(&usb3->lock, flags); 233762306a36Sopenharmony_ci } else { 233862306a36Sopenharmony_ci usb3_p0_con_clear_buffer(usb3); 233962306a36Sopenharmony_ci } 234062306a36Sopenharmony_ci} 234162306a36Sopenharmony_ci 234262306a36Sopenharmony_cistatic const struct usb_ep_ops renesas_usb3_ep_ops = { 234362306a36Sopenharmony_ci .enable = renesas_usb3_ep_enable, 234462306a36Sopenharmony_ci .disable = renesas_usb3_ep_disable, 234562306a36Sopenharmony_ci 234662306a36Sopenharmony_ci .alloc_request = renesas_usb3_ep_alloc_request, 234762306a36Sopenharmony_ci .free_request = renesas_usb3_ep_free_request, 234862306a36Sopenharmony_ci 234962306a36Sopenharmony_ci .queue = renesas_usb3_ep_queue, 235062306a36Sopenharmony_ci .dequeue = renesas_usb3_ep_dequeue, 235162306a36Sopenharmony_ci 235262306a36Sopenharmony_ci .set_halt = renesas_usb3_ep_set_halt, 235362306a36Sopenharmony_ci .set_wedge = renesas_usb3_ep_set_wedge, 235462306a36Sopenharmony_ci .fifo_flush = renesas_usb3_ep_fifo_flush, 235562306a36Sopenharmony_ci}; 235662306a36Sopenharmony_ci 235762306a36Sopenharmony_ci/*------- usb_gadget_ops -------------------------------------------------*/ 235862306a36Sopenharmony_cistatic int renesas_usb3_start(struct usb_gadget *gadget, 235962306a36Sopenharmony_ci struct usb_gadget_driver *driver) 236062306a36Sopenharmony_ci{ 236162306a36Sopenharmony_ci struct renesas_usb3 *usb3; 236262306a36Sopenharmony_ci 236362306a36Sopenharmony_ci if (!driver || driver->max_speed < USB_SPEED_FULL || 236462306a36Sopenharmony_ci !driver->setup) 236562306a36Sopenharmony_ci return -EINVAL; 236662306a36Sopenharmony_ci 236762306a36Sopenharmony_ci usb3 = gadget_to_renesas_usb3(gadget); 236862306a36Sopenharmony_ci 236962306a36Sopenharmony_ci if (usb3->is_rzv2m && usb3_is_a_device(usb3)) 237062306a36Sopenharmony_ci return -EBUSY; 237162306a36Sopenharmony_ci 237262306a36Sopenharmony_ci /* hook up the driver */ 237362306a36Sopenharmony_ci usb3->driver = driver; 237462306a36Sopenharmony_ci 237562306a36Sopenharmony_ci if (usb3->phy) 237662306a36Sopenharmony_ci phy_init(usb3->phy); 237762306a36Sopenharmony_ci 237862306a36Sopenharmony_ci pm_runtime_get_sync(usb3_to_dev(usb3)); 237962306a36Sopenharmony_ci 238062306a36Sopenharmony_ci /* Peripheral Reset */ 238162306a36Sopenharmony_ci if (usb3->is_rzv2m) 238262306a36Sopenharmony_ci rzv2m_usb3drd_reset(usb3_to_dev(usb3)->parent, false); 238362306a36Sopenharmony_ci 238462306a36Sopenharmony_ci renesas_usb3_init_controller(usb3); 238562306a36Sopenharmony_ci 238662306a36Sopenharmony_ci return 0; 238762306a36Sopenharmony_ci} 238862306a36Sopenharmony_ci 238962306a36Sopenharmony_cistatic int renesas_usb3_stop(struct usb_gadget *gadget) 239062306a36Sopenharmony_ci{ 239162306a36Sopenharmony_ci struct renesas_usb3 *usb3 = gadget_to_renesas_usb3(gadget); 239262306a36Sopenharmony_ci 239362306a36Sopenharmony_ci usb3->softconnect = false; 239462306a36Sopenharmony_ci usb3->gadget.speed = USB_SPEED_UNKNOWN; 239562306a36Sopenharmony_ci usb3->driver = NULL; 239662306a36Sopenharmony_ci if (usb3->is_rzv2m) 239762306a36Sopenharmony_ci rzv2m_usb3drd_reset(usb3_to_dev(usb3)->parent, false); 239862306a36Sopenharmony_ci 239962306a36Sopenharmony_ci renesas_usb3_stop_controller(usb3); 240062306a36Sopenharmony_ci if (usb3->phy) 240162306a36Sopenharmony_ci phy_exit(usb3->phy); 240262306a36Sopenharmony_ci 240362306a36Sopenharmony_ci pm_runtime_put(usb3_to_dev(usb3)); 240462306a36Sopenharmony_ci 240562306a36Sopenharmony_ci return 0; 240662306a36Sopenharmony_ci} 240762306a36Sopenharmony_ci 240862306a36Sopenharmony_cistatic int renesas_usb3_get_frame(struct usb_gadget *_gadget) 240962306a36Sopenharmony_ci{ 241062306a36Sopenharmony_ci return -EOPNOTSUPP; 241162306a36Sopenharmony_ci} 241262306a36Sopenharmony_ci 241362306a36Sopenharmony_cistatic int renesas_usb3_pullup(struct usb_gadget *gadget, int is_on) 241462306a36Sopenharmony_ci{ 241562306a36Sopenharmony_ci struct renesas_usb3 *usb3 = gadget_to_renesas_usb3(gadget); 241662306a36Sopenharmony_ci 241762306a36Sopenharmony_ci usb3->softconnect = !!is_on; 241862306a36Sopenharmony_ci 241962306a36Sopenharmony_ci return 0; 242062306a36Sopenharmony_ci} 242162306a36Sopenharmony_ci 242262306a36Sopenharmony_cistatic int renesas_usb3_set_selfpowered(struct usb_gadget *gadget, int is_self) 242362306a36Sopenharmony_ci{ 242462306a36Sopenharmony_ci gadget->is_selfpowered = !!is_self; 242562306a36Sopenharmony_ci 242662306a36Sopenharmony_ci return 0; 242762306a36Sopenharmony_ci} 242862306a36Sopenharmony_ci 242962306a36Sopenharmony_cistatic const struct usb_gadget_ops renesas_usb3_gadget_ops = { 243062306a36Sopenharmony_ci .get_frame = renesas_usb3_get_frame, 243162306a36Sopenharmony_ci .udc_start = renesas_usb3_start, 243262306a36Sopenharmony_ci .udc_stop = renesas_usb3_stop, 243362306a36Sopenharmony_ci .pullup = renesas_usb3_pullup, 243462306a36Sopenharmony_ci .set_selfpowered = renesas_usb3_set_selfpowered, 243562306a36Sopenharmony_ci}; 243662306a36Sopenharmony_ci 243762306a36Sopenharmony_cistatic enum usb_role renesas_usb3_role_switch_get(struct usb_role_switch *sw) 243862306a36Sopenharmony_ci{ 243962306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb_role_switch_get_drvdata(sw); 244062306a36Sopenharmony_ci enum usb_role cur_role; 244162306a36Sopenharmony_ci 244262306a36Sopenharmony_ci pm_runtime_get_sync(usb3_to_dev(usb3)); 244362306a36Sopenharmony_ci cur_role = usb3_is_host(usb3) ? USB_ROLE_HOST : USB_ROLE_DEVICE; 244462306a36Sopenharmony_ci pm_runtime_put(usb3_to_dev(usb3)); 244562306a36Sopenharmony_ci 244662306a36Sopenharmony_ci return cur_role; 244762306a36Sopenharmony_ci} 244862306a36Sopenharmony_ci 244962306a36Sopenharmony_cistatic void handle_ext_role_switch_states(struct device *dev, 245062306a36Sopenharmony_ci enum usb_role role) 245162306a36Sopenharmony_ci{ 245262306a36Sopenharmony_ci struct renesas_usb3 *usb3 = dev_get_drvdata(dev); 245362306a36Sopenharmony_ci struct device *host = usb3->host_dev; 245462306a36Sopenharmony_ci enum usb_role cur_role = renesas_usb3_role_switch_get(usb3->role_sw); 245562306a36Sopenharmony_ci 245662306a36Sopenharmony_ci switch (role) { 245762306a36Sopenharmony_ci case USB_ROLE_NONE: 245862306a36Sopenharmony_ci usb3->connection_state = USB_ROLE_NONE; 245962306a36Sopenharmony_ci if (!usb3->is_rzv2m && cur_role == USB_ROLE_HOST) 246062306a36Sopenharmony_ci device_release_driver(host); 246162306a36Sopenharmony_ci if (usb3->driver) { 246262306a36Sopenharmony_ci if (usb3->is_rzv2m) 246362306a36Sopenharmony_ci rzv2m_usb3drd_reset(dev->parent, false); 246462306a36Sopenharmony_ci usb3_disconnect(usb3); 246562306a36Sopenharmony_ci } 246662306a36Sopenharmony_ci usb3_vbus_out(usb3, false); 246762306a36Sopenharmony_ci 246862306a36Sopenharmony_ci if (usb3->is_rzv2m) { 246962306a36Sopenharmony_ci rzv2m_usb3drd_reset(dev->parent, true); 247062306a36Sopenharmony_ci device_release_driver(host); 247162306a36Sopenharmony_ci } 247262306a36Sopenharmony_ci break; 247362306a36Sopenharmony_ci case USB_ROLE_DEVICE: 247462306a36Sopenharmony_ci if (usb3->connection_state == USB_ROLE_NONE) { 247562306a36Sopenharmony_ci usb3->connection_state = USB_ROLE_DEVICE; 247662306a36Sopenharmony_ci usb3_set_mode(usb3, false); 247762306a36Sopenharmony_ci if (usb3->driver) { 247862306a36Sopenharmony_ci if (usb3->is_rzv2m) 247962306a36Sopenharmony_ci renesas_usb3_init_controller(usb3); 248062306a36Sopenharmony_ci usb3_connect(usb3); 248162306a36Sopenharmony_ci } 248262306a36Sopenharmony_ci } else if (cur_role == USB_ROLE_HOST) { 248362306a36Sopenharmony_ci device_release_driver(host); 248462306a36Sopenharmony_ci usb3_set_mode(usb3, false); 248562306a36Sopenharmony_ci if (usb3->driver) 248662306a36Sopenharmony_ci usb3_connect(usb3); 248762306a36Sopenharmony_ci } 248862306a36Sopenharmony_ci usb3_vbus_out(usb3, false); 248962306a36Sopenharmony_ci break; 249062306a36Sopenharmony_ci case USB_ROLE_HOST: 249162306a36Sopenharmony_ci if (usb3->connection_state == USB_ROLE_NONE) { 249262306a36Sopenharmony_ci if (usb3->driver) { 249362306a36Sopenharmony_ci if (usb3->is_rzv2m) 249462306a36Sopenharmony_ci rzv2m_usb3drd_reset(dev->parent, false); 249562306a36Sopenharmony_ci usb3_disconnect(usb3); 249662306a36Sopenharmony_ci } 249762306a36Sopenharmony_ci 249862306a36Sopenharmony_ci usb3->connection_state = USB_ROLE_HOST; 249962306a36Sopenharmony_ci usb3_set_mode(usb3, true); 250062306a36Sopenharmony_ci usb3_vbus_out(usb3, true); 250162306a36Sopenharmony_ci if (device_attach(host) < 0) 250262306a36Sopenharmony_ci dev_err(dev, "device_attach(host) failed\n"); 250362306a36Sopenharmony_ci } else if (cur_role == USB_ROLE_DEVICE) { 250462306a36Sopenharmony_ci usb3_disconnect(usb3); 250562306a36Sopenharmony_ci /* Must set the mode before device_attach of the host */ 250662306a36Sopenharmony_ci usb3_set_mode(usb3, true); 250762306a36Sopenharmony_ci /* This device_attach() might sleep */ 250862306a36Sopenharmony_ci if (device_attach(host) < 0) 250962306a36Sopenharmony_ci dev_err(dev, "device_attach(host) failed\n"); 251062306a36Sopenharmony_ci } 251162306a36Sopenharmony_ci break; 251262306a36Sopenharmony_ci default: 251362306a36Sopenharmony_ci break; 251462306a36Sopenharmony_ci } 251562306a36Sopenharmony_ci} 251662306a36Sopenharmony_ci 251762306a36Sopenharmony_cistatic void handle_role_switch_states(struct device *dev, 251862306a36Sopenharmony_ci enum usb_role role) 251962306a36Sopenharmony_ci{ 252062306a36Sopenharmony_ci struct renesas_usb3 *usb3 = dev_get_drvdata(dev); 252162306a36Sopenharmony_ci struct device *host = usb3->host_dev; 252262306a36Sopenharmony_ci enum usb_role cur_role = renesas_usb3_role_switch_get(usb3->role_sw); 252362306a36Sopenharmony_ci 252462306a36Sopenharmony_ci if (cur_role == USB_ROLE_HOST && role == USB_ROLE_DEVICE) { 252562306a36Sopenharmony_ci device_release_driver(host); 252662306a36Sopenharmony_ci usb3_set_mode(usb3, false); 252762306a36Sopenharmony_ci } else if (cur_role == USB_ROLE_DEVICE && role == USB_ROLE_HOST) { 252862306a36Sopenharmony_ci /* Must set the mode before device_attach of the host */ 252962306a36Sopenharmony_ci usb3_set_mode(usb3, true); 253062306a36Sopenharmony_ci /* This device_attach() might sleep */ 253162306a36Sopenharmony_ci if (device_attach(host) < 0) 253262306a36Sopenharmony_ci dev_err(dev, "device_attach(host) failed\n"); 253362306a36Sopenharmony_ci } 253462306a36Sopenharmony_ci} 253562306a36Sopenharmony_ci 253662306a36Sopenharmony_cistatic int renesas_usb3_role_switch_set(struct usb_role_switch *sw, 253762306a36Sopenharmony_ci enum usb_role role) 253862306a36Sopenharmony_ci{ 253962306a36Sopenharmony_ci struct renesas_usb3 *usb3 = usb_role_switch_get_drvdata(sw); 254062306a36Sopenharmony_ci 254162306a36Sopenharmony_ci pm_runtime_get_sync(usb3_to_dev(usb3)); 254262306a36Sopenharmony_ci 254362306a36Sopenharmony_ci if (usb3->role_sw_by_connector) 254462306a36Sopenharmony_ci handle_ext_role_switch_states(usb3_to_dev(usb3), role); 254562306a36Sopenharmony_ci else 254662306a36Sopenharmony_ci handle_role_switch_states(usb3_to_dev(usb3), role); 254762306a36Sopenharmony_ci 254862306a36Sopenharmony_ci pm_runtime_put(usb3_to_dev(usb3)); 254962306a36Sopenharmony_ci 255062306a36Sopenharmony_ci return 0; 255162306a36Sopenharmony_ci} 255262306a36Sopenharmony_ci 255362306a36Sopenharmony_cistatic ssize_t role_store(struct device *dev, struct device_attribute *attr, 255462306a36Sopenharmony_ci const char *buf, size_t count) 255562306a36Sopenharmony_ci{ 255662306a36Sopenharmony_ci struct renesas_usb3 *usb3 = dev_get_drvdata(dev); 255762306a36Sopenharmony_ci bool new_mode_is_host; 255862306a36Sopenharmony_ci 255962306a36Sopenharmony_ci if (!usb3->driver) 256062306a36Sopenharmony_ci return -ENODEV; 256162306a36Sopenharmony_ci 256262306a36Sopenharmony_ci if (usb3->forced_b_device) 256362306a36Sopenharmony_ci return -EBUSY; 256462306a36Sopenharmony_ci 256562306a36Sopenharmony_ci if (sysfs_streq(buf, "host")) 256662306a36Sopenharmony_ci new_mode_is_host = true; 256762306a36Sopenharmony_ci else if (sysfs_streq(buf, "peripheral")) 256862306a36Sopenharmony_ci new_mode_is_host = false; 256962306a36Sopenharmony_ci else 257062306a36Sopenharmony_ci return -EINVAL; 257162306a36Sopenharmony_ci 257262306a36Sopenharmony_ci if (new_mode_is_host == usb3_is_host(usb3)) 257362306a36Sopenharmony_ci return -EINVAL; 257462306a36Sopenharmony_ci 257562306a36Sopenharmony_ci usb3_mode_config(usb3, new_mode_is_host, usb3_is_a_device(usb3)); 257662306a36Sopenharmony_ci 257762306a36Sopenharmony_ci return count; 257862306a36Sopenharmony_ci} 257962306a36Sopenharmony_ci 258062306a36Sopenharmony_cistatic ssize_t role_show(struct device *dev, struct device_attribute *attr, 258162306a36Sopenharmony_ci char *buf) 258262306a36Sopenharmony_ci{ 258362306a36Sopenharmony_ci struct renesas_usb3 *usb3 = dev_get_drvdata(dev); 258462306a36Sopenharmony_ci 258562306a36Sopenharmony_ci if (!usb3->driver) 258662306a36Sopenharmony_ci return -ENODEV; 258762306a36Sopenharmony_ci 258862306a36Sopenharmony_ci return sprintf(buf, "%s\n", usb3_is_host(usb3) ? "host" : "peripheral"); 258962306a36Sopenharmony_ci} 259062306a36Sopenharmony_cistatic DEVICE_ATTR_RW(role); 259162306a36Sopenharmony_ci 259262306a36Sopenharmony_cistatic int renesas_usb3_b_device_show(struct seq_file *s, void *unused) 259362306a36Sopenharmony_ci{ 259462306a36Sopenharmony_ci struct renesas_usb3 *usb3 = s->private; 259562306a36Sopenharmony_ci 259662306a36Sopenharmony_ci seq_printf(s, "%d\n", usb3->forced_b_device); 259762306a36Sopenharmony_ci 259862306a36Sopenharmony_ci return 0; 259962306a36Sopenharmony_ci} 260062306a36Sopenharmony_ci 260162306a36Sopenharmony_cistatic int renesas_usb3_b_device_open(struct inode *inode, struct file *file) 260262306a36Sopenharmony_ci{ 260362306a36Sopenharmony_ci return single_open(file, renesas_usb3_b_device_show, inode->i_private); 260462306a36Sopenharmony_ci} 260562306a36Sopenharmony_ci 260662306a36Sopenharmony_cistatic ssize_t renesas_usb3_b_device_write(struct file *file, 260762306a36Sopenharmony_ci const char __user *ubuf, 260862306a36Sopenharmony_ci size_t count, loff_t *ppos) 260962306a36Sopenharmony_ci{ 261062306a36Sopenharmony_ci struct seq_file *s = file->private_data; 261162306a36Sopenharmony_ci struct renesas_usb3 *usb3 = s->private; 261262306a36Sopenharmony_ci char buf[32]; 261362306a36Sopenharmony_ci 261462306a36Sopenharmony_ci if (!usb3->driver) 261562306a36Sopenharmony_ci return -ENODEV; 261662306a36Sopenharmony_ci 261762306a36Sopenharmony_ci if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 261862306a36Sopenharmony_ci return -EFAULT; 261962306a36Sopenharmony_ci 262062306a36Sopenharmony_ci usb3->start_to_connect = false; 262162306a36Sopenharmony_ci if (usb3->workaround_for_vbus && usb3->forced_b_device && 262262306a36Sopenharmony_ci !strncmp(buf, "2", 1)) 262362306a36Sopenharmony_ci usb3->start_to_connect = true; 262462306a36Sopenharmony_ci else if (!strncmp(buf, "1", 1)) 262562306a36Sopenharmony_ci usb3->forced_b_device = true; 262662306a36Sopenharmony_ci else 262762306a36Sopenharmony_ci usb3->forced_b_device = false; 262862306a36Sopenharmony_ci 262962306a36Sopenharmony_ci if (usb3->workaround_for_vbus) 263062306a36Sopenharmony_ci usb3_disconnect(usb3); 263162306a36Sopenharmony_ci 263262306a36Sopenharmony_ci /* Let this driver call usb3_connect() if needed */ 263362306a36Sopenharmony_ci usb3_check_id(usb3); 263462306a36Sopenharmony_ci 263562306a36Sopenharmony_ci return count; 263662306a36Sopenharmony_ci} 263762306a36Sopenharmony_ci 263862306a36Sopenharmony_cistatic const struct file_operations renesas_usb3_b_device_fops = { 263962306a36Sopenharmony_ci .open = renesas_usb3_b_device_open, 264062306a36Sopenharmony_ci .write = renesas_usb3_b_device_write, 264162306a36Sopenharmony_ci .read = seq_read, 264262306a36Sopenharmony_ci .llseek = seq_lseek, 264362306a36Sopenharmony_ci .release = single_release, 264462306a36Sopenharmony_ci}; 264562306a36Sopenharmony_ci 264662306a36Sopenharmony_cistatic void renesas_usb3_debugfs_init(struct renesas_usb3 *usb3, 264762306a36Sopenharmony_ci struct device *dev) 264862306a36Sopenharmony_ci{ 264962306a36Sopenharmony_ci usb3->dentry = debugfs_create_dir(dev_name(dev), usb_debug_root); 265062306a36Sopenharmony_ci 265162306a36Sopenharmony_ci debugfs_create_file("b_device", 0644, usb3->dentry, usb3, 265262306a36Sopenharmony_ci &renesas_usb3_b_device_fops); 265362306a36Sopenharmony_ci} 265462306a36Sopenharmony_ci 265562306a36Sopenharmony_ci/*------- platform_driver ------------------------------------------------*/ 265662306a36Sopenharmony_cistatic void renesas_usb3_remove(struct platform_device *pdev) 265762306a36Sopenharmony_ci{ 265862306a36Sopenharmony_ci struct renesas_usb3 *usb3 = platform_get_drvdata(pdev); 265962306a36Sopenharmony_ci 266062306a36Sopenharmony_ci debugfs_remove_recursive(usb3->dentry); 266162306a36Sopenharmony_ci device_remove_file(&pdev->dev, &dev_attr_role); 266262306a36Sopenharmony_ci 266362306a36Sopenharmony_ci cancel_work_sync(&usb3->role_work); 266462306a36Sopenharmony_ci usb_role_switch_unregister(usb3->role_sw); 266562306a36Sopenharmony_ci 266662306a36Sopenharmony_ci usb_del_gadget_udc(&usb3->gadget); 266762306a36Sopenharmony_ci reset_control_assert(usb3->usbp_rstc); 266862306a36Sopenharmony_ci renesas_usb3_dma_free_prd(usb3, &pdev->dev); 266962306a36Sopenharmony_ci 267062306a36Sopenharmony_ci __renesas_usb3_ep_free_request(usb3->ep0_req); 267162306a36Sopenharmony_ci pm_runtime_disable(&pdev->dev); 267262306a36Sopenharmony_ci} 267362306a36Sopenharmony_ci 267462306a36Sopenharmony_cistatic int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev, 267562306a36Sopenharmony_ci const struct renesas_usb3_priv *priv) 267662306a36Sopenharmony_ci{ 267762306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep; 267862306a36Sopenharmony_ci int i; 267962306a36Sopenharmony_ci 268062306a36Sopenharmony_ci /* calculate num_usb3_eps from renesas_usb3_priv */ 268162306a36Sopenharmony_ci usb3->num_usb3_eps = priv->ramsize_per_ramif * priv->num_ramif * 2 / 268262306a36Sopenharmony_ci priv->ramsize_per_pipe + 1; 268362306a36Sopenharmony_ci 268462306a36Sopenharmony_ci if (usb3->num_usb3_eps > USB3_MAX_NUM_PIPES(usb3)) 268562306a36Sopenharmony_ci usb3->num_usb3_eps = USB3_MAX_NUM_PIPES(usb3); 268662306a36Sopenharmony_ci 268762306a36Sopenharmony_ci usb3->usb3_ep = devm_kcalloc(dev, 268862306a36Sopenharmony_ci usb3->num_usb3_eps, sizeof(*usb3_ep), 268962306a36Sopenharmony_ci GFP_KERNEL); 269062306a36Sopenharmony_ci if (!usb3->usb3_ep) 269162306a36Sopenharmony_ci return -ENOMEM; 269262306a36Sopenharmony_ci 269362306a36Sopenharmony_ci dev_dbg(dev, "%s: num_usb3_eps = %d\n", __func__, usb3->num_usb3_eps); 269462306a36Sopenharmony_ci /* 269562306a36Sopenharmony_ci * This driver prepares pipes as follows: 269662306a36Sopenharmony_ci * - odd pipes = IN pipe 269762306a36Sopenharmony_ci * - even pipes = OUT pipe (except pipe 0) 269862306a36Sopenharmony_ci */ 269962306a36Sopenharmony_ci usb3_for_each_ep(usb3_ep, usb3, i) { 270062306a36Sopenharmony_ci snprintf(usb3_ep->ep_name, sizeof(usb3_ep->ep_name), "ep%d", i); 270162306a36Sopenharmony_ci usb3_ep->usb3 = usb3; 270262306a36Sopenharmony_ci usb3_ep->num = i; 270362306a36Sopenharmony_ci usb3_ep->ep.name = usb3_ep->ep_name; 270462306a36Sopenharmony_ci usb3_ep->ep.ops = &renesas_usb3_ep_ops; 270562306a36Sopenharmony_ci INIT_LIST_HEAD(&usb3_ep->queue); 270662306a36Sopenharmony_ci INIT_LIST_HEAD(&usb3_ep->ep.ep_list); 270762306a36Sopenharmony_ci if (!i) { 270862306a36Sopenharmony_ci /* for control pipe */ 270962306a36Sopenharmony_ci usb3->gadget.ep0 = &usb3_ep->ep; 271062306a36Sopenharmony_ci usb_ep_set_maxpacket_limit(&usb3_ep->ep, 271162306a36Sopenharmony_ci USB3_EP0_SS_MAX_PACKET_SIZE); 271262306a36Sopenharmony_ci usb3_ep->ep.caps.type_control = true; 271362306a36Sopenharmony_ci usb3_ep->ep.caps.dir_in = true; 271462306a36Sopenharmony_ci usb3_ep->ep.caps.dir_out = true; 271562306a36Sopenharmony_ci continue; 271662306a36Sopenharmony_ci } 271762306a36Sopenharmony_ci 271862306a36Sopenharmony_ci /* for bulk or interrupt pipe */ 271962306a36Sopenharmony_ci usb_ep_set_maxpacket_limit(&usb3_ep->ep, ~0); 272062306a36Sopenharmony_ci list_add_tail(&usb3_ep->ep.ep_list, &usb3->gadget.ep_list); 272162306a36Sopenharmony_ci usb3_ep->ep.caps.type_bulk = true; 272262306a36Sopenharmony_ci usb3_ep->ep.caps.type_int = true; 272362306a36Sopenharmony_ci if (i & 1) 272462306a36Sopenharmony_ci usb3_ep->ep.caps.dir_in = true; 272562306a36Sopenharmony_ci else 272662306a36Sopenharmony_ci usb3_ep->ep.caps.dir_out = true; 272762306a36Sopenharmony_ci } 272862306a36Sopenharmony_ci 272962306a36Sopenharmony_ci return 0; 273062306a36Sopenharmony_ci} 273162306a36Sopenharmony_ci 273262306a36Sopenharmony_cistatic void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev, 273362306a36Sopenharmony_ci const struct renesas_usb3_priv *priv) 273462306a36Sopenharmony_ci{ 273562306a36Sopenharmony_ci struct renesas_usb3_ep *usb3_ep; 273662306a36Sopenharmony_ci int i; 273762306a36Sopenharmony_ci u32 ramif[2], basead[2]; /* index 0 = for IN pipes */ 273862306a36Sopenharmony_ci u32 *cur_ramif, *cur_basead; 273962306a36Sopenharmony_ci u32 val; 274062306a36Sopenharmony_ci 274162306a36Sopenharmony_ci memset(ramif, 0, sizeof(ramif)); 274262306a36Sopenharmony_ci memset(basead, 0, sizeof(basead)); 274362306a36Sopenharmony_ci 274462306a36Sopenharmony_ci /* 274562306a36Sopenharmony_ci * This driver prepares pipes as follows: 274662306a36Sopenharmony_ci * - all pipes = the same size as "ramsize_per_pipe" 274762306a36Sopenharmony_ci * Please refer to the "Method of Specifying RAM Mapping" 274862306a36Sopenharmony_ci */ 274962306a36Sopenharmony_ci usb3_for_each_ep(usb3_ep, usb3, i) { 275062306a36Sopenharmony_ci if (!i) 275162306a36Sopenharmony_ci continue; /* out of scope if ep num = 0 */ 275262306a36Sopenharmony_ci if (usb3_ep->ep.caps.dir_in) { 275362306a36Sopenharmony_ci cur_ramif = &ramif[0]; 275462306a36Sopenharmony_ci cur_basead = &basead[0]; 275562306a36Sopenharmony_ci } else { 275662306a36Sopenharmony_ci cur_ramif = &ramif[1]; 275762306a36Sopenharmony_ci cur_basead = &basead[1]; 275862306a36Sopenharmony_ci } 275962306a36Sopenharmony_ci 276062306a36Sopenharmony_ci if (*cur_basead > priv->ramsize_per_ramif) 276162306a36Sopenharmony_ci continue; /* out of memory for IN or OUT pipe */ 276262306a36Sopenharmony_ci 276362306a36Sopenharmony_ci /* calculate rammap_val */ 276462306a36Sopenharmony_ci val = PN_RAMMAP_RAMIF(*cur_ramif); 276562306a36Sopenharmony_ci val |= usb3_calc_ramarea(priv->ramsize_per_pipe); 276662306a36Sopenharmony_ci val |= PN_RAMMAP_BASEAD(*cur_basead); 276762306a36Sopenharmony_ci usb3_ep->rammap_val = val; 276862306a36Sopenharmony_ci 276962306a36Sopenharmony_ci dev_dbg(dev, "ep%2d: val = %08x, ramif = %d, base = %x\n", 277062306a36Sopenharmony_ci i, val, *cur_ramif, *cur_basead); 277162306a36Sopenharmony_ci 277262306a36Sopenharmony_ci /* update current ramif */ 277362306a36Sopenharmony_ci if (*cur_ramif + 1 == priv->num_ramif) { 277462306a36Sopenharmony_ci *cur_ramif = 0; 277562306a36Sopenharmony_ci *cur_basead += priv->ramsize_per_pipe; 277662306a36Sopenharmony_ci } else { 277762306a36Sopenharmony_ci (*cur_ramif)++; 277862306a36Sopenharmony_ci } 277962306a36Sopenharmony_ci } 278062306a36Sopenharmony_ci} 278162306a36Sopenharmony_ci 278262306a36Sopenharmony_cistatic const struct renesas_usb3_priv renesas_usb3_priv_gen3 = { 278362306a36Sopenharmony_ci .ramsize_per_ramif = SZ_16K, 278462306a36Sopenharmony_ci .num_ramif = 4, 278562306a36Sopenharmony_ci .ramsize_per_pipe = SZ_4K, 278662306a36Sopenharmony_ci}; 278762306a36Sopenharmony_ci 278862306a36Sopenharmony_cistatic const struct renesas_usb3_priv renesas_usb3_priv_r8a77990 = { 278962306a36Sopenharmony_ci .ramsize_per_ramif = SZ_16K, 279062306a36Sopenharmony_ci .num_ramif = 4, 279162306a36Sopenharmony_ci .ramsize_per_pipe = SZ_4K, 279262306a36Sopenharmony_ci .workaround_for_vbus = true, 279362306a36Sopenharmony_ci}; 279462306a36Sopenharmony_ci 279562306a36Sopenharmony_cistatic const struct renesas_usb3_priv renesas_usb3_priv_rzv2m = { 279662306a36Sopenharmony_ci .ramsize_per_ramif = SZ_16K, 279762306a36Sopenharmony_ci .num_ramif = 1, 279862306a36Sopenharmony_ci .ramsize_per_pipe = SZ_4K, 279962306a36Sopenharmony_ci .is_rzv2m = true, 280062306a36Sopenharmony_ci}; 280162306a36Sopenharmony_ci 280262306a36Sopenharmony_cistatic const struct of_device_id usb3_of_match[] = { 280362306a36Sopenharmony_ci { 280462306a36Sopenharmony_ci .compatible = "renesas,r8a774c0-usb3-peri", 280562306a36Sopenharmony_ci .data = &renesas_usb3_priv_r8a77990, 280662306a36Sopenharmony_ci }, { 280762306a36Sopenharmony_ci .compatible = "renesas,r8a7795-usb3-peri", 280862306a36Sopenharmony_ci .data = &renesas_usb3_priv_gen3, 280962306a36Sopenharmony_ci }, { 281062306a36Sopenharmony_ci .compatible = "renesas,r8a77990-usb3-peri", 281162306a36Sopenharmony_ci .data = &renesas_usb3_priv_r8a77990, 281262306a36Sopenharmony_ci }, { 281362306a36Sopenharmony_ci .compatible = "renesas,rzv2m-usb3-peri", 281462306a36Sopenharmony_ci .data = &renesas_usb3_priv_rzv2m, 281562306a36Sopenharmony_ci }, { 281662306a36Sopenharmony_ci .compatible = "renesas,rcar-gen3-usb3-peri", 281762306a36Sopenharmony_ci .data = &renesas_usb3_priv_gen3, 281862306a36Sopenharmony_ci }, 281962306a36Sopenharmony_ci { }, 282062306a36Sopenharmony_ci}; 282162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, usb3_of_match); 282262306a36Sopenharmony_ci 282362306a36Sopenharmony_cistatic const unsigned int renesas_usb3_cable[] = { 282462306a36Sopenharmony_ci EXTCON_USB, 282562306a36Sopenharmony_ci EXTCON_USB_HOST, 282662306a36Sopenharmony_ci EXTCON_NONE, 282762306a36Sopenharmony_ci}; 282862306a36Sopenharmony_ci 282962306a36Sopenharmony_cistatic struct usb_role_switch_desc renesas_usb3_role_switch_desc = { 283062306a36Sopenharmony_ci .set = renesas_usb3_role_switch_set, 283162306a36Sopenharmony_ci .get = renesas_usb3_role_switch_get, 283262306a36Sopenharmony_ci .allow_userspace_control = true, 283362306a36Sopenharmony_ci}; 283462306a36Sopenharmony_ci 283562306a36Sopenharmony_cistatic int renesas_usb3_probe(struct platform_device *pdev) 283662306a36Sopenharmony_ci{ 283762306a36Sopenharmony_ci struct renesas_usb3 *usb3; 283862306a36Sopenharmony_ci int irq, ret; 283962306a36Sopenharmony_ci const struct renesas_usb3_priv *priv; 284062306a36Sopenharmony_ci 284162306a36Sopenharmony_ci priv = of_device_get_match_data(&pdev->dev); 284262306a36Sopenharmony_ci 284362306a36Sopenharmony_ci irq = platform_get_irq(pdev, 0); 284462306a36Sopenharmony_ci if (irq < 0) 284562306a36Sopenharmony_ci return irq; 284662306a36Sopenharmony_ci 284762306a36Sopenharmony_ci usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL); 284862306a36Sopenharmony_ci if (!usb3) 284962306a36Sopenharmony_ci return -ENOMEM; 285062306a36Sopenharmony_ci 285162306a36Sopenharmony_ci usb3->is_rzv2m = priv->is_rzv2m; 285262306a36Sopenharmony_ci 285362306a36Sopenharmony_ci usb3->reg = devm_platform_ioremap_resource(pdev, 0); 285462306a36Sopenharmony_ci if (IS_ERR(usb3->reg)) 285562306a36Sopenharmony_ci return PTR_ERR(usb3->reg); 285662306a36Sopenharmony_ci 285762306a36Sopenharmony_ci platform_set_drvdata(pdev, usb3); 285862306a36Sopenharmony_ci spin_lock_init(&usb3->lock); 285962306a36Sopenharmony_ci 286062306a36Sopenharmony_ci usb3->gadget.ops = &renesas_usb3_gadget_ops; 286162306a36Sopenharmony_ci usb3->gadget.name = udc_name; 286262306a36Sopenharmony_ci usb3->gadget.max_speed = USB_SPEED_SUPER; 286362306a36Sopenharmony_ci INIT_LIST_HEAD(&usb3->gadget.ep_list); 286462306a36Sopenharmony_ci ret = renesas_usb3_init_ep(usb3, &pdev->dev, priv); 286562306a36Sopenharmony_ci if (ret < 0) 286662306a36Sopenharmony_ci return ret; 286762306a36Sopenharmony_ci renesas_usb3_init_ram(usb3, &pdev->dev, priv); 286862306a36Sopenharmony_ci 286962306a36Sopenharmony_ci ret = devm_request_irq(&pdev->dev, irq, renesas_usb3_irq, 0, 287062306a36Sopenharmony_ci dev_name(&pdev->dev), usb3); 287162306a36Sopenharmony_ci if (ret < 0) 287262306a36Sopenharmony_ci return ret; 287362306a36Sopenharmony_ci 287462306a36Sopenharmony_ci if (usb3->is_rzv2m) { 287562306a36Sopenharmony_ci struct rzv2m_usb3drd *ddata = dev_get_drvdata(pdev->dev.parent); 287662306a36Sopenharmony_ci 287762306a36Sopenharmony_ci usb3->drd_reg = ddata->reg; 287862306a36Sopenharmony_ci ret = devm_request_irq(&pdev->dev, ddata->drd_irq, 287962306a36Sopenharmony_ci renesas_usb3_otg_irq, 0, 288062306a36Sopenharmony_ci dev_name(&pdev->dev), usb3); 288162306a36Sopenharmony_ci if (ret < 0) 288262306a36Sopenharmony_ci return ret; 288362306a36Sopenharmony_ci } 288462306a36Sopenharmony_ci 288562306a36Sopenharmony_ci INIT_WORK(&usb3->extcon_work, renesas_usb3_extcon_work); 288662306a36Sopenharmony_ci usb3->extcon = devm_extcon_dev_allocate(&pdev->dev, renesas_usb3_cable); 288762306a36Sopenharmony_ci if (IS_ERR(usb3->extcon)) 288862306a36Sopenharmony_ci return PTR_ERR(usb3->extcon); 288962306a36Sopenharmony_ci 289062306a36Sopenharmony_ci ret = devm_extcon_dev_register(&pdev->dev, usb3->extcon); 289162306a36Sopenharmony_ci if (ret < 0) { 289262306a36Sopenharmony_ci dev_err(&pdev->dev, "Failed to register extcon\n"); 289362306a36Sopenharmony_ci return ret; 289462306a36Sopenharmony_ci } 289562306a36Sopenharmony_ci 289662306a36Sopenharmony_ci /* for ep0 handling */ 289762306a36Sopenharmony_ci usb3->ep0_req = __renesas_usb3_ep_alloc_request(GFP_KERNEL); 289862306a36Sopenharmony_ci if (!usb3->ep0_req) 289962306a36Sopenharmony_ci return -ENOMEM; 290062306a36Sopenharmony_ci 290162306a36Sopenharmony_ci ret = renesas_usb3_dma_alloc_prd(usb3, &pdev->dev); 290262306a36Sopenharmony_ci if (ret < 0) 290362306a36Sopenharmony_ci goto err_alloc_prd; 290462306a36Sopenharmony_ci 290562306a36Sopenharmony_ci /* 290662306a36Sopenharmony_ci * This is optional. So, if this driver cannot get a phy, 290762306a36Sopenharmony_ci * this driver will not handle a phy anymore. 290862306a36Sopenharmony_ci */ 290962306a36Sopenharmony_ci usb3->phy = devm_phy_optional_get(&pdev->dev, "usb"); 291062306a36Sopenharmony_ci if (IS_ERR(usb3->phy)) { 291162306a36Sopenharmony_ci ret = PTR_ERR(usb3->phy); 291262306a36Sopenharmony_ci goto err_add_udc; 291362306a36Sopenharmony_ci } 291462306a36Sopenharmony_ci 291562306a36Sopenharmony_ci usb3->usbp_rstc = devm_reset_control_get_optional_shared(&pdev->dev, 291662306a36Sopenharmony_ci NULL); 291762306a36Sopenharmony_ci if (IS_ERR(usb3->usbp_rstc)) { 291862306a36Sopenharmony_ci ret = PTR_ERR(usb3->usbp_rstc); 291962306a36Sopenharmony_ci goto err_add_udc; 292062306a36Sopenharmony_ci } 292162306a36Sopenharmony_ci 292262306a36Sopenharmony_ci reset_control_deassert(usb3->usbp_rstc); 292362306a36Sopenharmony_ci 292462306a36Sopenharmony_ci pm_runtime_enable(&pdev->dev); 292562306a36Sopenharmony_ci ret = usb_add_gadget_udc(&pdev->dev, &usb3->gadget); 292662306a36Sopenharmony_ci if (ret < 0) 292762306a36Sopenharmony_ci goto err_reset; 292862306a36Sopenharmony_ci 292962306a36Sopenharmony_ci ret = device_create_file(&pdev->dev, &dev_attr_role); 293062306a36Sopenharmony_ci if (ret < 0) 293162306a36Sopenharmony_ci goto err_dev_create; 293262306a36Sopenharmony_ci 293362306a36Sopenharmony_ci if (device_property_read_bool(&pdev->dev, "usb-role-switch")) { 293462306a36Sopenharmony_ci usb3->role_sw_by_connector = true; 293562306a36Sopenharmony_ci renesas_usb3_role_switch_desc.fwnode = dev_fwnode(&pdev->dev); 293662306a36Sopenharmony_ci } 293762306a36Sopenharmony_ci 293862306a36Sopenharmony_ci renesas_usb3_role_switch_desc.driver_data = usb3; 293962306a36Sopenharmony_ci 294062306a36Sopenharmony_ci INIT_WORK(&usb3->role_work, renesas_usb3_role_work); 294162306a36Sopenharmony_ci usb3->role_sw = usb_role_switch_register(&pdev->dev, 294262306a36Sopenharmony_ci &renesas_usb3_role_switch_desc); 294362306a36Sopenharmony_ci if (!IS_ERR(usb3->role_sw)) { 294462306a36Sopenharmony_ci usb3->host_dev = usb_of_get_companion_dev(&pdev->dev); 294562306a36Sopenharmony_ci if (!usb3->host_dev) { 294662306a36Sopenharmony_ci /* If not found, this driver will not use a role sw */ 294762306a36Sopenharmony_ci usb_role_switch_unregister(usb3->role_sw); 294862306a36Sopenharmony_ci usb3->role_sw = NULL; 294962306a36Sopenharmony_ci } 295062306a36Sopenharmony_ci } else { 295162306a36Sopenharmony_ci usb3->role_sw = NULL; 295262306a36Sopenharmony_ci } 295362306a36Sopenharmony_ci 295462306a36Sopenharmony_ci usb3->workaround_for_vbus = priv->workaround_for_vbus; 295562306a36Sopenharmony_ci 295662306a36Sopenharmony_ci renesas_usb3_debugfs_init(usb3, &pdev->dev); 295762306a36Sopenharmony_ci 295862306a36Sopenharmony_ci dev_info(&pdev->dev, "probed%s\n", usb3->phy ? " with phy" : ""); 295962306a36Sopenharmony_ci 296062306a36Sopenharmony_ci return 0; 296162306a36Sopenharmony_ci 296262306a36Sopenharmony_cierr_dev_create: 296362306a36Sopenharmony_ci usb_del_gadget_udc(&usb3->gadget); 296462306a36Sopenharmony_ci 296562306a36Sopenharmony_cierr_reset: 296662306a36Sopenharmony_ci reset_control_assert(usb3->usbp_rstc); 296762306a36Sopenharmony_ci 296862306a36Sopenharmony_cierr_add_udc: 296962306a36Sopenharmony_ci renesas_usb3_dma_free_prd(usb3, &pdev->dev); 297062306a36Sopenharmony_ci 297162306a36Sopenharmony_cierr_alloc_prd: 297262306a36Sopenharmony_ci __renesas_usb3_ep_free_request(usb3->ep0_req); 297362306a36Sopenharmony_ci 297462306a36Sopenharmony_ci return ret; 297562306a36Sopenharmony_ci} 297662306a36Sopenharmony_ci 297762306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 297862306a36Sopenharmony_cistatic int renesas_usb3_suspend(struct device *dev) 297962306a36Sopenharmony_ci{ 298062306a36Sopenharmony_ci struct renesas_usb3 *usb3 = dev_get_drvdata(dev); 298162306a36Sopenharmony_ci 298262306a36Sopenharmony_ci /* Not started */ 298362306a36Sopenharmony_ci if (!usb3->driver) 298462306a36Sopenharmony_ci return 0; 298562306a36Sopenharmony_ci 298662306a36Sopenharmony_ci renesas_usb3_stop_controller(usb3); 298762306a36Sopenharmony_ci if (usb3->phy) 298862306a36Sopenharmony_ci phy_exit(usb3->phy); 298962306a36Sopenharmony_ci pm_runtime_put(dev); 299062306a36Sopenharmony_ci 299162306a36Sopenharmony_ci return 0; 299262306a36Sopenharmony_ci} 299362306a36Sopenharmony_ci 299462306a36Sopenharmony_cistatic int renesas_usb3_resume(struct device *dev) 299562306a36Sopenharmony_ci{ 299662306a36Sopenharmony_ci struct renesas_usb3 *usb3 = dev_get_drvdata(dev); 299762306a36Sopenharmony_ci 299862306a36Sopenharmony_ci /* Not started */ 299962306a36Sopenharmony_ci if (!usb3->driver) 300062306a36Sopenharmony_ci return 0; 300162306a36Sopenharmony_ci 300262306a36Sopenharmony_ci if (usb3->phy) 300362306a36Sopenharmony_ci phy_init(usb3->phy); 300462306a36Sopenharmony_ci pm_runtime_get_sync(dev); 300562306a36Sopenharmony_ci renesas_usb3_init_controller(usb3); 300662306a36Sopenharmony_ci 300762306a36Sopenharmony_ci return 0; 300862306a36Sopenharmony_ci} 300962306a36Sopenharmony_ci#endif 301062306a36Sopenharmony_ci 301162306a36Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(renesas_usb3_pm_ops, renesas_usb3_suspend, 301262306a36Sopenharmony_ci renesas_usb3_resume); 301362306a36Sopenharmony_ci 301462306a36Sopenharmony_cistatic struct platform_driver renesas_usb3_driver = { 301562306a36Sopenharmony_ci .probe = renesas_usb3_probe, 301662306a36Sopenharmony_ci .remove_new = renesas_usb3_remove, 301762306a36Sopenharmony_ci .driver = { 301862306a36Sopenharmony_ci .name = udc_name, 301962306a36Sopenharmony_ci .pm = &renesas_usb3_pm_ops, 302062306a36Sopenharmony_ci .of_match_table = usb3_of_match, 302162306a36Sopenharmony_ci }, 302262306a36Sopenharmony_ci}; 302362306a36Sopenharmony_cimodule_platform_driver(renesas_usb3_driver); 302462306a36Sopenharmony_ci 302562306a36Sopenharmony_ciMODULE_DESCRIPTION("Renesas USB3.0 Peripheral driver"); 302662306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 302762306a36Sopenharmony_ciMODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>"); 302862306a36Sopenharmony_ciMODULE_ALIAS("platform:renesas_usb3"); 3029