diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2026-06-10 03:31:33 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-10 03:31:33 +0300 |
| commit | e8b38659decc03392200e082cdf3c57e9a4791b9 (patch) | |
| tree | eab80ee82a23d840614fe06f34f8fde42f5adbae | |
| parent | 81a699ccd3091915d00da847df8dac0d1b131693 (diff) | |
| parent | 554cfeb72e093102896f3f8b638c81a460f6449b (diff) | |
| download | linux-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.c | 77 |
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) }, |
