mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
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 <gpoulios@census-labs.com>
This commit is contained in:
parent
e540fae8b3
commit
03f7f59fa8
6 changed files with 134 additions and 1 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, ®);
|
||||
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, ®);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue