Hi Neil, > -----Original Message----- > From: Pritam Manohar Sutar <pritam.sutar@xxxxxxxxxxx> > Sent: 01 July 2025 05:37 PM > To: vkoul@xxxxxxxxxx; kishon@xxxxxxxxxx; robh@xxxxxxxxxx; > krzk+dt@xxxxxxxxxx; conor+dt@xxxxxxxxxx; alim.akhtar@xxxxxxxxxxx; > andre.draszik@xxxxxxxxxx; peter.griffin@xxxxxxxxxx; neil.armstrong@xxxxxxxxxx; > kauschluss@xxxxxxxxxxx; ivo.ivanov.ivanov1@xxxxxxxxx; > m.szyprowski@xxxxxxxxxxx; s.nawrocki@xxxxxxxxxxx; > pritam.sutar@xxxxxxxxxxx > Cc: linux-phy@xxxxxxxxxxxxxxxxxxx; devicetree@xxxxxxxxxxxxxxx; linux- > kernel@xxxxxxxxxxxxxxx; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux-samsung- > soc@xxxxxxxxxxxxxxx; rosa.pila@xxxxxxxxxxx; dev.tailor@xxxxxxxxxxx; > faraz.ata@xxxxxxxxxxx; muhammed.ali@xxxxxxxxxxx; > selvarasu.g@xxxxxxxxxxx > Subject: [PATCH v4 2/6] phy: exynos5-usbdrd: support HS phy for > ExynosAutov920 > > This SoC has a single USB 3.1 DRD combo phy that supports both > UTMI+ (HS) and PIPE3 (SS) and three USB2.0 DRD HS phy controllers > those only support the UTMI+ (HS) interface. > > Support only UTMI+ port for this SoC which is very similar to what the existing > Exynos850 supports. > > This SoC shares phy isol between USBs. Bypass PHY isol when first USB is > powered on and enable it when all of then are powered off. Add required > change in phy driver to support HS phy for this SoC. > > Reviewed-by: Neil Armstrong <neil.armstrong@xxxxxxxxxx> > Signed-off-by: Pritam Manohar Sutar <pritam.sutar@xxxxxxxxxxx> > --- > drivers/phy/samsung/phy-exynos5-usbdrd.c | 131 ++++++++++++++++++++ > include/linux/soc/samsung/exynos-regs-pmu.h | 2 + > 2 files changed, 133 insertions(+) > > diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c > b/drivers/phy/samsung/phy-exynos5-usbdrd.c > index dd660ebe8045..64f3316f6ad4 100644 > --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c > +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c > @@ -480,6 +480,8 @@ struct exynos5_usbdrd_phy { > enum typec_orientation orientation; > }; > > +static atomic_t usage_count = ATOMIC_INIT(0); > + Added phy isolation for exynosautov920 support as per comments on v3 patch-set. Since phy isol is shared across usb ports, added usage counter to bypass and enable it. Can you please review the code? However, added "Reviewed-by" tag as per comments on v3 patch-set. > static inline > struct exynos5_usbdrd_phy *to_usbdrd_phy(struct phy_usb_instance *inst) { > @@ -2054,6 +2056,132 @@ 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; > + > + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) { > + /* Bypass PHY isol when first USB is powered on */ > + if ((atomic_inc_return(&usage_count) == 1)) > + 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 = 0; > + > + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd- > >clks); > + if (ret) > + return ret; > + > + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) { > + exynos850_usbdrd_phy_exit(phy); > + > + /* enable PHY isol when all USBs are powered off */ > + if (atomic_dec_and_test(&usage_count)) > + 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) { > + int ret; > + 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_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_regulator_names[] = { > + "avdd075_usb", "avdd18_usb20", "avdd33_usb20", }; > + > +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_regulator_names, > + .n_regulators = > ARRAY_SIZE(exynosautov920_regulator_names), > +}; > + > static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = { > { > .id = EXYNOS5_DRDPHY_UTMI, > @@ -2260,6 +2388,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 > }, > { }, > }; > diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h > b/include/linux/soc/samsung/exynos-regs-pmu.h > index 71e0c09a49eb..4923f9be3d1f 100644 > --- a/include/linux/soc/samsung/exynos-regs-pmu.h > +++ b/include/linux/soc/samsung/exynos-regs-pmu.h > @@ -688,4 +688,6 @@ > #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 */ > -- > 2.34.1 Thank you. Regards, Pritam