Skip to contentSkip to conversation

usb: gadget: Report recommended BESL

PATCH New Thinh Nguyen 1 participant 5 messages Aug 20, 2019

Subsystems (2)
lore
Share & tools
lore

Thinh Nguyen

author maintainer
#0 lore raw

cover usb: gadget: Report recommended BESL

This patch series add an option for the gadget driver to export recommended BESL value to improve power saving for devices operating with LPM feature.

Thinh Nguyen (4):
usb: gadget: Export recommended BESL values
usb: dwc3: Separate field holding multiple properties
usb: dwc3: gadget: Set BESL config parameter
usb: gadget: composite: Set recommended BESL values

 drivers/usb/dwc3/core.c        |  3 +--
 drivers/usb/dwc3/gadget.c      | 13 ++++++++++++-
 drivers/usb/gadget/composite.c | 38 ++++++++++++++++++++++++++------------
 include/linux/usb/gadget.h     |  3 +++
 include/uapi/linux/usb/ch9.h   |  2 ++
 5 files changed, 44 insertions(+), 15 deletions(-)
Signature · 1 line
2.11.0
author maintainer
#1 lore raw

PATCH 1/4 usb: gadget: Export recommended BESL values

Currently there's no option for the controller driver to report the recommended Best Effort Service Latency (BESL) when operating with LPM support. Add new fields in usb_dcd_config_params to export the recommended baseline and deep BESL values for the function drivers to set the proper BESL value in the BOS descriptor.

---
 include/linux/usb/gadget.h | 3 +++
 1 file changed, 3 insertions(+)
include/linux/usb/gadget.h +3 -0
index fb19141151d8..124462d65eac 100644
@@ -291,6 +291,9 @@ struct usb_dcd_config_params {
 #define USB_DEFAULT_U1_DEV_EXIT_LAT	0x01	/* Less then 1 microsec */
 	__le16 bU2DevExitLat;	/* U2 Device exit Latency */
 #define USB_DEFAULT_U2_DEV_EXIT_LAT	0x1F4	/* Less then 500 microsec */
+	__u8 besl_baseline;	/* Recommended baseline BESL (0-15) */
+	__u8 besl_deep;		/* Recommended deep BESL (0-15) */
+#define USB_DEFAULT_BESL_UNSPECIFIED	0xFF	/* No recommended value */
 };
 
 
Signature · 1 line
2.11.0
author maintainer
#2 lore raw

PATCH 2/4 usb: dwc3: Separate field holding multiple properties

In reply to Thinh Nguyen

dwc->hird_threshold field should store "snps,hird_threshold" property only and not a combination of multiple properties. Remove the value of "snps,is-utmi-l1-suspend" property from the field dwc->hird_threshold.

---
 drivers/usb/dwc3/core.c   | 3 +--
 drivers/usb/dwc3/gadget.c | 3 ++-
 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/usb/dwc3/core.c +1 -2
index 30ebf3c65a63..f56d5058a66c 100644
@@ -1321,8 +1321,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 	dwc->lpm_nyet_threshold = lpm_nyet_threshold;
 	dwc->tx_de_emphasis = tx_de_emphasis;
 
-	dwc->hird_threshold = hird_threshold
-		| (dwc->is_utmi_l1_suspend << 4);
+	dwc->hird_threshold = hird_threshold;
 
 	dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd;
 	dwc->rx_max_burst_prd = rx_max_burst_prd;
drivers/usb/dwc3/gadget.c +2 -1
index 173f5329d3d9..afc2ddb080ae 100644
@@ -2868,7 +2868,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 		reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);
 
-		reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_threshold);
+		reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_threshold |
+					    (dwc->is_utmi_l1_suspend << 4));
 
 		/*
 		 * When dwc3 revisions >= 2.40a, LPM Erratum is enabled and
Signature · 1 line
2.11.0
author maintainer
#3 lore raw

PATCH 3/4 usb: dwc3: gadget: Set BESL config parameter

In reply to Thinh Nguyen

When operating with LPM signals, the controller asserts the deep low-power signal (utmi_l1_suspend_n) to the phy when the BESL value of the LPM token is equal to or greater than DCTL.HIRD_Thres[3:0] (and with DCTL.HIRD_Thres[4] set). Otherwise, the shallow low-power signal (utmi_sleep_n) is asserted. Set the recommended deep BESL equal to the controller's DCTL.HIRD_Thres[3:0] setting, and set the baseline BESL to 0 for the shallow low-power signal. This maximizes the opportunity for L1 residency and optimizes power savings.

---
 drivers/usb/dwc3/gadget.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/usb/dwc3/gadget.c +10 -0
index afc2ddb080ae..8ac024c5147a 100644
@@ -2078,6 +2078,16 @@ static void dwc3_gadget_config_params(struct usb_gadget *g,
 {
 	struct dwc3		*dwc = gadget_to_dwc(g);
 
+	params->besl_baseline = USB_DEFAULT_BESL_UNSPECIFIED;
+	params->besl_deep = USB_DEFAULT_BESL_UNSPECIFIED;
+
+	/* Recommended BESL */
+	if (!dwc->dis_enblslpm_quirk) {
+		params->besl_baseline = 0;
+		if (dwc->is_utmi_l1_suspend)
+			params->besl_deep = min_t(u8, dwc->hird_threshold, 15);
+	}
+
 	/* U1 Device exit Latency */
 	if (dwc->dis_u1_entry_quirk)
 		params->bU1devExitLat = 0;
