Linux-PHY Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Oltean <vladimir.oltean@nxp.com>
To: linux-phy@lists.infradead.org
Cc: Ioana Ciornei <ioana.ciornei@nxp.com>,
	Vinod Koul <vkoul@kernel.org>,
	Kishon Vijay Abraham I <kishon@kernel.org>,
	linux-kernel@vger.kernel.org, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	devicetree@vger.kernel.org
Subject: [PATCH phy 14/14] phy: lynx-28g: probe on per-SoC and per-instance compatible strings
Date: Thu,  4 Sep 2025 18:44:02 +0300	[thread overview]
Message-ID: <20250904154402.300032-15-vladimir.oltean@nxp.com> (raw)
In-Reply-To: <20250904154402.300032-1-vladimir.oltean@nxp.com>

There are 3 SerDes blocks on LX2160A and 2 on LX2162A, and they differ
in some aspects, namely in the number of lanes per SerDes and in the
protocol converters instantiated per lane.

All of this justifies introducing compatible strings for each SerDes and
some driver structures for figuring out the differences. The
"fsl,lynx-28g" compatible string is kind of the "maximal configuration".
It corresponds to SerDes 1 of LX2160A. If we were to treat all SerDes
blocks like this one, we would access lanes which do not exist (0-3) and
we would fail to reject lane modes which don't work.

Cc: Rob Herring <robh@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/phy/freescale/phy-fsl-lynx-28g.c | 97 +++++++++++++++++++++++-
 1 file changed, 93 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 91a3b3928ab4..991587c453df 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -479,9 +479,18 @@ struct lynx_28g_lane {
 	enum lynx_lane_mode mode;
 };
 
+struct lynx_info {
+	int (*get_pccr)(enum lynx_lane_mode lane_mode, int lane,
+			struct lynx_pccr *pccr);
+	int (*get_pcvt_offset)(int lane, enum lynx_lane_mode mode);
+	bool (*lane_supports_mode)(int lane, enum lynx_lane_mode mode);
+	int first_lane;
+};
+
 struct lynx_28g_priv {
 	void __iomem *base;
 	struct device *dev;
+	const struct lynx_info *info;
 	/* Serialize concurrent access to registers shared between lanes,
 	 * like PCCn
 	 */
@@ -800,6 +809,79 @@ static int lynx_28g_get_pcvt_offset(int lane, enum lynx_lane_mode lane_mode)
 	}
 }
 
+static bool lx2160a_serdes1_lane_supports_mode(int lane,
+					       enum lynx_lane_mode mode)
+{
+	return true;
+}
+
+static bool lx2160a_serdes2_lane_supports_mode(int lane,
+					       enum lynx_lane_mode mode)
+{
+	switch (mode) {
+	case LANE_MODE_1000BASEX_SGMII:
+		return true;
+	case LANE_MODE_USXGMII:
+	case LANE_MODE_10GBASER:
+		return lane == 6 || lane == 7;
+	default:
+		return false;
+	}
+}
+
+static bool lx2160a_serdes3_lane_supports_mode(int lane,
+					       enum lynx_lane_mode mode)
+{
+	/*
+	 * Non-networking SerDes, and this driver supports only
+	 * networking protocols
+	 */
+	return false;
+}
+
+static bool lx2162a_serdes1_lane_supports_mode(int lane,
+					       enum lynx_lane_mode mode)
+{
+	return true;
+}
+
+static bool lx2162a_serdes2_lane_supports_mode(int lane,
+					       enum lynx_lane_mode mode)
+{
+	return lx2160a_serdes2_lane_supports_mode(lane, mode);
+}
+
+static const struct lynx_info lynx_info_lx2160a_serdes1 = {
+	.get_pccr = lynx_28g_get_pccr,
+	.get_pcvt_offset = lynx_28g_get_pcvt_offset,
+	.lane_supports_mode = lx2160a_serdes1_lane_supports_mode,
+};
+
+static const struct lynx_info lynx_info_lx2160a_serdes2 = {
+	.get_pccr = lynx_28g_get_pccr,
+	.get_pcvt_offset = lynx_28g_get_pcvt_offset,
+	.lane_supports_mode = lx2160a_serdes2_lane_supports_mode,
+};
+
+static const struct lynx_info lynx_info_lx2160a_serdes3 = {
+	.get_pccr = lynx_28g_get_pccr,
+	.get_pcvt_offset = lynx_28g_get_pcvt_offset,
+	.lane_supports_mode = lx2160a_serdes3_lane_supports_mode,
+};
+
+static const struct lynx_info lynx_info_lx2162a_serdes1 = {
+	.get_pccr = lynx_28g_get_pccr,
+	.get_pcvt_offset = lynx_28g_get_pcvt_offset,
+	.lane_supports_mode = lx2162a_serdes1_lane_supports_mode,
+	.first_lane = 4,
+};
+
+static const struct lynx_info lynx_info_lx2162a_serdes2 = {
+	.get_pccr = lynx_28g_get_pccr,
+	.get_pcvt_offset = lynx_28g_get_pcvt_offset,
+	.lane_supports_mode = lx2162a_serdes2_lane_supports_mode,
+};
+
 static int lynx_pccr_read(struct lynx_28g_lane *lane, enum lynx_lane_mode mode,
 			  u32 *val)
 {
@@ -1202,7 +1284,7 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work)
 	u32 rrstctl;
 	int i;
 
