[PATCH v3 1/2] phy: mv88e61xx: add support for RGMII TX/RX delay
Pawel Dembicki
paweldembicki at gmail.com
Mon Jan 4 22:28:24 CET 2021
Clock delay in RGMII is required for some boards.
Clock delay is read from phy-mode dts property. Delay is configured via
proper bits in PORT_REG_PHYS_CTRL register.
Cc: Chris Packham <judge.packham at gmail.com>
Cc: Joe Hershberger <joe.hershberger at ni.com>
Cc: Anatolij Gustschin <agust at denx.de>
Cc: Tim Harvey <tharvey at gateworks.com>
Cc: Tom Rini <trini at konsulko.com>
Signed-off-by: Pawel Dembicki <paweldembicki at gmail.com>
---
Changes in v3:
- clear initial values of RX and TX delay bit
Changes in v2:
- change source info about delay: from hardcode to phy-mode propoperty in dts
drivers/net/phy/mv88e61xx.c | 66 ++++++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c
index 7eff37b244..3bcd2ba242 100644
--- a/drivers/net/phy/mv88e61xx.c
+++ b/drivers/net/phy/mv88e61xx.c
@@ -97,6 +97,8 @@
#define PORT_REG_STATUS_CMODE_1000BASE_X 0x9
#define PORT_REG_STATUS_CMODE_SGMII 0xa
+#define PORT_REG_PHYS_CTRL_RGMII_RX_DELAY BIT(15)
+#define PORT_REG_PHYS_CTRL_RGMII_TX_DELAY BIT(14)
#define PORT_REG_PHYS_CTRL_PCS_AN_EN BIT(10)
#define PORT_REG_PHYS_CTRL_PCS_AN_RST BIT(9)
#define PORT_REG_PHYS_CTRL_FC_VALUE BIT(7)
@@ -729,7 +731,45 @@ unforce:
static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)
{
struct mv88e61xx_phy_priv *priv = phydev->priv;
- int val;
+ ofnode node;
+ const char *str;
+ int val, phy_mode;
+ u32 phy_handle;
+
+ if (!ofnode_valid(phydev->node)) {
+ node = dev_ofnode(phydev->dev);
+ phy_handle = ofnode_read_u32_default(node, "phy-handle", -ENXIO);
+
+ if (phy_handle == -ENXIO) {
+ node = ofnode_first_subnode(node);
+
+ while (ofnode_valid(node)) {
+ phy_handle = ofnode_read_u32_default(node, "phy-handle", -ENXIO);
+ if (phy_handle != -ENXIO)
+ break;
+ node = ofnode_next_subnode(node);
+ }
+ }
+
+ if (phy_handle != -ENXIO)
+ node = ofnode_get_by_phandle(phy_handle);
+ else
+ node = ofnode_null();
+ } else {
+ node = phy_get_ofnode(phydev);
+ }
+
+ node = ofnode_find_subnode(node, "ports");
+ node = ofnode_first_subnode(node);
+
+ while (ofnode_valid(node)) {
+ u8 port_no = (u8)ofnode_read_u32_default(node, "reg", -1);
+
+ if (port_no == port)
+ break;
+
+ node = ofnode_next_subnode(node);
+ }
val = mv88e61xx_port_read(phydev, port, PORT_REG_PHYS_CTRL);
if (val < 0)
@@ -754,6 +794,30 @@ static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)
val |= PORT_REG_PHYS_CTRL_LINK_VALUE |
PORT_REG_PHYS_CTRL_LINK_FORCE;
+ if (ofnode_valid(node)) {
+ str = ofnode_read_string(node, "phy-mode");
+ if (str) {
+ phy_mode = phy_get_interface_by_name(str);
+ val &= ~(PORT_REG_PHYS_CTRL_RGMII_RX_DELAY |
+ PORT_REG_PHYS_CTRL_RGMII_TX_DELAY);
+
+ switch (phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ val |= PORT_REG_PHYS_CTRL_RGMII_RX_DELAY;
+ val |= PORT_REG_PHYS_CTRL_RGMII_TX_DELAY;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ val |= PORT_REG_PHYS_CTRL_RGMII_RX_DELAY;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ val |= PORT_REG_PHYS_CTRL_RGMII_TX_DELAY;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
return mv88e61xx_port_write(phydev, port, PORT_REG_PHYS_CTRL,
val);
}
--
2.25.1
More information about the U-Boot
mailing list