summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-06-10 03:31:33 +0300
committerJakub Kicinski <kuba@kernel.org>2026-06-10 03:31:33 +0300
commite8b38659decc03392200e082cdf3c57e9a4791b9 (patch)
treeeab80ee82a23d840614fe06f34f8fde42f5adbae
parent81a699ccd3091915d00da847df8dac0d1b131693 (diff)
parent554cfeb72e093102896f3f8b638c81a460f6449b (diff)
downloadlinux-e8b38659decc03392200e082cdf3c57e9a4791b9.tar.xz
Merge branch 'add-motorcomm-8531s-set-ds-func-and-8522-driver'
Minda Chen says: ==================== Add motorcomm 8531s set ds func and 8522 driver This patch is for Starfive JHB100 EVB board. JHB100 contain 1 RGMII/RMII and 1 RMII synopsys GMAC cores. In the EVB board, RGMII interface connect with YT8531s Ethernet PHY. RMII interface connect with YT8522 ethernet PHY. So patch 1-2 is for RGMII interface patch 3 is RMII is for RMII interface. JHB100 is a Starfive new RISC-V SoC for datacenter BMC (BaseBoard Managent Controller). Similar with Aspeed 27x0. The JHB100 minimal system upstream is in progress: https://patchwork.kernel.org/project/linux-riscv/cover/20260508053632.818548-1-changhuang.liang@starfivetech.com/ ==================== Link: https://patch.msgid.link/20260605060212.41895-1-minda.chen@starfivetech.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/phy/motorcomm.c77
1 files changed, 67 insertions, 10 deletions
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index 708491bc198a..5071605a1a11 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Motorcomm 8511/8521/8531/8531S/8821 PHY driver.
+ * Motorcomm 8511/8521/8522/8531/8531S/8821 PHY driver.
*
* Author: Peter Geis <pgwipeout@gmail.com>
* Author: Frank <Frank.Sae@motor-comm.com>
@@ -14,6 +14,7 @@
#define PHY_ID_YT8511 0x0000010a
#define PHY_ID_YT8521 0x0000011a
+#define PHY_ID_YT8522 0x4f51e928
#define PHY_ID_YT8531 0x4f51e91b
#define PHY_ID_YT8531S 0x4f51e91a
#define PHY_ID_YT8821 0x4f51ea19
@@ -227,6 +228,13 @@
#define YT8521_LED_100_ON_EN BIT(5)
#define YT8521_LED_10_ON_EN BIT(4)
+#define YT8522_EXTREG_SLEEP_CONTROL 0x2027
+#define YT8522_EN_SLEEP_SW BIT(15)
+
+#define YT8522_EXTENDED_COMBO_CTRL 0x4000
+#define YT8522_RXDV_SEL BIT(4)
+#define YT8522_RMII_EN BIT(1)
+
#define YTPHY_MISC_CONFIG_REG 0xA006
#define YTPHY_MCR_FIBER_SPEED_MASK BIT(0)
#define YTPHY_MCR_FIBER_1000BX (0x1 << 0)
@@ -974,7 +982,8 @@ static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
{
u32 val;
- val = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG);
+ val = ytphy_read_ext(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;
@@ -1010,10 +1019,11 @@ static int yt8531_set_ds(struct phy_device *phydev)
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));
+ ret = ytphy_modify_ext(phydev,
+ YTPHY_PAD_DRIVE_STRENGTH_REG,
+ YT8531_RGMII_RXC_DS_MASK,
+ FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
+
if (ret < 0)
return ret;
@@ -1033,10 +1043,11 @@ static int yt8531_set_ds(struct phy_device *phydev)
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);
+ ret = ytphy_modify_ext(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;
@@ -1694,6 +1705,11 @@ static int yt8521_config_init(struct phy_device *phydev)
if (ret < 0)
goto err_restore_page;
}
+
+ if (phy_interface_is_rgmii(phydev) &&
+ phydev_id_compare(phydev, PHY_ID_YT8531S))
+ ret = yt8531_set_ds(phydev);
+
err_restore_page:
return phy_restore_page(phydev, old_page, ret);
}
@@ -1825,13 +1841,45 @@ static int yt8531_config_init(struct phy_device *phydev)
return ret;
}
+ phy_lock_mdio_bus(phydev);
ret = yt8531_set_ds(phydev);
+ phy_unlock_mdio_bus(phydev);
if (ret < 0)
return ret;
return 0;
}
+static int yt8522_config_init(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int ret, val;
+
+ val = ytphy_read_ext_with_lock(phydev, YT8522_EXTENDED_COMBO_CTRL);
+ if (val < 0)
+ return val;
+
+ if (val & YT8522_RMII_EN) {
+ val |= YT8522_RXDV_SEL;
+ ret = ytphy_write_ext_with_lock(phydev,
+ YT8522_EXTENDED_COMBO_CTRL,
+ val);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (device_property_read_bool(dev, "motorcomm,auto-sleep-disabled")) {
+ /* disable auto sleep */
+ ret = ytphy_modify_ext_with_lock(phydev,
+ YT8522_EXTREG_SLEEP_CONTROL,
+ YT8522_EN_SLEEP_SW, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
/**
* yt8531_link_change_notify() - Adjust the tx clock direction according to
* the current speed and dts config.
@@ -3042,6 +3090,14 @@ static struct phy_driver motorcomm_phy_drvs[] = {
.led_hw_control_get = yt8521_led_hw_control_get,
},
{
+ PHY_ID_MATCH_EXACT(PHY_ID_YT8522),
+ .name = "YT8522 100 Megabit Ethernet",
+ .config_aneg = genphy_config_aneg,
+ .config_init = yt8522_config_init,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ },
+ {
PHY_ID_MATCH_EXACT(PHY_ID_YT8531),
.name = "YT8531 Gigabit Ethernet",
.probe = yt8531_probe,
@@ -3101,6 +3157,7 @@ MODULE_LICENSE("GPL");
static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8522) },
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8531) },
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8821) },