[PATCH v5 net-next 2/2] net: phy: c45-tja11xx: add support for outputting RMII reference clock

From: Wei Fang
Date: Thu Oct 10 2024 - 02:35:37 EST


For TJA11xx PHYs, they have the capability to output 50MHz reference
clock on REF_CLK pin in RMII mode, which is called "revRMII" mode in
the PHY data sheet.

Signed-off-by: Wei Fang <wei.fang@xxxxxxx>
---
V2 changes:
1. Change the property name.
2. Modify the subject and commit message.
V3 changes:
No changes.
V4 changes:
1. Change the property name based on patch 1.
V5 changes:
1. Fix a typo in the title.
2. Based on Russel's suggestion, add comment to MII_BASIC_CONFIG_REV
and the basic_config variable to make the code clearer.
---
drivers/net/phy/nxp-c45-tja11xx.c | 30 +++++++++++++++++++++++++++++-
drivers/net/phy/nxp-c45-tja11xx.h | 1 +
2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 5af5ade4fc64..7e328c2a29a4 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/mii.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/phy.h>
#include <linux/processor.h>
#include <linux/property.h>
@@ -185,6 +186,8 @@

#define NXP_C45_SKB_CB(skb) ((struct nxp_c45_skb_cb *)(skb)->cb)

+#define TJA11XX_REVERSE_MODE BIT(0)
+
struct nxp_c45_phy;

struct nxp_c45_skb_cb {
@@ -1510,6 +1513,8 @@ static int nxp_c45_get_delays(struct phy_device *phydev)

static int nxp_c45_set_phy_mode(struct phy_device *phydev)
{
+ struct nxp_c45_phy *priv = phydev->priv;
+ u16 basic_config;
int ret;

ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_ABILITIES);
@@ -1561,8 +1566,15 @@ static int nxp_c45_set_phy_mode(struct phy_device *phydev)
phydev_err(phydev, "rmii mode not supported\n");
return -EINVAL;
}
+
+ basic_config = MII_BASIC_CONFIG_RMII;
+
+ /* This is not PHY_INTERFACE_MODE_REVRMII */
+ if (priv->flags & TJA11XX_REVERSE_MODE)
+ basic_config |= MII_BASIC_CONFIG_REV;
+
phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_MII_BASIC_CONFIG,
- MII_BASIC_CONFIG_RMII);
+ basic_config);
break;
case PHY_INTERFACE_MODE_SGMII:
if (!(ret & SGMII_ABILITY)) {
@@ -1623,6 +1635,20 @@ static int nxp_c45_get_features(struct phy_device *phydev)
return genphy_c45_pma_read_abilities(phydev);
}

+static int nxp_c45_parse_dt(struct phy_device *phydev)
+{
+ struct device_node *node = phydev->mdio.dev.of_node;
+ struct nxp_c45_phy *priv = phydev->priv;
+
+ if (!IS_ENABLED(CONFIG_OF_MDIO))
+ return 0;
+
+ if (of_property_read_bool(node, "nxp,rmii-refclk-out"))
+ priv->flags |= TJA11XX_REVERSE_MODE;
+
+ return 0;
+}
+
static int nxp_c45_probe(struct phy_device *phydev)
{
struct nxp_c45_phy *priv;
@@ -1642,6 +1668,8 @@ static int nxp_c45_probe(struct phy_device *phydev)

phydev->priv = priv;

+ nxp_c45_parse_dt(phydev);
+
mutex_init(&priv->ptp_lock);

phy_abilities = phy_read_mmd(phydev, MDIO_MMD_VEND1,
diff --git a/drivers/net/phy/nxp-c45-tja11xx.h b/drivers/net/phy/nxp-c45-tja11xx.h
index f364fca68f0b..8b5fc383752b 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.h
+++ b/drivers/net/phy/nxp-c45-tja11xx.h
@@ -28,6 +28,7 @@ struct nxp_c45_phy {
int extts_index;
bool extts;
struct nxp_c45_macsec *macsec;
+ u32 flags;
};

#if IS_ENABLED(CONFIG_MACSEC)
--
2.34.1