|
@@ -634,7 +634,17 @@ static bool musb_tx_dma_program(struct dma_controller *dma,
|
|
|
mode = 1;
|
|
|
csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB;
|
|
|
/* autoset shouldn't be set in high bandwidth */
|
|
|
- if (qh->hb_mult == 1)
|
|
|
+ /*
|
|
|
+ * Enable Autoset according to table
|
|
|
+ * below
|
|
|
+ * bulk_split hb_mult Autoset_Enable
|
|
|
+ * 0 1 Yes(Normal)
|
|
|
+ * 0 >1 No(High BW ISO)
|
|
|
+ * 1 1 Yes(HS bulk)
|
|
|
+ * 1 >1 Yes(FS bulk)
|
|
|
+ */
|
|
|
+ if (qh->hb_mult == 1 || (qh->hb_mult > 1 &&
|
|
|
+ can_bulk_split(hw_ep->musb, qh->type)))
|
|
|
csr |= MUSB_TXCSR_AUTOSET;
|
|
|
} else {
|
|
|
mode = 0;
|
|
@@ -746,7 +756,13 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
|
|
|
/* general endpoint setup */
|
|
|
if (epnum) {
|
|
|
/* flush all old state, set default */
|
|
|
- musb_h_tx_flush_fifo(hw_ep);
|
|
|
+ /*
|
|
|
+ * We could be flushing valid
|
|
|
+ * packets in double buffering
|
|
|
+ * case
|
|
|
+ */
|
|
|
+ if (!hw_ep->tx_double_buffered)
|
|
|
+ musb_h_tx_flush_fifo(hw_ep);
|
|
|
|
|
|
/*
|
|
|
* We must not clear the DMAMODE bit before or in
|
|
@@ -763,11 +779,13 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
|
|
|
);
|
|
|
csr |= MUSB_TXCSR_MODE;
|
|
|
|
|
|
- if (usb_gettoggle(urb->dev, qh->epnum, 1))
|
|
|
- csr |= MUSB_TXCSR_H_WR_DATATOGGLE
|
|
|
- | MUSB_TXCSR_H_DATATOGGLE;
|
|
|
- else
|
|
|
- csr |= MUSB_TXCSR_CLRDATATOG;
|
|
|
+ if (!hw_ep->tx_double_buffered) {
|
|
|
+ if (usb_gettoggle(urb->dev, qh->epnum, 1))
|
|
|
+ csr |= MUSB_TXCSR_H_WR_DATATOGGLE
|
|
|
+ | MUSB_TXCSR_H_DATATOGGLE;
|
|
|
+ else
|
|
|
+ csr |= MUSB_TXCSR_CLRDATATOG;
|
|
|
+ }
|
|
|
|
|
|
musb_writew(epio, MUSB_TXCSR, csr);
|
|
|
/* REVISIT may need to clear FLUSHFIFO ... */
|
|
@@ -791,17 +809,19 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
|
|
|
/* protocol/endpoint/interval/NAKlimit */
|
|
|
if (epnum) {
|
|
|
musb_writeb(epio, MUSB_TXTYPE, qh->type_reg);
|
|
|
- if (musb->double_buffer_not_ok)
|
|
|
+ if (musb->double_buffer_not_ok) {
|
|
|
musb_writew(epio, MUSB_TXMAXP,
|
|
|
hw_ep->max_packet_sz_tx);
|
|
|
- else if (can_bulk_split(musb, qh->type))
|
|
|
+ } else if (can_bulk_split(musb, qh->type)) {
|
|
|
+ qh->hb_mult = hw_ep->max_packet_sz_tx
|
|
|
+ / packet_sz;
|
|
|
musb_writew(epio, MUSB_TXMAXP, packet_sz
|
|
|
- | ((hw_ep->max_packet_sz_tx /
|
|
|
- packet_sz) - 1) << 11);
|
|
|
- else
|
|
|
+ | ((qh->hb_mult) - 1) << 11);
|
|
|
+ } else {
|
|
|
musb_writew(epio, MUSB_TXMAXP,
|
|
|
qh->maxpacket |
|
|
|
((qh->hb_mult - 1) << 11));
|
|
|
+ }
|
|
|
musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg);
|
|
|
} else {
|
|
|
musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg);
|