linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v5] net: phy: intel-xway: Add RGMII internal delay configuration
@ 2021-07-12  7:24 Martin Schiller
  2021-07-12  9:54 ` Hauke Mehrtens
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Martin Schiller @ 2021-07-12  7:24 UTC (permalink / raw)
  To: hauke, martin.blumenstingl, f.fainelli, andrew, hkallweit1,
	linux, davem, kuba
  Cc: netdev, linux-kernel, Martin Schiller

This adds the possibility to configure the RGMII RX/TX clock skew via
devicetree.

Simply set phy mode to "rgmii-id", "rgmii-rxid" or "rgmii-txid" and add
the "rx-internal-delay-ps" or "tx-internal-delay-ps" property to the
devicetree.

Furthermore, a warning is now issued if the phy mode is configured to
"rgmii" and an internal delay is set in the phy (e.g. by pin-strapping),
as in the dp83867 driver.

Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---

Changes to v4:
o Fix Alignment to match open parenthesis

Changes to v3:
o Fix typo in commit message
o use FIELD_PREP() and FIELD_GET() macros
o further code cleanups
o always mask rxskew AND txskew value in the register value

Changes to v2:
o Fix missing whitespace in warning.

Changes to v1:
o code cleanup and use phy_modify().
o use default of 2.0ns if delay property is absent instead of returning
  an error.

---
 drivers/net/phy/intel-xway.c | 85 ++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/drivers/net/phy/intel-xway.c b/drivers/net/phy/intel-xway.c
index d453ec016168..bc7e2fdb8ea7 100644
--- a/drivers/net/phy/intel-xway.c
+++ b/drivers/net/phy/intel-xway.c
@@ -8,11 +8,16 @@
 #include <linux/module.h>
 #include <linux/phy.h>
 #include <linux/of.h>
+#include <linux/bitfield.h>
 
+#define XWAY_MDIO_MIICTRL		0x17	/* mii control */
 #define XWAY_MDIO_IMASK			0x19	/* interrupt mask */
 #define XWAY_MDIO_ISTAT			0x1A	/* interrupt status */
 #define XWAY_MDIO_LED			0x1B	/* led control */
 
+#define XWAY_MDIO_MIICTRL_RXSKEW_MASK	GENMASK(14, 12)
+#define XWAY_MDIO_MIICTRL_TXSKEW_MASK	GENMASK(10, 8)
+
 /* bit 15:12 are reserved */
 #define XWAY_MDIO_LED_LED3_EN		BIT(11)	/* Enable the integrated function of LED3 */
 #define XWAY_MDIO_LED_LED2_EN		BIT(10)	/* Enable the integrated function of LED2 */
@@ -157,6 +162,82 @@
 #define PHY_ID_PHY11G_VR9_1_2		0xD565A409
 #define PHY_ID_PHY22F_VR9_1_2		0xD565A419
 
+#if IS_ENABLED(CONFIG_OF_MDIO)
+static const int xway_internal_delay[] = {0, 500, 1000, 1500, 2000, 2500,
+					 3000, 3500};
+
+static int xway_gphy_of_reg_init(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	unsigned int delay_size = ARRAY_SIZE(xway_internal_delay);
+	s32 int_delay;
+	int val = 0;
+
+	if (!phy_interface_is_rgmii(phydev))
+		return 0;
+
+	/* Existing behavior was to use default pin strapping delay in rgmii
+	 * mode, but rgmii should have meant no delay.  Warn existing users,
+	 * but do not change anything at the moment.
+	 */
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
+		u16 txskew, rxskew;
+
+		val = phy_read(phydev, XWAY_MDIO_MIICTRL);
+		if (val < 0)
+			return val;
+
+		txskew = FIELD_GET(XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
+		rxskew = FIELD_GET(XWAY_MDIO_MIICTRL_RXSKEW_MASK, val);
+
+		if (txskew > 0 || rxskew > 0)
+			phydev_warn(phydev,
+				    "PHY has delays (e.g. via pin strapping), but phy-mode = 'rgmii'\n"
+				    "Should be 'rgmii-id' to use internal delays txskew:%d ps rxskew:%d ps\n",
+				    xway_internal_delay[txskew],
+				    xway_internal_delay[rxskew]);
+		return 0;
+	}
+
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
+		int_delay = phy_get_internal_delay(phydev, dev,
+						   xway_internal_delay,
+						   delay_size, true);
+
+		if (int_delay < 0) {
+			phydev_warn(phydev, "rx-internal-delay-ps is missing, use default of 2.0 ns\n");
+			int_delay = 4; /* 2000 ps */
+		}
+
+		val |= FIELD_PREP(XWAY_MDIO_MIICTRL_RXSKEW_MASK, int_delay);
+	}
+
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+		int_delay = phy_get_internal_delay(phydev, dev,
+						   xway_internal_delay,
+						   delay_size, false);
+
+		if (int_delay < 0) {
+			phydev_warn(phydev, "tx-internal-delay-ps is missing, use default of 2.0 ns\n");
+			int_delay = 4; /* 2000 ps */
+		}
+
+		val |= FIELD_PREP(XWAY_MDIO_MIICTRL_TXSKEW_MASK, int_delay);
+	}
+
+	return phy_modify(phydev, XWAY_MDIO_MIICTRL,
+			  XWAY_MDIO_MIICTRL_RXSKEW_MASK |
+			  XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
+}
+#else
+static int xway_gphy_of_reg_init(struct phy_device *phydev)
+{
+	return 0;
+}
+#endif /* CONFIG_OF_MDIO */
+
 static int xway_gphy_config_init(struct phy_device *phydev)
 {
 	int err;
@@ -204,6 +285,10 @@ static int xway_gphy_config_init(struct phy_device *phydev)
 	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh);
 	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl);
 
+	err = xway_gphy_of_reg_init(phydev);
+	if (err)
+		return err;
+
 	return 0;
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next v5] net: phy: intel-xway: Add RGMII internal delay configuration
  2021-07-12  7:24 [PATCH net-next v5] net: phy: intel-xway: Add RGMII internal delay configuration Martin Schiller
@ 2021-07-12  9:54 ` Hauke Mehrtens
  2021-07-12 11:12 ` Martin Blumenstingl
  2021-07-12 11:22 ` Russell King (Oracle)
  2 siblings, 0 replies; 4+ messages in thread
