A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009-2014 by Michael Sparmann
11 * Copyright © 2010 Amaury Pouly
12 * Copyright (C) 2014 by Marcin Bukat
13 * Copyright (C) 2016 by Cástor Muñoz
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24#include <inttypes.h>
25#include <string.h>
26
27#include "config.h"
28#include "cpu.h"
29#include "system.h"
30#include "kernel.h"
31#include "panic.h"
32#include "power.h"
33#include "usb.h"
34#include "usb_drv.h"
35#include "usb_ch9.h"
36#include "usb_core.h"
37
38#include "usb-designware.h"
39
40/* Define LOGF_ENABLE to enable logf output in this file */
41/*#define LOGF_ENABLE*/
42#include "logf.h"
43
44
45/* The ARM940T uses a subset of the ARMv4 functions, not
46 * supporting clean/invalidate cache entries using MVA.
47 */
48#if CONFIG_CPU == S5L8701
49#define DISCARD_DCACHE_RANGE(b,s) commit_discard_dcache()
50#define COMMIT_DCACHE_RANGE(b,s) commit_dcache()
51#else
52#define DISCARD_DCACHE_RANGE(b,s) discard_dcache_range(b,s)
53#define COMMIT_DCACHE_RANGE(b,s) commit_dcache_range(b,s)
54#endif
55
56/* USB_DW_PHYSADDR(x) converts the address of buffer x to one usable with DMA.
57 * For example, converting a virtual address to a physical address.
58 *
59 * USB_DW_UNCACHEDADDR(x) is used to get an uncached pointer to a buffer.
60 * If the platform doesn't support this, define NO_UNCACHED_ADDR instead.
61 *
62 * Define POST_DMA_FLUSH if the driver should discard DMA RX buffers after a
63 * transfer completes. Needed if the CPU can speculatively fetch cache lines
64 * in any way, eg. due to speculative execution / prefetching.
65 */
66#if CONFIG_CPU == X1000
67# define USB_DW_PHYSADDR(x) PHYSADDR(x)
68# define USB_DW_UNCACHEDADDR(x) ((typeof(x))UNCACHEDADDR(x))
69# define POST_DMA_FLUSH
70#elif CONFIG_CPU == AS3525v2
71# define USB_DW_PHYSADDR(x) AS3525_PHYSICAL_ADDR(x)
72# define USB_DW_UNCACHEDADDR(x) AS3525_UNCACHED_ADDR(x)
73#elif CONFIG_CPU == S5L8701
74# define USB_DW_PHYSADDR(x) x
75# define NO_UNCACHED_ADDR /* Not known how to form uncached addresses */
76#elif CONFIG_CPU == S5L8702 || CONFIG_CPU == S5L8720
77# define USB_DW_PHYSADDR(x) S5L8702_PHYSICAL_ADDR(x)
78# define USB_DW_UNCACHEDADDR(x) S5L8702_UNCACHED_ADDR(x)
79#elif CONFIG_CPU == STM32H743
80# define USB_DW_PHYSADDR(x) x
81# define NO_UNCACHED_ADDR /* TODO: maybe implement this */
82#elif !defined(USB_DW_ARCH_SLAVE)
83# error "Must define USB_DW_PHYSADDR / USB_DW_UNCACHEDADDR!"
84#endif
85
86#ifndef USB_DW_TOUTCAL
87#define USB_DW_TOUTCAL 0
88#endif
89
90#define GET_DTXFNUM(ep) ((DWC_DIEPCTL(ep)>>22) & 0xf)
91
92#define USB_DW_NUM_DIRS 2
93#define USB_DW_DIR_OFF(dir) (((dir) == USB_DW_EPDIR_IN) ? 0 : 16)
94
95enum usb_dw_epdir
96{
97 USB_DW_EPDIR_IN = 0,
98 USB_DW_EPDIR_OUT = 1,
99};
100
101enum usb_dw_ep0_state
102{
103 /* Waiting for a setup packet to arrive. This is the default state. */
104 EP0_SETUP,
105
106 /* Request wait states -- after submitting a request, we enter EP0_REQ
107 * (or EP0_REQ_CTRLWRITE for control writes). EP0_REQ is also used for
108 * the 2nd phase of a control write. EP0_REQ_CANCELLED is entered if we
109 * receive a setup packet before getting a response from the USB stack. */
110 EP0_REQ,
111 EP0_REQ_CTRLWRITE,
112 EP0_REQ_CANCELLED,
113
114 /* Waiting for a data phase to complete. */
115 EP0_DATA_IN,
116 EP0_DATA_OUT,
117
118 /* Waiting for the status phase */
119 EP0_STATUS_IN,
120 EP0_STATUS_OUT,
121
122 EP0_NUM_STATES
123};
124
125/* Internal EP state/info */
126struct usb_dw_ep
127{
128 struct semaphore complete;
129 void* req_addr;
130 uint32_t req_size;
131 uint32_t* addr;
132 uint32_t sizeleft;
133 uint32_t size;
134 int8_t status;
135 uint8_t active;
136 uint8_t busy;
137};
138
139/* Additional state for EP0 */
140struct usb_dw_ep0
141{
142 enum usb_dw_ep0_state state;
143 struct usb_ctrlrequest active_req;
144 struct usb_ctrlrequest pending_req;
145};
146
147static const char* const dw_dir_str[USB_DW_NUM_DIRS] =
148{
149 [USB_DW_EPDIR_IN] = "IN",
150 [USB_DW_EPDIR_OUT] = "OUT",
151};
152
153static const char* const dw_state_str[EP0_NUM_STATES] =
154{
155 [EP0_SETUP] = "setup",
156 [EP0_REQ] = "req",
157 [EP0_REQ_CTRLWRITE] = "req_cw",
158 [EP0_DATA_IN] = "dat_in",
159 [EP0_DATA_OUT] = "dat_out",
160 [EP0_STATUS_IN] = "sts_in",
161 [EP0_STATUS_OUT] = "sts_out",
162};
163
164#if 0
165static const char* const dw_resp_str[3] =
166{
167 [USB_CONTROL_ACK] = "ACK",
168 [USB_CONTROL_RECEIVE] = "RECV",
169 [USB_CONTROL_STALL] = "STALL",
170};
171#endif
172
173static struct usb_dw_ep usb_dw_ep_list[USB_NUM_ENDPOINTS][USB_DW_NUM_DIRS];
174static struct usb_dw_ep0 ep0;
175uint8_t _ep0_buffer[64] USB_DEVBSS_ATTR __attribute__((aligned(32)));
176uint8_t* ep0_buffer; /* Uncached, unless NO_UNCACHED_ADDR is defined */
177
178static uint32_t usb_endpoints; /* available EPs mask */
179
180/* For SHARED_FIFO mode this is the number of periodic Tx FIFOs
181 (usually 1), otherwise it is the number of dedicated Tx FIFOs
182 (not counting NPTX FIFO that is always dedicated for IN0). */
183static int n_ptxfifos;
184static uint16_t ptxfifo_usage;
185
186static uint32_t hw_maxbytes;
187static uint32_t hw_maxpackets;
188#ifdef USB_DW_SHARED_FIFO
189static uint8_t hw_nptxqdepth;
190static uint32_t epmis_msk;
191static uint32_t ep_periodic_msk;
192#endif
193
194static struct usb_dw_ep *usb_dw_get_ep(int epnum, enum usb_dw_epdir epdir)
195{
196 return &usb_dw_ep_list[epnum][epdir];
197}
198
199static uint32_t usb_dw_maxpktsize(int epnum, enum usb_dw_epdir epdir)
200{
201 return epnum ? DWC_EPCTL(epnum, epdir) & 0x3ff : 64;
202}
203
204static uint32_t usb_dw_maxxfersize(int epnum, enum usb_dw_epdir epdir)
205{
206 /* EP0 can only transfer one packet at a time. */
207 if(epnum == 0)
208 return 64;
209
210 uint32_t maxpktsize = usb_dw_maxpktsize(epnum, epdir);
211 return CACHEALIGN_DOWN(MIN(hw_maxbytes, hw_maxpackets * maxpktsize));
212}
213
214/* Calculate number of packets (if size == 0 an empty packet will be sent) */
215static uint32_t usb_dw_calc_packets(uint32_t size, uint32_t maxpktsize)
216{
217 return MAX(1, (size + maxpktsize - 1) / maxpktsize);
218}
219
220static int usb_dw_get_stall(int epnum, enum usb_dw_epdir epdir)
221{
222 return !!(DWC_EPCTL(epnum, epdir) & STALL);
223}
224
225static void usb_dw_set_stall(int epnum, enum usb_dw_epdir epdir, int stall)
226{
227 if (stall)
228 {
229 DWC_EPCTL(epnum, epdir) |= STALL;
230 }
231 else
232 {
233 DWC_EPCTL(epnum, epdir) &= ~STALL;
234 DWC_EPCTL(epnum, epdir) |= SETD0PIDEF;
235 }
236}
237
238static void usb_dw_set_address(uint8_t address)
239{
240 DWC_DCFG = (DWC_DCFG & ~(0x7f0)) | DAD(address);
241}
242
243static void usb_dw_wait_for_ahb_idle(void)
244{
245 while (!(DWC_GRSTCTL & AHBIDL));
246}
247
248#ifdef USB_DW_SHARED_FIFO
249static unsigned usb_dw_bytes_in_txfifo(int epnum, uint32_t *sentbytes)
250{
251 uint32_t size = usb_dw_get_ep(epnum, USB_DW_EPDIR_IN)->size;
252 if (sentbytes) *sentbytes = size;
253 uint32_t dieptsiz = DWC_DIEPTSIZ(epnum);
254 uint32_t packetsleft = (dieptsiz >> 19) & 0x3ff;
255 if (!packetsleft) return 0;
256 uint32_t maxpktsize = usb_dw_maxpktsize(epnum, USB_DW_EPDIR_IN);
257 uint32_t packets = usb_dw_calc_packets(size, maxpktsize);
258 uint32_t bytesleft = dieptsiz & 0x7ffff;
259 uint32_t bytespushed = size - bytesleft;
260 uint32_t bytespulled = (packets - packetsleft) * maxpktsize;
261
262 if (sentbytes) *sentbytes = bytespulled;
263 return bytespushed - bytespulled;
264}
265#endif
266
267#ifdef USB_DW_ARCH_SLAVE
268/* Read one packet/token from Rx FIFO */
269static void usb_dw_handle_rxfifo(void)
270{
271 uint32_t rxsts = DWC_GRXSTSP;
272 uint32_t pktsts = (rxsts >> 17) & 0xf;
273
274 switch (pktsts)
275 {
276 case PKTSTS_OUTRX:
277 case PKTSTS_SETUPRX:
278 {
279 int ep = rxsts & 0xf;
280 uint32_t words = (((rxsts >> 4) & 0x7ff) + 3) >> 2;
281
282 /* Annoyingly, we need to special-case EP0. */
283 if(ep == 0)
284 {
285 uint32_t* addr = (uint32_t*)ep0_buffer;
286 while (words--)
287 *addr++ = DWC_DFIFO(0);
288 }
289 else
290 {
291 struct usb_dw_ep* dw_ep = usb_dw_get_ep(ep, USB_DW_EPDIR_OUT);
292 if (dw_ep->busy)
293 {
294 while (words--)
295 *dw_ep->addr++ = DWC_DFIFO(0);
296 }
297 else
298 {
299 /* Discard data */
300 while (words--)
301 (void) DWC_DFIFO(0);
302 }
303 }
304
305 break;
306 }
307 case PKTSTS_OUTDONE:
308 case PKTSTS_SETUPDONE:
309 case PKTSTS_GLOBALOUTNAK:
310 default:
311 break;
312 }
313}
314
315#ifdef USB_DW_SHARED_FIFO
316static void usb_dw_try_push(int epnum)
317{
318 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, USB_DW_EPDIR_IN);
319
320 if (!dw_ep->busy)
321 return;
322
323 if (epmis_msk & (1 << epnum))
324 return;
325
326 uint32_t wordsleft = ((DWC_DIEPTSIZ(epnum) & 0x7ffff) + 3) >> 2;
327 if (!wordsleft) return;
328
329 /* Get fifo space for NPTXFIFO or PTXFIFO */
330 uint32_t fifospace;
331 int dtxfnum = GET_DTXFNUM(epnum);
332 if (dtxfnum)
333 {
334 uint32_t fifosize = DWC_DIEPTXF(dtxfnum - 1) >> 16;
335 fifospace = fifosize - ((usb_dw_bytes_in_txfifo(epnum, NULL) + 3) >> 2);
336 }
337 else
338 {
339 uint32_t gnptxsts = DWC_GNPTXSTS;
340 fifospace = ((gnptxsts >> 16) & 0xff) ? (gnptxsts & 0xffff) : 0;
341 }
342
343 uint32_t maxpktsize = usb_dw_maxpktsize(epnum, USB_DW_EPDIR_IN);
344 uint32_t words = MIN((maxpktsize + 3) >> 2, wordsleft);
345
346 if (fifospace >= words)
347 {
348 wordsleft -= words;
349 while (words--)
350 DWC_DFIFO(epnum) = *dw_ep->addr++;
351 }
352
353 if (wordsleft)
354 DWC_GINTMSK |= (dtxfnum ? PTXFE : NPTXFE);
355}
356
357#else /* !USB_DW_SHARED_FIFO */
358static void usb_dw_handle_dtxfifo(int epnum)
359{
360 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, USB_DW_EPDIR_IN);
361
362 if (!dw_ep->busy)
363 return;
364
365 uint32_t wordsleft = ((DWC_DIEPTSIZ(epnum) & 0x7ffff) + 3) >> 2;
366
367 while (wordsleft)
368 {
369 uint32_t words = wordsleft;
370 uint32_t fifospace = DWC_DTXFSTS(epnum) & 0xffff;
371
372 if (fifospace < words)
373 {
374 /* We push whole packets to read consistent info on DIEPTSIZ
375 (i.e. when FIFO size is not maxpktsize multiplo). */
376 uint32_t maxpktwords = usb_dw_maxpktsize(epnum, USB_DW_EPDIR_IN) >> 2;
377 words = (fifospace / maxpktwords) * maxpktwords;
378 }
379
380 if (!words)
381 break;
382
383 wordsleft -= words;
384 while (words--)
385 DWC_DFIFO(epnum) = *dw_ep->addr++;
386 }
387
388 if (!wordsleft)
389 DWC_DIEPEMPMSK &= ~(1 << GET_DTXFNUM(epnum));
390}
391#endif /* !USB_DW_SHARED_FIFO */
392#endif /* USB_DW_ARCH_SLAVE */
393
394static void usb_dw_flush_fifo(uint32_t fflsh, int fnum)
395{
396#ifdef USB_DW_ARCH_SLAVE
397 /* Rx queue must be emptied before flushing Rx FIFO */
398 if (fflsh & RXFFLSH)
399 while (DWC_GINTSTS & RXFLVL)
400 usb_dw_handle_rxfifo();
401#else
402 /* Wait for any DMA activity to stop */
403 usb_dw_wait_for_ahb_idle();
404#endif
405 DWC_GRSTCTL = TXFNUM(fnum) | fflsh;
406 while (DWC_GRSTCTL & fflsh);
407 udelay(1); /* Wait 3 PHY cycles */
408}
409
410/* These are the conditions that must be met so that the application can
411 * disable an endpoint avoiding race conditions:
412 *
413 * 1) The endpoint must be enabled when EPDIS is written, otherwise the
414 * core will never raise EPDISD interrupt (thus EPDIS remains enabled).
415 *
416 * 2) - Periodic (SHARED_FIFO) or dedicated (!SHARED_FIFO) IN endpoints:
417 * IN NAK must be effective, to ensure that the core is not going
418 * to disable the EP just before EPDIS is written.
419 * - Non-periodic (SHARED_FIFO) IN endpoints: use usb_dw_nptx_unqueue().
420 * - OUT endpoints: GONAK must be effective, this also ensures that the
421 * core is not going to disable the EP.
422 */
423static void usb_dw_disable_ep(int epnum, enum usb_dw_epdir epdir)
424{
425 if (!epnum && (epdir == USB_DW_EPDIR_OUT))
426 return; /* The application cannot disable OUT0 */
427
428 if (DWC_EPCTL(epnum, epdir) & EPENA)
429 {
430 int tmo = 50;
431 DWC_EPCTL(epnum, epdir) |= EPDIS;
432 while (DWC_EPCTL(epnum, epdir) & EPDIS)
433 {
434 if (!tmo--)
435 panicf("%s: %s%d failed!", __func__, dw_dir_str[epdir], epnum);
436 udelay(1);
437 }
438 }
439}
440
441static void usb_dw_gonak_effective(bool enable)
442{
443 if (enable)
444 {
445 if (!(DWC_DCTL & GONSTS))
446 DWC_DCTL |= SGONAK;
447
448 /* Wait for global IN NAK effective */
449 int tmo = 50;
450 while (~DWC_GINTSTS & GOUTNAKEFF)
451 {
452 if (!tmo--) panicf("%s: failed!", __func__);
453#ifdef USB_DW_ARCH_SLAVE
454 /* Pull Rx queue until GLOBALOUTNAK token is received. */
455 if (DWC_GINTSTS & RXFLVL)
456 usb_dw_handle_rxfifo();
457 else
458#endif
459 udelay(1);
460 }
461 }
462 else
463 {
464 if (DWC_DCTL & GONSTS)
465 DWC_DCTL |= CGONAK;
466 }
467}
468
469static void usb_dw_set_innak_effective(int epnum)
470{
471 if (~DWC_DIEPCTL(epnum) & NAKSTS)
472 {
473 /* Wait for IN NAK effective avoiding race conditions, if the
474 * endpoint is disabled by the core (or it was already disabled)
475 * then INEPNE is never raised.
476 */
477 int tmo = 50;
478 DWC_DIEPCTL(epnum) |= SNAK;
479 while ((DWC_DIEPCTL(epnum) & EPENA) && !(DWC_DIEPINT(epnum) & INEPNE))
480 {
481 if (!tmo--) panicf("%s: IN%d failed!", __func__, epnum);
482 udelay(1);
483 }
484 }
485}
486
487#ifdef USB_DW_SHARED_FIFO
488static void usb_dw_ginak_effective(bool enable)
489{
490 if (enable)
491 {
492 if (!(DWC_DCTL & GINSTS))
493 DWC_DCTL |= SGINAK;
494
495 /* Wait for global IN NAK effective */
496 int tmo = 50;
497 while (~DWC_GINTSTS & GINAKEFF)
498 {
499 if (!tmo--) panicf("%s: failed!", __func__);
500 udelay(1);
501 }
502#ifndef USB_DW_ARCH_SLAVE
503 /* Wait for any DMA activity to stop. */
504 usb_dw_wait_for_ahb_idle();
505#endif
506 }
507 else
508 {
509 if (DWC_DCTL & GINSTS)
510 DWC_DCTL |= CGINAK;
511 }
512}
513
514static void usb_dw_nptx_unqueue(int epnum)
515{
516 uint32_t reenable_msk = 0;
517
518 usb_dw_ginak_effective(true);
519
520 /* Disable EPs */
521 for (int ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
522 {
523 if (usb_endpoints & ~ep_periodic_msk & (1 << ep))
524 {
525 /* Disable */
526 if (~DWC_DIEPCTL(ep) & EPENA)
527 continue;
528 DWC_DIEPCTL(ep) |= EPDIS|SNAK;
529
530 /* Adjust */
531 uint32_t packetsleft = (DWC_DIEPTSIZ(ep) >> 19) & 0x3ff;
532 if (!packetsleft) continue;
533
534 struct usb_dw_ep* dw_ep = usb_dw_get_ep(ep, USB_DW_EPDIR_IN);
535 uint32_t sentbytes;
536 uint32_t bytesinfifo = usb_dw_bytes_in_txfifo(ep, &sentbytes);
537
538#ifdef USB_DW_ARCH_SLAVE
539 dw_ep->addr -= (bytesinfifo + 3) >> 2;
540#else
541 (void) bytesinfifo;
542 DWC_DIEPDMA(ep) = USB_DW_PHYSADDR((uint32_t)(dw_ep->addr) + sentbytes);
543#endif
544 DWC_DIEPTSIZ(ep) = PKTCNT(packetsleft) | (dw_ep->size - sentbytes);
545
546 /* Do not re-enable the EP we are going to unqueue */
547 if (ep == epnum)
548 continue;
549
550 /* Mark EP to be re-enabled later */
551 reenable_msk |= (1 << ep);
552 }
553 }
554
555 /* Flush NPTXFIFO */
556 usb_dw_flush_fifo(TXFFLSH, 0);
557
558 /* Re-enable EPs */
559 for (int ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
560 if (reenable_msk & (1 << ep))
561 DWC_DIEPCTL(ep) |= EPENA|CNAK;
562
563#ifdef USB_DW_ARCH_SLAVE
564 if (reenable_msk)
565 DWC_GINTMSK |= NPTXFE;
566#endif
567
568 usb_dw_ginak_effective(false);
569}
570#endif /* USB_DW_SHARED_FIFO */
571
572static void usb_dw_flush_endpoint(int epnum, enum usb_dw_epdir epdir)
573{
574 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, epdir);
575 dw_ep->busy = false;
576 dw_ep->status = -1;
577 semaphore_release(&dw_ep->complete);
578
579 if (DWC_EPCTL(epnum, epdir) & EPENA)
580 {
581 if (epdir == USB_DW_EPDIR_IN)
582 {
583 /* We are shutting down an endpoint that might still have IN
584 * packets in the FIFO. Disable the endpoint, wait for things
585 * to settle, and flush the relevant FIFO.
586 */
587 int dtxfnum = GET_DTXFNUM(epnum);
588
589#ifdef USB_DW_SHARED_FIFO
590 if (!dtxfnum)
591 {
592 usb_dw_nptx_unqueue(epnum);
593 }
594 else
595#endif
596 {
597 /* Wait for IN NAK effective to avoid race conditions
598 while shutting down the endpoint. */
599 usb_dw_set_innak_effective(epnum);
600
601 /* Disable the EP we are going to flush */
602 usb_dw_disable_ep(epnum, epdir);
603
604 /* Flush it all the way down! */
605 usb_dw_flush_fifo(TXFFLSH, dtxfnum);
606
607#if !defined(USB_DW_SHARED_FIFO) && defined(USB_DW_ARCH_SLAVE)
608 DWC_DIEPEMPMSK &= ~(1 << dtxfnum);
609#endif
610 }
611 }
612 else
613 {
614 /* We are waiting for an OUT packet on this endpoint, which
615 * might arrive any moment. Assert a global output NAK to
616 * avoid race conditions while shutting down the endpoint.
617 * Global output NAK also flushes the Rx FIFO.
618 */
619 usb_dw_gonak_effective(true);
620 usb_dw_disable_ep(epnum, epdir);
621 usb_dw_gonak_effective(false);
622 }
623 }
624
625 /* At this point the endpoint is disabled, SNAK it (in case it is not
626 * already done), it is needed for Tx shared FIFOs (to not to raise
627 * unwanted EPMIS interrupts) and recomended for dedicated FIFOs.
628 */
629 DWC_EPCTL(epnum, epdir) |= SNAK;
630
631#ifdef USB_DW_SHARED_FIFO
632 if (epdir == USB_DW_EPDIR_IN)
633 {
634 epmis_msk &= ~(1 << epnum);
635 if (!epmis_msk)
636 DWC_DIEPMSK &= ~ITTXFE;
637 }
638#endif
639
640 /* Clear all channel interrupts to avoid to process
641 pending tokens for the flushed EP. */
642 DWC_EPINT(epnum, epdir) = DWC_EPINT(epnum, epdir);
643}
644
645static void usb_dw_unconfigure_ep(int epnum, enum usb_dw_epdir epdir)
646{
647 uint32_t epctl = 0;
648
649 if (epdir == USB_DW_EPDIR_IN)
650 {
651#ifdef USB_DW_SHARED_FIFO
652#ifndef USB_DW_ARCH_SLAVE
653 int next;
654 for (next = epnum + 1; next < USB_NUM_ENDPOINTS; next++)
655 if (usb_endpoints & (1 << next))
656 break;
657 epctl = NEXTEP(next % USB_NUM_ENDPOINTS);
658#endif
659 ep_periodic_msk &= ~(1 << epnum);
660#endif
661 ptxfifo_usage &= ~(1 << GET_DTXFNUM(epnum));
662 }
663
664 usb_dw_flush_endpoint(epnum, epdir);
665 DWC_EPCTL(epnum, epdir) = epctl;
666}
667
668static int usb_dw_configure_ep(int epnum,
669 enum usb_dw_epdir epdir, int type, int maxpktsize)
670{
671 uint32_t epctl = SETD0PIDEF|EPTYP(type)|USBAEP|maxpktsize;
672
673 if (epdir == USB_DW_EPDIR_IN)
674 {
675 /*
676 * If the hardware has dedicated fifos, we must give each
677 * IN EP a unique tx-fifo even if it is non-periodic.
678 */
679#ifdef USB_DW_SHARED_FIFO
680#ifndef USB_DW_ARCH_SLAVE
681 epctl |= DWC_DIEPCTL(epnum) & NEXTEP(0xf);
682#endif
683 if (type == USB_ENDPOINT_XFER_INT)
684#endif
685 {
686 int fnum;
687 for (fnum = 1; fnum <= n_ptxfifos; fnum++)
688 if (~ptxfifo_usage & (1 << fnum))
689 break;
690 if (fnum > n_ptxfifos)
691 return -1; /* no available fifos */
692 ptxfifo_usage |= (1 << fnum);
693 epctl |= DTXFNUM(fnum);
694#ifdef USB_DW_SHARED_FIFO
695 ep_periodic_msk |= (1 << epnum);
696#endif
697 }
698 }
699
700 DWC_EPCTL(epnum, epdir) = epctl;
701 return 0; /* ok */
702}
703
704static void usb_dw_reset_endpoints(void)
705{
706 /* Initial state for all endpoints, setting OUT EPs as not busy
707 * will discard all pending data (if any) on the flush stage.
708 */
709 for (int ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
710 {
711 for (int dir = 0; dir < USB_DW_NUM_DIRS; dir++)
712 {
713 struct usb_dw_ep* dw_ep = usb_dw_get_ep(ep, dir);
714 dw_ep->active = !ep;
715 dw_ep->busy = false;
716 dw_ep->status = -1;
717 semaphore_release(&dw_ep->complete);
718 }
719 }
720
721#if CONFIG_CPU == S5L8701
722 /*
723 * Workaround for spurious -EPROTO when receiving bulk data on Nano2G.
724 *
725 * The Rx FIFO and Rx queue are currupted by the received (corrupted)
726 * data, must be flushed, otherwise the core can not set GONAK effective.
727 */
728 usb_dw_flush_fifo(RXFFLSH, 0);
729#endif
730
731 /* Flush and initialize EPs, includes disabling USBAEP on all EPs
732 * except EP0 (USB HW core keeps EP0 active on all configurations).
733 */
734 for (int ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
735 {
736 if (usb_endpoints & (1 << (ep + 16)))
737 usb_dw_unconfigure_ep(ep, USB_DW_EPDIR_OUT);
738 if (usb_endpoints & (1 << ep))
739 usb_dw_unconfigure_ep(ep, USB_DW_EPDIR_IN);
740 }
741
742 ptxfifo_usage = 0;
743#ifdef USB_DW_SHARED_FIFO
744 ep_periodic_msk = 0;
745#endif
746}
747
748static void usb_dw_epstart(int epnum, enum usb_dw_epdir epdir,
749 void* buf, uint32_t size)
750{
751 if ((uint32_t)buf & ((epdir == USB_DW_EPDIR_IN) ? 3 : CACHEALIGN_SIZE-1))
752 logf("%s: %s%d %p unaligned", __func__, dw_dir_str[epdir], epnum, buf);
753
754 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, epdir);
755 uint32_t xfersize = MIN(size, usb_dw_maxxfersize(epnum, epdir));
756
757 dw_ep->addr = (uint32_t*)buf;
758 dw_ep->size = xfersize;
759 dw_ep->sizeleft = size;
760 dw_ep->status = -1;
761 dw_ep->busy = true;
762
763 if (epnum == 0 && epdir == USB_DW_EPDIR_OUT)
764 {
765 /* FIXME: there's an extremely rare race condition here.
766 *
767 * 1. Host sends a control write.
768 * 2. We process the request.
769 * 3. (time passes)
770 * 4. This function is called via USB_CONTROL_RECEIVE response.
771 * 5. Right before we set CNAK, host sends another control write.
772 *
773 * So we may unintentionally receive data from the second request.
774 * It's possible to detect this when we see a setup packet because
775 * EP0 OUT will be busy. In principle it should even be possible to
776 * handle the 2nd request correctly. Currently we don't attempt to
777 * detect or recover from this error.
778 */
779 DWC_DOEPCTL(0) |= CNAK;
780 return;
781 }
782
783 uint32_t maxpktsize = usb_dw_maxpktsize(epnum, epdir);
784 uint32_t packets = usb_dw_calc_packets(xfersize, maxpktsize);
785 uint32_t eptsiz = PKTCNT(packets) | xfersize;
786 uint32_t nak = CNAK;
787
788 if (epdir == USB_DW_EPDIR_IN)
789 {
790#ifndef USB_DW_ARCH_SLAVE
791 COMMIT_DCACHE_RANGE(buf, xfersize);
792#endif
793#ifdef USB_DW_SHARED_FIFO
794 eptsiz |= MCCNT((ep_periodic_msk >> epnum) & 1);
795#endif
796
797 }
798 else
799 {
800#ifndef USB_DW_ARCH_SLAVE
801 DISCARD_DCACHE_RANGE(buf, xfersize);
802#endif
803 }
804
805#ifndef USB_DW_ARCH_SLAVE
806 DWC_EPDMA(epnum, epdir) = USB_DW_PHYSADDR((uint32_t)buf);
807#endif
808 DWC_EPTSIZ(epnum, epdir) = eptsiz;
809 DWC_EPCTL(epnum, epdir) |= EPENA | nak;
810
811#ifdef USB_DW_ARCH_SLAVE
812 /* Enable interrupts to start pushing data into the FIFO */
813 if ((epdir == USB_DW_EPDIR_IN) && dw_ep->size > 0)
814#ifdef USB_DW_SHARED_FIFO
815 DWC_GINTMSK |= ((ep_periodic_msk & (1 << epnum)) ? PTXFE : NPTXFE);
816#else
817 DWC_DIEPEMPMSK |= (1 << GET_DTXFNUM(epnum));
818#endif
819#endif
820}
821
822static void usb_dw_transfer(int epnum, enum usb_dw_epdir epdir,
823 void* buf, uint32_t size)
824{
825 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, epdir);
826
827 if (!dw_ep->active)
828 logf("%s: %s%d inactive", __func__, dw_dir_str[epdir], epnum);
829 if (dw_ep->busy)
830 logf("%s: %s%d busy", __func__, dw_dir_str[epdir], epnum);
831
832 dw_ep->req_addr = buf;
833 dw_ep->req_size = size;
834 usb_dw_epstart(epnum, epdir, buf, size);
835}
836
837static void usb_dw_ep0_recv(void)
838{
839#ifndef USB_DW_ARCH_SLAVE
840#ifdef NO_UNCACHED_ADDR
841 DISCARD_DCACHE_RANGE(&_ep0_buffer[0], 64);
842#endif
843 DWC_DOEPDMA(0) = USB_DW_PHYSADDR((uint32_t)&_ep0_buffer[0]);
844#endif
845 DWC_DOEPTSIZ(0) = STUPCNT(1) | PKTCNT(1) | 64;
846 DWC_DOEPCTL(0) |= EPENA | SNAK;
847}
848
849static void usb_dw_abort_endpoint(int epnum, enum usb_dw_epdir epdir)
850{
851 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, epdir);
852 if (dw_ep->busy)
853 {
854 usb_dw_flush_endpoint(epnum, epdir);
855 usb_core_transfer_complete(epnum, (epdir == USB_DW_EPDIR_OUT) ?
856 USB_DIR_OUT : USB_DIR_IN, -1, 0);
857 }
858}
859
860static void usb_dw_control_received(struct usb_ctrlrequest* req)
861{
862 logf("%s(%p) state=%s", __func__, req, dw_state_str[ep0.state]);
863 logf(" bRequestType=%02x bRequest=%02x", req->bRequestType, req->bRequest);
864 logf(" wValue=%04x wIndex=%u wLength=%u", req->wValue, req->wIndex, req->wLength);
865
866 switch(ep0.state) {
867 case EP0_REQ:
868 case EP0_REQ_CTRLWRITE:
869 case EP0_REQ_CANCELLED:
870 /* Save the request for later */
871 memcpy(&ep0.pending_req, req, sizeof(*req));
872 ep0.state = EP0_REQ_CANCELLED;
873 break;
874
875 case EP0_DATA_IN:
876 case EP0_STATUS_IN:
877 case EP0_DATA_OUT:
878 case EP0_STATUS_OUT:
879 usb_core_control_complete(-1);
880 /* fallthrough */
881
882 case EP0_SETUP:
883 /* Save the request */
884 memcpy(&ep0.active_req, req, sizeof(*req));
885 req = &ep0.active_req;
886
887 /* Check for a SET ADDRESS request, which we must handle here */
888 if ((req->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE &&
889 (req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
890 (req->bRequest == USB_REQ_SET_ADDRESS))
891 usb_dw_set_address(req->wValue);
892
893 /* Check for control writes */
894 if (req->wLength > 0 && !(req->bRequestType & USB_DIR_IN))
895 ep0.state = EP0_REQ_CTRLWRITE;
896 else
897 ep0.state = EP0_REQ;
898
899 usb_dw_flush_endpoint(0, USB_DW_EPDIR_IN);
900 usb_core_control_request(req, NULL);
901 break;
902
903 default:
904 panicf("%s: bad state=%s", __func__, ep0.state >= EP0_NUM_STATES ? "unk" : dw_state_str[ep0.state]);
905 }
906}
907
908/* note: must be called with IRQs disabled */
909static void usb_dw_control_response(enum usb_control_response resp,
910 void* data, int length)
911{
912 struct usb_ctrlrequest* req = &ep0.active_req;
913
914 switch(ep0.state) {
915 case EP0_REQ:
916 case EP0_REQ_CTRLWRITE:
917 switch(resp) {
918 case USB_CONTROL_ACK:
919 if(req->wLength > 0 && (req->bRequestType & USB_DIR_IN))
920 ep0.state = EP0_DATA_IN; /* control read */
921 else
922 ep0.state = EP0_STATUS_IN; /* non-data or write */
923
924 usb_dw_transfer(0, USB_DW_EPDIR_IN, data, length);
925 break;
926
927 case USB_CONTROL_RECEIVE:
928 if(ep0.state != EP0_REQ_CTRLWRITE)
929 panicf("%s: bad response", __func__);
930
931 ep0.state = EP0_DATA_OUT;
932 usb_dw_transfer(0, USB_DW_EPDIR_OUT, data, length);
933 break;
934
935 case USB_CONTROL_STALL:
936 if(ep0.state == EP0_REQ_CTRLWRITE)
937 usb_dw_set_stall(0, USB_DW_EPDIR_OUT, 1);
938 else
939 usb_dw_set_stall(0, USB_DW_EPDIR_IN, 1);
940
941 ep0.state = EP0_SETUP;
942 break;
943 }
944 break;
945
946 case EP0_REQ_CANCELLED:
947 /* Terminate the old request */
948 usb_core_control_complete(-3);
949
950 /* Submit the pending request */
951 ep0.state = EP0_SETUP;
952 usb_dw_control_received(&ep0.pending_req);
953 break;
954
955 default:
956 panicf("%s: bad state=%s", __func__, dw_state_str[ep0.state]);
957 }
958}
959
960static void usb_dw_ep0_xfer_complete(enum usb_dw_epdir epdir,
961 int status, int transferred)
962{
963 struct usb_dw_ep* dw_ep = usb_dw_get_ep(0, epdir);
964
965 switch((ep0.state << 1) | epdir)
966 {
967 case (EP0_DATA_IN << 1) | USB_DW_EPDIR_IN:
968 ep0.state = EP0_STATUS_OUT;
969 usb_dw_transfer(0, USB_DW_EPDIR_OUT, NULL, 0);
970 break;
971
972 case (EP0_DATA_OUT << 1) | USB_DW_EPDIR_OUT:
973 ep0.state = EP0_REQ;
974 usb_core_control_request(&ep0.active_req, dw_ep->req_addr);
975 break;
976
977 case (EP0_STATUS_IN << 1) | USB_DW_EPDIR_IN:
978 case (EP0_STATUS_OUT << 1) | USB_DW_EPDIR_OUT:
979 if(status != 0 || transferred != 0)
980 usb_core_control_complete(-2);
981 else
982 usb_core_control_complete(0);
983
984 ep0.state = EP0_SETUP;
985 break;
986
987 default:
988 panicf("%s: state=%s dir=%s", __func__,
989 dw_state_str[ep0.state], dw_dir_str[epdir]);
990 }
991}
992
993static void usb_dw_handle_xfer_complete(int epnum, enum usb_dw_epdir epdir)
994{
995 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, epdir);
996 bool is_ep0out = (epnum == 0 && epdir == USB_DW_EPDIR_OUT);
997
998 if (!dw_ep->busy)
999 {
1000 if(is_ep0out)
1001 usb_dw_ep0_recv();
1002 return;
1003 }
1004
1005 uint32_t bytes_left = DWC_EPTSIZ(epnum, epdir) & 0x7ffff;
1006 uint32_t transferred = (is_ep0out ? 64 : dw_ep->size) - bytes_left;
1007
1008 if(transferred > dw_ep->sizeleft)
1009 {
1010 /* Host sent more data than expected.
1011 * Shouldn't happen for IN endpoints. */
1012 dw_ep->status = -2;
1013 goto complete;
1014 }
1015
1016 if(is_ep0out)
1017 {
1018#if defined(NO_UNCACHED_ADDR) && defined(POST_DMA_FLUSH)
1019 DISCARD_DCACHE_RANGE(ep0_buffer, 64);
1020#endif
1021 memcpy(dw_ep->addr, ep0_buffer, transferred);
1022 usb_dw_ep0_recv();
1023 }
1024
1025 dw_ep->sizeleft -= transferred;
1026
1027 /* Start a new transfer if there is still more to go */
1028 if(bytes_left == 0 && dw_ep->sizeleft > 0)
1029 {
1030#ifndef USB_DW_ARCH_SLAVE
1031 dw_ep->addr += (dw_ep->size >> 2); /* offset in words */
1032#endif
1033 usb_dw_epstart(epnum, epdir, dw_ep->addr, dw_ep->sizeleft);
1034 return;
1035 }
1036
1037 if(epdir == USB_DW_EPDIR_IN)
1038 {
1039 /* SNAK the disabled EP, otherwise IN tokens for this
1040 EP could raise unwanted EPMIS interrupts. Useful for
1041 usbserial when there is no data to send. */
1042 DWC_DIEPCTL(epnum) |= SNAK;
1043
1044#ifdef USB_DW_SHARED_FIFO
1045 /* See usb-s5l8701.c */
1046 if (usb_dw_config.use_ptxfifo_as_plain_buffer)
1047 {
1048 int dtxfnum = GET_DTXFNUM(epnum);
1049 if (dtxfnum)
1050 usb_dw_flush_fifo(TXFFLSH, dtxfnum);
1051 }
1052#endif
1053 }
1054 else
1055 {
1056#if !defined(USB_DW_ARCH_SLAVE) && defined(POST_DMA_FLUSH)
1057 /* On EP0 OUT we do not DMA into the request buffer,
1058 * so do not discard the cache in this case. */
1059 if(!is_ep0out)
1060 DISCARD_DCACHE_RANGE(dw_ep->req_addr, dw_ep->req_size);
1061#endif
1062 }
1063
1064 dw_ep->status = 0;
1065
1066 complete:
1067 dw_ep->busy = false;
1068 semaphore_release(&dw_ep->complete);
1069
1070 int total_bytes = dw_ep->req_size - dw_ep->sizeleft;
1071 if (epnum == 0)
1072 {
1073 usb_dw_ep0_xfer_complete(epdir, dw_ep->status, total_bytes);
1074 }
1075 else
1076 {
1077 usb_core_transfer_complete(epnum, (epdir == USB_DW_EPDIR_OUT) ?
1078 USB_DIR_OUT : USB_DIR_IN, dw_ep->status, total_bytes);
1079 }
1080}
1081
1082static void usb_dw_handle_setup_received(void)
1083{
1084#if defined(NO_UNCACHED_ADDR) && defined(POST_DMA_FLUSH)
1085 DISCARD_DCACHE_RANGE(ep0_buffer, 64);
1086#endif
1087 struct usb_ctrlrequest req;
1088 memcpy(&req, ep0_buffer, sizeof(struct usb_ctrlrequest));
1089
1090 usb_dw_ep0_recv();
1091
1092 usb_dw_control_received(&req);
1093}
1094
1095#ifdef USB_DW_SHARED_FIFO
1096static int usb_dw_get_epmis(void)
1097{
1098 unsigned epmis;
1099 uint32_t gnptxsts = DWC_GNPTXSTS;
1100
1101 if (((gnptxsts >> 16) & 0xff) >= hw_nptxqdepth)
1102 return -1; /* empty queue */
1103
1104 /* Get the EP on the top of the queue, 0 < idx < number of available
1105 IN endpoints */
1106 uint32_t idx = (gnptxsts >> 27) & 0xf;
1107 for (epmis = 0; epmis < USB_NUM_ENDPOINTS; epmis++)
1108 if ((usb_endpoints & (1 << epmis)) && !idx--)
1109 break;
1110
1111 /* The maximum EP mismatch counter is configured, so we verify all NPTX
1112 queue entries, 4 bits per entry, first entry at DTKQNR1[11:8] */
1113 uint32_t volatile *dtknqr = &DWC_DTKNQR1;
1114 for (int i = 2; i < hw_nptxqdepth + 2; i++)
1115 if (((*(dtknqr+(i>>3)) >> ((i & 0x7)*4)) & 0xf) == epmis)
1116 return -1;
1117
1118 return epmis;
1119}
1120
1121static void usb_dw_handle_token_mismatch(void)
1122{
1123 usb_dw_ginak_effective(true);
1124 int epmis = usb_dw_get_epmis();
1125 if (epmis >= 0)
1126 {
1127 /* The EP is disabled, unqueued, and reconfigured to re-reenable it
1128 later when a token is received, (or it will be cancelled by
1129 timeout if it was a blocking request). */
1130 usb_dw_nptx_unqueue(epmis);
1131
1132 epmis_msk |= (1 << epmis);
1133 if (epmis_msk)
1134 DWC_DIEPMSK |= ITTXFE;
1135
1136 /* Be sure the status is clear */
1137 DWC_DIEPINT(epmis) = ITTXFE;
1138
1139 /* Must disable NAK to allow to get ITTXFE interrupts for this EP */
1140 DWC_DIEPCTL(epmis) |= CNAK;
1141 }
1142 usb_dw_ginak_effective(false);
1143}
1144#endif /* USB_DW_SHARED_FIFO */
1145
1146static void usb_dw_irq(void)
1147{
1148 int ep;
1149 uint32_t daint;
1150
1151#ifdef USB_DW_ARCH_SLAVE
1152 /* Handle one packet at a time, the IRQ will re-trigger if there's
1153 something left. */
1154 if (DWC_GINTSTS & RXFLVL)
1155 {
1156 usb_dw_handle_rxfifo();
1157 }
1158#endif
1159
1160#ifdef USB_DW_SHARED_FIFO
1161 if (DWC_GINTSTS & EPMIS)
1162 {
1163 usb_dw_handle_token_mismatch();
1164 DWC_GINTSTS = EPMIS;
1165 }
1166
1167#ifdef USB_DW_ARCH_SLAVE
1168 uint32_t gintsts = DWC_GINTSTS & DWC_GINTMSK;
1169 if (gintsts & PTXFE)
1170 {
1171 /* First disable the IRQ, it will be re-enabled later if there
1172 is anything left to be done. */
1173 DWC_GINTMSK &= ~PTXFE;
1174 /* Check all periodic endpoints for anything to be transmitted */
1175 for (ep = 1; ep < USB_NUM_ENDPOINTS; ep++)
1176 if (usb_endpoints & ep_periodic_msk & (1 << ep))
1177 usb_dw_try_push(ep);
1178 }
1179
1180 if (gintsts & NPTXFE)
1181 {
1182 /* First disable the IRQ, it will be re-enabled later if there
1183 is anything left to be done. */
1184 DWC_GINTMSK &= ~NPTXFE;
1185 /* Check all non-periodic endpoints for anything to be transmitted */
1186 for (ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
1187 if (usb_endpoints & ~ep_periodic_msk & (1 << ep))
1188 usb_dw_try_push(ep);
1189 }
1190#endif /* USB_DW_ARCH_SLAVE */
1191#endif /* USB_DW_SHARED_FIFO */
1192
1193 daint = DWC_DAINT;
1194
1195 /* IN */
1196 for (ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
1197 {
1198 if (daint & (1 << ep))
1199 {
1200 uint32_t epints = DWC_DIEPINT(ep);
1201
1202 if (epints & TOC)
1203 {
1204 usb_dw_abort_endpoint(ep, USB_DW_EPDIR_IN);
1205 }
1206
1207#ifdef USB_DW_SHARED_FIFO
1208 if (epints & ITTXFE)
1209 {
1210 if (epmis_msk & (1 << ep))
1211 {
1212 DWC_DIEPCTL(ep) |= EPENA;
1213 epmis_msk &= ~(1 << ep);
1214 if (!epmis_msk)
1215 DWC_DIEPMSK &= ~ITTXFE;
1216 }
1217 }
1218
1219#elif defined(USB_DW_ARCH_SLAVE)
1220 if (epints & TXFE)
1221 {
1222 usb_dw_handle_dtxfifo(ep);
1223 }
1224#endif
1225
1226 /* Clear XFRC here, if this is a 'multi-transfer' request then
1227 a new transfer is going to be launched, this ensures it will
1228 not miss a single interrupt. */
1229 DWC_DIEPINT(ep) = epints;
1230
1231 if (epints & XFRC)
1232 {
1233 usb_dw_handle_xfer_complete(ep, USB_DW_EPDIR_IN);
1234 }
1235 }
1236 }
1237
1238 /* OUT */
1239 for (ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
1240 {
1241 if (daint & (1 << (ep + 16)))
1242 {
1243 uint32_t epints = DWC_DOEPINT(ep);
1244 DWC_DOEPINT(ep) = epints;
1245
1246 if (!ep)
1247 {
1248 if (epints & STUP)
1249 {
1250 usb_dw_handle_setup_received();
1251 }
1252
1253 if (epints & XFRC)
1254 {
1255 if(epints & STATUSRECVD)
1256 {
1257 /* At the end of a control write's data phase, the
1258 * controller writes a spurious OUTDONE token to the
1259 * FIFO and raises StatusRecvd | XferCompl.
1260 *
1261 * We do not need or want this -- we've already handled
1262 * the data phase by this point -- but EP0 is stopped
1263 * as a side effect of XferCompl, so we need to restart
1264 * it to keep receiving packets. */
1265 usb_dw_ep0_recv();
1266 }
1267 else if(!(epints & SETUPRECVD))
1268 {
1269 /* Only call this for normal data packets. Setup
1270 * packets use the STUP interrupt handler instead. */
1271 usb_dw_handle_xfer_complete(0, USB_DW_EPDIR_OUT);
1272 }
1273 }
1274 }
1275 else
1276 {
1277 if (epints & XFRC)
1278 {
1279 usb_dw_handle_xfer_complete(ep, USB_DW_EPDIR_OUT);
1280 }
1281 }
1282 }
1283 }
1284
1285 if (DWC_GINTSTS & USBRST)
1286 {
1287 DWC_GINTSTS = USBRST;
1288 usb_dw_set_address(0);
1289 usb_dw_reset_endpoints();
1290 usb_core_bus_reset();
1291 }
1292
1293 if (DWC_GINTSTS & ENUMDNE)
1294 {
1295 DWC_GINTSTS = ENUMDNE;
1296 ep0.state = EP0_SETUP;
1297 usb_dw_ep0_recv();
1298 }
1299}
1300
1301static void usb_dw_check_hw(void)
1302{
1303 uint32_t ghwcfg2 = DWC_GHWCFG2;
1304 uint32_t ghwcfg3 = DWC_GHWCFG3;
1305 uint32_t ghwcfg4 = DWC_GHWCFG4;
1306 const struct usb_dw_config *c = &usb_dw_config;
1307 int hw_numeps;
1308 int hw_maxtxfifos; /* periodic or dedicated */
1309 char *err;
1310
1311 hw_numeps = ((ghwcfg2 >> 10) & 0xf) + 1;
1312
1313 if (hw_numeps < USB_NUM_ENDPOINTS)
1314 {
1315 err = "USB_NUM_ENDPOINTS too big";
1316 goto panic;
1317 }
1318 /* HWCFG registers are not checked to detect the PHY, if an option
1319 is not supported then the related bits should be Read-Only. */
1320 DWC_GUSBCFG = c->phytype;
1321 if (DWC_GUSBCFG != c->phytype)
1322 {
1323 err = "PHY type not supported";
1324 goto panic;
1325 }
1326#ifndef USB_DW_ARCH_SLAVE
1327 if (((ghwcfg2 >> 3) & 3) != 2)
1328 {
1329 err = "internal DMA not supported";
1330 goto panic;
1331 }
1332#endif
1333#ifdef USB_DW_SHARED_FIFO
1334 if ((ghwcfg4 >> 25) & 1)
1335 {
1336 err = "shared TxFIFO not supported";
1337 goto panic;
1338 }
1339 hw_maxtxfifos = ghwcfg4 & 0xf;
1340 hw_nptxqdepth = (1 << (((ghwcfg2 >> 22) & 3) + 1));
1341#else
1342 if (!((ghwcfg4 >> 25) & 1))
1343 {
1344 err = "dedicated TxFIFO not supported";
1345 goto panic;
1346 }
1347 hw_maxtxfifos = (ghwcfg4 >> 26) & 0xf;
1348#endif
1349 hw_maxbytes = (1 << (((ghwcfg3 >> 0) & 0xf) + 11)) - 1;
1350 hw_maxpackets = (1 << (((ghwcfg3 >> 4) & 0x7) + 4)) - 1;
1351 uint16_t hw_fifomem = ghwcfg3 >> 16;
1352
1353 /* Configure FIFOs, sizes are 32-bit words, we will need at least
1354 one periodic or dedicated Tx FIFO (really the periodic Tx FIFO
1355 is not needed if !USB_ENABLE_HID). */
1356 if (c->rx_fifosz + c->nptx_fifosz + c->ptx_fifosz > hw_fifomem)
1357 {
1358 err = "insufficient FIFO memory";
1359 goto panic;
1360 }
1361 n_ptxfifos = (hw_fifomem - c->rx_fifosz - c->nptx_fifosz) / c->ptx_fifosz;
1362 if (n_ptxfifos > hw_maxtxfifos) n_ptxfifos = hw_maxtxfifos;
1363
1364 logf("%s():", __func__);
1365 logf(" HW version: %4lx, num EPs: %d", DWC_GSNPSID & 0xffff, hw_numeps);
1366 logf(" FIFO mem=%d rx=%d nptx=%d ptx=%dx%d", hw_fifomem,
1367 c->rx_fifosz, c->nptx_fifosz, n_ptxfifos, c->ptx_fifosz);
1368
1369 return;
1370
1371panic:
1372 panicf("%s: %s", __func__, err);
1373}
1374
1375static void usb_dw_init(void)
1376{
1377 static bool initialized = false;
1378 const struct usb_dw_config *c = &usb_dw_config;
1379
1380 if (!initialized)
1381 {
1382#if !defined(USB_DW_ARCH_SLAVE) && !defined(NO_UNCACHED_ADDR)
1383 ep0_buffer = USB_DW_UNCACHEDADDR(&_ep0_buffer[0]);
1384#else
1385 /* DMA is not used so we can operate on cached addresses */
1386 ep0_buffer = &_ep0_buffer[0];
1387#endif
1388
1389 for (int ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
1390 for (int dir = 0; dir < USB_DW_NUM_DIRS; dir++)
1391 semaphore_init(&usb_dw_get_ep(ep, dir)->complete, 1, 0);
1392
1393 initialized = true;
1394 }
1395
1396 /* Disable IRQ during setup */
1397 usb_dw_target_disable_irq();
1398
1399 /* Enable OTG clocks */
1400 usb_dw_target_enable_clocks();
1401
1402 /* Enable PHY clocks */
1403 DWC_PCGCCTL = 0;
1404
1405 usb_dw_check_hw();
1406
1407 /* Configure PHY type (must be done before reset) */
1408#ifndef USB_DW_TURNAROUND
1409 /*
1410 * Turnaround time (in PHY clocks) = 4*AHB clocks + 1*PHY clock,
1411 * worst cases are:
1412 * 16-bit UTMI+: PHY=30MHz, AHB=30Mhz -> 5
1413 * 8-bit UTMI+: PHY=60MHz, AHB=30MHz -> 9
1414 */
1415 int USB_DW_TURNAROUND = (c->phytype == DWC_PHYTYPE_UTMI_16) ? 5 : 9;
1416#endif
1417 uint32_t gusbcfg = c->phytype|TRDT(USB_DW_TURNAROUND)|USB_DW_TOUTCAL;
1418 DWC_GUSBCFG = gusbcfg;
1419
1420 /* Reset the whole USB core */
1421 udelay(100);
1422 usb_dw_wait_for_ahb_idle();
1423 DWC_GRSTCTL = CSRST;
1424 while (DWC_GRSTCTL & CSRST);
1425 usb_dw_wait_for_ahb_idle();
1426
1427 /* Configure FIFOs */
1428 DWC_GRXFSIZ = c->rx_fifosz;
1429#ifdef USB_DW_SHARED_FIFO
1430 DWC_GNPTXFSIZ = (c->nptx_fifosz << 16) | c->rx_fifosz;
1431#else
1432 DWC_TX0FSIZ = (c->nptx_fifosz << 16) | c->rx_fifosz;
1433#endif
1434 for (int i = 0; i < n_ptxfifos; i++)
1435 DWC_DIEPTXF(i) = (c->ptx_fifosz << 16) |
1436 (c->nptx_fifosz + c->rx_fifosz + c->ptx_fifosz*i);
1437 /*
1438 * According to p428 of the design guide, we need to ensure that
1439 * fifos are flushed before continuing.
1440 */
1441 usb_dw_flush_fifo(TXFFLSH|RXFFLSH, 0x10);
1442
1443 /* Configure the core */
1444 DWC_GUSBCFG = gusbcfg;
1445
1446 uint32_t gahbcfg = GINT;
1447#ifdef USB_DW_ARCH_SLAVE
1448#ifdef USB_DW_SHARED_FIFO
1449 if (c->use_ptxfifo_as_plain_buffer)
1450 gahbcfg |= PTXFELVL;
1451#endif
1452 if (c->disable_double_buffering)
1453 gahbcfg |= TXFELVL;
1454#else
1455 gahbcfg |= HBSTLEN(c->ahb_burst_len)|DMAEN;
1456#endif
1457 DWC_GAHBCFG = gahbcfg;
1458
1459 DWC_DCFG = NZLSOHSK;
1460#ifdef USB_DW_SHARED_FIFO
1461 /* Set EP mismatch counter to the maximum */
1462 DWC_DCFG |= EPMISCNT(0x1f);
1463#endif
1464
1465#if !defined(USB_DW_ARCH_SLAVE) && !defined(USB_DW_SHARED_FIFO)
1466 if (c->ahb_threshold)
1467 DWC_DTHRCTL = ARPEN|RXTHRLEN(c->ahb_threshold)|RXTHREN;
1468#endif
1469
1470 /* Set up interrupts */
1471 DWC_DOEPMSK = STUP|XFRC;
1472 DWC_DIEPMSK = TOC|XFRC;
1473
1474 /* Unmask all available endpoints */
1475 DWC_DAINTMSK = 0xffffffff;
1476 usb_endpoints = DWC_DAINTMSK;
1477
1478 uint32_t gintmsk = USBRST|ENUMDNE|IEPINT|OEPINT;
1479#ifdef USB_DW_ARCH_SLAVE
1480 gintmsk |= RXFLVL;
1481#endif
1482#ifdef USB_DW_SHARED_FIFO
1483 gintmsk |= EPMIS;
1484#endif
1485 DWC_GINTMSK = gintmsk;
1486
1487 usb_dw_reset_endpoints();
1488
1489 /* Soft disconnect */
1490 DWC_DCTL = SDIS;
1491
1492 usb_dw_target_clear_irq();
1493 usb_dw_target_enable_irq();
1494
1495 /* Soft reconnect */
1496 udelay(3000);
1497 DWC_DCTL &= ~SDIS;
1498}
1499
1500static void usb_dw_exit(void)
1501{
1502 /* Soft disconnect */
1503 DWC_DCTL = SDIS;
1504 udelay(10);
1505
1506 DWC_PCGCCTL = 1; /* Stop Phy clock */
1507
1508 /* Disable IRQs */
1509 usb_dw_target_disable_irq();
1510
1511 /* Disable clocks */
1512 usb_dw_target_disable_clocks();
1513}
1514
1515
1516/*
1517 * API functions
1518 */
1519
1520/* Cancel transfers on configured EPs */
1521void usb_drv_cancel_all_transfers()
1522{
1523 usb_dw_target_disable_irq();
1524 for (int ep = 1; ep < USB_NUM_ENDPOINTS; ep++)
1525 for (int dir = 0; dir < USB_DW_NUM_DIRS; dir++)
1526 if (usb_endpoints & (1 << (ep + USB_DW_DIR_OFF(dir))))
1527 if (usb_dw_get_ep(ep, dir)->active)
1528 {
1529 //usb_dw_flush_endpoint(ep, dir);
1530 usb_dw_abort_endpoint(ep, dir);
1531 DWC_EPCTL(ep, dir) |= SETD0PIDEF;
1532 }
1533 usb_dw_target_enable_irq();
1534}
1535
1536bool usb_drv_stalled(int endpoint, bool in)
1537{
1538 return usb_dw_get_stall(EP_NUM(endpoint),
1539 in ? USB_DW_EPDIR_IN : USB_DW_EPDIR_OUT);
1540}
1541
1542void usb_drv_stall(int endpoint, bool stall, bool in)
1543{
1544 usb_dw_target_disable_irq();
1545 usb_dw_set_stall(EP_NUM(endpoint),
1546 in ? USB_DW_EPDIR_IN : USB_DW_EPDIR_OUT, stall);
1547 usb_dw_target_enable_irq();
1548}
1549
1550void usb_drv_set_address(int address)
1551{
1552#if 1
1553 /* Ignored intentionally, because the controller requires us to set the
1554 new address before sending the response for some reason. So we'll
1555 already set it when the control request arrives, before passing that
1556 into the USB core, which will then call this dummy function. */
1557 (void)address;
1558#else
1559 usb_dw_target_disable_irq();
1560 usb_dw_set_address(address);
1561 usb_dw_target_enable_irq();
1562#endif
1563}
1564
1565int usb_drv_port_speed(void)
1566{
1567 return ((DWC_DSTS & 0x6) == 0);
1568}
1569
1570void usb_drv_set_test_mode(int mode)
1571{
1572 (void)mode;
1573 /* Ignore this for now */
1574}
1575
1576void usb_attach(void)
1577{
1578}
1579
1580void usb_drv_init(void)
1581{
1582 usb_dw_init();
1583}
1584
1585void usb_drv_exit(void)
1586{
1587 usb_dw_exit();
1588}
1589
1590void INT_USB_FUNC(void)
1591{
1592 usb_dw_irq();
1593}
1594
1595int usb_drv_request_endpoint(int type, int dir)
1596{
1597 int request_ep = -1;
1598 enum usb_dw_epdir epdir = (EP_DIR(dir) == DIR_IN) ?
1599 USB_DW_EPDIR_IN : USB_DW_EPDIR_OUT;
1600
1601 usb_dw_target_disable_irq();
1602 for (int ep = 1; ep < USB_NUM_ENDPOINTS; ep++)
1603 {
1604 if (usb_endpoints & (1 << (ep + USB_DW_DIR_OFF(epdir))))
1605 {
1606 struct usb_dw_ep* dw_ep = usb_dw_get_ep(ep, epdir);
1607 if (!dw_ep->active)
1608 {
1609 int maxpktsize = 64;
1610 if (type == EPTYP_ISOCHRONOUS){
1611 maxpktsize = 1023;
1612 } else {
1613 maxpktsize = usb_drv_port_speed() ? 512 : 64;
1614 }
1615
1616 if (usb_dw_configure_ep(ep, epdir, type,
1617 maxpktsize) >= 0)
1618 {
1619 dw_ep->active = true;
1620 request_ep = ep | dir;
1621 }
1622 break;
1623 }
1624 }
1625 }
1626 usb_dw_target_enable_irq();
1627 return request_ep;
1628}
1629
1630void usb_drv_release_endpoint(int endpoint)
1631{
1632 int epnum = EP_NUM(endpoint);
1633 if (!epnum) return;
1634 enum usb_dw_epdir epdir = (EP_DIR(endpoint) == DIR_IN) ?
1635 USB_DW_EPDIR_IN : USB_DW_EPDIR_OUT;
1636 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, epdir);
1637
1638 usb_dw_target_disable_irq();
1639 if (dw_ep->active)
1640 {
1641 usb_dw_unconfigure_ep(epnum, epdir);
1642 dw_ep->active = false;
1643 }
1644 usb_dw_target_enable_irq();
1645}
1646
1647int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length)
1648{
1649 usb_dw_target_disable_irq();
1650 usb_dw_transfer(EP_NUM(endpoint), USB_DW_EPDIR_OUT, ptr, length);
1651 usb_dw_target_enable_irq();
1652 return 0;
1653}
1654
1655int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
1656{
1657 usb_dw_target_disable_irq();
1658 usb_dw_transfer(EP_NUM(endpoint), USB_DW_EPDIR_IN, ptr, length);
1659 usb_dw_target_enable_irq();
1660 return 0;
1661}
1662
1663int usb_drv_send(int endpoint, void *ptr, int length)
1664{
1665 int epnum = EP_NUM(endpoint);
1666 struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, USB_DW_EPDIR_IN);
1667
1668 semaphore_wait(&dw_ep->complete, 0);
1669
1670 usb_drv_send_nonblocking(endpoint, ptr, length);
1671
1672 if (semaphore_wait(&dw_ep->complete, HZ) == OBJ_WAIT_TIMEDOUT)
1673 {
1674 usb_dw_target_disable_irq();
1675 usb_dw_abort_endpoint(epnum, USB_DW_EPDIR_IN);
1676 usb_dw_target_enable_irq();
1677 }
1678
1679 return dw_ep->status;
1680}
1681
1682void usb_drv_control_response(enum usb_control_response resp,
1683 void* data, int length)
1684{
1685 usb_dw_target_disable_irq();
1686 usb_dw_control_response(resp, data, length);
1687 usb_dw_target_enable_irq();
1688}
1689
1690int usb_drv_get_frame_number()
1691{
1692 // SOFFN is 14 bits, the least significant 3 appear to be some sort of microframe count.
1693 // The USB spec says a frame number is 11 bits. This way we get 1 frame per millisecond,
1694 // just like we're supposed to!
1695 return (DWC_DSTS >> 11) & 0x7FF;
1696}