From 95f4fa1f459a69827d752bd55205af7c55b76e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Dautheribes?= Date: Thu, 22 Feb 2024 11:31:15 +0100 Subject: [PATCH 1/3] dt-bindings: net: dp83822: support configuring RMII master/slave mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add property ti,rmii-mode to support selecting the RMII operation mode between: - master mode (PHY operates from a 25MHz clock reference) - slave mode (PHY operates from a 50MHz clock reference) If not set, the operation mode is configured by hardware straps. Signed-off-by: Jérémie Dautheribes Acked-by: Krzysztof Kozlowski Signed-off-by: David S. Miller --- .../devicetree/bindings/net/ti,dp83822.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/net/ti,dp83822.yaml b/Documentation/devicetree/bindings/net/ti,dp83822.yaml index 8f4350be689c5..8f23254c0458f 100644 --- a/Documentation/devicetree/bindings/net/ti,dp83822.yaml +++ b/Documentation/devicetree/bindings/net/ti,dp83822.yaml @@ -80,6 +80,22 @@ properties: 10625, 11250, 11875, 12500, 13125, 13750, 14375, 15000] default: 10000 + ti,rmii-mode: + description: | + If present, select the RMII operation mode. Two modes are + available: + - RMII master, where the PHY operates from a 25MHz clock reference, + provided by a crystal or a CMOS-level oscillator + - RMII slave, where the PHY operates from a 50MHz clock reference, + provided by a CMOS-level oscillator + The RMII operation mode can also be configured by its straps. + If the strap pin is not set correctly or not set at all, then this can be + used to configure it. + $ref: /schemas/types.yaml#/definitions/string + enum: + - master + - slave + required: - reg From d2ed0774b6334ce3986c5efb17ab9c4095b8d969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Dautheribes?= Date: Thu, 22 Feb 2024 11:31:16 +0100 Subject: [PATCH 2/3] net: phy: dp83826: Add support for phy-mode configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TI DP83826 PHY can operate in either MII mode or RMII mode. By default, it is configured by straps. It can also be configured by writing to the bit 5 of register 0x17 - RMII and Status Register (RCSR). When phydev->interface is rmii, rmii mode must be enabled, otherwise mii mode must be set. This prevents misconfiguration of hw straps. Signed-off-by: Jérémie Dautheribes Reviewed-by: Maxime Chevallier Signed-off-by: David S. Miller --- drivers/net/phy/dp83822.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index 30f2616ab1c26..2d8275e59dcc2 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -100,6 +100,7 @@ #define DP83822_WOL_CLR_INDICATION BIT(11) /* RCSR bits */ +#define DP83822_RMII_MODE_EN BIT(5) #define DP83822_RGMII_MODE_EN BIT(9) #define DP83822_RX_CLK_SHIFT BIT(12) #define DP83822_TX_CLK_SHIFT BIT(11) @@ -500,6 +501,16 @@ static int dp83826_config_init(struct phy_device *phydev) u16 val, mask; int ret; + if (phydev->interface == PHY_INTERFACE_MODE_RMII) + ret = phy_set_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, + DP83822_RMII_MODE_EN); + else + ret = phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, + DP83822_RMII_MODE_EN); + + if (ret) + return ret; + if (dp83822->cfg_dac_minus != DP83826_CFG_DAC_MINUS_DEFAULT) { val = FIELD_PREP(DP83826_VOD_CFG1_MINUS_MDI_MASK, dp83822->cfg_dac_minus) | FIELD_PREP(DP83826_VOD_CFG1_MINUS_MDIX_MASK, From 2844a0d7cffe0567d1d3d18be227542bd1f15d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Dautheribes?= Date: Thu, 22 Feb 2024 11:31:17 +0100 Subject: [PATCH 3/3] net: phy: dp83826: support configuring RMII master/slave operation mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TI DP83826 PHY can operate between two RMII modes: - master mode (PHY operates from a 25MHz clock reference) - slave mode (PHY operates from a 50MHz clock reference) By default, the operation mode is configured by hardware straps. Add support to configure the operation mode from within the driver. Signed-off-by: Jérémie Dautheribes Signed-off-by: David S. Miller --- drivers/net/phy/dp83822.c | 43 ++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index 2d8275e59dcc2..edc39ae4c241b 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -101,6 +101,7 @@ /* RCSR bits */ #define DP83822_RMII_MODE_EN BIT(5) +#define DP83822_RMII_MODE_SEL BIT(7) #define DP83822_RGMII_MODE_EN BIT(9) #define DP83822_RX_CLK_SHIFT BIT(12) #define DP83822_TX_CLK_SHIFT BIT(11) @@ -495,21 +496,53 @@ static int dp83822_config_init(struct phy_device *phydev) return dp8382x_disable_wol(phydev); } +static int dp83826_config_rmii_mode(struct phy_device *phydev) +{ + struct device *dev = &phydev->mdio.dev; + const char *of_val; + int ret; + + if (!device_property_read_string(dev, "ti,rmii-mode", &of_val)) { + if (strcmp(of_val, "master") == 0) { + ret = phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, + DP83822_RMII_MODE_SEL); + } else if (strcmp(of_val, "slave") == 0) { + ret = phy_set_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, + DP83822_RMII_MODE_SEL); + } else { + phydev_err(phydev, "Invalid value for ti,rmii-mode property (%s)\n", + of_val); + ret = -EINVAL; + } + + if (ret) + return ret; + } + + return 0; +} + static int dp83826_config_init(struct phy_device *phydev) { struct dp83822_private *dp83822 = phydev->priv; u16 val, mask; int ret; - if (phydev->interface == PHY_INTERFACE_MODE_RMII) + if (phydev->interface == PHY_INTERFACE_MODE_RMII) { ret = phy_set_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, DP83822_RMII_MODE_EN); - else + if (ret) + return ret; + + ret = dp83826_config_rmii_mode(phydev); + if (ret) + return ret; + } else { ret = phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, DP83822_RMII_MODE_EN); - - if (ret) - return ret; + if (ret) + return ret; + } if (dp83822->cfg_dac_minus != DP83826_CFG_DAC_MINUS_DEFAULT) { val = FIELD_PREP(DP83826_VOD_CFG1_MINUS_MDI_MASK, dp83822->cfg_dac_minus) |