xref: /linux/drivers/phy/phy-snps-eusb2.c (revision 26ba30221c03364d6ed9910be8da4c1fd871b07b)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2023, Linaro Limited
4  */
5 
6 #include <linux/bitfield.h>
7 #include <linux/clk.h>
8 #include <linux/delay.h>
9 #include <linux/iopoll.h>
10 #include <linux/phy/phy.h>
11 #include <linux/platform_device.h>
12 #include <linux/regulator/consumer.h>
13 #include <linux/reset.h>
14 
15 #define EXYNOS_USB_PHY_HS_PHY_CTRL_RST	(0x0)
16 #define USB_PHY_RST_MASK		GENMASK(1, 0)
17 #define UTMI_PORT_RST_MASK		GENMASK(5, 4)
18 
19 #define EXYNOS_USB_PHY_HS_PHY_CTRL_COMMON	(0x4)
20 #define RPTR_MODE			BIT(10)
21 #define FSEL_20_MHZ_VAL			(0x1)
22 #define FSEL_24_MHZ_VAL			(0x2)
23 #define FSEL_26_MHZ_VAL			(0x3)
24 #define FSEL_48_MHZ_VAL			(0x2)
25 
26 #define EXYNOS_USB_PHY_CFG_PLLCFG0	(0x8)
27 #define PHY_CFG_PLL_FB_DIV_19_8_MASK	GENMASK(19, 8)
28 #define DIV_19_8_19_2_MHZ_VAL		(0x170)
29 #define DIV_19_8_20_MHZ_VAL		(0x160)
30 #define DIV_19_8_24_MHZ_VAL		(0x120)
31 #define DIV_19_8_26_MHZ_VAL		(0x107)
32 #define DIV_19_8_48_MHZ_VAL		(0x120)
33 
34 #define EXYNOS_USB_PHY_CFG_PLLCFG1	(0xc)
35 #define EXYNOS_PHY_CFG_PLL_FB_DIV_11_8_MASK	GENMASK(11, 8)
36 #define EXYNOS_DIV_11_8_19_2_MHZ_VAL	(0x0)
37 #define EXYNOS_DIV_11_8_20_MHZ_VAL	(0x0)
38 #define EXYNOS_DIV_11_8_24_MHZ_VAL	(0x0)
39 #define EXYNOS_DIV_11_8_26_MHZ_VAL	(0x0)
40 #define EXYNOS_DIV_11_8_48_MHZ_VAL	(0x1)
41 
42 #define EXYNOS_PHY_CFG_TX		(0x14)
43 #define EXYNOS_PHY_CFG_TX_FSLS_VREF_TUNE_MASK	GENMASK(2, 1)
44 
45 #define EXYNOS_USB_PHY_UTMI_TESTSE	(0x20)
46 #define TEST_IDDQ			BIT(6)
47 
48 #define QCOM_USB_PHY_UTMI_CTRL0		(0x3c)
49 #define SLEEPM				BIT(0)
50 #define OPMODE_MASK			GENMASK(4, 3)
51 #define OPMODE_NONDRIVING		BIT(3)
52 
53 #define QCOM_USB_PHY_UTMI_CTRL5		(0x50)
54 #define POR				BIT(1)
55 
56 #define QCOM_USB_PHY_HS_PHY_CTRL_COMMON0	(0x54)
57 #define PHY_ENABLE			BIT(0)
58 #define SIDDQ_SEL			BIT(1)
59 #define SIDDQ				BIT(2)
60 #define RETENABLEN			BIT(3)
61 #define FSEL_MASK			GENMASK(6, 4)
62 #define FSEL_19_2_MHZ_VAL		(0x0)
63 #define FSEL_38_4_MHZ_VAL		(0x4)
64 
65 #define QCOM_USB_PHY_CFG_CTRL_1		(0x58)
66 #define PHY_CFG_PLL_CPBIAS_CNTRL_MASK	GENMASK(7, 1)
67 
68 #define QCOM_USB_PHY_CFG_CTRL_2		(0x5c)
69 #define PHY_CFG_PLL_FB_DIV_7_0_MASK	GENMASK(7, 0)
70 #define DIV_7_0_19_2_MHZ_VAL		(0x90)
71 #define DIV_7_0_38_4_MHZ_VAL		(0xc8)
72 
73 #define QCOM_USB_PHY_CFG_CTRL_3		(0x60)
74 #define PHY_CFG_PLL_FB_DIV_11_8_MASK	GENMASK(3, 0)
75 #define DIV_11_8_19_2_MHZ_VAL		(0x1)
76 #define DIV_11_8_38_4_MHZ_VAL		(0x0)
77 
78 #define PHY_CFG_PLL_REF_DIV		GENMASK(7, 4)
79 #define PLL_REF_DIV_VAL			(0x0)
80 
81 #define QCOM_USB_PHY_HS_PHY_CTRL2	(0x64)
82 #define VBUSVLDEXT0			BIT(0)
83 #define USB2_SUSPEND_N			BIT(2)
84 #define USB2_SUSPEND_N_SEL		BIT(3)
85 #define VBUS_DET_EXT_SEL		BIT(4)
86 
87 #define QCOM_USB_PHY_CFG_CTRL_4		(0x68)
88 #define PHY_CFG_PLL_GMP_CNTRL_MASK	GENMASK(1, 0)
89 #define PHY_CFG_PLL_INT_CNTRL_MASK	GENMASK(7, 2)
90 
91 #define QCOM_USB_PHY_CFG_CTRL_5		(0x6c)
92 #define PHY_CFG_PLL_PROP_CNTRL_MASK	GENMASK(4, 0)
93 #define PHY_CFG_PLL_VREF_TUNE_MASK	GENMASK(7, 6)
94 
95 #define QCOM_USB_PHY_CFG_CTRL_6		(0x70)
96 #define PHY_CFG_PLL_VCO_CNTRL_MASK	GENMASK(2, 0)
97 
98 #define QCOM_USB_PHY_CFG_CTRL_7		(0x74)
99 
100 #define QCOM_USB_PHY_CFG_CTRL_8		(0x78)
101 #define PHY_CFG_TX_FSLS_VREF_TUNE_MASK	GENMASK(1, 0)
102 #define PHY_CFG_TX_FSLS_VREG_BYPASS	BIT(2)
103 #define PHY_CFG_TX_HS_VREF_TUNE_MASK	GENMASK(5, 3)
104 #define PHY_CFG_TX_HS_XV_TUNE_MASK	GENMASK(7, 6)
105 
106 #define QCOM_USB_PHY_CFG_CTRL_9		(0x7c)
107 #define PHY_CFG_TX_PREEMP_TUNE_MASK	GENMASK(2, 0)
108 #define PHY_CFG_TX_RES_TUNE_MASK	GENMASK(4, 3)
109 #define PHY_CFG_TX_RISE_TUNE_MASK	GENMASK(6, 5)
110 #define PHY_CFG_RCAL_BYPASS		BIT(7)
111 
112 #define QCOM_USB_PHY_CFG_CTRL_10	(0x80)
113 
114 #define QCOM_USB_PHY_CFG0		(0x94)
115 #define DATAPATH_CTRL_OVERRIDE_EN	BIT(0)
116 #define CMN_CTRL_OVERRIDE_EN		BIT(1)
117 
118 #define QCOM_UTMI_PHY_CMN_CTRL0		(0x98)
119 #define TESTBURNIN			BIT(6)
120 
121 #define QCOM_USB_PHY_FSEL_SEL		(0xb8)
122 #define FSEL_SEL			BIT(0)
123 
124 #define QCOM_USB_PHY_APB_ACCESS_CMD	(0x130)
125 #define RW_ACCESS			BIT(0)
126 #define APB_START_CMD			BIT(1)
127 #define APB_LOGIC_RESET			BIT(2)
128 
129 #define QCOM_USB_PHY_APB_ACCESS_STATUS	(0x134)
130 #define ACCESS_DONE			BIT(0)
131 #define TIMED_OUT			BIT(1)
132 #define ACCESS_ERROR			BIT(2)
133 #define ACCESS_IN_PROGRESS		BIT(3)
134 
135 #define QCOM_USB_PHY_APB_ADDRESS	(0x138)
136 #define APB_REG_ADDR_MASK		GENMASK(7, 0)
137 
138 #define QCOM_USB_PHY_APB_WRDATA_LSB	(0x13c)
139 #define APB_REG_WRDATA_7_0_MASK		GENMASK(3, 0)
140 
141 #define QCOM_USB_PHY_APB_WRDATA_MSB	(0x140)
142 #define APB_REG_WRDATA_15_8_MASK	GENMASK(7, 4)
143 
144 #define QCOM_USB_PHY_APB_RDDATA_LSB	(0x144)
145 #define APB_REG_RDDATA_7_0_MASK		GENMASK(3, 0)
146 
147 #define QCOM_USB_PHY_APB_RDDATA_MSB	(0x148)
148 #define APB_REG_RDDATA_15_8_MASK	GENMASK(7, 4)
149 
150 static const char * const eusb2_hsphy_vreg_names[] = {
151 	"vdd", "vdda12",
152 };
153 
154 #define EUSB2_NUM_VREGS		ARRAY_SIZE(eusb2_hsphy_vreg_names)
155 
156 struct snps_eusb2_phy_drvdata {
157 	int (*phy_init)(struct phy *p);
158 	const char * const *clk_names;
159 	int num_clks;
160 };
161 
162 struct snps_eusb2_hsphy {
163 	struct phy *phy;
164 	void __iomem *base;
165 
166 	struct clk *ref_clk;
167 	struct clk_bulk_data *clks;
168 	struct reset_control *phy_reset;
169 
170 	struct regulator_bulk_data vregs[EUSB2_NUM_VREGS];
171 
172 	enum phy_mode mode;
173 
174 	struct phy *repeater;
175 
176 	const struct snps_eusb2_phy_drvdata *data;
177 };
178 
179 static int snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode)
180 {
181 	struct snps_eusb2_hsphy *phy = phy_get_drvdata(p);
182 
183 	phy->mode = mode;
184 
185 	return phy_set_mode_ext(phy->repeater, mode, submode);
186 }
187 
188 static void snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset,
189 					u32 mask, u32 val)
190 {
191 	u32 reg;
192 
193 	reg = readl_relaxed(base + offset);
194 	reg &= ~mask;
195 	reg |= val & mask;
196 	writel_relaxed(reg, base + offset);
197 
198 	/* Ensure above write is completed */
199 	readl_relaxed(base + offset);
200 }
201 
202 static void qcom_eusb2_default_parameters(struct snps_eusb2_hsphy *phy)
203 {
204 	/* default parameters: tx pre-emphasis */
205 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9,
206 				    PHY_CFG_TX_PREEMP_TUNE_MASK,
207 				    FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0));
208 
209 	/* tx rise/fall time */
210 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9,
211 				    PHY_CFG_TX_RISE_TUNE_MASK,
212 				    FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2));
213 
214 	/* source impedance adjustment */
215 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9,
216 				    PHY_CFG_TX_RES_TUNE_MASK,
217 				    FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1));
218 
219 	/* dc voltage level adjustement */
220 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_8,
221 				    PHY_CFG_TX_HS_VREF_TUNE_MASK,
222 				    FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3));
223 
224 	/* transmitter HS crossover adjustement */
225 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_8,
226 				    PHY_CFG_TX_HS_XV_TUNE_MASK,
227 				    FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0));
228 }
229 
230 struct snps_eusb2_ref_clk {
231 	unsigned long freq;
232 	u32 fsel_val;
233 	u32 div_7_0_val;
234 	u32 div_11_8_val;
235 };
236 
237 static const struct snps_eusb2_ref_clk exynos_eusb2_ref_clk[] = {
238 	{ 19200000, FSEL_19_2_MHZ_VAL, DIV_19_8_19_2_MHZ_VAL, EXYNOS_DIV_11_8_19_2_MHZ_VAL },
239 	{ 20000000, FSEL_20_MHZ_VAL, DIV_19_8_20_MHZ_VAL, EXYNOS_DIV_11_8_20_MHZ_VAL },
240 	{ 24000000, FSEL_24_MHZ_VAL, DIV_19_8_24_MHZ_VAL, EXYNOS_DIV_11_8_24_MHZ_VAL },
241 	{ 26000000, FSEL_26_MHZ_VAL, DIV_19_8_26_MHZ_VAL, EXYNOS_DIV_11_8_26_MHZ_VAL },
242 	{ 48000000, FSEL_48_MHZ_VAL, DIV_19_8_48_MHZ_VAL, EXYNOS_DIV_11_8_48_MHZ_VAL },
243 };
244 
245 static int exynos_eusb2_ref_clk_init(struct snps_eusb2_hsphy *phy)
246 {
247 	const struct snps_eusb2_ref_clk *config = NULL;
248 	unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk);
249 
250 	for (int i = 0; i < ARRAY_SIZE(exynos_eusb2_ref_clk); i++) {
251 		if (exynos_eusb2_ref_clk[i].freq == ref_clk_freq) {
252 			config = &exynos_eusb2_ref_clk[i];
253 			break;
254 		}
255 	}
256 
257 	if (!config) {
258 		dev_err(&phy->phy->dev, "unsupported ref_clk_freq: %lu\n", ref_clk_freq);
259 		return -EINVAL;
260 	}
261 
262 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_COMMON,
263 				    FSEL_MASK,
264 				    FIELD_PREP(FSEL_MASK, config->fsel_val));
265 
266 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_CFG_PLLCFG0,
267 				    PHY_CFG_PLL_FB_DIV_19_8_MASK,
268 				    FIELD_PREP(PHY_CFG_PLL_FB_DIV_19_8_MASK,
269 					       config->div_7_0_val));
270 
271 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_CFG_PLLCFG1,
272 				    EXYNOS_PHY_CFG_PLL_FB_DIV_11_8_MASK,
273 				    config->div_11_8_val);
274 	return 0;
275 }
276 
277 static const struct snps_eusb2_ref_clk qcom_eusb2_ref_clk[] = {
278 	{ 19200000, FSEL_19_2_MHZ_VAL, DIV_7_0_19_2_MHZ_VAL, DIV_11_8_19_2_MHZ_VAL },
279 	{ 38400000, FSEL_38_4_MHZ_VAL, DIV_7_0_38_4_MHZ_VAL, DIV_11_8_38_4_MHZ_VAL },
280 };
281 
282 static int qcom_eusb2_ref_clk_init(struct snps_eusb2_hsphy *phy)
283 {
284 	const struct snps_eusb2_ref_clk *config = NULL;
285 	unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk);
286 
287 	for (int i = 0; i < ARRAY_SIZE(qcom_eusb2_ref_clk); i++) {
288 		if (qcom_eusb2_ref_clk[i].freq == ref_clk_freq) {
289 			config = &qcom_eusb2_ref_clk[i];
290 			break;
291 		}
292 	}
293 
294 	if (!config) {
295 		dev_err(&phy->phy->dev, "unsupported ref_clk_freq: %lu\n", ref_clk_freq);
296 		return -EINVAL;
297 	}
298 
299 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
300 				    FSEL_MASK,
301 				    FIELD_PREP(FSEL_MASK, config->fsel_val));
302 
303 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_2,
304 				    PHY_CFG_PLL_FB_DIV_7_0_MASK,
305 				    config->div_7_0_val);
306 
307 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3,
308 				    PHY_CFG_PLL_FB_DIV_11_8_MASK,
309 				    config->div_11_8_val);
310 
311 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3,
312 				    PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL);
313 
314 	return 0;
315 }
316 
317 static int exynos_snps_eusb2_hsphy_init(struct phy *p)
318 {
319 	struct snps_eusb2_hsphy *phy = phy_get_drvdata(p);
320 	int ret;
321 
322 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_RST,
323 				    USB_PHY_RST_MASK | UTMI_PORT_RST_MASK,
324 				    USB_PHY_RST_MASK | UTMI_PORT_RST_MASK);
325 	fsleep(50); /* required after holding phy in reset */
326 
327 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_COMMON,
328 				    RPTR_MODE, RPTR_MODE);
329 
330 	/* update ref_clk related registers */
331 	ret = exynos_eusb2_ref_clk_init(phy);
332 	if (ret)
333 		return ret;
334 
335 	/* default parameter: tx fsls-vref */
336 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_PHY_CFG_TX,
337 				    EXYNOS_PHY_CFG_TX_FSLS_VREF_TUNE_MASK,
338 				    FIELD_PREP(EXYNOS_PHY_CFG_TX_FSLS_VREF_TUNE_MASK, 0x0));
339 
340 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_UTMI_TESTSE,
341 				    TEST_IDDQ, 0);
342 	fsleep(10); /* required after releasing test_iddq */
343 
344 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_RST,
345 				    USB_PHY_RST_MASK, 0);
346 
347 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_COMMON,
348 				    PHY_ENABLE, PHY_ENABLE);
349 
350 	snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_RST,
351 				    UTMI_PORT_RST_MASK, 0);
352 
353 	return 0;
354 }
355 
356 static const char * const exynos_eusb2_hsphy_clock_names[] = {
357 	"ref", "bus", "ctrl",
358 };
359 
360 static const struct snps_eusb2_phy_drvdata exynos2200_snps_eusb2_phy = {
361 	.phy_init	= exynos_snps_eusb2_hsphy_init,
362 	.clk_names	= exynos_eusb2_hsphy_clock_names,
363 	.num_clks	= ARRAY_SIZE(exynos_eusb2_hsphy_clock_names),
364 };
365 
366 static int qcom_snps_eusb2_hsphy_init(struct phy *p)
367 {
368 	struct snps_eusb2_hsphy *phy = phy_get_drvdata(p);
369 	int ret;
370 
371 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG0,
372 				    CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN);
373 
374 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL5, POR, POR);
375 
376 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
377 				    PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN);
378 
379 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_APB_ACCESS_CMD,
380 				    APB_LOGIC_RESET, APB_LOGIC_RESET);
381 
382 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0);
383 
384 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_FSEL_SEL,
385 				    FSEL_SEL, FSEL_SEL);
386 
387 	/* update ref_clk related registers */
388 	ret = qcom_eusb2_ref_clk_init(phy);
389 	if (ret)
390 		return ret;
391 
392 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_1,
393 				    PHY_CFG_PLL_CPBIAS_CNTRL_MASK,
394 				    FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x0));
395 
396 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_4,
397 				    PHY_CFG_PLL_INT_CNTRL_MASK,
398 				    FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8));
399 
400 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_4,
401 				    PHY_CFG_PLL_GMP_CNTRL_MASK,
402 				    FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1));
403 
404 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_5,
405 				    PHY_CFG_PLL_PROP_CNTRL_MASK,
406 				    FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10));
407 
408 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_6,
409 				    PHY_CFG_PLL_VCO_CNTRL_MASK,
410 				    FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0));
411 
412 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_5,
413 				    PHY_CFG_PLL_VREF_TUNE_MASK,
414 				    FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1));
415 
416 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2,
417 				    VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL);
418 
419 	/* set default parameters */
420 	qcom_eusb2_default_parameters(phy);
421 
422 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2,
423 				    USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
424 				    USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
425 
426 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM);
427 
428 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
429 				    SIDDQ_SEL, SIDDQ_SEL);
430 
431 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
432 				    SIDDQ, 0);
433 
434 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL5, POR, 0);
435 
436 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2,
437 				    USB2_SUSPEND_N_SEL, 0);
438 
439 	snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG0,
440 				    CMN_CTRL_OVERRIDE_EN, 0);
441 
442 	return 0;
443 }
444 
445 static const char * const qcom_eusb2_hsphy_clock_names[] = {
446 	"ref",
447 };
448 
449 static const struct snps_eusb2_phy_drvdata sm8550_snps_eusb2_phy = {
450 	.phy_init	= qcom_snps_eusb2_hsphy_init,
451 	.clk_names      = qcom_eusb2_hsphy_clock_names,
452 	.num_clks       = ARRAY_SIZE(qcom_eusb2_hsphy_clock_names),
453 };
454 
455 static int snps_eusb2_hsphy_init(struct phy *p)
456 {
457 	struct snps_eusb2_hsphy *phy = phy_get_drvdata(p);
458 	int ret;
459 
460 	ret = regulator_bulk_enable(ARRAY_SIZE(phy->vregs), phy->vregs);
461 	if (ret)
462 		return ret;
463 
464 	ret = phy_init(phy->repeater);
465 	if (ret) {
466 		dev_err(&p->dev, "repeater init failed: %d\n", ret);
467 		goto disable_vreg;
468 	}
469 
470 	ret = clk_bulk_prepare_enable(phy->data->num_clks, phy->clks);
471 	if (ret) {
472 		dev_err(&p->dev, "failed to enable ref clock: %d\n", ret);
473 		goto exit_repeater;
474 	}
475 
476 	ret = reset_control_assert(phy->phy_reset);
477 	if (ret) {
478 		dev_err(&p->dev, "failed to assert phy_reset: %d\n", ret);
479 		goto disable_clks;
480 	}
481 
482 	usleep_range(100, 150);
483 
484 	ret = reset_control_deassert(phy->phy_reset);
485 	if (ret) {
486 		dev_err(&p->dev, "failed to de-assert phy_reset: %d\n", ret);
487 		goto disable_clks;
488 	}
489 
490 	ret = phy->data->phy_init(p);
491 	if (ret)
492 		goto disable_clks;
493 
494 	return 0;
495 
496 disable_clks:
497 	clk_bulk_disable_unprepare(phy->data->num_clks, phy->clks);
498 exit_repeater:
499 	phy_exit(phy->repeater);
500 disable_vreg:
501 	regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs);
502 
503 	return ret;
504 }
505 
506 static int snps_eusb2_hsphy_exit(struct phy *p)
507 {
508 	struct snps_eusb2_hsphy *phy = phy_get_drvdata(p);
509 
510 	clk_bulk_disable_unprepare(phy->data->num_clks, phy->clks);
511 
512 	regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs);
513 
514 	phy_exit(phy->repeater);
515 
516 	return 0;
517 }
518 
519 static const struct phy_ops snps_eusb2_hsphy_ops = {
520 	.init		= snps_eusb2_hsphy_init,
521 	.exit		= snps_eusb2_hsphy_exit,
522 	.set_mode	= snps_eusb2_hsphy_set_mode,
523 	.owner		= THIS_MODULE,
524 };
525 
526 static int snps_eusb2_hsphy_probe(struct platform_device *pdev)
527 {
528 	struct device *dev = &pdev->dev;
529 	struct device_node *np = dev->of_node;
530 	struct snps_eusb2_hsphy *phy;
531 	struct phy_provider *phy_provider;
532 	struct phy *generic_phy;
533 	int ret, i;
534 	int num;
535 
536 	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
537 	if (!phy)
538 		return -ENOMEM;
539 
540 	phy->data = device_get_match_data(dev);
541 	if (!phy->data)
542 		return -EINVAL;
543 
544 	phy->base = devm_platform_ioremap_resource(pdev, 0);
545 	if (IS_ERR(phy->base))
546 		return PTR_ERR(phy->base);
547 
548 	phy->phy_reset = devm_reset_control_get_optional_exclusive(dev, NULL);
549 	if (IS_ERR(phy->phy_reset))
550 		return PTR_ERR(phy->phy_reset);
551 
552 	phy->clks = devm_kcalloc(dev, phy->data->num_clks, sizeof(*phy->clks),
553 				 GFP_KERNEL);
554 	if (!phy->clks)
555 		return -ENOMEM;
556 
557 	for (i = 0; i < phy->data->num_clks; ++i)
558 		phy->clks[i].id = phy->data->clk_names[i];
559 
560 	ret = devm_clk_bulk_get(dev, phy->data->num_clks, phy->clks);
561 	if (ret)
562 		return dev_err_probe(dev, ret,
563 				     "failed to get phy clock(s)\n");
564 
565 	phy->ref_clk = NULL;
566 	for (i = 0; i < phy->data->num_clks; ++i) {
567 		if (!strcmp(phy->clks[i].id, "ref")) {
568 			phy->ref_clk = phy->clks[i].clk;
569 			break;
570 		}
571 	}
572 
573 	if (IS_ERR_OR_NULL(phy->ref_clk)) {
574 		ret = phy->ref_clk ? PTR_ERR(phy->ref_clk) : -ENOENT;
575 		return dev_err_probe(dev, ret,
576 				     "failed to get ref clk\n");
577 	}
578 
579 	num = ARRAY_SIZE(phy->vregs);
580 	for (i = 0; i < num; i++)
581 		phy->vregs[i].supply = eusb2_hsphy_vreg_names[i];
582 
583 	ret = devm_regulator_bulk_get(dev, num, phy->vregs);
584 	if (ret)
585 		return dev_err_probe(dev, ret,
586 				     "failed to get regulator supplies\n");
587 
588 	phy->repeater = devm_of_phy_optional_get(dev, np, NULL);
589 	if (IS_ERR(phy->repeater))
590 		return dev_err_probe(dev, PTR_ERR(phy->repeater),
591 				     "failed to get repeater\n");
592 
593 	generic_phy = devm_phy_create(dev, NULL, &snps_eusb2_hsphy_ops);
594 	if (IS_ERR(generic_phy)) {
595 		dev_err(dev, "failed to create phy: %d\n", ret);
596 		return PTR_ERR(generic_phy);
597 	}
598 
599 	dev_set_drvdata(dev, phy);
600 	phy_set_drvdata(generic_phy, phy);
601 
602 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
603 	if (IS_ERR(phy_provider))
604 		return PTR_ERR(phy_provider);
605 
606 	return 0;
607 }
608 
609 static const struct of_device_id snps_eusb2_hsphy_of_match_table[] = {
610 	{
611 		.compatible = "qcom,sm8550-snps-eusb2-phy",
612 		.data = &sm8550_snps_eusb2_phy,
613 	}, {
614 		.compatible = "samsung,exynos2200-eusb2-phy",
615 		.data = &exynos2200_snps_eusb2_phy,
616 	}, {
617 		/* sentinel */
618 	}
619 };
620 MODULE_DEVICE_TABLE(of, snps_eusb2_hsphy_of_match_table);
621 
622 static struct platform_driver snps_eusb2_hsphy_driver = {
623 	.probe		= snps_eusb2_hsphy_probe,
624 	.driver = {
625 		.name	= "snps-eusb2-hsphy",
626 		.of_match_table = snps_eusb2_hsphy_of_match_table,
627 	},
628 };
629 
630 module_platform_driver(snps_eusb2_hsphy_driver);
631 MODULE_DESCRIPTION("Synopsys eUSB2 HS PHY driver");
632 MODULE_LICENSE("GPL");
633