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