All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] phy: add common PHY polarity properties support
@ 2026-04-05 14:49 Lucien.Jheng
  2026-04-05 14:49 ` [PATCH v3 1/4] phy: add common PHY " Lucien.Jheng
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-05 14:49 UTC (permalink / raw)
  To: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean
  Cc: ericwouds, kabel, frank-w, daniel, ansuelsmth, mkorpershoek,
	skylake.huang, lucien.jheng, u-boot, Lucien.Jheng

This series ports PHY polarity inversion support via generic device tree
properties from Linux kernel, synchronizing with Merge tag 'phy-for-7.0'
of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.

Patch 1 introduces a new PHY_COMMON_PROPS library providing helper
functions (phy_get_rx_polarity, phy_get_tx_polarity, and their
"manual" variants) for PHY drivers to read standard polarity properties
from the device tree. The PHY_POL_NORMAL, PHY_POL_INVERT, and
PHY_POL_AUTO constants are consumed from dts/upstream/include, which is
already on the compiler include path.

Patch 2 updates the Airoha EN8811H PHY driver to use the new standard
rx-polarity and tx-polarity properties, with backward compatibility
fallback to the now-deprecated airoha,pnswap-rx and airoha,pnswap-tx
boolean properties.

Patches 3-4 add sandbox DM unit tests for the new library, ported from
the Linux KUnit test (linux/drivers/phy/phy-common-props-test.c). Patch 3
adds the build rule in test/dm/Makefile and 16 unit test cases (8 for rx,
8 for tx) covering: missing property, single value with no names array,
count mismatches, name-based lookup, missing default fallback, default
fallback, and unsupported polarity value. Patch 4 adds the corresponding
8 test DT nodes to arch/sandbox/dts/test.dts.

Changes in v3:
- patch 1: fix ofnode_get_u32_prop_for_name() to apply default_val and
  return 0 when the polarity property is absent, instead of returning
  -ENOENT; update @node and @default_val kdoc accordingly — this aligns
  the "missing property" path with the behaviour expected by
  phy_get_manual_rx/tx_polarity() and is validated by the new unit tests
- Add unit tests for the PHY_COMMON_PROPS library (patches 3-4), ported
  from Linux KUnit test linux/drivers/phy/phy-common-props-test.c
- Add test/dm/Makefile build entry gated on CONFIG_PHY_COMMON_PROPS
- Add 8 sandbox DT nodes to arch/sandbox/dts/test.dts covering all test
  scenarios; include <dt-bindings/phy/phy.h> in test.dts

Changes in v2:
- Drop DT binding patches (v1 patches 1 and 3): already merged via
  the DTS upstream subtree merge (tag 'v7.0-rc2-dts')
- Drop creation of include/dt-bindings/phy/phy.h: the header is now
  provided by dts/upstream/include/dt-bindings/phy/phy.h, which is
  already in the build's include search path

Lucien.Jheng (4):
  phy: add common PHY properties support
  net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties
  test: dm: add PHY common props unit tests
  sandbox: dts: add PHY common props test nodes

 arch/sandbox/dts/test.dts            |  60 +++++
 drivers/net/phy/airoha/Kconfig       |   1 +
 drivers/net/phy/airoha/air_en8811.c  |  58 +++--
 drivers/phy/Kconfig                  |   8 +
 drivers/phy/Makefile                 |   1 +
 drivers/phy/phy-common-props.c       | 286 ++++++++++++++++++++++++
 include/linux/phy/phy-common-props.h |  69 ++++++
 test/dm/Makefile                     |   1 +
 test/dm/phy_common_props.c           | 319 +++++++++++++++++++++++++++
 9 files changed, 789 insertions(+), 14 deletions(-)
 create mode 100644 drivers/phy/phy-common-props.c
 create mode 100644 include/linux/phy/phy-common-props.h
 create mode 100644 test/dm/phy_common_props.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 1/4] phy: add common PHY properties support
  2026-04-05 14:49 [PATCH v3 0/4] phy: add common PHY polarity properties support Lucien.Jheng
@ 2026-04-05 14:49 ` Lucien.Jheng
  2026-04-11 14:37   ` Simon Glass
  2026-04-05 14:49 ` [PATCH v3 2/4] net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties Lucien.Jheng
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-05 14:49 UTC (permalink / raw)
  To: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean
  Cc: ericwouds, kabel, frank-w, daniel, ansuelsmth, mkorpershoek,
	skylake.huang, lucien.jheng, u-boot, Lucien.Jheng

Add a new PHY_COMMON_PROPS library that provides helper functions for
PHY drivers to read standardized polarity properties from the device
tree node:

  - phy_get_rx_polarity() / phy_get_tx_polarity()
  - phy_get_manual_rx_polarity() / phy_get_manual_tx_polarity()

The dt-bindings/phy/phy.h header with PHY_POL_NORMAL, PHY_POL_INVERT,
and PHY_POL_AUTO constants is provided via dts/upstream/include, which
is already in the build include path.

Ported from Merge tag 'phy-for-7.0':
  git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy

Link: https://git.kernel.org/linus/e7556b59ba65179612bce3fa56bb53d1b4fb20db
Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
---
 drivers/phy/Kconfig                  |   8 +
 drivers/phy/Makefile                 |   1 +
 drivers/phy/phy-common-props.c       | 286 +++++++++++++++++++++++++++
 include/linux/phy/phy-common-props.h |  69 +++++++
 4 files changed, 364 insertions(+)
 create mode 100644 drivers/phy/phy-common-props.c
 create mode 100644 include/linux/phy/phy-common-props.h

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 09810b62b51..18419c1d490 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -339,4 +339,12 @@ source "drivers/phy/qcom/Kconfig"
 source "drivers/phy/renesas/Kconfig"
 source "drivers/phy/starfive/Kconfig"
 
+config PHY_COMMON_PROPS
+	bool "Common PHY properties support"
+	help
+	  Enable support for common PHY properties defined in the device tree,
+	  such as rx-polarity and tx-polarity. This provides helpers for PHY
+	  drivers to read polarity and other standard PHY properties from the
+	  device tree node.
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 83102349669..91610692cc0 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_PHY_NPCM_USB) += phy-npcm-usb.o
 obj-$(CONFIG_$(PHASE_)PHY_IMX8MQ_USB) += phy-imx8mq-usb.o
 obj-$(CONFIG_PHY_IMX8M_PCIE) += phy-imx8m-pcie.o
 obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o
+obj-$(CONFIG_PHY_COMMON_PROPS) += phy-common-props.o
 obj-y += cadence/
 obj-y += ti/
 obj-y += qcom/
