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? 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