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