From nobody Tue Feb 10 06:27:55 2026 Received: from mta-64-225.siemens.flowmailer.net (mta-64-225.siemens.flowmailer.net [185.136.64.225]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC322393DC2 for ; Wed, 14 Jan 2026 10:46:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.136.64.225 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768387576; cv=none; b=KOQeAxkNkIMvfYUH9iZZmA15ERRYnud0aVPkmmZVN5tHbjLaiJGsw2wPquw3XsF3N5Ictg8n+KPmVdlrLGJIR35yhKzlqbRtTvWwJ5ofURTvfvLwMu7Fo/4Fr9NKxL3q/ft4gOjfzvMdsEK/gFo9HfLkXCSwnx1AO/XMF6wqwFk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768387576; c=relaxed/simple; bh=vsY4t7iAts2jcnxV0WlUarWK8oCzNJWy2N9i6xt4aQU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ad1l8jAvE7dMUfjMU03MFBVZVSQG7Qfjum6ficQ/PLwFZXefcY86M5pQk/OCAmBMujtJipDtQADv2qfRY4phn3O96R2QyseG6Fof4PLkNaXOAqOGVqNVhoX+28tq4bVwroyMZ/EPMlkm3apqMRZPGJBkJJrSUuv6xk/0Y5h1PW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=siemens.com; spf=pass smtp.mailfrom=rts-flowmailer.siemens.com; dkim=pass (2048-bit key) header.d=siemens.com header.i=alexander.sverdlin@siemens.com header.b=JZA/od7k; arc=none smtp.client-ip=185.136.64.225 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=siemens.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rts-flowmailer.siemens.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=siemens.com header.i=alexander.sverdlin@siemens.com header.b="JZA/od7k" Received: by mta-64-225.siemens.flowmailer.net with ESMTPSA id 202601141046044e33d6a04500020722 for ; Wed, 14 Jan 2026 11:46:04 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=alexander.sverdlin@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=8bqFlPeW8UEYO5QEsPzlMr7wox/ozy0QqtSh3S128C8=; b=JZA/od7kt1ur1J7+WEbJHCWCMPCE2vWJjQcSVaLPaCH9cDDOtzPss29jl/2jWRPAGoO/qQ hmi1toCef6bMTHs4yInljX1AG2pIeZfgW+RZdoi6waadOlceyeSmLAxi3k3dLc8wZuvoQPsa i2SJNKgyUM7Uhd/LDq0rikgsmyn0e/vrkfeFQ2jtoq4azkRa8wb+VAF61pUnRu+fiWLrZp1D lU0YekrauPx9YBkACaP6GrxE/TOiZchkI3JRMvmsG6HUyPHyDx6zcHzCLxUtTAkLrXZJnCQp NEYzRjuXkFVyndd/09j2cVAZ3WnEQ79WN1LhvBHRvOdayUp1q5fmy+hA==; From: "A. Sverdlin" To: netdev@vger.kernel.org Cc: Alexander Sverdlin , Hauke Mehrtens , Andrew Lunn , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Daniel Golle Subject: [PATCH net-next v5 2/2] net: dsa: mxl-gsw1xx: Support R(G)MII slew rate configuration Date: Wed, 14 Jan 2026 11:45:04 +0100 Message-ID: <20260114104509.618984-3-alexander.sverdlin@siemens.com> In-Reply-To: <20260114104509.618984-1-alexander.sverdlin@siemens.com> References: <20260114104509.618984-1-alexander.sverdlin@siemens.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-456497:519-21489:flowmailer Content-Type: text/plain; charset="utf-8" From: Alexander Sverdlin 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 --- Changelog: v5: - unchanged v4: - separate properties for TXD and TXC pads v3: - use [pinctrl] standard "slew-rate" property as suggested by Rob https://lore.kernel.org/all/20251219204324.GA3881969-robh@kernel.org/ - better sorted struct gswip_hw_info initialisers as suggested by Daniel 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 | 40 ++++++++++++++++++++ drivers/net/dsa/lantiq/mxl-gsw1xx.h | 2 + 4 files changed, 49 insertions(+) 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); }; =20 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 =3D ds->priv; int err; =20 + if (priv->hw_info->port_setup) { + err =3D priv->hw_info->port_setup(ds, port); + if (err) + return err; + } + if (!dsa_is_cpu_port(ds, port)) { err =3D 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/m= xl-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_p= cs(struct phylink_config * } } =20 +static int gsw1xx_rmii_slew_rate(const struct device_node *np, struct gsw1= xx_priv *priv, + const char *prop, u16 mask) +{ + u32 rate; + int ret; + + ret =3D of_property_read_u32(np, prop, &rate); + /* Optional property */ + if (ret =3D=3D -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 =3D dsa_to_port(ds, port); + struct device_node *np =3D dp->dn; + struct gsw1xx_priv *gsw1xx_priv; + struct gswip_priv *gswip_priv; + + if (dp->index !=3D GSW1XX_MII_PORT) + return 0; + + gswip_priv =3D ds->priv; + gsw1xx_priv =3D 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 =3D { .mac_select_pcs =3D gsw1xx_phylink_mac_select_pcs, .phylink_get_caps =3D &gsw1xx_phylink_get_caps, .supports_2500m =3D true, + .port_setup =3D gsw1xx_port_setup, .pce_microcode =3D &gsw1xx_pce_microcode, .pce_microcode_size =3D ARRAY_SIZE(gsw1xx_pce_microcode), .tag_protocol =3D DSA_TAG_PROTO_MXL_GSW1XX, @@ -720,6 +758,7 @@ static const struct gswip_hw_info gsw140_data =3D { .mac_select_pcs =3D gsw1xx_phylink_mac_select_pcs, .phylink_get_caps =3D &gsw1xx_phylink_get_caps, .supports_2500m =3D true, + .port_setup =3D gsw1xx_port_setup, .pce_microcode =3D &gsw1xx_pce_microcode, .pce_microcode_size =3D ARRAY_SIZE(gsw1xx_pce_microcode), .tag_protocol =3D DSA_TAG_PROTO_MXL_GSW1XX, @@ -732,6 +771,7 @@ static const struct gswip_hw_info gsw141_data =3D { .mii_port_reg_offset =3D -GSW1XX_MII_PORT, .mac_select_pcs =3D gsw1xx_phylink_mac_select_pcs, .phylink_get_caps =3D gsw1xx_phylink_get_caps, + .port_setup =3D gsw1xx_port_setup, .pce_microcode =3D &gsw1xx_pce_microcode, .pce_microcode_size =3D ARRAY_SIZE(gsw1xx_pce_microcode), .tag_protocol =3D DSA_TAG_PROTO_MXL_GSW1XX, diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.h b/drivers/net/dsa/lantiq/m= xl-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) =20 --=20 2.52.0