From 5fc98f62c4fce75c7db9e89112cced08a5fc24d2 Mon Sep 17 00:00:00 2001 From: AmadeusGhost <42570690+AmadeusGhost@users.noreply.github.com> Date: Tue, 29 Nov 2022 23:18:06 +0800 Subject: [PATCH] rockchip: backport yt8531s driver from net-next Fixes: #10497 --- ...net-phy-add-Motorcomm-YT8531S-phy-id.patch | 140 ++++++++++ ...e-Improve-fallback-to-speed-modes-if.patch | 2 +- ...-driver-for-Motorcomm-yt8531-gigabit.patch | 254 ++++++++++++++++++ ...dd-support-for-Motorcomm-yt8531C-phy.patch | 141 ---------- ...net-phy-add-Motorcomm-YT8531S-phy-id.patch | 140 ++++++++++ ...-driver-for-Motorcomm-yt8531-gigabit.patch | 254 ++++++++++++++++++ ...dd-support-for-Motorcomm-yt8531C-phy.patch | 141 ---------- 7 files changed, 789 insertions(+), 283 deletions(-) create mode 100644 target/linux/rockchip/patches-5.15/073-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch create mode 100644 target/linux/rockchip/patches-5.15/108-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch delete mode 100644 target/linux/rockchip/patches-5.15/108-net-phy-add-support-for-Motorcomm-yt8531C-phy.patch create mode 100644 target/linux/rockchip/patches-6.0/021-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch create mode 100644 target/linux/rockchip/patches-6.0/108-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch delete mode 100644 target/linux/rockchip/patches-6.0/108-net-phy-add-support-for-Motorcomm-yt8531C-phy.patch diff --git a/target/linux/rockchip/patches-5.15/073-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch b/target/linux/rockchip/patches-5.15/073-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch new file mode 100644 index 000000000..e7fea514f --- /dev/null +++ b/target/linux/rockchip/patches-5.15/073-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch @@ -0,0 +1,140 @@ +From 813abcd98fb1b2cccf850cdfa092a4bfc50b2363 Mon Sep 17 00:00:00 2001 +From: Frank +Date: Tue, 22 Nov 2022 16:42:32 +0800 +Subject: [PATCH] net: phy: add Motorcomm YT8531S phy id. + +We added patch for motorcomm.c to support YT8531S. This patch has +been tested on AM335x platform which has one YT8531S interface +card and passed all test cases. +The tested cases indluding: YT8531S UTP function with support of +10M/100M/1000M; YT8531S Fiber function with support of 100M/1000M; +and YT8531S Combo function that supports auto detection of media type. + +Since most functions of YT8531S are similar to YT8521 and we reuse some +codes for YT8521 in the patch file. + +Signed-off-by: Frank +Signed-off-by: David S. Miller +--- + drivers/net/phy/Kconfig | 2 +- + drivers/net/phy/motorcomm.c | 52 +++++++++++++++++++++++++++++++++---- + 2 files changed, 48 insertions(+), 6 deletions(-) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -319,7 +319,7 @@ config MOTORCOMM_PHY + tristate "Motorcomm PHYs" + help + Enables support for Motorcomm network PHYs. +- Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs. ++ Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. + + config NATIONAL_PHY + tristate "National Semiconductor PHYs" +--- 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 PHY driver. ++ * Motorcomm 8511/8521/8531S PHY driver. + * + * Author: Peter Geis + * Author: Frank +@@ -12,9 +12,10 @@ + #include + + #define PHY_ID_YT8511 0x0000010a +-#define PHY_ID_YT8521 0x0000011A ++#define PHY_ID_YT8521 0x0000011A ++#define PHY_ID_YT8531S 0x4F51E91A + +-/* YT8521 Register Overview ++/* YT8521/YT8531S Register Overview + * UTP Register space | FIBER Register space + * ------------------------------------------------------------ + * | UTP MII | FIBER MII | +@@ -147,7 +148,7 @@ + #define YT8521_LINK_TIMER_CFG2_REG 0xA5 + #define YT8521_LTCR_EN_AUTOSEN BIT(15) + +-/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers ++/* 0xA000, 0xA001, 0xA003, 0xA006 ~ 0xA00A and 0xA012 are common ext registers + * of yt8521 phy. There is no need to switch reg space when operating these + * registers. + */ +@@ -221,6 +222,9 @@ + */ + #define YTPHY_WCR_TYPE_PULSE BIT(0) + ++#define YT8531S_SYNCE_CFG_REG 0xA012 ++#define YT8531S_SCR_SYNCE_ENABLE BIT(6) ++ + /* Extended Register end */ + + struct yt8521_priv { +@@ -647,6 +651,26 @@ static int yt8521_probe(struct phy_device *phydev) + return 0; + } + ++/** ++ * yt8531s_probe() - read chip config then set suitable polling_mode ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531s_probe(struct phy_device *phydev) ++{ ++ int ret; ++ ++ /* Disable SyncE clock output by default */ ++ ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG, ++ YT8531S_SCR_SYNCE_ENABLE, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* same as yt8521_probe */ ++ return yt8521_probe(phydev); ++} ++ + /** + * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp + * @phydev: a pointer to a &struct phy_device +@@ -1750,11 +1774,28 @@ static struct phy_driver motorcomm_phy_drvs[] = { + .suspend = yt8521_suspend, + .resume = yt8521_resume, + }, ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), ++ .name = "YT8531S Gigabit Ethernet", ++ .get_features = yt8521_get_features, ++ .probe = yt8531s_probe, ++ .read_page = yt8521_read_page, ++ .write_page = yt8521_write_page, ++ .get_wol = ytphy_get_wol, ++ .set_wol = ytphy_set_wol, ++ .config_aneg = yt8521_config_aneg, ++ .aneg_done = yt8521_aneg_done, ++ .config_init = yt8521_config_init, ++ .read_status = yt8521_read_status, ++ .soft_reset = yt8521_soft_reset, ++ .suspend = yt8521_suspend, ++ .resume = yt8521_resume, ++ }, + }; + + module_phy_driver(motorcomm_phy_drvs); + +-MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver"); ++MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); + MODULE_AUTHOR("Peter Geis"); + MODULE_AUTHOR("Frank"); + MODULE_LICENSE("GPL"); +@@ -1762,6 +1803,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_YT8531S) }, + { /* sentinal */ } + }; + diff --git a/target/linux/rockchip/patches-5.15/080-v5.18-mmc-core-Improve-fallback-to-speed-modes-if.patch b/target/linux/rockchip/patches-5.15/080-v5.18-mmc-core-Improve-fallback-to-speed-modes-if.patch index 142ddf98b..574a5cb29 100644 --- a/target/linux/rockchip/patches-5.15/080-v5.18-mmc-core-Improve-fallback-to-speed-modes-if.patch +++ b/target/linux/rockchip/patches-5.15/080-v5.18-mmc-core-Improve-fallback-to-speed-modes-if.patch @@ -25,7 +25,7 @@ Link: https://lore.kernel.org/r/20220303164522.129583-1-ulf.hansson@linaro.org --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c -@@ -1523,13 +1523,23 @@ static int mmc_select_timing(struct mmc_card *card) +@@ -1530,13 +1530,23 @@ static int mmc_select_timing(struct mmc_card *card) if (!mmc_can_ext_csd(card)) goto bus_speed; diff --git a/target/linux/rockchip/patches-5.15/108-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch b/target/linux/rockchip/patches-5.15/108-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch new file mode 100644 index 000000000..c1e16d40f --- /dev/null +++ b/target/linux/rockchip/patches-5.15/108-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch @@ -0,0 +1,254 @@ +From cfb1aa4c805e58287dd0ce292b5c64309e3dba2f Mon Sep 17 00:00:00 2001 +From: Frank +Date: Wed, 30 Nov 2022 17:49:28 +0800 +Subject: [PATCH] net: phy: Add driver for Motorcomm yt8531 gigabit ethernet phy + +Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have +verified the patch on AM335x platform which has one YT8531 interface +card and passed all test cases. The tested cases indluding: YT8531 UTP +function with support of 10M/100M/1000M and wol(based on magic packet). + +Signed-off-by: Frank +--- + drivers/net/phy/Kconfig | 2 +- + drivers/net/phy/motorcomm.c | 162 ++++++++++++++++++++++++++++++++++-- + 2 files changed, 158 insertions(+), 6 deletions(-) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -319,7 +319,7 @@ config MOTORCOMM_PHY + tristate "Motorcomm PHYs" + help + Enables support for Motorcomm network PHYs. +- Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. ++ Currently supports the YT8511, YT8521, YT8531, YT8531S Gigabit Ethernet PHYs. + + config NATIONAL_PHY + tristate "National Semiconductor PHYs" +--- 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/8531S PHY driver. ++ * Motorcomm 8511/8521/8531/8531S PHY driver. + * + * Author: Peter Geis + * Author: Frank +@@ -12,8 +12,9 @@ + #include + + #define PHY_ID_YT8511 0x0000010a +-#define PHY_ID_YT8521 0x0000011A +-#define PHY_ID_YT8531S 0x4F51E91A ++#define PHY_ID_YT8521 0x0000011a ++#define PHY_ID_YT8531 0x4f51e91b ++#define PHY_ID_YT8531S 0x4f51e91a + + /* YT8521/YT8531S Register Overview + * UTP Register space | FIBER Register space +@@ -225,6 +226,9 @@ + #define YT8531S_SYNCE_CFG_REG 0xA012 + #define YT8531S_SCR_SYNCE_ENABLE BIT(6) + ++#define YT8531_SYNCE_CFG_REG 0xA012 ++#define YT8531_SCR_SYNCE_ENABLE BIT(6) ++ + /* Extended Register end */ + + struct yt8521_priv { +@@ -479,6 +483,77 @@ static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) + return phy_restore_page(phydev, old_page, ret); + } + ++/** ++ * yt8531_set_wol() - turn wake-on-lan on or off ++ * @phydev: a pointer to a &struct phy_device ++ * @wol: a pointer to a &struct ethtool_wolinfo ++ * ++ * NOTE: YTPHY_WOL_CONFIG_REG, YTPHY_WOL_MACADDR2_REG, YTPHY_WOL_MACADDR1_REG ++ * and YTPHY_WOL_MACADDR0_REG are common ext reg. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_set_wol(struct phy_device *phydev, ++ struct ethtool_wolinfo *wol) ++{ ++ struct net_device *p_attached_dev; ++ const u16 mac_addr_reg[] = { ++ YTPHY_WOL_MACADDR2_REG, ++ YTPHY_WOL_MACADDR1_REG, ++ YTPHY_WOL_MACADDR0_REG, ++ }; ++ const u8 *mac_addr; ++ u16 mask; ++ u16 val; ++ int ret; ++ u8 i; ++ ++ if (wol->wolopts & WAKE_MAGIC) { ++ p_attached_dev = phydev->attached_dev; ++ if (!p_attached_dev) ++ return -ENODEV; ++ ++ mac_addr = (const u8 *)p_attached_dev->dev_addr; ++ if (!is_valid_ether_addr(mac_addr)) ++ return -EINVAL; ++ ++ /* Store the device address for the magic packet */ ++ for (i = 0; i < 3; i++) { ++ ret = ytphy_write_ext(phydev, mac_addr_reg[i], ++ ((mac_addr[i * 2] << 8)) | ++ (mac_addr[i * 2 + 1])); ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* Enable WOL feature */ ++ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL; ++ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; ++ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS; ++ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, val); ++ if (ret < 0) ++ return ret; ++ ++ /* Enable WOL interrupt */ ++ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0, ++ YTPHY_IER_WOL); ++ if (ret < 0) ++ return ret; ++ } else { ++ /* Disable WOL feature */ ++ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; ++ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, 0); ++ ++ /* Disable WOL interrupt */ ++ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, ++ YTPHY_IER_WOL, 0); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int yt8511_read_page(struct phy_device *phydev) + { + return __phy_read(phydev, YT8511_PAGE_SELECT); +@@ -651,6 +726,19 @@ static int yt8521_probe(struct phy_device *phydev) + return 0; + } + ++/** ++ * yt8531_probe() - Now only disable SyncE clock output ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_probe(struct phy_device *phydev) ++{ ++ /* Disable SyncE clock output by default */ ++ return ytphy_modify_ext_with_lock(phydev, YT8531_SYNCE_CFG_REG, ++ YT8531_SCR_SYNCE_ENABLE, 0); ++} ++ + /** + * yt8531s_probe() - read chip config then set suitable polling_mode + * @phydev: a pointer to a &struct phy_device +@@ -1192,6 +1280,59 @@ static int yt8521_config_init(struct phy_device *phydev) + return phy_restore_page(phydev, old_page, ret); + } + ++/** ++ * yt8531_config_init() - called to initialize the PHY ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_config_init(struct phy_device *phydev) ++{ ++ int ret; ++ u16 val; ++ ++ switch (phydev->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; ++ val |= YT8521_RC1R_RX_DELAY_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; ++ val |= YT8521_RC1R_RX_DELAY_EN; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; ++ val |= YT8521_RC1R_RX_DELAY_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; ++ val |= YT8521_RC1R_RX_DELAY_EN; ++ break; ++ default: /* do not support other modes */ ++ return -EOPNOTSUPP; ++ } ++ ++ /* set rgmii delay mode */ ++ ret = ytphy_modify_ext_with_lock(phydev, YT8521_RGMII_CONFIG1_REG, ++ (YT8521_RC1R_RX_DELAY_MASK | ++ YT8521_RC1R_FE_TX_DELAY_MASK | ++ YT8521_RC1R_GE_TX_DELAY_MASK), ++ val); ++ if (ret < 0) ++ return ret; ++ ++ /* disable auto sleep */ ++ ret = ytphy_modify_ext_with_lock(phydev, ++ YT8521_EXTREG_SLEEP_CONTROL1_REG, ++ YT8521_ESC1R_SLEEP_SW, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* enable RXC clock when no wire plug */ ++ return ytphy_modify_ext_with_lock(phydev, YT8521_CLOCK_GATING_REG, ++ YT8521_CGR_RX_CLK_EN, 0); ++} ++ + /** + * yt8521_prepare_fiber_features() - A small helper function that setup + * fiber's features. +@@ -1774,6 +1915,16 @@ static struct phy_driver motorcomm_phy_drvs[] = { + .suspend = yt8521_suspend, + .resume = yt8521_resume, + }, ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8531), ++ .name = "YT8531 Gigabit Ethernet", ++ .probe = yt8531_probe, ++ .config_init = yt8531_config_init, ++ .suspend = genphy_suspend, ++ .resume = genphy_resume, ++ .get_wol = ytphy_get_wol, ++ .set_wol = yt8531_set_wol, ++ }, + { + PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), + .name = "YT8531S Gigabit Ethernet", +@@ -1795,7 +1946,7 @@ static struct phy_driver motorcomm_phy_drvs[] = { + + module_phy_driver(motorcomm_phy_drvs); + +-MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); ++MODULE_DESCRIPTION("Motorcomm 8511/8521/8531/8531S PHY driver"); + MODULE_AUTHOR("Peter Geis"); + MODULE_AUTHOR("Frank"); + MODULE_LICENSE("GPL"); +@@ -1803,8 +1954,9 @@ 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_YT8531) }, + { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, +- { /* sentinal */ } ++ { /* sentinel */ } + }; + + MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); diff --git a/target/linux/rockchip/patches-5.15/108-net-phy-add-support-for-Motorcomm-yt8531C-phy.patch b/target/linux/rockchip/patches-5.15/108-net-phy-add-support-for-Motorcomm-yt8531C-phy.patch deleted file mode 100644 index 842047d87..000000000 --- a/target/linux/rockchip/patches-5.15/108-net-phy-add-support-for-Motorcomm-yt8531C-phy.patch +++ /dev/null @@ -1,141 +0,0 @@ -From cfb1aa4c805e58287dd0ce292b5c64309e3dba2f Mon Sep 17 00:00:00 2001 -From: Furkan Kardame -Date: Sun, 9 Oct 2022 22:24:05 +0300 -Subject: [PATCH] net: phy: add support for Motorcomm yt8531C phy - -This patch adds support for Motorcomm YT8531C which is -used in OrangePi 3 LTS, OrangePi 4 LTS and OrangePi 800 -Currently being used by Manjaro Arm kernel - -Signed-off-by: Peter Geis -Signed-off-by: Furkan Kardame ---- - drivers/net/phy/motorcomm.c | 90 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 90 insertions(+) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -13,6 +13,7 @@ - - #define PHY_ID_YT8511 0x0000010a - #define PHY_ID_YT8521 0x0000011A -+#define PHY_ID_YT8531 0x4f51e91b - - /* YT8521 Register Overview - * UTP Register space | FIBER Register space -@@ -129,6 +130,38 @@ - #define YT8511_DELAY_FE_TX_EN (0xf << 12) - #define YT8511_DELAY_FE_TX_DIS (0x2 << 12) - -+#define YT8531_RGMII_CONFIG1 0xa003 -+ -+/* TX Gig-E Delay is bits 3:0, default 0x1 -+ * TX Fast-E Delay is bits 7:4, default 0xf -+ * RX Delay is bits 13:10, default 0x0 -+ * Delay = 150ps * N -+ * On = 2000ps, off = 50ps -+ */ -+#define YT8531_DELAY_GE_TX_EN (0xd << 0) -+#define YT8531_DELAY_GE_TX_DIS (0x0 << 0) -+#define YT8531_DELAY_FE_TX_EN (0xd << 4) -+#define YT8531_DELAY_FE_TX_DIS (0x0 << 4) -+#define YT8531_DELAY_RX_EN (0xd << 10) -+#define YT8531_DELAY_RX_DIS (0x0 << 10) -+#define YT8531_DELAY_MASK (GENMASK(13, 10) | GENMASK(7, 0)) -+ -+#define YT8531_SYNCE_CFG 0xa012 -+ -+/* Clk src config is bits 3:1 -+ * 3b000 src from pll -+ * 3b001 src from rx_clk -+ * 3b010 src from serdes -+ * 3b011 src from ptp_in -+ * 3b100 src from 25mhz refclk *default* -+ * 3b101 src from 25mhz ssc -+ * Clk rate select is bit 4 -+ * 1b0 25mhz clk output *default* -+ * 1b1 125mhz clk output -+ * Clkout enable is bit 6 -+ */ -+#define YT8531_CLKCFG_125M (BIT(6) | BIT(4) | (0x0 < 1)) -+ - /* Extended register is different from MMD Register and MII Register. - * We can use ytphy_read_ext/ytphy_write_ext/ytphy_modify_ext function to - * operate extended register. -@@ -1723,6 +1756,51 @@ err_restore_page: - return ret; - } - -+static int yt8531_config_init(struct phy_device *phydev) -+{ -+ int oldpage, ret = 0; -+ unsigned int val; -+ -+ oldpage = phy_select_page(phydev, YT8531_RGMII_CONFIG1); -+ if (oldpage < 0) -+ goto err_restore_page; -+ -+ /* set rgmii delay mode */ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ val = YT8531_DELAY_RX_DIS | YT8531_DELAY_GE_TX_DIS | YT8531_DELAY_FE_TX_DIS; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ val = YT8531_DELAY_RX_EN | YT8531_DELAY_GE_TX_DIS | YT8531_DELAY_FE_TX_DIS; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ val = YT8531_DELAY_RX_DIS | YT8531_DELAY_GE_TX_EN | YT8531_DELAY_FE_TX_EN; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ val = YT8531_DELAY_RX_EN | YT8531_DELAY_GE_TX_EN | YT8531_DELAY_FE_TX_EN; -+ break; -+ default: /* do not support other modes */ -+ ret = -EOPNOTSUPP; -+ goto err_restore_page; -+ } -+ -+ ret = __phy_modify(phydev, YT8511_PAGE, YT8531_DELAY_MASK, val); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ /* set clock mode to 125mhz */ -+ ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8531_SYNCE_CFG); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ ret = __phy_write(phydev, YT8511_PAGE, YT8531_CLKCFG_125M); -+ if (ret < 0) -+ goto err_restore_page; -+ -+err_restore_page: -+ return phy_restore_page(phydev, oldpage, ret); -+} -+ - static struct phy_driver motorcomm_phy_drvs[] = { - { - PHY_ID_MATCH_EXACT(PHY_ID_YT8511), -@@ -1749,7 +1827,16 @@ static struct phy_driver motorcomm_phy_d - .soft_reset = yt8521_soft_reset, - .suspend = yt8521_suspend, - .resume = yt8521_resume, -+ }, { -+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531), -+ .name = "YT8531 Gigabit Ethernet", -+ .config_init = yt8531_config_init, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_page = yt8511_read_page, -+ .write_page = yt8511_write_page, - }, -+ - }; - - module_phy_driver(motorcomm_phy_drvs); -@@ -1762,6 +1849,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_YT8531) }, - { /* sentinal */ } - }; - diff --git a/target/linux/rockchip/patches-6.0/021-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch b/target/linux/rockchip/patches-6.0/021-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch new file mode 100644 index 000000000..7ec6867ea --- /dev/null +++ b/target/linux/rockchip/patches-6.0/021-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch @@ -0,0 +1,140 @@ +From 813abcd98fb1b2cccf850cdfa092a4bfc50b2363 Mon Sep 17 00:00:00 2001 +From: Frank +Date: Tue, 22 Nov 2022 16:42:32 +0800 +Subject: [PATCH] net: phy: add Motorcomm YT8531S phy id. + +We added patch for motorcomm.c to support YT8531S. This patch has +been tested on AM335x platform which has one YT8531S interface +card and passed all test cases. +The tested cases indluding: YT8531S UTP function with support of +10M/100M/1000M; YT8531S Fiber function with support of 100M/1000M; +and YT8531S Combo function that supports auto detection of media type. + +Since most functions of YT8531S are similar to YT8521 and we reuse some +codes for YT8521 in the patch file. + +Signed-off-by: Frank +Signed-off-by: David S. Miller +--- + drivers/net/phy/Kconfig | 2 +- + drivers/net/phy/motorcomm.c | 52 +++++++++++++++++++++++++++++++++---- + 2 files changed, 48 insertions(+), 6 deletions(-) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -334,7 +334,7 @@ config MOTORCOMM_PHY + tristate "Motorcomm PHYs" + help + Enables support for Motorcomm network PHYs. +- Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs. ++ Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. + + config NATIONAL_PHY + tristate "National Semiconductor PHYs" +--- 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 PHY driver. ++ * Motorcomm 8511/8521/8531S PHY driver. + * + * Author: Peter Geis + * Author: Frank +@@ -12,9 +12,10 @@ + #include + + #define PHY_ID_YT8511 0x0000010a +-#define PHY_ID_YT8521 0x0000011A ++#define PHY_ID_YT8521 0x0000011A ++#define PHY_ID_YT8531S 0x4F51E91A + +-/* YT8521 Register Overview ++/* YT8521/YT8531S Register Overview + * UTP Register space | FIBER Register space + * ------------------------------------------------------------ + * | UTP MII | FIBER MII | +@@ -147,7 +148,7 @@ + #define YT8521_LINK_TIMER_CFG2_REG 0xA5 + #define YT8521_LTCR_EN_AUTOSEN BIT(15) + +-/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers ++/* 0xA000, 0xA001, 0xA003, 0xA006 ~ 0xA00A and 0xA012 are common ext registers + * of yt8521 phy. There is no need to switch reg space when operating these + * registers. + */ +@@ -221,6 +222,9 @@ + */ + #define YTPHY_WCR_TYPE_PULSE BIT(0) + ++#define YT8531S_SYNCE_CFG_REG 0xA012 ++#define YT8531S_SCR_SYNCE_ENABLE BIT(6) ++ + /* Extended Register end */ + + struct yt8521_priv { +@@ -647,6 +651,26 @@ static int yt8521_probe(struct phy_device *phydev) + return 0; + } + ++/** ++ * yt8531s_probe() - read chip config then set suitable polling_mode ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531s_probe(struct phy_device *phydev) ++{ ++ int ret; ++ ++ /* Disable SyncE clock output by default */ ++ ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG, ++ YT8531S_SCR_SYNCE_ENABLE, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* same as yt8521_probe */ ++ return yt8521_probe(phydev); ++} ++ + /** + * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp + * @phydev: a pointer to a &struct phy_device +@@ -1750,11 +1774,28 @@ static struct phy_driver motorcomm_phy_drvs[] = { + .suspend = yt8521_suspend, + .resume = yt8521_resume, + }, ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), ++ .name = "YT8531S Gigabit Ethernet", ++ .get_features = yt8521_get_features, ++ .probe = yt8531s_probe, ++ .read_page = yt8521_read_page, ++ .write_page = yt8521_write_page, ++ .get_wol = ytphy_get_wol, ++ .set_wol = ytphy_set_wol, ++ .config_aneg = yt8521_config_aneg, ++ .aneg_done = yt8521_aneg_done, ++ .config_init = yt8521_config_init, ++ .read_status = yt8521_read_status, ++ .soft_reset = yt8521_soft_reset, ++ .suspend = yt8521_suspend, ++ .resume = yt8521_resume, ++ }, + }; + + module_phy_driver(motorcomm_phy_drvs); + +-MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver"); ++MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); + MODULE_AUTHOR("Peter Geis"); + MODULE_AUTHOR("Frank"); + MODULE_LICENSE("GPL"); +@@ -1762,6 +1803,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_YT8531S) }, + { /* sentinal */ } + }; + diff --git a/target/linux/rockchip/patches-6.0/108-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch b/target/linux/rockchip/patches-6.0/108-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch new file mode 100644 index 000000000..358295459 --- /dev/null +++ b/target/linux/rockchip/patches-6.0/108-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch @@ -0,0 +1,254 @@ +From cfb1aa4c805e58287dd0ce292b5c64309e3dba2f Mon Sep 17 00:00:00 2001 +From: Frank +Date: Wed, 30 Nov 2022 17:49:28 +0800 +Subject: [PATCH] net: phy: Add driver for Motorcomm yt8531 gigabit ethernet phy + +Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have +verified the patch on AM335x platform which has one YT8531 interface +card and passed all test cases. The tested cases indluding: YT8531 UTP +function with support of 10M/100M/1000M and wol(based on magic packet). + +Signed-off-by: Frank +--- + drivers/net/phy/Kconfig | 2 +- + drivers/net/phy/motorcomm.c | 162 ++++++++++++++++++++++++++++++++++-- + 2 files changed, 158 insertions(+), 6 deletions(-) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -334,7 +334,7 @@ config MOTORCOMM_PHY + tristate "Motorcomm PHYs" + help + Enables support for Motorcomm network PHYs. +- Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. ++ Currently supports the YT8511, YT8521, YT8531, YT8531S Gigabit Ethernet PHYs. + + config NATIONAL_PHY + tristate "National Semiconductor PHYs" +--- 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/8531S PHY driver. ++ * Motorcomm 8511/8521/8531/8531S PHY driver. + * + * Author: Peter Geis + * Author: Frank +@@ -12,8 +12,9 @@ + #include + + #define PHY_ID_YT8511 0x0000010a +-#define PHY_ID_YT8521 0x0000011A +-#define PHY_ID_YT8531S 0x4F51E91A ++#define PHY_ID_YT8521 0x0000011a ++#define PHY_ID_YT8531 0x4f51e91b ++#define PHY_ID_YT8531S 0x4f51e91a + + /* YT8521/YT8531S Register Overview + * UTP Register space | FIBER Register space +@@ -225,6 +226,9 @@ + #define YT8531S_SYNCE_CFG_REG 0xA012 + #define YT8531S_SCR_SYNCE_ENABLE BIT(6) + ++#define YT8531_SYNCE_CFG_REG 0xA012 ++#define YT8531_SCR_SYNCE_ENABLE BIT(6) ++ + /* Extended Register end */ + + struct yt8521_priv { +@@ -479,6 +483,77 @@ static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) + return phy_restore_page(phydev, old_page, ret); + } + ++/** ++ * yt8531_set_wol() - turn wake-on-lan on or off ++ * @phydev: a pointer to a &struct phy_device ++ * @wol: a pointer to a &struct ethtool_wolinfo ++ * ++ * NOTE: YTPHY_WOL_CONFIG_REG, YTPHY_WOL_MACADDR2_REG, YTPHY_WOL_MACADDR1_REG ++ * and YTPHY_WOL_MACADDR0_REG are common ext reg. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_set_wol(struct phy_device *phydev, ++ struct ethtool_wolinfo *wol) ++{ ++ struct net_device *p_attached_dev; ++ const u16 mac_addr_reg[] = { ++ YTPHY_WOL_MACADDR2_REG, ++ YTPHY_WOL_MACADDR1_REG, ++ YTPHY_WOL_MACADDR0_REG, ++ }; ++ const u8 *mac_addr; ++ u16 mask; ++ u16 val; ++ int ret; ++ u8 i; ++ ++ if (wol->wolopts & WAKE_MAGIC) { ++ p_attached_dev = phydev->attached_dev; ++ if (!p_attached_dev) ++ return -ENODEV; ++ ++ mac_addr = (const u8 *)p_attached_dev->dev_addr; ++ if (!is_valid_ether_addr(mac_addr)) ++ return -EINVAL; ++ ++ /* Store the device address for the magic packet */ ++ for (i = 0; i < 3; i++) { ++ ret = ytphy_write_ext(phydev, mac_addr_reg[i], ++ ((mac_addr[i * 2] << 8)) | ++ (mac_addr[i * 2 + 1])); ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* Enable WOL feature */ ++ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL; ++ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; ++ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS; ++ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, val); ++ if (ret < 0) ++ return ret; ++ ++ /* Enable WOL interrupt */ ++ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0, ++ YTPHY_IER_WOL); ++ if (ret < 0) ++ return ret; ++ } else { ++ /* Disable WOL feature */ ++ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; ++ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, 0); ++ ++ /* Disable WOL interrupt */ ++ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, ++ YTPHY_IER_WOL, 0); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int yt8511_read_page(struct phy_device *phydev) + { + return __phy_read(phydev, YT8511_PAGE_SELECT); +@@ -651,6 +726,19 @@ static int yt8521_probe(struct phy_device *phydev) + return 0; + } + ++/** ++ * yt8531_probe() - Now only disable SyncE clock output ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_probe(struct phy_device *phydev) ++{ ++ /* Disable SyncE clock output by default */ ++ return ytphy_modify_ext_with_lock(phydev, YT8531_SYNCE_CFG_REG, ++ YT8531_SCR_SYNCE_ENABLE, 0); ++} ++ + /** + * yt8531s_probe() - read chip config then set suitable polling_mode + * @phydev: a pointer to a &struct phy_device +@@ -1192,6 +1280,59 @@ static int yt8521_config_init(struct phy_device *phydev) + return phy_restore_page(phydev, old_page, ret); + } + ++/** ++ * yt8531_config_init() - called to initialize the PHY ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_config_init(struct phy_device *phydev) ++{ ++ int ret; ++ u16 val; ++ ++ switch (phydev->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; ++ val |= YT8521_RC1R_RX_DELAY_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; ++ val |= YT8521_RC1R_RX_DELAY_EN; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; ++ val |= YT8521_RC1R_RX_DELAY_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; ++ val |= YT8521_RC1R_RX_DELAY_EN; ++ break; ++ default: /* do not support other modes */ ++ return -EOPNOTSUPP; ++ } ++ ++ /* set rgmii delay mode */ ++ ret = ytphy_modify_ext_with_lock(phydev, YT8521_RGMII_CONFIG1_REG, ++ (YT8521_RC1R_RX_DELAY_MASK | ++ YT8521_RC1R_FE_TX_DELAY_MASK | ++ YT8521_RC1R_GE_TX_DELAY_MASK), ++ val); ++ if (ret < 0) ++ return ret; ++ ++ /* disable auto sleep */ ++ ret = ytphy_modify_ext_with_lock(phydev, ++ YT8521_EXTREG_SLEEP_CONTROL1_REG, ++ YT8521_ESC1R_SLEEP_SW, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* enable RXC clock when no wire plug */ ++ return ytphy_modify_ext_with_lock(phydev, YT8521_CLOCK_GATING_REG, ++ YT8521_CGR_RX_CLK_EN, 0); ++} ++ + /** + * yt8521_prepare_fiber_features() - A small helper function that setup + * fiber's features. +@@ -1774,6 +1915,16 @@ static struct phy_driver motorcomm_phy_drvs[] = { + .suspend = yt8521_suspend, + .resume = yt8521_resume, + }, ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8531), ++ .name = "YT8531 Gigabit Ethernet", ++ .probe = yt8531_probe, ++ .config_init = yt8531_config_init, ++ .suspend = genphy_suspend, ++ .resume = genphy_resume, ++ .get_wol = ytphy_get_wol, ++ .set_wol = yt8531_set_wol, ++ }, + { + PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), + .name = "YT8531S Gigabit Ethernet", +@@ -1795,7 +1946,7 @@ static struct phy_driver motorcomm_phy_drvs[] = { + + module_phy_driver(motorcomm_phy_drvs); + +-MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); ++MODULE_DESCRIPTION("Motorcomm 8511/8521/8531/8531S PHY driver"); + MODULE_AUTHOR("Peter Geis"); + MODULE_AUTHOR("Frank"); + MODULE_LICENSE("GPL"); +@@ -1803,8 +1954,9 @@ 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_YT8531) }, + { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, +- { /* sentinal */ } ++ { /* sentinel */ } + }; + + MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); diff --git a/target/linux/rockchip/patches-6.0/108-net-phy-add-support-for-Motorcomm-yt8531C-phy.patch b/target/linux/rockchip/patches-6.0/108-net-phy-add-support-for-Motorcomm-yt8531C-phy.patch deleted file mode 100644 index 842047d87..000000000 --- a/target/linux/rockchip/patches-6.0/108-net-phy-add-support-for-Motorcomm-yt8531C-phy.patch +++ /dev/null @@ -1,141 +0,0 @@ -From cfb1aa4c805e58287dd0ce292b5c64309e3dba2f Mon Sep 17 00:00:00 2001 -From: Furkan Kardame -Date: Sun, 9 Oct 2022 22:24:05 +0300 -Subject: [PATCH] net: phy: add support for Motorcomm yt8531C phy - -This patch adds support for Motorcomm YT8531C which is -used in OrangePi 3 LTS, OrangePi 4 LTS and OrangePi 800 -Currently being used by Manjaro Arm kernel - -Signed-off-by: Peter Geis -Signed-off-by: Furkan Kardame ---- - drivers/net/phy/motorcomm.c | 90 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 90 insertions(+) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -13,6 +13,7 @@ - - #define PHY_ID_YT8511 0x0000010a - #define PHY_ID_YT8521 0x0000011A -+#define PHY_ID_YT8531 0x4f51e91b - - /* YT8521 Register Overview - * UTP Register space | FIBER Register space -@@ -129,6 +130,38 @@ - #define YT8511_DELAY_FE_TX_EN (0xf << 12) - #define YT8511_DELAY_FE_TX_DIS (0x2 << 12) - -+#define YT8531_RGMII_CONFIG1 0xa003 -+ -+/* TX Gig-E Delay is bits 3:0, default 0x1 -+ * TX Fast-E Delay is bits 7:4, default 0xf -+ * RX Delay is bits 13:10, default 0x0 -+ * Delay = 150ps * N -+ * On = 2000ps, off = 50ps -+ */ -+#define YT8531_DELAY_GE_TX_EN (0xd << 0) -+#define YT8531_DELAY_GE_TX_DIS (0x0 << 0) -+#define YT8531_DELAY_FE_TX_EN (0xd << 4) -+#define YT8531_DELAY_FE_TX_DIS (0x0 << 4) -+#define YT8531_DELAY_RX_EN (0xd << 10) -+#define YT8531_DELAY_RX_DIS (0x0 << 10) -+#define YT8531_DELAY_MASK (GENMASK(13, 10) | GENMASK(7, 0)) -+ -+#define YT8531_SYNCE_CFG 0xa012 -+ -+/* Clk src config is bits 3:1 -+ * 3b000 src from pll -+ * 3b001 src from rx_clk -+ * 3b010 src from serdes -+ * 3b011 src from ptp_in -+ * 3b100 src from 25mhz refclk *default* -+ * 3b101 src from 25mhz ssc -+ * Clk rate select is bit 4 -+ * 1b0 25mhz clk output *default* -+ * 1b1 125mhz clk output -+ * Clkout enable is bit 6 -+ */ -+#define YT8531_CLKCFG_125M (BIT(6) | BIT(4) | (0x0 < 1)) -+ - /* Extended register is different from MMD Register and MII Register. - * We can use ytphy_read_ext/ytphy_write_ext/ytphy_modify_ext function to - * operate extended register. -@@ -1723,6 +1756,51 @@ err_restore_page: - return ret; - } - -+static int yt8531_config_init(struct phy_device *phydev) -+{ -+ int oldpage, ret = 0; -+ unsigned int val; -+ -+ oldpage = phy_select_page(phydev, YT8531_RGMII_CONFIG1); -+ if (oldpage < 0) -+ goto err_restore_page; -+ -+ /* set rgmii delay mode */ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ val = YT8531_DELAY_RX_DIS | YT8531_DELAY_GE_TX_DIS | YT8531_DELAY_FE_TX_DIS; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ val = YT8531_DELAY_RX_EN | YT8531_DELAY_GE_TX_DIS | YT8531_DELAY_FE_TX_DIS; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ val = YT8531_DELAY_RX_DIS | YT8531_DELAY_GE_TX_EN | YT8531_DELAY_FE_TX_EN; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ val = YT8531_DELAY_RX_EN | YT8531_DELAY_GE_TX_EN | YT8531_DELAY_FE_TX_EN; -+ break; -+ default: /* do not support other modes */ -+ ret = -EOPNOTSUPP; -+ goto err_restore_page; -+ } -+ -+ ret = __phy_modify(phydev, YT8511_PAGE, YT8531_DELAY_MASK, val); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ /* set clock mode to 125mhz */ -+ ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8531_SYNCE_CFG); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ ret = __phy_write(phydev, YT8511_PAGE, YT8531_CLKCFG_125M); -+ if (ret < 0) -+ goto err_restore_page; -+ -+err_restore_page: -+ return phy_restore_page(phydev, oldpage, ret); -+} -+ - static struct phy_driver motorcomm_phy_drvs[] = { - { - PHY_ID_MATCH_EXACT(PHY_ID_YT8511), -@@ -1749,7 +1827,16 @@ static struct phy_driver motorcomm_phy_d - .soft_reset = yt8521_soft_reset, - .suspend = yt8521_suspend, - .resume = yt8521_resume, -+ }, { -+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531), -+ .name = "YT8531 Gigabit Ethernet", -+ .config_init = yt8531_config_init, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_page = yt8511_read_page, -+ .write_page = yt8511_write_page, - }, -+ - }; - - module_phy_driver(motorcomm_phy_drvs); -@@ -1762,6 +1849,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_YT8531) }, - { /* sentinal */ } - }; -