1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright © 2010 Tobias Diedrich
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
25 #include "usb-target.h"
27 #include "clock-target.h"
32 /*#define LOGF_ENABLE*/
38 #if defined(USE_ROCKBOX_USB)
40 #include "usb-drv-as3525.h"
42 static struct usb_endpoint endpoints
[USB_NUM_EPS
][2];
43 static int got_set_configuration
= 0;
44 static int usb_enum_timeout
= -1;
47 * dma/setup descriptors and buffers should avoid sharing
48 * a cacheline with other data.
49 * dmadescs may share with each other, since we only access them uncached.
51 static struct usb_dev_dma_desc dmadescs
[USB_NUM_EPS
][2] __attribute__((aligned(32)));
52 /* reuse unused EP2 OUT descriptor here */
53 static struct usb_dev_setup_buf
*setup_desc
= (void*)&dmadescs
[2][1];
55 #if AS3525_MCLK_SEL != AS3525_CLK_PLLB
56 static inline void usb_enable_pll(void)
58 CGU_COUNTB
= CGU_LOCK_CNT
;
59 CGU_PLLB
= AS3525_PLLB_SETTING
;
60 CGU_PLLBSUP
= 0; /* enable PLLB */
61 while(!(CGU_INTCTRL
& CGU_PLLB_LOCK
)); /* wait until PLLB is locked */
64 static inline void usb_disable_pll(void)
66 CGU_PLLBSUP
= CGU_PLL_POWERDOWN
;
69 static inline void usb_enable_pll(void)
73 static inline void usb_disable_pll(void)
76 #endif /* AS3525_MCLK_SEL != AS3525_CLK_PLLB */
83 static void usb_tick(void);
85 static void usb_phy_on(void)
88 CGU_USB
= 1<<5 /* enable */
89 | (CLK_DIV(AS3525_PLLB_FREQ
, 48000000) / 2) << 2
90 | 2; /* source = PLLB */
93 ascodec_write(AS3515_USB_UTIL
, ascodec_read(AS3515_USB_UTIL
) | (1<<4));
97 CCU_SRC
= CCU_SRC_USB_AHB_EN
|CCU_SRC_USB_PHY_EN
;
98 CCU_SRL
= CCU_SRL_MAGIC_NUMBER
;
100 CCU_SRC
= CCU_SRC_USB_AHB_EN
;
102 CCU_SRC
= CCU_SRL
= 0;
104 USB_GPIO_CSR
= USB_GPIO_TX_ENABLE_N
105 | USB_GPIO_TX_BIT_STUFF_EN
107 | USB_GPIO_CLK_SEL10
; /* 0x06180000; */
110 static void usb_phy_suspend(void)
112 USB_GPIO_CSR
|= USB_GPIO_ASESSVLD_EXT
|
113 USB_GPIO_BSESSVLD_EXT
|
114 USB_GPIO_VBUS_VLD_EXT
;
116 USB_GPIO_CSR
|= USB_GPIO_VBUS_VLD_EXT_SEL
;
120 static void usb_phy_resume(void)
122 USB_GPIO_CSR
&= ~(USB_GPIO_ASESSVLD_EXT
|
123 USB_GPIO_BSESSVLD_EXT
|
124 USB_GPIO_VBUS_VLD_EXT
);
126 USB_GPIO_CSR
&= ~USB_GPIO_VBUS_VLD_EXT_SEL
;
130 static void setup_desc_init(struct usb_dev_setup_buf
*desc
)
132 struct usb_dev_setup_buf
*uc_desc
= AS3525_UNCACHED_ADDR(desc
);
134 uc_desc
->status
= USB_DMA_DESC_BS_HST_RDY
;
135 uc_desc
->resv
= 0xffffffff;
136 uc_desc
->data1
= 0xffffffff;
137 uc_desc
->data2
= 0xffffffff;
140 static void dma_desc_init(int ep
, int dir
)
142 struct usb_dev_dma_desc
*desc
= &dmadescs
[ep
][dir
];
143 struct usb_dev_dma_desc
*uc_desc
= AS3525_UNCACHED_ADDR(desc
);
145 endpoints
[ep
][dir
].uc_desc
= uc_desc
;
147 uc_desc
->status
= USB_DMA_DESC_BS_DMA_DONE
| \
148 USB_DMA_DESC_LAST
| \
149 USB_DMA_DESC_ZERO_LEN
;
150 uc_desc
->resv
= 0xffffffff;
151 uc_desc
->data_ptr
= 0;
152 uc_desc
->next_desc
= 0;
155 static void reset_endpoints(int init
)
160 * OUT EP 2 is an alias for OUT EP 0 on this HW!
162 * Resonates with "3 bidirectional- plus 1 in-endpoints in device mode"
163 * from the datasheet, but why ep2 and not ep3?
165 * Reserve it here so we will skip over it in request_endpoint().
167 endpoints
[2][1].state
|= EP_STATE_ALLOCATED
;
169 for(i
= 0; i
< USB_NUM_EPS
; i
++) {
171 * MPS sizes depending on speed:
172 * LS: 8 (control), no bulk available
173 * FS: 64 (control), 64 (bulk)
174 * HS: 64 (control), 512 (bulk)
176 * We don't need to handle LS since there is no low-speed only
179 int mps
= i
== 0 ? 64 : (usb_drv_port_speed() ? 512 : 64);
182 if (endpoints
[i
][0].state
& EP_STATE_BUSY
) {
183 if (endpoints
[i
][0].state
& EP_STATE_ASYNC
) {
184 endpoints
[i
][0].rc
= -1;
185 wakeup_signal(&endpoints
[i
][0].complete
);
187 usb_core_transfer_complete(i
, USB_DIR_IN
, -1, 0);
190 endpoints
[i
][0].state
= 0;
191 wakeup_init(&endpoints
[i
][0].complete
);
193 if (i
!= 2) { /* Skip the OUT EP0 alias */
194 if (endpoints
[i
][1].state
& EP_STATE_BUSY
)
195 usb_core_transfer_complete(i
, USB_DIR_OUT
, -1, 0);
196 endpoints
[i
][1].state
= 0;
197 wakeup_init(&endpoints
[i
][1].complete
);
198 USB_OEP_SUP_PTR(i
) = 0;
203 USB_IEP_CTRL (i
) = USB_EP_CTRL_FLUSH
|USB_EP_CTRL_SNAK
;
204 USB_IEP_MPS (i
) = mps
; /* in bytes */
205 /* We don't care about the 'IN token received' event */
206 USB_IEP_STS_MASK(i
) = USB_EP_STAT_IN
; /* OF: 0x840 */
207 USB_IEP_TXFSIZE (i
) = mps
/2; /* in dwords => mps*2 bytes */
208 USB_IEP_STS (i
) = 0xffffffff; /* clear status */
209 USB_IEP_DESC_PTR(i
) = 0;
211 if (i
!= 2) { /* Skip the OUT EP0 alias */
213 USB_OEP_CTRL (i
) = USB_EP_CTRL_FLUSH
|USB_EP_CTRL_SNAK
;
214 USB_OEP_MPS (i
) = (mps
/2 << 16) | mps
;
215 USB_OEP_STS_MASK(i
) = USB_EP_STAT_BNA
; /* OF: 0x1800 */
216 USB_OEP_RXFR (i
) = 0; /* Always 0 in OF trace? */
217 USB_OEP_STS (i
) = 0xffffffff; /* clear status */
218 USB_OEP_DESC_PTR(i
) = 0;
222 setup_desc_init(setup_desc
);
223 USB_OEP_SUP_PTR(0) = (int)setup_desc
;
226 void usb_drv_init(void)
228 logf("usb_drv_init() !!!!\n");
232 /* we have external power, so boost cpu */
235 /* length regulator: normal operation */
236 ascodec_write(AS3514_CVDD_DCDC3
, ascodec_read(AS3514_CVDD_DCDC3
) | 1<<2);
239 CGU_PERI
|= CGU_USB_CLOCK_ENABLE
;
242 CCU_SRC
= CCU_SRC_USB_AHB_EN
;
243 CCU_SRL
= CCU_SRL_MAGIC_NUMBER
;
245 CCU_SRC
= CCU_SRL
= 0;
247 USB_GPIO_CSR
= USB_GPIO_TX_ENABLE_N
248 | USB_GPIO_TX_BIT_STUFF_EN
250 | USB_GPIO_CLK_SEL10
; /* 0x06180000; */
252 /* bug workaround according to linux patch */
253 USB_DEV_CFG
= (USB_DEV_CFG
& ~3) | 1; /* full speed */
255 /* enable soft disconnect */
256 USB_DEV_CTRL
|= USB_DEV_CTRL_SOFT_DISCONN
;
260 USB_DEV_CTRL
|= USB_DEV_CTRL_SOFT_DISCONN
;
262 /* We don't care about SVC or SOF events */
263 /* Right now we don't handle suspend, so mask those too */
264 USB_DEV_INTR_MASK
= USB_DEV_INTR_SVC
|
266 USB_DEV_INTR_USB_SUSPEND
|
267 USB_DEV_INTR_EARLY_SUSPEND
;
269 USB_DEV_CFG
= USB_DEV_CFG_STAT_ACK
|
270 USB_DEV_CFG_UNI_DIR
|
271 USB_DEV_CFG_PI_16BIT
|
273 USB_DEV_CFG_SELF_POWERED
|
274 USB_DEV_CFG_CSR_PRG
|
275 USB_DEV_CFG_PHY_ERR_DETECT
;
277 USB_DEV_CTRL
= USB_DEV_CTRL_DESC_UPDATE
|
278 USB_DEV_CTRL_THRES_ENABLE
|
279 USB_DEV_CTRL_BURST_ENABLE
|
280 USB_DEV_CTRL_BLEN_8DWORDS
|
281 USB_DEV_CTRL_TLEN_8THMAXSIZE
;
283 USB_DEV_EP_INTR_MASK
&= ~((1<<0) | (1<<16)); /* ep 0 */
287 /* clear pending interrupts */
288 USB_DEV_EP_INTR
= 0xffffffff;
289 USB_DEV_INTR
= 0xffffffff;
291 VIC_INT_ENABLE
= INTERRUPT_USB
;
294 USB_DEV_CTRL
&= ~USB_DEV_CTRL_SOFT_DISCONN
;
296 USB_GPIO_CSR
= USB_GPIO_TX_ENABLE_N
297 | USB_GPIO_TX_BIT_STUFF_EN
300 | USB_GPIO_CLK_SEL10
; /* 0x06180000; */
302 tick_add_task(usb_tick
);
304 usb_enum_timeout
= HZ
; /* one second timeout for enumeration */
307 void usb_drv_exit(void)
309 tick_remove_task(usb_tick
);
310 USB_DEV_CTRL
|= (1<<10); /* soft disconnect */
313 * mask all interrupts _before_ writing to VIC_INT_EN_CLEAR,
314 * or else the core might latch the interrupt while
315 * the write ot VIC_INT_EN_CLEAR is in the pipeline and
316 * so cause a fake spurious interrupt.
318 USB_DEV_EP_INTR_MASK
= 0xffffffff;
319 USB_DEV_INTR_MASK
= 0xffffffff;
320 VIC_INT_EN_CLEAR
= INTERRUPT_USB
;
322 CGU_PERI
&= ~CGU_USB_CLOCK_ENABLE
;
323 /* Disable UVDD generating LDO */
324 ascodec_write(AS3515_USB_UTIL
, ascodec_read(AS3515_USB_UTIL
) & ~(1<<4));
327 logf("usb_drv_exit() !!!!\n");
330 int usb_drv_port_speed(void)
332 return (USB_DEV_STS
& USB_DEV_STS_MASK_SPD
) ? 0 : 1;
335 int usb_drv_request_endpoint(int type
, int dir
)
337 int d
= dir
== USB_DIR_IN
? 0 : 1;
338 int i
= 1; /* skip the control EP */
340 for(; i
< USB_NUM_EPS
; i
++) {
341 if (endpoints
[i
][d
].state
& EP_STATE_ALLOCATED
)
344 endpoints
[i
][d
].state
|= EP_STATE_ALLOCATED
;
346 if (dir
== USB_DIR_IN
) {
347 USB_IEP_CTRL(i
) = USB_EP_CTRL_FLUSH
|
351 USB_DEV_EP_INTR_MASK
&= ~(1<<i
);
353 USB_OEP_CTRL(i
) = USB_EP_CTRL_FLUSH
|
357 USB_DEV_EP_INTR_MASK
&= ~(1<<(16+i
));
359 /* logf("usb_drv_request_endpoint(%d, %d): returning %02x\n", type, dir, i | dir); */
363 logf("usb_drv_request_endpoint(%d, %d): no free endpoint found\n", type
, dir
);
367 void usb_drv_release_endpoint(int ep
)
370 int d
= ep
& USB_DIR_IN
? 0 : 1;
372 if (i
>= USB_NUM_EPS
)
375 * Check for control EP and ignore it.
376 * Unfortunately the usb core calls
377 * usb_drv_release_endpoint() for ep=0..(USB_NUM_ENDPOINTS-1),
378 * but doesn't request a new control EP after that...
380 if (i
== 0 || /* Don't mask control EP */
381 (i
== 2 && d
== 1)) /* See reset_endpoints(), EP2_OUT == EP0_OUT */
384 if (!(endpoints
[i
][d
].state
& EP_STATE_ALLOCATED
))
387 /* logf("usb_drv_release_endpoint(%d, %d)\n", i, d); */
388 endpoints
[i
][d
].state
= 0;
389 USB_DEV_EP_INTR_MASK
|= (1<<(16*d
+i
));
390 USB_EP_CTRL(i
, !d
) = USB_EP_CTRL_FLUSH
| USB_EP_CTRL_SNAK
;
393 void usb_drv_cancel_all_transfers(void)
395 logf("usb_drv_cancel_all_transfers()\n");
398 int flags
= disable_irq_save();
403 int usb_drv_recv(int ep
, void *ptr
, int len
)
405 struct usb_dev_dma_desc
*uc_desc
= endpoints
[ep
][1].uc_desc
;
408 logf("usb_drv_recv(%d,%x,%d)\n", ep
, (int)ptr
, len
);
410 if (len
> USB_DMA_DESC_RXTX_BYTES
)
411 panicf("usb_recv: len=%d > %d", len
, USB_DMA_DESC_RXTX_BYTES
);
414 logf("addr %08x not aligned!\n", (int)ptr
);
417 endpoints
[ep
][1].state
|= EP_STATE_BUSY
;
418 endpoints
[ep
][1].len
= len
;
419 endpoints
[ep
][1].rc
= -1;
420 endpoints
[ep
][1].timeout
= current_tick
+ HZ
;
422 /* remove data buffer from cache */
423 invalidate_dcache_range(ptr
, len
);
426 uc_desc
->status
= USB_DMA_DESC_BS_HST_RDY
|
430 uc_desc
->status
|= USB_DMA_DESC_ZERO_LEN
;
431 uc_desc
->data_ptr
= 0;
433 uc_desc
->data_ptr
= ptr
;
435 USB_OEP_DESC_PTR(ep
) = (int)&dmadescs
[ep
][1];
436 USB_OEP_STS(ep
) = USB_EP_STAT_OUT_RCVD
; /* clear status */
438 /* Make sure receive DMA is on */
439 if (!(USB_DEV_CTRL
& USB_DEV_CTRL_RDE
)){
440 logf("enabling receive DMA\n");
441 USB_DEV_CTRL
|= USB_DEV_CTRL_RDE
;
442 if (!(USB_DEV_CTRL
& USB_DEV_CTRL_RDE
))
443 logf("failed to enable!\n");
446 USB_OEP_CTRL(ep
) |= USB_EP_CTRL_CNAK
; /* Go! */
448 if (USB_OEP_CTRL(ep
) & USB_EP_CTRL_NAK
) {
450 while (USB_OEP_CTRL(ep
) & USB_EP_CTRL_NAK
) {
451 USB_OEP_CTRL(ep
) |= USB_EP_CTRL_CNAK
; /* Go! */
454 logf("ep%d CNAK needed %d retries CTRL=%x\n", ep
, i
, (int)USB_OEP_CTRL(ep
));
460 #if defined(LOGF_ENABLE)
461 static char hexbuf
[1025];
462 static char hextab
[16] = "0123456789abcdef";
464 char *make_hex(char *data
, int len
)
467 if (!((int)data
& 0x40000000))
468 data
= AS3525_UNCACHED_ADDR(data
); /* don't pollute the cache */
473 for (i
=0; i
<len
; i
++) {
474 hexbuf
[2*i
] = hextab
[(unsigned char)data
[i
] >> 4 ];
475 hexbuf
[2*i
+1] = hextab
[(unsigned char)data
[i
] & 0xf];
483 void ep_send(int ep
, void *ptr
, int len
)
485 struct usb_dev_dma_desc
*uc_desc
= endpoints
[ep
][0].uc_desc
;
487 endpoints
[ep
][0].state
|= EP_STATE_BUSY
;
488 endpoints
[ep
][0].len
= len
;
489 endpoints
[ep
][0].rc
= -1;
490 endpoints
[ep
][0].timeout
= current_tick
+ HZ
;
492 /* Make sure data is committed to memory */
493 clean_dcache_range(ptr
, len
);
495 logf("xx%s\n", make_hex(ptr
, len
));
497 uc_desc
->status
= USB_DMA_DESC_BS_HST_RDY
|
501 uc_desc
->status
|= USB_DMA_DESC_ZERO_LEN
;
503 uc_desc
->data_ptr
= ptr
;
505 USB_IEP_DESC_PTR(ep
) = (int)&dmadescs
[ep
][0];
506 USB_IEP_STS(ep
) = 0xffffffff; /* clear status */
508 USB_IEP_CTRL(ep
) |= USB_EP_CTRL_CNAK
| USB_EP_CTRL_PD
;
509 /* HW automatically sets NAK bit later */
512 int usb_drv_send(int ep
, void *ptr
, int len
)
514 logf("usb_drv_send(%d,%x,%d): ", ep
, (int)ptr
, len
);
518 if (ep
== 0 && got_set_configuration
) {
519 got_set_configuration
= 0;
521 panicf("usb_drv_send: GSC, but len!=0");
522 /* Tell the HW we handled the request */
523 USB_DEV_CTRL
|= USB_DEV_CTRL_APCSR_DONE
;
527 ep_send(ep
, ptr
, len
);
528 while (endpoints
[ep
][0].state
& EP_STATE_BUSY
)
529 wakeup_wait(&endpoints
[ep
][0].complete
, TIMEOUT_BLOCK
);
531 return endpoints
[ep
][0].rc
;
534 int usb_drv_send_nonblocking(int ep
, void *ptr
, int len
)
536 logf("usb_drv_send_nonblocking(%d,%x,%d): ", ep
, (int)ptr
, len
);
538 endpoints
[ep
][0].state
|= EP_STATE_ASYNC
;
539 ep_send(ep
, ptr
, len
);
543 static void handle_in_ep(int ep
)
545 int ep_sts
= USB_IEP_STS(ep
) & ~USB_IEP_STS_MASK(ep
);
548 panicf("in_ep > 3?!");
550 USB_IEP_STS(ep
) = ep_sts
; /* ack */
552 if (ep_sts
& USB_EP_STAT_BNA
) { /* Buffer was not set up */
553 int ctrl
= USB_IEP_CTRL(ep
);
554 logf("ep%d IN, status %x ctrl %x (BNA)\n", ep
, ep_sts
, ctrl
);
555 panicf("ep%d IN 0x%x 0x%x (BNA)", ep
, ep_sts
, ctrl
);
558 if (ep_sts
& USB_EP_STAT_TDC
) {
559 endpoints
[ep
][0].state
&= ~EP_STATE_BUSY
;
560 endpoints
[ep
][0].rc
= 0;
561 logf("EP%d %x %stx done len %x stat %08x\n",
562 ep
, ep_sts
, endpoints
[ep
][0].state
& EP_STATE_ASYNC
? "async " :"",
563 endpoints
[ep
][0].len
,
564 endpoints
[ep
][0].uc_desc
->status
);
565 if (endpoints
[ep
][0].state
& EP_STATE_ASYNC
) {
566 endpoints
[ep
][0].state
&= ~EP_STATE_ASYNC
;
567 usb_core_transfer_complete(ep
, USB_DIR_IN
, 0, endpoints
[ep
][0].len
);
569 wakeup_signal(&endpoints
[ep
][0].complete
);
571 ep_sts
&= ~USB_EP_STAT_TDC
;
575 logf("ep%d IN, hwstat %lx, epstat %x\n", ep
, USB_IEP_STS(ep
), endpoints
[ep
][0].state
);
576 panicf("ep%d IN 0x%x", ep
, ep_sts
);
580 static void handle_out_ep(int ep
)
582 struct usb_ctrlrequest
*req
= (void*)AS3525_UNCACHED_ADDR(&setup_desc
->data1
);
583 int ep_sts
= USB_OEP_STS(ep
) & ~USB_OEP_STS_MASK(ep
);
586 panicf("out_ep > 3!?");
588 USB_OEP_STS(ep
) = ep_sts
; /* ACK */
590 if (ep_sts
& USB_EP_STAT_BNA
) { /* Buffer was not set up */
591 int ctrl
= USB_OEP_CTRL(ep
);
592 logf("ep%d OUT, status %x ctrl %x (BNA)\n", ep
, ep_sts
, ctrl
);
593 panicf("ep%d OUT 0x%x 0x%x (BNA)", ep
, ep_sts
, ctrl
);
594 ep_sts
&= ~USB_EP_STAT_BNA
;
597 if (ep_sts
& USB_EP_STAT_OUT_RCVD
) {
598 struct usb_dev_dma_desc
*uc_desc
= endpoints
[ep
][1].uc_desc
;
599 int dma_sts
= uc_desc
->status
;
600 int dma_len
= dma_sts
& 0xffff;
602 if (!(dma_sts
& USB_DMA_DESC_ZERO_LEN
)) {
603 logf("EP%d OUT token, st:%08x len:%d frm:%x data=%s epstate=%d\n",
604 ep
, dma_sts
& 0xf8000000, dma_len
, (dma_sts
>> 16) & 0x7ff,
605 make_hex(uc_desc
->data_ptr
, dma_len
), endpoints
[ep
][1].state
);
607 * If parts of the just dmaed range are in cache, dump them now.
609 dump_dcache_range(uc_desc
->data_ptr
, dma_len
);
611 logf("EP%d OUT token, st:%08x frm:%x (no data)\n", ep
,
612 dma_sts
& 0xf8000000, (dma_sts
>> 16) & 0x7ff);
615 if (endpoints
[ep
][1].state
& EP_STATE_BUSY
) {
616 endpoints
[ep
][1].state
&= ~EP_STATE_BUSY
;
617 endpoints
[ep
][1].rc
= 0;
618 usb_core_transfer_complete(ep
, USB_DIR_OUT
, 0, dma_len
);
620 logf("EP%d OUT, but no one was listening?\n", ep
);
623 USB_OEP_CTRL(ep
) |= USB_EP_CTRL_SNAK
; /* make sure NAK is set */
624 ep_sts
&= ~USB_EP_STAT_OUT_RCVD
;
627 if (ep_sts
& USB_EP_STAT_SETUP_RCVD
) {
628 static struct usb_ctrlrequest req_copy
;
631 logf("t%ld:got SETUP packet: %s type=%d req=%d val=%d ind=%d len=%d\n",
633 make_hex((void*)req
, 8),
640 usb_core_control_request(&req_copy
);
641 setup_desc_init(setup_desc
);
643 ep_sts
&= ~USB_EP_STAT_SETUP_RCVD
;
647 logf("ep%d OUT, status %x\n", ep
, ep_sts
);
648 panicf("ep%d OUT 0x%x", ep
, ep_sts
);
652 /* HW automatically disables RDE, re-enable it */
653 /* THEORY: Because we only set up one DMA buffer... */
654 USB_DEV_CTRL
|= USB_DEV_CTRL_RDE
;
657 if (!(USB_DEV_CTRL
& USB_DEV_CTRL_RDE
)){
658 logf("receive DMA is disabled!\n");
659 //USB_DEV_CTRL |= USB_DEV_CTRL_RDE;
664 * This is a simplified version of the timer based RDE enable from
665 * the Linux amd5536udc.c driver.
666 * We need this because of the following hw issue:
667 * The usb_storage buffer is 63KB, but Linux sends 120KB.
668 * We get the first part, but upon re-enabling receive dma we
669 * get a 'buffer not available' error from the hardware, since
670 * we haven't gotten the next usb_drv_recv() from the stack yet.
671 * It seems the NAK bit is ignored here and the HW tries to dma
672 * the incoming data anyway.
673 * In theory I think the BNA error should be recoverable, but
674 * I haven't figured out how to do that yet and this approach seems
677 static void usb_tick(void)
679 static int rde_timer
= 0;
680 static int rde_fails
= 0;
681 struct usb_endpoint
*eps
= &endpoints
[0][0];
684 if (usb_enum_timeout
!= -1) {
686 * If the enum times out it's a charger, drop out of usb mode.
688 if (usb_enum_timeout
-- <= 0)
692 for (i
=0; i
<2*USB_NUM_EPS
; i
++) {
693 if (!(eps
[i
].state
& EP_STATE_BUSY
) ||
694 !TIME_AFTER(current_tick
, endpoints
[i
]))
697 /* recv or send timed out */
698 if (eps
[i
].state
& EP_STATE_ASYNC
) {
700 wakeup_signal(&eps
[i
].complete
);
702 usb_core_transfer_complete(i
/2, i
&1 ? USB_DIR_OUT
: USB_DIR_IN
,
705 eps
[i
].state
&= ~(EP_STATE_BUSY
|EP_STATE_ASYNC
);
708 if (USB_DEV_CTRL
& USB_DEV_CTRL_RDE
)
711 if (!(USB_DEV_STS
& USB_DEV_STS_RXF_EMPTY
)) {
713 logf("usb_tick: fifo got filled\n");
718 logf("usb_tick: re-enabling RDE\n");
719 USB_DEV_CTRL
|= USB_DEV_CTRL_RDE
;
721 if (USB_DEV_CTRL
& USB_DEV_CTRL_RDE
) {
726 panicf("usb_tick: failed to set RDE");
731 /* interrupt service routine */
734 int ep
= USB_DEV_EP_INTR
& ~USB_DEV_EP_INTR_MASK
;
735 int intr
= USB_DEV_INTR
& ~USB_DEV_INTR_MASK
;
737 /* ACK interrupt sources */
738 USB_DEV_EP_INTR
= ep
;
741 /* Handle endpoint interrupts */
743 int onebit
= 31-__builtin_clz(ep
);
745 if (onebit
< 16) handle_in_ep(onebit
);
746 else handle_out_ep(onebit
-16);
748 ep
&= ~(1 << onebit
);
751 /* Handle general device interrupts */
753 if (intr
& USB_DEV_INTR_SET_INTERFACE
) {/* SET_INTERFACE received */
754 logf("set interface\n");
755 panicf("set interface");
756 intr
&= ~USB_DEV_INTR_SET_INTERFACE
;
758 if (intr
& USB_DEV_INTR_SET_CONFIG
) {/* SET_CONFIGURATION received */
760 * This is handled in HW, we have to fake a request here
763 static struct usb_ctrlrequest set_config
= {
764 bRequestType
: USB_TYPE_STANDARD
| USB_RECIP_DEVICE
,
765 bRequest
: USB_REQ_SET_CONFIGURATION
,
771 logf("set config\n");
772 got_set_configuration
= 1;
774 set_config
.wValue
= USB_DEV_STS
& USB_DEV_STS_MASK_CFG
;
775 usb_core_control_request(&set_config
);
776 intr
&= ~USB_DEV_INTR_SET_CONFIG
;
778 if (intr
& USB_DEV_INTR_EARLY_SUSPEND
) {/* idle >3ms detected */
780 intr
&= ~USB_DEV_INTR_EARLY_SUSPEND
;
782 if (intr
& USB_DEV_INTR_USB_RESET
) {/* usb reset from host? */
785 usb_core_bus_reset();
786 intr
&= ~USB_DEV_INTR_USB_RESET
;
788 if (intr
& USB_DEV_INTR_USB_SUSPEND
) {/* suspend req from host? */
789 logf("usb suspend\n");
790 intr
&= ~USB_DEV_INTR_USB_SUSPEND
;
792 if (intr
& USB_DEV_INTR_SOF
) {/* sof received */
794 intr
&= ~USB_DEV_INTR_SOF
;
796 if (intr
& USB_DEV_INTR_SVC
) {/* device status changed */
797 logf("svc: %08x otg: %08x\n", (int)USB_DEV_STS
, (int)USB_OTG_CSR
);
798 intr
&= ~USB_DEV_INTR_SVC
;
800 if (intr
& USB_DEV_INTR_ENUM_DONE
) {/* speed enumeration complete */
801 int spd
= USB_DEV_STS
& USB_DEV_STS_MASK_SPD
; /* Enumerated Speed */
802 usb_enum_timeout
= -1;
804 logf("speed enum complete: ");
805 if (spd
== USB_DEV_STS_SPD_HS
) logf("hs\n");
806 if (spd
== USB_DEV_STS_SPD_FS
) logf("fs\n");
807 if (spd
== USB_DEV_STS_SPD_LS
) logf("ls\n");
809 USB_PHY_EP0_INFO
= 0x00200000 |
812 USB_PHY_EP1_INFO
= 0x00200000 |
815 USB_PHY_EP2_INFO
= 0x00200001 |
818 USB_PHY_EP3_INFO
= 0x00200001 |
821 USB_DEV_CTRL
|= USB_DEV_CTRL_APCSR_DONE
;
822 USB_IEP_CTRL(0) |= USB_EP_CTRL_ACT
;
823 USB_OEP_CTRL(0) |= USB_EP_CTRL_ACT
;
824 intr
&= ~USB_DEV_INTR_ENUM_DONE
;
826 if (intr
& USB_DEV_INTR_MYSTERY
) {
827 logf("got mystery dev intr\n");
828 USB_DEV_INTR_MASK
|= USB_DEV_INTR_MYSTERY
;
829 intr
&= ~USB_DEV_INTR_MYSTERY
;
832 logf("usb devirq 0x%x", intr
);
833 panicf("usb devirq 0x%x", intr
);
838 /* (not essential? , not implemented in usb-tcc.c) */
839 void usb_drv_set_test_mode(int mode
)
844 /* handled internally by controller */
845 void usb_drv_set_address(int address
)
850 void usb_drv_stall(int ep
, bool stall
, bool in
)
852 if (stall
) USB_EP_CTRL(ep
, in
) |= USB_EP_CTRL_STALL
;
853 else USB_EP_CTRL(ep
, in
) &= ~USB_EP_CTRL_STALL
;
856 bool usb_drv_stalled(int ep
, bool in
)
858 return USB_EP_CTRL(ep
, in
) & USB_EP_CTRL_STALL
;
863 void usb_attach(void)
867 void usb_drv_init(void)
871 void usb_drv_exit(void)
875 int usb_drv_port_speed(void)
880 int usb_drv_request_endpoint(int type
, int dir
)
888 void usb_drv_release_endpoint(int ep
)
893 void usb_drv_cancel_all_transfers(void)
897 void usb_drv_set_test_mode(int mode
)
902 void usb_drv_set_address(int address
)
907 int usb_drv_recv(int ep
, void *ptr
, int len
)
916 int usb_drv_send(int ep
, void *ptr
, int len
)
925 int usb_drv_send_nonblocking(int ep
, void *ptr
, int len
)
934 void usb_drv_stall(int ep
, bool stall
, bool in
)
941 bool usb_drv_stalled(int ep
, bool in
)