aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/dwc_otg/dwc_otg_cfi.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/dwc_otg/dwc_otg_cfi.h')
-rw-r--r--drivers/usb/host/dwc_otg/dwc_otg_cfi.h320
1 files changed, 320 insertions, 0 deletions
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cfi.h b/drivers/usb/host/dwc_otg/dwc_otg_cfi.h
new file mode 100644
index 000000000000..55fd337a283c
--- /dev/null
+++ b/drivers/usb/host/dwc_otg/dwc_otg_cfi.h
@@ -0,0 +1,320 @@
+/* ==========================================================================
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+#if !defined(__DWC_OTG_CFI_H__)
+#define __DWC_OTG_CFI_H__
+
+#include "dwc_otg_pcd.h"
+#include "dwc_cfi_common.h"
+
+/**
+ * @file
+ * This file contains the CFI related OTG PCD specific common constants,
+ * interfaces(functions and macros) and data structures.The CFI Protocol is an
+ * optional interface for internal testing purposes that a DUT may implement to
+ * support testing of configurable features.
+ *
+ */
+
+struct dwc_otg_pcd;
+struct dwc_otg_pcd_ep;
+
+/** OTG CFI Features (properties) ID constants */
+/** This is a request for all Core Features */
+#define FT_ID_DMA_MODE 0x0001
+#define FT_ID_DMA_BUFFER_SETUP 0x0002
+#define FT_ID_DMA_BUFF_ALIGN 0x0003
+#define FT_ID_DMA_CONCAT_SETUP 0x0004
+#define FT_ID_DMA_CIRCULAR 0x0005
+#define FT_ID_THRESHOLD_SETUP 0x0006
+#define FT_ID_DFIFO_DEPTH 0x0007
+#define FT_ID_TX_FIFO_DEPTH 0x0008
+#define FT_ID_RX_FIFO_DEPTH 0x0009
+
+/**********************************************************/
+#define CFI_INFO_DEF
+
+#ifdef CFI_INFO_DEF
+#define CFI_INFO(fmt...) DWC_PRINTF("CFI: " fmt);
+#else
+#define CFI_INFO(fmt...)
+#endif
+
+#define min(x,y) ({ \
+ x < y ? x : y; })
+
+#define max(x,y) ({ \
+ x > y ? x : y; })
+
+/**
+ * Descriptor DMA SG Buffer setup structure (SG buffer). This structure is
+ * also used for setting up a buffer for Circular DDMA.
+ */
+struct _ddma_sg_buffer_setup {
+#define BS_SG_VAL_DESC_LEN 6
+ /* The OUT EP address */
+ uint8_t bOutEndpointAddress;
+ /* The IN EP address */
+ uint8_t bInEndpointAddress;
+ /* Number of bytes to put between transfer segments (must be DWORD boundaries) */
+ uint8_t bOffset;
+ /* The number of transfer segments (a DMA descriptors per each segment) */
+ uint8_t bCount;
+ /* Size (in byte) of each transfer segment */
+ uint16_t wSize;
+} __attribute__ ((packed));
+typedef struct _ddma_sg_buffer_setup ddma_sg_buffer_setup_t;
+
+/** Descriptor DMA Concatenation Buffer setup structure */
+struct _ddma_concat_buffer_setup_hdr {
+#define BS_CONCAT_VAL_HDR_LEN 4
+ /* The endpoint for which the buffer is to be set up */
+ uint8_t bEndpointAddress;
+ /* The count of descriptors to be used */
+ uint8_t bDescCount;
+ /* The total size of the transfer */
+ uint16_t wSize;
+} __attribute__ ((packed));
+typedef struct _ddma_concat_buffer_setup_hdr ddma_concat_buffer_setup_hdr_t;
+
+/** Descriptor DMA Concatenation Buffer setup structure */
+struct _ddma_concat_buffer_setup {
+ /* The SG header */
+ ddma_concat_buffer_setup_hdr_t hdr;
+
+ /* The XFER sizes pointer (allocated dynamically) */
+ uint16_t *wTxBytes;
+} __attribute__ ((packed));
+typedef struct _ddma_concat_buffer_setup ddma_concat_buffer_setup_t;
+
+/** Descriptor DMA Alignment Buffer setup structure */
+struct _ddma_align_buffer_setup {
+#define BS_ALIGN_VAL_HDR_LEN 2
+ uint8_t bEndpointAddress;
+ uint8_t bAlign;
+} __attribute__ ((packed));
+typedef struct _ddma_align_buffer_setup ddma_align_buffer_setup_t;
+
+/** Transmit FIFO Size setup structure */
+struct _tx_fifo_size_setup {
+ uint8_t bEndpointAddress;
+ uint16_t wDepth;
+} __attribute__ ((packed));
+typedef struct _tx_fifo_size_setup tx_fifo_size_setup_t;
+
+/** Transmit FIFO Size setup structure */
+struct _rx_fifo_size_setup {
+ uint16_t wDepth;
+} __attribute__ ((packed));
+typedef struct _rx_fifo_size_setup rx_fifo_size_setup_t;
+
+/**
+ * struct cfi_usb_ctrlrequest - the CFI implementation of the struct usb_ctrlrequest
+ * This structure encapsulates the standard usb_ctrlrequest and adds a pointer
+ * to the data returned in the data stage of a 3-stage Control Write requests.
+ */
+struct cfi_usb_ctrlrequest {
+ uint8_t bRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+ uint8_t *data;
+} UPACKED;
+
+/*---------------------------------------------------------------------------*/
+
+/**
+ * The CFI wrapper of the enabled and activated dwc_otg_pcd_ep structures.
+ * This structure is used to store the buffer setup data for any
+ * enabled endpoint in the PCD.
+ */
+struct cfi_ep {
+ /* Entry for the list container */
+ dwc_list_link_t lh;
+ /* Pointer to the active PCD endpoint structure */
+ struct dwc_otg_pcd_ep *ep;
+ /* The last descriptor in the chain of DMA descriptors of the endpoint */
+ struct dwc_otg_dma_desc *dma_desc_last;
+ /* The SG feature value */
+ ddma_sg_buffer_setup_t *bm_sg;
+ /* The Circular feature value */
+ ddma_sg_buffer_setup_t *bm_circ;
+ /* The Concatenation feature value */
+ ddma_concat_buffer_setup_t *bm_concat;
+ /* The Alignment feature value */
+ ddma_align_buffer_setup_t *bm_align;
+ /* XFER length */
+ uint32_t xfer_len;
+ /*
+ * Count of DMA descriptors currently used.
+ * The total should not exceed the MAX_DMA_DESCS_PER_EP value
+ * defined in the dwc_otg_cil.h
+ */
+ uint32_t desc_count;
+};
+typedef struct cfi_ep cfi_ep_t;
+
+typedef struct cfi_dma_buff {
+#define CFI_IN_BUF_LEN 1024
+#define CFI_OUT_BUF_LEN 1024
+ dma_addr_t addr;
+ uint8_t *buf;
+} cfi_dma_buff_t;
+
+struct cfiobject;
+
+/**
+ * This is the interface for the CFI operations.
+ *
+ * @param ep_enable Called when any endpoint is enabled and activated.
+ * @param release Called when the CFI object is released and it needs to correctly
+ * deallocate the dynamic memory
+ * @param ctrl_write_complete Called when the data stage of the request is complete
+ */
+typedef struct cfi_ops {
+ int (*ep_enable) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
+ struct dwc_otg_pcd_ep * ep);
+ void *(*ep_alloc_buf) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
+ struct dwc_otg_pcd_ep * ep, dma_addr_t * dma,
+ unsigned size, gfp_t flags);
+ void (*release) (struct cfiobject * cfi);
+ int (*ctrl_write_complete) (struct cfiobject * cfi,
+ struct dwc_otg_pcd * pcd);
+ void (*build_descriptors) (struct cfiobject * cfi,
+ struct dwc_otg_pcd * pcd,
+ struct dwc_otg_pcd_ep * ep,
+ dwc_otg_pcd_request_t * req);
+} cfi_ops_t;
+
+struct cfiobject {
+ cfi_ops_t ops;
+ struct dwc_otg_pcd *pcd;
+ struct usb_gadget *gadget;
+
+ /* Buffers used to send/receive CFI-related request data */
+ cfi_dma_buff_t buf_in;
+ cfi_dma_buff_t buf_out;
+
+ /* CFI specific Control request wrapper */
+ struct cfi_usb_ctrlrequest ctrl_req;
+
+ /* The list of active EP's in the PCD of type cfi_ep_t */
+ dwc_list_link_t active_eps;
+
+ /* This flag shall control the propagation of a specific request
+ * to the gadget's processing routines.
+ * 0 - no gadget handling
+ * 1 - the gadget needs to know about this request (w/o completing a status
+ * phase - just return a 0 to the _setup callback)
+ */
+ uint8_t need_gadget_att;
+
+ /* Flag indicating whether the status IN phase needs to be
+ * completed by the PCD
+ */
+ uint8_t need_status_in_complete;
+};
+typedef struct cfiobject cfiobject_t;
+
+#define DUMP_MSG
+
+#if defined(DUMP_MSG)
+static inline void dump_msg(const u8 * buf, unsigned int length)
+{
+ unsigned int start, num, i;
+ char line[52], *p;
+
+ if (length >= 512)
+ return;
+
+ start = 0;
+ while (length > 0) {
+ num = min(length, 16u);
+ p = line;
+ for (i = 0; i < num; ++i) {
+ if (i == 8)
+ *p++ = ' ';
+ DWC_SPRINTF(p, " %02x", buf[i]);
+ p += 3;
+ }
+ *p = 0;
+ DWC_DEBUG("%6x: %s\n", start, line);
+ buf += num;
+ start += num;
+ length -= num;
+ }
+}
+#else
+static inline void dump_msg(const u8 * buf, unsigned int length)
+{
+}
+#endif
+
+/**
+ * This function returns a pointer to cfi_ep_t object with the addr address.
+ */
+static inline struct cfi_ep *get_cfi_ep_by_addr(struct cfiobject *cfi,
+ uint8_t addr)
+{
+ struct cfi_ep *pcfiep;
+ dwc_list_link_t *tmp;
+
+ DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
+ pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
+
+ if (pcfiep->ep->desc->bEndpointAddress == addr) {
+ return pcfiep;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * This function returns a pointer to cfi_ep_t object that matches
+ * the dwc_otg_pcd_ep object.
+ */
+static inline struct cfi_ep *get_cfi_ep_by_pcd_ep(struct cfiobject *cfi,
+ struct dwc_otg_pcd_ep *ep)
+{
+ struct cfi_ep *pcfiep = NULL;
+ dwc_list_link_t *tmp;
+
+ DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
+ pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
+ if (pcfiep->ep == ep) {
+ return pcfiep;
+ }
+ }
+ return NULL;
+}
+
+int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl);
+
+#endif /* (__DWC_OTG_CFI_H__) */