Signature · 1 line
2.11.0
author maintainer
#4 lore raw

PATCH 4/4 usb: gadget: composite: Set recommended BESL values

In reply to Thinh Nguyen

Set the recommended BESL deep and baseline values based on the gadget's configuration parameters to the extended BOS descriptor. This feature helps to optimize power savings by maximizing the opportunity for longer L1 residency time.

---
 drivers/usb/gadget/composite.c | 38 ++++++++++++++++++++++++++------------
 include/uapi/linux/usb/ch9.h   |  2 ++
 2 files changed, 28 insertions(+), 12 deletions(-)
drivers/usb/gadget/composite.c +26 -12
index 9118b42c70b6..7ed009dc0f92 100644
@@ -612,6 +612,7 @@ static int bos_desc(struct usb_composite_dev *cdev)
 	struct usb_ext_cap_descriptor	*usb_ext;
 	struct usb_dcd_config_params	dcd_config_params;
 	struct usb_bos_descriptor	*bos = cdev->req->buf;
+	unsigned int			besl = 0;
 
 	bos->bLength = USB_DT_BOS_SIZE;
 	bos->bDescriptorType = USB_DT_BOS;
@@ -619,6 +620,29 @@ static int bos_desc(struct usb_composite_dev *cdev)
 	bos->wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE);
 	bos->bNumDeviceCaps = 0;
 
+	/* Get Controller configuration */
+	if (cdev->gadget->ops->get_config_params) {
+		cdev->gadget->ops->get_config_params(cdev->gadget,
+						     &dcd_config_params);
+	} else {
+		dcd_config_params.besl_baseline =
+			USB_DEFAULT_BESL_UNSPECIFIED;
+		dcd_config_params.besl_deep =
+			USB_DEFAULT_BESL_UNSPECIFIED;
+		dcd_config_params.bU1devExitLat =
+			USB_DEFAULT_U1_DEV_EXIT_LAT;
+		dcd_config_params.bU2DevExitLat =
+			cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT);
+	}
+
+	if (dcd_config_params.besl_baseline != USB_DEFAULT_BESL_UNSPECIFIED)
+		besl = USB_BESL_BASELINE_VALID |
+			USB_SET_BESL_BASELINE(dcd_config_params.besl_baseline);
+
+	if (dcd_config_params.besl_deep != USB_DEFAULT_BESL_UNSPECIFIED)
+		besl |= USB_BESL_DEEP_VALID |
+			USB_SET_BESL_DEEP(dcd_config_params.besl_deep);
+
 	/*
 	 * A SuperSpeed device shall include the USB2.0 extension descriptor
 	 * and shall support LPM when operating in USB2.0 HS mode.
@@ -629,7 +653,8 @@ static int bos_desc(struct usb_composite_dev *cdev)
 	usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE;
 	usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
 	usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT;
-	usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | USB_BESL_SUPPORT);
+	usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT |
+					    USB_BESL_SUPPORT | besl);
 
 	/*
 	 * The Superspeed USB Capability descriptor shall be implemented by all
@@ -650,17 +675,6 @@ static int bos_desc(struct usb_composite_dev *cdev)
 						      USB_HIGH_SPEED_OPERATION |
 						      USB_5GBPS_OPERATION);
 		ss_cap->bFunctionalitySupport = USB_LOW_SPEED_OPERATION;
-
-		/* Get Controller configuration */
-		if (cdev->gadget->ops->get_config_params) {
-			cdev->gadget->ops->get_config_params(cdev->gadget,
-				&dcd_config_params);
-		} else {
-			dcd_config_params.bU1devExitLat =
-				USB_DEFAULT_U1_DEV_EXIT_LAT;
-			dcd_config_params.bU2DevExitLat =
-				cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT);
-		}
 		ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat;
 		ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat;
 	}
include/uapi/linux/usb/ch9.h +2 -0
index d5a5caec8fbc..2b623f36af6b 100644
@@ -894,6 +894,8 @@ struct usb_ext_cap_descriptor {		/* Link Power Management */
 #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_SET_BESL_BASELINE(p)	(((p) & 0xf) << 8)
+#define USB_SET_BESL_DEEP(p)		(((p) & 0xf) << 12)
 #define USB_GET_BESL_BASELINE(p)	(((p) & (0xf << 8)) >> 8)
 #define USB_GET_BESL_DEEP(p)		(((p) & (0xf << 12)) >> 12)
 } __attribute__((packed));
Signature · 1 line
2.11.0