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

Commit 0855ddf8 authored by Sriharsha Allenki's avatar Sriharsha Allenki Committed by Hemant Kumar
Browse files

USB: dwc3: Add support for fixing SS enumeration issue



On some platforms, enabling U1 and U2 modes in SS
mode results in enumeration failures after multiple
cable disconnect and connect. And the device
enumerates in HS mode.
Hence add workaround by adding support to disable
U1 and U2 modes in SS mode on these platforms.

Change-Id: I8668ced09a88b77f37265ab15e89fa9e964bfbe9
Signed-off-by: default avatarSriharsha Allenki <sallenki@codeaurora.org>
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 420c9cb7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ Optional properties:
 - usb-core-id: Differentiates between different controllers present on a device.
 - snps,bus-suspend-enable: If present then controller supports low power mode
	during bus suspend.
 - snps,usb3-u1u2-disable: If present, disable U1U2 low power modes in Superspeed mode

 - in addition all properties from usb-xhci.txt from the current directory are
   supported as well
+2 −0
Original line number Diff line number Diff line
@@ -1136,6 +1136,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
				 &dwc->fladj);
	dwc->enable_bus_suspend = device_property_read_bool(dev,
					"snps,bus-suspend-enable");
	dwc->usb3_u1u2_disable = device_property_read_bool(dev,
					"snps,usb3-u1u2-disable");

	dwc->dis_metastability_quirk = device_property_read_bool(dev,
				"snps,dis_metastability_quirk");
+2 −0
Original line number Diff line number Diff line
@@ -1068,6 +1068,7 @@ struct dwc3_scratchpad_array {
 * 	3	- Reserved
 * @dis_metastability_quirk: set to disable metastability quirk.
 * @err_evt_seen: previous event in queue was erratic error
 * @usb3_u1u2_disable: if true, disable U1U2 low power modes in Superspeed mode
 * @in_lpm: indicates if controller is in low power mode (no clocks)
 * @irq: irq number
 * @irq_cnt: total irq count
@@ -1260,6 +1261,7 @@ struct dwc3 {
	unsigned		tx_de_emphasis:2;
	unsigned		err_evt_seen:1;
	unsigned		enable_bus_suspend:1;
	unsigned		usb3_u1u2_disable:1;

	atomic_t		in_lpm;
	bool			b_suspend;
+21 −7
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -27,6 +28,10 @@
#include "gadget.h"
#include "io.h"

static bool enable_dwc3_u1u2;
module_param(enable_dwc3_u1u2, bool, 0644);
MODULE_PARM_DESC(enable_dwc3_u1u2, "Enable support for U1U2 low power modes");

static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
		struct dwc3_ep *dep, struct dwc3_request *req);
@@ -399,6 +404,9 @@ static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state,
			(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
		return -EINVAL;

	if (dwc->usb3_u1u2_disable && !enable_dwc3_u1u2)
		return -EINVAL;

	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
	if (set)
		reg |= DWC3_DCTL_INITU1ENA;
@@ -421,6 +429,9 @@ static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state,
			(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
		return -EINVAL;

	if (dwc->usb3_u1u2_disable && !enable_dwc3_u1u2)
		return -EINVAL;

	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
	if (set)
		reg |= DWC3_DCTL_INITU2ENA;
@@ -669,14 +680,17 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
				usb_gadget_set_state(&dwc->gadget,
						USB_STATE_CONFIGURED);

			if (!dwc->usb3_u1u2_disable || enable_dwc3_u1u2) {
				/*
				 * Enable transition to U1/U2 state when
				 * nothing is pending from application.
				 */
				reg = dwc3_readl(dwc->regs, DWC3_DCTL);
			reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
				reg |= (DWC3_DCTL_ACCEPTU1ENA |
							DWC3_DCTL_ACCEPTU2ENA);
				dwc3_writel(dwc->regs, DWC3_DCTL, reg);
			}
		}
		break;

	case USB_STATE_CONFIGURED: