diff options
author | shanlong.li <shanlong.li@starfivetech.com> | 2023-05-31 11:14:01 +0300 |
---|---|---|
committer | Minda Chen <minda.chen@starfivetech.com> | 2024-01-11 13:59:08 +0300 |
commit | 053e9d112865f5ea2e79f0100455584796219805 (patch) | |
tree | 39f70fd3440e2f11627077a9ab0a7f2f55b6b438 | |
parent | c6abff96e98932130f2c8014782e633c57e8c91d (diff) | |
download | linux-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.c | 62 |
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; } |