From: Hauke Mehrtens @ 2021-07-12  9:54 UTC (permalink / raw)
  To: Martin Schiller, martin.blumenstingl, f.fainelli, andrew,
	hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel

On 7/12/21 9:24 AM, Martin Schiller wrote:
> This adds the possibility to configure the RGMII RX/TX clock skew via
> devicetree.
> 
> Simply set phy mode to "rgmii-id", "rgmii-rxid" or "rgmii-txid" and add
> the "rx-internal-delay-ps" or "tx-internal-delay-ps" property to the
> devicetree.
> 
> Furthermore, a warning is now issued if the phy mode is configured to
> "rgmii" and an internal delay is set in the phy (e.g. by pin-strapping),
> as in the dp83867 driver.
> 
> Signed-off-by: Martin Schiller <ms@dev.tdt.de>

Acked-by: Hauke Mehrtens <hauke@hauke-m.de>

> ---
> 
> Changes to v4:
> o Fix Alignment to match open parenthesis
> 
> Changes to v3:
> o Fix typo in commit message
> o use FIELD_PREP() and FIELD_GET() macros
> o further code cleanups
> o always mask rxskew AND txskew value in the register value
> 
> Changes to v2:
> o Fix missing whitespace in warning.
> 
> Changes to v1:
> o code cleanup and use phy_modify().
> o use default of 2.0ns if delay property is absent instead of returning
>    an error.
> 
> ---
>   drivers/net/phy/intel-xway.c | 85 ++++++++++++++++++++++++++++++++++++
>   1 file changed, 85 insertions(+)
> 
> diff --git a/drivers/net/phy/intel-xway.c b/drivers/net/phy/intel-xway.c
> index d453ec016168..bc7e2fdb8ea7 100644
> --- a/drivers/net/phy/intel-xway.c
> +++ b/drivers/net/phy/intel-xway.c
> @@ -8,11 +8,16 @@
>   #include <linux/module.h>
>   #include <linux/phy.h>
>   #include <linux/of.h>
> +#include <linux/bitfield.h>
>   
> +#define XWAY_MDIO_MIICTRL		0x17	/* mii control */
>   #define XWAY_MDIO_IMASK			0x19	/* interrupt mask */
>   #define XWAY_MDIO_ISTAT			0x1A	/* interrupt status */
>   #define XWAY_MDIO_LED			0x1B	/* led control */
>   
> +#define XWAY_MDIO_MIICTRL_RXSKEW_MASK	GENMASK(14, 12)
> +#define XWAY_MDIO_MIICTRL_TXSKEW_MASK	GENMASK(10, 8)
> +
>   /* bit 15:12 are reserved */
>   #define XWAY_MDIO_LED_LED3_EN		BIT(11)	/* Enable the integrated function of LED3 */
>   #define XWAY_MDIO_LED_LED2_EN		BIT(10)	/* Enable the integrated function of LED2 */
> @@ -157,6 +162,82 @@
>   #define PHY_ID_PHY11G_VR9_1_2		0xD565A409
>   #define PHY_ID_PHY22F_VR9_1_2		0xD565A419
>   
> +#if IS_ENABLED(CONFIG_OF_MDIO)
> +static const int xway_internal_delay[] = {0, 500, 1000, 1500, 2000, 2500,
> +					 3000, 3500};
> +
> +static int xway_gphy_of_reg_init(struct phy_device *phydev)
> +{
> +	struct device *dev = &phydev->mdio.dev;
> +	unsigned int delay_size = ARRAY_SIZE(xway_internal_delay);
> +	s32 int_delay;
> +	int val = 0;
> +
> +	if (!phy_interface_is_rgmii(phydev))
> +		return 0;
> +
> +	/* Existing behavior was to use default pin strapping delay in rgmii
> +	 * mode, but rgmii should have meant no delay.  Warn existing users,
> +	 * but do not change anything at the moment.
> +	 */
> +	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
> +		u16 txskew, rxskew;
> +
> +		val = phy_read(phydev, XWAY_MDIO_MIICTRL);
> +		if (val < 0)
> +			return val;
> +
> +		txskew = FIELD_GET(XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
> +		rxskew = FIELD_GET(XWAY_MDIO_MIICTRL_RXSKEW_MASK, val);
> +
> +		if (txskew > 0 || rxskew > 0)
> +			phydev_warn(phydev,
> +				    "PHY has delays (e.g. via pin strapping), but phy-mode = 'rgmii'\n"
> +				    "Should be 'rgmii-id' to use internal delays txskew:%d ps rxskew:%d ps\n",
> +				    xway_internal_delay[txskew],
> +				    xway_internal_delay[rxskew]);
> +		return 0;
> +	}
> +
> +	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> +	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
> +		int_delay = phy_get_internal_delay(phydev, dev,
> +						   xway_internal_delay,
> +						   delay_size, true);
> +
> +		if (int_delay < 0) {
> +			phydev_warn(phydev, "rx-internal-delay-ps is missing, use default of 2.0 ns\n");
> +			int_delay = 4; /* 2000 ps */
> +		}
> +
> +		val |= FIELD_PREP(XWAY_MDIO_MIICTRL_RXSKEW_MASK, int_delay);
> +	}
> +
> +	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> +	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
> +		int_delay = phy_get_internal_delay(phydev, dev,
> +						   xway_internal_delay,
> +						   delay_size, false);
> +
> +		if (int_delay < 0) {
> +			phydev_warn(phydev, "tx-internal-delay-ps is missing, use default of 2.0 ns\n");
> +			int_delay = 4; /* 2000 ps */
> +		}
> +
> +		val |= FIELD_PREP(XWAY_MDIO_MIICTRL_TXSKEW_MASK, int_delay);
> +	}
> +
> +	return phy_modify(phydev, XWAY_MDIO_MIICTRL,
> +			  XWAY_MDIO_MIICTRL_RXSKEW_MASK |
> +			  XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
> +}
> +#else
> +static int xway_gphy_of_reg_init(struct phy_device *phydev)
> +{
> +	return 0;
> +}
> +#endif /* CONFIG_OF_MDIO */
> +
>   static int xway_gphy_config_init(struct phy_device *phydev)
>   {
>   	int err;
> @@ -204,6 +285,10 @@ static int xway_gphy_config_init(struct phy_device *phydev)
>   	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh);
>   	phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl);
>   
> +	err = xway_gphy_of_reg_init(phydev);
> +	if (err)
> +		return err;
> +
>   	return 0;
>   }
>   
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next v5] net: phy: intel-xway: Add RGMII internal delay configuration
  2021-07-12  7:24 [PATCH net-next v5] net: phy: intel-xway: Add RGMII internal delay configuration Martin Schiller
  2021-07-12  9:54 ` Hauke Mehrtens
@ 2021-07-12 11:12 ` Martin Blumenstingl
  2021-07-12 11:22 ` Russell King (Oracle)
  2 siblings, 0 replies; 4+ messages in thread
From: Martin Blumenstingl @ 2021-07-12 11:12 UTC (permalink / raw)
  To: Martin Schiller
  Cc: Hauke Mehrtens, f.fainelli, andrew, hkallweit1, linux, davem,
	kuba, netdev, linux-kernel

On Mon, Jul 12, 2021 at 9:24 AM Martin Schiller <ms@dev.tdt.de> wrote:
>
> This adds the possibility to configure the RGMII RX/TX clock skew via
> devicetree.
>
> Simply set phy mode to "rgmii-id", "rgmii-rxid" or "rgmii-txid" and add
> the "rx-internal-delay-ps" or "tx-internal-delay-ps" property to the
> devicetree.
>
> Furthermore, a warning is now issued if the phy mode is configured to
> "rgmii" and an internal delay is set in the phy (e.g. by pin-strapping),
> as in the dp83867 driver.
>
> Signed-off-by: Martin Schiller <ms@dev.tdt.de>
Thanks for this updated version!
Everything's looking good so:
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next v5] net: phy: intel-xway: Add RGMII internal delay configuration
  2021-07-12  7:24 [PATCH net-next v5] net: phy: intel-xway: Add RGMII internal delay configuration Martin Schiller
  2021-07-12  9:54 ` Hauke Mehrtens
  2021-07-12 11:12 ` Martin Blumenstingl
@ 2021-07-12 11:22 ` Russell King (Oracle)
  2 siblings, 0 replies; 4+ messages in thread
