Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78d434a2 authored by Vamsi Krishna Samavedam's avatar Vamsi Krishna Samavedam Committed by Sriharsha Allenki
Browse files

dwc3-msm: Do not resume usb3 phy if max speed is HS only



usb3 phy is needed when core is operating at super speed or
higher. Do not turn on usb3 phy clocks even when core is
programmed to work at high speed only mode. While at it,
remove redundant module parameter to control max speed. Speed
can be controlled using existing sysfs entry.

Example: To set High speed only:
echo "high" > /sys/devices/platform/soc/<devname>/speed

To set super speed:
echo "super" > /sys/devices/platform/soc/<devname>/speed

Change-Id: I24a9a869d97e6efc3ebc0d7a1374805139c65648
Signed-off-by: default avatarVamsi Krishna Samavedam <vskrishn@codeaurora.org>
Signed-off-by: default avatarSriharsha Allenki <sallenki@codeaurora.org>
parent 58a9174f
Loading
Loading
Loading
Loading
+41 −7
Original line number Diff line number Diff line
@@ -239,6 +239,8 @@ struct dwc3_msm {
	struct delayed_work sdp_check;
	bool usb_compliance_mode;
	struct mutex suspend_resume_mutex;

	enum usb_device_speed override_usb_speed;
};

#define USB_HSPHY_3P3_VOL_MIN		3050000 /* uV */
@@ -1574,8 +1576,17 @@ static void dwc3_restart_usb_work(struct work_struct *w)

	mdwc->in_restart = false;
	/* Force reconnect only if cable is still connected */
	if (mdwc->vbus_active)
	if (mdwc->vbus_active) {
		if (mdwc->override_usb_speed) {
			dwc->maximum_speed = mdwc->override_usb_speed;
			dwc->gadget.max_speed = dwc->maximum_speed;
			dbg_event(0xFF, "override_usb_speed",
					mdwc->override_usb_speed);
			mdwc->override_usb_speed = 0;
		}

		dwc3_resume_work(&mdwc->resume_work);
	}

	dwc->err_evt_seen = false;
	flush_delayed_work(&mdwc->sm_work);
@@ -2649,6 +2660,13 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb,
	if (dwc->maximum_speed > dwc->max_hw_supp_speed)
		dwc->maximum_speed = dwc->max_hw_supp_speed;

	if (!id && mdwc->override_usb_speed) {
		dwc->maximum_speed = mdwc->override_usb_speed;
		dbg_event(0xFF, "override_usb_speed",
				mdwc->override_usb_speed);
		mdwc->override_usb_speed = 0;
	}

	if (mdwc->id_state != id) {
		mdwc->id_state = id;
		dbg_event(0xFF, "id_state", mdwc->id_state);
@@ -2833,14 +2851,19 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr,

static DEVICE_ATTR_RW(mode);

/* This node only shows max speed supported dwc3 and it should be
 * same as what is reported in udc/core.c max_speed node. For current
 * operating gadget speed, query current_speed node which is implemented
 * by udc/core.c
 */
static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	return snprintf(buf, PAGE_SIZE, "%s",
			usb_speed_string(dwc->max_hw_supp_speed));
	return snprintf(buf, PAGE_SIZE, "%s\n",
			usb_speed_string(dwc->maximum_speed));
}

static ssize_t speed_store(struct device *dev, struct device_attribute *attr,
@@ -2850,14 +2873,25 @@ static ssize_t speed_store(struct device *dev, struct device_attribute *attr,
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
	enum usb_device_speed req_speed = USB_SPEED_UNKNOWN;

	if (sysfs_streq(buf, "high"))
	/* DEVSPD can only have values SS(0x4), HS(0x0) and FS(0x1).
	 * per 3.20a data book. Allow only these settings. Note that,
	 * xhci does not support full-speed only mode.
	 */
	if (sysfs_streq(buf, "full"))
		req_speed = USB_SPEED_FULL;
	else if (sysfs_streq(buf, "high"))
		req_speed = USB_SPEED_HIGH;
	else if (sysfs_streq(buf, "super"))
		req_speed = USB_SPEED_SUPER;
	else
		return -EINVAL;

	if (req_speed != USB_SPEED_UNKNOWN &&
			req_speed != dwc->max_hw_supp_speed) {
		dwc->maximum_speed = dwc->max_hw_supp_speed = req_speed;
	/* restart usb only works for device mode. Perform manual cable
	 * plug in/out for host mode restart.
	 */
	if (req_speed != dwc->maximum_speed &&
			req_speed <= dwc->max_hw_supp_speed) {
		mdwc->override_usb_speed = req_speed;
		schedule_work(&mdwc->restart_usb_work);
	}