/* SPDX-License-Identifier: GPL-2.0 */ /* * USBHS-DEV device controller driver header file * * Copyright (C) 2023 Cadence. * * Author: Pawel Laszczak <[email protected]> */ #ifndef __LINUX_CDNS2_GADGET #define __LINUX_CDNS2_GADGET #include <linux/usb/gadget.h> #include <linux/dma-direction.h> /* * USBHS register interface. * This corresponds to the USBHS Device Controller Interface. */ /** * struct cdns2_ep0_regs - endpoint 0 related registers. * @rxbc: receive (OUT) 0 endpoint byte count register. * @txbc: transmit (IN) 0 endpoint byte count register. * @cs: 0 endpoint control and status register. * @reserved1: reserved. * @fifo: 0 endpoint fifo register. * @reserved2: reserved. * @setupdat: SETUP data register. * @reserved4: reserved. * @maxpack: 0 endpoint max packet size. */ struct cdns2_ep0_regs { … } __packed __aligned(…); /* EP0CS - bitmasks. */ /* Endpoint 0 stall bit for status stage. */ #define EP0CS_STALL … /* HSNAK bit. */ #define EP0CS_HSNAK … /* IN 0 endpoint busy bit. */ #define EP0CS_TXBSY_MSK … /* OUT 0 endpoint busy bit. */ #define EP0CS_RXBSY_MSK … /* Send STALL in the data stage phase. */ #define EP0CS_DSTALL … /* SETUP buffer content was changed. */ #define EP0CS_CHGSET … /* EP0FIFO - bitmasks. */ /* Direction. */ #define EP0_FIFO_IO_TX … /* FIFO auto bit. */ #define EP0_FIFO_AUTO … /* FIFO commit bit. */ #define EP0_FIFO_COMMIT … /* FIFO access bit. */ #define EP0_FIFO_ACCES … /** * struct cdns2_epx_base - base endpoint registers. * @rxbc: OUT endpoint byte count register. * @rxcon: OUT endpoint control register. * @rxcs: OUT endpoint control and status register. * @txbc: IN endpoint byte count register. * @txcon: IN endpoint control register. * @txcs: IN endpoint control and status register. */ struct cdns2_epx_base { … } __packed __aligned(…); /* rxcon/txcon - endpoint control register bitmasks. */ /* Endpoint buffering: 0 - single buffering ... 3 - quad buffering. */ #define EPX_CON_BUF … /* Endpoint type. */ #define EPX_CON_TYPE … /* Endpoint type: isochronous. */ #define EPX_CON_TYPE_ISOC … /* Endpoint type: bulk. */ #define EPX_CON_TYPE_BULK … /* Endpoint type: interrupt. */ #define EPX_CON_TYPE_INT … /* Number of packets per microframe. */ #define EPX_CON_ISOD … #define EPX_CON_ISOD_SHIFT … /* Endpoint stall bit. */ #define EPX_CON_STALL … /* Endpoint enable bit.*/ #define EPX_CON_VAL … /* rxcs/txcs - endpoint control and status bitmasks. */ /* Data sequence error for the ISO endpoint. */ #define EPX_CS_ERR(p) … /** * struct cdns2_epx_regs - endpoint 1..15 related registers. * @reserved: reserved. * @ep: none control endpoints array. * @reserved2: reserved. * @endprst: endpoint reset register. * @reserved3: reserved. * @isoautoarm: ISO auto-arm register. * @reserved4: reserved. * @isodctrl: ISO control register. * @reserved5: reserved. * @isoautodump: ISO auto dump enable register. * @reserved6: reserved. * @rxmaxpack: receive (OUT) Max packet size register. * @reserved7: reserved. * @rxstaddr: receive (OUT) start address endpoint buffer register. * @reserved8: reserved. * @txstaddr: transmit (IN) start address endpoint buffer register. * @reserved9: reserved. * @txmaxpack: transmit (IN) Max packet size register. */ struct cdns2_epx_regs { … } __packed __aligned(…); /* ENDPRST - bitmasks. */ /* Endpoint number. */ #define ENDPRST_EP … /* IN direction bit. */ #define ENDPRST_IO_TX … /* Toggle reset bit. */ #define ENDPRST_TOGRST … /* FIFO reset bit. */ #define ENDPRST_FIFORST … /* Toggle status and reset bit. */ #define ENDPRST_TOGSETQ … /** * struct cdns2_interrupt_regs - USB interrupt related registers. * @reserved: reserved. * @usbirq: USB interrupt request register. * @extirq: external interrupt request register. * @rxpngirq: external interrupt request register. * @reserved1: reserved. * @usbien: USB interrupt enable register. * @extien: external interrupt enable register. * @reserved2: reserved. * @usbivect: USB interrupt vector register. */ struct cdns2_interrupt_regs { … } __packed __aligned(…); /* EXTIRQ and EXTIEN - bitmasks. */ /* VBUS fault fall interrupt. */ #define EXTIRQ_VBUSFAULT_FALL … /* VBUS fault fall interrupt. */ #define EXTIRQ_VBUSFAULT_RISE … /* Wake up interrupt bit. */ #define EXTIRQ_WAKEUP … /* USBIEN and USBIRQ - bitmasks. */ /* SETUP data valid interrupt bit.*/ #define USBIRQ_SUDAV … /* Start-of-frame interrupt bit. */ #define USBIRQ_SOF … /* SETUP token interrupt bit. */ #define USBIRQ_SUTOK … /* USB suspend interrupt bit. */ #define USBIRQ_SUSPEND … /* USB reset interrupt bit. */ #define USBIRQ_URESET … /* USB high-speed mode interrupt bit. */ #define USBIRQ_HSPEED … /* Link Power Management interrupt bit. */ #define USBIRQ_LPM … #define USB_IEN_INIT … /** * struct cdns2_usb_regs - USB controller registers. * @reserved: reserved. * @lpmctrl: LPM control register. * @lpmclock: LPM clock register. * @reserved2: reserved. * @endprst: endpoint reset register. * @usbcs: USB control and status register. * @frmnr: USB frame counter register. * @fnaddr: function Address register. * @clkgate: clock gate register. * @fifoctrl: FIFO control register. * @speedctrl: speed Control register. * @sleep_clkgate: sleep Clock Gate register. * @reserved3: reserved. * @cpuctrl: microprocessor control register. */ struct cdns2_usb_regs { … } __packed __aligned(…); /* LPMCTRL - bitmasks. */ /* BESL (Best Effort Service Latency). */ #define LPMCTRLLL_HIRD … /* Last received Remote Wakeup field from LPM Extended Token packet. */ #define LPMCTRLLH_BREMOTEWAKEUP … /* Reflects value of the lpmnyet bit located in the usbcs[1] register. */ #define LPMCTRLLH_LPMNYET … /* LPMCLOCK - bitmasks. */ /* * If bit is 1 the controller automatically turns off clock * (utmisleepm goes to low), else the microprocessor should use * sleep clock gate register to turn off clock. */ #define LPMCLOCK_SLEEP_ENTRY … /* USBCS - bitmasks. */ /* Send NYET handshake for the LPM transaction. */ #define USBCS_LPMNYET … /* Remote wake-up bit. */ #define USBCS_SIGRSUME … /* Software disconnect bit. */ #define USBCS_DISCON … /* Indicates that a wakeup pin resumed the controller. */ #define USBCS_WAKESRC … /* FIFOCTRL - bitmasks. */ /* Endpoint number. */ #define FIFOCTRL_EP … /* Direction bit. */ #define FIFOCTRL_IO_TX … /* FIFO auto bit. */ #define FIFOCTRL_FIFOAUTO … /* FIFO commit bit. */ #define FIFOCTRL_FIFOCMIT … /* FIFO access bit. */ #define FIFOCTRL_FIFOACC … /* SPEEDCTRL - bitmasks. */ /* Device works in Full Speed. */ #define SPEEDCTRL_FS … /* Device works in High Speed. */ #define SPEEDCTRL_HS … /* Force FS mode. */ #define SPEEDCTRL_HSDISABLE … /* CPUCTRL- bitmasks. */ /* Controller reset bit. */ #define CPUCTRL_SW_RST … /** * struct cdns2_adma_regs - ADMA controller registers. * @conf: DMA global configuration register. * @sts: DMA global Status register. * @reserved1: reserved. * @ep_sel: DMA endpoint select register. * @ep_traddr: DMA endpoint transfer ring address register. * @ep_cfg: DMA endpoint configuration register. * @ep_cmd: DMA endpoint command register. * @ep_sts: DMA endpoint status register. * @reserved2: reserved. * @ep_sts_en: DMA endpoint status enable register. * @drbl: DMA doorbell register. * @ep_ien: DMA endpoint interrupt enable register. * @ep_ists: DMA endpoint interrupt status register. * @axim_ctrl: AXI Master Control register. * @axim_id: AXI Master ID register. * @reserved3: reserved. * @axim_cap: AXI Master Wrapper Extended Capability. * @reserved4: reserved. * @axim_ctrl0: AXI Master Wrapper Extended Capability Control Register 0. * @axim_ctrl1: AXI Master Wrapper Extended Capability Control Register 1. */ struct cdns2_adma_regs { … }; #define CDNS2_ADMA_REGS_OFFSET … /* DMA_CONF - bitmasks. */ /* Reset USB device configuration. */ #define DMA_CONF_CFGRST … /* Singular DMA transfer mode.*/ #define DMA_CONF_DSING … /* Multiple DMA transfers mode.*/ #define DMA_CONF_DMULT … /* DMA_EP_CFG - bitmasks. */ /* Endpoint enable. */ #define DMA_EP_CFG_ENABLE … /* DMA_EP_CMD - bitmasks. */ /* Endpoint reset. */ #define DMA_EP_CMD_EPRST … /* Transfer descriptor ready. */ #define DMA_EP_CMD_DRDY … /* Data flush. */ #define DMA_EP_CMD_DFLUSH … /* DMA_EP_STS - bitmasks. */ /* Interrupt On Complete. */ #define DMA_EP_STS_IOC … /* Interrupt on Short Packet. */ #define DMA_EP_STS_ISP … /* Transfer descriptor missing. */ #define DMA_EP_STS_DESCMIS … /* TRB error. */ #define DMA_EP_STS_TRBERR … /* DMA busy bit. */ #define DMA_EP_STS_DBUSY … /* Current Cycle Status. */ #define DMA_EP_STS_CCS(p) … /* OUT size mismatch. */ #define DMA_EP_STS_OUTSMM … /* ISO transmission error. */ #define DMA_EP_STS_ISOERR … /* DMA_EP_STS_EN - bitmasks. */ /* OUT transfer missing descriptor enable. */ #define DMA_EP_STS_EN_DESCMISEN … /* TRB enable. */ #define DMA_EP_STS_EN_TRBERREN … /* OUT size mismatch enable. */ #define DMA_EP_STS_EN_OUTSMMEN … /* ISO transmission error enable. */ #define DMA_EP_STS_EN_ISOERREN … /* DMA_EP_IEN - bitmasks. */ #define DMA_EP_IEN(index) … #define DMA_EP_IEN_EP_OUT0 … #define DMA_EP_IEN_EP_IN0 … /* DMA_EP_ISTS - bitmasks. */ #define DMA_EP_ISTS(index) … #define DMA_EP_ISTS_EP_OUT0 … #define DMA_EP_ISTS_EP_IN0 … #define gadget_to_cdns2_device(g) … #define ep_to_cdns2_ep(ep) … /*-------------------------------------------------------------------------*/ #define TRBS_PER_SEGMENT … #define ISO_MAX_INTERVAL … #define MAX_TRB_LENGTH … #define MAX_ISO_SIZE … /* * To improve performance the TRB buffer pointers can't cross * 4KB boundaries. */ #define TRB_MAX_ISO_BUFF_SHIFT … #define TRB_MAX_ISO_BUFF_SIZE … /* How much data is left before the 4KB boundary? */ #define TRB_BUFF_LEN_UP_TO_BOUNDARY(addr) … #if TRBS_PER_SEGMENT < 2 #error "Incorrect TRBS_PER_SEGMENT. Minimal Transfer Ring size is 2." #endif /** * struct cdns2_trb - represent Transfer Descriptor block. * @buffer: pointer to buffer data. * @length: length of data. * @control: control flags. * * This structure describes transfer block handled by DMA module. */ struct cdns2_trb { … }; #define TRB_SIZE … /* * These two extra TRBs are reserved for isochronous transfer * to inject 0 length packet and extra LINK TRB to synchronize the ISO transfer. */ #define TRB_ISO_RESERVED … #define TR_SEG_SIZE … /* TRB bit mask. */ #define TRB_TYPE_BITMASK … #define TRB_TYPE(p) … #define TRB_FIELD_TO_TYPE(p) … /* TRB type IDs. */ /* Used for Bulk, Interrupt, ISOC, and control data stage. */ #define TRB_NORMAL … /* TRB for linking ring segments. */ #define TRB_LINK … /* Cycle bit - indicates TRB ownership by driver or hw. */ #define TRB_CYCLE … /* * When set to '1', the device will toggle its interpretation of the Cycle bit. */ #define TRB_TOGGLE … /* Interrupt on short packet. */ #define TRB_ISP … /* Chain bit associate this TRB with next one TRB. */ #define TRB_CHAIN … /* Interrupt on completion. */ #define TRB_IOC … /* Transfer_len bitmasks. */ #define TRB_LEN(p) … #define TRB_BURST(p) … #define TRB_FIELD_TO_BURST(p) … /* Data buffer pointer bitmasks. */ #define TRB_BUFFER(p) … /*-------------------------------------------------------------------------*/ /* Driver numeric constants. */ /* Maximum address that can be assigned to device. */ #define USB_DEVICE_MAX_ADDRESS … /* One control and 15 IN and 15 OUT endpoints. */ #define CDNS2_ENDPOINTS_NUM … #define CDNS2_EP_ZLP_BUF_SIZE … /*-------------------------------------------------------------------------*/ /* Used structures. */ struct cdns2_device; /** * struct cdns2_ring - transfer ring representation. * @trbs: pointer to transfer ring. * @dma: dma address of transfer ring. * @free_trbs: number of free TRBs in transfer ring. * @pcs: producer cycle state. * @ccs: consumer cycle state. * @enqueue: enqueue index in transfer ring. * @dequeue: dequeue index in transfer ring. */ struct cdns2_ring { … }; /** * struct cdns2_endpoint - extended device side representation of USB endpoint. * @endpoint: usb endpoint. * @pending_list: list of requests queuing on transfer ring. * @deferred_list: list of requests waiting for queuing on transfer ring. * @pdev: device associated with endpoint. * @name: a human readable name e.g. ep1out. * @ring: transfer ring associated with endpoint. * @ep_state: state of endpoint. * @idx: index of endpoint in pdev->eps table. * @dir: endpoint direction. * @num: endpoint number (1 - 15). * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK. * @interval: interval between packets used for ISOC and Interrupt endpoint. * @buffering: on-chip buffers assigned to endpoint. * @trb_burst_size: number of burst used in TRB. * @skip: Sometimes the controller cannot process isochronous endpoint ring * quickly enough and it will miss some isoc tds on the ring and * generate ISO transmition error. * Driver sets skip flag when receive a ISO transmition error and * process the missed TDs on the endpoint ring. * @wa1_set: use WA1. * @wa1_trb: TRB assigned to WA1. * @wa1_trb_index: TRB index for WA1. * @wa1_cycle_bit: correct cycle bit for WA1. */ struct cdns2_endpoint { … }; /** * struct cdns2_request - extended device side representation of usb_request * object. * @request: generic usb_request object describing single I/O request. * @pep: extended representation of usb_ep object. * @trb: the first TRB association with this request. * @start_trb: number of the first TRB in transfer ring. * @end_trb: number of the last TRB in transfer ring. * @list: used for queuing request in lists. * @finished_trb: number of trb has already finished per request. * @num_of_trb: how many trbs are associated with request. */ struct cdns2_request { … }; #define to_cdns2_request(r) … /* Stages used during enumeration process.*/ #define CDNS2_SETUP_STAGE … #define CDNS2_DATA_STAGE … #define CDNS2_STATUS_STAGE … /** * struct cdns2_device - represent USB device. * @dev: pointer to device structure associated whit this controller. * @gadget: device side representation of the peripheral controller. * @gadget_driver: pointer to the gadget driver. * @lock: for synchronizing. * @irq: interrupt line number. * @regs: base address for registers * @usb_regs: base address for common USB registers. * @ep0_regs: base address for endpoint 0 related registers. * @epx_regs: base address for all none control endpoint registers. * @interrupt_regs: base address for interrupt handling related registers. * @adma_regs: base address for ADMA registers. * @eps_dma_pool: endpoint Transfer Ring pool. * @setup: used while processing usb control requests. * @ep0_preq: private request used while handling EP0. * @ep0_stage: ep0 stage during enumeration process. * @zlp_buf: zlp buffer. * @dev_address: device address assigned by host. * @eps: array of objects describing endpoints. * @selected_ep: actually selected endpoint. It's used only to improve * performance by limiting access to dma_ep_sel register. * @is_selfpowered: device is self powered. * @may_wakeup: allows device to remote wakeup the host. * @status_completion_no_call: indicate that driver is waiting for status * stage completion. It's used in deferred SET_CONFIGURATION request. * @in_lpm: indicate the controller is in low power mode. * @pending_status_wq: workqueue handling status stage for deferred requests. * @pending_status_request: request for which status stage was deferred. * @eps_supported: endpoints supported by controller in form: * bit: 0 - ep0, 1 - epOut1, 2 - epIn1, 3 - epOut2 ... * @burst_opt: array with the best burst size value for different TRB size. * @onchip_tx_buf: size of transmit on-chip buffer in KB. * @onchip_rx_buf: size of receive on-chip buffer in KB. */ struct cdns2_device { … }; #define CDNS2_IF_EP_EXIST(pdev, ep_num, dir) … dma_addr_t cdns2_trb_virt_to_dma(struct cdns2_endpoint *pep, struct cdns2_trb *trb); void cdns2_pending_setup_status_handler(struct work_struct *work); void cdns2_select_ep(struct cdns2_device *pdev, u32 ep); struct cdns2_request *cdns2_next_preq(struct list_head *list); struct usb_request *cdns2_gadget_ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags); void cdns2_gadget_ep_free_request(struct usb_ep *ep, struct usb_request *request); int cdns2_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *request); void cdns2_gadget_giveback(struct cdns2_endpoint *pep, struct cdns2_request *priv_req, int status); void cdns2_init_ep0(struct cdns2_device *pdev, struct cdns2_endpoint *pep); void cdns2_ep0_config(struct cdns2_device *pdev); void cdns2_handle_ep0_interrupt(struct cdns2_device *pdev, int dir); void cdns2_handle_setup_packet(struct cdns2_device *pdev); int cdns2_gadget_resume(struct cdns2_device *pdev, bool hibernated); int cdns2_gadget_suspend(struct cdns2_device *pdev); void cdns2_gadget_remove(struct cdns2_device *pdev); int cdns2_gadget_init(struct cdns2_device *pdev); void set_reg_bit_8(void __iomem *ptr, u8 mask); int cdns2_halt_endpoint(struct cdns2_device *pdev, struct cdns2_endpoint *pep, int value); #endif /* __LINUX_CDNS2_GADGET */