dwc_otg_cfi.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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. #if !defined(__DWC_OTG_CFI_H__)
  29. #define __DWC_OTG_CFI_H__
  30. #include "dwc_otg_pcd.h"
  31. #include "dwc_cfi_common.h"
  32. /**
  33. * @file
  34. * This file contains the CFI related OTG PCD specific common constants,
  35. * interfaces(functions and macros) and data structures.The CFI Protocol is an
  36. * optional interface for internal testing purposes that a DUT may implement to
  37. * support testing of configurable features.
  38. *
  39. */
  40. struct dwc_otg_pcd;
  41. struct dwc_otg_pcd_ep;
  42. /** OTG CFI Features (properties) ID constants */
  43. /** This is a request for all Core Features */
  44. #define FT_ID_DMA_MODE 0x0001
  45. #define FT_ID_DMA_BUFFER_SETUP 0x0002
  46. #define FT_ID_DMA_BUFF_ALIGN 0x0003
  47. #define FT_ID_DMA_CONCAT_SETUP 0x0004
  48. #define FT_ID_DMA_CIRCULAR 0x0005
  49. #define FT_ID_THRESHOLD_SETUP 0x0006
  50. #define FT_ID_DFIFO_DEPTH 0x0007
  51. #define FT_ID_TX_FIFO_DEPTH 0x0008
  52. #define FT_ID_RX_FIFO_DEPTH 0x0009
  53. /**********************************************************/
  54. #define CFI_INFO_DEF
  55. #ifdef CFI_INFO_DEF
  56. #define CFI_INFO(fmt...) DWC_PRINTF("CFI: " fmt);
  57. #else
  58. #define CFI_INFO(fmt...)
  59. #endif
  60. #define min(x,y) ({ \
  61. x < y ? x : y; })
  62. #define max(x,y) ({ \
  63. x > y ? x : y; })
  64. /**
  65. * Descriptor DMA SG Buffer setup structure (SG buffer). This structure is
  66. * also used for setting up a buffer for Circular DDMA.
  67. */
  68. struct _ddma_sg_buffer_setup {
  69. #define BS_SG_VAL_DESC_LEN 6
  70. /* The OUT EP address */
  71. uint8_t bOutEndpointAddress;
  72. /* The IN EP address */
  73. uint8_t bInEndpointAddress;
  74. /* Number of bytes to put between transfer segments (must be DWORD boundaries) */
  75. uint8_t bOffset;
  76. /* The number of transfer segments (a DMA descriptors per each segment) */
  77. uint8_t bCount;
  78. /* Size (in byte) of each transfer segment */
  79. uint16_t wSize;
  80. } __attribute__ ((packed));
  81. typedef struct _ddma_sg_buffer_setup ddma_sg_buffer_setup_t;
  82. /** Descriptor DMA Concatenation Buffer setup structure */
  83. struct _ddma_concat_buffer_setup_hdr {
  84. #define BS_CONCAT_VAL_HDR_LEN 4
  85. /* The endpoint for which the buffer is to be set up */
  86. uint8_t bEndpointAddress;
  87. /* The count of descriptors to be used */
  88. uint8_t bDescCount;
  89. /* The total size of the transfer */
  90. uint16_t wSize;
  91. } __attribute__ ((packed));
  92. typedef struct _ddma_concat_buffer_setup_hdr ddma_concat_buffer_setup_hdr_t;
  93. /** Descriptor DMA Concatenation Buffer setup structure */
  94. struct _ddma_concat_buffer_setup {
  95. /* The SG header */
  96. ddma_concat_buffer_setup_hdr_t hdr;
  97. /* The XFER sizes pointer (allocated dynamically) */
  98. uint16_t *wTxBytes;
  99. } __attribute__ ((packed));
  100. typedef struct _ddma_concat_buffer_setup ddma_concat_buffer_setup_t;
  101. /** Descriptor DMA Alignment Buffer setup structure */
  102. struct _ddma_align_buffer_setup {
  103. #define BS_ALIGN_VAL_HDR_LEN 2
  104. uint8_t bEndpointAddress;
  105. uint8_t bAlign;
  106. } __attribute__ ((packed));
  107. typedef struct _ddma_align_buffer_setup ddma_align_buffer_setup_t;
  108. /** Transmit FIFO Size setup structure */
  109. struct _tx_fifo_size_setup {
  110. uint8_t bEndpointAddress;
  111. uint16_t wDepth;
  112. } __attribute__ ((packed));
  113. typedef struct _tx_fifo_size_setup tx_fifo_size_setup_t;
  114. /** Transmit FIFO Size setup structure */
  115. struct _rx_fifo_size_setup {
  116. uint16_t wDepth;
  117. } __attribute__ ((packed));
  118. typedef struct _rx_fifo_size_setup rx_fifo_size_setup_t;
  119. /**
  120. * struct cfi_usb_ctrlrequest - the CFI implementation of the struct usb_ctrlrequest
  121. * This structure encapsulates the standard usb_ctrlrequest and adds a pointer
  122. * to the data returned in the data stage of a 3-stage Control Write requests.
  123. */
  124. struct cfi_usb_ctrlrequest {
  125. uint8_t bRequestType;
  126. uint8_t bRequest;
  127. uint16_t wValue;
  128. uint16_t wIndex;
  129. uint16_t wLength;
  130. uint8_t *data;
  131. } UPACKED;
  132. /*---------------------------------------------------------------------------*/
  133. /**
  134. * The CFI wrapper of the enabled and activated dwc_otg_pcd_ep structures.
  135. * This structure is used to store the buffer setup data for any
  136. * enabled endpoint in the PCD.
  137. */
  138. struct cfi_ep {
  139. /* Entry for the list container */
  140. dwc_list_link_t lh;
  141. /* Pointer to the active PCD endpoint structure */
  142. struct dwc_otg_pcd_ep *ep;
  143. /* The last descriptor in the chain of DMA descriptors of the endpoint */
  144. struct dwc_otg_dma_desc *dma_desc_last;
  145. /* The SG feature value */
  146. ddma_sg_buffer_setup_t *bm_sg;
  147. /* The Circular feature value */
  148. ddma_sg_buffer_setup_t *bm_circ;
  149. /* The Concatenation feature value */
  150. ddma_concat_buffer_setup_t *bm_concat;
  151. /* The Alignment feature value */
  152. ddma_align_buffer_setup_t *bm_align;
  153. /* XFER length */
  154. uint32_t xfer_len;
  155. /*
  156. * Count of DMA descriptors currently used.
  157. * The total should not exceed the MAX_DMA_DESCS_PER_EP value
  158. * defined in the dwc_otg_cil.h
  159. */
  160. uint32_t desc_count;
  161. };
  162. typedef struct cfi_ep cfi_ep_t;
  163. typedef struct cfi_dma_buff {
  164. #define CFI_IN_BUF_LEN 1024
  165. #define CFI_OUT_BUF_LEN 1024
  166. dma_addr_t addr;
  167. uint8_t *buf;
  168. } cfi_dma_buff_t;
  169. struct cfiobject;
  170. /**
  171. * This is the interface for the CFI operations.
  172. *
  173. * @param ep_enable Called when any endpoint is enabled and activated.
  174. * @param release Called when the CFI object is released and it needs to correctly
  175. * deallocate the dynamic memory
  176. * @param ctrl_write_complete Called when the data stage of the request is complete
  177. */
  178. typedef struct cfi_ops {
  179. int (*ep_enable) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
  180. struct dwc_otg_pcd_ep * ep);
  181. void *(*ep_alloc_buf) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
  182. struct dwc_otg_pcd_ep * ep, dma_addr_t * dma,
  183. unsigned size, gfp_t flags);
  184. void (*release) (struct cfiobject * cfi);
  185. int (*ctrl_write_complete) (struct cfiobject * cfi,
  186. struct dwc_otg_pcd * pcd);
  187. void (*build_descriptors) (struct cfiobject * cfi,
  188. struct dwc_otg_pcd * pcd,
  189. struct dwc_otg_pcd_ep * ep,
  190. dwc_otg_pcd_request_t * req);
  191. } cfi_ops_t;
  192. struct cfiobject {
  193. cfi_ops_t ops;
  194. struct dwc_otg_pcd *pcd;
  195. struct usb_gadget *gadget;
  196. /* Buffers used to send/receive CFI-related request data */
  197. cfi_dma_buff_t buf_in;
  198. cfi_dma_buff_t buf_out;
  199. /* CFI specific Control request wrapper */
  200. struct cfi_usb_ctrlrequest ctrl_req;
  201. /* The list of active EP's in the PCD of type cfi_ep_t */
  202. dwc_list_link_t active_eps;
  203. /* This flag shall control the propagation of a specific request
  204. * to the gadget's processing routines.
  205. * 0 - no gadget handling
  206. * 1 - the gadget needs to know about this request (w/o completing a status
  207. * phase - just return a 0 to the _setup callback)
  208. */
  209. uint8_t need_gadget_att;
  210. /* Flag indicating whether the status IN phase needs to be
  211. * completed by the PCD
  212. */
  213. uint8_t need_status_in_complete;
  214. };
  215. typedef struct cfiobject cfiobject_t;
  216. #define DUMP_MSG
  217. #if defined(DUMP_MSG)
  218. static inline void dump_msg(const u8 * buf, unsigned int length)
  219. {
  220. unsigned int start, num, i;
  221. char line[52], *p;
  222. if (length >= 512)
  223. return;
  224. start = 0;
  225. while (length > 0) {
  226. num = min(length, 16u);
  227. p = line;
  228. for (i = 0; i < num; ++i) {
  229. if (i == 8)
  230. *p++ = ' ';
  231. DWC_SPRINTF(p, " %02x", buf[i]);
  232. p += 3;
  233. }
  234. *p = 0;
  235. DWC_DEBUG("%6x: %s\n", start, line);
  236. buf += num;
  237. start += num;
  238. length -= num;
  239. }
  240. }
  241. #else
  242. static inline void dump_msg(const u8 * buf, unsigned int length)
  243. {
  244. }
  245. #endif
  246. /**
  247. * This function returns a pointer to cfi_ep_t object with the addr address.
  248. */
  249. static inline struct cfi_ep *get_cfi_ep_by_addr(struct cfiobject *cfi,
  250. uint8_t addr)
  251. {
  252. struct cfi_ep *pcfiep;
  253. dwc_list_link_t *tmp;
  254. DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
  255. pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
  256. if (pcfiep->ep->desc->bEndpointAddress == addr) {
  257. return pcfiep;
  258. }
  259. }
  260. return NULL;
  261. }
  262. /**
  263. * This function returns a pointer to cfi_ep_t object that matches
  264. * the dwc_otg_pcd_ep object.
  265. */
  266. static inline struct cfi_ep *get_cfi_ep_by_pcd_ep(struct cfiobject *cfi,
  267. struct dwc_otg_pcd_ep *ep)
  268. {
  269. struct cfi_ep *pcfiep = NULL;
  270. dwc_list_link_t *tmp;
  271. DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
  272. pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
  273. if (pcfiep->ep == ep) {
  274. return pcfiep;
  275. }
  276. }
  277. return NULL;
  278. }
  279. int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl);
  280. #endif /* (__DWC_OTG_CFI_H__) */