1 /* ==========================================================================
2 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
3 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
4 * otherwise expressly agreed to in writing between Synopsys and you.
6 * The Software IS NOT an item of Licensed Software or Licensed Product under
7 * any End User Software License Agreement or Agreement for Licensed Product
8 * with Synopsys or any supplement thereto. You are permitted to use and
9 * redistribute this Software in source and binary forms, with or without
10 * modification, provided that redistributions of source code must retain this
11 * notice. You may not view, use, disclose, copy or distribute this file or
12 * any information contained herein except pursuant to this license grant from
13 * Synopsys. If you do not agree with this notice, including the disclaimer
14 * below, then you are not authorized to use the Software.
16 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 * ========================================================================== */
29 #if !defined(__DWC_OTG_CFI_H__)
30 #define __DWC_OTG_CFI_H__
32 #include "dwc_otg_pcd.h"
33 #include "dwc_cfi_common.h"
37 * This file contains the CFI related OTG PCD specific common constants,
38 * interfaces(functions and macros) and data structures.The CFI Protocol is an
39 * optional interface for internal testing purposes that a DUT may implement to
40 * support testing of configurable features.
45 struct dwc_otg_pcd_ep;
47 /** OTG CFI Features (properties) ID constants */
48 /** This is a request for all Core Features */
49 #define FT_ID_DMA_MODE 0x0001
50 #define FT_ID_DMA_BUFFER_SETUP 0x0002
51 #define FT_ID_DMA_BUFF_ALIGN 0x0003
52 #define FT_ID_DMA_CONCAT_SETUP 0x0004
53 #define FT_ID_DMA_CIRCULAR 0x0005
54 #define FT_ID_THRESHOLD_SETUP 0x0006
55 #define FT_ID_DFIFO_DEPTH 0x0007
56 #define FT_ID_TX_FIFO_DEPTH 0x0008
57 #define FT_ID_RX_FIFO_DEPTH 0x0009
59 /**********************************************************/
63 #define CFI_INFO(fmt...) DWC_PRINTF("CFI: " fmt);
65 #define CFI_INFO(fmt...)
68 #define min(x, y) ({ \
71 #define max(x, y) ({ \
75 * Descriptor DMA SG Buffer setup structure (SG buffer). This structure is
76 * also used for setting up a buffer for Circular DDMA.
78 struct _ddma_sg_buffer_setup {
79 #define BS_SG_VAL_DESC_LEN 6
80 /* The OUT EP address */
81 uint8_t bOutEndpointAddress;
82 /* The IN EP address */
83 uint8_t bInEndpointAddress;
84 /* Number of bytes to put between transfer segments (must be DWORD boundaries) */
86 /* The number of transfer segments (a DMA descriptors per each segment) */
88 /* Size (in byte) of each transfer segment */
90 } __attribute__ ((packed));
91 typedef struct _ddma_sg_buffer_setup ddma_sg_buffer_setup_t;
93 /** Descriptor DMA Concatenation Buffer setup structure */
94 struct _ddma_concat_buffer_setup_hdr {
95 #define BS_CONCAT_VAL_HDR_LEN 4
96 /* The endpoint for which the buffer is to be set up */
97 uint8_t bEndpointAddress;
98 /* The count of descriptors to be used */
100 /* The total size of the transfer */
102 } __attribute__ ((packed));
103 typedef struct _ddma_concat_buffer_setup_hdr ddma_concat_buffer_setup_hdr_t;
105 /** Descriptor DMA Concatenation Buffer setup structure */
106 struct _ddma_concat_buffer_setup {
108 ddma_concat_buffer_setup_hdr_t hdr;
110 /* The XFER sizes pointer (allocated dynamically) */
112 } __attribute__ ((packed));
113 typedef struct _ddma_concat_buffer_setup ddma_concat_buffer_setup_t;
115 /** Descriptor DMA Alignment Buffer setup structure */
116 struct _ddma_align_buffer_setup {
117 #define BS_ALIGN_VAL_HDR_LEN 2
118 uint8_t bEndpointAddress;
120 } __attribute__ ((packed));
121 typedef struct _ddma_align_buffer_setup ddma_align_buffer_setup_t;
123 /** Transmit FIFO Size setup structure */
124 struct _tx_fifo_size_setup {
125 uint8_t bEndpointAddress;
127 } __attribute__ ((packed));
128 typedef struct _tx_fifo_size_setup tx_fifo_size_setup_t;
130 /** Transmit FIFO Size setup structure */
131 struct _rx_fifo_size_setup {
133 } __attribute__ ((packed));
134 typedef struct _rx_fifo_size_setup rx_fifo_size_setup_t;
137 * struct cfi_usb_ctrlrequest - the CFI implementation of the struct usb_ctrlrequest
138 * This structure encapsulates the standard usb_ctrlrequest and adds a pointer
139 * to the data returned in the data stage of a 3-stage Control Write requests.
141 struct cfi_usb_ctrlrequest {
142 uint8_t bRequestType;
150 /*---------------------------------------------------------------------------*/
153 * The CFI wrapper of the enabled and activated dwc_otg_pcd_ep structures.
154 * This structure is used to store the buffer setup data for any
155 * enabled endpoint in the PCD.
158 /* Entry for the list container */
160 /* Pointer to the active PCD endpoint structure */
161 struct dwc_otg_pcd_ep *ep;
162 /* The last descriptor in the chain of DMA descriptors of the endpoint */
163 struct dwc_otg_dma_desc *dma_desc_last;
164 /* The SG feature value */
165 ddma_sg_buffer_setup_t *bm_sg;
166 /* The Circular feature value */
167 ddma_sg_buffer_setup_t *bm_circ;
168 /* The Concatenation feature value */
169 ddma_concat_buffer_setup_t *bm_concat;
170 /* The Alignment feature value */
171 ddma_align_buffer_setup_t *bm_align;
175 * Count of DMA descriptors currently used.
176 * The total should not exceed the MAX_DMA_DESCS_PER_EP value
177 * defined in the dwc_otg_cil.h
181 typedef struct cfi_ep cfi_ep_t;
183 typedef struct cfi_dma_buff {
184 #define CFI_IN_BUF_LEN 1024
185 #define CFI_OUT_BUF_LEN 1024
193 * This is the interface for the CFI operations.
195 * @param ep_enable Called when any endpoint is enabled and activated.
196 * @param release Called when the CFI object is released and it needs to correctly
197 * deallocate the dynamic memory
198 * @param ctrl_write_complete Called when the data stage of the request is complete
200 typedef struct cfi_ops {
201 int (*ep_enable) (struct cfiobject *cfi, struct dwc_otg_pcd *pcd,
202 struct dwc_otg_pcd_ep *ep);
203 void *(*ep_alloc_buf) (struct cfiobject *cfi, struct dwc_otg_pcd *pcd,
204 struct dwc_otg_pcd_ep *ep, dma_addr_t *dma,
205 unsigned size, gfp_t flags);
206 void (*release) (struct cfiobject *cfi);
207 int (*ctrl_write_complete) (struct cfiobject *cfi,
208 struct dwc_otg_pcd *pcd);
209 void (*build_descriptors) (struct cfiobject *cfi,
210 struct dwc_otg_pcd *pcd,
211 struct dwc_otg_pcd_ep *ep,
212 dwc_otg_pcd_request_t *req);
217 struct dwc_otg_pcd *pcd;
218 struct usb_gadget *gadget;
220 /* Buffers used to send/receive CFI-related request data */
221 cfi_dma_buff_t buf_in;
222 cfi_dma_buff_t buf_out;
224 /* CFI specific Control request wrapper */
225 struct cfi_usb_ctrlrequest ctrl_req;
227 /* The list of active EP's in the PCD of type cfi_ep_t */
228 dwc_list_link_t active_eps;
230 /* This flag shall control the propagation of a specific request
231 * to the gadget's processing routines.
232 * 0 - no gadget handling
233 * 1 - the gadget needs to know about this request (w/o completing a status
234 * phase - just return a 0 to the _setup callback)
236 uint8_t need_gadget_att;
238 /* Flag indicating whether the status IN phase needs to be
239 * completed by the PCD
241 uint8_t need_status_in_complete;
243 typedef struct cfiobject cfiobject_t;
247 #if defined(DUMP_MSG)
248 static inline void dump_msg(const u8 *buf, unsigned int length)
250 unsigned int start, num, i;
258 num = min(length, 16u);
260 for (i = 0; i < num; ++i) {
263 DWC_SPRINTF(p, " %02x", buf[i]);
267 DWC_DEBUG("%6x: %s\n", start, line);
274 static inline void dump_msg(const u8 *buf, unsigned int length)
280 * This function returns a pointer to cfi_ep_t object with the addr address.
282 static inline struct cfi_ep *get_cfi_ep_by_addr(struct cfiobject *cfi,
285 struct cfi_ep *pcfiep;
286 dwc_list_link_t *tmp;
288 DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
289 pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
291 if (pcfiep->ep->desc->bEndpointAddress == addr) {
300 * This function returns a pointer to cfi_ep_t object that matches
301 * the dwc_otg_pcd_ep object.
303 static inline struct cfi_ep *get_cfi_ep_by_pcd_ep(struct cfiobject *cfi,
304 struct dwc_otg_pcd_ep *ep)
306 struct cfi_ep *pcfiep = NULL;
307 dwc_list_link_t *tmp;
309 DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
310 pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
311 if (pcfiep->ep == ep) {
318 int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl);
320 #endif /* (__DWC_OTG_CFI_H__) */