162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Cadence USBHS-DEV Driver. 462306a36Sopenharmony_ci * Debug header file. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2023 Cadence. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Author: Pawel Laszczak <pawell@cadence.com> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#ifndef __LINUX_CDNS2_DEBUG 1262306a36Sopenharmony_ci#define __LINUX_CDNS2_DEBUG 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistatic inline const char *cdns2_decode_usb_irq(char *str, size_t size, 1562306a36Sopenharmony_ci u8 usb_irq, u8 ext_irq) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci int ret; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci ret = snprintf(str, size, "usbirq: 0x%02x - ", usb_irq); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci if (usb_irq & USBIRQ_SOF) 2262306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "SOF "); 2362306a36Sopenharmony_ci if (usb_irq & USBIRQ_SUTOK) 2462306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "SUTOK "); 2562306a36Sopenharmony_ci if (usb_irq & USBIRQ_SUDAV) 2662306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "SETUP "); 2762306a36Sopenharmony_ci if (usb_irq & USBIRQ_SUSPEND) 2862306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "Suspend "); 2962306a36Sopenharmony_ci if (usb_irq & USBIRQ_URESET) 3062306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "Reset "); 3162306a36Sopenharmony_ci if (usb_irq & USBIRQ_HSPEED) 3262306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "HS "); 3362306a36Sopenharmony_ci if (usb_irq & USBIRQ_LPM) 3462306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "LPM "); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, ", EXT: 0x%02x - ", ext_irq); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci if (ext_irq & EXTIRQ_WAKEUP) 3962306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "Wakeup "); 4062306a36Sopenharmony_ci if (ext_irq & EXTIRQ_VBUSFAULT_FALL) 4162306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "VBUS_FALL "); 4262306a36Sopenharmony_ci if (ext_irq & EXTIRQ_VBUSFAULT_RISE) 4362306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "VBUS_RISE "); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci if (ret >= size) 4662306a36Sopenharmony_ci pr_info("CDNS2: buffer overflowed.\n"); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci return str; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic inline const char *cdns2_decode_dma_irq(char *str, size_t size, 5262306a36Sopenharmony_ci u32 ep_ists, u32 ep_sts, 5362306a36Sopenharmony_ci const char *ep_name) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci int ret; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci ret = snprintf(str, size, "ISTS: %08x, %s: %08x ", 5862306a36Sopenharmony_ci ep_ists, ep_name, ep_sts); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci if (ep_sts & DMA_EP_STS_IOC) 6162306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "IOC "); 6262306a36Sopenharmony_ci if (ep_sts & DMA_EP_STS_ISP) 6362306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "ISP "); 6462306a36Sopenharmony_ci if (ep_sts & DMA_EP_STS_DESCMIS) 6562306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "DESCMIS "); 6662306a36Sopenharmony_ci if (ep_sts & DMA_EP_STS_TRBERR) 6762306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "TRBERR "); 6862306a36Sopenharmony_ci if (ep_sts & DMA_EP_STS_OUTSMM) 6962306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "OUTSMM "); 7062306a36Sopenharmony_ci if (ep_sts & DMA_EP_STS_ISOERR) 7162306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "ISOERR "); 7262306a36Sopenharmony_ci if (ep_sts & DMA_EP_STS_DBUSY) 7362306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "DBUSY "); 7462306a36Sopenharmony_ci if (DMA_EP_STS_CCS(ep_sts)) 7562306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, "CCS "); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci if (ret >= size) 7862306a36Sopenharmony_ci pr_info("CDNS2: buffer overflowed.\n"); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci return str; 8162306a36Sopenharmony_ci} 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cistatic inline const char *cdns2_decode_epx_irq(char *str, size_t size, 8462306a36Sopenharmony_ci char *ep_name, u32 ep_ists, 8562306a36Sopenharmony_ci u32 ep_sts) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci return cdns2_decode_dma_irq(str, size, ep_ists, ep_sts, ep_name); 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic inline const char *cdns2_decode_ep0_irq(char *str, size_t size, 9162306a36Sopenharmony_ci u32 ep_ists, u32 ep_sts, 9262306a36Sopenharmony_ci int dir) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci return cdns2_decode_dma_irq(str, size, ep_ists, ep_sts, 9562306a36Sopenharmony_ci dir ? "ep0IN" : "ep0OUT"); 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic inline const char *cdns2_raw_ring(struct cdns2_endpoint *pep, 9962306a36Sopenharmony_ci struct cdns2_trb *trbs, 10062306a36Sopenharmony_ci char *str, size_t size) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci struct cdns2_ring *ring = &pep->ring; 10362306a36Sopenharmony_ci struct cdns2_trb *trb; 10462306a36Sopenharmony_ci dma_addr_t dma; 10562306a36Sopenharmony_ci int ret; 10662306a36Sopenharmony_ci int i; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci ret = snprintf(str, size, "\n\t\tTR for %s:", pep->name); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci trb = &trbs[ring->dequeue]; 11162306a36Sopenharmony_ci dma = cdns2_trb_virt_to_dma(pep, trb); 11262306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, 11362306a36Sopenharmony_ci "\n\t\tRing deq index: %d, trb: V=%p, P=0x%pad\n", 11462306a36Sopenharmony_ci ring->dequeue, trb, &dma); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci trb = &trbs[ring->enqueue]; 11762306a36Sopenharmony_ci dma = cdns2_trb_virt_to_dma(pep, trb); 11862306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, 11962306a36Sopenharmony_ci "\t\tRing enq index: %d, trb: V=%p, P=0x%pad\n", 12062306a36Sopenharmony_ci ring->enqueue, trb, &dma); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, 12362306a36Sopenharmony_ci "\t\tfree trbs: %d, CCS=%d, PCS=%d\n", 12462306a36Sopenharmony_ci ring->free_trbs, ring->ccs, ring->pcs); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci if (TRBS_PER_SEGMENT > 40) { 12762306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, 12862306a36Sopenharmony_ci "\t\tTransfer ring %d too big\n", TRBS_PER_SEGMENT); 12962306a36Sopenharmony_ci return str; 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci dma = ring->dma; 13362306a36Sopenharmony_ci for (i = 0; i < TRBS_PER_SEGMENT; ++i) { 13462306a36Sopenharmony_ci trb = &trbs[i]; 13562306a36Sopenharmony_ci ret += snprintf(str + ret, size - ret, 13662306a36Sopenharmony_ci "\t\t@%pad %08x %08x %08x\n", &dma, 13762306a36Sopenharmony_ci le32_to_cpu(trb->buffer), 13862306a36Sopenharmony_ci le32_to_cpu(trb->length), 13962306a36Sopenharmony_ci le32_to_cpu(trb->control)); 14062306a36Sopenharmony_ci dma += sizeof(*trb); 14162306a36Sopenharmony_ci } 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci if (ret >= size) 14462306a36Sopenharmony_ci pr_info("CDNS2: buffer overflowed.\n"); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci return str; 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic inline const char *cdns2_trb_type_string(u8 type) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci switch (type) { 15262306a36Sopenharmony_ci case TRB_NORMAL: 15362306a36Sopenharmony_ci return "Normal"; 15462306a36Sopenharmony_ci case TRB_LINK: 15562306a36Sopenharmony_ci return "Link"; 15662306a36Sopenharmony_ci default: 15762306a36Sopenharmony_ci return "UNKNOWN"; 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic inline const char *cdns2_decode_trb(char *str, size_t size, u32 flags, 16262306a36Sopenharmony_ci u32 length, u32 buffer) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci int type = TRB_FIELD_TO_TYPE(flags); 16562306a36Sopenharmony_ci int ret; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci switch (type) { 16862306a36Sopenharmony_ci case TRB_LINK: 16962306a36Sopenharmony_ci ret = snprintf(str, size, 17062306a36Sopenharmony_ci "LINK %08x type '%s' flags %c:%c:%c%c:%c", 17162306a36Sopenharmony_ci buffer, cdns2_trb_type_string(type), 17262306a36Sopenharmony_ci flags & TRB_CYCLE ? 'C' : 'c', 17362306a36Sopenharmony_ci flags & TRB_TOGGLE ? 'T' : 't', 17462306a36Sopenharmony_ci flags & TRB_CHAIN ? 'C' : 'c', 17562306a36Sopenharmony_ci flags & TRB_CHAIN ? 'H' : 'h', 17662306a36Sopenharmony_ci flags & TRB_IOC ? 'I' : 'i'); 17762306a36Sopenharmony_ci break; 17862306a36Sopenharmony_ci case TRB_NORMAL: 17962306a36Sopenharmony_ci ret = snprintf(str, size, 18062306a36Sopenharmony_ci "type: '%s', Buffer: %08x, length: %ld, burst len: %ld, " 18162306a36Sopenharmony_ci "flags %c:%c:%c%c:%c", 18262306a36Sopenharmony_ci cdns2_trb_type_string(type), 18362306a36Sopenharmony_ci buffer, TRB_LEN(length), 18462306a36Sopenharmony_ci TRB_FIELD_TO_BURST(length), 18562306a36Sopenharmony_ci flags & TRB_CYCLE ? 'C' : 'c', 18662306a36Sopenharmony_ci flags & TRB_ISP ? 'I' : 'i', 18762306a36Sopenharmony_ci flags & TRB_CHAIN ? 'C' : 'c', 18862306a36Sopenharmony_ci flags & TRB_CHAIN ? 'H' : 'h', 18962306a36Sopenharmony_ci flags & TRB_IOC ? 'I' : 'i'); 19062306a36Sopenharmony_ci break; 19162306a36Sopenharmony_ci default: 19262306a36Sopenharmony_ci ret = snprintf(str, size, "type '%s' -> raw %08x %08x %08x", 19362306a36Sopenharmony_ci cdns2_trb_type_string(type), 19462306a36Sopenharmony_ci buffer, length, flags); 19562306a36Sopenharmony_ci } 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci if (ret >= size) 19862306a36Sopenharmony_ci pr_info("CDNS2: buffer overflowed.\n"); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci return str; 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#endif /*__LINUX_CDNS2_DEBUG*/ 204