imxrt:Support TJ1103 PHY

This commit is contained in:
David Sidrane
2022-11-04 11:39:39 -07:00
committed by Xiang Xiao
parent c8855ab986
commit d05a5d16ee
3 changed files with 243 additions and 2 deletions
+236 -2
View File
@@ -247,6 +247,19 @@
# define BOARD_PHY_10BASET(s) (((s) & MII_DP83825I_PHYSTS_SPEED) != 0)
# define BOARD_PHY_100BASET(s) (((s) & MII_DP83825I_PHYSTS_SPEED) == 0)
# define BOARD_PHY_ISDUPLEX(s) (((s) & MII_DP83825I_PHYSTS_DUPLEX) != 0)
#elif defined(CONFIG_ETH0_PHY_TJA1103)
# define BOARD_PHY_NAME "TJA1103"
# define BOARD_PHYID1 MII_PHYID1_TJA1103
# define BOARD_PHYID2 MII_PHYID2_TJA1103
# define BOARD_PHY_STATUS MII_TJA110X_BSR
# define BOARD_PHY_10BASET(s) 0 /* PHY only supports 100BASE-T1 */
# define BOARD_PHY_100BASET(s) 1 /* PHY only supports 100BASE-T1 */
# define BOARD_PHY_ISDUPLEX(s) 1 /* PHY only supports fullduplex */
# define CLAUSE45 1
# define MMD1 1
# define MMD1_PMA_STATUS1 1
# define MMD1_PS1_RECEIVE_LINK_STATUS (1 << 2)
#else
# error "Unrecognized or missing PHY selection"
#endif
@@ -424,7 +437,14 @@ static int imxrt_writemii(struct imxrt_driver_s *priv, uint8_t phyaddr,
static int imxrt_readmii(struct imxrt_driver_s *priv, uint8_t phyaddr,
uint8_t regaddr, uint16_t *data);
static int imxrt_initphy(struct imxrt_driver_s *priv, bool renogphy);
#if defined(CLAUSE45)
static int imxrt_readmmd(struct imxrt_driver_s *priv, uint8_t phyaddr,
uint8_t mmd, uint16_t regaddr, uint16_t *data);
#if 0
static int imxrt_writemmd(struct imxrt_driver_s *priv, uint8_t phyaddr,
uint8_t mmd, uint16_t regaddr, uint16_t data);
#endif
#endif
/* Initialization */
static void imxrt_initbuffers(struct imxrt_driver_s *priv);
@@ -1842,8 +1862,18 @@ static int imxrt_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg)
{
struct mii_ioctl_data_s *req =
(struct mii_ioctl_data_s *)((uintptr_t)arg);
ret = imxrt_readmii(priv, req->phy_id,
#if defined(CLAUSE45)
if (MII_MSR == req->reg_num)
{
ret = imxrt_readmmd(priv, req->phy_id, MMD1, MMD1_PMA_STATUS1,
&req->val_out);
}
else
#endif
{
ret = imxrt_readmii(priv, req->phy_id,
req->reg_num, &req->val_out);
}
}
break;
@@ -2065,6 +2095,206 @@ static int imxrt_readmii(struct imxrt_driver_s *priv, uint8_t phyaddr,
return OK;
}
#if 0
#if defined(CLAUSE45)
/****************************************************************************
* Function: imxrt_writemmd
*
* Description:
* Write a 16-bit value to a the selected MMD PHY register.
*
* Input Parameters:
* priv - Reference to the private ENET driver state structure
* phyaddr - The PHY address
* mmd - The Selected MMD Space
* regaddr - The PHY register address
* data - The data to write to the PHY register
*
* Returned Value:
* Zero on success, a negated errno value on failure.
*
****************************************************************************/
static int imxrt_writemmd(struct imxrt_driver_s *priv, uint8_t phyaddr,
uint8_t mmd, uint16_t regaddr, uint16_t data)
{
int timeout;
/* Clear the MII interrupt bit */
imxrt_enet_putreg32(priv, ENET_INT_MII, IMXRT_ENET_EIR_OFFSET);
/* Initiate the MMD Management write - Address Phase */
imxrt_enet_putreg32(priv,
0 << ENET_MMFR_ST_SHIFT |
ENET_MMFR_OP_WRNOTMII |
(uint32_t)mmd << ENET_MMFR_RA_SHIFT |
(uint32_t)phyaddr << ENET_MMFR_PA_SHIFT |
2 << ENET_MMFR_TA_SHIFT |
regaddr,
IMXRT_ENET_MMFR_OFFSET);
/* Wait for the transfer to complete */
for (timeout = 0; timeout < MII_MAXPOLLS; timeout++)
{
if ((imxrt_enet_getreg32(priv, IMXRT_ENET_EIR_OFFSET) &
ENET_INT_MII) != 0)
{
break;
}
}
imxrt_enet_putreg32(priv, ENET_INT_MII, IMXRT_ENET_EIR_OFFSET);
/* Check for a timeout */
if (timeout == MII_MAXPOLLS)
{
return -ETIMEDOUT;
}
/* Initiate the MMD Management write - Data Phase */
imxrt_enet_putreg32(priv,
0 << ENET_MMFR_ST_SHIFT |
ENET_MMFR_OP_WRMII |
(uint32_t)mmd << ENET_MMFR_RA_SHIFT |
(uint32_t)phyaddr << ENET_MMFR_PA_SHIFT |
2 << ENET_MMFR_TA_SHIFT |
data,
IMXRT_ENET_MMFR_OFFSET);
/* Wait for the transfer to complete */
for (timeout = 0; timeout < MII_MAXPOLLS; timeout++)
{
if ((imxrt_enet_getreg32(priv, IMXRT_ENET_EIR_OFFSET) &
ENET_INT_MII) != 0)
{
break;
}
}
/* Clear the MII interrupt bit */
imxrt_enet_putreg32(priv, ENET_INT_MII, IMXRT_ENET_EIR_OFFSET);
/* Check for a timeout */
if (timeout == MII_MAXPOLLS)
{
return -ETIMEDOUT;
}
return OK;
}
#endif
#endif
#if defined(CLAUSE45)
/****************************************************************************
* Function: imxrt_reademmd
*
* Description:
* Read a 16-bit value from a PHY register.
*
* Input Parameters:
* priv - Reference to the private ENET driver state structure
* phyaddr - The PHY address
* mmd - The Selected MMD Space
* regaddr - The PHY register address
* data - A pointer to the location to return the data
*
* Returned Value:
* Zero on success, a negated errno value on failure.
*
****************************************************************************/
static int imxrt_readmmd(struct imxrt_driver_s *priv, uint8_t phyaddr,
uint8_t mmd, uint16_t regaddr, uint16_t *data)
{
int timeout;
/* Clear the MII interrupt bit */
imxrt_enet_putreg32(priv, ENET_INT_MII, IMXRT_ENET_EIR_OFFSET);
/* Initiate the MMD Management read - Address Phase */
imxrt_enet_putreg32(priv,
0 << ENET_MMFR_ST_SHIFT |
ENET_MMFR_OP_WRNOTMII |
(uint32_t)mmd << ENET_MMFR_RA_SHIFT |
(uint32_t)phyaddr << ENET_MMFR_PA_SHIFT |
2 << ENET_MMFR_TA_SHIFT |
regaddr,
IMXRT_ENET_MMFR_OFFSET);
/* Wait for the transfer to complete */
for (timeout = 0; timeout < MII_MAXPOLLS; timeout++)
{
if ((imxrt_enet_getreg32(priv, IMXRT_ENET_EIR_OFFSET) &
ENET_INT_MII) != 0)
{
break;
}
}
/* Clear the MII interrupt bit */
imxrt_enet_putreg32(priv, ENET_INT_MII, IMXRT_ENET_EIR_OFFSET);
/* Check for a timeout */
if (timeout >= MII_MAXPOLLS)
{
nerr("ERROR: Timed out waiting for transfer to complete\n");
return -ETIMEDOUT;
}
/* Initiate the MMD Management read - Data Phase */
imxrt_enet_putreg32(priv,
0 << ENET_MMFR_ST_SHIFT |
ENET_MMFR_OP_RdNOTMII |
(uint32_t)mmd << ENET_MMFR_RA_SHIFT |
(uint32_t)phyaddr << ENET_MMFR_PA_SHIFT |
2 << ENET_MMFR_TA_SHIFT,
IMXRT_ENET_MMFR_OFFSET);
/* Wait for the transfer to complete */
for (timeout = 0; timeout < MII_MAXPOLLS; timeout++)
{
if ((imxrt_enet_getreg32(priv, IMXRT_ENET_EIR_OFFSET) &
ENET_INT_MII) != 0)
{
break;
}
}
/* Clear the MII interrupt bit */
imxrt_enet_putreg32(priv, ENET_INT_MII, IMXRT_ENET_EIR_OFFSET);
/* Check for a timeout */
if (timeout == MII_MAXPOLLS)
{
return -ETIMEDOUT;
}
/* And return the MII data */
*data = (uint16_t)(imxrt_enet_getreg32(priv, IMXRT_ENET_MMFR_OFFSET) &
ENET_MMFR_DATA_MASK);
return OK;
}
#endif
/****************************************************************************
* Function: imxrt_initphy
*
@@ -2240,6 +2470,7 @@ static inline int imxrt_initphy(struct imxrt_driver_s *priv, bool renogphy)
MII_ADVERTISE_CSMA);
#endif
#if !defined(CONFIG_ETH0_PHY_TJA1103)
/* Start auto negotiation */
@@ -2288,8 +2519,10 @@ static inline int imxrt_initphy(struct imxrt_driver_s *priv, bool renogphy)
imxrt_writemii(priv, phyaddr, MII_MCR, 0);
}
#endif
}
#if !defined(CONFIG_ETH0_PHY_TJA1103)
/* When we get here we have a (negotiated) speed and duplex. This is also
* the point we enter if renegotiation is turned off, so have multiple
* attempts at reading the status register in case the PHY isn't awake
@@ -2327,6 +2560,7 @@ static inline int imxrt_initphy(struct imxrt_driver_s *priv, bool renogphy)
}
ninfo("%s: BOARD_PHY_STATUS: %04x\n", BOARD_PHY_NAME, phydata);
#endif
/* Set up the transmit and receive control registers based on the
* configuration and the auto negotiation results.
+4
View File
@@ -429,6 +429,10 @@ config ETH0_PHY_TJA1101
bool "NXP TJA1101 PHY"
select ARCH_PHY_100BASE_T1
config ETH0_PHY_TJA1103
bool "NXP TJA1103 PHY"
select ARCH_PHY_100BASE_T1
config ETH0_PHY_LAN8720
bool "SMSC LAN8720 PHY"
+3
View File
@@ -700,6 +700,9 @@
#define MII_PHYID1_TJA1101 0x0180 /* ID1 value for NXP TJA1101 */
#define MII_PHYID2_TJA1101 0xdd00 /* ID2 value for NXP TJA1101 */
#define MII_PHYID1_TJA1103 0x01b /* ID1 value for NXP TJA1103 */
#define MII_PHYID2_TJA1103 0xB013 /* ID2 value for NXP TJA1103 */
#define MII_TJA110X_BCR 0x0 /* Basic Control register */
#define MII_TJA110X_BSR 0x1 /* Basic Status register */
#define MII_TJA110X_EXT_CNTRL 0x11 /* Extra control register */