aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.h
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-08-19 11:10:58 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-22 19:03:11 -0400
commit72246da40f3719af3bfd104a2365b32537c27d83 (patch)
treedb6a4b139c24340e0d5dccab8d9df0b23ab509ef /drivers/usb/dwc3/gadget.h
parent500fdf8becb9c8d51970c7ac6a4fa308a5481ebe (diff)
usb: Introduce DesignWare USB3 DRD Driver
The DesignWare USB3 is a highly configurable IP Core which can be instantiated as Dual-Role Device (DRD), Peripheral Only and Host Only (XHCI) configurations. Several other parameters can be configured like amount of FIFO space, amount of TX and RX endpoints, amount of Host Interrupters, etc. The current driver has been validated with a virtual model of version 1.73a of that core and with an FPGA burned with version 1.83a of the DRD core. We have support for PCIe bus, which is used on FPGA prototyping, and for the OMAP5, more adaptation (or glue) layers can be easily added and the driver is half prepared to handle any possible configuration the HW engineer has chosen considering we have the information on one of the GHWPARAMS registers to do runtime checking of certain features. More runtime checks can, and should, be added in order to make this driver even more flexible with regards to number of endpoints, FIFO sizes, transfer types, etc. While this supports only the device side, for now, we will add support for Host side (xHCI - see the updated series Sebastian has sent [1]) and OTG after we have it all stabilized. [1] http://marc.info/?l=linux-usb&m=131341992020339&w=2 Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/dwc3/gadget.h')
-rw-r--r--drivers/usb/dwc3/gadget.h292
1 files changed, 292 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
new file mode 100644
index 000000000000..ccfc109f0902
--- /dev/null
+++ b/drivers/usb/dwc3/gadget.h
@@ -0,0 +1,292 @@
1/**
2 * gadget.h - DesignWare USB3 DRD Gadget Header
3 *
4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
5 * All rights reserved.
6 *
7 * Authors: Felipe Balbi <balbi@ti.com>,
8 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The names of the above-listed copyright holders may not be used
20 * to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * ALTERNATIVELY, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2, as published by the Free
25 * Software Foundation.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39
40#ifndef __DRIVERS_USB_DWC3_GADGET_H
41#define __DRIVERS_USB_DWC3_GADGET_H
42
43#include <linux/list.h>
44#include <linux/usb/gadget.h>
45#include "io.h"
46
47struct dwc3;
48#define to_dwc3_ep(ep) (container_of(ep, struct dwc3_ep, endpoint))
49#define gadget_to_dwc(g) (container_of(g, struct dwc3, gadget))
50
51/**
52 * struct dwc3_gadget_ep_depcfg_param1 - DEPCMDPAR0 for DEPCFG command
53 * @interrupt_number: self-explanatory
54 * @reserved7_5: set to zero
55 * @xfer_complete_enable: event generated when transfer completed
56 * @xfer_in_progress_enable: event generated when transfer in progress
57 * @xfer_not_ready_enable: event generated when transfer not read
58 * @fifo_error_enable: generates events when FIFO Underrun (IN eps)
59 * or FIFO Overrun (OUT) eps
60 * @reserved_12: set to zero
61 * @stream_event_enable: event generated on stream
62 * @reserved14_15: set to zero
63 * @binterval_m1: bInterval minus 1
64 * @stream_capable: this EP is capable of handling streams
65 * @ep_number: self-explanatory
66 * @bulk_based: Set to ‘1’ if this isochronous endpoint represents a bulk
67 * data stream that ignores the relationship of bus time to the
68 * intervals programmed in TRBs.
69 * @fifo_based: Set to ‘1’ if this isochronous endpoint represents a
70 * FIFO-based data stream where TRBs have fixed values and are never
71 * written back by the core.
72 */
73struct dwc3_gadget_ep_depcfg_param1 {
74 u32 interrupt_number:5;
75 u32 reserved7_5:3; /* set to zero */
76 u32 xfer_complete_enable:1;
77 u32 xfer_in_progress_enable:1;
78 u32 xfer_not_ready_enable:1;
79 u32 fifo_error_enable:1; /* IN-underrun, OUT-overrun */
80 u32 reserved12:1; /* set to zero */
81 u32 stream_event_enable:1;
82 u32 reserved14_15:2;
83 u32 binterval_m1:8; /* bInterval minus 1 */
84 u32 stream_capable:1;
85 u32 ep_number:5;
86 u32 bulk_based:1;
87 u32 fifo_based:1;
88} __packed;
89
90/**
91 * struct dwc3_gadget_ep_depcfg_param0 - Parameter 0 for DEPCFG
92 * @reserved0: set to zero
93 * @ep_type: Endpoint Type (control, bulk, iso, interrupt)
94 * @max_packet_size: max packet size in bytes
95 * @reserved16_14: set to zero
96 * @fifo_number: self-explanatory
97 * @burst_size: burst size minus 1
98 * @data_sequence_number: Must be 0 when an endpoint is initially configured
99 * May be non-zero when an endpoint is configured after a power transition
100 * that requires a save/restore.
101 * @ignore_sequence_number: Set to ‘1’ to avoid resetting the sequence
102 * number. This setting is used by software to modify the DEPEVTEN
103 * event enable bits without modifying other endpoint settings.
104 */
105struct dwc3_gadget_ep_depcfg_param0 {
106 u32 reserved0:1;
107 u32 ep_type:2;
108 u32 max_packet_size:11;
109 u32 reserved16_14:3;
110 u32 fifo_number:5;
111 u32 burst_size:4;
112 u32 data_sequence_number:5;
113 u32 ignore_sequence_number:1;
114} __packed;
115
116/**
117 * struct dwc3_gadget_ep_depxfercfg_param0 - Parameter 0 of DEPXFERCFG
118 * @number_xfer_resources: Defines the number of Transfer Resources allocated
119 * to this endpoint. This field must be set to 1.
120 * @reserved16_31: set to zero;
121 */
122struct dwc3_gadget_ep_depxfercfg_param0 {
123 u32 number_xfer_resources:16;
124 u32 reserved16_31:16;
125} __packed;
126
127/**
128 * struct dwc3_gadget_ep_depstrtxfer_param1 - Parameter 1 of DEPSTRTXFER
129 * @transfer_desc_addr_low: Indicates the lower 32 bits of the external
130 * memory's start address for the transfer descriptor. Because TRBs
131 * must be aligned to a 16-byte boundary, the lower 4 bits of this
132 * address must be 0.
133 */
134struct dwc3_gadget_ep_depstrtxfer_param1 {
135 u32 transfer_desc_addr_low;
136} __packed;
137
138/**
139 * struct dwc3_gadget_ep_depstrtxfer_param1 - Parameter 1 of DEPSTRTXFER
140 * @transfer_desc_addr_high: Indicates the higher 32 bits of the external
141 * memory’s start address for the transfer descriptor.
142 */
143struct dwc3_gadget_ep_depstrtxfer_param0 {
144 u32 transfer_desc_addr_high;
145} __packed;
146
147struct dwc3_gadget_ep_cmd_params {
148 union {
149 u32 raw;
150 } param2;
151
152 union {
153 u32 raw;
154 struct dwc3_gadget_ep_depcfg_param1 depcfg;
155 struct dwc3_gadget_ep_depstrtxfer_param1 depstrtxfer;
156 } param1;
157
158 union {
159 u32 raw;
160 struct dwc3_gadget_ep_depcfg_param0 depcfg;
161 struct dwc3_gadget_ep_depxfercfg_param0 depxfercfg;
162 struct dwc3_gadget_ep_depstrtxfer_param0 depstrtxfer;
163 } param0;
164} __packed;
165
166/* -------------------------------------------------------------------------- */
167
168struct dwc3_request {
169 struct usb_request request;
170 struct list_head list;
171 struct dwc3_ep *dep;
172
173 u8 epnum;
174 struct dwc3_trb_hw *trb;
175 dma_addr_t trb_dma;
176
177 unsigned direction:1;
178 unsigned mapped:1;
179 unsigned queued:1;
180};
181#define to_dwc3_request(r) (container_of(r, struct dwc3_request, request))
182
183static inline struct dwc3_request *next_request(struct list_head *list)
184{
185 if (list_empty(list))
186 return NULL;
187
188 return list_first_entry(list, struct dwc3_request, list);
189}
190
191static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req)
192{
193 struct dwc3_ep *dep = req->dep;
194
195 req->queued = true;
196 list_move_tail(&req->list, &dep->req_queued);
197}
198
199#if defined(CONFIG_USB_GADGET_DWC3) || defined(CONFIG_USB_GADGET_DWC3_MODULE)
200int dwc3_gadget_init(struct dwc3 *dwc);
201void dwc3_gadget_exit(struct dwc3 *dwc);
202#else
203static inline int dwc3_gadget_init(struct dwc3 *dwc) { return 0; }
204static inline void dwc3_gadget_exit(struct dwc3 *dwc) { }
205#endif
206
207void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
208 int status);
209
210void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event);
211void dwc3_ep0_out_start(struct dwc3 *dwc);
212int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
213 gfp_t gfp_flags);
214int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value);
215int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
216 unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
217void dwc3_map_buffer_to_dma(struct dwc3_request *req);
218void dwc3_unmap_buffer_from_dma(struct dwc3_request *req);
219
220/**
221 * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
222 * @dwc: DesignWare USB3 Pointer
223 * @number: DWC endpoint number
224 *
225 * Caller should take care of locking
226 */
227static inline u32 dwc3_gadget_ep_get_transfer_index(struct dwc3 *dwc, u8 number)
228{
229 u32 res_id;
230
231 res_id = dwc3_readl(dwc->regs, DWC3_DEPCMD(number));
232
233 return DWC3_DEPCMD_GET_RSC_IDX(res_id);
234}
235
236/**
237 * dwc3_gadget_event_string - returns event name
238 * @event: the event code
239 */
240static inline const char *dwc3_gadget_event_string(u8 event)
241{
242 switch (event) {
243 case DWC3_DEVICE_EVENT_DISCONNECT:
244 return "Disconnect";
245 case DWC3_DEVICE_EVENT_RESET:
246 return "Reset";
247 case DWC3_DEVICE_EVENT_CONNECT_DONE:
248 return "Connection Done";
249 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
250 return "Link Status Change";
251 case DWC3_DEVICE_EVENT_WAKEUP:
252 return "WakeUp";
253 case DWC3_DEVICE_EVENT_EOPF:
254 return "End-Of-Frame";
255 case DWC3_DEVICE_EVENT_SOF:
256 return "Start-Of-Frame";
257 case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
258 return "Erratic Error";
259 case DWC3_DEVICE_EVENT_CMD_CMPL:
260 return "Command Complete";
261 case DWC3_DEVICE_EVENT_OVERFLOW:
262 return "Overflow";
263 }
264
265 return "UNKNOWN";
266}
267
268/**
269 * dwc3_ep_event_string - returns event name
270 * @event: then event code
271 */
272static inline const char *dwc3_ep_event_string(u8 event)
273{
274 switch (event) {
275 case DWC3_DEPEVT_XFERCOMPLETE:
276 return "Transfer Complete";
277 case DWC3_DEPEVT_XFERINPROGRESS:
278 return "Transfer In-Progress";
279 case DWC3_DEPEVT_XFERNOTREADY:
280 return "Transfer Not Ready";
281 case DWC3_DEPEVT_RXTXFIFOEVT:
282 return "FIFO";
283 case DWC3_DEPEVT_STREAMEVT:
284 return "Stream";
285 case DWC3_DEPEVT_EPCMDCMPLT:
286 return "Endpoint Command Complete";
287 }
288
289 return "UNKNOWN";
290}
291
292#endif /* __DRIVERS_USB_DWC3_GADGET_H */