diff mbox series

[U-Boot,12/14] usb: xhci: Program max burst size for endpoint

Message ID 1505742050-5697-13-git-send-email-bmeng.cn@gmail.com
State Accepted
Commit fa483b2c750f6ebdb5946f46b217aa3f9a449531
Delegated to: Marek Vasut
Headers show
Series usb: xhci: Add interrupt transfer support and full speed device support | expand

Commit Message

Bin Meng Sept. 18, 2017, 1:40 p.m. UTC
The 'Max Burst Size' indicates to the xHC the maximum number of
consecutive USB transactions that should be executed per scheduling
opportunity. This is a “zero-based” value, where 0 to 15 represents
burst sizes of 1 to 16, but at present this is always set to zero.
Let's program the required value according to real needs.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

 drivers/usb/host/xhci.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

Comments

Stefan Roese Sept. 22, 2017, 5:11 a.m. UTC | #1
On 18.09.2017 15:40, Bin Meng wrote:
> The 'Max Burst Size' indicates to the xHC the maximum number of
> consecutive USB transactions that should be executed per scheduling
> opportunity. This is a “zero-based” value, where 0 to 15 represents
> burst sizes of 1 to 16, but at present this is always set to zero.
> Let's program the required value according to real needs.
> 
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> ---
> 
>   drivers/usb/host/xhci.c | 21 ++++++++++++++++++++-
>   1 file changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 8aed428..dfb188d 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -395,6 +395,22 @@ static u32 xhci_get_endpoint_mult(struct usb_device *udev,
>   	return ss_ep_comp_desc->bmAttributes;
>   }
>   
> +static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,
> +	struct usb_endpoint_descriptor *endpt_desc,
> +	struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc)
> +{
> +	/* Super speed and Plus have max burst in ep companion desc */
> +	if (udev->speed >= USB_SPEED_SUPER)
> +		return ss_ep_comp_desc->bMaxBurst;
> +
> +	if (udev->speed == USB_SPEED_HIGH &&
> +	    (usb_endpoint_xfer_isoc(endpt_desc) ||
> +	     usb_endpoint_xfer_int(endpt_desc)))
> +		return usb_endpoint_maxp_mult(endpt_desc) - 1;
> +
> +	return 0;
> +}
> +
>   /*
>    * Return the maximum endpoint service interval time (ESIT) payload.
>    * Basically, this is the maxpacket size, multiplied by the burst size
> @@ -493,6 +509,7 @@ static int xhci_set_configuration(struct usb_device *udev)
>   	u32 max_esit_payload;
>   	unsigned int interval;
>   	unsigned int mult;
> +	unsigned int max_burst;
>   	unsigned int avg_trb_len;
>   
>   	out_ctx = virt_dev->out_ctx;
> @@ -545,6 +562,8 @@ static int xhci_set_configuration(struct usb_device *udev)
>   		interval = xhci_get_endpoint_interval(udev, endpt_desc);
>   		mult = xhci_get_endpoint_mult(udev, endpt_desc,
>   					      ss_ep_comp_desc);
> +		max_burst = xhci_get_endpoint_max_burst(udev, endpt_desc,
> +							ss_ep_comp_desc);
>   		avg_trb_len = max_esit_payload;
>   
>   		ep_index = xhci_get_ep_index(endpt_desc);
> @@ -570,7 +589,7 @@ static int xhci_set_configuration(struct usb_device *udev)
>   			(get_unaligned(&endpt_desc->wMaxPacketSize)));
>   
>   		ep_ctx[ep_index]->ep_info2 |=
> -			cpu_to_le32(((0 & MAX_BURST_MASK) << MAX_BURST_SHIFT) |
> +			cpu_to_le32(MAX_BURST(max_burst) |
>   			((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT));
>   
>   		trb_64 = (uintptr_t)
> 

Reviewed-by: Stefan Roese <sr@denx.de>
Tested-by: Stefan Roese <sr@denx.de>

Thanks,
Stefan
diff mbox series

Patch

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 8aed428..dfb188d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -395,6 +395,22 @@  static u32 xhci_get_endpoint_mult(struct usb_device *udev,
 	return ss_ep_comp_desc->bmAttributes;
 }
 
+static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,
+	struct usb_endpoint_descriptor *endpt_desc,
+	struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc)
+{
+	/* Super speed and Plus have max burst in ep companion desc */
+	if (udev->speed >= USB_SPEED_SUPER)
+		return ss_ep_comp_desc->bMaxBurst;
+
+	if (udev->speed == USB_SPEED_HIGH &&
+	    (usb_endpoint_xfer_isoc(endpt_desc) ||
+	     usb_endpoint_xfer_int(endpt_desc)))
+		return usb_endpoint_maxp_mult(endpt_desc) - 1;
+
+	return 0;
+}
+
 /*
  * Return the maximum endpoint service interval time (ESIT) payload.
  * Basically, this is the maxpacket size, multiplied by the burst size
@@ -493,6 +509,7 @@  static int xhci_set_configuration(struct usb_device *udev)
 	u32 max_esit_payload;
 	unsigned int interval;
 	unsigned int mult;
+	unsigned int max_burst;
 	unsigned int avg_trb_len;
 
 	out_ctx = virt_dev->out_ctx;
@@ -545,6 +562,8 @@  static int xhci_set_configuration(struct usb_device *udev)
 		interval = xhci_get_endpoint_interval(udev, endpt_desc);
 		mult = xhci_get_endpoint_mult(udev, endpt_desc,
 					      ss_ep_comp_desc);
+		max_burst = xhci_get_endpoint_max_burst(udev, endpt_desc,
+							ss_ep_comp_desc);
 		avg_trb_len = max_esit_payload;
 
 		ep_index = xhci_get_ep_index(endpt_desc);
@@ -570,7 +589,7 @@  static int xhci_set_configuration(struct usb_device *udev)
 			(get_unaligned(&endpt_desc->wMaxPacketSize)));
 
 		ep_ctx[ep_index]->ep_info2 |=
-			cpu_to_le32(((0 & MAX_BURST_MASK) << MAX_BURST_SHIFT) |
+			cpu_to_le32(MAX_BURST(max_burst) |
 			((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT));
 
 		trb_64 = (uintptr_t)