From: Russell King (Oracle) @ 2021-07-12 11:22 UTC (permalink / raw)
  To: Martin Schiller
  Cc: hauke, martin.blumenstingl, f.fainelli, andrew, hkallweit1,
	davem, kuba, netdev, linux-kernel

On Mon, Jul 12, 2021 at 09:24:13AM +0200, Martin Schiller wrote:
> This adds the possibility to configure the RGMII RX/TX clock skew via
> devicetree.
> 
> Simply set phy mode to "rgmii-id", "rgmii-rxid" or "rgmii-txid" and add
> the "rx-internal-delay-ps" or "tx-internal-delay-ps" property to the
> devicetree.
> 
> Furthermore, a warning is now issued if the phy mode is configured to
> "rgmii" and an internal delay is set in the phy (e.g. by pin-strapping),
> as in the dp83867 driver.
> 
> Signed-off-by: Martin Schiller <ms@dev.tdt.de>

Acked-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Thanks.
-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-07-12 11:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-12  7:24 [PATCH net-next v5] net: phy: intel-xway: Add RGMII internal delay configuration Martin Schiller
2021-07-12  9:54 ` Hauke Mehrtens
2021-07-12 11:12 ` Martin Blumenstingl
2021-07-12 11:22 ` Russell King (Oracle)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).