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