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/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/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); } 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(); 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(); 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 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,