Re: [PATCH] xHCI: BESL calculation based on USB2.0 LPM errata

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Feb 18, 2012 at 04:53:13PM +0800, Andiry Xu wrote:
> On 12/12/2011 04:45 PM, Andiry Xu wrote:
> > The latest released errata for USB2.0 ECN LPM adds new fields to USB2.0
> > extension descriptor, defines two BESL values for device: baseline BESL
> > and deep BESL. Baseline BESL value communicates a nominal power savings
> > design point and the deep BESL value communicates a significant power
> > savings design point.
> > 
> > If device indicates BESL value, driver will use a value count in both
> > host BESL and device BESL. Use baseline BESL value as default.
> > 
> > Signed-off-by: Andiry Xu <andiry.xu@xxxxxxx>
> > Tested-by: Jason Fan <jcfan@xxxxxxxxxxxxxxxx>
> 
> Ping. I'm curious about the fate of this patch... Is it lost in the sea
> of mails?

Yeah, sorry, it got lost. :(  I had been meaning to read the USB 2.0 LPM
errata before I commented on this patch, but if you've tested it with
devices that implement the errata, then I can just take it.

Do you have any plans to add the fix for xHCI 1.0 hosts that use the
BESL encoding in the register, rather than the HIRD encoding?

Sarah Sharp

> 
> Thanks,
> Andiry
> 
> > ---
> >  drivers/usb/host/xhci.c |   51
> > ++++++++++++++++++++++++----------------------
> >  include/linux/usb/ch9.h |    5 ++++
> >  2 files changed, 32 insertions(+), 24 deletions(-)
> > 
> > diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> > index a1afb7c..79943ee 100644
> > --- a/drivers/usb/host/xhci.c
> > +++ b/drivers/usb/host/xhci.c
> > @@ -3606,26 +3606,38 @@ static int xhci_besl_encoding[16] = {125, 150,
> > 200, 300, 400, 500, 1000, 2000,
> >  	3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000};
> >  
> >  /* Calculate HIRD/BESL for USB2 PORTPMSC*/
> > -static int xhci_calculate_hird_besl(int u2del, bool use_besl)
> > +static int xhci_calculate_hird_besl(struct xhci_hcd *xhci,
> > +					struct usb_device *udev)
> >  {
> > -	int hird;
> > +	int u2del, besl, besl_host;
> > +	int besl_device = 0;
> > +	u32 field;
> > +
> > +	u2del = HCS_U2_LATENCY(xhci->hcs_params3);
> > +	field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
> >  
> > -	if (use_besl) {
> > -		for (hird = 0; hird < 16; hird++) {
> > -			if (xhci_besl_encoding[hird] >= u2del)
> > +	if (field & USB_BESL_SUPPORT) {
> > +		for (besl_host = 0; besl_host < 16; besl_host++) {
> > +			if (xhci_besl_encoding[besl_host] >= u2del)
> >  				break;
> >  		}
> > +		/* Use baseline BESL value as default */
> > +		if (field & USB_BESL_BASELINE_VALID)
> > +			besl_device = USB_GET_BESL_BASELINE(field);
> > +		else if (field & USB_BESL_DEEP_VALID)
> > +			besl_device = USB_GET_BESL_DEEP(field);
> >  	} else {
> >  		if (u2del <= 50)
> > -			hird = 0;
> > +			besl_host = 0;
> >  		else
> > -			hird = (u2del - 51) / 75 + 1;
> > -
> > -		if (hird > 15)
> > -			hird = 15;
> > +			besl_host = (u2del - 51) / 75 + 1;
> >  	}
> >  
> > -	return hird;
> > +	besl = besl_host + besl_device;
> > +	if (besl > 15)
> > +		besl = 15;
> > +
> > +	return besl;
> >  }
> >  
> >  static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd,
> > @@ -3638,7 +3650,7 @@ static int xhci_usb2_software_lpm_test(struct
> > usb_hcd *hcd,
> >  	u32		temp, dev_id;
> >  	unsigned int	port_num;
> >  	unsigned long	flags;
> > -	int		u2del, hird;
> > +	int		hird;
> >  	int		ret;
> >  
> >  	if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support ||
> > @@ -3684,12 +3696,7 @@ static int xhci_usb2_software_lpm_test(struct
> > usb_hcd *hcd,
> >  	 * HIRD or BESL shoule be used. See USB2.0 LPM errata.
> >  	 */
> >  	pm_addr = port_array[port_num] + 1;
> > -	u2del = HCS_U2_LATENCY(xhci->hcs_params3);
> > -	if (le32_to_cpu(udev->bos->ext_cap->bmAttributes) & (1 << 2))
> > -		hird = xhci_calculate_hird_besl(u2del, 1);
> > -	else
> > -		hird = xhci_calculate_hird_besl(u2del, 0);
> > -
> > +	hird = xhci_calculate_hird_besl(xhci, udev);
> >  	temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird);
> >  	xhci_writel(xhci, temp, pm_addr);
> >  
> > @@ -3768,7 +3775,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd
> > *hcd,
> >  	u32		temp;
> >  	unsigned int	port_num;
> >  	unsigned long	flags;
> > -	int		u2del, hird;
> > +	int		hird;
> >  
> >  	if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support ||
> >  			!udev->lpm_capable)
> > @@ -3791,11 +3798,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd
> > *hcd,
> >  	xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
> >  			enable ? "enable" : "disable", port_num);
> >  
> > -	u2del = HCS_U2_LATENCY(xhci->hcs_params3);
> > -	if (le32_to_cpu(udev->bos->ext_cap->bmAttributes) & (1 << 2))
> > -		hird = xhci_calculate_hird_besl(u2del, 1);
> > -	else
> > -		hird = xhci_calculate_hird_besl(u2del, 0);
> > +	hird = xhci_calculate_hird_besl(xhci, udev);
> >  
> >  	if (enable) {
> >  		temp &= ~PORT_HIRD_MASK;
> > diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
> > index d5da6c6..b94f5ba 100644
> > --- a/include/linux/usb/ch9.h
> > +++ b/include/linux/usb/ch9.h
> > @@ -771,6 +771,11 @@ struct usb_ext_cap_descriptor {		/* Link
> > Power Management */
> >  	__u8  bDevCapabilityType;
> >  	__le32 bmAttributes;
> >  #define USB_LPM_SUPPORT			(1 << 1)	/*
> > supports LPM */
> > +#define USB_BESL_SUPPORT		(1 << 2)	/* supports BESL
> > */
> > +#define USB_BESL_BASELINE_VALID		(1 << 3)	/*
> > Baseline BESL valid*/
> > +#define USB_BESL_DEEP_VALID		(1 << 4)	/* Deep BESL
> > valid */
> > +#define USB_GET_BESL_BASELINE(p)	(((p) & (0xf << 8)) >> 8)
> > +#define USB_GET_BESL_DEEP(p)		(((p) & (0xf << 12)) >> 12)
> >  } __attribute__((packed));
> >  
> >  #define USB_DT_USB_EXT_CAP_SIZE	7
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux