[PATCH v3 1/2] phy: mv88e61xx: add support for RGMII TX/RX delay

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@gmail.com Cc: Joe Hershberger joe.hershberger@ni.com Cc: Anatolij Gustschin agust@denx.de Cc: Tim Harvey tharvey@gateworks.com Cc: Tom Rini trini@konsulko.com Signed-off-by: Pawel Dembicki paweldembicki@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); }

This patch add MV88E6171 id to driver data.
Tested on Checkpoint L-50 board.
Cc: Chris Packham judge.packham@gmail.com Cc: Joe Hershberger joe.hershberger@ni.com Cc: Anatolij Gustschin agust@denx.de Cc: Tim Harvey tharvey@gateworks.com Signed-off-by: Pawel Dembicki paweldembicki@gmail.com --- Changes in v3,v2: - resend only drivers/net/phy/mv88e61xx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c index 3bcd2ba242..82f1587ff5 100644 --- a/drivers/net/phy/mv88e61xx.c +++ b/drivers/net/phy/mv88e61xx.c @@ -183,6 +183,7 @@ #define PORT_SWITCH_ID_6071 0x0710 #define PORT_SWITCH_ID_6096 0x0980 #define PORT_SWITCH_ID_6097 0x0990 +#define PORT_SWITCH_ID_6171 0x1710 #define PORT_SWITCH_ID_6172 0x1720 #define PORT_SWITCH_ID_6176 0x1760 #define PORT_SWITCH_ID_6220 0x2200 @@ -1055,6 +1056,7 @@ static int mv88e61xx_probe(struct phy_device *phydev) switch (priv->id) { case PORT_SWITCH_ID_6096: case PORT_SWITCH_ID_6097: + case PORT_SWITCH_ID_6171: case PORT_SWITCH_ID_6172: case PORT_SWITCH_ID_6176: case PORT_SWITCH_ID_6240: @@ -1210,6 +1212,17 @@ static struct phy_driver mv88e61xx_driver = { .shutdown = &genphy_shutdown, };
+static struct phy_driver mv88e617x_driver = { + .name = "Marvell MV88E617x", + .uid = 0x01410e70, + .mask = 0xfffffff0, + .features = PHY_GBIT_FEATURES, + .probe = mv88e61xx_probe, + .config = mv88e61xx_phy_config, + .startup = mv88e61xx_phy_startup, + .shutdown = &genphy_shutdown, +}; + static struct phy_driver mv88e609x_driver = { .name = "Marvell MV88E609x", .uid = 0x1410c89, @@ -1235,6 +1248,7 @@ static struct phy_driver mv88e6071_driver = { int phy_mv88e61xx_init(void) { phy_register(&mv88e61xx_driver); + phy_register(&mv88e617x_driver); phy_register(&mv88e609x_driver); phy_register(&mv88e6071_driver);

On Tue, 5 Jan 2021, 10:28 AM Pawel Dembicki, paweldembicki@gmail.com wrote:
This patch add MV88E6171 id to driver data.
Tested on Checkpoint L-50 board.
Cc: Chris Packham judge.packham@gmail.com Cc: Joe Hershberger joe.hershberger@ni.com Cc: Anatolij Gustschin agust@denx.de Cc: Tim Harvey tharvey@gateworks.com Signed-off-by: Pawel Dembicki paweldembicki@gmail.com
Looks good to me.
Reviewed-by: Chris Packham judge.packham@gmail.com
---
Changes in v3,v2:
- resend only
drivers/net/phy/mv88e61xx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c index 3bcd2ba242..82f1587ff5 100644 --- a/drivers/net/phy/mv88e61xx.c +++ b/drivers/net/phy/mv88e61xx.c @@ -183,6 +183,7 @@ #define PORT_SWITCH_ID_6071 0x0710 #define PORT_SWITCH_ID_6096 0x0980 #define PORT_SWITCH_ID_6097 0x0990 +#define PORT_SWITCH_ID_6171 0x1710 #define PORT_SWITCH_ID_6172 0x1720 #define PORT_SWITCH_ID_6176 0x1760 #define PORT_SWITCH_ID_6220 0x2200 @@ -1055,6 +1056,7 @@ static int mv88e61xx_probe(struct phy_device *phydev) switch (priv->id) { case PORT_SWITCH_ID_6096: case PORT_SWITCH_ID_6097:
case PORT_SWITCH_ID_6171: case PORT_SWITCH_ID_6172: case PORT_SWITCH_ID_6176: case PORT_SWITCH_ID_6240:
@@ -1210,6 +1212,17 @@ static struct phy_driver mv88e61xx_driver = { .shutdown = &genphy_shutdown, };
+static struct phy_driver mv88e617x_driver = {
.name = "Marvell MV88E617x",
.uid = 0x01410e70,
.mask = 0xfffffff0,
.features = PHY_GBIT_FEATURES,
.probe = mv88e61xx_probe,
.config = mv88e61xx_phy_config,
.startup = mv88e61xx_phy_startup,
.shutdown = &genphy_shutdown,
+};
static struct phy_driver mv88e609x_driver = { .name = "Marvell MV88E609x", .uid = 0x1410c89, @@ -1235,6 +1248,7 @@ static struct phy_driver mv88e6071_driver = { int phy_mv88e61xx_init(void) { phy_register(&mv88e61xx_driver);
phy_register(&mv88e617x_driver); phy_register(&mv88e609x_driver); phy_register(&mv88e6071_driver);
-- 2.25.1

On Tue, 5 Jan 2021, 10:28 AM Pawel Dembicki, paweldembicki@gmail.com wrote:
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@gmail.com Cc: Joe Hershberger joe.hershberger@ni.com Cc: Anatolij Gustschin agust@denx.de Cc: Tim Harvey tharvey@gateworks.com Cc: Tom Rini trini@konsulko.com Signed-off-by: Pawel Dembicki paweldembicki@gmail.com
Looks good to me.
Reviewed-by: Chris Packham judge.packham@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
participants (2)
-
Chris Packham
-
Pawel Dembicki