162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * USB Peripheral Controller driver for Aeroflex Gaisler GRUSBDC. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * 2013 (c) Aeroflex Gaisler AB 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * This driver supports GRUSBDC USB Device Controller cores available in the 862306a36Sopenharmony_ci * GRLIB VHDL IP core library. 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Full documentation of the GRUSBDC core can be found here: 1162306a36Sopenharmony_ci * https://www.gaisler.com/products/grlib/grip.pdf 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * Contributors: 1462306a36Sopenharmony_ci * - Andreas Larsson <andreas@gaisler.com> 1562306a36Sopenharmony_ci * - Marko Isomaki 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Control registers on the AMBA bus */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define GR_MAXEP 16 /* Max # endpoints for *each* direction */ 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistruct gr_epregs { 2362306a36Sopenharmony_ci u32 epctrl; 2462306a36Sopenharmony_ci union { 2562306a36Sopenharmony_ci struct { /* Slave mode*/ 2662306a36Sopenharmony_ci u32 slvctrl; 2762306a36Sopenharmony_ci u32 slvdata; 2862306a36Sopenharmony_ci }; 2962306a36Sopenharmony_ci struct { /* DMA mode*/ 3062306a36Sopenharmony_ci u32 dmactrl; 3162306a36Sopenharmony_ci u32 dmaaddr; 3262306a36Sopenharmony_ci }; 3362306a36Sopenharmony_ci }; 3462306a36Sopenharmony_ci u32 epstat; 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistruct gr_regs { 3862306a36Sopenharmony_ci struct gr_epregs epo[GR_MAXEP]; /* 0x000 - 0x0fc */ 3962306a36Sopenharmony_ci struct gr_epregs epi[GR_MAXEP]; /* 0x100 - 0x1fc */ 4062306a36Sopenharmony_ci u32 control; /* 0x200 */ 4162306a36Sopenharmony_ci u32 status; /* 0x204 */ 4262306a36Sopenharmony_ci}; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#define GR_EPCTRL_BUFSZ_SCALER 8 4562306a36Sopenharmony_ci#define GR_EPCTRL_BUFSZ_MASK 0xffe00000 4662306a36Sopenharmony_ci#define GR_EPCTRL_BUFSZ_POS 21 4762306a36Sopenharmony_ci#define GR_EPCTRL_PI BIT(20) 4862306a36Sopenharmony_ci#define GR_EPCTRL_CB BIT(19) 4962306a36Sopenharmony_ci#define GR_EPCTRL_CS BIT(18) 5062306a36Sopenharmony_ci#define GR_EPCTRL_MAXPL_MASK 0x0003ff80 5162306a36Sopenharmony_ci#define GR_EPCTRL_MAXPL_POS 7 5262306a36Sopenharmony_ci#define GR_EPCTRL_NT_MASK 0x00000060 5362306a36Sopenharmony_ci#define GR_EPCTRL_NT_POS 5 5462306a36Sopenharmony_ci#define GR_EPCTRL_TT_MASK 0x00000018 5562306a36Sopenharmony_ci#define GR_EPCTRL_TT_POS 3 5662306a36Sopenharmony_ci#define GR_EPCTRL_EH BIT(2) 5762306a36Sopenharmony_ci#define GR_EPCTRL_ED BIT(1) 5862306a36Sopenharmony_ci#define GR_EPCTRL_EV BIT(0) 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#define GR_DMACTRL_AE BIT(10) 6162306a36Sopenharmony_ci#define GR_DMACTRL_AD BIT(3) 6262306a36Sopenharmony_ci#define GR_DMACTRL_AI BIT(2) 6362306a36Sopenharmony_ci#define GR_DMACTRL_IE BIT(1) 6462306a36Sopenharmony_ci#define GR_DMACTRL_DA BIT(0) 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#define GR_EPSTAT_PT BIT(29) 6762306a36Sopenharmony_ci#define GR_EPSTAT_PR BIT(29) 6862306a36Sopenharmony_ci#define GR_EPSTAT_B1CNT_MASK 0x1fff0000 6962306a36Sopenharmony_ci#define GR_EPSTAT_B1CNT_POS 16 7062306a36Sopenharmony_ci#define GR_EPSTAT_B0CNT_MASK 0x0000fff8 7162306a36Sopenharmony_ci#define GR_EPSTAT_B0CNT_POS 3 7262306a36Sopenharmony_ci#define GR_EPSTAT_B1 BIT(2) 7362306a36Sopenharmony_ci#define GR_EPSTAT_B0 BIT(1) 7462306a36Sopenharmony_ci#define GR_EPSTAT_BS BIT(0) 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci#define GR_CONTROL_SI BIT(31) 7762306a36Sopenharmony_ci#define GR_CONTROL_UI BIT(30) 7862306a36Sopenharmony_ci#define GR_CONTROL_VI BIT(29) 7962306a36Sopenharmony_ci#define GR_CONTROL_SP BIT(28) 8062306a36Sopenharmony_ci#define GR_CONTROL_FI BIT(27) 8162306a36Sopenharmony_ci#define GR_CONTROL_EP BIT(14) 8262306a36Sopenharmony_ci#define GR_CONTROL_DH BIT(13) 8362306a36Sopenharmony_ci#define GR_CONTROL_RW BIT(12) 8462306a36Sopenharmony_ci#define GR_CONTROL_TS_MASK 0x00000e00 8562306a36Sopenharmony_ci#define GR_CONTROL_TS_POS 9 8662306a36Sopenharmony_ci#define GR_CONTROL_TM BIT(8) 8762306a36Sopenharmony_ci#define GR_CONTROL_UA_MASK 0x000000fe 8862306a36Sopenharmony_ci#define GR_CONTROL_UA_POS 1 8962306a36Sopenharmony_ci#define GR_CONTROL_SU BIT(0) 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci#define GR_STATUS_NEPI_MASK 0xf0000000 9262306a36Sopenharmony_ci#define GR_STATUS_NEPI_POS 28 9362306a36Sopenharmony_ci#define GR_STATUS_NEPO_MASK 0x0f000000 9462306a36Sopenharmony_ci#define GR_STATUS_NEPO_POS 24 9562306a36Sopenharmony_ci#define GR_STATUS_DM BIT(23) 9662306a36Sopenharmony_ci#define GR_STATUS_SU BIT(17) 9762306a36Sopenharmony_ci#define GR_STATUS_UR BIT(16) 9862306a36Sopenharmony_ci#define GR_STATUS_VB BIT(15) 9962306a36Sopenharmony_ci#define GR_STATUS_SP BIT(14) 10062306a36Sopenharmony_ci#define GR_STATUS_AF_MASK 0x00003800 10162306a36Sopenharmony_ci#define GR_STATUS_AF_POS 11 10262306a36Sopenharmony_ci#define GR_STATUS_FN_MASK 0x000007ff 10362306a36Sopenharmony_ci#define GR_STATUS_FN_POS 0 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci#define MAX_CTRL_PL_SIZE 64 /* As per USB standard for full and high speed */ 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/ 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/* Driver data structures and utilities */ 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistruct gr_dma_desc { 11362306a36Sopenharmony_ci u32 ctrl; 11462306a36Sopenharmony_ci u32 data; 11562306a36Sopenharmony_ci u32 next; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci /* These must be last because hw uses the previous three */ 11862306a36Sopenharmony_ci u32 paddr; 11962306a36Sopenharmony_ci struct gr_dma_desc *next_desc; 12062306a36Sopenharmony_ci}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci#define GR_DESC_OUT_CTRL_SE BIT(17) 12362306a36Sopenharmony_ci#define GR_DESC_OUT_CTRL_IE BIT(15) 12462306a36Sopenharmony_ci#define GR_DESC_OUT_CTRL_NX BIT(14) 12562306a36Sopenharmony_ci#define GR_DESC_OUT_CTRL_EN BIT(13) 12662306a36Sopenharmony_ci#define GR_DESC_OUT_CTRL_LEN_MASK 0x00001fff 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci#define GR_DESC_IN_CTRL_MO BIT(18) 12962306a36Sopenharmony_ci#define GR_DESC_IN_CTRL_PI BIT(17) 13062306a36Sopenharmony_ci#define GR_DESC_IN_CTRL_ML BIT(16) 13162306a36Sopenharmony_ci#define GR_DESC_IN_CTRL_IE BIT(15) 13262306a36Sopenharmony_ci#define GR_DESC_IN_CTRL_NX BIT(14) 13362306a36Sopenharmony_ci#define GR_DESC_IN_CTRL_EN BIT(13) 13462306a36Sopenharmony_ci#define GR_DESC_IN_CTRL_LEN_MASK 0x00001fff 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci#define GR_DESC_DMAADDR_MASK 0xfffffffc 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_cistruct gr_ep { 13962306a36Sopenharmony_ci struct usb_ep ep; 14062306a36Sopenharmony_ci struct gr_udc *dev; 14162306a36Sopenharmony_ci u16 bytes_per_buffer; 14262306a36Sopenharmony_ci unsigned int dma_start; 14362306a36Sopenharmony_ci struct gr_epregs __iomem *regs; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci unsigned num:8; 14662306a36Sopenharmony_ci unsigned is_in:1; 14762306a36Sopenharmony_ci unsigned stopped:1; 14862306a36Sopenharmony_ci unsigned wedged:1; 14962306a36Sopenharmony_ci unsigned callback:1; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci /* analogous to a host-side qh */ 15262306a36Sopenharmony_ci struct list_head queue; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci struct list_head ep_list; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci /* Bounce buffer for end of "odd" sized OUT requests */ 15762306a36Sopenharmony_ci void *tailbuf; 15862306a36Sopenharmony_ci dma_addr_t tailbuf_paddr; 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistruct gr_request { 16262306a36Sopenharmony_ci struct usb_request req; 16362306a36Sopenharmony_ci struct list_head queue; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci /* Chain of dma descriptors */ 16662306a36Sopenharmony_ci struct gr_dma_desc *first_desc; /* First in the chain */ 16762306a36Sopenharmony_ci struct gr_dma_desc *curr_desc; /* Current descriptor */ 16862306a36Sopenharmony_ci struct gr_dma_desc *last_desc; /* Last in the chain */ 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci u16 evenlen; /* Size of even length head (if oddlen != 0) */ 17162306a36Sopenharmony_ci u16 oddlen; /* Size of odd length tail if buffer length is "odd" */ 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci u8 setup; /* Setup packet */ 17462306a36Sopenharmony_ci}; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cienum gr_ep0state { 17762306a36Sopenharmony_ci GR_EP0_DISCONNECT = 0, /* No host */ 17862306a36Sopenharmony_ci GR_EP0_SETUP, /* Between STATUS ack and SETUP report */ 17962306a36Sopenharmony_ci GR_EP0_IDATA, /* IN data stage */ 18062306a36Sopenharmony_ci GR_EP0_ODATA, /* OUT data stage */ 18162306a36Sopenharmony_ci GR_EP0_ISTATUS, /* Status stage after IN data stage */ 18262306a36Sopenharmony_ci GR_EP0_OSTATUS, /* Status stage after OUT data stage */ 18362306a36Sopenharmony_ci GR_EP0_STALL, /* Data or status stages */ 18462306a36Sopenharmony_ci GR_EP0_SUSPEND, /* USB suspend */ 18562306a36Sopenharmony_ci}; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_cistruct gr_udc { 18862306a36Sopenharmony_ci struct usb_gadget gadget; 18962306a36Sopenharmony_ci struct gr_ep epi[GR_MAXEP]; 19062306a36Sopenharmony_ci struct gr_ep epo[GR_MAXEP]; 19162306a36Sopenharmony_ci struct usb_gadget_driver *driver; 19262306a36Sopenharmony_ci struct dma_pool *desc_pool; 19362306a36Sopenharmony_ci struct device *dev; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci enum gr_ep0state ep0state; 19662306a36Sopenharmony_ci struct gr_request *ep0reqo; 19762306a36Sopenharmony_ci struct gr_request *ep0reqi; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci struct gr_regs __iomem *regs; 20062306a36Sopenharmony_ci int irq; 20162306a36Sopenharmony_ci int irqi; 20262306a36Sopenharmony_ci int irqo; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci unsigned added:1; 20562306a36Sopenharmony_ci unsigned irq_enabled:1; 20662306a36Sopenharmony_ci unsigned remote_wakeup:1; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci u8 test_mode; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci enum usb_device_state suspended_from; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci unsigned int nepi; 21362306a36Sopenharmony_ci unsigned int nepo; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci struct list_head ep_list; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci spinlock_t lock; /* General lock, a.k.a. "dev->lock" in comments */ 21862306a36Sopenharmony_ci}; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci#define to_gr_udc(gadget) (container_of((gadget), struct gr_udc, gadget)) 221