devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jacky Chou <jacky_chou@aspeedtech.com>
To: Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Po-Yu Chuang <ratbert@faraday-tech.com>,
	Joel Stanley <joel@jms.id.au>,
	Andrew Jeffery <andrew@codeconstruct.com.au>
Cc: <netdev@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-aspeed@lists.ozlabs.org>, <taoren@meta.com>,
	Jacky Chou <jacky_chou@aspeedtech.com>
Subject: [PATCH net-next v4 4/4] net: ftgmac100: Add RGMII delay support for AST2600
Date: Mon, 10 Nov 2025 19:09:28 +0800	[thread overview]
Message-ID: <20251110-rgmii_delay_2600-v4-4-5cad32c766f7@aspeedtech.com> (raw)
In-Reply-To: <20251110-rgmii_delay_2600-v4-0-5cad32c766f7@aspeedtech.com>

On the AST2600 platform, the RGMII delay is controlled via the
SCU registers. The delay chain configuration differs between MAC0/1
and MAC2/3, even though all four MACs use a 32-stage delay chain.
+------+----------+-----------+-------------+-------------+
|      |Delay Unit|Delay Stage|TX Edge Stage|RX Edge Stage|
+------+----------+-----------+-------------+-------------+
|MAC0/1|     45 ps|        32 |           0 |           0 |
+------+----------+-----------+-------------+-------------+
|MAC2/3|    250 ps|        32 |           0 |          26 |
+------+----------+-----------+-------------+-------------+
For MAC2/3, the "no delay" condition starts from stage 26.
Setting the RX delay stage to 26 means that no additional RX
delay is applied.
Here lists the RX delay setting of MAC2/3 below.
26 -> 0   ns, 27 -> 0.25 ns, ... , 31 -> 1.25 ns,
0  -> 1.5 ns, 1  -> 1.75 ns, ... , 25 -> 7.75 ns

Therefore, we calculate the delay stage from the
rx-internal-delay-ps of MAC2/3 to add 26. If the stage is equel
to or bigger than 32, the delay stage will be mask 0x1f to get
the correct setting.
The delay chain is like a ring for configuration.
Example for the rx-internal-delay-ps of MAC2/3 is 2000 ps,
we will get the delay stage is 2.

Strating to this patch, driver will remind the legacy dts to update the
"phy-mode" to "rgmii-id, and add the corresponding rgmii delay with
"rx-internal-delay-id" and "tx-internal-delay-id".
If lack these properties, driver will configure the default rgmii delay,
that means driver will disable the TX and RX delay in MAC side.

Signed-off-by: Jacky Chou <jacky_chou@aspeedtech.com>
---
 drivers/net/ethernet/faraday/ftgmac100.c | 148 +++++++++++++++++++++++++++++++
 drivers/net/ethernet/faraday/ftgmac100.h |  20 +++++
 2 files changed, 168 insertions(+)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index a863f7841210..5cecdd4583f6 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -26,6 +26,9 @@
 #include <linux/if_vlan.h>
 #include <linux/of_net.h>
 #include <linux/phy_fixed.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/bitfield.h>
 #include <net/ip.h>
 #include <net/ncsi.h>
 
@@ -1833,6 +1836,146 @@ static bool ftgmac100_has_child_node(struct device_node *np, const char *name)
 	return ret;
 }
 
