[PATCH net-next v2 2/2] net: dsa: mxl-gsw1xx: Support R(G)MII slew rate configuration

A. Sverdlin posted 2 patches 1 day, 12 hours ago
[PATCH net-next v2 2/2] net: dsa: mxl-gsw1xx: Support R(G)MII slew rate configuration
Posted by A. Sverdlin 1 day, 12 hours ago
From: Alexander Sverdlin <alexander.sverdlin@siemens.com>

Support newly introduced maxlinear,mii-slew-rate-slow device tree property
to configure R(G)MII interface pins slew rate into "slow" mode. It might be
used to reduce the radiated emissions.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
---
Changelog:
v2:
- do not hijack gsw1xx_phylink_mac_select_pcs() for configuring the port,
  introduce struct gswip_hw_info::port_setup callback
- actively configure "normal" slew rate (if the new DT property is missing)
- properly use regmap_set_bits() (v1 had reg and value mixed up)

 drivers/net/dsa/lantiq/lantiq_gswip.h        |  1 +
 drivers/net/dsa/lantiq/lantiq_gswip_common.c |  6 +++++
 drivers/net/dsa/lantiq/mxl-gsw1xx.c          | 26 ++++++++++++++++++++
 drivers/net/dsa/lantiq/mxl-gsw1xx.h          |  2 ++
 4 files changed, 35 insertions(+)

diff --git a/drivers/net/dsa/lantiq/lantiq_gswip.h b/drivers/net/dsa/lantiq/lantiq_gswip.h
index 9c38e51a75e80..3dc6c232a2e7b 100644
--- a/drivers/net/dsa/lantiq/lantiq_gswip.h
+++ b/drivers/net/dsa/lantiq/lantiq_gswip.h
@@ -263,6 +263,7 @@ struct gswip_hw_info {
 				 struct phylink_config *config);
 	struct phylink_pcs *(*mac_select_pcs)(struct phylink_config *config,
 					      phy_interface_t interface);
+	int (*port_setup)(struct dsa_switch *ds, int port);
 };
 
 struct gswip_gphy_fw {
diff --git a/drivers/net/dsa/lantiq/lantiq_gswip_common.c b/drivers/net/dsa/lantiq/lantiq_gswip_common.c
index 9da39edf8f574..efa7526609a41 100644
--- a/drivers/net/dsa/lantiq/lantiq_gswip_common.c
+++ b/drivers/net/dsa/lantiq/lantiq_gswip_common.c
@@ -425,6 +425,12 @@ static int gswip_port_setup(struct dsa_switch *ds, int port)
 	struct gswip_priv *priv = ds->priv;
 	int err;
 
+	if (priv->hw_info->port_setup) {
+		err = priv->hw_info->port_setup(ds, port);
+		if (err)
+			return err;
+	}
+
 	if (!dsa_is_cpu_port(ds, port)) {
 		err = gswip_add_single_port_br(priv, port, true);
 		if (err)
diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.c b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
index 0816c61a47f12..cf35d5a00b7c8 100644
--- a/drivers/net/dsa/lantiq/mxl-gsw1xx.c
+++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
@@ -531,6 +531,29 @@ static struct phylink_pcs *gsw1xx_phylink_mac_select_pcs(struct phylink_config *
 	}
 }
 
+static int gsw1xx_port_setup(struct dsa_switch *ds, int port)
+{
+	struct dsa_port *dp = dsa_to_port(ds, port);
+	struct gsw1xx_priv *gsw1xx_priv;
+	struct gswip_priv *gswip_priv;
+	int ret;
+
+	if (dp->index != GSW1XX_MII_PORT)
+		return 0;
+
+	gswip_priv = ds->priv;
+	gsw1xx_priv = container_of(gswip_priv, struct gsw1xx_priv, gswip);
+
+	if (of_property_read_bool(dp->dn, "maxlinear,mii-slew-rate-slow"))
+		ret = regmap_set_bits(gsw1xx_priv->shell, GSW1XX_SHELL_RGMII_SLEW_CFG,
+				      RGMII_SLEW_CFG_DRV_TXD | RGMII_SLEW_CFG_DRV_TXC);
+	else
+		ret = regmap_clear_bits(gsw1xx_priv->shell, GSW1XX_SHELL_RGMII_SLEW_CFG,
+					RGMII_SLEW_CFG_DRV_TXD | RGMII_SLEW_CFG_DRV_TXC);
+
+	return ret;
+}
+
 static struct regmap *gsw1xx_regmap_init(struct gsw1xx_priv *priv,
 					 const char *name,
 					 unsigned int reg_base,
@@ -674,6 +697,7 @@ static const struct gswip_hw_info gsw12x_data = {
 	.pce_microcode		= &gsw1xx_pce_microcode,
 	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
 	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
+	.port_setup		= gsw1xx_port_setup,
 };
 
 static const struct gswip_hw_info gsw140_data = {
@@ -687,6 +711,7 @@ static const struct gswip_hw_info gsw140_data = {
 	.pce_microcode		= &gsw1xx_pce_microcode,
 	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
 	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
+	.port_setup		= gsw1xx_port_setup,
 };
 
 static const struct gswip_hw_info gsw141_data = {
@@ -699,6 +724,7 @@ static const struct gswip_hw_info gsw141_data = {
 	.pce_microcode		= &gsw1xx_pce_microcode,
 	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
 	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
+	.port_setup		= gsw1xx_port_setup,
 };
 
 /*
diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.h b/drivers/net/dsa/lantiq/mxl-gsw1xx.h
index 38e03c048a26c..8c0298b2b7663 100644
--- a/drivers/net/dsa/lantiq/mxl-gsw1xx.h
+++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.h
@@ -110,6 +110,8 @@
 #define   GSW1XX_RST_REQ_SGMII_SHELL		BIT(5)
 /* RGMII PAD Slew Control Register */
 #define  GSW1XX_SHELL_RGMII_SLEW_CFG		0x78
+#define   RGMII_SLEW_CFG_DRV_TXC		BIT(2)
+#define   RGMII_SLEW_CFG_DRV_TXD		BIT(3)
 #define   RGMII_SLEW_CFG_RX_2_5_V		BIT(4)
 #define   RGMII_SLEW_CFG_TX_2_5_V		BIT(5)
 
-- 
2.52.0
Re: [PATCH net-next v2 2/2] net: dsa: mxl-gsw1xx: Support R(G)MII slew rate configuration
Posted by Daniel Golle 1 day, 11 hours ago
On Tue, Dec 16, 2025 at 01:17:01PM +0100, A. Sverdlin wrote:
> From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
> 
> Support newly introduced maxlinear,mii-slew-rate-slow device tree property
> to configure R(G)MII interface pins slew rate into "slow" mode. It might be
> used to reduce the radiated emissions.
> 
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>

Reviewed-by: Daniel Golle <daniel@makrotopia.org>

> ---
> Changelog:
> v2:
> - do not hijack gsw1xx_phylink_mac_select_pcs() for configuring the port,
>   introduce struct gswip_hw_info::port_setup callback
> - actively configure "normal" slew rate (if the new DT property is missing)
> - properly use regmap_set_bits() (v1 had reg and value mixed up)
> 
>  drivers/net/dsa/lantiq/lantiq_gswip.h        |  1 +
>  drivers/net/dsa/lantiq/lantiq_gswip_common.c |  6 +++++
>  drivers/net/dsa/lantiq/mxl-gsw1xx.c          | 26 ++++++++++++++++++++
>  drivers/net/dsa/lantiq/mxl-gsw1xx.h          |  2 ++
>  4 files changed, 35 insertions(+)
> 
> diff --git a/drivers/net/dsa/lantiq/lantiq_gswip.h b/drivers/net/dsa/lantiq/lantiq_gswip.h
> index 9c38e51a75e80..3dc6c232a2e7b 100644
> --- a/drivers/net/dsa/lantiq/lantiq_gswip.h
> +++ b/drivers/net/dsa/lantiq/lantiq_gswip.h
> @@ -263,6 +263,7 @@ struct gswip_hw_info {
>  				 struct phylink_config *config);
>  	struct phylink_pcs *(*mac_select_pcs)(struct phylink_config *config,
>  					      phy_interface_t interface);
> +	int (*port_setup)(struct dsa_switch *ds, int port);
>  };
>  
>  struct gswip_gphy_fw {
> diff --git a/drivers/net/dsa/lantiq/lantiq_gswip_common.c b/drivers/net/dsa/lantiq/lantiq_gswip_common.c
> index 9da39edf8f574..efa7526609a41 100644
> --- a/drivers/net/dsa/lantiq/lantiq_gswip_common.c
> +++ b/drivers/net/dsa/lantiq/lantiq_gswip_common.c
> @@ -425,6 +425,12 @@ static int gswip_port_setup(struct dsa_switch *ds, int port)
>  	struct gswip_priv *priv = ds->priv;
>  	int err;
>  
> +	if (priv->hw_info->port_setup) {
> +		err = priv->hw_info->port_setup(ds, port);
> +		if (err)
> +			return err;
> +	}
> +
>  	if (!dsa_is_cpu_port(ds, port)) {
>  		err = gswip_add_single_port_br(priv, port, true);
>  		if (err)
> diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.c b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
> index 0816c61a47f12..cf35d5a00b7c8 100644
> --- a/drivers/net/dsa/lantiq/mxl-gsw1xx.c
> +++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
> @@ -531,6 +531,29 @@ static struct phylink_pcs *gsw1xx_phylink_mac_select_pcs(struct phylink_config *
>  	}
>  }
>  
> +static int gsw1xx_port_setup(struct dsa_switch *ds, int port)
> +{
> +	struct dsa_port *dp = dsa_to_port(ds, port);
> +	struct gsw1xx_priv *gsw1xx_priv;
> +	struct gswip_priv *gswip_priv;
> +	int ret;
> +
> +	if (dp->index != GSW1XX_MII_PORT)
> +		return 0;
> +
> +	gswip_priv = ds->priv;
> +	gsw1xx_priv = container_of(gswip_priv, struct gsw1xx_priv, gswip);
> +
> +	if (of_property_read_bool(dp->dn, "maxlinear,mii-slew-rate-slow"))
> +		ret = regmap_set_bits(gsw1xx_priv->shell, GSW1XX_SHELL_RGMII_SLEW_CFG,
> +				      RGMII_SLEW_CFG_DRV_TXD | RGMII_SLEW_CFG_DRV_TXC);
> +	else
> +		ret = regmap_clear_bits(gsw1xx_priv->shell, GSW1XX_SHELL_RGMII_SLEW_CFG,
> +					RGMII_SLEW_CFG_DRV_TXD | RGMII_SLEW_CFG_DRV_TXC);
> +
> +	return ret;
> +}
> +
>  static struct regmap *gsw1xx_regmap_init(struct gsw1xx_priv *priv,
>  					 const char *name,
>  					 unsigned int reg_base,
> @@ -674,6 +697,7 @@ static const struct gswip_hw_info gsw12x_data = {
>  	.pce_microcode		= &gsw1xx_pce_microcode,
>  	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
>  	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
> +	.port_setup		= gsw1xx_port_setup,

Nit: I'd place this before .pce_microcode, but as neither the
struct definition nor the individual instances follow any sorted
order at this moment (which could clearly be improved, mea culpa)
it's also ok like this and not worth an other round of submitting
the series imho.

>  };
>  
>  static const struct gswip_hw_info gsw140_data = {
> @@ -687,6 +711,7 @@ static const struct gswip_hw_info gsw140_data = {
>  	.pce_microcode		= &gsw1xx_pce_microcode,
>  	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
>  	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
> +	.port_setup		= gsw1xx_port_setup,
>  };
>  
>  static const struct gswip_hw_info gsw141_data = {
> @@ -699,6 +724,7 @@ static const struct gswip_hw_info gsw141_data = {
>  	.pce_microcode		= &gsw1xx_pce_microcode,
>  	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
>  	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
> +	.port_setup		= gsw1xx_port_setup,
>  };
>  
>  /*
> diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.h b/drivers/net/dsa/lantiq/mxl-gsw1xx.h
> index 38e03c048a26c..8c0298b2b7663 100644
> --- a/drivers/net/dsa/lantiq/mxl-gsw1xx.h
> +++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.h
> @@ -110,6 +110,8 @@
>  #define   GSW1XX_RST_REQ_SGMII_SHELL		BIT(5)
>  /* RGMII PAD Slew Control Register */
>  #define  GSW1XX_SHELL_RGMII_SLEW_CFG		0x78
> +#define   RGMII_SLEW_CFG_DRV_TXC		BIT(2)
> +#define   RGMII_SLEW_CFG_DRV_TXD		BIT(3)
>  #define   RGMII_SLEW_CFG_RX_2_5_V		BIT(4)
>  #define   RGMII_SLEW_CFG_TX_2_5_V		BIT(5)
>  
> -- 
> 2.52.0
>