1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform
4  *
5  * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd.
6  *		http://www.huawei.com
7  *
8  * Authors: Yu Chen <chenyu56@huawei.com>
9  */
10 
11 #include <linux/bitfield.h>
12 #include <linux/clk.h>
13 #include <linux/kernel.h>
14 #include <linux/mfd/syscon.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/phy/phy.h>
18 #include <linux/platform_device.h>
19 #include <linux/regmap.h>
20 
21 #define SCTRL_SCDEEPSLEEPED		(0x0)
22 #define USB_CLK_SELECTED		BIT(20)
23 
24 #define PERI_CRG_PEREN0			(0x00)
25 #define PERI_CRG_PERDIS0		(0x04)
26 #define PERI_CRG_PEREN4			(0x40)
27 #define PERI_CRG_PERDIS4		(0x44)
28 #define PERI_CRG_PERRSTEN4		(0x90)
29 #define PERI_CRG_PERRSTDIS4		(0x94)
30 #define PERI_CRG_ISODIS			(0x148)
31 #define PERI_CRG_PEREN6			(0x410)
32 #define PERI_CRG_PERDIS6		(0x414)
33 
34 #define USB_REFCLK_ISO_EN		BIT(25)
35 
36 #define GT_CLK_USB2PHY_REF		BIT(19)
37 
38 #define PCTRL_PERI_CTRL3		(0x10)
39 #define PCTRL_PERI_CTRL3_MSK_START	(16)
40 #define USB_TCXO_EN			BIT(1)
41 
42 #define PCTRL_PERI_CTRL24		(0x64)
43 #define SC_CLK_USB3PHY_3MUX1_SEL	BIT(25)
44 
45 #define USB3OTG_CTRL0			(0x00)
46 #define USB3OTG_CTRL3			(0x0c)
47 #define USB3OTG_CTRL4			(0x10)
48 #define USB3OTG_CTRL5			(0x14)
49 #define USB3OTG_CTRL7			(0x1c)
50 #define USB_MISC_CFG50			(0x50)
51 #define USB_MISC_CFG54			(0x54)
52 #define USB_MISC_CFG58			(0x58)
53 #define USB_MISC_CFG5C			(0x5c)
54 #define USB_MISC_CFGA0			(0xa0)
55 #define TCA_CLK_RST			(0x200)
56 #define TCA_INTR_EN			(0x204)
57 #define TCA_INTR_STS			(0x208)
58 #define TCA_GCFG			(0x210)
59 #define TCA_TCPC			(0x214)
60 #define TCA_SYSMODE_CFG			(0x218)
61 #define TCA_VBUS_CTRL			(0x240)
62 
63 #define CTRL0_USB3_VBUSVLD		BIT(7)
64 #define CTRL0_USB3_VBUSVLD_SEL		BIT(6)
65 
66 #define CTRL3_USB2_VBUSVLDEXT0		BIT(6)
67 #define CTRL3_USB2_VBUSVLDEXTSEL0	BIT(5)
68 
69 #define CTRL5_USB2_SIDDQ		BIT(0)
70 
71 #define CTRL7_USB2_REFCLKSEL_MASK	GENMASK(4, 3)
72 #define CTRL7_USB2_REFCLKSEL_ABB	(BIT(4) | BIT(3))
73 #define CTRL7_USB2_REFCLKSEL_PAD	BIT(4)
74 
75 #define CFG50_USB3_PHY_TEST_POWERDOWN	BIT(23)
76 
77 #define CFG54_USB31PHY_CR_ADDR_MASK	GENMASK(31, 16)
78 
79 #define CFG54_USB3PHY_REF_USE_PAD	BIT(12)
80 #define CFG54_PHY0_PMA_PWR_STABLE	BIT(11)
81 #define CFG54_PHY0_PCS_PWR_STABLE	BIT(9)
82 #define CFG54_USB31PHY_CR_ACK		BIT(7)
83 #define CFG54_USB31PHY_CR_WR_EN		BIT(5)
84 #define CFG54_USB31PHY_CR_SEL		BIT(4)
85 #define CFG54_USB31PHY_CR_RD_EN		BIT(3)
86 #define CFG54_USB31PHY_CR_CLK		BIT(2)
87 #define CFG54_USB3_PHY0_ANA_PWR_EN	BIT(1)
88 
89 #define CFG58_USB31PHY_CR_DATA_MASK     GENMASK(31, 16)
90 
91 #define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN	BIT(1)
92 
93 #define CFGA0_VAUX_RESET		BIT(9)
94 #define CFGA0_USB31C_RESET		BIT(8)
95 #define CFGA0_USB2PHY_REFCLK_SELECT	BIT(4)
96 #define CFGA0_USB3PHY_RESET		BIT(1)
97 #define CFGA0_USB2PHY_POR		BIT(0)
98 
99 #define INTR_EN_XA_TIMEOUT_EVT_EN	BIT(1)
100 #define INTR_EN_XA_ACK_EVT_EN		BIT(0)
101 
102 #define CLK_RST_TCA_REF_CLK_EN		BIT(1)
103 #define CLK_RST_SUSPEND_CLK_EN		BIT(0)
104 
105 #define GCFG_ROLE_HSTDEV		BIT(4)
106 #define GCFG_OP_MODE			GENMASK(1, 0)
107 #define GCFG_OP_MODE_CTRL_SYNC_MODE	BIT(0)
108 
109 #define TCPC_VALID			BIT(4)
110 #define TCPC_LOW_POWER_EN		BIT(3)
111 #define TCPC_MUX_CONTROL_MASK		GENMASK(1, 0)
112 #define TCPC_MUX_CONTROL_USB31		BIT(0)
113 
114 #define SYSMODE_CFG_TYPEC_DISABLE	BIT(3)
115 
116 #define VBUS_CTRL_POWERPRESENT_OVERRD	GENMASK(3, 2)
117 #define VBUS_CTRL_VBUSVALID_OVERRD	GENMASK(1, 0)
118 
119 #define KIRIN970_USB_DEFAULT_PHY_PARAM	(0xfdfee4)
120 #define KIRIN970_USB_DEFAULT_PHY_VBOOST	(0x5)
121 
122 #define TX_VBOOST_LVL_REG		(0xf)
123 #define TX_VBOOST_LVL_START		(6)
124 #define TX_VBOOST_LVL_ENABLE		BIT(9)
125 
126 struct hi3670_priv {
127 	struct device *dev;
128 	struct regmap *peri_crg;
129 	struct regmap *pctrl;
130 	struct regmap *sctrl;
131 	struct regmap *usb31misc;
132 
133 	u32 eye_diagram_param;
134 	u32 tx_vboost_lvl;
135 
136 	u32 peri_crg_offset;
137 	u32 pctrl_offset;
138 	u32 usb31misc_offset;
139 };
140 
141 static int hi3670_phy_cr_clk(struct regmap *usb31misc)
142 {
143 	int ret;
144 
145 	/* Clock up */
146 	ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
147 				 CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK);
148 	if (ret)
149 		return ret;
150 
151 	/* Clock down */
152 	return regmap_update_bits(usb31misc, USB_MISC_CFG54,
153 				  CFG54_USB31PHY_CR_CLK, 0);
154 }
155 
156 static int hi3670_phy_cr_set_sel(struct regmap *usb31misc)
157 {
158 	return regmap_update_bits(usb31misc, USB_MISC_CFG54,
159 				  CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL);
160 }
161 
162 static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction)
163 {
164 	int ret, reg;
165 
166 	if (direction)
167 		reg = CFG54_USB31PHY_CR_WR_EN;
168 	else
169 		reg = CFG54_USB31PHY_CR_RD_EN;
170 
171 	ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, reg, reg);
172 
173 	if (ret)
174 		return ret;
175 
176 	ret = hi3670_phy_cr_clk(usb31misc);
177 	if (ret)
178 		return ret;
179 
180 	return regmap_update_bits(usb31misc, USB_MISC_CFG54,
181 				  CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0);
182 }
183 
184 static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc)
185 {
186 	u32 reg;
187 	int retry = 10;
188 	int ret;
189 
190 	while (retry-- > 0) {
191 		ret = regmap_read(usb31misc, USB_MISC_CFG54, &reg);
192 		if (ret)
193 			return ret;
194 		if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK)
195 			return 0;
196 
197 		ret = hi3670_phy_cr_clk(usb31misc);
198 		if (ret)
199 			return ret;
200 
201 		usleep_range(10, 20);
202 	}
203 
204 	return -ETIMEDOUT;
205 }
206 
207 static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr)
208 {
209 	u32 reg;
210 	int ret;
211 
212 	ret = regmap_read(usb31misc, USB_MISC_CFG54, &reg);
213 	if (ret)
214 		return ret;
215 
216 	reg = FIELD_PREP(CFG54_USB31PHY_CR_ADDR_MASK, addr);
217 
218 	return regmap_update_bits(usb31misc, USB_MISC_CFG54,
219 				  CFG54_USB31PHY_CR_ADDR_MASK, reg);
220 }
221 
222 static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val)
223 {
224 	int reg, i, ret;
225 
226 	for (i = 0; i < 100; i++) {
227 		ret = hi3670_phy_cr_clk(usb31misc);
228 		if (ret)
229 			return ret;
230 	}
231 
232 	ret = hi3670_phy_cr_set_sel(usb31misc);
233 	if (ret)
234 		return ret;
235 
236 	ret = hi3670_phy_cr_set_addr(usb31misc, addr);
237 	if (ret)
238 		return ret;
239 
240 	ret = hi3670_phy_cr_start(usb31misc, 0);
241 	if (ret)
242 		return ret;
243 
244 	ret = hi3670_phy_cr_wait_ack(usb31misc);
245 	if (ret)
246 		return ret;
247 
248 	ret = regmap_read(usb31misc, USB_MISC_CFG58, &reg);
249 	if (ret)
250 		return ret;
251 
252 	*val = FIELD_GET(CFG58_USB31PHY_CR_DATA_MASK, reg);
253 
254 	return 0;
255 }
256 
257 static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val)
258 {
259 	int i;
260 	int ret;
261 
262 	for (i = 0; i < 100; i++) {
263 		ret = hi3670_phy_cr_clk(usb31misc);
264 		if (ret)
265 			return ret;
266 	}
267 
268 	ret = hi3670_phy_cr_set_sel(usb31misc);
269 	if (ret)
270 		return ret;
271 
272 	ret = hi3670_phy_cr_set_addr(usb31misc, addr);
273 	if (ret)
274 		return ret;
275 
276 	ret = regmap_write(usb31misc, USB_MISC_CFG58,
277 			   FIELD_PREP(CFG58_USB31PHY_CR_DATA_MASK, val));
278 	if (ret)
279 		return ret;
280 
281 	ret = hi3670_phy_cr_start(usb31misc, 1);
282 	if (ret)
283 		return ret;
284 
285 	return hi3670_phy_cr_wait_ack(usb31misc);
286 }
287 
288 static int hi3670_phy_set_params(struct hi3670_priv *priv)
289 {
290 	u32 reg;
291 	int ret;
292 	int retry = 3;
293 
294 	ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4,
295 			   priv->eye_diagram_param);
296 	if (ret) {
297 		dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n");
298 		return ret;
299 	}
300 
301 	while (retry-- > 0) {
302 		ret = hi3670_phy_cr_read(priv->usb31misc,
303 					 TX_VBOOST_LVL_REG, &reg);
304 		if (!ret)
305 			break;
306 
307 		if (ret != -ETIMEDOUT) {
308 			dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n");
309 			return ret;
310 		}
311 	}
312 	if (ret)
313 		return ret;
314 
315 	reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START));
316 	ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg);
317 	if (ret)
318 		dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n");
319 
320 	return ret;
321 }
322 
323 static bool hi3670_is_abbclk_selected(struct hi3670_priv *priv)
324 {
325 	u32 reg;
326 
327 	if (!priv->sctrl) {
328 		dev_err(priv->dev, "priv->sctrl is null!\n");
329 		return false;
330 	}
331 
332 	if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, &reg)) {
333 		dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n");
334 		return false;
335 	}
336 
337 	if ((reg & USB_CLK_SELECTED) == 0)
338 		return false;
339 
340 	return true;
341 }
342 
343 static int hi3670_config_phy_clock(struct hi3670_priv *priv)
344 {
345 	u32 val, mask;
346 	int ret;
347 
348 	if (!hi3670_is_abbclk_selected(priv)) {
349 		/* usb refclk iso disable */
350 		ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS,
351 				   USB_REFCLK_ISO_EN);
352 		if (ret)
353 			goto out;
354 
355 		/* enable usb_tcxo_en */
356 		ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
357 				   USB_TCXO_EN |
358 				   (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START));
359 
360 		/* select usbphy clk from abb */
361 		mask = SC_CLK_USB3PHY_3MUX1_SEL;
362 		ret = regmap_update_bits(priv->pctrl,
363 					 PCTRL_PERI_CTRL24, mask, 0);
364 		if (ret)
365 			goto out;
366 
367 		ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
368 					 CFGA0_USB2PHY_REFCLK_SELECT, 0);
369 		if (ret)
370 			goto out;
371 
372 		ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
373 		if (ret)
374 			goto out;
375 		val &= ~CTRL7_USB2_REFCLKSEL_MASK;
376 		val |= CTRL7_USB2_REFCLKSEL_ABB;
377 		ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
378 		if (ret)
379 			goto out;
380 
381 		return 0;
382 	}
383 
384 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
385 				 CFG54_USB3PHY_REF_USE_PAD,
386 				 CFG54_USB3PHY_REF_USE_PAD);
387 	if (ret)
388 		goto out;
389 
390 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
391 				 CFGA0_USB2PHY_REFCLK_SELECT,
392 				 CFGA0_USB2PHY_REFCLK_SELECT);
393 	if (ret)
394 		goto out;
395 
396 	ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
397 	if (ret)
398 		goto out;
399 	val &= ~CTRL7_USB2_REFCLKSEL_MASK;
400 	val |= CTRL7_USB2_REFCLKSEL_PAD;
401 	ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
402 	if (ret)
403 		goto out;
404 
405 	ret = regmap_write(priv->peri_crg,
406 			   PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF);
407 	if (ret)
408 		goto out;
409 
410 	return 0;
411 out:
412 	dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
413 	return ret;
414 }
415 
416 static int hi3670_config_tca(struct hi3670_priv *priv)
417 {
418 	u32 val, mask;
419 	int ret;
420 
421 	ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff);
422 	if (ret)
423 		goto out;
424 
425 	ret = regmap_write(priv->usb31misc, TCA_INTR_EN,
426 			   INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN);
427 	if (ret)
428 		goto out;
429 
430 	mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN;
431 	ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0);
432 	if (ret)
433 		goto out;
434 
435 	ret = regmap_update_bits(priv->usb31misc, TCA_GCFG,
436 				 GCFG_ROLE_HSTDEV | GCFG_OP_MODE,
437 				 GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE);
438 	if (ret)
439 		goto out;
440 
441 	ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG,
442 				 SYSMODE_CFG_TYPEC_DISABLE, 0);
443 	if (ret)
444 		goto out;
445 
446 	ret = regmap_read(priv->usb31misc, TCA_TCPC, &val);
447 	if (ret)
448 		goto out;
449 	val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK);
450 	val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31);
451 	ret = regmap_write(priv->usb31misc, TCA_TCPC, val);
452 	if (ret)
453 		goto out;
454 
455 	ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL,
456 			   VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD);
457 	if (ret)
458 		goto out;
459 
460 	return 0;
461 out:
462 	dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
463 	return ret;
464 }
465 
466 static int hi3670_phy_init(struct phy *phy)
467 {
468 	struct hi3670_priv *priv = phy_get_drvdata(phy);
469 	u32 val;
470 	int ret;
471 
472 	/* assert controller */
473 	val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET |
474 	      CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
475 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0);
476 	if (ret)
477 		goto out;
478 
479 	ret = hi3670_config_phy_clock(priv);
480 	if (ret)
481 		goto out;
482 
483 	/* Exit from IDDQ mode */
484 	ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5,
485 				 CTRL5_USB2_SIDDQ, 0);
486 	if (ret)
487 		goto out;
488 
489 	/* Release USB31 PHY out of TestPowerDown mode */
490 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50,
491 				 CFG50_USB3_PHY_TEST_POWERDOWN, 0);
492 	if (ret)
493 		goto out;
494 
495 	/* Deassert phy */
496 	val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
497 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
498 	if (ret)
499 		goto out;
500 
501 	usleep_range(100, 120);
502 
503 	/* Tell the PHY power is stable */
504 	val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE |
505 	      CFG54_PHY0_PMA_PWR_STABLE;
506 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
507 				 val, val);
508 	if (ret)
509 		goto out;
510 
511 	ret = hi3670_config_tca(priv);
512 	if (ret)
513 		goto out;
514 
515 	/* Enable SSC */
516 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C,
517 				 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN,
518 				 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN);
519 	if (ret)
520 		goto out;
521 
522 	/* Deassert controller */
523 	val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET;
524 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
525 	if (ret)
526 		goto out;
527 
528 	usleep_range(100, 120);
529 
530 	/* Set fake vbus valid signal */
531 	val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL;
532 	ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val);
533 	if (ret)
534 		goto out;
535 
536 	val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0;
537 	ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val);
538 	if (ret)
539 		goto out;
540 
541 	usleep_range(100, 120);
542 
543 	ret = hi3670_phy_set_params(priv);
544 	if (ret)
545 		goto out;
546 
547 	return 0;
548 out:
549 	dev_err(priv->dev, "failed to init phy ret: %d\n", ret);
550 	return ret;
551 }
552 
553 static int hi3670_phy_exit(struct phy *phy)
554 {
555 	struct hi3670_priv *priv = phy_get_drvdata(phy);
556 	u32 mask;
557 	int ret;
558 
559 	/* Assert phy */
560 	mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
561 	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0);
562 	if (ret)
563 		goto out;
564 
565 	if (!hi3670_is_abbclk_selected(priv)) {
566 		/* disable usb_tcxo_en */
567 		ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
568 				   USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START);
569 	} else {
570 		ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6,
571 				   GT_CLK_USB2PHY_REF);
572 		if (ret)
573 			goto out;
574 	}
575 
576 	return 0;
577 out:
578 	dev_err(priv->dev, "failed to exit phy ret: %d\n", ret);
579 	return ret;
580 }
581 
582 static const struct phy_ops hi3670_phy_ops = {
583 	.init		= hi3670_phy_init,
584 	.exit		= hi3670_phy_exit,
585 	.owner		= THIS_MODULE,
586 };
587 
588 static int hi3670_phy_probe(struct platform_device *pdev)
589 {
590 	struct phy_provider *phy_provider;
591 	struct device *dev = &pdev->dev;
592 	struct phy *phy;
593 	struct hi3670_priv *priv;
594 
595 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
596 	if (!priv)
597 		return -ENOMEM;
598 
599 	priv->dev = dev;
600 	priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node,
601 							 "hisilicon,pericrg-syscon");
602 	if (IS_ERR(priv->peri_crg)) {
603 		dev_err(dev, "no hisilicon,pericrg-syscon\n");
604 		return PTR_ERR(priv->peri_crg);
605 	}
606 
607 	priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
608 						      "hisilicon,pctrl-syscon");
609 	if (IS_ERR(priv->pctrl)) {
610 		dev_err(dev, "no hisilicon,pctrl-syscon\n");
611 		return PTR_ERR(priv->pctrl);
612 	}
613 
614 	priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
615 						      "hisilicon,sctrl-syscon");
616 	if (IS_ERR(priv->sctrl)) {
617 		dev_err(dev, "no hisilicon,sctrl-syscon\n");
618 		return PTR_ERR(priv->sctrl);
619 	}
620 
621 	/* node of hi3670 phy is a sub-node of usb3_otg_bc */
622 	priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node);
623 	if (IS_ERR(priv->usb31misc)) {
624 		dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n");
625 		return PTR_ERR(priv->usb31misc);
626 	}
627 
628 	if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param",
629 				 &priv->eye_diagram_param))
630 		priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM;
631 
632 	if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl",
633 				 &priv->tx_vboost_lvl))
634 		priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST;
635 
636 	phy = devm_phy_create(dev, NULL, &hi3670_phy_ops);
637 	if (IS_ERR(phy))
638 		return PTR_ERR(phy);
639 
640 	phy_set_drvdata(phy, priv);
641 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
642 	return PTR_ERR_OR_ZERO(phy_provider);
643 }
644 
645 static const struct of_device_id hi3670_phy_of_match[] = {
646 	{ .compatible = "hisilicon,hi3670-usb-phy" },
647 	{ },
648 };
649 MODULE_DEVICE_TABLE(of, hi3670_phy_of_match);
650 
651 static struct platform_driver hi3670_phy_driver = {
652 	.probe	= hi3670_phy_probe,
653 	.driver = {
654 		.name	= "hi3670-usb-phy",
655 		.of_match_table	= hi3670_phy_of_match,
656 	}
657 };
658 module_platform_driver(hi3670_phy_driver);
659 
660 MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>");
661 MODULE_LICENSE("GPL v2");
662 MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");
663