From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
To: robh+dt@kernel.org, andrew@lunn.ch, f.fainelli@gmail.com,
linux-amlogic@lists.infradead.org, devicetree@vger.kernel.org
Cc: jianxin.pan@amlogic.com, davem@davemloft.net,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Subject: [PATCH RFC v2 08/11] net: stmmac: dwmac-meson8b: add support for the RX delay configuration
Date: Wed, 29 Apr 2020 22:16:41 +0200 [thread overview]
Message-ID: <20200429201644.1144546-9-martin.blumenstingl@googlemail.com> (raw)
In-Reply-To: <20200429201644.1144546-1-martin.blumenstingl@googlemail.com>
Configure the PRG_ETH0_ADJ_* bits to enable or disable the RX delay
based on the various RGMII PHY modes. For now the only supported RX
delay settings are:
- disabled, use for example for phy-mode "rgmii-id"
- 0ns - this is treated identical to "disabled", used for example on
boards where the PHY provides 2ns TX delay and the PCB trace length
already adds 2ns RX delay
- 2ns - for whenever the PHY cannot add the RX delay and the traces on
the PCB don't add any RX delay
Disabling the RX delay (in case u-boot enables it, which is the case
for example on Meson8b Odroid-C1) simply means that PRG_ETH0_ADJ_ENABLE,
PRG_ETH0_ADJ_SETUP, PRG_ETH0_ADJ_DELAY and PRG_ETH0_ADJ_SKEW should be
disabled (just disabling PRG_ETH0_ADJ_ENABLE may be enough, since that
disables the whole re-timing logic - but I find it makes more sense to
clear the other bits as well since they depend on that setting).
u-boot on Odroid-C1 uses the following steps to enable a 2ns RX delay:
- enabling enabling the timing adjustment clock
- enabling the timing adjustment logic by setting PRG_ETH0_ADJ_ENABLE
- setting the PRG_ETH0_ADJ_SETUP bit
The documentation for the PRG_ETH0_ADJ_DELAY and PRG_ETH0_ADJ_SKEW
registers indicates that we can even set different RX delays. However,
I could not find out how this works exactly, so for now we only support
a 2ns RX delay using the exact same way that Odroid-C1's u-boot does.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
.../ethernet/stmicro/stmmac/dwmac-meson8b.c | 79 +++++++++++++------
1 file changed, 56 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index d31f79c455de..73c84108d65b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -85,6 +85,7 @@ struct meson8b_dwmac {
phy_interface_t phy_mode;
struct clk *rgmii_tx_clk;
u32 tx_delay_ns;
+ u32 rx_delay_ns;
struct clk *timing_adj_clk;
};
@@ -284,25 +285,58 @@ static int meson8b_devm_clk_prepare_enable(struct meson8b_dwmac *dwmac,
static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
{
+ u32 tx_dly_config, rx_dly_config, delay_config;
int ret;
- u8 tx_dly_val = 0;
+
+ tx_dly_config = FIELD_PREP(PRG_ETH0_TXDLY_MASK,
+ dwmac->tx_delay_ns >> 1);
+
+ if (dwmac->rx_delay_ns == 2)
+ rx_dly_config = PRG_ETH0_ADJ_ENABLE | PRG_ETH0_ADJ_SETUP;
+ else
+ rx_dly_config = 0;
switch (dwmac->phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
+ delay_config = tx_dly_config | rx_dly_config;
+ break;
case PHY_INTERFACE_MODE_RGMII_RXID:
- tx_dly_val = dwmac->tx_delay_ns >> 1;
- /* fall through */
-
- case PHY_INTERFACE_MODE_RGMII_ID:
+ delay_config = tx_dly_config;
+ break;
case PHY_INTERFACE_MODE_RGMII_TXID:
+ delay_config = rx_dly_config;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RMII:
+ delay_config = 0;
+ break;
+ default:
+ dev_err(dwmac->dev, "unsupported phy-mode %s\n",
+ phy_modes(dwmac->phy_mode));
+ return -EINVAL;
+ };
+
+ if (rx_dly_config & PRG_ETH0_ADJ_ENABLE) {
+ /* The timing adjustment logic is driven by a separate clock */
+ ret = meson8b_devm_clk_prepare_enable(dwmac,
+ dwmac->timing_adj_clk);
+ if (ret) {
+ dev_err(dwmac->dev,
+ "Failed to enable the timing-adjustment clock\n");
+ return ret;
+ }
+ }
+
+ 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,
+ delay_config);
+
+ if (phy_interface_mode_is_rgmii(dwmac->phy_mode)) {
/* only relevant for RMII mode -> disable in RGMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
PRG_ETH0_INVERTED_RMII_CLK, 0);
- meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
- FIELD_PREP(PRG_ETH0_TXDLY_MASK,
- tx_dly_val));
-
/* Configure the 125MHz RGMII TX clock, the IP block changes
* the output automatically (= without us having to configure
* a register) based on the line-speed (125MHz for Gbit speeds,
@@ -322,24 +356,11 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
"failed to enable the RGMII TX clock\n");
return ret;
}
- break;
-
- case PHY_INTERFACE_MODE_RMII:
+ } else {
/* invert internal clk_rmii_i to generate 25/2.5 tx_rx_clk */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
PRG_ETH0_INVERTED_RMII_CLK,
PRG_ETH0_INVERTED_RMII_CLK);
-
- /* TX clock delay cannot be configured in RMII mode */
- meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
- 0);
-
- break;
-
- default:
- dev_err(dwmac->dev, "unsupported phy-mode %s\n",
- phy_modes(dwmac->phy_mode));
- return -EINVAL;
}
/* enable TX_CLK and PHY_REF_CLK generator */
@@ -394,6 +415,18 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
&dwmac->tx_delay_ns))
dwmac->tx_delay_ns = 2;
+ /* use 0ns as fallback since this is what most boards actually use */
+ if (of_property_read_u32(pdev->dev.of_node, "amlogic,rx-delay-ns",
+ &dwmac->rx_delay_ns))
+ dwmac->rx_delay_ns = 0;
+
+ if (dwmac->rx_delay_ns != 0 && dwmac->rx_delay_ns != 2) {
+ dev_err(&pdev->dev,
+ "The only allowed RX delays values are: 0ns, 2ns");
+ ret = -EINVAL;
+ goto err_remove_config_dt;
+ }
+
dwmac->timing_adj_clk = devm_clk_get_optional(dwmac->dev,
"timing-adjustment");
if (IS_ERR(dwmac->timing_adj_clk)) {
--
2.26.2
next prev parent reply other threads:[~2020-04-29 20:17 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-29 20:16 [PATCH RFC v2 00/11] dwmac-meson8b Ethernet RX delay configuration Martin Blumenstingl
2020-04-29 20:16 ` [PATCH RFC v2 01/11] dt-bindings: net: meson-dwmac: Add the amlogic,rx-delay-ns property Martin Blumenstingl
2020-05-01 15:26 ` Andrew Lunn
2020-05-12 14:51 ` Rob Herring
2020-04-29 20:16 ` [PATCH RFC v2 02/11] dt-bindings: net: dwmac-meson: Document the "timing-adjustment" clock Martin Blumenstingl
2020-05-01 15:27 ` Andrew Lunn
2020-05-01 21:09 ` Rob Herring
2020-05-01 21:53 ` Martin Blumenstingl
2020-05-10 22:34 ` Martin Blumenstingl
2020-04-29 20:16 ` [PATCH RFC v2 03/11] net: stmmac: dwmac-meson8b: use FIELD_PREP instead of open-coding it Martin Blumenstingl
2020-05-01 15:28 ` Andrew Lunn
2020-04-29 20:16 ` [PATCH RFC v2 04/11] net: stmmac: dwmac-meson8b: Move the documentation for the TX delay Martin Blumenstingl
2020-05-01 15:29 ` Andrew Lunn
2020-04-29 20:16 ` [PATCH RFC v2 05/11] net: stmmac: dwmac-meson8b: Add the PRG_ETH0_ADJ_* bits Martin Blumenstingl
2020-05-01 15:33 ` Andrew Lunn
2020-04-29 20:16 ` [PATCH RFC v2 06/11] net: stmmac: dwmac-meson8b: Fetch the "timing-adjustment" clock Martin Blumenstingl
2020-05-01 15:35 ` Andrew Lunn
2020-04-29 20:16 ` [PATCH RFC v2 07/11] net: stmmac: dwmac-meson8b: Make the clock enabling code re-usable Martin Blumenstingl
2020-05-01 15:37 ` Andrew Lunn
2020-04-29 20:16 ` Martin Blumenstingl [this message]
2020-05-01 15:44 ` [PATCH RFC v2 08/11] net: stmmac: dwmac-meson8b: add support for the RX delay configuration Andrew Lunn
2020-05-01 17:10 ` Martin Blumenstingl
2020-04-29 20:16 ` [PATCH DO NOT MERGE v2 09/11] arm64: dts: amlogic: Add the Ethernet "timing-adjustment" clock Martin Blumenstingl
2020-04-29 20:16 ` [PATCH DO NOT MERGE v2 10/11] ARM: dts: meson: " Martin Blumenstingl
2020-04-29 20:16 ` [PATCH DO NOT MERGE v2 11/11] ARM: dts: meson: Switch existing boards with RGMII PHY to "rgmii-id" Martin Blumenstingl
2020-04-29 21:29 ` [PATCH RFC v2 00/11] dwmac-meson8b Ethernet RX delay configuration Andrew Lunn
2020-05-01 14:49 ` 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=20200429201644.1144546-9-martin.blumenstingl@googlemail.com \
--to=martin.blumenstingl@googlemail.com \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=f.fainelli@gmail.com \
--cc=jianxin.pan@amlogic.com \
--cc=linux-amlogic@lists.infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=robh+dt@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;
as well as URLs for NNTP newsgroup(s).