X-Git-Url: https://git.stricted.de/?p=GitHub%2Fmt8127%2Fandroid_kernel_alcatel_ttab.git;a=blobdiff_plain;f=drivers%2Fusb%2Fhost%2Fxhci-ring.c;h=d52c1653ce658f0d7cf60a467044d58ebcdd3de5;hp=fde0277adc2c4884a5cbbc28f7480780c6cd1a06;hb=3460ea59c67f92c0e873e00e2508c88fb1955988;hpb=5a427ce18a14d6b85972c62196a8f10c3624d74a diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index fde0277adc2c..d52c1653ce65 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -242,9 +242,13 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, * carry over the chain bit of the previous TRB * (which may mean the chain bit is cleared). */ + #ifdef CONFIG_MTK_XHCI + if (!xhci_link_trb_quirk(xhci)) { + #else if (!(ring->type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST)) && !xhci_link_trb_quirk(xhci)) { + #endif next->link.control &= cpu_to_le32(~TRB_CHAIN); next->link.control |= @@ -273,16 +277,20 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, static inline int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, unsigned int num_trbs) { +#ifndef CONFIG_MTK_XHCI int num_trbs_in_deq_seg; +#endif if (ring->num_trbs_free < num_trbs) return 0; +#ifndef CONFIG_MTK_XHCI if (ring->type != TYPE_COMMAND && ring->type != TYPE_EVENT) { num_trbs_in_deq_seg = ring->dequeue - ring->deq_seg->trbs; if (ring->num_trbs_free < num_trbs + num_trbs_in_deq_seg) return 0; } +#endif return 1; } @@ -730,10 +738,12 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, if (urb_priv->td_cnt == urb_priv->length) { if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; + #ifndef CONFIG_MTK_XHCI if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { if (xhci->quirks & XHCI_AMD_PLL_FIX) usb_amd_quirk_pll_enable(); } + #endif } usb_hcd_unlink_urb_from_ep(hcd, urb); @@ -1982,11 +1992,13 @@ td_cleanup: ret = 1; if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; + #ifndef CONFIG_MTK_XHCI if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { if (xhci->quirks & XHCI_AMD_PLL_FIX) usb_amd_quirk_pll_enable(); } + #endif } } } @@ -2558,7 +2570,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, * successful event after a short transfer. * Ignore it. */ - if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && + if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && ep_ring->last_td_was_short) { ep_ring->last_td_was_short = false; ret = 0; @@ -2927,13 +2939,16 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, /* If we're not dealing with 0.95 hardware or isoc rings * on AMD 0.96 host, clear the chain bit. */ + #ifndef CONFIG_MTK_XHCI if (!xhci_link_trb_quirk(xhci) && !(ring->type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST))) next->link.control &= cpu_to_le32(~TRB_CHAIN); else next->link.control |= cpu_to_le32(TRB_CHAIN); - + #else + next->link.control &= cpu_to_le32(~TRB_CHAIN); + #endif wmb(); next->link.control ^= cpu_to_le32(TRB_CYCLE); @@ -3112,6 +3127,29 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, * right shifted by 10. * It must fit in bits 21:17, so it can't be bigger than 31. */ +#ifdef CONFIG_MTK_XHCI +static u32 xhci_td_remainder(unsigned int td_transfer_size, unsigned int td_running_total + , unsigned int maxp, unsigned trb_buffer_length) +{ + u32 max = 31; + int remainder, td_packet_count, packet_transferred; + + //0 for the last TRB + //FIXME: need to workaround if there is ZLP in this TD + if (td_running_total + trb_buffer_length == td_transfer_size) + return 0; + + //FIXME: need to take care of high-bandwidth (MAX_ESIT) + packet_transferred = (td_running_total /*+ trb_buffer_length*/) / maxp; + td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp); + remainder = td_packet_count - packet_transferred; + + if (remainder > max) + return max << 17; + else + return remainder << 17; +} +#else static u32 xhci_td_remainder(unsigned int remainder) { u32 max = (1 << (21 - 17 + 1)) - 1; @@ -3121,7 +3159,10 @@ static u32 xhci_td_remainder(unsigned int remainder) else return (remainder >> 10) << 17; } +#endif + +#ifndef CONFIG_MTK_XHCI /* * For xHCI 1.0 host controllers, TD size is the number of max packet sized * packets remaining in the TD (*not* including this TRB). @@ -3157,6 +3198,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, return 31 << 17; return (total_packet_count - packets_transferred) << 17; } +#endif static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int slot_id, unsigned int ep_index) @@ -3258,6 +3300,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, (unsigned int) addr + trb_buff_len); } + /* Set the TRB length, TD size, and interrupter fields. */ + #ifdef CONFIG_MTK_XHCI + if(num_trbs >1){ + remainder = xhci_td_remainder(urb->transfer_buffer_length, + running_total, urb->ep->desc.wMaxPacketSize, trb_buff_len); + } + #else /* Set the TRB length, TD size, and interrupter fields. */ if (xhci->hci_version < 0x100) { remainder = xhci_td_remainder( @@ -3268,6 +3317,8 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, trb_buff_len, total_packet_count, urb, num_trbs - 1); } + #endif + length_field = TRB_LEN(trb_buff_len) | remainder | TRB_INTR_TARGET(0); @@ -3326,7 +3377,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, bool more_trbs_coming; int start_cycle; u32 field, length_field; - +#ifdef CONFIG_MTK_XHCI + int max_packet = USB_SPEED_HIGH; +#endif int running_total, trb_buff_len, ret; unsigned int total_packet_count; u64 addr; @@ -3356,6 +3409,24 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */ +#ifdef CONFIG_MTK_XHCI + switch(urb->dev->speed){ + case USB_SPEED_SUPER: + max_packet = urb->ep->desc.wMaxPacketSize; + break; + case USB_SPEED_HIGH: + case USB_SPEED_FULL: + case USB_SPEED_LOW: + default: + max_packet = urb->ep->desc.wMaxPacketSize & 0x7ff; + break; + } + if((urb->transfer_flags & URB_ZERO_PACKET) + && ((urb->transfer_buffer_length % max_packet) == 0)){ + num_trbs++; + } +#endif + ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, num_trbs, urb, 0, mem_flags); @@ -3412,7 +3483,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Only set interrupt on short packet for IN endpoints */ if (usb_urb_dir_in(urb)) field |= TRB_ISP; - + #ifdef CONFIG_MTK_XHCI + remainder = xhci_td_remainder(urb->transfer_buffer_length, running_total, max_packet, trb_buff_len); + #else /* Set the TRB length, TD size, and interrupter fields. */ if (xhci->hci_version < 0x100) { remainder = xhci_td_remainder( @@ -3423,6 +3496,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, trb_buff_len, total_packet_count, urb, num_trbs - 1); } + #endif length_field = TRB_LEN(trb_buff_len) | remainder | TRB_INTR_TARGET(0); @@ -3512,7 +3586,11 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field |= 0x1; /* xHCI 1.0 6.4.1.2.1: Transfer Type field */ +#ifdef CONFIG_MTK_XHCI + if(1){ +#else if (xhci->hci_version == 0x100) { +#endif if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) field |= TRB_TX_TYPE(TRB_DATA_IN); @@ -3536,7 +3614,12 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field = TRB_TYPE(TRB_DATA); length_field = TRB_LEN(urb->transfer_buffer_length) | + #ifdef CONFIG_MTK_XHCI + //CC: MTK style, no scatter-gather for control transfer + 0 | + #else xhci_td_remainder(urb->transfer_buffer_length) | + #endif TRB_INTR_TARGET(0); if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) @@ -3659,6 +3742,9 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, u64 start_addr, addr; int i, j; bool more_trbs_coming; +#ifdef CONFIG_MTK_XHCI + int max_packet = USB_SPEED_HIGH; +#endif ep_ring = xhci->devs[slot_id]->eps[ep_index].ring; @@ -3672,6 +3758,19 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, start_trb = &ep_ring->enqueue->generic; start_cycle = ep_ring->cycle_state; +#ifdef CONFIG_MTK_XHCI + switch(urb->dev->speed){ + case USB_SPEED_SUPER: + max_packet = urb->ep->desc.wMaxPacketSize; + break; + case USB_SPEED_HIGH: + case USB_SPEED_FULL: + case USB_SPEED_LOW: + default: + max_packet = urb->ep->desc.wMaxPacketSize & 0x7ff; + break; + } +#endif urb_priv = urb->hcpriv; /* Queue the first TRB, even if it's zero-length */ for (i = 0; i < num_tds; i++) { @@ -3760,6 +3859,9 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, trb_buff_len = td_remain_len; /* Set the TRB length, TD size, & interrupter fields. */ + #ifdef CONFIG_MTK_XHCI + remainder = xhci_td_remainder(urb->transfer_buffer_length, running_total, max_packet, trb_buff_len); + #else if (xhci->hci_version < 0x100) { remainder = xhci_td_remainder( td_len - running_total); @@ -3769,6 +3871,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, total_packet_count, urb, (trbs_per_td - j - 1)); } + #endif length_field = TRB_LEN(trb_buff_len) | remainder | TRB_INTR_TARGET(0); @@ -3791,11 +3894,12 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, goto cleanup; } } - + #ifndef CONFIG_MTK_XHCI if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { if (xhci->quirks & XHCI_AMD_PLL_FIX) usb_amd_quirk_pll_disable(); } + #endif xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs++; giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,