diff --git a/drivers/phy/phy-common-props.c b/drivers/phy/phy-common-props.c
new file mode 100644
index 00000000000..36fe48fc1b9
--- /dev/null
+++ b/drivers/phy/phy-common-props.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * phy-common-props.c  --  Common PHY properties
+ *
+ * Copyright 2025-2026 NXP
+ */
+#include <dm/ofnode.h>
+#include <log.h>
+#include <malloc.h>
+#include <linux/phy/phy-common-props.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+
+/**
+ * ofnode_count_u32_prop - Count number of u32 elements in a property
+ * @node: Device tree node
+ * @propname: Property name
+ *
+ * Return: number of u32 elements, or negative error code
+ */
+static int ofnode_count_u32_prop(ofnode node, const char *propname)
+{
+	int size;
+
+	size = ofnode_read_size(node, propname);
+	if (size < 0) {
+		pr_debug("%s: property '%s' not found (err=%d)\n",
+			 __func__, propname, size);
+		return size;
+	}
+
+	pr_debug("%s: property '%s' has %zu bytes (%zu elements)\n",
+		 __func__, propname, (size_t)size, (size_t)(size / sizeof(u32)));
+
+	return size / sizeof(u32);
+}
+
+/**
+ * ofnode_get_u32_prop_for_name - Find u32 property by name, or default value
+ * @node: Device tree node; if invalid or @props_title is absent, @default_val is used
+ * @name: Property name used as lookup key in @names_title (must not be NULL)
+ * @props_title: Name of u32 array property holding values
+ * @names_title: Name of string array property holding lookup keys
+ * @default_val: Default value if @node is invalid, @props_title is absent, or empty
+ * @val: Pointer to store the returned value
+ *
+ * This function retrieves a u32 value from @props_title based on a name lookup
+ * in @names_title. The value stored in @val is determined as follows:
+ *
+ * - If @node is invalid or @props_title is absent: @default_val is used
+ * - If @props_title exists but is empty: @default_val is used
+ * - If @props_title has exactly one element and @names_title is empty:
+ *   that element is used
+ * - Otherwise: @val is set to the element at the same index where @name is
+ *   found in @names_title.
+ * - If @name is not found, the function looks for a "default" entry in
+ *   @names_title and uses the corresponding value from @props_title
+ *
+ * When both @props_title and @names_title are present, they must have the
+ * same number of elements (except when @props_title has exactly one element).
+ *
+ * Return: zero on success, negative error on failure.
+ */
+static int ofnode_get_u32_prop_for_name(ofnode node, const char *name,
+					const char *props_title,
+					const char *names_title,
+					unsigned int default_val,
+					unsigned int *val)
+{
+	int err, n_props, n_names, idx;
+	u32 *props;
+
+	if (!name) {
+		printf("Error: Lookup key inside \"%s\" is mandatory\n",
+		       names_title);
+		return -EINVAL;
+	}
+
+	pr_debug("%s: looking up '%s' in props='%s' names='%s' default=%u\n",
+		 __func__, name, props_title, names_title, default_val);
+
+	n_props = ofnode_count_u32_prop(node, props_title);
+	if (n_props < 0) {
+		/* property is absent */
+		pr_debug("%s: '%s' is absent, using default value %u\n",
+			 __func__, props_title, default_val);
+		*val = default_val;
+		return 0;
+	}
+	if (n_props == 0) {
+		/* property exists but is empty, use default */
+		pr_debug("%s: '%s' is empty, using default value %u\n",
+			 __func__, props_title, default_val);
+		*val = default_val;
+		return 0;
+	}
+
+	n_names = ofnode_read_string_count(node, names_title);
+
+	pr_debug("%s: '%s' has %d elements, '%s' has %d entries\n",
+		 __func__, props_title, n_props, names_title, n_names);
+	if (n_names >= 0 && n_props != n_names) {
+		printf("Error: mismatch between \"%s\" and \"%s\" property count (%d vs %d)\n",
+		       props_title, names_title, n_props, n_names);
+		return -EINVAL;
+	}
+
+	idx = ofnode_stringlist_search(node, names_title, name);
+	if (idx >= 0) {
+		pr_debug("%s: found '%s' at index %d in '%s'\n",
+			 __func__, name, idx, names_title);
+	} else {
+		pr_debug("%s: '%s' not found in '%s', trying 'default'\n",
+			 __func__, name, names_title);
+		idx = ofnode_stringlist_search(node, names_title, "default");
+		if (idx >= 0)
+			pr_debug("%s: 'default' entry found at index %d\n",
+				 __func__, idx);
+		else
+			pr_debug("%s: 'default' entry not found in '%s'\n",
+				 __func__, names_title);
+	}
+	/*
+	 * If the mode name is missing, it can only mean the specified property
+	 * is the default one for all modes, so reject any other property count
+	 * than 1.
+	 */
+	if (idx < 0 && n_props != 1) {
+		printf("Error: \"%s\" property has %d elements, but cannot find \"%s\" in \"%s\" and there is no default value\n",
+		       props_title, n_props, name, names_title);
+		return -EINVAL;
+	}
+
+	if (n_props == 1) {
+		pr_debug("%s: single-element '%s', reading directly\n",
+			 __func__, props_title);
+		err = ofnode_read_u32(node, props_title, val);
+		if (err) {
+			pr_debug("%s: failed to read '%s' (err=%d)\n",
+				 __func__, props_title, err);
+			return err;
+		}
+		pr_debug("%s: resolved value %u for name '%s' from '%s'\n",
+			 __func__, *val, name, props_title);
+		return 0;
+	}
+
+	/* We implicitly know idx >= 0 here */
+	props = calloc(n_props, sizeof(*props));
+	if (!props)
+		return -ENOMEM;
+
+	err = ofnode_read_u32_array(node, props_title, props, n_props);
+	if (err >= 0) {
+		*val = props[idx];
+		pr_debug("%s: resolved value %u at index %d for name '%s' from '%s'\n",
+			 __func__, *val, idx, name, props_title);
+	} else {
+		pr_debug("%s: failed to read u32 array '%s' (err=%d)\n",
+			 __func__, props_title, err);
+	}
+
+	free(props);
+
+	return err;
+}
+
+/**
+ * phy_get_polarity_for_mode - Get polarity for a specific PHY mode
+ * @node: Device tree node
+ * @mode_name: The name of the PHY mode to look up
+ * @supported: Bit mask of supported polarity values
+ * @default_val: Default polarity value if property is missing
+ * @polarity_prop: Name of the polarity property
+ * @names_prop: Name of the names property
+ * @val: Pointer to returned polarity
+ *
+ * Return: zero on success, negative error on failure.
+ */
+static int phy_get_polarity_for_mode(ofnode node, const char *mode_name,
+				     unsigned int supported,
+				     unsigned int default_val,
+				     const char *polarity_prop,
+				     const char *names_prop,
+				     unsigned int *val)
+{
+	int err;
+
+	pr_debug("%s: querying '%s' for mode '%s' (supported=0x%x, default=%u)\n",
+		 __func__, polarity_prop, mode_name, supported, default_val);
+
+	err = ofnode_get_u32_prop_for_name(node, mode_name, polarity_prop,
+					   names_prop, default_val, val);
+	if (err) {
+		pr_debug("%s: '%s' lookup failed for mode '%s' (err=%d)\n",
+			 __func__, polarity_prop, mode_name, err);
+		return err;
+	}
+
+	pr_debug("%s: '%s' for mode '%s' = %u\n",
+		 __func__, polarity_prop, mode_name, *val);
+
+	if (!(supported & BIT(*val))) {
+		printf("Error: %d is not a supported value for '%s' element '%s'\n",
+		       *val, polarity_prop, mode_name);
+		err = -EOPNOTSUPP;
+	}
+
+	return err;
+}
+
+/**
+ * phy_get_rx_polarity - Get RX polarity for PHY differential lane
+ * @node: Pointer to the PHY's device tree node.
+ * @mode_name: The name of the PHY mode to look up.
+ * @supported: Bit mask of PHY_POL_NORMAL, PHY_POL_INVERT and PHY_POL_AUTO
+ * @default_val: Default polarity value if property is missing
+ * @val: Pointer to returned polarity.
+ *
+ * Return: zero on success, negative error on failure.
+ */
+int phy_get_rx_polarity(ofnode node, const char *mode_name,
+			unsigned int supported, unsigned int default_val,
+			unsigned int *val)
+{
+	return phy_get_polarity_for_mode(node, mode_name, supported,
+					 default_val, "rx-polarity",
+					 "rx-polarity-names", val);
+}
+
+/**
+ * phy_get_tx_polarity - Get TX polarity for PHY differential lane
+ * @node: Pointer to the PHY's device tree node.
+ * @mode_name: The name of the PHY mode to look up.
+ * @supported: Bit mask of PHY_POL_NORMAL, PHY_POL_INVERT and PHY_POL_AUTO
+ * @default_val: Default polarity value if property is missing
+ * @val: Pointer to returned polarity.
+ *
+ * Return: zero on success, negative error on failure.
+ */
+int phy_get_tx_polarity(ofnode node, const char *mode_name,
+			unsigned int supported, unsigned int default_val,
+			unsigned int *val)
+{
+	return phy_get_polarity_for_mode(node, mode_name, supported,
+					 default_val, "tx-polarity",
+					 "tx-polarity-names", val);
+}
+
+/**
+ * phy_get_manual_rx_polarity - Get manual RX polarity for PHY differential lane
+ * @node: Pointer to the PHY's device tree node.
+ * @mode_name: The name of the PHY mode to look up.
+ * @val: Pointer to returned polarity.
+ *
+ * Helper for PHYs which do not support protocols with automatic RX polarity
+ * detection and correction.
+ *
+ * Return: zero on success, negative error on failure.
+ */
+int phy_get_manual_rx_polarity(ofnode node, const char *mode_name,
+			       unsigned int *val)
+{
+	return phy_get_rx_polarity(node, mode_name,
+				   BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+				   PHY_POL_NORMAL, val);
+}
+
+/**
+ * phy_get_manual_tx_polarity - Get manual TX polarity for PHY differential lane
+ * @node: Pointer to the PHY's device tree node.
+ * @mode_name: The name of the PHY mode to look up.
+ * @val: Pointer to returned polarity.
+ *
+ * Helper for PHYs without any custom default value for the TX polarity.
+ *
+ * Return: zero on success, negative error on failure.
+ */
+int phy_get_manual_tx_polarity(ofnode node, const char *mode_name,
+			       unsigned int *val)
+{
+	return phy_get_tx_polarity(node, mode_name,
+				   BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+				   PHY_POL_NORMAL, val);
+}
diff --git a/include/linux/phy/phy-common-props.h b/include/linux/phy/phy-common-props.h
new file mode 100644
index 00000000000..9158851f2e1
--- /dev/null
+++ b/include/linux/phy/phy-common-props.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * phy-common-props.h -- Common properties for generic PHYs
+ *
+ * Copyright 2025-2026 NXP
+ */
+
+#ifndef __PHY_COMMON_PROPS_H
+#define __PHY_COMMON_PROPS_H
+
+#include <dt-bindings/phy/phy.h>
+#include <dm/ofnode.h>
+
+/**
+ * phy_get_rx_polarity - Get RX polarity for PHY differential lane
+ * @node: Pointer to the PHY's device tree node.
+ * @mode_name: The name of the PHY mode to look up.
+ * @supported: Bit mask of PHY_POL_NORMAL, PHY_POL_INVERT and PHY_POL_AUTO
+ * @default_val: Default polarity value if property is missing
+ * @val: Pointer to returned polarity.
+ *
+ * Return: zero on success, negative error on failure.
+ */
+int phy_get_rx_polarity(ofnode node, const char *mode_name,
+			unsigned int supported, unsigned int default_val,
+			unsigned int *val);
+
+/**
+ * phy_get_tx_polarity - Get TX polarity for PHY differential lane
+ * @node: Pointer to the PHY's device tree node.
+ * @mode_name: The name of the PHY mode to look up.
+ * @supported: Bit mask of PHY_POL_NORMAL, PHY_POL_INVERT and PHY_POL_AUTO
+ * @default_val: Default polarity value if property is missing
+ * @val: Pointer to returned polarity.
+ *
+ * Return: zero on success, negative error on failure.
+ */
+int phy_get_tx_polarity(ofnode node, const char *mode_name,
+			unsigned int supported, unsigned int default_val,
+			unsigned int *val);
+
+/**
+ * phy_get_manual_rx_polarity - Get manual RX polarity for PHY differential lane
+ * @node: Pointer to the PHY's device tree node.
+ * @mode_name: The name of the PHY mode to look up.
+ * @val: Pointer to returned polarity.
+ *
+ * Helper for PHYs which do not support protocols with automatic RX polarity
+ * detection and correction.
+ *
+ * Return: zero on success, negative error on failure.
+ */
+int phy_get_manual_rx_polarity(ofnode node, const char *mode_name,
+			       unsigned int *val);
+
+/**
+ * phy_get_manual_tx_polarity - Get manual TX polarity for PHY differential lane
+ * @node: Pointer to the PHY's device tree node.
+ * @mode_name: The name of the PHY mode to look up.
+ * @val: Pointer to returned polarity.
+ *
+ * Helper for PHYs without any custom default value for the TX polarity.
+ *
+ * Return: zero on success, negative error on failure.
+ */
+int phy_get_manual_tx_polarity(ofnode node, const char *mode_name,
+			       unsigned int *val);
+
+#endif /* __PHY_COMMON_PROPS_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 2/4] net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties
  2026-04-05 14:49 [PATCH v3 0/4] phy: add common PHY polarity properties support Lucien.Jheng
  2026-04-05 14:49 ` [PATCH v3 1/4] phy: add common PHY " Lucien.Jheng
@ 2026-04-05 14:49 ` Lucien.Jheng
  2026-04-11 14:37   ` Simon Glass
  2026-04-05 14:49 ` [PATCH v3 3/4] test: dm: add PHY common props unit tests Lucien.Jheng
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-05 14:49 UTC (permalink / raw)
  To: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean
  Cc: ericwouds, kabel, frank-w, daniel, ansuelsmth, mkorpershoek,
	skylake.huang, lucien.jheng, u-boot, Lucien.Jheng

Replace the proprietary airoha,pnswap-rx / airoha,pnswap-tx boolean
device tree properties with the standard rx-polarity and tx-polarity
properties defined in phy-common-props.yaml.

Backward compatibility is maintained by reading the legacy boolean
properties first and passing them as the default_pol argument to
phy_get_rx/tx_polarity(). If the standard properties are absent the
legacy values are used transparently, so existing device trees remain
functional without modification.

Link: https://git.kernel.org/linus/66d8a334b57e64e43810623b3d88f0ce9745270b
Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
---
 drivers/net/phy/airoha/Kconfig      |  1 +
 drivers/net/phy/airoha/air_en8811.c | 58 ++++++++++++++++++++++-------
 2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/drivers/net/phy/airoha/Kconfig b/drivers/net/phy/airoha/Kconfig
index da8747939e3..4139df343ad 100644
--- a/drivers/net/phy/airoha/Kconfig
+++ b/drivers/net/phy/airoha/Kconfig
@@ -7,6 +7,7 @@ config PHY_AIROHA_EN8811
 	depends on PHY_AIROHA
 	depends on SUPPORTS_FW_LOADER
 	select FW_LOADER
+	select PHY_COMMON_PROPS
 	help
 	  AIROHA EN8811H supported.
 	  AIROHA AN8811HB supported.
diff --git a/drivers/net/phy/airoha/air_en8811.c b/drivers/net/phy/airoha/air_en8811.c
index 0b974472732..0a56ee0bdf3 100644
--- a/drivers/net/phy/airoha/air_en8811.c
+++ b/drivers/net/phy/airoha/air_en8811.c
@@ -23,6 +23,7 @@
 #include <linux/compat.h>
 #include <dm/device_compat.h>
 #include <u-boot/crc.h>
