#define YT8521_CHIP_CONFIG_REG                 0xA001
 #define YT8521_CCR_SW_RST                      BIT(15)
+#define YT8531_RGMII_LDO_VOL_MASK              GENMASK(5, 4)
+#define YT8531_LDO_VOL_3V3                     0x0
+#define YT8531_LDO_VOL_1V8                     0x2
+
 /* 1b0 disable 1.9ns rxc clock delay  *default*
  * 1b1 enable 1.9ns rxc clock delay
  */
  */
 #define YTPHY_WCR_TYPE_PULSE                   BIT(0)
 
+#define YTPHY_PAD_DRIVE_STRENGTH_REG           0xA010
+#define YT8531_RGMII_RXC_DS_MASK               GENMASK(15, 13)
+#define YT8531_RGMII_RXD_DS_HI_MASK            BIT(12)         /* Bit 2 of rxd_ds */
+#define YT8531_RGMII_RXD_DS_LOW_MASK           GENMASK(5, 4)   /* Bit 1/0 of rxd_ds */
+#define YT8531_RGMII_RX_DS_DEFAULT             0x3
+
 #define YTPHY_SYNCE_CFG_REG                    0xA012
 #define YT8521_SCR_SYNCE_ENABLE                        BIT(5)
 /* 1b0 output 25m clock
        return ret;
 }
 
+/**
+ * struct ytphy_ldo_vol_map - map a current value to a register value
+ * @vol: ldo voltage
+ * @ds:  value in the register
+ * @cur: value in device configuration
+ */
+struct ytphy_ldo_vol_map {
+       u32 vol;
+       u32 ds;
+       u32 cur;
+};
+
+static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
+       {.vol = YT8531_LDO_VOL_1V8, .ds = 0, .cur = 1200},
+       {.vol = YT8531_LDO_VOL_1V8, .ds = 1, .cur = 2100},
+       {.vol = YT8531_LDO_VOL_1V8, .ds = 2, .cur = 2700},
+       {.vol = YT8531_LDO_VOL_1V8, .ds = 3, .cur = 2910},
+       {.vol = YT8531_LDO_VOL_1V8, .ds = 4, .cur = 3110},
+       {.vol = YT8531_LDO_VOL_1V8, .ds = 5, .cur = 3600},
+       {.vol = YT8531_LDO_VOL_1V8, .ds = 6, .cur = 3970},
+       {.vol = YT8531_LDO_VOL_1V8, .ds = 7, .cur = 4350},
+       {.vol = YT8531_LDO_VOL_3V3, .ds = 0, .cur = 3070},
+       {.vol = YT8531_LDO_VOL_3V3, .ds = 1, .cur = 4080},
+       {.vol = YT8531_LDO_VOL_3V3, .ds = 2, .cur = 4370},
+       {.vol = YT8531_LDO_VOL_3V3, .ds = 3, .cur = 4680},
+       {.vol = YT8531_LDO_VOL_3V3, .ds = 4, .cur = 5020},
+       {.vol = YT8531_LDO_VOL_3V3, .ds = 5, .cur = 5450},
+       {.vol = YT8531_LDO_VOL_3V3, .ds = 6, .cur = 5740},
+       {.vol = YT8531_LDO_VOL_3V3, .ds = 7, .cur = 6140},
+};
+
+static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
+{
+       u32 val;
+
+       val = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG);
+       val = FIELD_GET(YT8531_RGMII_LDO_VOL_MASK, val);
+
+       return val <= YT8531_LDO_VOL_1V8 ? val : YT8531_LDO_VOL_1V8;
+}
+
+static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
+{
+       u32 vol;
+       int i;
+
+       vol = yt8531_get_ldo_vol(phydev);
+       for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
+               if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
+                       return yt8531_ldo_vol[i].ds;
+       }
+
+       return -EINVAL;
+}
+
+static int yt8531_set_ds(struct phy_device *phydev)
+{
+       struct device_node *node = phydev->mdio.dev.of_node;
+       u32 ds_field_low, ds_field_hi, val;
+       int ret, ds;
+
+       /* set rgmii rx clk driver strength */
+       if (!of_property_read_u32(node, "motorcomm,rx-clk-drv-microamp", &val)) {
+               ds = yt8531_get_ds_map(phydev, val);
+               if (ds < 0)
+                       return dev_err_probe(&phydev->mdio.dev, ds,
+                                            "No matching current value was found.\n");
+       } else {
+               ds = YT8531_RGMII_RX_DS_DEFAULT;
+       }
+
+       ret = ytphy_modify_ext_with_lock(phydev,
+                                        YTPHY_PAD_DRIVE_STRENGTH_REG,
+                                        YT8531_RGMII_RXC_DS_MASK,
+                                        FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
+       if (ret < 0)
+               return ret;
+
+       /* set rgmii rx data driver strength */
+       if (!of_property_read_u32(node, "motorcomm,rx-data-drv-microamp", &val)) {
+               ds = yt8531_get_ds_map(phydev, val);
+               if (ds < 0)
+                       return dev_err_probe(&phydev->mdio.dev, ds,
+                                            "No matching current value was found.\n");
+       } else {
+               ds = YT8531_RGMII_RX_DS_DEFAULT;
+       }
+
+       ds_field_hi = FIELD_GET(BIT(2), ds);
+       ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
+
+       ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
+       ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
+
+       ret = ytphy_modify_ext_with_lock(phydev,
+                                        YTPHY_PAD_DRIVE_STRENGTH_REG,
+                                        YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
+                                        ds_field_low | ds_field_hi);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
 /**
  * yt8521_probe() - read chip config then set suitable polling_mode
  * @phydev: a pointer to a &struct phy_device
                        return ret;
        }
 
+       ret = yt8531_set_ds(phydev);
+       if (ret < 0)
+               return ret;
+
        return 0;
 }