+static int ftgmac100_set_ast2600_rgmii_delay(struct ftgmac100 *priv,
+					     u32 rgmii_tx_delay,
+					     u32 rgmii_rx_delay)
+{
+	struct device *dev = priv->dev;
+	struct device_node *np;
+	u32 rgmii_delay_unit;
+	u32 rx_delay_index;
+	u32 tx_delay_index;
+	struct regmap *scu;
+	int dly_mask;
+	int dly_reg;
+	int mac_id;
+	int ret;
+
+	np = dev->of_node;
+
+	/* Add a warning to notify the existed dts based on AST2600. It is
+	 * recommended to update the dts to add the rx/tx-internal-delay-ps to
+	 * specify the RGMII delay and we recommend using the "rgmii-id" for
+	 * phy-mode property to tell the PHY enables TX/RX internal delay and
+	 * add the corresponding rx/tx-internal-delay-ps properties.
+	 */
+	if (priv->netdev->phydev->interface != PHY_INTERFACE_MODE_RGMII_ID)
+		dev_warn(dev, "Update the phy-mode to 'rgmii-id'.\n");
+
+	scu = syscon_regmap_lookup_by_phandle(np, "aspeed,scu");
+	if (IS_ERR(scu)) {
+		dev_err(dev, "failed to get aspeed,scu");
+		return PTR_ERR(scu);
+	}
+
+	ret = of_property_read_u32(np, "aspeed,rgmii-delay-ps",
+				   &rgmii_delay_unit);
+	if (ret) {
+		dev_err(dev, "failed to get aspeed,rgmii-delay-ps value\n");
+		return -EINVAL;
+	}
+
+	/* According to the register base address to specify the corresponding
+	 * values.
+	 */
+	switch (priv->res->start) {
+	case AST2600_MAC0_BASE_ADDR:
+		mac_id = 0;
+		break;
+	case AST2600_MAC1_BASE_ADDR:
+		mac_id = 1;
+		break;
+	case AST2600_MAC2_BASE_ADDR:
+		mac_id = 2;
+		break;
+	case AST2600_MAC3_BASE_ADDR:
+		mac_id = 3;
+		break;
+	default:
+		dev_err(dev, "Invalid mac base address");
+		return -EINVAL;
+	}
+
+	if (mac_id == 0 || mac_id == 1) {
+		if (rgmii_delay_unit != AST2600_MAC01_CLK_DLY_UNIT) {
+			dev_err(dev, "aspeed,rgmii-delay-ps %u is invalid\n",
+				rgmii_delay_unit);
+			return -EINVAL;
+		}
+		dly_reg = AST2600_MAC01_CLK_DLY;
+	} else {
+		if (rgmii_delay_unit != AST2600_MAC23_CLK_DLY_UNIT) {
+			dev_err(dev, "aspeed,rgmii-delay-ps %u is invalid\n",
+				rgmii_delay_unit);
+			return -EINVAL;
+		}
+		dly_reg = AST2600_MAC23_CLK_DLY;
+	}
+
+	tx_delay_index = DIV_ROUND_CLOSEST(rgmii_tx_delay, rgmii_delay_unit);
+	if (tx_delay_index >= 32) {
+		dev_err(dev, "The %u ps of TX delay is out of range\n",
+			rgmii_tx_delay);
+		return -EINVAL;
+	}
+
+	rx_delay_index = DIV_ROUND_CLOSEST(rgmii_rx_delay, rgmii_delay_unit);
+	if (rx_delay_index >= 32) {
+		dev_err(dev, "The %u ps of RX delay is out of range\n",
+			rgmii_rx_delay);
+		return -EINVAL;
+	}
+
+	/* Due to the hardware design reason, for MAC2/3 on AST2600, the zero
+	 * delay ns on RX is configured by setting value 0x1a.
+	 * List as below:
+	 * 0x1a -> 0   ns, 0x1b -> 0.25 ns, ... , 0x1f -> 1.25 ns,
+	 * 0x00 -> 1.5 ns, 0x01 -> 1.75 ns, ... , 0x19 -> 7.75 ns, 0x1a -> 0 ns
+	 */
+	if (mac_id == 2 || mac_id == 3)
+		rx_delay_index = (AST2600_MAC23_RX_DLY_0_NS + rx_delay_index) &
+				 AST2600_MAC_TX_RX_DLY_MASK;
+
+	if (mac_id == 0 || mac_id == 2) {
+		dly_mask = ASPEED_MAC0_2_TX_DLY | ASPEED_MAC0_2_RX_DLY;
+		tx_delay_index = FIELD_PREP(ASPEED_MAC0_2_TX_DLY, tx_delay_index);
+		rx_delay_index = FIELD_PREP(ASPEED_MAC0_2_RX_DLY, rx_delay_index);
+	} else {
+		dly_mask = ASPEED_MAC1_3_TX_DLY | ASPEED_MAC1_3_RX_DLY;
+		tx_delay_index = FIELD_PREP(ASPEED_MAC1_3_TX_DLY, tx_delay_index);
+		rx_delay_index = FIELD_PREP(ASPEED_MAC1_3_RX_DLY, rx_delay_index);
+	}
+
+	regmap_update_bits(scu, dly_reg, dly_mask, tx_delay_index | rx_delay_index);
+
+	return 0;
+}
+
+static int ftgmac100_set_internal_delay(struct ftgmac100 *priv)
+{
+	struct device_node *np = priv->dev->of_node;
+	u32 rgmii_tx_delay;
+	u32 rgmii_rx_delay;
+	int err;
+
+	if (!(of_device_is_compatible(np, "aspeed,ast2600-mac")))
+		return 0;
+
+	if (of_property_read_u32(np, "tx-internal-delay-ps", &rgmii_tx_delay))
+		/* Default to 0 ps delay */
+		rgmii_tx_delay = 0;
+
+	if (of_property_read_u32(np, "rx-internal-delay-ps", &rgmii_rx_delay))
+		/* Default to 0 ps delay */
+		rgmii_rx_delay = 0;
+
+	err = ftgmac100_set_ast2600_rgmii_delay(priv,
+						rgmii_tx_delay,
+						rgmii_rx_delay);
+
+	return err;
+}
+
 static int ftgmac100_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -2004,6 +2147,11 @@ static int ftgmac100_probe(struct platform_device *pdev)
 		if (of_device_is_compatible(np, "aspeed,ast2600-mac"))
 			iowrite32(FTGMAC100_TM_DEFAULT,
 				  priv->base + FTGMAC100_OFFSET_TM);
