]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
imx8mm-cl-iot-gate: Add support for the Realtek RTL8211E PHY
authorFabio Estevam <festevam@denx.de>
Tue, 28 May 2024 19:15:10 +0000 (16:15 -0300)
committerFabio Estevam <festevam@gmail.com>
Mon, 3 Jun 2024 15:14:29 +0000 (12:14 -0300)
Newer imx8mm-cl-iot-gate versions are populated with a Realtek RTL8211E
PHY instead of the Atheros AR8033.

Adapted Compulab's patch from:
https://github.com/compulab-yokneam/meta-bsp-imx8mm/blob/iot-gate-imx8_5.10.72/recipes-bsp/u-boot/compulab/imx8mm/0125-imx8mm-net-enable-phy-Realtek-RTL8211E.patch

to support both PHYs in U-Boot.

Signed-off-by: Fabio Estevam <festevam@denx.de>
board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c
include/configs/imx8mm-cl-iot-gate.h

index ba15873414283b4c334bb9bec5ff03a052706696..bda7aac5be4b3006447c251cec55bd24511701d6 100644 (file)
@@ -8,6 +8,7 @@
 #include <efi_loader.h>
 #include <env.h>
 #include <extension_board.h>
+#include <fdt_support.h>
 #include <hang.h>
 #include <i2c.h>
 #include <init.h>
@@ -30,6 +31,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static int fec_phyaddr = -1;
+
 #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
 struct efi_fw_image fw_images[] = {
 #if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE)
@@ -109,10 +112,72 @@ static int setup_fec(void)
        return 0;
 }
 
+#define FDT_PHYADDR "/soc@0/bus@30800000/ethernet@30be0000/mdio/ethernet-phy@0"
+#define FLIP_32B(val) (((val >> 24) & 0xff) | ((val << 8) & 0xff0000) | ((val >> 8) & 0xff00) | ((val << 24) & 0xff000000))
+static int fdt_set_fec_phy_addr(void *blob)
+{
+       u32 val;
+
+       if (fec_phyaddr < 0)
+               return -EINVAL;
+
+       val = FLIP_32B(fec_phyaddr);
+       return fdt_find_and_setprop(blob, FDT_PHYADDR, "reg", (const void *)&val,
+                                   sizeof(val), 0);
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+       fdt_set_fec_phy_addr(blob);
+       return 0;
+}
+
+/*
+ * These are specific ID, purposed to distiguish between PHY vendors.
+ * These values are not equal to real vendors' OUI (half of MAC address)
+ */
+#define OUI_PHY_ATHEROS 0x1374
+#define OUI_PHY_REALTEK 0x0732
+
 int board_phy_config(struct phy_device *phydev)
 {
-       if (IS_ENABLED(CONFIG_FEC_MXC)) {
+       unsigned int model, rev, oui;
+       int phyid1, phyid2;
+       unsigned int reg;
+
+       if (!IS_ENABLED(CONFIG_FEC_MXC))
+               return 0;
+
+       phyid1 = phy_read(phydev, MDIO_DEVAD_NONE, MII_PHYSID1);
+       if (phyid1 < 0) {
+               printf("%s: PHYID1 registry read fail %i\n", __func__, phyid1);
+               return phyid1;
+       }
+
+       phyid2 = phy_read(phydev, MDIO_DEVAD_NONE, MII_PHYSID2);
+       if (phyid2 < 0) {
+               printf("%s: PHYID2 registry read fail %i\n", __func__, phyid2);
+               return phyid2;
+       }
+
+       reg = phyid2 | phyid1 << 16;
+       if (reg == 0xffff) {
+               printf("%s: There is no device @%i\n", __func__, phydev->addr);
+               return -ENODEV;
+       }
+
+       rev = reg & 0xf;
+       reg >>= 4;
+       model = reg & 0x3f;
+       reg >>= 6;
+       oui = reg;
+       debug("%s: PHY @0x%x OUI 0x%06x model 0x%x rev 0x%x\n",
+             __func__, phydev->addr, oui, model, rev);
+
+       switch (oui) {
+       case OUI_PHY_ATHEROS:
                /* enable rgmii rxc skew and phy mode select to RGMII copper */
+               printf("phy: AR803x@%x\t", phydev->addr);
                phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
                phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
 
@@ -120,10 +185,45 @@ int board_phy_config(struct phy_device *phydev)
                phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee);
                phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
                phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
+               break;
+       case OUI_PHY_REALTEK:
+               printf("phy: RTL8211E@%x\t", phydev->addr);
+               /* RTL8211E-VB-CG - add TX and RX delay */
+               unsigned short val;
+
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x07);
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0xa4);
+               val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1c);
+               val |= (0x1 << 13) | (0x1 << 12) | (0x1 << 11);
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1c, val);
+               /* LEDs: set to extension page */
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x0007);
+               /* extension Page44 */
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x002c);
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1c, 0x0430);//LCR
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1a, 0x0010);//LACR
+               /*
+                * To disable EEE LED mode (blinking .4s/2s)
+                * Extension Page5
+                */
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x0005);
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x05, 0x8b82);//magic const
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x06, 0x052b);//magic const
+
+               phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x00);// Back to Page0
 
-               if (phydev->drv->config)
-                       phydev->drv->config(phydev);
+               break;
+       default:
+               printf("%s: ERROR: unknown PHY @0x%x OUI 0x%06x model 0x%x rev 0x%x\n",
+                      __func__, phydev->addr, oui, model, rev);
+               return -ENOSYS;
        }
+
+       fec_phyaddr = phydev->addr;
+
+       if (phydev->drv->config)
+               phydev->drv->config(phydev);
+
        return 0;
 }
 
index 09d87cf214bf3e9e427ca34335044328aa3551f3..0c547027ba69013a2093b82b0faf026ade6f9c7c 100644 (file)
 #define CFG_SYS_FSL_USDHC_NUM  2
 #define CFG_SYS_FSL_ESDHC_ADDR 0
 
-#define CFG_FEC_MXC_PHYADDR            0
+#define CFG_FEC_MXC_PHYADDR            -1 /* Auto search of PHY on MII */
 
 /* USB Configs */
 #define CFG_MXC_USB_PORTSC     (PORT_PTS_UTMI | PORT_PTS_PTW)