[PATCH 0/2] board: visionfive2: add pad drive strength config

gmac0 does not work correctly with the default settings of the pad drive strength. 100Mbit link does not work at all. This series fixes the issue by porting the pad drive strength register configuration from the Linux driver from commit 67a8976780858461b3c2d0dc501d207452543c53.
Lukasz Tekieli (2): net: phy: motorcomm: configure pad drive strength register board: visionfive2: configure PHY pad drive strength
board/starfive/visionfive2/spl.c | 8 ++ drivers/net/phy/motorcomm.c | 130 +++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+)
-- 2.39.2

This ports the pad drive strength register configuration which can be already found in the Linux driver for this PHY.
Signed-off-by: Lukasz Tekieli tekieli.lukasz@gmail.com --- drivers/net/phy/motorcomm.c | 130 ++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c index 8635a960d6e..a2c763c8791 100644 --- a/drivers/net/phy/motorcomm.c +++ b/drivers/net/phy/motorcomm.c @@ -23,6 +23,12 @@
#define YTPHY_SYNCE_CFG_REG 0xA012
+#define YT8531_PAD_DRIVE_STRENGTH_CFG_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_DTS_OUTPUT_CLK_DIS 0 #define YTPHY_DTS_OUTPUT_CLK_25M 25000000 #define YTPHY_DTS_OUTPUT_CLK_125M 125000000 @@ -114,6 +120,10 @@ #define YT8531_CCR_RXC_DLY_EN BIT(8) #define YT8531_CCR_RXC_DLY_1_900_NS 1900
+#define YT8531_CCR_CFG_LDO_MASK GENMASK(5, 4) +#define YT8531_CCR_CFG_LDO_3V3 0x0 +#define YT8531_CCR_CFG_LDO_1V8 0x2 + /* bits in struct ytphy_plat_priv->flag */ #define TX_CLK_ADJ_ENABLED BIT(0) #define AUTO_SLEEP_DISABLED BIT(1) @@ -224,6 +234,17 @@ static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask, return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set); }
+static int ytphy_read_ext(struct phy_device *phydev, u16 regnum) +{ + int ret; + + ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum); + if (ret < 0) + return ret; + + return phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA); +} + static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev) { struct ytphy_plat_priv *priv = phydev->priv; @@ -425,6 +446,111 @@ static int yt8511_config(struct phy_device *phydev) return 0; }
+/** + * 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_CCR_CFG_LDO_1V8, .ds = 0, .cur = 1200}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 1, .cur = 2100}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 2, .cur = 2700}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 3, .cur = 2910}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 4, .cur = 3110}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 5, .cur = 3600}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 6, .cur = 3970}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 7, .cur = 4350}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 0, .cur = 3070}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 1, .cur = 4080}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 2, .cur = 4370}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 3, .cur = 4680}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 4, .cur = 5020}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 5, .cur = 5450}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 6, .cur = 5740}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 7, .cur = 6140}, +}; + +static u32 yt8531_get_ldo_vol(struct phy_device *phydev) +{ + u32 val; + + val = ytphy_read_ext(phydev, YT8531_CHIP_CONFIG_REG); + val = FIELD_GET(YT8531_CCR_CFG_LDO_MASK, val); + + return val <= YT8531_CCR_CFG_LDO_1V8 ? val : YT8531_CCR_CFG_LDO_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) +{ + u32 ds_field_low, ds_field_hi, val; + int ret, ds; + + /* set rgmii rx clk driver strength */ + if (!ofnode_read_u32(phydev->node, "motorcomm,rx-clk-drv-microamp", &val)) { + ds = yt8531_get_ds_map(phydev, val); + if (ds < 0) { + pr_warn("No matching current value was found."); + return -EINVAL; + } + } else { + ds = YT8531_RGMII_RX_DS_DEFAULT; + } + + ret = ytphy_modify_ext(phydev, + YT8531_PAD_DRIVE_STRENGTH_CFG_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 (!ofnode_read_u32(phydev->node, "motorcomm,rx-data-drv-microamp", &val)) { + ds = yt8531_get_ds_map(phydev, val); + if (ds < 0) { + pr_warn("No matching current value was found."); + return -EINVAL; + } + } 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(phydev, + YT8531_PAD_DRIVE_STRENGTH_CFG_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; +} + static int yt8531_config(struct phy_device *phydev) { struct ytphy_plat_priv *priv = phydev->priv; @@ -487,6 +613,10 @@ static int yt8531_config(struct phy_device *phydev) return ret; }
+ ret = yt8531_set_ds(phydev); + if (ret < 0) + return ret; + return 0; }

On Sun, Jan 28, 2024 at 08:22:47PM +0100, Lukasz Tekieli wrote:
This ports the pad drive strength register configuration which can be already found in the Linux driver for this PHY.
Signed-off-by: Lukasz Tekieli tekieli.lukasz@gmail.com
drivers/net/phy/motorcomm.c | 130 ++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
Reviewed-by: Leo Yu-Chi Liang ycliang@andestech.com

Configure the pad drive strength register for both PHYs. The values correspond to what can be found in the Linux DTS for VisionFive2 v1.3b.
Pad drive strength configuration is required for the phy0 to work correctly with 100Mbit links.
Signed-off-by: Lukasz Tekieli tekieli.lukasz@gmail.com --- board/starfive/visionfive2/spl.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c index 336f0cdfc90..ba9c62f2f97 100644 --- a/board/starfive/visionfive2/spl.c +++ b/board/starfive/visionfive2/spl.c @@ -44,6 +44,10 @@ static const struct starfive_vf2_pro starfive_verb[] = { "motorcomm,tx-clk-100-inverted", NULL}, {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "motorcomm,tx-clk-1000-inverted", NULL}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "motorcomm,rx-clk-drv-microamp", "3970"}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "motorcomm,rx-data-drv-microamp", "2910"}, {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps", "1900"}, {"/soc/ethernet@16030000/mdio/ethernet-phy@0", @@ -53,6 +57,10 @@ static const struct starfive_vf2_pro starfive_verb[] = { "motorcomm,tx-clk-adj-enabled", NULL}, { "/soc/ethernet@16040000/mdio/ethernet-phy@1", "motorcomm,tx-clk-100-inverted", NULL}, + {"/soc/ethernet@16040000/mdio/ethernet-phy@1", + "motorcomm,rx-clk-drv-microamp", "3970"}, + {"/soc/ethernet@16040000/mdio/ethernet-phy@1", + "motorcomm,rx-data-drv-microamp", "2910"}, {"/soc/ethernet@16040000/mdio/ethernet-phy@1", "rx-internal-delay-ps", "0"}, {"/soc/ethernet@16040000/mdio/ethernet-phy@1",

On Sun, Jan 28, 2024 at 08:22:48PM +0100, Lukasz Tekieli wrote:
Configure the pad drive strength register for both PHYs. The values correspond to what can be found in the Linux DTS for VisionFive2 v1.3b.
Pad drive strength configuration is required for the phy0 to work correctly with 100Mbit links.
Signed-off-by: Lukasz Tekieli tekieli.lukasz@gmail.com
board/starfive/visionfive2/spl.c | 8 ++++++++ 1 file changed, 8 insertions(+)
Reviewed-by: Leo Yu-Chi Liang ycliang@andestech.com
participants (2)
-
Leo Liang
-
Lukasz Tekieli