cdns2-debug.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Cadence USBHS-DEV Driver.
  4. * Debug header file.
  5. *
  6. * Copyright (C) 2023 Cadence.
  7. *
  8. * Author: Pawel Laszczak <pawell@cadence.com>
  9. */
  10. #ifndef __LINUX_CDNS2_DEBUG
  11. #define __LINUX_CDNS2_DEBUG
  12. static inline const char *cdns2_decode_usb_irq(char *str, size_t size,
  13. u8 usb_irq, u8 ext_irq)
  14. {
  15. int ret;
  16. ret = scnprintf(str, size, "usbirq: 0x%02x - ", usb_irq);
  17. if (usb_irq & USBIRQ_SOF)
  18. ret += scnprintf(str + ret, size - ret, "SOF ");
  19. if (usb_irq & USBIRQ_SUTOK)
  20. ret += scnprintf(str + ret, size - ret, "SUTOK ");
  21. if (usb_irq & USBIRQ_SUDAV)
  22. ret += scnprintf(str + ret, size - ret, "SETUP ");
  23. if (usb_irq & USBIRQ_SUSPEND)
  24. ret += scnprintf(str + ret, size - ret, "Suspend ");
  25. if (usb_irq & USBIRQ_URESET)
  26. ret += scnprintf(str + ret, size - ret, "Reset ");
  27. if (usb_irq & USBIRQ_HSPEED)
  28. ret += scnprintf(str + ret, size - ret, "HS ");
  29. if (usb_irq & USBIRQ_LPM)
  30. ret += scnprintf(str + ret, size - ret, "LPM ");
  31. ret += scnprintf(str + ret, size - ret, ", EXT: 0x%02x - ", ext_irq);
  32. if (ext_irq & EXTIRQ_WAKEUP)
  33. ret += scnprintf(str + ret, size - ret, "Wakeup ");
  34. if (ext_irq & EXTIRQ_VBUSFAULT_FALL)
  35. ret += scnprintf(str + ret, size - ret, "VBUS_FALL ");
  36. if (ext_irq & EXTIRQ_VBUSFAULT_RISE)
  37. ret += scnprintf(str + ret, size - ret, "VBUS_RISE ");
  38. if (ret == size - 1)
  39. pr_info("CDNS2: buffer may be truncated.\n");
  40. return str;
  41. }
  42. static inline const char *cdns2_decode_dma_irq(char *str, size_t size,
  43. u32 ep_ists, u32 ep_sts,
  44. const char *ep_name)
  45. {
  46. int ret;
  47. ret = scnprintf(str, size, "ISTS: %08x, %s: %08x ",
  48. ep_ists, ep_name, ep_sts);
  49. if (ep_sts & DMA_EP_STS_IOC)
  50. ret += scnprintf(str + ret, size - ret, "IOC ");
  51. if (ep_sts & DMA_EP_STS_ISP)
  52. ret += scnprintf(str + ret, size - ret, "ISP ");
  53. if (ep_sts & DMA_EP_STS_DESCMIS)
  54. ret += scnprintf(str + ret, size - ret, "DESCMIS ");
  55. if (ep_sts & DMA_EP_STS_TRBERR)
  56. ret += scnprintf(str + ret, size - ret, "TRBERR ");
  57. if (ep_sts & DMA_EP_STS_OUTSMM)
  58. ret += scnprintf(str + ret, size - ret, "OUTSMM ");
  59. if (ep_sts & DMA_EP_STS_ISOERR)
  60. ret += scnprintf(str + ret, size - ret, "ISOERR ");
  61. if (ep_sts & DMA_EP_STS_DBUSY)
  62. ret += scnprintf(str + ret, size - ret, "DBUSY ");
  63. if (DMA_EP_STS_CCS(ep_sts))
  64. ret += scnprintf(str + ret, size - ret, "CCS ");
  65. if (ret == size - 1)
  66. pr_info("CDNS2: buffer may be truncated.\n");
  67. return str;
  68. }
  69. static inline const char *cdns2_decode_epx_irq(char *str, size_t size,
  70. char *ep_name, u32 ep_ists,
  71. u32 ep_sts)
  72. {
  73. return cdns2_decode_dma_irq(str, size, ep_ists, ep_sts, ep_name);
  74. }
  75. static inline const char *cdns2_decode_ep0_irq(char *str, size_t size,
  76. u32 ep_ists, u32 ep_sts,
  77. int dir)
  78. {
  79. return cdns2_decode_dma_irq(str, size, ep_ists, ep_sts,
  80. dir ? "ep0IN" : "ep0OUT");
  81. }
  82. static inline const char *cdns2_raw_ring(struct cdns2_endpoint *pep,
  83. struct cdns2_trb *trbs,
  84. char *str, size_t size)
  85. {
  86. struct cdns2_ring *ring = &pep->ring;
  87. struct cdns2_trb *trb;
  88. dma_addr_t dma;
  89. int ret;
  90. int i;
  91. ret = scnprintf(str, size, "\n\t\tTR for %s:", pep->name);
  92. trb = &trbs[ring->dequeue];
  93. dma = cdns2_trb_virt_to_dma(pep, trb);
  94. ret += scnprintf(str + ret, size - ret,
  95. "\n\t\tRing deq index: %d, trb: V=%p, P=0x%pad\n",
  96. ring->dequeue, trb, &dma);
  97. trb = &trbs[ring->enqueue];
  98. dma = cdns2_trb_virt_to_dma(pep, trb);
  99. ret += scnprintf(str + ret, size - ret,
  100. "\t\tRing enq index: %d, trb: V=%p, P=0x%pad\n",
  101. ring->enqueue, trb, &dma);
  102. ret += scnprintf(str + ret, size - ret,
  103. "\t\tfree trbs: %d, CCS=%d, PCS=%d\n",
  104. ring->free_trbs, ring->ccs, ring->pcs);
  105. if (TRBS_PER_SEGMENT > 40) {
  106. ret += scnprintf(str + ret, size - ret,
  107. "\t\tTransfer ring %d too big\n", TRBS_PER_SEGMENT);
  108. return str;
  109. }
  110. dma = ring->dma;
  111. for (i = 0; i < TRBS_PER_SEGMENT; ++i) {
  112. trb = &trbs[i];
  113. ret += scnprintf(str + ret, size - ret,
  114. "\t\t@%pad %08x %08x %08x\n", &dma,
  115. le32_to_cpu(trb->buffer),
  116. le32_to_cpu(trb->length),
  117. le32_to_cpu(trb->control));
  118. dma += sizeof(*trb);
  119. }
  120. if (ret == size - 1)
  121. pr_info("CDNS2: buffer may be truncated.\n");
  122. return str;
  123. }
  124. static inline const char *cdns2_trb_type_string(u8 type)
  125. {
  126. switch (type) {
  127. case TRB_NORMAL:
  128. return "Normal";
  129. case TRB_LINK:
  130. return "Link";
  131. default:
  132. return "UNKNOWN";
  133. }
  134. }
  135. static inline const char *cdns2_decode_trb(char *str, size_t size, u32 flags,
  136. u32 length, u32 buffer)
  137. {
  138. int type = TRB_FIELD_TO_TYPE(flags);
  139. int ret;
  140. switch (type) {
  141. case TRB_LINK:
  142. ret = scnprintf(str, size,
  143. "LINK %08x type '%s' flags %c:%c:%c%c:%c",
  144. buffer, cdns2_trb_type_string(type),
  145. flags & TRB_CYCLE ? 'C' : 'c',
  146. flags & TRB_TOGGLE ? 'T' : 't',
  147. flags & TRB_CHAIN ? 'C' : 'c',
  148. flags & TRB_CHAIN ? 'H' : 'h',
  149. flags & TRB_IOC ? 'I' : 'i');
  150. break;
  151. case TRB_NORMAL:
  152. ret = scnprintf(str, size,
  153. "type: '%s', Buffer: %08x, length: %ld, burst len: %ld, "
  154. "flags %c:%c:%c%c:%c",
  155. cdns2_trb_type_string(type),
  156. buffer, TRB_LEN(length),
  157. TRB_FIELD_TO_BURST(length),
  158. flags & TRB_CYCLE ? 'C' : 'c',
  159. flags & TRB_ISP ? 'I' : 'i',
  160. flags & TRB_CHAIN ? 'C' : 'c',
  161. flags & TRB_CHAIN ? 'H' : 'h',
  162. flags & TRB_IOC ? 'I' : 'i');
  163. break;
  164. default:
  165. ret = scnprintf(str, size, "type '%s' -> raw %08x %08x %08x",
  166. cdns2_trb_type_string(type),
  167. buffer, length, flags);
  168. }
  169. if (ret == size - 1)
  170. pr_info("CDNS2: buffer may be truncated.\n");
  171. return str;
  172. }
  173. #endif /*__LINUX_CDNS2_DEBUG*/