1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Cadence USBSS DRD Driver. 4 * Debug header file. 5 * 6 * Copyright (C) 2018-2019 Cadence. 7 * 8 * Author: Pawel Laszczak <pawell@cadence.com> 9 */ 10 #ifndef __LINUX_CDNS3_DEBUG 11 #define __LINUX_CDNS3_DEBUG 12 13 #include "core.h" 14 15 static inline char *cdns3_decode_usb_irq(char *str, 16 enum usb_device_speed speed, 17 u32 usb_ists) 18 { 19 int ret; 20 21 ret = sprintf(str, "IRQ %08x = ", usb_ists); 22 23 if (usb_ists & (USB_ISTS_CON2I | USB_ISTS_CONI)) { 24 ret += sprintf(str + ret, "Connection %s\n", 25 usb_speed_string(speed)); 26 } 27 if (usb_ists & USB_ISTS_DIS2I || usb_ists & USB_ISTS_DISI) 28 ret += sprintf(str + ret, "Disconnection "); 29 if (usb_ists & USB_ISTS_L2ENTI) 30 ret += sprintf(str + ret, "suspended "); 31 if (usb_ists & USB_ISTS_L1ENTI) 32 ret += sprintf(str + ret, "L1 enter "); 33 if (usb_ists & USB_ISTS_L1EXTI) 34 ret += sprintf(str + ret, "L1 exit "); 35 if (usb_ists & USB_ISTS_L2ENTI) 36 ret += sprintf(str + ret, "L2 enter "); 37 if (usb_ists & USB_ISTS_L2EXTI) 38 ret += sprintf(str + ret, "L2 exit "); 39 if (usb_ists & USB_ISTS_U3EXTI) 40 ret += sprintf(str + ret, "U3 exit "); 41 if (usb_ists & USB_ISTS_UWRESI) 42 ret += sprintf(str + ret, "Warm Reset "); 43 if (usb_ists & USB_ISTS_UHRESI) 44 ret += sprintf(str + ret, "Hot Reset "); 45 if (usb_ists & USB_ISTS_U2RESI) 46 ret += sprintf(str + ret, "Reset"); 47 48 return str; 49 } 50 51 static inline char *cdns3_decode_ep_irq(char *str, 52 u32 ep_sts, 53 const char *ep_name) 54 { 55 int ret; 56 57 ret = sprintf(str, "IRQ for %s: %08x ", ep_name, ep_sts); 58 59 if (ep_sts & EP_STS_SETUP) 60 ret += sprintf(str + ret, "SETUP "); 61 if (ep_sts & EP_STS_IOC) 62 ret += sprintf(str + ret, "IOC "); 63 if (ep_sts & EP_STS_ISP) 64 ret += sprintf(str + ret, "ISP "); 65 if (ep_sts & EP_STS_DESCMIS) 66 ret += sprintf(str + ret, "DESCMIS "); 67 if (ep_sts & EP_STS_STREAMR) 68 ret += sprintf(str + ret, "STREAMR "); 69 if (ep_sts & EP_STS_MD_EXIT) 70 ret += sprintf(str + ret, "MD_EXIT "); 71 if (ep_sts & EP_STS_TRBERR) 72 ret += sprintf(str + ret, "TRBERR "); 73 if (ep_sts & EP_STS_NRDY) 74 ret += sprintf(str + ret, "NRDY "); 75 if (ep_sts & EP_STS_PRIME) 76 ret += sprintf(str + ret, "PRIME "); 77 if (ep_sts & EP_STS_SIDERR) 78 ret += sprintf(str + ret, "SIDERRT "); 79 if (ep_sts & EP_STS_OUTSMM) 80 ret += sprintf(str + ret, "OUTSMM "); 81 if (ep_sts & EP_STS_ISOERR) 82 ret += sprintf(str + ret, "ISOERR "); 83 if (ep_sts & EP_STS_IOT) 84 ret += sprintf(str + ret, "IOT "); 85 86 return str; 87 } 88 89 static inline char *cdns3_decode_epx_irq(char *str, 90 char *ep_name, 91 u32 ep_sts) 92 { 93 return cdns3_decode_ep_irq(str, ep_sts, ep_name); 94 } 95 96 static inline char *cdns3_decode_ep0_irq(char *str, 97 int dir, 98 u32 ep_sts) 99 { 100 return cdns3_decode_ep_irq(str, ep_sts, 101 dir ? "ep0IN" : "ep0OUT"); 102 } 103 104 /** 105 * Debug a transfer ring. 106 * 107 * Prints out all TRBs in the endpoint ring, even those after the Link TRB. 108 *. 109 */ 110 static inline char *cdns3_dbg_ring(struct cdns3_endpoint *priv_ep, 111 struct cdns3_trb *ring, char *str) 112 { 113 dma_addr_t addr = priv_ep->trb_pool_dma; 114 struct cdns3_trb *trb; 115 int trb_per_sector; 116 int ret = 0; 117 int i; 118 119 trb_per_sector = GET_TRBS_PER_SEGMENT(priv_ep->type); 120 121 trb = &priv_ep->trb_pool[priv_ep->dequeue]; 122 ret += sprintf(str + ret, "\n\t\tRing contents for %s:", priv_ep->name); 123 124 ret += sprintf(str + ret, 125 "\n\t\tRing deq index: %d, trb: %p (virt), 0x%llx (dma)\n", 126 priv_ep->dequeue, trb, 127 (unsigned long long)cdns3_trb_virt_to_dma(priv_ep, trb)); 128 129 trb = &priv_ep->trb_pool[priv_ep->enqueue]; 130 ret += sprintf(str + ret, 131 "\t\tRing enq index: %d, trb: %p (virt), 0x%llx (dma)\n", 132 priv_ep->enqueue, trb, 133 (unsigned long long)cdns3_trb_virt_to_dma(priv_ep, trb)); 134 135 ret += sprintf(str + ret, 136 "\t\tfree trbs: %d, CCS=%d, PCS=%d\n", 137 priv_ep->free_trbs, priv_ep->ccs, priv_ep->pcs); 138 139 if (trb_per_sector > TRBS_PER_SEGMENT) 140 trb_per_sector = TRBS_PER_SEGMENT; 141 142 if (trb_per_sector > TRBS_PER_SEGMENT) { 143 sprintf(str + ret, "\t\tTransfer ring %d too big\n", 144 trb_per_sector); 145 return str; 146 } 147 148 for (i = 0; i < trb_per_sector; ++i) { 149 trb = &ring[i]; 150 ret += sprintf(str + ret, 151 "\t\t@%pad %08x %08x %08x\n", &addr, 152 le32_to_cpu(trb->buffer), 153 le32_to_cpu(trb->length), 154 le32_to_cpu(trb->control)); 155 addr += sizeof(*trb); 156 } 157 158 return str; 159 } 160 161 #endif /*__LINUX_CDNS3_DEBUG*/ 162