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