usb: dwc_otg_310: fix usb vbus power controlled by pmic
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / dwc_otg_cfi.h
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.
5  *
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.
15  *
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
26  * DAMAGE.
27  * ========================================================================== */
28
29 #if !defined(__DWC_OTG_CFI_H__)
30 #define __DWC_OTG_CFI_H__
31
32 #include "dwc_otg_pcd.h"
33 #include "dwc_cfi_common.h"
34
35 /**
36  * @file
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.
41  *
42  */
43
44 struct dwc_otg_pcd;
45 struct dwc_otg_pcd_ep;
46
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
58
59 /**********************************************************/
60 #define CFI_INFO_DEF
61
62 #ifdef CFI_INFO_DEF
63 #define CFI_INFO(fmt...)        DWC_PRINTF("CFI: " fmt);
64 #else
65 #define CFI_INFO(fmt...)
66 #endif
67
68 #define min(x, y) ({ \
69         x < y ? x : y; })
70
71 #define max(x, y) ({ \
72         x > y ? x : y; })
73
74 /**
75  * Descriptor DMA SG Buffer setup structure (SG buffer). This structure is
76  * also used for setting up a buffer for Circular DDMA.
77  */
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) */
85         uint8_t bOffset;
86         /* The number of transfer segments (a DMA descriptors per each segment) */
87         uint8_t bCount;
88         /* Size (in byte) of each transfer segment */
89         uint16_t wSize;
90 } __attribute__ ((packed));
91 typedef struct _ddma_sg_buffer_setup ddma_sg_buffer_setup_t;
92
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 */
99         uint8_t bDescCount;
100         /* The total size of the transfer */
101         uint16_t wSize;
102 } __attribute__ ((packed));
103 typedef struct _ddma_concat_buffer_setup_hdr ddma_concat_buffer_setup_hdr_t;
104
105 /** Descriptor DMA Concatenation Buffer setup structure */
106 struct _ddma_concat_buffer_setup {
107         /* The SG header */
108         ddma_concat_buffer_setup_hdr_t hdr;
109
110         /* The XFER sizes pointer (allocated dynamically) */
111         uint16_t *wTxBytes;
112 } __attribute__ ((packed));
113 typedef struct _ddma_concat_buffer_setup ddma_concat_buffer_setup_t;
114
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;
119         uint8_t bAlign;
120 } __attribute__ ((packed));
121 typedef struct _ddma_align_buffer_setup ddma_align_buffer_setup_t;
122
123 /** Transmit FIFO Size setup structure */
124 struct _tx_fifo_size_setup {
125         uint8_t bEndpointAddress;
126         uint16_t wDepth;
127 } __attribute__ ((packed));
128 typedef struct _tx_fifo_size_setup tx_fifo_size_setup_t;
129
130 /** Transmit FIFO Size setup structure */
131 struct _rx_fifo_size_setup {
132         uint16_t wDepth;
133 } __attribute__ ((packed));
134 typedef struct _rx_fifo_size_setup rx_fifo_size_setup_t;
135
136 /**
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.
140  */
141 struct cfi_usb_ctrlrequest {
142         uint8_t bRequestType;
143         uint8_t bRequest;
144         uint16_t wValue;
145         uint16_t wIndex;
146         uint16_t wLength;
147         uint8_t *data;
148 } UPACKED;
149
150 /*---------------------------------------------------------------------------*/
151
152 /**
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.
156  */
157 struct cfi_ep {
158         /* Entry for the list container */
159         dwc_list_link_t lh;
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;
172         /* XFER length */
173         uint32_t xfer_len;
174         /*
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
178          */
179         uint32_t desc_count;
180 };
181 typedef struct cfi_ep cfi_ep_t;
182
183 typedef struct cfi_dma_buff {
184 #define CFI_IN_BUF_LEN  1024
185 #define CFI_OUT_BUF_LEN 1024
186         dma_addr_t addr;
187         uint8_t *buf;
188 } cfi_dma_buff_t;
189
190 struct cfiobject;
191
192 /**
193  * This is the interface for the CFI operations.
194  *
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
199  */
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);
213 } cfi_ops_t;
214
215 struct cfiobject {
216         cfi_ops_t ops;
217         struct dwc_otg_pcd *pcd;
218         struct usb_gadget *gadget;
219
220         /* Buffers used to send/receive CFI-related request data */
221         cfi_dma_buff_t buf_in;
222         cfi_dma_buff_t buf_out;
223
224         /* CFI specific Control request wrapper */
225         struct cfi_usb_ctrlrequest ctrl_req;
226
227         /* The list of active EP's in the PCD of type cfi_ep_t */
228         dwc_list_link_t active_eps;
229
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)
235          */
236         uint8_t need_gadget_att;
237
238         /* Flag indicating whether the status IN phase needs to be
239          * completed by the PCD
240          */
241         uint8_t need_status_in_complete;
242 };
243 typedef struct cfiobject cfiobject_t;
244
245 #define DUMP_MSG
246
247 #if defined(DUMP_MSG)
248 static inline void dump_msg(const u8 *buf, unsigned int length)
249 {
250         unsigned int start, num, i;
251         char line[52], *p;
252
253         if (length >= 512)
254                 return;
255
256         start = 0;
257         while (length > 0) {
258                 num = min(length, 16u);
259                 p = line;
260                 for (i = 0; i < num; ++i) {
261                         if (i == 8)
262                                 *p++ = ' ';
263                         DWC_SPRINTF(p, " %02x", buf[i]);
264                         p += 3;
265                 }
266                 *p = 0;
267                 DWC_DEBUG("%6x: %s\n", start, line);
268                 buf += num;
269                 start += num;
270                 length -= num;
271         }
272 }
273 #else
274 static inline void dump_msg(const u8 *buf, unsigned int length)
275 {
276 }
277 #endif
278
279 /**
280  * This function returns a pointer to cfi_ep_t object with the addr address.
281  */
282 static inline struct cfi_ep *get_cfi_ep_by_addr(struct cfiobject *cfi,
283                                                 uint8_t addr)
284 {
285         struct cfi_ep *pcfiep;
286         dwc_list_link_t *tmp;
287
288         DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
289                 pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
290
291                 if (pcfiep->ep->desc->bEndpointAddress == addr) {
292                         return pcfiep;
293                 }
294         }
295
296         return NULL;
297 }
298
299 /**
300  * This function returns a pointer to cfi_ep_t object that matches
301  * the dwc_otg_pcd_ep object.
302  */
303 static inline struct cfi_ep *get_cfi_ep_by_pcd_ep(struct cfiobject *cfi,
304                                                   struct dwc_otg_pcd_ep *ep)
305 {
306         struct cfi_ep *pcfiep = NULL;
307         dwc_list_link_t *tmp;
308
309         DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
310                 pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
311                 if (pcfiep->ep == ep) {
312                         return pcfiep;
313                 }
314         }
315         return NULL;
316 }
317
318 int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl);
319
320 #endif /* (__DWC_OTG_CFI_H__) */