Merge branch 'net-phy-dp83822-add-support-for-changing-the-mac-series-termination'

Dimitri Fedrau says:

====================
net: phy: dp83822: Add support for changing the MAC series termination

The dp83822 provides the possibility to set the resistance value of the
the MAC series termination. Modifying the resistance to an appropriate
value can reduce signal reflections and therefore improve signal quality.

v2: https://lore.kernel.org/20250408-dp83822-mac-impedance-v2-0-fefeba4a9804@liebherr.com
v1: https://lore.kernel.org/20250307-dp83822-mac-impedance-v1-0-bdd85a759b45@liebherr.com
====================

Link: https://patch.msgid.link/20250416-dp83822-mac-impedance-v3-0-028ac426cddb@liebherr.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-04-22 17:50:01 -07:00
commit 044412d9b6
5 changed files with 65 additions and 0 deletions

View File

@ -238,6 +238,16 @@ properties:
peak-to-peak specified in ANSI X3.263. When omitted, the PHYs default
will be left as is.
mac-termination-ohms:
maximum: 200
description:
The xMII signals need series termination on the driver side to match both
the output driver impedance and the line characteristic impedance, to
prevent reflections and EMI problems. Select a resistance value which is
supported by the builtin resistors of the PHY, otherwise the resistors may
have to be placed on board. When omitted, the PHYs default will be left as
is.
leds:
type: object

View File

@ -122,6 +122,9 @@ properties:
- free-running
- recovered
mac-termination-ohms:
enum: [43, 44, 46, 48, 50, 53, 55, 58, 61, 65, 69, 73, 78, 84, 91, 99]
required:
- reg
@ -137,6 +140,7 @@ examples:
rx-internal-delay-ps = <1>;
tx-internal-delay-ps = <1>;
ti,gpio2-clk-out = "xi";
mac-termination-ohms = <43>;
};
};

View File

@ -33,6 +33,7 @@
#define MII_DP83822_MLEDCR 0x25
#define MII_DP83822_LDCTRL 0x403
#define MII_DP83822_LEDCFG1 0x460
#define MII_DP83822_IOCTRL 0x461
#define MII_DP83822_IOCTRL1 0x462
#define MII_DP83822_IOCTRL2 0x463
#define MII_DP83822_GENCFG 0x465
@ -118,6 +119,9 @@
#define DP83822_LEDCFG1_LED1_CTRL GENMASK(11, 8)
#define DP83822_LEDCFG1_LED3_CTRL GENMASK(7, 4)
/* IOCTRL bits */
#define DP83822_IOCTRL_MAC_IMPEDANCE_CTRL GENMASK(4, 1)
/* IOCTRL1 bits */
#define DP83822_IOCTRL1_GPIO3_CTRL GENMASK(10, 8)
#define DP83822_IOCTRL1_GPIO3_CTRL_LED3 BIT(0)
@ -202,6 +206,7 @@ struct dp83822_private {
u32 gpio2_clk_out;
bool led_pin_enable[DP83822_MAX_LED_PINS];
int tx_amplitude_100base_tx_index;
int mac_termination_index;
};
static int dp83822_config_wol(struct phy_device *phydev,
@ -533,6 +538,12 @@ static int dp83822_config_init(struct phy_device *phydev)
FIELD_PREP(DP83822_100BASE_TX_LINE_DRIVER_SWING,
dp83822->tx_amplitude_100base_tx_index));
if (dp83822->mac_termination_index >= 0)
phy_modify_mmd(phydev, MDIO_MMD_VEND2, MII_DP83822_IOCTRL,
DP83822_IOCTRL_MAC_IMPEDANCE_CTRL,
FIELD_PREP(DP83822_IOCTRL_MAC_IMPEDANCE_CTRL,
dp83822->mac_termination_index));
err = dp83822_config_init_leds(phydev);
if (err)
return err;
@ -736,6 +747,10 @@ static const u32 tx_amplitude_100base_tx_gain[] = {
93, 95, 97, 98, 100, 102, 103, 105,
};
static const u32 mac_termination[] = {
99, 91, 84, 78, 73, 69, 65, 61, 58, 55, 53, 50, 48, 46, 44, 43,
};
static int dp83822_of_init_leds(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;
@ -852,6 +867,23 @@ static int dp83822_of_init(struct phy_device *phydev)
}
}
ret = phy_get_mac_termination(phydev, dev, &val);
if (!ret) {
for (i = 0; i < ARRAY_SIZE(mac_termination); i++) {
if (mac_termination[i] == val) {
dp83822->mac_termination_index = i;
break;
}
}
if (dp83822->mac_termination_index < 0) {
phydev_err(phydev,
"Invalid value for mac-termination-ohms property (%u)\n",
val);
return -EINVAL;
}
}
return dp83822_of_init_leds(phydev);
}
@ -931,6 +963,7 @@ static int dp8382x_probe(struct phy_device *phydev)
return -ENOMEM;
dp83822->tx_amplitude_100base_tx_index = -1;
dp83822->mac_termination_index = -1;
phydev->priv = dp83822;
return 0;

View File

@ -2975,6 +2975,21 @@ int phy_get_tx_amplitude_gain(struct phy_device *phydev, struct device *dev,
}
EXPORT_SYMBOL_GPL(phy_get_tx_amplitude_gain);
/**
* phy_get_mac_termination - stores MAC termination in @val
* @phydev: phy_device struct
* @dev: pointer to the devices device struct
* @val: MAC termination
*
* Returns: 0 on success, < 0 on failure
*/
int phy_get_mac_termination(struct phy_device *phydev, struct device *dev,
u32 *val)
{
return phy_get_u32_property(dev, "mac-termination-ohms", val);
}
EXPORT_SYMBOL_GPL(phy_get_mac_termination);
static int phy_led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{

View File

@ -2040,6 +2040,9 @@ int phy_get_tx_amplitude_gain(struct phy_device *phydev, struct device *dev,
enum ethtool_link_mode_bit_indices linkmode,
u32 *val);
int phy_get_mac_termination(struct phy_device *phydev, struct device *dev,
u32 *val);
void phy_resolve_pause(unsigned long *local_adv, unsigned long *partner_adv,
bool *tx_pause, bool *rx_pause);