net: phy: dp83822: Add support for changing the transmit amplitude voltage

Add support for changing the transmit amplitude voltage in 100BASE-TX mode.
Modifying it can be necessary to compensate losses on the PCB and
connector, so the voltages measured on the RJ45 pins are conforming.

Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20250214-dp83822-tx-swing-v5-3-02ca72620599@liebherr.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Dimitri Fedrau 2025-02-14 15:14:11 +01:00 committed by Jakub Kicinski
parent 961ee5aeea
commit 4f3735e82d

View File

@ -31,6 +31,7 @@
#define MII_DP83822_RCSR 0x17
#define MII_DP83822_RESET_CTRL 0x1f
#define MII_DP83822_MLEDCR 0x25
#define MII_DP83822_LDCTRL 0x403
#define MII_DP83822_LEDCFG1 0x460
#define MII_DP83822_IOCTRL1 0x462
#define MII_DP83822_IOCTRL2 0x463
@ -123,6 +124,9 @@
#define DP83822_IOCTRL1_GPIO1_CTRL GENMASK(2, 0)
#define DP83822_IOCTRL1_GPIO1_CTRL_LED_1 BIT(0)
/* LDCTRL bits */
#define DP83822_100BASE_TX_LINE_DRIVER_SWING GENMASK(7, 4)
/* IOCTRL2 bits */
#define DP83822_IOCTRL2_GPIO2_CLK_SRC GENMASK(6, 4)
#define DP83822_IOCTRL2_GPIO2_CTRL GENMASK(2, 0)
@ -197,6 +201,7 @@ struct dp83822_private {
bool set_gpio2_clk_out;
u32 gpio2_clk_out;
bool led_pin_enable[DP83822_MAX_LED_PINS];
int tx_amplitude_100base_tx_index;
};
static int dp83822_config_wol(struct phy_device *phydev,
@ -522,6 +527,12 @@ static int dp83822_config_init(struct phy_device *phydev)
FIELD_PREP(DP83822_IOCTRL2_GPIO2_CLK_SRC,
dp83822->gpio2_clk_out));
if (dp83822->tx_amplitude_100base_tx_index >= 0)
phy_modify_mmd(phydev, MDIO_MMD_VEND2, MII_DP83822_LDCTRL,
DP83822_100BASE_TX_LINE_DRIVER_SWING,
FIELD_PREP(DP83822_100BASE_TX_LINE_DRIVER_SWING,
dp83822->tx_amplitude_100base_tx_index));
err = dp83822_config_init_leds(phydev);
if (err)
return err;
@ -720,6 +731,11 @@ static int dp83822_phy_reset(struct phy_device *phydev)
}
#ifdef CONFIG_OF_MDIO
static const u32 tx_amplitude_100base_tx_gain[] = {
80, 82, 83, 85, 87, 88, 90, 92,
93, 95, 97, 98, 100, 102, 103, 105,
};
static int dp83822_of_init_leds(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;
@ -780,6 +796,8 @@ static int dp83822_of_init(struct phy_device *phydev)
struct dp83822_private *dp83822 = phydev->priv;
struct device *dev = &phydev->mdio.dev;
const char *of_val;
int i, ret;
u32 val;
/* Signal detection for the PHY is only enabled if the FX_EN and the
* SD_EN pins are strapped. Signal detection can only enabled if FX_EN
@ -815,6 +833,26 @@ static int dp83822_of_init(struct phy_device *phydev)
dp83822->set_gpio2_clk_out = true;
}
dp83822->tx_amplitude_100base_tx_index = -1;
ret = phy_get_tx_amplitude_gain(phydev, dev,
ETHTOOL_LINK_MODE_100baseT_Full_BIT,
&val);
if (!ret) {
for (i = 0; i < ARRAY_SIZE(tx_amplitude_100base_tx_gain); i++) {
if (tx_amplitude_100base_tx_gain[i] == val) {
dp83822->tx_amplitude_100base_tx_index = i;
break;
}
}
if (dp83822->tx_amplitude_100base_tx_index < 0) {
phydev_err(phydev,
"Invalid value for tx-amplitude-100base-tx-percent property (%u)\n",
val);
return -EINVAL;
}
}
return dp83822_of_init_leds(phydev);
}