1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * debug.h - DesignWare USB3 DRD Controller Debug Header
4 *
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
6 *
7 * Authors: Felipe Balbi <balbi@ti.com>,
8 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
9 */
10
11 #ifndef __DWC3_DEBUG_H
12 #define __DWC3_DEBUG_H
13
14 #include "core.h"
15
16 /**
17 * dwc3_mode_string - returns mode name
18 * @mode: GCTL.PrtCapDir value
19 */
dwc3_mode_string(u32 mode)20 static inline const char *dwc3_mode_string(u32 mode)
21 {
22 switch (mode) {
23 case DWC3_GCTL_PRTCAP_HOST:
24 return "host";
25 case DWC3_GCTL_PRTCAP_DEVICE:
26 return "device";
27 case DWC3_GCTL_PRTCAP_OTG:
28 return "otg";
29 default:
30 return "UNKNOWN";
31 }
32 }
33
34 /**
35 * dwc3_gadget_ep_cmd_string - returns endpoint command string
36 * @cmd: command code
37 */
38 static inline const char *
dwc3_gadget_ep_cmd_string(u8 cmd)39 dwc3_gadget_ep_cmd_string(u8 cmd)
40 {
41 switch (cmd) {
42 case DWC3_DEPCMD_DEPSTARTCFG:
43 return "Start New Configuration";
44 case DWC3_DEPCMD_ENDTRANSFER:
45 return "End Transfer";
46 case DWC3_DEPCMD_UPDATETRANSFER:
47 return "Update Transfer";
48 case DWC3_DEPCMD_STARTTRANSFER:
49 return "Start Transfer";
50 case DWC3_DEPCMD_CLEARSTALL:
51 return "Clear Stall";
52 case DWC3_DEPCMD_SETSTALL:
53 return "Set Stall";
54 case DWC3_DEPCMD_GETEPSTATE:
55 return "Get Endpoint State";
56 case DWC3_DEPCMD_SETTRANSFRESOURCE:
57 return "Set Endpoint Transfer Resource";
58 case DWC3_DEPCMD_SETEPCONFIG:
59 return "Set Endpoint Configuration";
60 default:
61 return "UNKNOWN command";
62 }
63 }
64
65 /**
66 * dwc3_gadget_generic_cmd_string - returns generic command string
67 * @cmd: command code
68 */
69 static inline const char *
dwc3_gadget_generic_cmd_string(u8 cmd)70 dwc3_gadget_generic_cmd_string(u8 cmd)
71 {
72 switch (cmd) {
73 case DWC3_DGCMD_SET_LMP:
74 return "Set LMP";
75 case DWC3_DGCMD_SET_PERIODIC_PAR:
76 return "Set Periodic Parameters";
77 case DWC3_DGCMD_XMIT_FUNCTION:
78 return "Transmit Function Wake Device Notification";
79 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO:
80 return "Set Scratchpad Buffer Array Address Lo";
81 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI:
82 return "Set Scratchpad Buffer Array Address Hi";
83 case DWC3_DGCMD_SELECTED_FIFO_FLUSH:
84 return "Selected FIFO Flush";
85 case DWC3_DGCMD_ALL_FIFO_FLUSH:
86 return "All FIFO Flush";
87 case DWC3_DGCMD_SET_ENDPOINT_NRDY:
88 return "Set Endpoint NRDY";
89 case DWC3_DGCMD_SET_ENDPOINT_PRIME:
90 return "Set Endpoint Prime";
91 case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK:
92 return "Run SoC Bus Loopback Test";
93 case DWC3_DGCMD_DEV_NOTIFICATION:
94 return "Device Notification";
95 default:
96 return "UNKNOWN";
97 }
98 }
99
100 /**
101 * dwc3_gadget_link_string - returns link name
102 * @link_state: link state code
103 */
104 static inline const char *
dwc3_gadget_link_string(enum dwc3_link_state link_state)105 dwc3_gadget_link_string(enum dwc3_link_state link_state)
106 {
107 switch (link_state) {
108 case DWC3_LINK_STATE_U0:
109 return "U0";
110 case DWC3_LINK_STATE_U1:
111 return "U1";
112 case DWC3_LINK_STATE_U2:
113 return "U2";
114 case DWC3_LINK_STATE_U3:
115 return "U3";
116 case DWC3_LINK_STATE_SS_DIS:
117 return "SS.Disabled";
118 case DWC3_LINK_STATE_RX_DET:
119 return "RX.Detect";
120 case DWC3_LINK_STATE_SS_INACT:
121 return "SS.Inactive";
122 case DWC3_LINK_STATE_POLL:
123 return "Polling";
124 case DWC3_LINK_STATE_RECOV:
125 return "Recovery";
126 case DWC3_LINK_STATE_HRESET:
127 return "Hot Reset";
128 case DWC3_LINK_STATE_CMPLY:
129 return "Compliance";
130 case DWC3_LINK_STATE_LPBK:
131 return "Loopback";
132 case DWC3_LINK_STATE_RESET:
133 return "Reset";
134 case DWC3_LINK_STATE_RESUME:
135 return "Resume";
136 default:
137 return "UNKNOWN link state";
138 }
139 }
140
141 /**
142 * dwc3_gadget_hs_link_string - returns highspeed and below link name
143 * @link_state: link state code
144 */
145 static inline const char *
dwc3_gadget_hs_link_string(enum dwc3_link_state link_state)146 dwc3_gadget_hs_link_string(enum dwc3_link_state link_state)
147 {
148 switch (link_state) {
149 case DWC3_LINK_STATE_U0:
150 return "On";
151 case DWC3_LINK_STATE_U2:
152 return "Sleep";
153 case DWC3_LINK_STATE_U3:
154 return "Suspend";
155 case DWC3_LINK_STATE_SS_DIS:
156 return "Disconnected";
157 case DWC3_LINK_STATE_RX_DET:
158 return "Early Suspend";
159 case DWC3_LINK_STATE_RECOV:
160 return "Recovery";
161 case DWC3_LINK_STATE_RESET:
162 return "Reset";
163 case DWC3_LINK_STATE_RESUME:
164 return "Resume";
165 default:
166 return "UNKNOWN link state";
167 }
168 }
169
170 /**
171 * dwc3_trb_type_string - returns TRB type as a string
172 * @type: the type of the TRB
173 */
dwc3_trb_type_string(unsigned int type)174 static inline const char *dwc3_trb_type_string(unsigned int type)
175 {
176 switch (type) {
177 case DWC3_TRBCTL_NORMAL:
178 return "normal";
179 case DWC3_TRBCTL_CONTROL_SETUP:
180 return "setup";
181 case DWC3_TRBCTL_CONTROL_STATUS2:
182 return "status2";
183 case DWC3_TRBCTL_CONTROL_STATUS3:
184 return "status3";
185 case DWC3_TRBCTL_CONTROL_DATA:
186 return "data";
187 case DWC3_TRBCTL_ISOCHRONOUS_FIRST:
188 return "isoc-first";
189 case DWC3_TRBCTL_ISOCHRONOUS:
190 return "isoc";
191 case DWC3_TRBCTL_LINK_TRB:
192 return "link";
193 default:
194 return "UNKNOWN";
195 }
196 }
197
dwc3_ep0_state_string(enum dwc3_ep0_state state)198 static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
199 {
200 switch (state) {
201 case EP0_UNCONNECTED:
202 return "Unconnected";
203 case EP0_SETUP_PHASE:
204 return "Setup Phase";
205 case EP0_DATA_PHASE:
206 return "Data Phase";
207 case EP0_STATUS_PHASE:
208 return "Status Phase";
209 default:
210 return "UNKNOWN";
211 }
212 }
213
214 /**
215 * dwc3_gadget_event_string - returns event name
216 * @event: the event code
217 */
dwc3_gadget_event_string(char * str,size_t size,const struct dwc3_event_devt * event)218 static inline const char *dwc3_gadget_event_string(char *str, size_t size,
219 const struct dwc3_event_devt *event)
220 {
221 enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK;
222
223 switch (event->type) {
224 case DWC3_DEVICE_EVENT_DISCONNECT:
225 snprintf(str, size, "Disconnect: [%s]",
226 dwc3_gadget_link_string(state));
227 break;
228 case DWC3_DEVICE_EVENT_RESET:
229 snprintf(str, size, "Reset [%s]",
230 dwc3_gadget_link_string(state));
231 break;
232 case DWC3_DEVICE_EVENT_CONNECT_DONE:
233 snprintf(str, size, "Connection Done [%s]",
234 dwc3_gadget_link_string(state));
235 break;
236 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
237 snprintf(str, size, "Link Change [%s]",
238 dwc3_gadget_link_string(state));
239 break;
240 case DWC3_DEVICE_EVENT_WAKEUP:
241 snprintf(str, size, "WakeUp [%s]",
242 dwc3_gadget_link_string(state));
243 break;
244 case DWC3_DEVICE_EVENT_SUSPEND:
245 snprintf(str, size, "Suspend [%s]",
246 dwc3_gadget_link_string(state));
247 break;
248 case DWC3_DEVICE_EVENT_SOF:
249 snprintf(str, size, "Start-Of-Frame [%s]",
250 dwc3_gadget_link_string(state));
251 break;
252 case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
253 snprintf(str, size, "Erratic Error [%s]",
254 dwc3_gadget_link_string(state));
255 break;
256 case DWC3_DEVICE_EVENT_CMD_CMPL:
257 snprintf(str, size, "Command Complete [%s]",
258 dwc3_gadget_link_string(state));
259 break;
260 case DWC3_DEVICE_EVENT_OVERFLOW:
261 snprintf(str, size, "Overflow [%s]",
262 dwc3_gadget_link_string(state));
263 break;
264 default:
265 snprintf(str, size, "UNKNOWN");
266 }
267
268 return str;
269 }
270
271 /**
272 * dwc3_ep_event_string - returns event name
273 * @event: then event code
274 */
dwc3_ep_event_string(char * str,size_t size,const struct dwc3_event_depevt * event,u32 ep0state)275 static inline const char *dwc3_ep_event_string(char *str, size_t size,
276 const struct dwc3_event_depevt *event, u32 ep0state)
277 {
278 u8 epnum = event->endpoint_number;
279 size_t len;
280 int status;
281
282 len = scnprintf(str, size, "ep%d%s: ", epnum >> 1,
283 (epnum & 1) ? "in" : "out");
284
285 status = event->status;
286
287 switch (event->endpoint_event) {
288 case DWC3_DEPEVT_XFERCOMPLETE:
289 len += scnprintf(str + len, size - len,
290 "Transfer Complete (%c%c%c)",
291 status & DEPEVT_STATUS_SHORT ? 'S' : 's',
292 status & DEPEVT_STATUS_IOC ? 'I' : 'i',
293 status & DEPEVT_STATUS_LST ? 'L' : 'l');
294
295 if (epnum <= 1)
296 scnprintf(str + len, size - len, " [%s]",
297 dwc3_ep0_state_string(ep0state));
298 break;
299 case DWC3_DEPEVT_XFERINPROGRESS:
300 scnprintf(str + len, size - len,
301 "Transfer In Progress [%08x] (%c%c%c)",
302 event->parameters,
303 status & DEPEVT_STATUS_SHORT ? 'S' : 's',
304 status & DEPEVT_STATUS_IOC ? 'I' : 'i',
305 status & DEPEVT_STATUS_LST ? 'M' : 'm');
306 break;
307 case DWC3_DEPEVT_XFERNOTREADY:
308 len += scnprintf(str + len, size - len,
309 "Transfer Not Ready [%08x]%s",
310 event->parameters,
311 status & DEPEVT_STATUS_TRANSFER_ACTIVE ?
312 " (Active)" : " (Not Active)");
313
314 /* Control Endpoints */
315 if (epnum <= 1) {
316 int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status);
317
318 switch (phase) {
319 case DEPEVT_STATUS_CONTROL_DATA:
320 scnprintf(str + len, size - len,
321 " [Data Phase]");
322 break;
323 case DEPEVT_STATUS_CONTROL_STATUS:
324 scnprintf(str + len, size - len,
325 " [Status Phase]");
326 }
327 }
328 break;
329 case DWC3_DEPEVT_RXTXFIFOEVT:
330 scnprintf(str + len, size - len, "FIFO");
331 break;
332 case DWC3_DEPEVT_STREAMEVT:
333 status = event->status;
334
335 switch (status) {
336 case DEPEVT_STREAMEVT_FOUND:
337 scnprintf(str + len, size - len, " Stream %d Found",
338 event->parameters);
339 break;
340 case DEPEVT_STREAMEVT_NOTFOUND:
341 default:
342 scnprintf(str + len, size - len, " Stream Not Found");
343 break;
344 }
345
346 break;
347 case DWC3_DEPEVT_EPCMDCMPLT:
348 scnprintf(str + len, size - len, "Endpoint Command Complete");
349 break;
350 default:
351 scnprintf(str + len, size - len, "UNKNOWN");
352 }
353
354 return str;
355 }
356
357 /**
358 * dwc3_gadget_event_type_string - return event name
359 * @event: the event code
360 */
dwc3_gadget_event_type_string(u8 event)361 static inline const char *dwc3_gadget_event_type_string(u8 event)
362 {
363 switch (event) {
364 case DWC3_DEVICE_EVENT_DISCONNECT:
365 return "Disconnect";
366 case DWC3_DEVICE_EVENT_RESET:
367 return "Reset";
368 case DWC3_DEVICE_EVENT_CONNECT_DONE:
369 return "Connect Done";
370 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
371 return "Link Status Change";
372 case DWC3_DEVICE_EVENT_WAKEUP:
373 return "Wake-Up";
374 case DWC3_DEVICE_EVENT_HIBER_REQ:
375 return "Hibernation";
376 case DWC3_DEVICE_EVENT_SUSPEND:
377 return "Suspend";
378 case DWC3_DEVICE_EVENT_SOF:
379 return "Start of Frame";
380 case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
381 return "Erratic Error";
382 case DWC3_DEVICE_EVENT_CMD_CMPL:
383 return "Command Complete";
384 case DWC3_DEVICE_EVENT_OVERFLOW:
385 return "Overflow";
386 default:
387 return "UNKNOWN";
388 }
389 }
390
dwc3_decode_event(char * str,size_t size,u32 event,u32 ep0state)391 static inline const char *dwc3_decode_event(char *str, size_t size, u32 event,
392 u32 ep0state)
393 {
394 union dwc3_event evt;
395
396 memcpy(&evt, &event, sizeof(event));
397
398 if (evt.type.is_devspec)
399 return dwc3_gadget_event_string(str, size, &evt.devt);
400 else
401 return dwc3_ep_event_string(str, size, &evt.depevt, ep0state);
402 }
403
dwc3_ep_cmd_status_string(int status)404 static inline const char *dwc3_ep_cmd_status_string(int status)
405 {
406 switch (status) {
407 case -ETIMEDOUT:
408 return "Timed Out";
409 case 0:
410 return "Successful";
411 case DEPEVT_TRANSFER_NO_RESOURCE:
412 return "No Resource";
413 case DEPEVT_TRANSFER_BUS_EXPIRY:
414 return "Bus Expiry";
415 default:
416 return "UNKNOWN";
417 }
418 }
419
dwc3_gadget_generic_cmd_status_string(int status)420 static inline const char *dwc3_gadget_generic_cmd_status_string(int status)
421 {
422 switch (status) {
423 case -ETIMEDOUT:
424 return "Timed Out";
425 case 0:
426 return "Successful";
427 case 1:
428 return "Error";
429 default:
430 return "UNKNOWN";
431 }
432 }
433
434
435 #ifdef CONFIG_DEBUG_FS
436 extern void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep);
437 extern void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep);
438 extern void dwc3_debugfs_init(struct dwc3 *d);
439 extern void dwc3_debugfs_exit(struct dwc3 *d);
440 #else
dwc3_debugfs_create_endpoint_dir(struct dwc3_ep * dep)441 static inline void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
442 { }
dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep * dep)443 static inline void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep)
444 { }
dwc3_debugfs_init(struct dwc3 * d)445 static inline void dwc3_debugfs_init(struct dwc3 *d)
446 { }
dwc3_debugfs_exit(struct dwc3 * d)447 static inline void dwc3_debugfs_exit(struct dwc3 *d)
448 { }
449 #endif
450 #endif /* __DWC3_DEBUG_H */
451