Commit 044412d9 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
parents b7ed5d5a 6c3c3c23
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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

+4 −0
Original line number Diff line number Diff line
@@ -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>;
      };
    };

+33 −0
Original line number Diff line number Diff line
@@ -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;
+15 −0
Original line number Diff line number Diff line
@@ -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)
{
+3 −0
Original line number Diff line number Diff line
@@ -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);