-	for (i = 0; i < LYNX_28G_NUM_LANE; i++) {
+	for (i = priv->info->first_lane; i < LYNX_28G_NUM_LANE; i++) {
 		lane = &priv->lane[i];
 
 		mutex_lock(&lane->phy->mutex);
@@ -1258,7 +1340,8 @@ static struct phy *lynx_28g_xlate(struct device *dev,
 	struct lynx_28g_priv *priv = dev_get_drvdata(dev);
 	int idx = args->args[0];
 
-	if (WARN_ON(idx >= LYNX_28G_NUM_LANE))
+	if (WARN_ON(idx >= LYNX_28G_NUM_LANE ||
+		    idx < priv->info->first_lane))
 		return ERR_PTR(-EINVAL);
 
 	return priv->lane[idx].phy;
@@ -1275,6 +1358,7 @@ static int lynx_28g_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 	priv->dev = &pdev->dev;
+	priv->info = of_device_get_match_data(dev);
 
 	priv->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->base))
@@ -1282,7 +1366,7 @@ static int lynx_28g_probe(struct platform_device *pdev)
 
 	lynx_28g_pll_read_configuration(priv);
 
-	for (i = 0; i < LYNX_28G_NUM_LANE; i++) {
+	for (i = priv->info->first_lane; i < LYNX_28G_NUM_LANE; i++) {
 		struct lynx_28g_lane *lane = &priv->lane[i];
 		struct phy *phy;
 
@@ -1322,7 +1406,12 @@ static void lynx_28g_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id lynx_28g_of_match_table[] = {
-	{ .compatible = "fsl,lynx-28g" },
+	{ .compatible = "fsl,lx2160a-serdes1", .data = &lynx_info_lx2160a_serdes1 },
+	{ .compatible = "fsl,lx2160a-serdes2", .data = &lynx_info_lx2160a_serdes2 },
+	{ .compatible = "fsl,lx2160a-serdes3", .data = &lynx_info_lx2160a_serdes3 },
+	{ .compatible = "fsl,lx2162a-serdes1", .data = &lynx_info_lx2162a_serdes1 },
+	{ .compatible = "fsl,lx2162a-serdes2", .data = &lynx_info_lx2162a_serdes2 },
+	{ .compatible = "fsl,lynx-28g", .data = &lynx_info_lx2160a_serdes1 }, /* fallback */
 	{ },
 };
 MODULE_DEVICE_TABLE(of, lynx_28g_of_match_table);
-- 
2.34.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

  parent reply	other threads:[~2025-09-04 19:53 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-04 15:43 [PATCH phy 00/14] Lynx 28G improvements part 1 Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 01/14] phy: lynx-28g: remove LYNX_28G_ prefix from register names Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 02/14] phy: lynx-28g: don't concatenate lynx_28g_lane_rmw() argument "reg" with "val" and "mask" Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 03/14] phy: lynx-28g: use FIELD_GET() and FIELD_PREP() Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 04/14] phy: lynx-28g: convert iowrite32() calls with magic values to macros Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 05/14] phy: lynx-28g: restructure protocol configuration register accesses Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 06/14] phy: lynx-28g: make lynx_28g_set_lane_mode() more systematic Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 07/14] phy: lynx-28g: refactor lane->interface to lane->mode Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 08/14] phy: lynx-28g: distinguish between 10GBASE-R and USXGMII Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 09/14] phy: lynx-28g: configure more equalization params for 1GbE and 10GbE Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 10/14] phy: lynx-28g: add support for 25GBASER Vladimir Oltean
2025-09-04 15:43 ` [PATCH phy 11/14] phy: lynx-28g: truly power the lanes up or down Vladimir Oltean
2025-09-04 15:44 ` [PATCH phy 12/14] phy: lynx-28g: implement phy_exit() operation Vladimir Oltean
2025-09-04 15:44 ` [PATCH phy 13/14] dt-bindings: phy: lynx-28g: add compatible strings per SerDes and instantiation Vladimir Oltean
2025-09-04 19:22   ` Conor Dooley
2025-09-05 10:49     ` Vladimir Oltean
2025-09-05 11:10       ` Josua Mayer
2025-09-05 11:37         ` Vladimir Oltean
2025-09-05 14:23           ` Josua Mayer
2025-09-05 14:44             ` Josua Mayer
2025-09-05 15:29               ` Vladimir Oltean
2025-09-05 15:50                 ` Josua Mayer
2025-09-09 11:37                   ` Vladimir Oltean
2025-09-05 18:58       ` Conor Dooley
2025-09-05  8:29   ` Krzysztof Kozlowski
2025-09-05 11:02     ` Vladimir Oltean
2025-09-05 15:41     ` Vladimir Oltean
2025-09-05 19:02       ` Conor Dooley
2025-09-08  9:37         ` Vladimir Oltean
2025-09-08 14:02           ` Josua Mayer
2025-09-08 15:37             ` Vladimir Oltean
2025-09-08 16:04               ` Josua Mayer
2025-09-09 11:35                 ` Vladimir Oltean
2025-09-09 18:35                   ` Conor Dooley
2025-09-09 18:58                     ` Vladimir Oltean
2025-09-16 17:07                   ` Vladimir Oltean
2025-09-17 10:47                   ` Josua Mayer
2025-09-08 18:39             ` Conor Dooley
2025-09-04 15:44 ` Vladimir Oltean [this message]
2025-09-05 10:41   ` [PATCH phy 14/14] phy: lynx-28g: probe on per-SoC and per-instance compatible strings Ioana Ciornei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250904154402.300032-15-vladimir.oltean@nxp.com \
    --to=vladimir.oltean@nxp.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=ioana.ciornei@nxp.com \
    --cc=kishon@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=robh@kernel.org \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox