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

Commit a9152646 authored by Vamsi Krishna Samavedam's avatar Vamsi Krishna Samavedam
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>
parent 8e795a3a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -858,6 +858,7 @@ int dwc3_core_init(struct dwc3 *dwc)
	dwc3_frame_length_adjustment(dwc);

	usb_phy_set_suspend(dwc->usb2_phy, 0);
	if (dwc->maximum_speed >= USB_SPEED_SUPER)
		usb_phy_set_suspend(dwc->usb3_phy, 0);
	ret = phy_power_on(dwc->usb2_generic_phy);
	if (ret < 0)
+30 −23
Original line number Diff line number Diff line
@@ -71,11 +71,6 @@ static int cpu_to_affin;
module_param(cpu_to_affin, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(cpu_to_affin, "affin usb irq to this cpu");

/* override for USB speed */
static int override_usb_speed;
module_param(override_usb_speed, int, 0644);
MODULE_PARM_DESC(override_usb_speed, "override for USB speed");

/* XHCI registers */
#define USB3_HCSPARAMS1		(0x4)
#define USB3_PORTSC		(0x420)
@@ -273,6 +268,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 */
@@ -296,14 +293,6 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event);
static int dwc3_restart_usb_host_mode(struct notifier_block *nb,
					unsigned long event, void *ptr);

static inline bool is_valid_usb_speed(struct dwc3 *dwc, int speed)
{

	return (((speed == USB_SPEED_FULL) || (speed == USB_SPEED_HIGH) ||
		(speed == USB_SPEED_SUPER) || (speed == USB_SPEED_SUPER_PLUS))
		&& (speed <= dwc->maximum_speed));
}

/**
 *
 * Read register with debug info.
@@ -2560,7 +2549,7 @@ static void dwc3_resume_work(struct work_struct *w)

	dev_dbg(mdwc->dev, "%s: dwc3 resume work\n", __func__);

	if (mdwc->vbus_active) {
	if (mdwc->vbus_active && !mdwc->in_restart) {
		edev = mdwc->extcon_vbus;
		extcon_id = EXTCON_USB;
	} else if (mdwc->id_state == DWC3_ID_GROUND) {
@@ -2581,10 +2570,12 @@ static void dwc3_resume_work(struct work_struct *w)
		if (dwc->maximum_speed > dwc->max_hw_supp_speed)
			dwc->maximum_speed = dwc->max_hw_supp_speed;

		if (override_usb_speed &&
				is_valid_usb_speed(dwc, override_usb_speed)) {
			dwc->maximum_speed = override_usb_speed;
			dbg_event(0xFF, "override_speed", override_usb_speed);
		if (mdwc->override_usb_speed) {
			dwc->maximum_speed = mdwc->override_usb_speed;
			dwc->gadget.max_speed = dwc->maximum_speed;
			dbg_event(0xFF, "override_speed",
					mdwc->override_usb_speed);
			mdwc->override_usb_speed = 0;
		}

		dbg_event(0xFF, "speed", dwc->maximum_speed);
@@ -3124,6 +3115,11 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR_RW(mode);
static void msm_dwc3_perf_vote_work(struct work_struct *w);

/* 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)
{
@@ -3131,7 +3127,7 @@ static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

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

static ssize_t speed_store(struct device *dev, struct device_attribute *attr,
@@ -3141,14 +3137,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);
	}