i.MX6 PCB rev 1.9 and 2.0 - Analog Devices PHY

i.MX6 SOM rev 1.9 and 2.0 migrates from Atheros PHY AR8035 to Analog Devices ADIN 1300 PHY.

This article comes to detail the software modifications required to accomodate this hardware change.

Please note that using those modifications you will be able to support both the AR8035 and the ADIN1300 phys in the same kernel / u-boot images.

U-boot

In order to add support for this PHY in U-boot, you can perform one of the follow options:

 

git clone https://github.com/SolidRun/u-boot.git -b v2018.01-solidrun-imx6

Or

  • Apply the following patch to your U-boot repository (If you're using SolidRun's u-boot)

    From 1b9da6319d32cb66cc05df695bc07fd8cf65a311 Mon Sep 17 00:00:00 2001 From: Alvaro-Karsz <alvaro.karsz@solid-run.com> Date: Sun, 9 Jan 2022 14:58:51 +0200 Subject: [PATCH] Add support for Analog Devices PHY. New configurations for ADIN1300 PHY, including: * New ETH mask with ADIN1300 address, which is 1. * 125MHz Clock out. * Delay before attepting to read the PHY registers. * SW reset. Signed-off-by: Alvaro-Karsz <alvaro.karsz@solid-run.com> --- board/solidrun/mx6cuboxi/mx6cuboxi.c | 74 +++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index adc2c6a00e..a4b85d758f 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -308,8 +308,60 @@ int board_phy_config(struct phy_device *phydev) return 0; } -/* On Cuboxi Ethernet PHY can be located at addresses 0x0 or 0x4 */ -#define ETH_PHY_MASK ((1 << 0x0) | (1 << 0x4)) + + + +#define ADIN1300_MII_EXT_REG_PTR 0x10 +#define ADIN1300_MII_EXT_REG_DATA 0x11 +#define ADIN1300_CLK_CFG_REG 0xff1f +#define ADIN1300_MII_CONTROL_REG 0x0 +#define ADIN_PHY_ADDR 0x1 +#define ADIN_PHY_ID 0x283bc30 + + +/*ADIN1300 PHY - write to MMD registers*/ +int adin_phy_mmd_write(struct phy_device *phydev, int regnum, u16 val) +{ + int ret; + + /*write to external pointer register*/ + ret = phy_write(phydev, MDIO_MMD_VEND1, + ADIN1300_MII_EXT_REG_PTR, regnum); + + if (ret) + return ret; + + /*write to external data register*/ + return phy_write(phydev, MDIO_MMD_VEND1, + ADIN1300_MII_EXT_REG_DATA, val); +} + + +/*additional init for ADIN1300 PHY*/ +int eth_init_adin_phy(struct phy_device *phydev) +{ + int ret; + + + /* Configure clock by writing to the clock register + * 0x10 -> GE_CLK_FREE_125_EN + */ + ret = adin_phy_mmd_write(phydev, ADIN1300_CLK_CFG_REG, 0x10); + if (ret) + return ret; + + /* Do SW reset by writing to MII control register + * 0x8000 -> SFT_RST + */ + return phy_write(phydev, MDIO_MMD_VEND1, + ADIN1300_MII_CONTROL_REG, 0x8000); +} + + +/* On Cuboxi Ethernet PHY can be located at addresses 0x0 or 0x4 + * Update: ADIN PHY is located at address 0x1. + */ +#define ETH_PHY_MASK ((1 << 0x0) | (1 << 0x4) | (1 << ADIN_PHY_ADDR)) int board_eth_init(bd_t *bis) { @@ -330,6 +382,13 @@ int board_eth_init(bd_t *bis) if (!bus) return -EINVAL; + /* Add a 20ms delay before searching for phy devices. + * ADIN PHY needs a delay before attempting to read the PHY registers. + * Without this delay, PHY register read will result in 0, + * thus, the phy id will be read as 0. + */ + mdelay(20); + phydev = phy_find_by_mask(bus, ETH_PHY_MASK, PHY_INTERFACE_MODE_RGMII); if (!phydev) { ret = -EINVAL; @@ -341,6 +400,17 @@ int board_eth_init(bd_t *bis) if (ret) goto free_phydev; + + /* If this board has a ADIN1300 PHY, + * additional configurations are required + */ + if (phydev->phy_id == ADIN_PHY_ID) { + ret = eth_init_adin_phy(phydev); + if (ret) + goto free_phydev; + } + + return 0; free_phydev: -- 2.25.1

Linux Kernel

In order to add support in Linux kernel, you can perform one of the follow options:

git clone https://github.com/SolidRun/linux-fslc.git

Or

  • Apply the following patch to your Linux repository (If you're using SolidRun's Linux)

 

If you are using a different U-boot/Linux kenrel, and you're not able to apply this patch, please contact us for assistance.

 

SolidRun Ltd.