Lines Matching +full:vbus +full:- +full:boost +full:- +full:supply
1 // SPDX-License-Identifier: GPL-2.0-only
26 #include <linux/soc/samsung/exynos-regs-pmu.h>
176 * struct exynos5_usbdrd_phy - driver data for USB 3.0 PHY
190 * @vbus: VBUS regulator for phy
191 * @vbus_boost: Boost regulator for VBUS present on few Exynos boards
210 struct regulator *vbus; member
218 phys[(inst)->index]); in to_usbdrd_phy()
252 return -EINVAL; in exynos5_rate_to_clk()
263 if (!inst->reg_pmu) in exynos5_usbdrd_phy_isol()
268 regmap_update_bits(inst->reg_pmu, inst->pmu_offset, in exynos5_usbdrd_phy_isol()
284 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); in exynos5_usbdrd_pipe3_set_refclk()
294 switch (phy_drd->extrefclk) { in exynos5_usbdrd_pipe3_set_refclk()
312 dev_dbg(phy_drd->dev, "unsupported ref clk\n"); in exynos5_usbdrd_pipe3_set_refclk()
330 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); in exynos5_usbdrd_utmi_set_refclk()
338 reg |= PHYCLKRST_FSEL(phy_drd->extrefclk); in exynos5_usbdrd_utmi_set_refclk()
347 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); in exynos5_usbdrd_pipe3_init()
348 /* Set Tx De-Emphasis level */ in exynos5_usbdrd_pipe3_init()
351 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); in exynos5_usbdrd_pipe3_init()
353 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); in exynos5_usbdrd_pipe3_init()
355 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); in exynos5_usbdrd_pipe3_init()
362 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); in exynos5_usbdrd_utmi_init()
363 /* Set Loss-of-Signal Detector sensitivity */ in exynos5_usbdrd_utmi_init()
366 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); in exynos5_usbdrd_utmi_init()
368 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); in exynos5_usbdrd_utmi_init()
369 /* Set Tx De-Emphasis level */ in exynos5_usbdrd_utmi_init()
372 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); in exynos5_usbdrd_utmi_init()
375 writel(PHYUTMI_OTGDISABLE, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); in exynos5_usbdrd_utmi_init()
377 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); in exynos5_usbdrd_utmi_init()
379 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); in exynos5_usbdrd_utmi_init()
389 ret = clk_prepare_enable(phy_drd->clk); in exynos5_usbdrd_phy_init()
394 writel(0x0, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); in exynos5_usbdrd_phy_init()
395 writel(0x0, phy_drd->reg_phy + EXYNOS5_DRD_PHYRESUME); in exynos5_usbdrd_phy_init()
403 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); in exynos5_usbdrd_phy_init()
405 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); in exynos5_usbdrd_phy_init()
408 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); in exynos5_usbdrd_phy_init()
411 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMICLKSEL); in exynos5_usbdrd_phy_init()
413 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMICLKSEL); in exynos5_usbdrd_phy_init()
416 inst->phy_cfg->phy_init(phy_drd); in exynos5_usbdrd_phy_init()
419 reg = inst->phy_cfg->set_refclk(inst); in exynos5_usbdrd_phy_init()
421 /* Digital power supply in normal operating mode */ in exynos5_usbdrd_phy_init()
432 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); in exynos5_usbdrd_phy_init()
437 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); in exynos5_usbdrd_phy_init()
439 clk_disable_unprepare(phy_drd->clk); in exynos5_usbdrd_phy_init()
451 ret = clk_prepare_enable(phy_drd->clk); in exynos5_usbdrd_phy_exit()
458 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); in exynos5_usbdrd_phy_exit()
461 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); in exynos5_usbdrd_phy_exit()
465 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); in exynos5_usbdrd_phy_exit()
468 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); in exynos5_usbdrd_phy_exit()
471 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); in exynos5_usbdrd_phy_exit()
473 clk_disable_unprepare(phy_drd->clk); in exynos5_usbdrd_phy_exit()
484 dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); in exynos5_usbdrd_phy_power_on()
486 clk_prepare_enable(phy_drd->ref_clk); in exynos5_usbdrd_phy_power_on()
487 if (!phy_drd->drv_data->has_common_clk_gate) { in exynos5_usbdrd_phy_power_on()
488 clk_prepare_enable(phy_drd->pipeclk); in exynos5_usbdrd_phy_power_on()
489 clk_prepare_enable(phy_drd->utmiclk); in exynos5_usbdrd_phy_power_on()
490 clk_prepare_enable(phy_drd->itpclk); in exynos5_usbdrd_phy_power_on()
493 /* Enable VBUS supply */ in exynos5_usbdrd_phy_power_on()
494 if (phy_drd->vbus_boost) { in exynos5_usbdrd_phy_power_on()
495 ret = regulator_enable(phy_drd->vbus_boost); in exynos5_usbdrd_phy_power_on()
497 dev_err(phy_drd->dev, in exynos5_usbdrd_phy_power_on()
498 "Failed to enable VBUS boost supply\n"); in exynos5_usbdrd_phy_power_on()
503 if (phy_drd->vbus) { in exynos5_usbdrd_phy_power_on()
504 ret = regulator_enable(phy_drd->vbus); in exynos5_usbdrd_phy_power_on()
506 dev_err(phy_drd->dev, "Failed to enable VBUS supply\n"); in exynos5_usbdrd_phy_power_on()
511 /* Power-on PHY*/ in exynos5_usbdrd_phy_power_on()
512 inst->phy_cfg->phy_isol(inst, 0); in exynos5_usbdrd_phy_power_on()
517 if (phy_drd->vbus_boost) in exynos5_usbdrd_phy_power_on()
518 regulator_disable(phy_drd->vbus_boost); in exynos5_usbdrd_phy_power_on()
521 clk_disable_unprepare(phy_drd->ref_clk); in exynos5_usbdrd_phy_power_on()
522 if (!phy_drd->drv_data->has_common_clk_gate) { in exynos5_usbdrd_phy_power_on()
523 clk_disable_unprepare(phy_drd->itpclk); in exynos5_usbdrd_phy_power_on()
524 clk_disable_unprepare(phy_drd->utmiclk); in exynos5_usbdrd_phy_power_on()
525 clk_disable_unprepare(phy_drd->pipeclk); in exynos5_usbdrd_phy_power_on()
536 dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n"); in exynos5_usbdrd_phy_power_off()
538 /* Power-off the PHY */ in exynos5_usbdrd_phy_power_off()
539 inst->phy_cfg->phy_isol(inst, 1); in exynos5_usbdrd_phy_power_off()
541 /* Disable VBUS supply */ in exynos5_usbdrd_phy_power_off()
542 if (phy_drd->vbus) in exynos5_usbdrd_phy_power_off()
543 regulator_disable(phy_drd->vbus); in exynos5_usbdrd_phy_power_off()
544 if (phy_drd->vbus_boost) in exynos5_usbdrd_phy_power_off()
545 regulator_disable(phy_drd->vbus_boost); in exynos5_usbdrd_phy_power_off()
547 clk_disable_unprepare(phy_drd->ref_clk); in exynos5_usbdrd_phy_power_off()
548 if (!phy_drd->drv_data->has_common_clk_gate) { in exynos5_usbdrd_phy_power_off()
549 clk_disable_unprepare(phy_drd->itpclk); in exynos5_usbdrd_phy_power_off()
550 clk_disable_unprepare(phy_drd->pipeclk); in exynos5_usbdrd_phy_power_off()
551 clk_disable_unprepare(phy_drd->utmiclk); in exynos5_usbdrd_phy_power_off()
563 writel(val | cmd, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); in crport_handshake()
565 err = readl_poll_timeout(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1, in crport_handshake()
567 if (err == -ETIMEDOUT) { in crport_handshake()
568 dev_err(phy_drd->dev, "CRPORT handshake timeout1 (0x%08x)\n", val); in crport_handshake()
572 writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); in crport_handshake()
574 err = readl_poll_timeout(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1, in crport_handshake()
576 if (err == -ETIMEDOUT) { in crport_handshake()
577 dev_err(phy_drd->dev, "CRPORT handshake timeout2 (0x%08x)\n", val); in crport_handshake()
591 phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); in crport_ctrl_write()
599 phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); in crport_ctrl_write()
634 dev_err(phy_drd->dev, in exynos5420_usbdrd_phy_calibrate()
635 "Failed setting Loss-of-Signal level for SuperSpeed\n"); in exynos5420_usbdrd_phy_calibrate()
648 dev_err(phy_drd->dev, in exynos5420_usbdrd_phy_calibrate()
649 "Failed setting Tx-Vboost-Level for SuperSpeed\n"); in exynos5420_usbdrd_phy_calibrate()
660 * e.g. Samsung SUM-TSB16S 3.0 USB drive. in exynos5420_usbdrd_phy_calibrate()
662 switch (phy_drd->extrefclk) { in exynos5420_usbdrd_phy_calibrate()
680 dev_err(phy_drd->dev, in exynos5420_usbdrd_phy_calibrate()
691 if (WARN_ON(args->args[0] >= EXYNOS5_DRDPHYS_NUM)) in exynos5_usbdrd_phy_xlate()
692 return ERR_PTR(-ENODEV); in exynos5_usbdrd_phy_xlate()
694 return phy_drd->phys[args->args[0]].phy; in exynos5_usbdrd_phy_xlate()
702 if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) in exynos5_usbdrd_phy_calibrate()
721 phy_drd->clk = devm_clk_get(phy_drd->dev, "phy"); in exynos5_usbdrd_phy_clk_handle()
722 if (IS_ERR(phy_drd->clk)) { in exynos5_usbdrd_phy_clk_handle()
723 dev_err(phy_drd->dev, "Failed to get phy clock\n"); in exynos5_usbdrd_phy_clk_handle()
724 return PTR_ERR(phy_drd->clk); in exynos5_usbdrd_phy_clk_handle()
727 phy_drd->ref_clk = devm_clk_get(phy_drd->dev, "ref"); in exynos5_usbdrd_phy_clk_handle()
728 if (IS_ERR(phy_drd->ref_clk)) { in exynos5_usbdrd_phy_clk_handle()
729 dev_err(phy_drd->dev, "Failed to get phy reference clock\n"); in exynos5_usbdrd_phy_clk_handle()
730 return PTR_ERR(phy_drd->ref_clk); in exynos5_usbdrd_phy_clk_handle()
732 ref_rate = clk_get_rate(phy_drd->ref_clk); in exynos5_usbdrd_phy_clk_handle()
734 ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); in exynos5_usbdrd_phy_clk_handle()
736 dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", in exynos5_usbdrd_phy_clk_handle()
741 if (!phy_drd->drv_data->has_common_clk_gate) { in exynos5_usbdrd_phy_clk_handle()
742 phy_drd->pipeclk = devm_clk_get(phy_drd->dev, "phy_pipe"); in exynos5_usbdrd_phy_clk_handle()
743 if (IS_ERR(phy_drd->pipeclk)) { in exynos5_usbdrd_phy_clk_handle()
744 dev_info(phy_drd->dev, in exynos5_usbdrd_phy_clk_handle()
746 phy_drd->pipeclk = NULL; in exynos5_usbdrd_phy_clk_handle()
749 phy_drd->utmiclk = devm_clk_get(phy_drd->dev, "phy_utmi"); in exynos5_usbdrd_phy_clk_handle()
750 if (IS_ERR(phy_drd->utmiclk)) { in exynos5_usbdrd_phy_clk_handle()
751 dev_info(phy_drd->dev, in exynos5_usbdrd_phy_clk_handle()
753 phy_drd->utmiclk = NULL; in exynos5_usbdrd_phy_clk_handle()
756 phy_drd->itpclk = devm_clk_get(phy_drd->dev, "itp"); in exynos5_usbdrd_phy_clk_handle()
757 if (IS_ERR(phy_drd->itpclk)) { in exynos5_usbdrd_phy_clk_handle()
758 dev_info(phy_drd->dev, in exynos5_usbdrd_phy_clk_handle()
760 phy_drd->itpclk = NULL; in exynos5_usbdrd_phy_clk_handle()
810 .compatible = "samsung,exynos5250-usbdrd-phy",
813 .compatible = "samsung,exynos5420-usbdrd-phy",
816 .compatible = "samsung,exynos5433-usbdrd-phy",
819 .compatible = "samsung,exynos7-usbdrd-phy",
828 struct device *dev = &pdev->dev; in exynos5_usbdrd_phy_probe()
829 struct device_node *node = dev->of_node; in exynos5_usbdrd_phy_probe()
840 return -ENOMEM; in exynos5_usbdrd_phy_probe()
843 phy_drd->dev = dev; in exynos5_usbdrd_phy_probe()
845 phy_drd->reg_phy = devm_platform_ioremap_resource(pdev, 0); in exynos5_usbdrd_phy_probe()
846 if (IS_ERR(phy_drd->reg_phy)) in exynos5_usbdrd_phy_probe()
847 return PTR_ERR(phy_drd->reg_phy); in exynos5_usbdrd_phy_probe()
851 return -EINVAL; in exynos5_usbdrd_phy_probe()
853 phy_drd->drv_data = drv_data; in exynos5_usbdrd_phy_probe()
861 reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, in exynos5_usbdrd_phy_probe()
862 "samsung,pmu-syscon"); in exynos5_usbdrd_phy_probe()
875 dev_dbg(dev, "Not a multi-controller usbdrd phy\n"); in exynos5_usbdrd_phy_probe()
879 pmu_offset = phy_drd->drv_data->pmu_offset_usbdrd1_phy; in exynos5_usbdrd_phy_probe()
883 pmu_offset = phy_drd->drv_data->pmu_offset_usbdrd0_phy; in exynos5_usbdrd_phy_probe()
887 /* Get Vbus regulators */ in exynos5_usbdrd_phy_probe()
888 phy_drd->vbus = devm_regulator_get(dev, "vbus"); in exynos5_usbdrd_phy_probe()
889 if (IS_ERR(phy_drd->vbus)) { in exynos5_usbdrd_phy_probe()
890 ret = PTR_ERR(phy_drd->vbus); in exynos5_usbdrd_phy_probe()
891 if (ret == -EPROBE_DEFER) in exynos5_usbdrd_phy_probe()
894 dev_warn(dev, "Failed to get VBUS supply regulator\n"); in exynos5_usbdrd_phy_probe()
895 phy_drd->vbus = NULL; in exynos5_usbdrd_phy_probe()
898 phy_drd->vbus_boost = devm_regulator_get(dev, "vbus-boost"); in exynos5_usbdrd_phy_probe()
899 if (IS_ERR(phy_drd->vbus_boost)) { in exynos5_usbdrd_phy_probe()
900 ret = PTR_ERR(phy_drd->vbus_boost); in exynos5_usbdrd_phy_probe()
901 if (ret == -EPROBE_DEFER) in exynos5_usbdrd_phy_probe()
904 dev_warn(dev, "Failed to get VBUS boost supply regulator\n"); in exynos5_usbdrd_phy_probe()
905 phy_drd->vbus_boost = NULL; in exynos5_usbdrd_phy_probe()
918 phy_drd->phys[i].phy = phy; in exynos5_usbdrd_phy_probe()
919 phy_drd->phys[i].index = i; in exynos5_usbdrd_phy_probe()
920 phy_drd->phys[i].reg_pmu = reg_pmu; in exynos5_usbdrd_phy_probe()
921 phy_drd->phys[i].pmu_offset = pmu_offset; in exynos5_usbdrd_phy_probe()
922 phy_drd->phys[i].phy_cfg = &drv_data->phy_cfg[i]; in exynos5_usbdrd_phy_probe()
923 phy_set_drvdata(phy, &phy_drd->phys[i]); in exynos5_usbdrd_phy_probe()
929 dev_err(phy_drd->dev, "Failed to register phy provider\n"); in exynos5_usbdrd_phy_probe()