This is an automated email from the ASF dual-hosted git repository.

jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 67c7a4018ad5a27b544353ac0549fa27c22605a2
Author: George Poulios <gpoul...@census-labs.com>
AuthorDate: Wed Jun 4 11:33:35 2025 +0300

    arm64/imx9: Support & configure RGMII-ID on RTL8211F
    
    For the RTL8211F PHY, configuration of RX/TXDLY was missing.
    At least on my i.MX93 EVK, this is necessary for transmission
    to work (RXDLY defaults to true on the PHY).
    
    This commit brings support for RGMII internal delay configuration
    (on or off for both directions) and enables it on the i.MX93 EVK
    board. The introduced Kconfig is set to default to 'n', to avoid
    breaking the functionality of other, out-of-tree boards based on
    i.MX93, running the RTL8211F PHY, or to avoid introducing
    unnecessary code on boards running other PHYs.
    
    Configuration of internal delay on other PHYs is not
    implemented, and results in a warning (but no error).
    
    Signed-off-by: George Poulios <gpoul...@census-labs.com>
---
 arch/arm64/src/imx9/Kconfig                        |  15 +++
 arch/arm64/src/imx9/imx9_enet.c                    | 112 +++++++++++++++++++++
 boards/arm64/imx9/imx93-evk/configs/knsh/defconfig |   1 +
 .../arm64/imx9/imx93-evk/configs/koptee/defconfig  |   1 +
 boards/arm64/imx9/imx93-evk/configs/nsh/defconfig  |   1 +
 include/nuttx/net/gmii.h                           |   5 +-
 6 files changed, 134 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/src/imx9/Kconfig b/arch/arm64/src/imx9/Kconfig
index ee0dd1627f..79dcafad16 100644
--- a/arch/arm64/src/imx9/Kconfig
+++ b/arch/arm64/src/imx9/Kconfig
@@ -1003,6 +1003,21 @@ config IMX9_ENET1_RGMII
 
 endchoice
 
+if IMX9_ENET1_RGMII
+
+config IMX9_ENET1_RGMII_ID
+       bool "Enable the PHY internal delay on both TX & RX signals"
+       default n
+       depends on IMX9_ENET1_RGMII
+       ---help---
+               In RGMII-ID mode, the PHY introduces an internal delay 
eliminating
+               the need for a timing skew between the data and clock signals 
otherwise
+               generated by the PCB design. This is currently only implemented 
for the
+               RTL8211F chip; enabling or disabling it on any other PHYs will 
not make
+               any difference.
+
+endif # IMX9_ENET1_RGMII
+
 config IMX9_ENET1_TX_CLOCK_IS_INPUT
        bool "ENET1 TX clock is input"
        default y if IMX9_ENET1_RMII
diff --git a/arch/arm64/src/imx9/imx9_enet.c b/arch/arm64/src/imx9/imx9_enet.c
index f79663e9b7..6a10d12fd0 100644
--- a/arch/arm64/src/imx9/imx9_enet.c
+++ b/arch/arm64/src/imx9/imx9_enet.c
@@ -277,6 +277,11 @@ static int imx9_writemii(struct imx9_driver_s *priv, 
uint8_t regaddr,
                          uint16_t data);
 static int imx9_readmii(struct imx9_driver_s *priv, uint8_t regaddr,
                         uint16_t *data);
+#ifdef CONFIG_IMX9_ENET1_RGMII
+static int imx9_config_rgmii_id(struct imx9_driver_s *priv);
+#else
+#  define imx9_config_rgmii_id(priv) (OK)
+#endif
 static int imx9_initphy(struct imx9_driver_s *priv, bool renogphy);
 
 static int imx9_readmmd(struct imx9_driver_s *priv, uint8_t mmd,
@@ -2677,6 +2682,102 @@ static int imx9_phy_wait_autoneg_complete(struct 
imx9_driver_s *priv)
   return imx9_read_phy_status(priv);
 }
 
