Lines Matching +full:hi3670 +full:- +full:usb +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform
5 * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd.
17 #include <linux/phy/phy.h>
190 while (retry-- > 0) { in hi3670_phy_cr_wait_ack()
204 return -ETIMEDOUT; in hi3670_phy_cr_wait_ack()
294 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4, in hi3670_phy_set_params()
295 priv->eye_diagram_param); in hi3670_phy_set_params()
297 dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n"); in hi3670_phy_set_params()
301 while (retry-- > 0) { in hi3670_phy_set_params()
302 ret = hi3670_phy_cr_read(priv->usb31misc, in hi3670_phy_set_params()
307 if (ret != -ETIMEDOUT) { in hi3670_phy_set_params()
308 dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n"); in hi3670_phy_set_params()
315 reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START)); in hi3670_phy_set_params()
316 ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg); in hi3670_phy_set_params()
318 dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n"); in hi3670_phy_set_params()
327 if (!priv->sctrl) { in hi3670_is_abbclk_selected()
328 dev_err(priv->dev, "priv->sctrl is null!\n"); in hi3670_is_abbclk_selected()
332 if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, ®)) { in hi3670_is_abbclk_selected()
333 dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n"); in hi3670_is_abbclk_selected()
349 /* usb refclk iso disable */ in hi3670_config_phy_clock()
350 ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS, in hi3670_config_phy_clock()
356 ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3, in hi3670_config_phy_clock()
362 ret = regmap_update_bits(priv->pctrl, in hi3670_config_phy_clock()
367 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, in hi3670_config_phy_clock()
372 ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val); in hi3670_config_phy_clock()
377 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val); in hi3670_config_phy_clock()
384 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54, in hi3670_config_phy_clock()
390 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, in hi3670_config_phy_clock()
396 ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val); in hi3670_config_phy_clock()
401 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val); in hi3670_config_phy_clock()
405 ret = regmap_write(priv->peri_crg, in hi3670_config_phy_clock()
412 dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret); in hi3670_config_phy_clock()
421 ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff); in hi3670_config_tca()
425 ret = regmap_write(priv->usb31misc, TCA_INTR_EN, in hi3670_config_tca()
431 ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0); in hi3670_config_tca()
435 ret = regmap_update_bits(priv->usb31misc, TCA_GCFG, in hi3670_config_tca()
441 ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG, in hi3670_config_tca()
446 ret = regmap_read(priv->usb31misc, TCA_TCPC, &val); in hi3670_config_tca()
451 ret = regmap_write(priv->usb31misc, TCA_TCPC, val); in hi3670_config_tca()
455 ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL, in hi3670_config_tca()
462 dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret); in hi3670_config_tca()
466 static int hi3670_phy_init(struct phy *phy) in hi3670_phy_init() argument
468 struct hi3670_priv *priv = phy_get_drvdata(phy); in hi3670_phy_init()
475 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0); in hi3670_phy_init()
484 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5, in hi3670_phy_init()
489 /* Release USB31 PHY out of TestPowerDown mode */ in hi3670_phy_init()
490 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50, in hi3670_phy_init()
495 /* Deassert phy */ in hi3670_phy_init()
497 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val); in hi3670_phy_init()
503 /* Tell the PHY power is stable */ in hi3670_phy_init()
506 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54, in hi3670_phy_init()
516 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C, in hi3670_phy_init()
524 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val); in hi3670_phy_init()
532 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val); in hi3670_phy_init()
537 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val); in hi3670_phy_init()
549 dev_err(priv->dev, "failed to init phy ret: %d\n", ret); in hi3670_phy_init()
553 static int hi3670_phy_exit(struct phy *phy) in hi3670_phy_exit() argument
555 struct hi3670_priv *priv = phy_get_drvdata(phy); in hi3670_phy_exit()
559 /* Assert phy */ in hi3670_phy_exit()
561 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0); in hi3670_phy_exit()
567 ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3, in hi3670_phy_exit()
570 ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6, in hi3670_phy_exit()
578 dev_err(priv->dev, "failed to exit phy ret: %d\n", ret); in hi3670_phy_exit()
591 struct device *dev = &pdev->dev; in hi3670_phy_probe()
592 struct phy *phy; in hi3670_phy_probe() local
597 return -ENOMEM; in hi3670_phy_probe()
599 priv->dev = dev; in hi3670_phy_probe()
600 priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node, in hi3670_phy_probe()
601 "hisilicon,pericrg-syscon"); in hi3670_phy_probe()
602 if (IS_ERR(priv->peri_crg)) { in hi3670_phy_probe()
603 dev_err(dev, "no hisilicon,pericrg-syscon\n"); in hi3670_phy_probe()
604 return PTR_ERR(priv->peri_crg); in hi3670_phy_probe()
607 priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node, in hi3670_phy_probe()
608 "hisilicon,pctrl-syscon"); in hi3670_phy_probe()
609 if (IS_ERR(priv->pctrl)) { in hi3670_phy_probe()
610 dev_err(dev, "no hisilicon,pctrl-syscon\n"); in hi3670_phy_probe()
611 return PTR_ERR(priv->pctrl); in hi3670_phy_probe()
614 priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node, in hi3670_phy_probe()
615 "hisilicon,sctrl-syscon"); in hi3670_phy_probe()
616 if (IS_ERR(priv->sctrl)) { in hi3670_phy_probe()
617 dev_err(dev, "no hisilicon,sctrl-syscon\n"); in hi3670_phy_probe()
618 return PTR_ERR(priv->sctrl); in hi3670_phy_probe()
621 /* node of hi3670 phy is a sub-node of usb3_otg_bc */ in hi3670_phy_probe()
622 priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node); in hi3670_phy_probe()
623 if (IS_ERR(priv->usb31misc)) { in hi3670_phy_probe()
624 dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n"); in hi3670_phy_probe()
625 return PTR_ERR(priv->usb31misc); in hi3670_phy_probe()
628 if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param", in hi3670_phy_probe()
629 &priv->eye_diagram_param)) in hi3670_phy_probe()
630 priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM; in hi3670_phy_probe()
632 if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl", in hi3670_phy_probe()
633 &priv->tx_vboost_lvl)) in hi3670_phy_probe()
634 priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST; in hi3670_phy_probe()
636 phy = devm_phy_create(dev, NULL, &hi3670_phy_ops); in hi3670_phy_probe()
637 if (IS_ERR(phy)) in hi3670_phy_probe()
638 return PTR_ERR(phy); in hi3670_phy_probe()
640 phy_set_drvdata(phy, priv); in hi3670_phy_probe()
646 { .compatible = "hisilicon,hi3670-usb-phy" },
654 .name = "hi3670-usb-phy",
662 MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");