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 */ 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 * 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 * 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 * 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 * 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 */ 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 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 */ 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 */ 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 */ 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 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 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 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 441 static inline void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep) 442 { } 443 static inline void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep) 444 { } 445 static inline void dwc3_debugfs_init(struct dwc3 *d) 446 { } 447 static inline void dwc3_debugfs_exit(struct dwc3 *d) 448 { } 449 #endif 450 #endif /* __DWC3_DEBUG_H */ 451