+/****************************************************************************
+ * Function: imx9_config_rgmii_id
+ *
+ * Description:
+ *   Configure the PHY internal delay. Currently only supported on RTL8211F.
+ *   If CONFIG_IMX9_ENET1_RGMII_ID is set, this function sets both TXDLY
+ *   and RXDLY bit on MIICR1 and MIICR2 respectively. Otherwise, it clears
+ *   the respective bits.
+ *
+ * Input Parameters:
+ *   priv     - Reference to the private ENET driver state structure
+ *
+ * Returned Value:
+ *   Zero (OK) returned on success; a negated errno value is returned on any
+ *   failure;
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_IMX9_ENET1_RGMII
+static int imx9_config_rgmii_id(struct imx9_driver_s *priv)
+{
+  int ret;
+  uint16_t prev_page;
+  uint16_t reg;
+
+  if (!imx9_phy_is(priv, GMII_RTL8211F_NAME))
+    {
+      nwarn("WARN: not configuring RGMII Internal Delay on %s phy\n",
+            priv->cur_phy->name);
+      return OK;
+    }
+
+  ret = imx9_readmii(priv, GMII_RTL8211F_PAGSR, &prev_page);
+  if (ret < 0)
+    {
+      nerr("ERROR: Getting page, imx9_readmii failed: %d\n", ret);
+      goto errout;
+    }
+
+  ret = imx9_writemii(priv, GMII_RTL8211F_PAGSR, 0xd08);
+  if (ret < 0)
+    {
+      nerr("ERROR: Selecting page, imx9_writemii failed: %d\n", ret);
+      goto errout;
+    }
+
+  ret = imx9_readmii(priv, GMII_RTL8211F_MIICR1_D08, &reg);
+  if (ret < 0)
+    {
+      nerr("ERROR: Reading MIICR1, imx9_readmii failed: %d\n", ret);
+      goto errout;
+    }
+
+#ifdef CONFIG_IMX9_ENET1_RGMII_ID
+  reg |= GMII_RTL8211F_MIICR1_TX_DELAY;
+#else
+  reg &= ~GMII_RTL8211F_MIICR1_TX_DELAY;
+#endif
+  ret = imx9_writemii(priv, GMII_RTL8211F_MIICR1_D08, reg);
+  if (ret < 0)
+    {
+      nerr("ERROR: Enabling TXDLY, imx9_writemii failed: %d\n", ret);
+      goto errout;
+    }
+
+  ret = imx9_readmii(priv, GMII_RTL8211F_MIICR2_D08, &reg);
+  if (ret < 0)
+    {
+      nerr("ERROR: Reading MIICR2, imx9_readmii failed: %d\n", ret);
+      goto errout;
+    }
+
+#ifdef CONFIG_IMX9_ENET1_RGMII_ID
+  reg |= GMII_RTL8211F_MIICR2_RX_DELAY;
+#else
+  reg &= ~GMII_RTL8211F_MIICR2_RX_DELAY;
+#endif
+  ret = imx9_writemii(priv, GMII_RTL8211F_MIICR2_D08, reg);
+  if (ret < 0)
+    {
+      nerr("ERROR: Enabling RXDLY, imx9_writemii failed: %d\n", ret);
+      goto errout;
+    }
+
+  ret = imx9_writemii(priv, GMII_RTL8211F_PAGSR, prev_page);
+  if (ret < 0)
+    {
+      nerr("ERROR: Restoring page, imx9_writemii failed: %d\n", ret);
+      goto errout;
+    }
+
+errout:
+  return ret;
+}
+#endif /* CONFIG_IMX9_ENET1_RGMII */
+
 /****************************************************************************
  * Function: imx9_initphy
  *
@@ -2897,6 +2998,17 @@ static inline int imx9_initphy(struct imx9_driver_s 
*priv, bool renogphy)
 
   imx9_enet_putreg32(priv, rcr, IMX9_ENET_RCR_OFFSET);
   imx9_enet_putreg32(priv, tcr, IMX9_ENET_TCR_OFFSET);
+
+  if (priv->phy_type == PHY_RGMII)
+    {
+      ret = imx9_config_rgmii_id(priv);
+      if (ret < 0)
+        {
+          nerr("ERROR: configure internal delay failed: %d\n", ret);
+          return ret;
+        }
+    }
+
   return OK;
 }
 
diff --git a/boards/arm64/imx9/imx93-evk/configs/knsh/defconfig 
b/boards/arm64/imx9/imx93-evk/configs/knsh/defconfig
index cb66d1c771..e44ea00775 100644
--- a/boards/arm64/imx9/imx93-evk/configs/knsh/defconfig
+++ b/boards/arm64/imx9/imx93-evk/configs/knsh/defconfig
@@ -68,6 +68,7 @@ CONFIG_IMX9_DMA_ALLOC=y
 CONFIG_IMX9_DMA_ALLOC_POOL_SIZE=81920
 CONFIG_IMX9_EDMA=y
 CONFIG_IMX9_ENET1_RGMII=y
+CONFIG_IMX9_ENET1_RGMII_ID=y
 CONFIG_IMX9_ENET=y
 CONFIG_IMX9_ENET_USE_OTP_MAC=y
 CONFIG_IMX9_FLEXIO1_PWM=y
diff --git a/boards/arm64/imx9/imx93-evk/configs/koptee/defconfig 
b/boards/arm64/imx9/imx93-evk/configs/koptee/defconfig
index 375110df10..ef92227dee 100644
--- a/boards/arm64/imx9/imx93-evk/configs/koptee/defconfig
+++ b/boards/arm64/imx9/imx93-evk/configs/koptee/defconfig
@@ -73,6 +73,7 @@ CONFIG_IMX9_DMA_ALLOC=y
 CONFIG_IMX9_DMA_ALLOC_POOL_SIZE=81920
 CONFIG_IMX9_EDMA=y
 CONFIG_IMX9_ENET1_RGMII=y
+CONFIG_IMX9_ENET1_RGMII_ID=y
 CONFIG_IMX9_ENET=y
 CONFIG_IMX9_ENET_USE_OTP_MAC=y
 CONFIG_IMX9_FLEXIO1_PWM=y
diff --git a/boards/arm64/imx9/imx93-evk/configs/nsh/defconfig 
b/boards/arm64/imx9/imx93-evk/configs/nsh/defconfig
index 6ed1e18226..09f153f038 100644
--- a/boards/arm64/imx9/imx93-evk/configs/nsh/defconfig
+++ b/boards/arm64/imx9/imx93-evk/configs/nsh/defconfig
@@ -46,6 +46,7 @@ CONFIG_IMX9_DMA_ALLOC=y
 CONFIG_IMX9_DMA_ALLOC_POOL_SIZE=81920
 CONFIG_IMX9_EDMA=y
 CONFIG_IMX9_ENET1_RGMII=y
+CONFIG_IMX9_ENET1_RGMII_ID=y
 CONFIG_IMX9_ENET=y
 CONFIG_IMX9_ENET_USE_OTP_MAC=y
 CONFIG_IMX9_FLEXIO1_PWM=y
diff --git a/include/nuttx/net/gmii.h b/include/nuttx/net/gmii.h
index 184af40783..f4be7bb5bb 100644
--- a/include/nuttx/net/gmii.h
+++ b/include/nuttx/net/gmii.h
@@ -94,7 +94,8 @@
 #define GMII_RTL8211F_PHYSCR_A46      20      /* PHY Special Config Register */
 #define GMII_RTL8211F_LCR_D04         16      /* LED Control Register */
 #define GMII_RTL8211F_EEELCR_D04      17      /* EEE LED Control Register */
-#define GMII_RTL8211F_MIICR_D08       21      /* MII Control Register */
+#define GMII_RTL8211F_MIICR1_D08      17      /* MII Control Register 1 */
+#define GMII_RTL8211F_MIICR2_D08      21      /* MII Control Register 2 */
 #define GMII_RTL8211F_INTBCR_D40      22      /* INTB Pin Control Register */
 
 /* MII register bit settings ************************************************/
@@ -308,6 +309,8 @@
 #define GMII_RTL8211F_PHYSR_100MBPS    0x10
 #define GMII_RTL8211F_PHYSR_1000MBPS   0x20
 #define GMII_RTL8211F_PHYSR_DUPLEX     0x8
+#define GMII_RTL8211F_MIICR1_TX_DELAY  (1 << 8) /* Enable PHY internal TX 
delay */
+#define GMII_RTL8211F_MIICR2_RX_DELAY  (1 << 3) /* Enable PHY internal RX 
delay */
 
 /****************************************************************************
  * Type Definitions

Reply via email to