linux/drivers/usb/gadget/udc/cdns2/cdns2-gadget.h

/* 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 */