]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
phy: exynos5-usbdrd: support HS phy for ExynosAutov920
authorPritam Manohar Sutar <pritam.sutar@samsung.com>
Mon, 24 Nov 2025 11:04:49 +0000 (16:34 +0530)
committerVinod Koul <vkoul@kernel.org>
Tue, 23 Dec 2025 17:41:05 +0000 (23:11 +0530)
Enable UTMI+ phy support for this SoC which is very similar to what
the existing Exynos850 supports.

Add required change in phy driver to support HS phy for this SoC.

Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
Signed-off-by: Pritam Manohar Sutar <pritam.sutar@samsung.com>
Link: https://patch.msgid.link/20251124110453.2887437-3-pritam.sutar@samsung.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/samsung/phy-exynos5-usbdrd.c
include/linux/soc/samsung/exynos-regs-pmu.h

index 1c8bf80119f11e2cd2f07c829986908c150688ac..7416d2e1e358014fcdee06476130a0a91ea87459 100644 (file)
@@ -2054,6 +2054,126 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
        .n_regulators           = ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static int exynosautov920_usbdrd_phy_init(struct phy *phy)
+{
+       struct phy_usb_instance *inst = phy_get_drvdata(phy);
+       struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+       int ret;
+
+       ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+       if (ret)
+               return ret;
+
+       /* Bypass PHY isol */
+       inst->phy_cfg->phy_isol(inst, false);
+
+       /* UTMI or PIPE3 specific init */
+       inst->phy_cfg->phy_init(phy_drd);
+
+       clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+       return 0;
+}
+
+static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
+{
+       struct phy_usb_instance *inst = phy_get_drvdata(phy);
+       struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+       int ret;
+
+       ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+       if (ret)
+               return ret;
+
+       exynos850_usbdrd_phy_exit(phy);
+
+       /* enable PHY isol */
+       inst->phy_cfg->phy_isol(inst, true);
+
+       clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+       return 0;
+}
+
+static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
+{
+       struct phy_usb_instance *inst = phy_get_drvdata(phy);
+       struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+       int ret;
+
+       dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n");
+
+       ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks,
+                                     phy_drd->core_clks);
+       if (ret)
+               return ret;
+
+       /* Enable supply */
+       ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators,
+                                   phy_drd->regulators);
+       if (ret) {
+               dev_err(phy_drd->dev, "Failed to enable PHY regulator(s)\n");
+               goto fail_supply;
+       }
+
+       return 0;
+
+fail_supply:
+       clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
+                                  phy_drd->core_clks);
+
+       return ret;
+}
+
+static int exynosautov920_usbdrd_phy_power_off(struct phy *phy)
+{
+       struct phy_usb_instance *inst = phy_get_drvdata(phy);
+       struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+
+       dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n");
+
+       /* Disable supply */
+       regulator_bulk_disable(phy_drd->drv_data->n_regulators,
+                              phy_drd->regulators);
+
+       clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
+                                  phy_drd->core_clks);
+
+       return 0;
+}
+
+static const char * const exynosautov920_usb20_regulators[] = {
+       "dvdd", "vdd18", "vdd33",
+};
+
+static const struct phy_ops exynosautov920_usbdrd_phy_ops = {
+       .init           = exynosautov920_usbdrd_phy_init,
+       .exit           = exynosautov920_usbdrd_phy_exit,
+       .power_on       = exynosautov920_usbdrd_phy_power_on,
+       .power_off      = exynosautov920_usbdrd_phy_power_off,
+       .owner          = THIS_MODULE,
+};
+
+static const struct exynos5_usbdrd_phy_config phy_cfg_exynosautov920[] = {
+       {
+               .id             = EXYNOS5_DRDPHY_UTMI,
+               .phy_isol       = exynos5_usbdrd_phy_isol,
+               .phy_init       = exynos850_usbdrd_utmi_init,
+       },
+};
+
+static const struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_phy = {
+       .phy_cfg                = phy_cfg_exynosautov920,
+       .phy_ops                = &exynosautov920_usbdrd_phy_ops,
+       .pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB20,
+       .clk_names              = exynos5_clk_names,
+       .n_clks                 = ARRAY_SIZE(exynos5_clk_names),
+       .core_clk_names         = exynos5_core_clk_names,
+       .n_core_clks            = ARRAY_SIZE(exynos5_core_clk_names),
+       .regulator_names        = exynosautov920_usb20_regulators,
+       .n_regulators           = ARRAY_SIZE(exynosautov920_usb20_regulators),
+};
+
 static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = {
        {
                .id             = EXYNOS5_DRDPHY_UTMI,
@@ -2260,6 +2380,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
        }, {
                .compatible = "samsung,exynos990-usbdrd-phy",
                .data = &exynos990_usbdrd_phy
+       }, {
+               .compatible = "samsung,exynosautov920-usbdrd-phy",
+               .data = &exynosautov920_usbdrd_phy
        },
        { },
 };
index 532c6c2d11950c606576805aeeb38b4612cd2d44..ab4d8be0e0738a0300395f739f559c30126d2c84 100644 (file)
 #define GS101_GRP2_INTR_BID_UPEND                              (0x0208)
 #define GS101_GRP2_INTR_BID_CLEAR                              (0x020c)
 
+/* exynosautov920 */
+#define EXYNOSAUTOV920_PHY_CTRL_USB20                          (0x0710)
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */