Commit 8d347992 authored by David S. Miller's avatar David S. Miller

Merge branch 'RTL8211F-RGMII-RX-TX-delay-configuration-improvements'

Martin Blumenstingl says:

====================
RTL8211F: RGMII RX/TX delay configuration improvements

In discussion with Andrew [0] we figured out that it would be best to
make the RX delay of the RTL8211F PHY configurable (just like the TX
delay is already configurable).

While here I took the opportunity to add some logging to the TX delay
configuration as well.

There is no public documentation for the RX and TX delay registers.
I received this information a while ago (and created this RfC patch
back then: [1]). Realtek gave me permission to take the information
from the datasheet extracts and phase them in my own words and publish
that (I am not allowed to publish the datasheet extracts).

I have tested these patches on two boards:
- Amlogic Meson8b Odroid-C1
- Amlogic GXM Khadas VIM2
Both still behave as before these changes (iperf3 speeds are the same
in both directions: RX and TX), which is expected because they are
currently using phy-mode = "rgmii" with the RX delay not being generated
by the PHY.

[0] https://patchwork.ozlabs.org/patch/1215313/
[1] https://patchwork.ozlabs.org/patch/843946/
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1f4f16fa 1b3047b5
......@@ -29,6 +29,8 @@
#define RTL8211F_INSR 0x1d
#define RTL8211F_TX_DELAY BIT(8)
#define RTL8211F_RX_DELAY BIT(3)
#define RTL8211E_TX_DELAY BIT(1)
#define RTL8211E_RX_DELAY BIT(2)
#define RTL8211E_MODE_MII_GMII BIT(3)
......@@ -171,25 +173,66 @@ static int rtl8211c_config_init(struct phy_device *phydev)
static int rtl8211f_config_init(struct phy_device *phydev)
{
u16 val;
struct device *dev = &phydev->mdio.dev;
u16 val_txdly, val_rxdly;
int ret;
/* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and
* rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin.
*/
switch (phydev->interface) {
case PHY_INTERFACE_MODE_RGMII:
val_txdly = 0;
val_rxdly = 0;
break;
case PHY_INTERFACE_MODE_RGMII_RXID:
val = 0;
val_txdly = 0;
val_rxdly = RTL8211F_RX_DELAY;
break;
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_TXID:
val = RTL8211F_TX_DELAY;
val_txdly = RTL8211F_TX_DELAY;
val_rxdly = 0;
break;
case PHY_INTERFACE_MODE_RGMII_ID:
val_txdly = RTL8211F_TX_DELAY;
val_rxdly = RTL8211F_RX_DELAY;
break;
default: /* the rest of the modes imply leaving delay as is. */
return 0;
}
return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val);
ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
val_txdly);
if (ret < 0) {
dev_err(dev, "Failed to update the TX delay register\n");
return ret;
} else if (ret) {
dev_dbg(dev,
"%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
val_txdly ? "Enabling" : "Disabling");
} else {
dev_dbg(dev,
"2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
val_txdly ? "enabled" : "disabled");
}
ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
val_rxdly);
if (ret < 0) {
dev_err(dev, "Failed to update the RX delay register\n");
return ret;
} else if (ret) {
dev_dbg(dev,
"%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
val_rxdly ? "Enabling" : "Disabling");
} else {
dev_dbg(dev,
"2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
val_rxdly ? "enabled" : "disabled");
}
return 0;
}
static int rtl8211e_config_init(struct phy_device *phydev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment