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

Commit 1c3a8722 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: msm-hsusb: Add support for PHY CSR registers"

parents 650a6e11 54627cf6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ Optional properties:
	"tcsr" : top-level CSR register to be written during power-on reset
		 intialize the internal MUX that controls whether this PHY is
		 used with the USB3 or the USB2 controller.
	"phy_csr" : register region that contains additional PHY CSRs that
		    offer additional control apart from the QSCRATCH registers.
		    These handle functions such as controlling the internal
		    reference clock buffer and powering on/off the entire PHY.

 - qcom,hsphy-init: Init value used to override HSPHY parameters into
   QSCRATCH register. This 32-bit value represents parameters as follows:
+81 −1
Original line number Diff line number Diff line
@@ -106,6 +106,20 @@ MODULE_PARM_DESC(override_phy_init, "Override HSPHY Init Seq");
#define TCSR_USB30_CONTROL		BIT(8)
#define TCSR_HSPHY_ARES			BIT(11)

/* USB2PHY CSR register offsets */
#define USB2PHY_HS_PHY_CTRL_COMMON0	(0x78)
#define USB2PHY_COMMONONN		BIT(7)
#define USB2PHY_RETENABLEN		BIT(3)
#define USB2PHY_HS_PHY_CTRL2		(0x90)
#define USB2PHY_SUSPEND_N_SEL		BIT(7)
#define USB2PHY_SUSPEND_N		BIT(6)
#define USB2PHY_USB_PHY_CFG0		(0xC4)
#define USB2PHY_OVERRIDE_EN		(0x7)
#define USB2PHY_USB_PHY_REFCLK_CTRL	(0xE8)
#define REFCLK_RXTAP_EN			BIT(0)
#define USB2PHY_USB_PHY_PWRDOWN_CTRL	(0xEC)
#define PWRDN_B				BIT(0)

#define USB_HSPHY_3P3_VOL_MIN			3050000 /* uV */
#define USB_HSPHY_3P3_VOL_MAX			3300000 /* uV */
#define USB_HSPHY_3P3_HPM_LOAD			16000	/* uA */
@@ -119,6 +133,7 @@ struct msm_hsphy {
	struct usb_phy		phy;
	void __iomem		*base;
	void __iomem		*tcsr;
	void __iomem		*csr;
	int			hsphy_init_seq;
	bool			set_pllbtune;
	u32			core_ver;
@@ -258,7 +273,7 @@ static void msm_usb_write_readback(void *base, u32 offset,
	tmp &= mask;		/* clear other bits */

	if (tmp != val)
		pr_err("%s: write: %x to QSCRATCH: %x FAILED\n",
		pr_err("%s: write: %x to offset(%x) FAILED\n",
			__func__, val, offset);
}

@@ -442,6 +457,34 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
				msm_usb_write_readback(phy->base,
					HS_PHY_CTRL_REG(0),
					RETENABLEN, 0);

			if (phy->csr) {
				/* switch PHY control to USB2PHY CSRs */
				msm_usb_write_readback(phy->csr,
						USB2PHY_USB_PHY_CFG0,
						USB2PHY_OVERRIDE_EN,
						USB2PHY_OVERRIDE_EN);
				/* clear suspend_n */
				msm_usb_write_readback(phy->csr,
						USB2PHY_HS_PHY_CTRL2,
						USB2PHY_SUSPEND_N_SEL |
						USB2PHY_SUSPEND_N,
						USB2PHY_SUSPEND_N_SEL);
				/* enable retention */
				msm_usb_write_readback(phy->csr,
						USB2PHY_HS_PHY_CTRL_COMMON0,
						USB2PHY_COMMONONN |
						USB2PHY_RETENABLEN, 0);
				/* disable internal ref clock buffer */
				msm_usb_write_readback(phy->csr,
						USB2PHY_USB_PHY_REFCLK_CTRL,
						REFCLK_RXTAP_EN, 0);
				/* power down PHY */
				msm_usb_write_readback(phy->csr,
						USB2PHY_USB_PHY_PWRDOWN_CTRL,
						PWRDN_B, 0);
			}

			phy->lpm_flags |= PHY_RETENTIONED;
		}

@@ -469,6 +512,33 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
				phy->lpm_flags &= ~PHY_PWR_COLLAPSED;
			}

			if (phy->csr) {
				/* power on PHY */
				msm_usb_write_readback(phy->csr,
						USB2PHY_USB_PHY_PWRDOWN_CTRL,
						PWRDN_B, PWRDN_B);
				/* enable internal ref clock buffer */
				msm_usb_write_readback(phy->csr,
						USB2PHY_USB_PHY_REFCLK_CTRL,
						REFCLK_RXTAP_EN,
						REFCLK_RXTAP_EN);
				/* disable retention */
				msm_usb_write_readback(phy->csr,
						USB2PHY_HS_PHY_CTRL_COMMON0,
						USB2PHY_COMMONONN |
						USB2PHY_RETENABLEN,
						USB2PHY_COMMONONN |
						USB2PHY_RETENABLEN);
				/* switch suspend_n_sel back to HW */
				msm_usb_write_readback(phy->csr,
						USB2PHY_HS_PHY_CTRL2,
						USB2PHY_SUSPEND_N_SEL |
						USB2PHY_SUSPEND_N, 0);
				msm_usb_write_readback(phy->csr,
						USB2PHY_USB_PHY_CFG0,
						USB2PHY_OVERRIDE_EN, 0);
			}

			/* Disable PHY retention */
			if (phy->core_ver == MSM_CORE_VER_120 &&
					phy->set_pllbtune)
@@ -691,6 +761,16 @@ static int msm_hsphy_probe(struct platform_device *pdev)
				phy->tcsr);
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_csr");
	if (res) {
		phy->csr = devm_ioremap_nocache(dev, res->start,
						 resource_size(res));
		if (!phy->csr) {
			dev_err(dev, "phy_csr ioremap failed\n");
			return -ENODEV;
		}
	}

	if (of_get_property(dev->of_node, "qcom,primary-phy", NULL)) {
		dev_dbg(dev, "secondary HSPHY\n");
		phy->phy.flags |= ENABLE_SECONDARY_PHY;