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

Commit de87ca32 authored by Ajay Agarwal's avatar Ajay Agarwal
Browse files

usb: dwc3-msm: Add sysfs node to enable SS host compliance



xHCI specs revision 1.1 mentions that if Compliance Transition
Capability (CTC) flag is set, then xHC supports software control
of the transition to Compliance mode. For this, we need to write
a value of 10 to Port Link State(PLS) field of PORTSC register
during dwc3_otg_start_host time after the xhci platform device
has been added. Then the link transitions to compliance state
on detection of first LFPS timeout.

Steps to enable compliance transition:
  1. Do not connect host cable
  2. echo y > /sys/devices/8a00000.ssusb/xhci_link_compliance
  3. Connect host cable with breakout fixture and start testing

Steps to disable compliance transition:
  1. Disconnect the host cable
  2. echo n > /sys/devices/8a00000.ssusb/xhci_link_compliance
  3. Connect host cable

Change-Id: I73225ccad105414d3ebd60f95138b9ecf65005d4
Signed-off-by: default avatarAjay Agarwal <ajaya@codeaurora.org>
parent 9f54d28c
Loading
Loading
Loading
Loading
+60 −2
Original line number Diff line number Diff line
@@ -87,6 +87,8 @@ MODULE_PARM_DESC(dcp_max_current, "max current drawn for DCP charger");

/* XHCI registers */
#define USB3_HCSPARAMS1		(0x4)
#define USB3_HCCPARAMS2		(0x1c)
#define HCC_CTC(p)		((p) & (1 << 3))
#define USB3_PORTSC		(0x420)

/**
@@ -258,6 +260,7 @@ struct dwc3_msm {
	bool			no_wakeup_src_in_hostmode;
	bool			host_only_mode;
	bool			psy_not_used;
	bool			xhci_ss_compliance_enable;

	int  pwr_event_irq;
	atomic_t                in_p3;
@@ -2853,6 +2856,35 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr,

static DEVICE_ATTR_RW(mode);

static ssize_t xhci_link_compliance_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);

	if (mdwc->xhci_ss_compliance_enable)
		return snprintf(buf, PAGE_SIZE, "y\n");
	else
		return snprintf(buf, PAGE_SIZE, "n\n");
}

static ssize_t xhci_link_compliance_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	bool value;
	int ret;

	ret = strtobool(buf, &value);
	if (!ret) {
		mdwc->xhci_ss_compliance_enable = value;
		return count;
	}

	return ret;
}

static DEVICE_ATTR_RW(xhci_link_compliance);

static int dwc3_msm_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node, *dwc3_node;
@@ -3238,13 +3270,16 @@ static int dwc3_msm_probe(struct platform_device *pdev)
		enable_irq_wake(mdwc->pmic_id_irq);
	}

	if (dwc->is_drd)
	if (dwc->is_drd) {
		device_create_file(&pdev->dev, &dev_attr_mode);
		device_create_file(&pdev->dev, &dev_attr_xhci_link_compliance);
	}

	if (!dwc->is_drd && host_mode) {
		dev_dbg(&pdev->dev, "DWC3 in host only mode\n");
		mdwc->host_only_mode = true;
		mdwc->id_state = DWC3_ID_GROUND;
		device_create_file(&pdev->dev, &dev_attr_xhci_link_compliance);
		dwc3_ext_event_notify(mdwc);
	}

@@ -3283,8 +3318,12 @@ static int dwc3_msm_remove(struct platform_device *pdev)
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
	int ret_pm;

	if (dwc->is_drd)
	if (dwc->is_drd) {
		device_remove_file(&pdev->dev, &dev_attr_mode);
		device_remove_file(&pdev->dev, &dev_attr_xhci_link_compliance);
	} else if (mdwc->host_only_mode) {
		device_remove_file(&pdev->dev, &dev_attr_xhci_link_compliance);
	}

	if (cpu_to_affin)
		unregister_cpu_notifier(&mdwc->dwc3_cpu_notifier);
@@ -3541,6 +3580,25 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
			return ret;
		}

		/*
		 * If the Compliance Transition Capability(CTC) flag of
		 * HCCPARAMS2 register is set and xhci_link_compliance sysfs
		 * param has been enabled by the user for the SuperSpeed host
		 * controller, then write 10 (Link in Compliance Mode State)
		 * onto the Port Link State(PLS) field of the PORTSC register
		 * for 3.0 host controller which is at an offset of USB3_PORTSC
		 * + 0x10 from the DWC3 base address. Also, disable the runtime
		 * PM of 3.0 root hub (root hub of shared_hcd of xhci device)
		 */
		if (HCC_CTC(dwc3_msm_read_reg(mdwc->base, USB3_HCCPARAMS2))
				&& mdwc->xhci_ss_compliance_enable
				&& dwc->maximum_speed == USB_SPEED_SUPER) {
			dwc3_msm_write_reg(mdwc->base, USB3_PORTSC + 0x10,
					0x10340);
			pm_runtime_disable(&hcd_to_xhci(platform_get_drvdata(
				dwc->xhci))->shared_hcd->self.root_hub->dev);
		}

		/*
		 * In some cases it is observed that USB PHY is not going into
		 * suspend with host mode suspend functionality. Hence disable