Merge branch 'dsa-mxl-gsw1xx-support-r-g-mii-slew-rate-configuration'

Alexander Sverdlin says:

====================
dsa: mxl-gsw1xx: Support R(G)MII slew rate configuration

Maxlinear GSW1xx switches offer slew rate configuration bits for R(G)MII
interface. The default state of the configuration bits is "normal", while
"slow" can be used to reduce the radiated emissions. Add the support for
the latter option into the driver as well as the new DT bindings.
====================

Link: https://patch.msgid.link/20260114104509.618984-1-alexander.sverdlin@siemens.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-01-19 10:08:28 -08:00
commit 2f52f835b4
5 changed files with 71 additions and 0 deletions

View File

@ -106,6 +106,28 @@ patternProperties:
unevaluatedProperties: false
properties:
maxlinear,slew-rate-txc:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1]
description: |
RMII/RGMII TX Clock Slew Rate:
0: Normal
1: Slow
If not present, the configuration made by the switch bootloader is
preserved.
maxlinear,slew-rate-txd:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1]
description: |
RMII/RGMII TX Non-Clock PAD Slew Rate:
0: Normal
1: Slow
If not present, the configuration made by the switch bootloader is
preserved.
maxlinear,rmii-refclk-out:
type: boolean
description:

View File

@ -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 {

View File

@ -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)

View File

@ -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,

View File

@ -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)