+#include <linux/phy/phy-common-props.h>
 
 /* MII Registers */
 #define AIR_AUX_CTRL_STATUS		0x1d
@@ -1046,6 +1047,47 @@ static int air_leds_init(struct phy_device *phydev, int num, u16 dur, int mode)
 	return 0;
 }
 
+static int en8811h_config_serdes_polarity(struct phy_device *phydev)
+{
+	ofnode node = phy_get_ofnode(phydev);
+	unsigned int pol, default_pol;
+	u32 pbus_value = 0;
+	int ret;
+
+	if (!ofnode_valid(node))
+		return 0;
+
+	default_pol = PHY_POL_NORMAL;
+	if (ofnode_read_bool(node, "airoha,pnswap-rx"))
+		default_pol = PHY_POL_INVERT;
+
+	ret = phy_get_rx_polarity(node,
+				  phy_interface_strings[phydev->interface],
+				  BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+				  default_pol, &pol);
+	if (ret)
+		return ret;
+	if (pol == PHY_POL_INVERT)
+		pbus_value |= EN8811H_POLARITY_RX_REVERSE;
+
+	default_pol = PHY_POL_NORMAL;
+	if (ofnode_read_bool(node, "airoha,pnswap-tx"))
+		default_pol = PHY_POL_INVERT;
+
+	ret = phy_get_tx_polarity(node,
+				  phy_interface_strings[phydev->interface],
+				  BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+				  default_pol, &pol);
+	if (ret)
+		return ret;
+	if (pol == PHY_POL_NORMAL)
+		pbus_value |= EN8811H_POLARITY_TX_NORMAL;
+
+	return air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
+				       EN8811H_POLARITY_RX_REVERSE |
+				       EN8811H_POLARITY_TX_NORMAL, pbus_value);
+}
+
 static int en8811h_config(struct phy_device *phydev)
 {
 	struct en8811h_priv *priv = phydev->priv;
@@ -1081,20 +1123,8 @@ static int en8811h_config(struct phy_device *phydev)
 	if (ret < 0)
 		return ret;
 
-	/* Serdes polarity */
-	pbus_value = 0;
-	if (ofnode_read_bool(node, "airoha,pnswap-rx"))
-		pbus_value |=  EN8811H_POLARITY_RX_REVERSE;
-	else
-		pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
-	if (ofnode_read_bool(node, "airoha,pnswap-tx"))
-		pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
-	else
-		pbus_value |=  EN8811H_POLARITY_TX_NORMAL;
-	ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
-				      EN8811H_POLARITY_RX_REVERSE |
-				      EN8811H_POLARITY_TX_NORMAL,
-				      pbus_value);
+	/* Configure Serdes polarity from device tree */
+	ret = en8811h_config_serdes_polarity(phydev);
 	if (ret < 0)
 		return ret;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 3/4] test: dm: add PHY common props unit tests
  2026-04-05 14:49 [PATCH v3 0/4] phy: add common PHY polarity properties support Lucien.Jheng
  2026-04-05 14:49 ` [PATCH v3 1/4] phy: add common PHY " Lucien.Jheng
  2026-04-05 14:49 ` [PATCH v3 2/4] net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties Lucien.Jheng
@ 2026-04-05 14:49 ` Lucien.Jheng
  2026-04-11 14:38   ` Simon Glass
  2026-04-05 14:49 ` [PATCH v3 4/4] sandbox: dts: add PHY common props test nodes Lucien.Jheng
  2026-04-11 14:37 ` [v3,0/4] phy: add common PHY polarity properties support Simon Glass
  4 siblings, 1 reply; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-05 14:49 UTC (permalink / raw)
  To: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean
  Cc: ericwouds, kabel, frank-w, daniel, ansuelsmth, mkorpershoek,
	skylake.huang, lucien.jheng, u-boot, Lucien.Jheng

Add obj-$(CONFIG_PHY_COMMON_PROPS) build entry in test/dm/Makefile and
sandbox DM unit tests for the PHY common properties library, covering
rx/tx polarity lookups for all relevant cases:

  - missing property (defaults to PHY_POL_NORMAL)
  - single value without names array (applies to all modes)
  - count mismatch between values and names arrays (-EINVAL)
  - name found by exact match
  - name not found with no "default" fallback (-EINVAL)
  - name not found with a "default" entry (uses fallback value)
  - unsupported polarity value (-EOPNOTSUPP)

Ported from Linux KUnit test:
  linux/drivers/phy/phy-common-props-test.c

Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
---

```test log```
執行 phy common props 測試...
Bloblist at 100 not found (err=-2)
pinctrl_select_state_full() sandbox_serial serial: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19


U-Boot 2026.01-rc5--g11ad53c5213e-dirty (Mar 22 2026 - 22:31:17 +0800)

Reset Status: WARM Reset Status: COLD
Model: sandbox
DRAM:  256 MiB
Core:  294 devices, 105 uclasses, devicetree: board, universal payload active
WDT:   Not starting wdt-gpio-toggle
WDT:   Not starting wdt-gpio-level
WDT:   Not starting wdt@0
NAND:  4100 MiB
MMC:   Can't map file 'mmc1.img': Invalid argument
   sandbox_mmc_probe() mmc1: Unable to map file 'mmc1.img'
Can't map file 'mmc1.img': Invalid argument
   sandbox_mmc_probe() mmc1: Unable to map file 'mmc1.img'
           mmc_probe() mmc1 - probe failed: -1
mmc2: 2 (SD)Can't map file 'mmc1.img': Invalid argument
   sandbox_mmc_probe() mmc1: Unable to map file 'mmc1.img'
, mmc0: 0 (SD)
Loading Environment from nowhere... OK
In:    serial
Out:   serial,vidconsole
Err:   serial,vidconsole
Model: sandbox
Net:   eth0: eth@10002000, eth5: eth@10003000, eth3: sbe5, eth6: eth@10004000, eth8: phy-test-eth, eth4: dsa-test-eth, eth2: lan0, eth7: lan1

Test: phy_common_props_rx_find_by_name: phy_common_props.c
Test: phy_common_props_rx_find_by_name: phy_common_props.c (flat tree)
Test: phy_common_props_rx_missing: phy_common_props.c
Test: phy_common_props_rx_missing: phy_common_props.c (flat tree)
Test: phy_common_props_rx_more_names: phy_common_props.c
Test: phy_common_props_rx_more_names: phy_common_props.c (flat tree)
Test: phy_common_props_rx_more_values: phy_common_props.c
Test: phy_common_props_rx_more_values: phy_common_props.c (flat tree)
Test: phy_common_props_rx_no_default: phy_common_props.c
Test: phy_common_props_rx_no_default: phy_common_props.c (flat tree)
Test: phy_common_props_rx_single_value: phy_common_props.c
Test: phy_common_props_rx_single_value: phy_common_props.c (flat tree)
Test: phy_common_props_rx_unsupported: phy_common_props.c
Test: phy_common_props_rx_unsupported: phy_common_props.c (flat tree)
Test: phy_common_props_rx_with_default: phy_common_props.c
Test: phy_common_props_rx_with_default: phy_common_props.c (flat tree)
Test: phy_common_props_tx_find_by_name: phy_common_props.c
Test: phy_common_props_tx_find_by_name: phy_common_props.c (flat tree)
Test: phy_common_props_tx_missing: phy_common_props.c
Test: phy_common_props_tx_missing: phy_common_props.c (flat tree)
Test: phy_common_props_tx_more_names: phy_common_props.c
Test: phy_common_props_tx_more_names: phy_common_props.c (flat tree)
Test: phy_common_props_tx_more_values: phy_common_props.c
Test: phy_common_props_tx_more_values: phy_common_props.c (flat tree)
Test: phy_common_props_tx_no_default: phy_common_props.c
Test: phy_common_props_tx_no_default: phy_common_props.c (flat tree)
Test: phy_common_props_tx_single_value: phy_common_props.c
Test: phy_common_props_tx_single_value: phy_common_props.c (flat tree)
Test: phy_common_props_tx_unsupported: phy_common_props.c
Test: phy_common_props_tx_unsupported: phy_common_props.c (flat tree)
Test: phy_common_props_tx_with_default: phy_common_props.c
Test: phy_common_props_tx_with_default: phy_common_props.c (flat tree)
Tests run: 16, 37 ms, average: 2 ms, failures: 0

 test/dm/Makefile           |   1 +
 test/dm/phy_common_props.c | 319 +++++++++++++++++++++++++++++++++++++
 2 files changed, 320 insertions(+)
 create mode 100644 test/dm/phy_common_props.c

