From 733bf5cac4715e474f50f14ba7d8030fe3a039c8 Mon Sep 17 00:00:00 2001 From: Ozan Durgut Date: Tue, 21 Jul 2026 09:34:49 +0200 Subject: [PATCH 1/5] net: phy: adin: support ADIN1200 RMII configuration Configure the shared ADIN vendor registers for both ADIN1200 and ADIN1300 PHYs. This enables RMII mode and programs the RMII FIFO depth for ADIN1200 instead of relying only on generic PHY configuration. Keep the device-tree values in physical units. When the delay and FIFO properties are absent, use the ADIN1300 defaults of 2 ns for RGMII internal delay and 8 bits for RMII FIFO depth. Signed-off-by: Ozan Durgut --- drivers/net/phy/adin.c | 98 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 10 deletions(-) diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c index ce448810ff6d..0c3dbbcb0d70 100644 --- a/drivers/net/phy/adin.c +++ b/drivers/net/phy/adin.c @@ -10,6 +10,7 @@ #include #include +#define PHY_ID_ADIN1200 0x0283bc20 #define PHY_ID_ADIN1300 0x0283bc30 #define ADIN1300_EXT_REG_PTR 0x10 #define ADIN1300_EXT_REG_DATA 0x11 @@ -34,6 +35,12 @@ #define ADIN1300_GE_RGMII_TXID_EN BIT(1) #define ADIN1300_GE_RGMII_EN BIT(0) +#define ADIN1300_GE_RMII_CFG 0xff24 +#define ADIN1300_GE_RMII_FIFO_DEPTH_MSK GENMASK(6, 4) +#define ADIN1300_GE_RMII_FIFO_DEPTH_SEL(x) \ + FIELD_PREP(ADIN1300_GE_RMII_FIFO_DEPTH_MSK, x) +#define ADIN1300_GE_RMII_EN BIT(0) + /* RGMII internal delay settings for rx and tx for ADIN1300 */ #define ADIN1300_RGMII_1_60_NS 0x0001 #define ADIN1300_RGMII_1_80_NS 0x0002 @@ -41,6 +48,14 @@ #define ADIN1300_RGMII_2_20_NS 0x0006 #define ADIN1300_RGMII_2_40_NS 0x0007 +/* RMII FIFO depth settings for ADIN1200/ADIN1300 */ +#define ADIN1300_RMII_4_BITS 0x0000 +#define ADIN1300_RMII_8_BITS 0x0001 +#define ADIN1300_RMII_12_BITS 0x0002 +#define ADIN1300_RMII_16_BITS 0x0003 +#define ADIN1300_RMII_20_BITS 0x0004 +#define ADIN1300_RMII_24_BITS 0x0005 + /** * struct adin_cfg_reg_map - map a config value to aregister value * @cfg value in device configuration @@ -60,6 +75,16 @@ static const struct adin_cfg_reg_map adin_rgmii_delays[] = { { }, }; +static const struct adin_cfg_reg_map adin_rmii_fifo_depths[] = { + { 4, ADIN1300_RMII_4_BITS }, + { 8, ADIN1300_RMII_8_BITS }, + { 12, ADIN1300_RMII_12_BITS }, + { 16, ADIN1300_RMII_16_BITS }, + { 20, ADIN1300_RMII_20_BITS }, + { 24, ADIN1300_RMII_24_BITS }, + { }, +}; + static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg) { size_t i; @@ -75,10 +100,14 @@ static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg) static u32 adin_get_reg_value(struct phy_device *phydev, const char *prop_name, const struct adin_cfg_reg_map *tbl, - u32 dflt) + u32 dflt_cfg) { u32 val; - int rc; + int dflt, rc; + + dflt = adin_lookup_reg_value(tbl, dflt_cfg); + if (dflt < 0) + return dflt; ofnode node = phy_get_ofnode(phydev); if (!ofnode_valid(node)) { @@ -87,8 +116,8 @@ static u32 adin_get_reg_value(struct phy_device *phydev, } if (ofnode_read_u32(node, prop_name, &val)) { - printf("%s: failed to find %s, using default %d\n", - __func__, prop_name, dflt); + printf("%s: failed to find %s, using default %u\n", + __func__, prop_name, dflt_cfg); return dflt; } @@ -97,7 +126,7 @@ static u32 adin_get_reg_value(struct phy_device *phydev, rc = adin_lookup_reg_value(tbl, val); if (rc < 0) { printf("%s: Unsupported value %u for %s using default (%u)\n", - __func__, val, prop_name, dflt); + __func__, val, prop_name, dflt_cfg); return dflt; } @@ -221,7 +250,7 @@ static int adin_config_rgmii_mode(struct phy_device *phydev) val = adin_get_reg_value(phydev, "adi,rx-internal-delay-ps", adin_rgmii_delays, - ADIN1300_RGMII_2_00_NS); + 2000); reg_val &= ~ADIN1300_GE_RGMII_RX_MSK; reg_val |= ADIN1300_GE_RGMII_RX_SEL(val); } else { @@ -235,7 +264,7 @@ static int adin_config_rgmii_mode(struct phy_device *phydev) val = adin_get_reg_value(phydev, "adi,tx-internal-delay-ps", adin_rgmii_delays, - ADIN1300_RGMII_2_00_NS); + 2000); reg_val &= ~ADIN1300_GE_RGMII_GTX_MSK; reg_val |= ADIN1300_GE_RGMII_GTX_SEL(val); } else { @@ -245,11 +274,30 @@ static int adin_config_rgmii_mode(struct phy_device *phydev) return adin_ext_write(phydev, ADIN1300_GE_RGMII_CFG, reg_val); } -static int adin1300_config(struct phy_device *phydev) +static int adin_config_rmii_mode(struct phy_device *phydev) { - int ret; + u16 reg_val; + u32 val; - printf("ADIN1300 PHY detected at addr %d\n", phydev->addr); + reg_val = adin_ext_read(phydev, ADIN1300_GE_RMII_CFG); + + if (phydev->interface != PHY_INTERFACE_MODE_RMII) { + reg_val &= ~ADIN1300_GE_RMII_EN; + return adin_ext_write(phydev, ADIN1300_GE_RMII_CFG, reg_val); + } + + reg_val |= ADIN1300_GE_RMII_EN; + val = adin_get_reg_value(phydev, "adi,fifo-depth-bits", + adin_rmii_fifo_depths, 8); + reg_val &= ~ADIN1300_GE_RMII_FIFO_DEPTH_MSK; + reg_val |= ADIN1300_GE_RMII_FIFO_DEPTH_SEL(val); + + return adin_ext_write(phydev, ADIN1300_GE_RMII_CFG, reg_val); +} + +static int adin_config(struct phy_device *phydev) +{ + int ret; ret = adin_config_clk_out(phydev); if (ret < 0) @@ -257,12 +305,42 @@ static int adin1300_config(struct phy_device *phydev) ret = adin_config_rgmii_mode(phydev); + if (ret < 0) + return ret; + + ret = adin_config_rmii_mode(phydev); if (ret < 0) return ret; return genphy_config(phydev); } +static int adin1200_config(struct phy_device *phydev) +{ + printf("ADIN1200 PHY detected at addr %d\n", phydev->addr); + + return adin_config(phydev); +} + +static int adin1300_config(struct phy_device *phydev) +{ + printf("ADIN1300 PHY detected at addr %d\n", phydev->addr); + + return adin_config(phydev); +} + +U_BOOT_PHY_DRIVER(ADIN1200) = { + .name = "ADIN1200", + .uid = PHY_ID_ADIN1200, + .mask = 0xffffffff, + .features = PHY_BASIC_FEATURES, + .config = adin1200_config, + .startup = genphy_startup, + .shutdown = genphy_shutdown, + .readext = adin_extread, + .writeext = adin_extwrite, +}; + U_BOOT_PHY_DRIVER(ADIN1300) = { .name = "ADIN1300", .uid = PHY_ID_ADIN1300, From fa816987d3a90f3e6bd11697d2494018869a57b0 Mon Sep 17 00:00:00 2001 From: Ozan Durgut Date: Tue, 21 Jul 2026 09:34:49 +0200 Subject: [PATCH 2/5] configs: adi: enable ADIN PHY support Enable the ADIN PHY driver in the SC594 and SC598 SPL defconfigs, which describe ADIN1200 and ADIN1300 PHYs. Signed-off-by: Ozan Durgut --- configs/sc594-som-ezkit-spl_defconfig | 1 + configs/sc594-som-ezlite-spl_defconfig | 1 + configs/sc598-htol-spl_defconfig | 1 + configs/sc598-som-ezkit-spl_defconfig | 1 + configs/sc598-som-ezlite-spl_defconfig | 1 + 5 files changed, 5 insertions(+) diff --git a/configs/sc594-som-ezkit-spl_defconfig b/configs/sc594-som-ezkit-spl_defconfig index 0cbce440e014..54b8ff30e084 100644 --- a/configs/sc594-som-ezkit-spl_defconfig +++ b/configs/sc594-som-ezkit-spl_defconfig @@ -60,6 +60,7 @@ CONFIG_SPI_FLASH_SFDP_SUPPORT=y CONFIG_SPI_FLASH_SOFT_RESET=y CONFIG_SPI_FLASH_ISSI=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_ADIN=y CONFIG_ETH_DESIGNWARE=y CONFIG_DW_ALTDESCRIPTOR=y CONFIG_PHY=y diff --git a/configs/sc594-som-ezlite-spl_defconfig b/configs/sc594-som-ezlite-spl_defconfig index 34f9c65ebe08..5466dbdcac86 100644 --- a/configs/sc594-som-ezlite-spl_defconfig +++ b/configs/sc594-som-ezlite-spl_defconfig @@ -66,6 +66,7 @@ CONFIG_SPI_FLASH_SFDP_SUPPORT=y CONFIG_SPI_FLASH_SOFT_RESET=y CONFIG_SPI_FLASH_ISSI=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_ADIN=y CONFIG_ETH_DESIGNWARE=y CONFIG_DW_ALTDESCRIPTOR=y CONFIG_PHY=y diff --git a/configs/sc598-htol-spl_defconfig b/configs/sc598-htol-spl_defconfig index e798af87ed20..c9d19354d702 100644 --- a/configs/sc598-htol-spl_defconfig +++ b/configs/sc598-htol-spl_defconfig @@ -92,6 +92,7 @@ CONFIG_SPI_FLASH_SOFT_RESET=y CONFIG_SPI_FLASH_ISSI=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_ADIN=y CONFIG_DWC_ETH_QOS=y CONFIG_DWC_ETH_QOS_ADI=y CONFIG_PHY=y diff --git a/configs/sc598-som-ezkit-spl_defconfig b/configs/sc598-som-ezkit-spl_defconfig index a1a200092a16..253e40b3a677 100644 --- a/configs/sc598-som-ezkit-spl_defconfig +++ b/configs/sc598-som-ezkit-spl_defconfig @@ -91,6 +91,7 @@ CONFIG_SPI_FLASH_SOFT_RESET=y CONFIG_SPI_FLASH_ISSI=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_ADIN=y CONFIG_DWC_ETH_QOS=y CONFIG_DWC_ETH_QOS_ADI=y CONFIG_PHY=y diff --git a/configs/sc598-som-ezlite-spl_defconfig b/configs/sc598-som-ezlite-spl_defconfig index b96ae6d33fcc..744b90821f87 100644 --- a/configs/sc598-som-ezlite-spl_defconfig +++ b/configs/sc598-som-ezlite-spl_defconfig @@ -89,6 +89,7 @@ CONFIG_SPI_FLASH_SOFT_RESET=y CONFIG_SPI_FLASH_ISSI=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_ADIN=y CONFIG_DWC_ETH_QOS=y CONFIG_DWC_ETH_QOS_ADI=y CONFIG_PHY=y From 3df97216c0c588e9e4393fea0b3414dedc272c1b Mon Sep 17 00:00:00 2001 From: Ozan Durgut Date: Tue, 21 Jul 2026 09:35:15 +0200 Subject: [PATCH 3/5] board: adi: somcrr: leave PHY reset to the PHY driver The ADIN1300 reset GPIO is now described by the PHY node. Remove the obsolete carrier reset hooks so the PHY driver is the sole reset owner. Signed-off-by: Ozan Durgut --- board/adi/carriers/somcrr_ezkit.c | 6 ------ board/adi/carriers/somcrr_ezlite.c | 8 -------- 2 files changed, 14 deletions(-) diff --git a/board/adi/carriers/somcrr_ezkit.c b/board/adi/carriers/somcrr_ezkit.c index 3cd5a6cd10bb..57a87311fac1 100644 --- a/board/adi/carriers/somcrr_ezkit.c +++ b/board/adi/carriers/somcrr_ezkit.c @@ -11,26 +11,20 @@ void adi_somcrr_enable_ethernet(void) { struct gpio_desc *eth1; struct gpio_desc *eth1_reset; - struct gpio_desc *gige_reset; if (!gpio_hog_lookup_name("eth1-en", ð1)) dm_gpio_set_value(eth1, 1); if (!gpio_hog_lookup_name("eth1-reset", ð1_reset)) dm_gpio_set_value(eth1_reset, 0); - if (!gpio_hog_lookup_name("gige-reset", &gige_reset)) - dm_gpio_set_value(gige_reset, 0); } void adi_somcrr_disable_ethernet(void) { struct gpio_desc *eth1; struct gpio_desc *eth1_reset; - struct gpio_desc *gige_reset; if (!gpio_hog_lookup_name("eth1-en", ð1)) dm_gpio_set_value(eth1, 0); if (!gpio_hog_lookup_name("eth1-reset", ð1_reset)) dm_gpio_set_value(eth1_reset, 1); - if (!gpio_hog_lookup_name("gige-reset", &gige_reset)) - dm_gpio_set_value(gige_reset, 1); } diff --git a/board/adi/carriers/somcrr_ezlite.c b/board/adi/carriers/somcrr_ezlite.c index 1f1984cf9124..53ff6e6ddb1c 100644 --- a/board/adi/carriers/somcrr_ezlite.c +++ b/board/adi/carriers/somcrr_ezlite.c @@ -9,16 +9,8 @@ void adi_somcrr_enable_ethernet(void) { - struct gpio_desc *gige_reset; - - if (!gpio_hog_lookup_name("eth0-reset", &gige_reset)) - dm_gpio_set_value(gige_reset, 0); } void adi_somcrr_disable_ethernet(void) { - struct gpio_desc *gige_reset; - - if (!gpio_hog_lookup_name("eth0-reset", &gige_reset)) - dm_gpio_set_value(gige_reset, 1); } From 917b8e2718968cf015029dea3526b068a078a822 Mon Sep 17 00:00:00 2001 From: Ozan Durgut Date: Tue, 21 Jul 2026 09:35:15 +0200 Subject: [PATCH 4/5] arm: dts: sc598: describe ADIN Ethernet PHYs The SC598 boards use an ADIN1300 on eth0, and the EZKIT also uses an ADIN1200 on eth1. Replace the stale DP83867 description, describe the second RMII PHY, and remove the obsolete board PHY fixup. Move the ADIN1300 reset GPIO into the PHY nodes. The ADIN1300 data sheet, Table 3, requires RESET_N to be asserted for at least 10 us and specifies a 5 ms delay before MDIO registers are accessible after reset deassertion. Signed-off-by: Ozan Durgut --- arch/arm/dts/sc598-som-ezkit.dts | 28 ++++++++++++++++++++------ arch/arm/dts/sc598-som-ezlite.dts | 14 ++++++------- arch/arm/dts/sc598-som.dtsi | 4 ++-- board/adi/common-sc598-som/sc598-som.c | 7 ------- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/arch/arm/dts/sc598-som-ezkit.dts b/arch/arm/dts/sc598-som-ezkit.dts index 54ba866db4b8..91356ed1cd82 100644 --- a/arch/arm/dts/sc598-som-ezkit.dts +++ b/arch/arm/dts/sc598-som-ezkit.dts @@ -136,12 +136,28 @@ bootph-pre-ram; }; - gige-reset { - gpio-hog; - gpios = <15 GPIO_ACTIVE_LOW>; - output-high; - line-name = "gige-reset"; - bootph-pre-ram; + }; +}; + +&adin1300 { + reset-gpios = <&crr_gpio_expander 15 GPIO_ACTIVE_LOW>; + reset-assert-us = <10>; + reset-deassert-us = <5000>; +}; + +ð1 { + phy-handle = <&adin1200>; + phy-mode = "rmii"; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + adin1200: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; }; }; }; diff --git a/arch/arm/dts/sc598-som-ezlite.dts b/arch/arm/dts/sc598-som-ezlite.dts index 179c291f34b3..8fe7b9d5a491 100644 --- a/arch/arm/dts/sc598-som-ezlite.dts +++ b/arch/arm/dts/sc598-som-ezlite.dts @@ -52,14 +52,6 @@ bootph-pre-ram; }; - eth0-reset { - gpio-hog; - gpios = <12 GPIO_ACTIVE_LOW>; - output-high; - line-name = "eth0-reset"; - bootph-pre-ram; - }; - adau1372-pwrdwn { gpio-hog; gpios = <13 GPIO_ACTIVE_LOW>; @@ -93,3 +85,9 @@ }; }; }; + +&adin1300 { + reset-gpios = <&crr_gpio_expander 12 GPIO_ACTIVE_LOW>; + reset-assert-us = <10>; + reset-deassert-us = <5000>; +}; diff --git a/arch/arm/dts/sc598-som.dtsi b/arch/arm/dts/sc598-som.dtsi index ac1f24c86c39..2fd54998d0c2 100644 --- a/arch/arm/dts/sc598-som.dtsi +++ b/arch/arm/dts/sc598-som.dtsi @@ -171,7 +171,7 @@ ð0 { compatible = "adi,sc59x-dwmac-eqos"; reg = <0x31040000 0x10000>; - phy-handle = <&dp83867>; + phy-handle = <&adin1300>; phy-mode = "rgmii-id"; mdio { @@ -179,7 +179,7 @@ #address-cells = <1>; #size-cells = <0>; - dp83867: ethernet-phy@0 { + adin1300: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; }; diff --git a/board/adi/common-sc598-som/sc598-som.c b/board/adi/common-sc598-som/sc598-som.c index 0e1ee828956a..20821fc82f38 100644 --- a/board/adi/common-sc598-som/sc598-som.c +++ b/board/adi/common-sc598-som/sc598-som.c @@ -12,13 +12,6 @@ #include "../carriers/somcrr.h" -int board_phy_config(struct phy_device *phydev) -{ - if (IS_ENABLED(CONFIG_ADI_CARRIER_SOMCRR_EZKIT)) - fixup_dp83867_phy(phydev); - return 0; -} - int board_init(void) { sc59x_remap_ospi(); From 036effbf72c3c321cee217373ace4501b1f24f87 Mon Sep 17 00:00:00 2001 From: Ozan Durgut Date: Tue, 21 Jul 2026 09:35:25 +0200 Subject: [PATCH 5/5] arm: dts: sc594: describe ADIN Ethernet PHYs The SC594 EZKIT uses an ADIN1300 on eth0 and an ADIN1200 on eth1. Replace the stale PHY descriptions, describe the second RMII PHY, and remove the obsolete board PHY fixup. Move the ADIN1300 reset GPIO into the PHY nodes. The ADIN1300 data sheet, Table 3, requires RESET_N to be asserted for at least 10 us and specifies a 5 ms delay before MDIO registers are accessible after reset deassertion. Signed-off-by: Ozan Durgut --- arch/arm/dts/sc594-som-ezkit.dts | 28 ++++++++++++++++++++------ arch/arm/dts/sc594-som-ezlite.dts | 18 +++++++++-------- arch/arm/dts/sc594-som.dtsi | 18 +++++++++++++++++ board/adi/common-sc594-som/sc594-som.c | 9 --------- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/arch/arm/dts/sc594-som-ezkit.dts b/arch/arm/dts/sc594-som-ezkit.dts index e1628ce20825..f90c372e67b0 100644 --- a/arch/arm/dts/sc594-som-ezkit.dts +++ b/arch/arm/dts/sc594-som-ezkit.dts @@ -128,12 +128,28 @@ bootph-pre-ram; }; - gige-reset { - gpio-hog; - gpios = <15 GPIO_ACTIVE_LOW>; - output-high; - line-name = "gige-reset"; - bootph-pre-ram; + }; +}; + +&adin1300 { + reset-gpios = <&crr_gpio_expander 15 GPIO_ACTIVE_LOW>; + reset-assert-us = <10>; + reset-deassert-us = <5000>; +}; + +ð1 { + phy-handle = <&adin1200>; + phy-mode = "rmii"; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + adin1200: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; }; }; }; diff --git a/arch/arm/dts/sc594-som-ezlite.dts b/arch/arm/dts/sc594-som-ezlite.dts index ab6f94352fcc..1b10085d7fad 100644 --- a/arch/arm/dts/sc594-som-ezlite.dts +++ b/arch/arm/dts/sc594-som-ezlite.dts @@ -52,14 +52,6 @@ bootph-pre-ram; }; - eth0-reset { - gpio-hog; - gpios = <12 GPIO_ACTIVE_LOW>; - output-high; - line-name = "eth0-reset"; - bootph-pre-ram; - }; - adau1372-pwrdwn { gpio-hog; gpios = <13 GPIO_ACTIVE_LOW>; @@ -94,3 +86,13 @@ }; }; + +&adin1300 { + reset-gpios = <&crr_gpio_expander 12 GPIO_ACTIVE_LOW>; + reset-assert-us = <10>; + reset-deassert-us = <5000>; +}; + +ð1 { + status = "disabled"; +}; diff --git a/arch/arm/dts/sc594-som.dtsi b/arch/arm/dts/sc594-som.dtsi index c4373aea60f4..91d190622663 100644 --- a/arch/arm/dts/sc594-som.dtsi +++ b/arch/arm/dts/sc594-som.dtsi @@ -217,3 +217,21 @@ &usb0 { status = "okay"; }; + +ð0 { + compatible = "adi,sc59x-dwmac-eqos"; + reg = <0x31040000 0x10000>; + phy-handle = <&adin1300>; + phy-mode = "rgmii-id"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + adin1300: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + }; +}; diff --git a/board/adi/common-sc594-som/sc594-som.c b/board/adi/common-sc594-som/sc594-som.c index 37817c4b0628..c84b7be8bdb5 100644 --- a/board/adi/common-sc594-som/sc594-som.c +++ b/board/adi/common-sc594-som/sc594-som.c @@ -4,21 +4,12 @@ */ #include -#include #include #include #include #include "../carriers/somcrr.h" -int board_phy_config(struct phy_device *phydev) -{ - if (IS_ENABLED(CONFIG_ADI_CARRIER_SOMCRR_EZKIT)) - fixup_dp83867_phy(phydev); - - return 0; -} - int board_init(void) { sc59x_remap_ospi();