From: Lucas Tanure <tanure@linux.com>
To: xianwei.zhao@amlogic.com, Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
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>,
Neil Armstrong <neil.armstrong@linaro.org>,
Kevin Hilman <khilman@baylibre.com>,
Jerome Brunet <jbrunet@baylibre.com>,
Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
Maxime Chevallier <maxime.chevallier@bootlin.com>,
Maxime Coquelin <mcoquelin.stm32@gmail.com>,
Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: netdev@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 4/8] net: stmmac: dwmac-meson8b: apply the RGMII delays the T7 way
Date: Sat, 10 Oct 2026 11:58:56 +0100 [thread overview]
Message-ID: <20261010105900.247342-5-tanure@linux.com> (raw)
In-Reply-To: <20261010105900.247342-1-tanure@linux.com>
RGMII needs a delay on each of its two clocks. phy-mode says whether
the board provides them with longer traces, and the generic
tx-internal-delay-ps and rx-internal-delay-ps properties say this
controller provides them. Whatever is left is the PHY's job.
The existing code reads phy-mode as naming the chip that adds the
delay, which is the opposite, and it ignores both properties. Changing
it would change every board already relying on it, so the T7 gets a
path of its own and the rest stays as it is.
Assisted-by: LLM
Signed-off-by: Lucas Tanure <tanure@linux.com>
---
.../ethernet/stmicro/stmmac/dwmac-meson8b.c | 103 +++++++++++++-----
1 file changed, 76 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 450f7b4b29a6..1861a0d45b2d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -82,6 +82,7 @@ struct meson8b_dwmac_data {
int (*set_phy_mode)(struct meson8b_dwmac *dwmac);
bool has_prg_eth1_rgmii_rx_delay;
bool has_pipeline_clk;
+ bool mac_applies_dt_delays;
};
struct meson8b_dwmac {
@@ -272,6 +273,49 @@ static int meson8b_devm_clk_prepare_enable(struct meson8b_dwmac *dwmac,
meson8b_clk_disable_unprepare, clk);
}
+static int meson_dwmac_init_dt_delays(struct meson8b_dwmac *dwmac,
+ struct plat_stmmacenet_data *plat_dat)
+{
+ struct device_node *np = dwmac->dev->of_node;
+ u32 tx_delay_ps = 0, rx_delay_ps = 0;
+ phy_interface_t phy_mode;
+ bool mac_tx, mac_rx;
+
+ mac_tx = !of_property_read_u32(np, "tx-internal-delay-ps", &tx_delay_ps);
+ mac_rx = !of_property_read_u32(np, "rx-internal-delay-ps", &rx_delay_ps);
+
+ /* one step is a quarter of the RGMII clock period, 2ns at 1Gbit/s */
+ if (tx_delay_ps > 6000 || tx_delay_ps % 2000)
+ return dev_err_probe(dwmac->dev, -EINVAL,
+ "The RGMII TX delay must be 0, 2000, 4000 or 6000ps\n");
+
+ /* the RX delay line moves in 200ps steps and reaches 3000ps */
+ if (rx_delay_ps > 3000 || rx_delay_ps % 200)
+ return dev_err_probe(dwmac->dev, -EINVAL,
+ "The RGMII RX delay range is 0..3000ps in 200ps steps\n");
+
+ phy_mode = phy_fix_phy_mode_for_mac_delays(dwmac->phy_mode, mac_tx,
+ mac_rx);
+ if (phy_mode == PHY_INTERFACE_MODE_NA)
+ return dev_err_probe(dwmac->dev, -EINVAL,
+ "Cannot provide the delays %s asks for\n",
+ phy_modes(dwmac->phy_mode));
+
+ plat_dat->phy_interface = phy_mode;
+
+ meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK |
+ PRG_ETH0_ADJ_ENABLE | PRG_ETH0_ADJ_SETUP |
+ PRG_ETH0_ADJ_DELAY | PRG_ETH0_ADJ_SKEW,
+ FIELD_PREP(PRG_ETH0_TXDLY_MASK,
+ tx_delay_ps / 2000));
+
+ meson8b_dwmac_mask_bits(dwmac, PRG_ETH1, PRG_ETH1_CFG_RXCLK_DLY,
+ FIELD_PREP(PRG_ETH1_CFG_RXCLK_DLY,
+ rx_delay_ps / 200));
+
+ return 0;
+}
+
static int meson8b_init_rgmii_delays(struct meson8b_dwmac *dwmac)
{
u32 tx_dly_config, rx_adj_config, cfg_rxclk_dly, delay_config;
@@ -411,32 +455,34 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
dwmac->dev = &pdev->dev;
dwmac->phy_mode = plat_dat->phy_interface;
- /* use 2ns as fallback since this value was previously hardcoded */
- if (of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns",
- &dwmac->tx_delay_ns))
- dwmac->tx_delay_ns = 2;
-
- /* RX delay defaults to 0ps since this is what many boards use */
- if (of_property_read_u32(pdev->dev.of_node, "rx-internal-delay-ps",
- &dwmac->rx_delay_ps)) {
- if (!of_property_read_u32(pdev->dev.of_node,
- "amlogic,rx-delay-ns",
- &dwmac->rx_delay_ps))
- /* convert ns to ps */
- dwmac->rx_delay_ps *= 1000;
- }
-
- if (dwmac->data->has_prg_eth1_rgmii_rx_delay) {
- if (dwmac->rx_delay_ps > 3000 || dwmac->rx_delay_ps % 200) {
- dev_err(dwmac->dev,
- "The RGMII RX delay range is 0..3000ps in 200ps steps");
- return -EINVAL;
+ if (!dwmac->data->mac_applies_dt_delays) {
+ /* use 2ns as fallback since this value was previously hardcoded */
+ if (of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns",
+ &dwmac->tx_delay_ns))
+ dwmac->tx_delay_ns = 2;
+
+ /* RX delay defaults to 0ps since this is what many boards use */
+ if (of_property_read_u32(pdev->dev.of_node, "rx-internal-delay-ps",
+ &dwmac->rx_delay_ps)) {
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "amlogic,rx-delay-ns",
+ &dwmac->rx_delay_ps))
+ /* convert ns to ps */
+ dwmac->rx_delay_ps *= 1000;
}
- } else {
- if (dwmac->rx_delay_ps != 0 && dwmac->rx_delay_ps != 2000) {
- dev_err(dwmac->dev,
- "The only allowed RGMII RX delays values are: 0ps, 2000ps");
- return -EINVAL;
+
+ if (dwmac->data->has_prg_eth1_rgmii_rx_delay) {
+ if (dwmac->rx_delay_ps > 3000 || dwmac->rx_delay_ps % 200) {
+ dev_err(dwmac->dev,
+ "The RGMII RX delay range is 0..3000ps in 200ps steps");
+ return -EINVAL;
+ }
+ } else {
+ if (dwmac->rx_delay_ps != 0 && dwmac->rx_delay_ps != 2000) {
+ dev_err(dwmac->dev,
+ "The only allowed RGMII RX delays values are: 0ps, 2000ps");
+ return -EINVAL;
+ }
}
}
@@ -452,7 +498,10 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
"missing pipeline clock\n");
}
- ret = meson8b_init_rgmii_delays(dwmac);
+ if (dwmac->data->mac_applies_dt_delays)
+ ret = meson_dwmac_init_dt_delays(dwmac, plat_dat);
+ else
+ ret = meson8b_init_rgmii_delays(dwmac);
if (ret)
return ret;
@@ -490,8 +539,8 @@ static const struct meson8b_dwmac_data meson_g12a_dwmac_data = {
static const struct meson8b_dwmac_data meson_t7_dwmac_data = {
.set_phy_mode = meson_axg_set_phy_mode,
- .has_prg_eth1_rgmii_rx_delay = true,
.has_pipeline_clk = true,
+ .mac_applies_dt_delays = true,
};
static const struct of_device_id meson8b_dwmac_match[] = {
--
2.56.0
next prev parent reply other threads:[~2026-10-10 10:59 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-10 10:58 [PATCH v3 0/8] Add ethernet support for the Amlogic T7 Lucas Tanure
2026-10-10 10:58 ` [PATCH v3 1/8] dt-bindings: net: amlogic,meson-dwmac: list the compatible combinations Lucas Tanure
2026-10-10 22:04 ` Martin Blumenstingl
2026-10-10 10:58 ` [PATCH v3 2/8] dt-bindings: net: amlogic,meson-dwmac: add amlogic,t7-dwmac Lucas Tanure
2026-10-10 22:14 ` Martin Blumenstingl
2026-10-10 10:58 ` [PATCH v3 3/8] net: stmmac: dwmac-meson8b: add support for the Amlogic T7 Lucas Tanure
2026-10-10 22:40 ` Martin Blumenstingl
2026-10-10 10:58 ` Lucas Tanure [this message]
2026-10-10 21:49 ` [PATCH v3 4/8] net: stmmac: dwmac-meson8b: apply the RGMII delays the T7 way Martin Blumenstingl
2026-10-10 10:58 ` [PATCH v3 5/8] arm64: dts: amlogic: t7: add the ethernet pinctrl nodes Lucas Tanure
2026-10-10 10:58 ` [PATCH v3 6/8] arm64: dts: amlogic: t7: add the ethernet controller Lucas Tanure
2026-10-10 10:58 ` [PATCH v3 7/8] arm64: dts: amlogic: t7: khadas-vim4: enable the ethernet port Lucas Tanure
2026-10-10 22:00 ` Martin Blumenstingl
2026-10-10 10:59 ` [PATCH v3 8/8] dt-bindings: net: ethernet-controller: tabulate who adds the RGMII delays Lucas Tanure
2026-10-10 22:37 ` Martin Blumenstingl
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=20261010105900.247342-5-tanure@linux.com \
--to=tanure@linux.com \
--cc=alexandre.torgue@foss.st.com \
--cc=andrew+netdev@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@kernel.org \
--cc=jbrunet@baylibre.com \
--cc=khilman@baylibre.com \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-amlogic@lists.infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.blumenstingl@googlemail.com \
--cc=maxime.chevallier@bootlin.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=neil.armstrong@linaro.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=robh@kernel.org \
--cc=xianwei.zhao@amlogic.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