diff --git a/test/dm/Makefile b/test/dm/Makefile
index 771b703b737..d69b0e08d66 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_P2SB) += p2sb.o
 obj-$(CONFIG_PCI_ENDPOINT) += pci_ep.o
 obj-$(CONFIG_PCH) += pch.o
 obj-$(CONFIG_PHY) += phy.o
+obj-$(CONFIG_PHY_COMMON_PROPS) += phy_common_props.o
 ifneq ($(CONFIG_PINMUX),)
 obj-$(CONFIG_PINCONF) += pinmux.o
 endif
diff --git a/test/dm/phy_common_props.c b/test/dm/phy_common_props.c
new file mode 100644
index 00000000000..21f5042b7a0
--- /dev/null
+++ b/test/dm/phy_common_props.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * U-Boot sandbox DM tests for PHY common props
+ *
+ * Ported from Linux KUnit test:
+ *   linux/drivers/phy/phy-common-props-test.c
+ *
+ * Copyright 2025-2026 NXP
+ */
+#include <dm.h>
+#include <dm/ofnode.h>
+#include <dm/test.h>
+#include <linux/bitops.h>
+#include <linux/phy/phy-common-props.h>
+#include <dt-bindings/phy/phy.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+/* --- RX polarity tests -------------------------------------------------- */
+
+/* Test: rx-polarity property is missing => default PHY_POL_NORMAL */
+static int dm_test_phy_common_props_rx_missing(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-missing");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_rx_polarity(node, "sgmii", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_NORMAL, val);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_rx_missing, UTF_SCAN_FDT);
+
+/* Test: rx-polarity has more values than rx-polarity-names => -EINVAL */
+static int dm_test_phy_common_props_rx_more_values(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-more-values");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_rx_polarity(node, "sgmii", &val);
+	ut_asserteq(-EINVAL, ret);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_rx_more_values, UTF_SCAN_FDT);
+
+/* Test: rx-polarity has 1 value and rx-polarity-names does not exist */
+static int dm_test_phy_common_props_rx_single_value(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-single");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_rx_polarity(node, "sgmii", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_INVERT, val);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_rx_single_value, UTF_SCAN_FDT);
+
+/* Test: rx-polarity-names has more values than rx-polarity => -EINVAL */
+static int dm_test_phy_common_props_rx_more_names(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-more-names");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_rx_polarity(node, "sgmii", &val);
+	ut_asserteq(-EINVAL, ret);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_rx_more_names, UTF_SCAN_FDT);
+
+/* Test: valid arrays, find polarity by mode name */
+static int dm_test_phy_common_props_rx_find_by_name(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-find-by-name");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_rx_polarity(node, "sgmii", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_NORMAL, val);
+
+	ret = phy_get_manual_rx_polarity(node, "2500base-x", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_INVERT, val);
+
+	/* "usb-ss" has PHY_POL_AUTO; auto is supported here */
+	ret = phy_get_rx_polarity(node, "usb-ss", BIT(PHY_POL_AUTO),
+				  PHY_POL_AUTO, &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_AUTO, val);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_rx_find_by_name, UTF_SCAN_FDT);
+
+/* Test: name not found, no "default" entry => -EINVAL */
+static int dm_test_phy_common_props_rx_no_default(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-no-default");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_rx_polarity(node, "sgmii", &val);
+	ut_asserteq(-EINVAL, ret);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_rx_no_default, UTF_SCAN_FDT);
+
+/* Test: name not found, "default" entry exists => use default polarity */
+static int dm_test_phy_common_props_rx_with_default(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-with-default");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_rx_polarity(node, "sgmii", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_INVERT, val);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_rx_with_default, UTF_SCAN_FDT);
+
+/* Test: polarity value found but not in supported set => -EOPNOTSUPP */
+static int dm_test_phy_common_props_rx_unsupported(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-unsupported");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_rx_polarity(node, "sgmii", &val);
+	ut_asserteq(-EOPNOTSUPP, ret);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_rx_unsupported, UTF_SCAN_FDT);
+
+/* --- TX polarity tests -------------------------------------------------- */
+
+/* Test: tx-polarity property is missing => default PHY_POL_NORMAL */
+static int dm_test_phy_common_props_tx_missing(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-missing");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_tx_polarity(node, "sgmii", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_NORMAL, val);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_tx_missing, UTF_SCAN_FDT);
+
+/* Test: tx-polarity has more values than tx-polarity-names => -EINVAL */
+static int dm_test_phy_common_props_tx_more_values(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-more-values");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_tx_polarity(node, "sgmii", &val);
+	ut_asserteq(-EINVAL, ret);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_tx_more_values, UTF_SCAN_FDT);
+
+/* Test: tx-polarity has 1 value and tx-polarity-names does not exist */
+static int dm_test_phy_common_props_tx_single_value(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-single");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_tx_polarity(node, "sgmii", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_INVERT, val);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_tx_single_value, UTF_SCAN_FDT);
+
+/* Test: tx-polarity-names has more values than tx-polarity => -EINVAL */
+static int dm_test_phy_common_props_tx_more_names(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-more-names");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_tx_polarity(node, "sgmii", &val);
+	ut_asserteq(-EINVAL, ret);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_tx_more_names, UTF_SCAN_FDT);
+
+/* Test: valid arrays, find polarity by mode name */
+static int dm_test_phy_common_props_tx_find_by_name(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-find-by-name");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_tx_polarity(node, "sgmii", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_NORMAL, val);
+
+	ret = phy_get_manual_tx_polarity(node, "2500base-x", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_INVERT, val);
+
+	ret = phy_get_manual_tx_polarity(node, "1000base-x", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_NORMAL, val);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_tx_find_by_name, UTF_SCAN_FDT);
+
+/* Test: name not found, no "default" entry => -EINVAL */
+static int dm_test_phy_common_props_tx_no_default(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-no-default");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_tx_polarity(node, "sgmii", &val);
+	ut_asserteq(-EINVAL, ret);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_tx_no_default, UTF_SCAN_FDT);
+
+/* Test: name not found, "default" entry exists => use default polarity */
+static int dm_test_phy_common_props_tx_with_default(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-with-default");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_tx_polarity(node, "sgmii", &val);
+	ut_asserteq(0, ret);
+	ut_asserteq(PHY_POL_INVERT, val);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_tx_with_default, UTF_SCAN_FDT);
+
+/* Test: polarity value found but not in supported set => -EOPNOTSUPP */
+static int dm_test_phy_common_props_tx_unsupported(struct unit_test_state *uts)
+{
+	ofnode node = ofnode_path("/phy-common-props-unsupported");
+	unsigned int val;
+	int ret;
+
+	ut_assert(ofnode_valid(node));
+
+	ret = phy_get_manual_tx_polarity(node, "sgmii", &val);
+	ut_asserteq(-EOPNOTSUPP, ret);
+
+	return 0;
+}
+
+DM_TEST(dm_test_phy_common_props_tx_unsupported, UTF_SCAN_FDT);
--
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 4/4] sandbox: dts: add PHY common props test nodes
  2026-04-05 14:49 [PATCH v3 0/4] phy: add common PHY polarity properties support Lucien.Jheng
                   ` (2 preceding siblings ...)
  2026-04-05 14:49 ` [PATCH v3 3/4] test: dm: add PHY common props unit tests Lucien.Jheng
@ 2026-04-05 14:49 ` Lucien.Jheng
  2026-04-11 14:38   ` Simon Glass
  2026-04-11 14:37 ` [v3,0/4] phy: add common PHY polarity properties support Simon Glass
  4 siblings, 1 reply; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-05 14:49 UTC (permalink / raw)
  To: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean
  Cc: ericwouds, kabel, frank-w, daniel, ansuelsmth, mkorpershoek,
	skylake.huang, lucien.jheng, u-boot, Lucien.Jheng

Add device tree test nodes to arch/sandbox/dts/test.dts for the PHY
common properties unit tests.

Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
---
 arch/sandbox/dts/test.dts | 60 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index ac92ebf1afd..0887de4333b 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -16,6 +16,7 @@
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/pinctrl/sandbox-pinmux.h>
 #include <dt-bindings/mux/mux.h>
+#include <dt-bindings/phy/phy.h>
 
 / {
 	model = "sandbox";
@@ -502,6 +503,65 @@
 		phy-names = "phy1";
 	};
 
+	/* PHY common props test nodes */
+	phy_common_props_missing: phy-common-props-missing {
+		/* empty: no rx-polarity or tx-polarity properties */
+	};
+
+	phy_common_props_more_values: phy-common-props-more-values {
+		/* 3 values but only 2 names => count mismatch */
+		rx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT PHY_POL_NORMAL>;
+		rx-polarity-names = "sgmii", "2500base-x";
+		tx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT PHY_POL_NORMAL>;
+		tx-polarity-names = "sgmii", "2500base-x";
+	};
+
+	phy_common_props_single: phy-common-props-single {
+		/* 1 value, no names array => value applies to all modes */
+		rx-polarity = <PHY_POL_INVERT>;
+		tx-polarity = <PHY_POL_INVERT>;
+	};
+
+	phy_common_props_more_names: phy-common-props-more-names {
+		/* 2 values but 3 names => count mismatch */
+		rx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT>;
+		rx-polarity-names = "sgmii", "2500base-x", "1000base-x";
+		tx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT>;
+		tx-polarity-names = "sgmii", "2500base-x", "1000base-x";
+	};
+
+	phy_common_props_find_by_name: phy-common-props-find-by-name {
+		/* valid 3-element arrays, lookup by mode name */
+		rx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT PHY_POL_AUTO>;
+		rx-polarity-names = "sgmii", "2500base-x", "usb-ss";
+		tx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT PHY_POL_NORMAL>;
+		tx-polarity-names = "sgmii", "2500base-x", "1000base-x";
+	};
+
+	phy_common_props_no_default: phy-common-props-no-default {
+		/* name not in array, no "default" entry => -EINVAL */
+		rx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT>;
+		rx-polarity-names = "2500base-x", "1000base-x";
+		tx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT>;
+		tx-polarity-names = "2500base-x", "1000base-x";
+	};
+
+	phy_common_props_with_default: phy-common-props-with-default {
+		/* name not in array, but "default" entry exists */
+		rx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT>;
+		rx-polarity-names = "2500base-x", "default";
+		tx-polarity = <PHY_POL_NORMAL PHY_POL_INVERT>;
+		tx-polarity-names = "2500base-x", "default";
+	};
+
+	phy_common_props_unsupported: phy-common-props-unsupported {
+		/* PHY_POL_AUTO is not supported for manual-only modes */
+		rx-polarity = <PHY_POL_AUTO>;
+		rx-polarity-names = "sgmii";
+		tx-polarity = <PHY_POL_AUTO>;
+		tx-polarity-names = "sgmii";
+	};
+
 	some-bus {
 		#address-cells = <1>;
 		#size-cells = <0>;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [v3,0/4] phy: add common PHY polarity properties support
  2026-04-05 14:49 [PATCH v3 0/4] phy: add common PHY polarity properties support Lucien.Jheng
                   ` (3 preceding siblings ...)
  2026-04-05 14:49 ` [PATCH v3 4/4] sandbox: dts: add PHY common props test nodes Lucien.Jheng
@ 2026-04-11 14:37 ` Simon Glass
  2026-04-25  2:18   ` Lucien.Jheng
  4 siblings, 1 reply; 14+ messages in thread
From: Simon Glass @ 2026-04-11 14:37 UTC (permalink / raw)
  To: lucienzx159; +Cc: u-boot

Hi Lucien,

On 2026-04-05T14:49:40, Lucien.Jheng <lucienzx159@gmail.com> wrote:

> Patches 3-4 add sandbox DM unit tests for the new library

Patches 3 and 4 have a bisection problem. Patch 3 adds test code
referencing DT nodes like /phy-common-props-missing, but those nodes
are only created in patch 4. Please can you squash patches 3 and 4
together, or reorder so the DTS changes come first?

> Add obj-$(CONFIG_PHY_COMMON_PROPS) build entry in test/dm/Makefile

I don't see an update to sandbox_defconfig to enable
CONFIG_PHY_COMMON_PROPS for testing. Please can you add a patch to
enable PHY_COMMON_PROPS in sandbox_defconfig, or imply it from
SANDBOX?

Regards,
Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/4] phy: add common PHY properties support
  2026-04-05 14:49 ` [PATCH v3 1/4] phy: add common PHY " Lucien.Jheng
@ 2026-04-11 14:37   ` Simon Glass
  2026-04-24 16:46     ` Lucien.Jheng
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Glass @ 2026-04-11 14:37 UTC (permalink / raw)
  To: lucienzx159
  Cc: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean, ericwouds, kabel, frank-w, daniel, ansuelsmth,
	mkorpershoek, skylake.huang, lucien.jheng, u-boot

Hi Lucien,

On 2026-04-05T14:49:40, Lucien.Jheng <lucienzx159@gmail.com> wrote:
> phy: add common PHY properties support
>
> Add a new PHY_COMMON_PROPS library that provides helper functions for
> PHY drivers to read standardized polarity properties from the device
> tree node:
>
>   - phy_get_rx_polarity() / phy_get_tx_polarity()
>   - phy_get_manual_rx_polarity() / phy_get_manual_tx_polarity()
>
> The dt-bindings/phy/phy.h header with PHY_POL_NORMAL, PHY_POL_INVERT,
> and PHY_POL_AUTO constants is provided via dts/upstream/include, which
> is already in the build include path.
>
> Ported from Merge tag 'phy-for-7.0':
>   git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
>
> Link: https://git.kernel.org/linus/e7556b59ba65179612bce3fa56bb53d1b4fb20db
> Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
>
> drivers/phy/Kconfig                  |   8 +
>  drivers/phy/Makefile                 |   1 +
>  drivers/phy/phy-common-props.c       | 286 +++++++++++++++++++++++++++++++++++
>  include/linux/phy/phy-common-props.h |  69 +++++++++
>  4 files changed, 364 insertions(+)

> diff --git a/drivers/phy/phy-common-props.c b/drivers/phy/phy-common-props.c
> @@ -74,6 +74,10 @@ static int ofnode_get_u32_prop_for_name(ofnode node, const char *name,
> +     if (!name) {
> +             printf("Error: Lookup key inside \"%s\" is mandatory\n",
> +                    names_title);

In U-Boot drivers, error messages typically use log_err() or pr_err()
rather than printf(). This applies to the other printf() calls in this
file as well. Please can you switch to pr_err() for consistency? Also
note that these errors consume code space, so you could use
log_debug() if you don't want to do that.

Regards,
Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 2/4] net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties
  2026-04-05 14:49 ` [PATCH v3 2/4] net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties Lucien.Jheng
@ 2026-04-11 14:37   ` Simon Glass
  2026-04-24 16:48     ` Lucien.Jheng
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Glass @ 2026-04-11 14:37 UTC (permalink / raw)
  To: lucienzx159
  Cc: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean, ericwouds, kabel, frank-w, daniel, ansuelsmth,
	mkorpershoek, skylake.huang, lucien.jheng, u-boot

Hi Lucien,

On 2026-04-05T14:49:40, Lucien.Jheng <lucienzx159@gmail.com> wrote:
> net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties
>
> Replace the proprietary airoha,pnswap-rx / airoha,pnswap-tx boolean
> device tree properties with the standard rx-polarity and tx-polarity
> properties defined in phy-common-props.yaml.
>
> Backward compatibility is maintained by reading the legacy boolean
> properties first and passing them as the default_pol argument to
> phy_get_rx/tx_polarity(). If the standard properties are absent the
> legacy values are used transparently, so existing device trees remain
> functional without modification.
>
> Link: https://git.kernel.org/linus/66d8a334b57e64e43810623b3d88f0ce9745270b
> Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
>
> drivers/net/phy/airoha/Kconfig      |  1 +
>  drivers/net/phy/airoha/air_en8811.c | 58 ++++++++++++++++++++++++++++---------
>  2 files changed, 45 insertions(+), 14 deletions(-)

> diff --git a/drivers/net/phy/airoha/air_en8811.c b/drivers/net/phy/airoha/air_en8811.c
> @@ -1046,6 +1047,47 @@ static int air_leds_init(...)
> +     ret = phy_get_rx_polarity(node,
> +                               phy_interface_strings[phydev->interface],

Should you use phy_string_for_interface() here instead of directly indexing?

> diff --git a/drivers/net/phy/airoha/air_en8811.c b/drivers/net/phy/airoha/air_en8811.c
> @@ -1046,6 +1047,47 @@ static int air_leds_init(...)
> +     ret = phy_get_tx_polarity(node,
> +                               phy_interface_strings[phydev->interface],

Same here.

Regards,
Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 3/4] test: dm: add PHY common props unit tests
  2026-04-05 14:49 ` [PATCH v3 3/4] test: dm: add PHY common props unit tests Lucien.Jheng
@ 2026-04-11 14:38   ` Simon Glass
  0 siblings, 0 replies; 14+ messages in thread
From: Simon Glass @ 2026-04-11 14:38 UTC (permalink / raw)
  To: lucienzx159
  Cc: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean, ericwouds, kabel, frank-w, daniel, ansuelsmth,
	mkorpershoek, skylake.huang, lucien.jheng, u-boot

Hi Lucien,

On 2026-04-05T14:49:40, Lucien.Jheng <lucienzx159@gmail.com> wrote:
> test: dm: add PHY common props unit tests
>
> Add obj-$(CONFIG_PHY_COMMON_PROPS) build entry in test/dm/Makefile and
> sandbox DM unit tests for the PHY common properties library, covering
> rx/tx polarity lookups for all relevant cases:
>
>   - missing property (defaults to PHY_POL_NORMAL)
>   - single value without names array (applies to all modes)
>   - count mismatch between values and names arrays (-EINVAL)
>   - name found by exact match
>   - name not found with no "default" fallback (-EINVAL)
>   - name not found with a "default" entry (uses fallback value)
>   - unsupported polarity value (-EOPNOTSUPP)
>
> Ported from Linux KUnit test:
>   linux/drivers/phy/phy-common-props-test.c
>
> Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
>
> test/dm/Makefile           |   1 +
>  test/dm/phy_common_props.c | 319 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 320 insertions(+)

> diff --git a/test/dm/phy_common_props.c b/test/dm/phy_common_props.c
> @@ -0,0 +1,319 @@
> +static int dm_test_phy_common_props_rx_missing(struct unit_test_state *uts)
> +{
> +     ofnode node = ofnode_path("/phy-common-props-missing");

This patch references DT nodes (e.g. /phy-common-props-missing) which
are added in patch 4/4. This breaks bisectability. Please can you
either squash patches 3 and 4 together, or swap their order so the DT
nodes are added first?

Regards,
Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 4/4] sandbox: dts: add PHY common props test nodes
  2026-04-05 14:49 ` [PATCH v3 4/4] sandbox: dts: add PHY common props test nodes Lucien.Jheng
@ 2026-04-11 14:38   ` Simon Glass
  2026-04-24 17:01     ` Lucien.Jheng
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Glass @ 2026-04-11 14:38 UTC (permalink / raw)
  To: lucienzx159
  Cc: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean, ericwouds, kabel, frank-w, daniel, ansuelsmth,
	mkorpershoek, skylake.huang, lucien.jheng, u-boot

Hi Lucien,

On 2026-04-05T14:49:40, Lucien.Jheng <lucienzx159@gmail.com> wrote:
> sandbox: dts: add PHY common props test nodes
>
> Add device tree test nodes to arch/sandbox/dts/test.dts for the PHY
> common properties unit tests.
>
> Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
>
> arch/sandbox/dts/test.dts | 60 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 60 insertions(+)

> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> @@ -16,6 +16,7 @@
> +#include <dt-bindings/phy/phy.h>

Are PHY_POL_NORMAL, PHY_POL_INVERT, and PHY_POL_AUTO in an upcoming
subtree merge?

Regards,
Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/4] phy: add common PHY properties support
  2026-04-11 14:37   ` Simon Glass
@ 2026-04-24 16:46     ` Lucien.Jheng
  0 siblings, 0 replies; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-24 16:46 UTC (permalink / raw)
  To: Simon Glass
  Cc: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean, ericwouds, kabel, frank-w, daniel, ansuelsmth,
	mkorpershoek, skylake.huang, lucien.jheng, u-boot


Simon Glass 於 2026/4/11 下午 10:37 寫道:
> Hi Lucien,
>
> On 2026-04-05T14:49:40, Lucien.Jheng<lucienzx159@gmail.com> wrote:
>> phy: add common PHY properties support
>>
>> Add a new PHY_COMMON_PROPS library that provides helper functions for
>> PHY drivers to read standardized polarity properties from the device
>> tree node:
>>
>>    - phy_get_rx_polarity() / phy_get_tx_polarity()
>>    - phy_get_manual_rx_polarity() / phy_get_manual_tx_polarity()
>>
>> The dt-bindings/phy/phy.h header with PHY_POL_NORMAL, PHY_POL_INVERT,
>> and PHY_POL_AUTO constants is provided via dts/upstream/include, which
>> is already in the build include path.
>>
>> Ported from Merge tag 'phy-for-7.0':
>>    git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
>>
>> Link:https://git.kernel.org/linus/e7556b59ba65179612bce3fa56bb53d1b4fb20db
>> Signed-off-by: Lucien.Jheng<lucienzx159@gmail.com>
>>
>> drivers/phy/Kconfig                  |   8 +
>>   drivers/phy/Makefile                 |   1 +
>>   drivers/phy/phy-common-props.c       | 286 +++++++++++++++++++++++++++++++++++
>>   include/linux/phy/phy-common-props.h |  69 +++++++++
>>   4 files changed, 364 insertions(+)
>> diff --git a/drivers/phy/phy-common-props.c b/drivers/phy/phy-common-props.c
>> @@ -74,6 +74,10 @@ static int ofnode_get_u32_prop_for_name(ofnode node, const char *name,
>> +     if (!name) {
>> +             printf("Error: Lookup key inside \"%s\" is mandatory\n",
>> +                    names_title);
> In U-Boot drivers, error messages typically use log_err() or pr_err()
> rather than printf(). This applies to the other printf() calls in this
> file as well. Please can you switch to pr_err() for consistency? Also
> note that these errors consume code space, so you could use
> log_debug() if you don't want to do that.

Sorry for the late reply.

I will switch to pr_err for consistency.

Thank you.

>
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 2/4] net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties
  2026-04-11 14:37   ` Simon Glass
@ 2026-04-24 16:48     ` Lucien.Jheng
  0 siblings, 0 replies; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-24 16:48 UTC (permalink / raw)
  To: Simon Glass
  Cc: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean, ericwouds, kabel, frank-w, daniel, ansuelsmth,
	mkorpershoek, skylake.huang, lucien.jheng, u-boot


Simon Glass 於 2026/4/11 下午 10:37 寫道:
> Hi Lucien,
>
> On 2026-04-05T14:49:40, Lucien.Jheng<lucienzx159@gmail.com> wrote:
>> net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties
>>
>> Replace the proprietary airoha,pnswap-rx / airoha,pnswap-tx boolean
>> device tree properties with the standard rx-polarity and tx-polarity
>> properties defined in phy-common-props.yaml.
>>
>> Backward compatibility is maintained by reading the legacy boolean
>> properties first and passing them as the default_pol argument to
>> phy_get_rx/tx_polarity(). If the standard properties are absent the
>> legacy values are used transparently, so existing device trees remain
>> functional without modification.
>>
>> Link:https://git.kernel.org/linus/66d8a334b57e64e43810623b3d88f0ce9745270b
>> Signed-off-by: Lucien.Jheng<lucienzx159@gmail.com>
>>
>> drivers/net/phy/airoha/Kconfig      |  1 +
>>   drivers/net/phy/airoha/air_en8811.c | 58 ++++++++++++++++++++++++++++---------
>>   2 files changed, 45 insertions(+), 14 deletions(-)
>> diff --git a/drivers/net/phy/airoha/air_en8811.c b/drivers/net/phy/airoha/air_en8811.c
>> @@ -1046,6 +1047,47 @@ static int air_leds_init(...)
>> +     ret = phy_get_rx_polarity(node,
>> +                               phy_interface_strings[phydev->interface],
> Should you use phy_string_for_interface() here instead of directly indexing?
>
>> diff --git a/drivers/net/phy/airoha/air_en8811.c b/drivers/net/phy/airoha/air_en8811.c
>> @@ -1046,6 +1047,47 @@ static int air_leds_init(...)
>> +     ret = phy_get_tx_polarity(node,
>> +                               phy_interface_strings[phydev->interface],
> Same here.

I will use phy_string_for_interface() in the next patch.

Thanks
>
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 4/4] sandbox: dts: add PHY common props test nodes
  2026-04-11 14:38   ` Simon Glass
@ 2026-04-24 17:01     ` Lucien.Jheng
  0 siblings, 0 replies; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-24 17:01 UTC (permalink / raw)
  To: Simon Glass
  Cc: trini, jerome.forissier, sumit.garg, marek.vasut+renesas,
	vladimir.oltean, ericwouds, kabel, frank-w, daniel, ansuelsmth,
	mkorpershoek, skylake.huang, lucien.jheng, u-boot


Simon Glass 於 2026/4/11 下午 10:38 寫道:
> Hi Lucien,
>
> On 2026-04-05T14:49:40, Lucien.Jheng <lucienzx159@gmail.com> wrote:
>> sandbox: dts: add PHY common props test nodes
>>
>> Add device tree test nodes to arch/sandbox/dts/test.dts for the PHY
>> common properties unit tests.
>>
>> Signed-off-by: Lucien.Jheng <lucienzx159@gmail.com>
>>
>> arch/sandbox/dts/test.dts | 60 +++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 60 insertions(+)
>> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
>> @@ -16,6 +16,7 @@
>> +#include <dt-bindings/phy/phy.h>
> Are PHY_POL_NORMAL, PHY_POL_INVERT, and PHY_POL_AUTO in an upcoming
> subtree merge?

Correct. I used tools/update-subtree.sh to merge the latest DTS tag into 
U-Boot.

Thanks

> Regards,
> Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [v3,0/4] phy: add common PHY polarity properties support
  2026-04-11 14:37 ` [v3,0/4] phy: add common PHY polarity properties support Simon Glass
@ 2026-04-25  2:18   ` Lucien.Jheng
  0 siblings, 0 replies; 14+ messages in thread
From: Lucien.Jheng @ 2026-04-25  2:18 UTC (permalink / raw)
  To: Simon Glass; +Cc: u-boot

Hi Simon

Simon Glass 於 2026/4/11 下午 10:37 寫道:
> Hi Lucien,
>
> On 2026-04-05T14:49:40, Lucien.Jheng<lucienzx159@gmail.com> wrote:
>
>> Patches 3-4 add sandbox DM unit tests for the new library
> Patches 3 and 4 have a bisection problem. Patch 3 adds test code
> referencing DT nodes like /phy-common-props-missing, but those nodes
> are only created in patch 4. Please can you squash patches 3 and 4
> together, or reorder so the DTS changes come first?
I will squash patch 3 and 4 together in the next patch.
>
>> Add obj-$(CONFIG_PHY_COMMON_PROPS) build entry in test/dm/Makefile
> I don't see an update to sandbox_defconfig to enable
> CONFIG_PHY_COMMON_PROPS for testing. Please can you add a patch to
> enable PHY_COMMON_PROPS in sandbox_defconfig, or imply it from
> SANDBOX?

I will update sandbox_defconfig in the next patch.

Thanks

>
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-04-25 18:07 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-05 14:49 [PATCH v3 0/4] phy: add common PHY polarity properties support Lucien.Jheng
2026-04-05 14:49 ` [PATCH v3 1/4] phy: add common PHY " Lucien.Jheng
2026-04-11 14:37   ` Simon Glass
2026-04-24 16:46     ` Lucien.Jheng
2026-04-05 14:49 ` [PATCH v3 2/4] net: phy: air_en8811h: use standard rx-polarity/tx-polarity properties Lucien.Jheng
2026-04-11 14:37   ` Simon Glass
2026-04-24 16:48     ` Lucien.Jheng
2026-04-05 14:49 ` [PATCH v3 3/4] test: dm: add PHY common props unit tests Lucien.Jheng
2026-04-11 14:38   ` Simon Glass
2026-04-05 14:49 ` [PATCH v3 4/4] sandbox: dts: add PHY common props test nodes Lucien.Jheng
2026-04-11 14:38   ` Simon Glass
2026-04-24 17:01     ` Lucien.Jheng
2026-04-11 14:37 ` [v3,0/4] phy: add common PHY polarity properties support Simon Glass
2026-04-25  2:18   ` Lucien.Jheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.