xref: /linux/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c (revision 7559e7572c03e433efec7734af6a674fdd83dd68)
180090810SAbel Vesa // SPDX-License-Identifier: GPL-2.0
280090810SAbel Vesa /*
380090810SAbel Vesa  * Copyright (c) 2023, Linaro Limited
480090810SAbel Vesa  */
580090810SAbel Vesa 
6037d05afSVinod Koul #include <linux/bitfield.h>
780090810SAbel Vesa #include <linux/clk.h>
880090810SAbel Vesa #include <linux/delay.h>
9037d05afSVinod Koul #include <linux/iopoll.h>
10*7559e757SRob Herring #include <linux/mod_devicetable.h>
1180090810SAbel Vesa #include <linux/phy/phy.h>
1280090810SAbel Vesa #include <linux/platform_device.h>
1380090810SAbel Vesa #include <linux/regulator/consumer.h>
1480090810SAbel Vesa #include <linux/reset.h>
1580090810SAbel Vesa 
1680090810SAbel Vesa #define USB_PHY_UTMI_CTRL0		(0x3c)
1780090810SAbel Vesa #define SLEEPM				BIT(0)
1880090810SAbel Vesa #define OPMODE_MASK			GENMASK(4, 3)
1980090810SAbel Vesa #define OPMODE_NONDRIVING		BIT(3)
2080090810SAbel Vesa 
2180090810SAbel Vesa #define USB_PHY_UTMI_CTRL5		(0x50)
2280090810SAbel Vesa #define POR				BIT(1)
2380090810SAbel Vesa 
2480090810SAbel Vesa #define USB_PHY_HS_PHY_CTRL_COMMON0	(0x54)
2580090810SAbel Vesa #define PHY_ENABLE			BIT(0)
2680090810SAbel Vesa #define SIDDQ_SEL			BIT(1)
2780090810SAbel Vesa #define SIDDQ				BIT(2)
2880090810SAbel Vesa #define RETENABLEN			BIT(3)
2980090810SAbel Vesa #define FSEL_MASK			GENMASK(6, 4)
3080090810SAbel Vesa #define FSEL_19_2_MHZ_VAL		(0x0)
3180090810SAbel Vesa #define FSEL_38_4_MHZ_VAL		(0x4)
3280090810SAbel Vesa 
3380090810SAbel Vesa #define USB_PHY_CFG_CTRL_1		(0x58)
3480090810SAbel Vesa #define PHY_CFG_PLL_CPBIAS_CNTRL_MASK	GENMASK(7, 1)
3580090810SAbel Vesa 
3680090810SAbel Vesa #define USB_PHY_CFG_CTRL_2		(0x5c)
3780090810SAbel Vesa #define PHY_CFG_PLL_FB_DIV_7_0_MASK	GENMASK(7, 0)
3880090810SAbel Vesa #define DIV_7_0_19_2_MHZ_VAL		(0x90)
3980090810SAbel Vesa #define DIV_7_0_38_4_MHZ_VAL		(0xc8)
4080090810SAbel Vesa 
4180090810SAbel Vesa #define USB_PHY_CFG_CTRL_3		(0x60)
4280090810SAbel Vesa #define PHY_CFG_PLL_FB_DIV_11_8_MASK	GENMASK(3, 0)
4380090810SAbel Vesa #define DIV_11_8_19_2_MHZ_VAL		(0x1)
4480090810SAbel Vesa #define DIV_11_8_38_4_MHZ_VAL		(0x0)
4580090810SAbel Vesa 
4680090810SAbel Vesa #define PHY_CFG_PLL_REF_DIV		GENMASK(7, 4)
4780090810SAbel Vesa #define PLL_REF_DIV_VAL			(0x0)
4880090810SAbel Vesa 
4980090810SAbel Vesa #define USB_PHY_HS_PHY_CTRL2		(0x64)
5080090810SAbel Vesa #define VBUSVLDEXT0			BIT(0)
5180090810SAbel Vesa #define USB2_SUSPEND_N			BIT(2)
5280090810SAbel Vesa #define USB2_SUSPEND_N_SEL		BIT(3)
5380090810SAbel Vesa #define VBUS_DET_EXT_SEL		BIT(4)
5480090810SAbel Vesa 
5580090810SAbel Vesa #define USB_PHY_CFG_CTRL_4		(0x68)
5680090810SAbel Vesa #define PHY_CFG_PLL_GMP_CNTRL_MASK	GENMASK(1, 0)
5780090810SAbel Vesa #define PHY_CFG_PLL_INT_CNTRL_MASK	GENMASK(7, 2)
5880090810SAbel Vesa 
5980090810SAbel Vesa #define USB_PHY_CFG_CTRL_5		(0x6c)
6080090810SAbel Vesa #define PHY_CFG_PLL_PROP_CNTRL_MASK	GENMASK(4, 0)
6180090810SAbel Vesa #define PHY_CFG_PLL_VREF_TUNE_MASK	GENMASK(7, 6)
6280090810SAbel Vesa 
6380090810SAbel Vesa #define USB_PHY_CFG_CTRL_6		(0x70)
6480090810SAbel Vesa #define PHY_CFG_PLL_VCO_CNTRL_MASK	GENMASK(2, 0)
6580090810SAbel Vesa 
6680090810SAbel Vesa #define USB_PHY_CFG_CTRL_7		(0x74)
6780090810SAbel Vesa 
6880090810SAbel Vesa #define USB_PHY_CFG_CTRL_8		(0x78)
6980090810SAbel Vesa #define PHY_CFG_TX_FSLS_VREF_TUNE_MASK	GENMASK(1, 0)
7080090810SAbel Vesa #define PHY_CFG_TX_FSLS_VREG_BYPASS	BIT(2)
7180090810SAbel Vesa #define PHY_CFG_TX_HS_VREF_TUNE_MASK	GENMASK(5, 3)
7280090810SAbel Vesa #define PHY_CFG_TX_HS_XV_TUNE_MASK	GENMASK(7, 6)
7380090810SAbel Vesa 
7480090810SAbel Vesa #define USB_PHY_CFG_CTRL_9		(0x7c)
7580090810SAbel Vesa #define PHY_CFG_TX_PREEMP_TUNE_MASK	GENMASK(2, 0)
7680090810SAbel Vesa #define PHY_CFG_TX_RES_TUNE_MASK	GENMASK(4, 3)
7780090810SAbel Vesa #define PHY_CFG_TX_RISE_TUNE_MASK	GENMASK(6, 5)
7880090810SAbel Vesa #define PHY_CFG_RCAL_BYPASS		BIT(7)
7980090810SAbel Vesa 
8080090810SAbel Vesa #define USB_PHY_CFG_CTRL_10		(0x80)
8180090810SAbel Vesa 
8280090810SAbel Vesa #define USB_PHY_CFG0			(0x94)
8380090810SAbel Vesa #define DATAPATH_CTRL_OVERRIDE_EN	BIT(0)
8480090810SAbel Vesa #define CMN_CTRL_OVERRIDE_EN		BIT(1)
8580090810SAbel Vesa 
8680090810SAbel Vesa #define UTMI_PHY_CMN_CTRL0		(0x98)
8780090810SAbel Vesa #define TESTBURNIN			BIT(6)
8880090810SAbel Vesa 
8980090810SAbel Vesa #define USB_PHY_FSEL_SEL		(0xb8)
9080090810SAbel Vesa #define FSEL_SEL			BIT(0)
9180090810SAbel Vesa 
9280090810SAbel Vesa #define USB_PHY_APB_ACCESS_CMD		(0x130)
9380090810SAbel Vesa #define RW_ACCESS			BIT(0)
9480090810SAbel Vesa #define APB_START_CMD			BIT(1)
9580090810SAbel Vesa #define APB_LOGIC_RESET			BIT(2)
9680090810SAbel Vesa 
9780090810SAbel Vesa #define USB_PHY_APB_ACCESS_STATUS	(0x134)
9880090810SAbel Vesa #define ACCESS_DONE			BIT(0)
9980090810SAbel Vesa #define TIMED_OUT			BIT(1)
10080090810SAbel Vesa #define ACCESS_ERROR			BIT(2)
10180090810SAbel Vesa #define ACCESS_IN_PROGRESS		BIT(3)
10280090810SAbel Vesa 
10380090810SAbel Vesa #define USB_PHY_APB_ADDRESS		(0x138)
10480090810SAbel Vesa #define APB_REG_ADDR_MASK		GENMASK(7, 0)
10580090810SAbel Vesa 
10680090810SAbel Vesa #define USB_PHY_APB_WRDATA_LSB		(0x13c)
10780090810SAbel Vesa #define APB_REG_WRDATA_7_0_MASK		GENMASK(3, 0)
10880090810SAbel Vesa 
10980090810SAbel Vesa #define USB_PHY_APB_WRDATA_MSB		(0x140)
11080090810SAbel Vesa #define APB_REG_WRDATA_15_8_MASK	GENMASK(7, 4)
11180090810SAbel Vesa 
11280090810SAbel Vesa #define USB_PHY_APB_RDDATA_LSB		(0x144)
11380090810SAbel Vesa #define APB_REG_RDDATA_7_0_MASK		GENMASK(3, 0)
11480090810SAbel Vesa 
11580090810SAbel Vesa #define USB_PHY_APB_RDDATA_MSB		(0x148)
11680090810SAbel Vesa #define APB_REG_RDDATA_15_8_MASK	GENMASK(7, 4)
11780090810SAbel Vesa 
11880090810SAbel Vesa static const char * const eusb2_hsphy_vreg_names[] = {
11980090810SAbel Vesa 	"vdd", "vdda12",
12080090810SAbel Vesa };
12180090810SAbel Vesa 
12280090810SAbel Vesa #define EUSB2_NUM_VREGS		ARRAY_SIZE(eusb2_hsphy_vreg_names)
12380090810SAbel Vesa 
12480090810SAbel Vesa struct qcom_snps_eusb2_hsphy {
12580090810SAbel Vesa 	struct phy *phy;
12680090810SAbel Vesa 	void __iomem *base;
12780090810SAbel Vesa 
12880090810SAbel Vesa 	struct clk *ref_clk;
12980090810SAbel Vesa 	struct reset_control *phy_reset;
13080090810SAbel Vesa 
13180090810SAbel Vesa 	struct regulator_bulk_data vregs[EUSB2_NUM_VREGS];
13280090810SAbel Vesa 
13380090810SAbel Vesa 	enum phy_mode mode;
1343584f639SNeil Armstrong 
1353584f639SNeil Armstrong 	struct phy *repeater;
13680090810SAbel Vesa };
13780090810SAbel Vesa 
13880090810SAbel Vesa static int qcom_snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode)
13980090810SAbel Vesa {
14080090810SAbel Vesa 	struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
14180090810SAbel Vesa 
14280090810SAbel Vesa 	phy->mode = mode;
14380090810SAbel Vesa 
1443584f639SNeil Armstrong 	return phy_set_mode_ext(phy->repeater, mode, submode);
14580090810SAbel Vesa }
14680090810SAbel Vesa 
14780090810SAbel Vesa static void qcom_snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset,
14880090810SAbel Vesa 					     u32 mask, u32 val)
14980090810SAbel Vesa {
15080090810SAbel Vesa 	u32 reg;
15180090810SAbel Vesa 
15280090810SAbel Vesa 	reg = readl_relaxed(base + offset);
15380090810SAbel Vesa 	reg &= ~mask;
15480090810SAbel Vesa 	reg |= val & mask;
15580090810SAbel Vesa 	writel_relaxed(reg, base + offset);
15680090810SAbel Vesa 
15780090810SAbel Vesa 	/* Ensure above write is completed */
15880090810SAbel Vesa 	readl_relaxed(base + offset);
15980090810SAbel Vesa }
16080090810SAbel Vesa 
16180090810SAbel Vesa static void qcom_eusb2_default_parameters(struct qcom_snps_eusb2_hsphy *phy)
16280090810SAbel Vesa {
16380090810SAbel Vesa 	/* default parameters: tx pre-emphasis */
16480090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
16580090810SAbel Vesa 					 PHY_CFG_TX_PREEMP_TUNE_MASK,
16680090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0));
16780090810SAbel Vesa 
16880090810SAbel Vesa 	/* tx rise/fall time */
16980090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
17080090810SAbel Vesa 					 PHY_CFG_TX_RISE_TUNE_MASK,
17180090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2));
17280090810SAbel Vesa 
17380090810SAbel Vesa 	/* source impedance adjustment */
17480090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
17580090810SAbel Vesa 					 PHY_CFG_TX_RES_TUNE_MASK,
17680090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1));
17780090810SAbel Vesa 
17880090810SAbel Vesa 	/* dc voltage level adjustement */
17980090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8,
18080090810SAbel Vesa 					 PHY_CFG_TX_HS_VREF_TUNE_MASK,
18180090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3));
18280090810SAbel Vesa 
18380090810SAbel Vesa 	/* transmitter HS crossover adjustement */
18480090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8,
18580090810SAbel Vesa 					 PHY_CFG_TX_HS_XV_TUNE_MASK,
18680090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0));
18780090810SAbel Vesa }
18880090810SAbel Vesa 
18980090810SAbel Vesa static int qcom_eusb2_ref_clk_init(struct qcom_snps_eusb2_hsphy *phy)
19080090810SAbel Vesa {
19180090810SAbel Vesa 	unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk);
19280090810SAbel Vesa 
19380090810SAbel Vesa 	switch (ref_clk_freq) {
19480090810SAbel Vesa 	case 19200000:
19580090810SAbel Vesa 		qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
19680090810SAbel Vesa 						 FSEL_MASK,
19780090810SAbel Vesa 						 FIELD_PREP(FSEL_MASK, FSEL_19_2_MHZ_VAL));
19880090810SAbel Vesa 
19980090810SAbel Vesa 		qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2,
20080090810SAbel Vesa 						 PHY_CFG_PLL_FB_DIV_7_0_MASK,
20180090810SAbel Vesa 						 DIV_7_0_19_2_MHZ_VAL);
20280090810SAbel Vesa 
20380090810SAbel Vesa 		qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
20480090810SAbel Vesa 						 PHY_CFG_PLL_FB_DIV_11_8_MASK,
20580090810SAbel Vesa 						 DIV_11_8_19_2_MHZ_VAL);
20680090810SAbel Vesa 		break;
20780090810SAbel Vesa 
20880090810SAbel Vesa 	case 38400000:
20980090810SAbel Vesa 		qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
21080090810SAbel Vesa 						 FSEL_MASK,
21180090810SAbel Vesa 						 FIELD_PREP(FSEL_MASK, FSEL_38_4_MHZ_VAL));
21280090810SAbel Vesa 
21380090810SAbel Vesa 		qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2,
21480090810SAbel Vesa 						 PHY_CFG_PLL_FB_DIV_7_0_MASK,
21580090810SAbel Vesa 						 DIV_7_0_38_4_MHZ_VAL);
21680090810SAbel Vesa 
21780090810SAbel Vesa 		qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
21880090810SAbel Vesa 						 PHY_CFG_PLL_FB_DIV_11_8_MASK,
21980090810SAbel Vesa 						 DIV_11_8_38_4_MHZ_VAL);
22080090810SAbel Vesa 		break;
22180090810SAbel Vesa 
22280090810SAbel Vesa 	default:
22380090810SAbel Vesa 		dev_err(&phy->phy->dev, "unsupported ref_clk_freq:%lu\n", ref_clk_freq);
22480090810SAbel Vesa 		return -EINVAL;
22580090810SAbel Vesa 	}
22680090810SAbel Vesa 
22780090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
22880090810SAbel Vesa 					 PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL);
22980090810SAbel Vesa 
23080090810SAbel Vesa 	return 0;
23180090810SAbel Vesa }
23280090810SAbel Vesa 
23380090810SAbel Vesa static int qcom_snps_eusb2_hsphy_init(struct phy *p)
23480090810SAbel Vesa {
23580090810SAbel Vesa 	struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
23680090810SAbel Vesa 	int ret;
23780090810SAbel Vesa 
23880090810SAbel Vesa 	ret = regulator_bulk_enable(ARRAY_SIZE(phy->vregs), phy->vregs);
23980090810SAbel Vesa 	if (ret)
24080090810SAbel Vesa 		return ret;
24180090810SAbel Vesa 
2423584f639SNeil Armstrong 	ret = phy_init(phy->repeater);
2433584f639SNeil Armstrong 	if (ret) {
2443584f639SNeil Armstrong 		dev_err(&p->dev, "repeater init failed. %d\n", ret);
2453584f639SNeil Armstrong 		goto disable_vreg;
2463584f639SNeil Armstrong 	}
2473584f639SNeil Armstrong 
24880090810SAbel Vesa 	ret = clk_prepare_enable(phy->ref_clk);
24980090810SAbel Vesa 	if (ret) {
25080090810SAbel Vesa 		dev_err(&p->dev, "failed to enable ref clock, %d\n", ret);
25180090810SAbel Vesa 		goto disable_vreg;
25280090810SAbel Vesa 	}
25380090810SAbel Vesa 
25480090810SAbel Vesa 	ret = reset_control_assert(phy->phy_reset);
25580090810SAbel Vesa 	if (ret) {
25680090810SAbel Vesa 		dev_err(&p->dev, "failed to assert phy_reset, %d\n", ret);
25780090810SAbel Vesa 		goto disable_ref_clk;
25880090810SAbel Vesa 	}
25980090810SAbel Vesa 
26080090810SAbel Vesa 	usleep_range(100, 150);
26180090810SAbel Vesa 
26280090810SAbel Vesa 	ret = reset_control_deassert(phy->phy_reset);
26380090810SAbel Vesa 	if (ret) {
26480090810SAbel Vesa 		dev_err(&p->dev, "failed to de-assert phy_reset, %d\n", ret);
26580090810SAbel Vesa 		goto disable_ref_clk;
26680090810SAbel Vesa 	}
26780090810SAbel Vesa 
26880090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG0,
26980090810SAbel Vesa 					 CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN);
27080090810SAbel Vesa 
27180090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, POR);
27280090810SAbel Vesa 
27380090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
27480090810SAbel Vesa 					 PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN);
27580090810SAbel Vesa 
27680090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_APB_ACCESS_CMD,
27780090810SAbel Vesa 					 APB_LOGIC_RESET, APB_LOGIC_RESET);
27880090810SAbel Vesa 
27980090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0);
28080090810SAbel Vesa 
28180090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_FSEL_SEL,
28280090810SAbel Vesa 					 FSEL_SEL, FSEL_SEL);
28380090810SAbel Vesa 
28480090810SAbel Vesa 	/* update ref_clk related registers */
28580090810SAbel Vesa 	ret = qcom_eusb2_ref_clk_init(phy);
28680090810SAbel Vesa 	if (ret)
28780090810SAbel Vesa 		goto disable_ref_clk;
28880090810SAbel Vesa 
28980090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_1,
29080090810SAbel Vesa 					 PHY_CFG_PLL_CPBIAS_CNTRL_MASK,
29180090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1));
29280090810SAbel Vesa 
29380090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4,
29480090810SAbel Vesa 					 PHY_CFG_PLL_INT_CNTRL_MASK,
29580090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8));
29680090810SAbel Vesa 
29780090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4,
29880090810SAbel Vesa 					 PHY_CFG_PLL_GMP_CNTRL_MASK,
29980090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1));
30080090810SAbel Vesa 
30180090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5,
30280090810SAbel Vesa 					 PHY_CFG_PLL_PROP_CNTRL_MASK,
30380090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10));
30480090810SAbel Vesa 
30580090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_6,
30680090810SAbel Vesa 					 PHY_CFG_PLL_VCO_CNTRL_MASK,
30780090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0));
30880090810SAbel Vesa 
30980090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5,
31080090810SAbel Vesa 					 PHY_CFG_PLL_VREF_TUNE_MASK,
31180090810SAbel Vesa 					 FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1));
31280090810SAbel Vesa 
31380090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
31480090810SAbel Vesa 					 VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL);
31580090810SAbel Vesa 
31680090810SAbel Vesa 	/* set default parameters */
31780090810SAbel Vesa 	qcom_eusb2_default_parameters(phy);
31880090810SAbel Vesa 
31980090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
32080090810SAbel Vesa 					 USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
32180090810SAbel Vesa 					 USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
32280090810SAbel Vesa 
32380090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM);
32480090810SAbel Vesa 
32580090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
32680090810SAbel Vesa 					 SIDDQ_SEL, SIDDQ_SEL);
32780090810SAbel Vesa 
32880090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
32980090810SAbel Vesa 					 SIDDQ, 0);
33080090810SAbel Vesa 
33180090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, 0);
33280090810SAbel Vesa 
33380090810SAbel Vesa 	qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
33480090810SAbel Vesa 					 USB2_SUSPEND_N_SEL, 0);
33580090810SAbel Vesa 
33680090810SAbel Vesa 	return 0;
33780090810SAbel Vesa 
33880090810SAbel Vesa disable_ref_clk:
33980090810SAbel Vesa 	clk_disable_unprepare(phy->ref_clk);
34080090810SAbel Vesa 
34180090810SAbel Vesa disable_vreg:
34280090810SAbel Vesa 	regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs);
34380090810SAbel Vesa 
34480090810SAbel Vesa 	return ret;
34580090810SAbel Vesa }
34680090810SAbel Vesa 
34780090810SAbel Vesa static int qcom_snps_eusb2_hsphy_exit(struct phy *p)
34880090810SAbel Vesa {
34980090810SAbel Vesa 	struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
35080090810SAbel Vesa 
35180090810SAbel Vesa 	clk_disable_unprepare(phy->ref_clk);
35280090810SAbel Vesa 
35380090810SAbel Vesa 	regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs);
35480090810SAbel Vesa 
3553584f639SNeil Armstrong 	phy_exit(phy->repeater);
3563584f639SNeil Armstrong 
35780090810SAbel Vesa 	return 0;
35880090810SAbel Vesa }
35980090810SAbel Vesa 
36080090810SAbel Vesa static const struct phy_ops qcom_snps_eusb2_hsphy_ops = {
36180090810SAbel Vesa 	.init		= qcom_snps_eusb2_hsphy_init,
36280090810SAbel Vesa 	.exit		= qcom_snps_eusb2_hsphy_exit,
36380090810SAbel Vesa 	.set_mode	= qcom_snps_eusb2_hsphy_set_mode,
36480090810SAbel Vesa 	.owner		= THIS_MODULE,
36580090810SAbel Vesa };
36680090810SAbel Vesa 
36780090810SAbel Vesa static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev)
36880090810SAbel Vesa {
36980090810SAbel Vesa 	struct device *dev = &pdev->dev;
3703584f639SNeil Armstrong 	struct device_node *np = dev->of_node;
37180090810SAbel Vesa 	struct qcom_snps_eusb2_hsphy *phy;
37280090810SAbel Vesa 	struct phy_provider *phy_provider;
37380090810SAbel Vesa 	struct phy *generic_phy;
37480090810SAbel Vesa 	int ret, i;
37580090810SAbel Vesa 	int num;
37680090810SAbel Vesa 
37780090810SAbel Vesa 	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
37880090810SAbel Vesa 	if (!phy)
37980090810SAbel Vesa 		return -ENOMEM;
38080090810SAbel Vesa 
38180090810SAbel Vesa 	phy->base = devm_platform_ioremap_resource(pdev, 0);
38280090810SAbel Vesa 	if (IS_ERR(phy->base))
38380090810SAbel Vesa 		return PTR_ERR(phy->base);
38480090810SAbel Vesa 
38580090810SAbel Vesa 	phy->phy_reset = devm_reset_control_get_exclusive(dev, NULL);
38680090810SAbel Vesa 	if (IS_ERR(phy->phy_reset))
38780090810SAbel Vesa 		return PTR_ERR(phy->phy_reset);
38880090810SAbel Vesa 
38980090810SAbel Vesa 	phy->ref_clk = devm_clk_get(dev, "ref");
39080090810SAbel Vesa 	if (IS_ERR(phy->ref_clk))
39180090810SAbel Vesa 		return dev_err_probe(dev, PTR_ERR(phy->ref_clk),
39280090810SAbel Vesa 				     "failed to get ref clk\n");
39380090810SAbel Vesa 
39480090810SAbel Vesa 	num = ARRAY_SIZE(phy->vregs);
39580090810SAbel Vesa 	for (i = 0; i < num; i++)
39680090810SAbel Vesa 		phy->vregs[i].supply = eusb2_hsphy_vreg_names[i];
39780090810SAbel Vesa 
39880090810SAbel Vesa 	ret = devm_regulator_bulk_get(dev, num, phy->vregs);
39980090810SAbel Vesa 	if (ret)
40080090810SAbel Vesa 		return dev_err_probe(dev, ret,
40180090810SAbel Vesa 				     "failed to get regulator supplies\n");
4023584f639SNeil Armstrong 
4033584f639SNeil Armstrong 	phy->repeater = devm_of_phy_get_by_index(dev, np, 0);
4043584f639SNeil Armstrong 	if (IS_ERR(phy->repeater))
4053584f639SNeil Armstrong 		return dev_err_probe(dev, PTR_ERR(phy->repeater),
4063584f639SNeil Armstrong 				     "failed to get repeater\n");
4073584f639SNeil Armstrong 
40880090810SAbel Vesa 	generic_phy = devm_phy_create(dev, NULL, &qcom_snps_eusb2_hsphy_ops);
40980090810SAbel Vesa 	if (IS_ERR(generic_phy)) {
41080090810SAbel Vesa 		dev_err(dev, "failed to create phy %d\n", ret);
41180090810SAbel Vesa 		return PTR_ERR(generic_phy);
41280090810SAbel Vesa 	}
41380090810SAbel Vesa 
41480090810SAbel Vesa 	dev_set_drvdata(dev, phy);
41580090810SAbel Vesa 	phy_set_drvdata(generic_phy, phy);
41680090810SAbel Vesa 
41780090810SAbel Vesa 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
41880090810SAbel Vesa 	if (IS_ERR(phy_provider))
41980090810SAbel Vesa 		return PTR_ERR(phy_provider);
42080090810SAbel Vesa 
42180090810SAbel Vesa 	dev_info(dev, "Registered Qcom-eUSB2 phy\n");
42280090810SAbel Vesa 
42380090810SAbel Vesa 	return 0;
42480090810SAbel Vesa }
42580090810SAbel Vesa 
42680090810SAbel Vesa static const struct of_device_id qcom_snps_eusb2_hsphy_of_match_table[] = {
42780090810SAbel Vesa 	{ .compatible = "qcom,sm8550-snps-eusb2-phy", },
42880090810SAbel Vesa 	{ },
42980090810SAbel Vesa };
43080090810SAbel Vesa MODULE_DEVICE_TABLE(of, qcom_snps_eusb2_hsphy_of_match_table);
43180090810SAbel Vesa 
43280090810SAbel Vesa static struct platform_driver qcom_snps_eusb2_hsphy_driver = {
43380090810SAbel Vesa 	.probe		= qcom_snps_eusb2_hsphy_probe,
43480090810SAbel Vesa 	.driver = {
43580090810SAbel Vesa 		.name	= "qcom-snps-eusb2-hsphy",
43680090810SAbel Vesa 		.of_match_table = qcom_snps_eusb2_hsphy_of_match_table,
43780090810SAbel Vesa 	},
43880090810SAbel Vesa };
43980090810SAbel Vesa 
44080090810SAbel Vesa module_platform_driver(qcom_snps_eusb2_hsphy_driver);
44180090810SAbel Vesa MODULE_DESCRIPTION("Qualcomm SNPS eUSB2 HS PHY driver");
44280090810SAbel Vesa MODULE_LICENSE("GPL");
443