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

Commit 74e1a426 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: phy: Add autonomous mode support for QMP SS PHY"

parents 383ef204 d2602d71
Loading
Loading
Loading
Loading
+48 −9
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@
#define PCIE_USB3_PHY_START			0x608
#define PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL	0x64C
#define PCIE_USB3_PHY_POWER_STATE_CONFIG2	0x654
#define PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL	0x6BC

#define PCIE_USB3_PHY_PCS_STATUS		0x728

@@ -86,6 +87,11 @@

#define INIT_MAX_TIME_USEC			1000

/* PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL bits */
#define ARCVR_DTCT_EN		BIT(0)
#define ALFPS_DTCT_EN		BIT(1)
#define ARCVR_DTCT_EVENT_SEL	BIT(4)


struct msm_ssphy_qmp {
	struct usb_phy		phy;
@@ -102,6 +108,30 @@ struct msm_ssphy_qmp {
	bool			suspend_allowed;
};

static void msm_ssusb_qmp_enable_autonomous(struct msm_ssphy_qmp *phy,
					  bool detached)
{
	u8 val;

	dev_dbg(phy->phy.dev, "enabling QMP autonomous mode with cable %s\n",
			(detached ? "detached" : "attached"));
	val = readb_relaxed(phy->base + PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL);

	val |= ARCVR_DTCT_EN;
	if (!detached) {
		val |= ALFPS_DTCT_EN;
		/* Detect detach */
		val &= ~ARCVR_DTCT_EVENT_SEL;
	} else {
		val &= ~ALFPS_DTCT_EN;
		/* Detect attach */
		val |= ARCVR_DTCT_EVENT_SEL;
	}

	writeb_relaxed(val, phy->base + PCIE_USB3_PHY_AUTONOMOUS_MODE_CTRL);
}


static int msm_ssusb_qmp_config_vdd(struct msm_ssphy_qmp *phy, int high)
{
	int min, ret;
@@ -114,7 +144,7 @@ static int msm_ssusb_qmp_config_vdd(struct msm_ssphy_qmp *phy, int high)
		return ret;
	}

	dev_dbg(phy->phy.dev, "%s: min_vol:%d max_vol:%d\n", __func__,
	dev_dbg(phy->phy.dev, "min_vol:%d max_vol:%d\n",
		phy->vdd_levels[min], phy->vdd_levels[2]);
	return ret;
}
@@ -238,7 +268,7 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy)
	int ret;
	unsigned init_timeout_usec = INIT_MAX_TIME_USEC;

	dev_dbg(uphy->dev, "%s\n", __func__);
	dev_dbg(uphy->dev, "Initializing QMP phy\n");

	if (!phy->clk_enabled) {
		ret = msm_ssphy_qmp_init_clocks(phy);
@@ -330,7 +360,7 @@ static int msm_ssphy_qmp_reset(struct usb_phy *uphy)
					phy);
	int ret;

	dev_dbg(uphy->dev, "%s\n", __func__);
	dev_dbg(uphy->dev, "Resetting QMP phy\n");

	if (!phy->clk_enabled) {
		ret = msm_ssphy_qmp_init_clocks(phy);
@@ -386,7 +416,7 @@ deassert_phy_com_reset:

static int msm_ssphy_qmp_set_params(struct usb_phy *uphy)
{
	dev_dbg(uphy->dev, "%s\n", __func__);
	dev_dbg(uphy->dev, "Setting phy parameters\n");
	return 0;
}

@@ -402,24 +432,30 @@ static int msm_ssphy_qmp_set_suspend(struct usb_phy *uphy, int suspend)
	struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp,
					phy);

	dev_dbg(uphy->dev, "%s: suspend state: current :%d new:%d\n",
				__func__, phy->suspend_allowed, suspend);
	dev_dbg(uphy->dev, "suspend state: current :%d new:%d\n",
				phy->suspend_allowed, suspend);

	if (!!suspend == phy->suspend_allowed) {
		pr_debug("%s(): USB PHY is already suspended.\n", __func__);
		pr_debug("USB PHY is already suspended.\n");
		return 0;
	}

	if (suspend) {
		msm_ssusb_qmp_enable_autonomous(phy, false);
		clk_disable_unprepare(phy->pipe_clk);
		clk_disable_unprepare(phy->cfg_ahb_clk);
		clk_disable_unprepare(phy->aux_clk);
		phy->suspend_allowed = true;
		dev_dbg(uphy->dev, "suspend_allowed=%d\n",
				phy->suspend_allowed);
	} else {
		clk_prepare_enable(phy->aux_clk);
		clk_prepare_enable(phy->cfg_ahb_clk);
		clk_prepare_enable(phy->pipe_clk);
		msm_ssusb_qmp_enable_autonomous(phy, false);
		phy->suspend_allowed = false;
		dev_dbg(uphy->dev, "suspend_allowed=%d\n",
				phy->suspend_allowed);
	}

	return 0;
@@ -431,8 +467,9 @@ static int msm_ssphy_qmp_notify_connect(struct usb_phy *uphy,
	struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp,
					phy);

	dev_dbg(uphy->dev, "%s\n", __func__);
	dev_dbg(uphy->dev, "QMP phy connect notification\n");
	phy->suspend_allowed = true;
	dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed);
	return 0;
}

@@ -442,8 +479,10 @@ static int msm_ssphy_qmp_notify_disconnect(struct usb_phy *uphy,
	struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp,
					phy);

	dev_dbg(uphy->dev, "%s\n", __func__);
	dev_dbg(uphy->dev, "QMP phy disconnect notification\n");
	phy->suspend_allowed = false;
	dev_dbg(uphy->dev, "suspend_allowed=%d\n", phy->suspend_allowed);
	msm_ssusb_qmp_enable_autonomous(phy, true);
	return 0;
}