summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshanlong.li <shanlong.li@starfivetech.com>2023-05-31 11:14:01 +0300
committerMinda Chen <minda.chen@starfivetech.com>2024-01-11 13:59:08 +0300
commit053e9d112865f5ea2e79f0100455584796219805 (patch)
tree39f70fd3440e2f11627077a9ab0a7f2f55b6b438
parentc6abff96e98932130f2c8014782e633c57e8c91d (diff)
downloadlinux-053e9d112865f5ea2e79f0100455584796219805.tar.xz
net: phy: motorcomm: Add pad drive strength cfg support
The motorcomm phy (YT8531) supports the ability to adjust the drive strength of the rx_clk/rx_data, and the default strength may not be suitable for all boards. So add configurable options to better match the boards.(e.g. StarFive VisionFive 2) Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
-rw-r--r--drivers/net/phy/motorcomm.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index 08f28ed83e60..e5d6b491046e 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -237,9 +237,13 @@
#define YTPHY_WCR_TYPE_PULSE BIT(0)
#define YTPHY_PAD_DRIVE_STRENGTH_REG 0xA010
-#define YTPHY_RGMII_RXC_DS GENMASK(15, 13)
-#define YTPHY_RGMII_RXD_DS GENMASK(5, 4) /* Bit 1 and 0 of rgmii_rxd_ds */
-#define YTPHY_RGMII_RXD_DS2 BIT(12) /* Bit 2 of rgmii_rxd_ds */
+#define YT8531_RGMII_RXC_DS_DEFAULT 0x3
+#define YT8531_RGMII_RXC_DS_MAX 0x7
+#define YT8531_RGMII_RXC_DS GENMASK(15, 13)
+#define YT8531_RGMII_RXD_DS_DEFAULT 0x3
+#define YT8531_RGMII_RXD_DS_MAX 0x7
+#define YT8531_RGMII_RXD_DS_LOW GENMASK(5, 4) /* Bit 1/0 of rxd_ds */
+#define YT8531_RGMII_RXD_DS_HI BIT(12) /* Bit 2 of rxd_ds */
#define YTPHY_SYNCE_CFG_REG 0xA012
#define YT8521_SCR_SYNCE_ENABLE BIT(5)
@@ -1499,8 +1503,8 @@ err_restore_page:
static int yt8531_config_init(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;
+ u32 ds, val;
int ret;
- u32 val;
ret = ytphy_rgmii_clk_delay_config_with_lock(phydev);
if (ret < 0)
@@ -1524,32 +1528,42 @@ static int yt8531_config_init(struct phy_device *phydev)
return ret;
}
- if (!of_property_read_u32(node, "rx-clk-driver-strength", &val)) {
- ret = ytphy_modify_ext_with_lock(phydev,
- YTPHY_PAD_DRIVE_STRENGTH_REG,
- YTPHY_RGMII_RXC_DS,
- FIELD_PREP(YTPHY_RGMII_RXC_DS, val));
- if (ret < 0)
- return ret;
+ ds = YT8531_RGMII_RXC_DS_DEFAULT;
+ if (!of_property_read_u32(node, "motorcomm,rx-clk-driver-strength", &val)) {
+ if (val > YT8531_RGMII_RXC_DS_MAX)
+ return -EINVAL;
+
+ ds = val;
}
- if (!of_property_read_u32(node, "rx-data-driver-strength", &val)) {
- if (val > FIELD_MAX(YTPHY_RGMII_RXD_DS)) {
- val &= FIELD_MAX(YTPHY_RGMII_RXD_DS);
- val = FIELD_PREP(YTPHY_RGMII_RXD_DS, val);
- val |= YTPHY_RGMII_RXD_DS2;
+ ret = ytphy_modify_ext_with_lock(phydev,
+ YTPHY_PAD_DRIVE_STRENGTH_REG,
+ YT8531_RGMII_RXC_DS,
+ FIELD_PREP(YT8531_RGMII_RXC_DS, ds));
+ if (ret < 0)
+ return ret;
+
+ ds = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW, YT8531_RGMII_RXD_DS_DEFAULT);
+ if (!of_property_read_u32(node, "motorcomm,rx-data-driver-strength", &val)) {
+ if (val > YT8531_RGMII_RXD_DS_MAX)
+ return -EINVAL;
+
+ if (val > FIELD_MAX(YT8531_RGMII_RXD_DS_LOW)) {
+ ds = val & FIELD_MAX(YT8531_RGMII_RXD_DS_LOW);
+ ds = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW, ds);
+ ds |= YT8531_RGMII_RXD_DS_HI;
} else {
- val = FIELD_PREP(YTPHY_RGMII_RXD_DS, val);
+ ds = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW, val);
}
-
- ret = ytphy_modify_ext_with_lock(phydev,
- YTPHY_PAD_DRIVE_STRENGTH_REG,
- YTPHY_RGMII_RXD_DS | YTPHY_RGMII_RXD_DS2,
- val);
- if (ret < 0)
- return ret;
}
+ ret = ytphy_modify_ext_with_lock(phydev,
+ YTPHY_PAD_DRIVE_STRENGTH_REG,
+ YT8531_RGMII_RXD_DS_LOW | YT8531_RGMII_RXD_DS_HI,
+ ds);
+ if (ret < 0)
+ return ret;
+
return 0;
}