+
+		/* Configure RGMII delay if there are the corresponding compatibles */
+		err = ftgmac100_set_internal_delay(priv);
+		if (err)
+			goto err_phy_connect;
 	}
 
 	/* Default ring sizes */
diff --git a/drivers/net/ethernet/faraday/ftgmac100.h b/drivers/net/ethernet/faraday/ftgmac100.h
index 4968f6f0bdbc..d19d44d1b8e0 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.h
+++ b/drivers/net/ethernet/faraday/ftgmac100.h
@@ -271,4 +271,24 @@ struct ftgmac100_rxdes {
 #define FTGMAC100_RXDES1_UDP_CHKSUM_ERR	(1 << 26)
 #define FTGMAC100_RXDES1_IP_CHKSUM_ERR	(1 << 27)
 
+/* Aspeed SCU */
+#define AST2600_MAC01_CLK_DLY	0x340
+#define AST2600_MAC23_CLK_DLY	0x350
+#define AST2600_MAC01_CLK_DLY_UNIT	45	/* ps */
+#define AST2600_MAC01_TX_DLY_0_NS	0
+#define AST2600_MAC01_RX_DLY_0_NS	0
+#define AST2600_MAC23_CLK_DLY_UNIT	250	/* ps */
+#define AST2600_MAC23_TX_DLY_0_NS	0
+#define AST2600_MAC23_RX_DLY_0_NS	0x1a
+#define AST2600_MAC_TX_RX_DLY_MASK	0x1f
+#define ASPEED_MAC0_2_TX_DLY		GENMASK(5, 0)
+#define ASPEED_MAC0_2_RX_DLY		GENMASK(17, 12)
+#define ASPEED_MAC1_3_TX_DLY		GENMASK(11, 6)
+#define ASPEED_MAC1_3_RX_DLY		GENMASK(23, 18)
+
+#define AST2600_MAC0_BASE_ADDR		0x1e660000
+#define AST2600_MAC1_BASE_ADDR		0x1e680000
+#define AST2600_MAC2_BASE_ADDR		0x1e670000
+#define AST2600_MAC3_BASE_ADDR		0x1e690000
+
 #endif /* __FTGMAC100_H */

-- 
2.34.1


  parent reply	other threads:[~2025-11-10 11:10 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-10 11:09 [PATCH net-next v4 0/4] Add AST2600 RGMII delay into ftgmac100 Jacky Chou
2025-11-10 11:09 ` [PATCH net-next v4 1/4] dt-bindings: net: ftgmac100: Add delay properties for AST2600 Jacky Chou
2025-11-10 12:29   ` Rob Herring (Arm)
2025-11-10 15:21   ` Andrew Lunn
2025-11-11  3:09     ` Jacky Chou
2025-11-10 11:09 ` [PATCH net-next v4 2/4] ARM: dts: aspeed-g6: Add scu and rgmii delay value per step for MAC Jacky Chou
2025-11-10 11:09 ` [PATCH net-next v4 3/4] ARM: dts: aspeed: ast2600-evb: Configure RGMII delay " Jacky Chou
2025-11-10 11:09 ` Jacky Chou [this message]
2025-11-10 15:35   ` [PATCH net-next v4 4/4] net: ftgmac100: Add RGMII delay support for AST2600 Andrew Lunn
2025-11-12  3:45     ` Jacky Chou
2025-11-12 13:19       ` Andrew Lunn
2025-11-13 10:40         ` Jacky Chou
2025-11-15 21:46           ` Andrew Lunn
2025-11-10 15:45   ` Andrew Lunn
2025-11-10 14:34 ` [PATCH net-next v4 0/4] Add AST2600 RGMII delay into ftgmac100 Rob Herring (Arm)

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=20251110-rgmii_delay_2600-v4-4-5cad32c766f7@aspeedtech.com \
    --to=jacky_chou@aspeedtech.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=andrew@codeconstruct.com.au \
    --cc=conor+dt@kernel.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=joel@jms.id.au \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-aspeed@lists.ozlabs.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=ratbert@faraday-tech.com \
    --cc=robh@kernel.org \
    --cc=taoren@meta.com \
    /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;
as well as URLs for NNTP newsgroup(s).