From: Alexander Sverdlin Date: Wed, 14 Jan 2026 10:45:04 +0000 (+0100) Subject: net: dsa: mxl-gsw1xx: Support R(G)MII slew rate configuration X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dbf24ab58fec34e168e331a0a2065ce7805fb3f4;p=thirdparty%2Fkernel%2Flinux.git net: dsa: mxl-gsw1xx: Support R(G)MII slew rate configuration Support newly introduced maxlinear,slew-rate-txc and maxlinear,slew-rate-txd device tree properties to configure R(G)MII interface pins' slew rate. It might be used to reduce the radiated emissions. Reviewed-by: Daniel Golle Tested-by: Daniel Golle Signed-off-by: Alexander Sverdlin Reviewed-by: Andrew Lunn Reviewed-by: Vladimir Oltean Link: https://patch.msgid.link/20260114104509.618984-3-alexander.sverdlin@siemens.com Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/dsa/lantiq/lantiq_gswip.h b/drivers/net/dsa/lantiq/lantiq_gswip.h index 2e0f2afbadbbc..8fc4c7cc5283a 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 e790f2ef75884..17a61e445f00f 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 f8ff8a604bf53..6afc7539fefbe 100644 --- a/drivers/net/dsa/lantiq/mxl-gsw1xx.c +++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.c @@ -559,6 +559,43 @@ static struct phylink_pcs *gsw1xx_phylink_mac_select_pcs(struct phylink_config * } } +static int gsw1xx_rmii_slew_rate(const struct device_node *np, struct gsw1xx_priv *priv, + const char *prop, u16 mask) +{ + u32 rate; + int ret; + + ret = of_property_read_u32(np, prop, &rate); + /* Optional property */ + if (ret == -EINVAL) + return 0; + if (ret < 0 || rate > 1) { + dev_err(&priv->mdio_dev->dev, "Invalid %s value\n", prop); + return (ret < 0) ? ret : -EINVAL; + } + + return regmap_update_bits(priv->shell, GSW1XX_SHELL_RGMII_SLEW_CFG, mask, mask * rate); +} + +static int gsw1xx_port_setup(struct dsa_switch *ds, int port) +{ + struct dsa_port *dp = dsa_to_port(ds, port); + struct device_node *np = dp->dn; + struct gsw1xx_priv *gsw1xx_priv; + struct gswip_priv *gswip_priv; + + if (dp->index != GSW1XX_MII_PORT) + return 0; + + gswip_priv = ds->priv; + gsw1xx_priv = container_of(gswip_priv, struct gsw1xx_priv, gswip); + + return gsw1xx_rmii_slew_rate(np, gsw1xx_priv, + "maxlinear,slew-rate-txc", RGMII_SLEW_CFG_DRV_TXC) ?: + gsw1xx_rmii_slew_rate(np, gsw1xx_priv, + "maxlinear,slew-rate-txd", RGMII_SLEW_CFG_DRV_TXD); +} + static struct regmap *gsw1xx_regmap_init(struct gsw1xx_priv *priv, const char *name, unsigned int reg_base, @@ -707,6 +744,7 @@ static const struct gswip_hw_info gsw12x_data = { .mac_select_pcs = gsw1xx_phylink_mac_select_pcs, .phylink_get_caps = &gsw1xx_phylink_get_caps, .supports_2500m = true, + .port_setup = gsw1xx_port_setup, .pce_microcode = &gsw1xx_pce_microcode, .pce_microcode_size = ARRAY_SIZE(gsw1xx_pce_microcode), .tag_protocol = DSA_TAG_PROTO_MXL_GSW1XX, @@ -720,6 +758,7 @@ static const struct gswip_hw_info gsw140_data = { .mac_select_pcs = gsw1xx_phylink_mac_select_pcs, .phylink_get_caps = &gsw1xx_phylink_get_caps, .supports_2500m = true, + .port_setup = gsw1xx_port_setup, .pce_microcode = &gsw1xx_pce_microcode, .pce_microcode_size = ARRAY_SIZE(gsw1xx_pce_microcode), .tag_protocol = DSA_TAG_PROTO_MXL_GSW1XX, @@ -732,6 +771,7 @@ static const struct gswip_hw_info gsw141_data = { .mii_port_reg_offset = -GSW1XX_MII_PORT, .mac_select_pcs = gsw1xx_phylink_mac_select_pcs, .phylink_get_caps = gsw1xx_phylink_get_caps, + .port_setup = gsw1xx_port_setup, .pce_microcode = &gsw1xx_pce_microcode, .pce_microcode_size = ARRAY_SIZE(gsw1xx_pce_microcode), .tag_protocol = DSA_TAG_PROTO_MXL_GSW1XX, 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)