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