Commit 542897d9 authored by Antoine Tenart's avatar Antoine Tenart Committed by David S. Miller

net: mvpp2: initialize the comphy

On some platforms, the comphy is between the MAC GoP and the PHYs. The
mvpp2 driver currently relies on the firmware/bootloader to configure
the comphy. As a comphy driver was added to the generic PHY framework,
this patch uses it in the mvpp2 driver to configure the comphy at boot
time to avoid relying on the bootloader.
Signed-off-by: default avatarAntoine Tenart <antoine.tenart@free-electrons.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9c2cbd47
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/hrtimer.h> #include <linux/hrtimer.h>
#include <linux/ktime.h> #include <linux/ktime.h>
...@@ -861,6 +862,7 @@ struct mvpp2_port { ...@@ -861,6 +862,7 @@ struct mvpp2_port {
phy_interface_t phy_interface; phy_interface_t phy_interface;
struct device_node *phy_node; struct device_node *phy_node;
struct phy *comphy;
unsigned int link; unsigned int link;
unsigned int duplex; unsigned int duplex;
unsigned int speed; unsigned int speed;
...@@ -4420,6 +4422,32 @@ static int mvpp22_gop_init(struct mvpp2_port *port) ...@@ -4420,6 +4422,32 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
return -EINVAL; return -EINVAL;
} }
static int mvpp22_comphy_init(struct mvpp2_port *port)
{
enum phy_mode mode;
int ret;
if (!port->comphy)
return 0;
switch (port->phy_interface) {
case PHY_INTERFACE_MODE_SGMII:
mode = PHY_MODE_SGMII;
break;
case PHY_INTERFACE_MODE_10GKR:
mode = PHY_MODE_10GKR;
break;
default:
return -EINVAL;
}
ret = phy_set_mode(port->comphy, mode);
if (ret)
return ret;
return phy_power_on(port->comphy);
}
static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port) static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port)
{ {
u32 val; u32 val;
...@@ -6404,8 +6432,10 @@ static void mvpp2_start_dev(struct mvpp2_port *port) ...@@ -6404,8 +6432,10 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
/* Enable interrupts on all CPUs */ /* Enable interrupts on all CPUs */
mvpp2_interrupts_enable(port); mvpp2_interrupts_enable(port);
if (port->priv->hw_version == MVPP22) if (port->priv->hw_version == MVPP22) {
mvpp22_comphy_init(port);
mvpp22_gop_init(port); mvpp22_gop_init(port);
}
mvpp2_port_mii_set(port); mvpp2_port_mii_set(port);
mvpp2_port_enable(port); mvpp2_port_enable(port);
...@@ -6436,6 +6466,7 @@ static void mvpp2_stop_dev(struct mvpp2_port *port) ...@@ -6436,6 +6466,7 @@ static void mvpp2_stop_dev(struct mvpp2_port *port)
mvpp2_egress_disable(port); mvpp2_egress_disable(port);
mvpp2_port_disable(port); mvpp2_port_disable(port);
phy_stop(ndev->phydev); phy_stop(ndev->phydev);
phy_power_off(port->comphy);
} }
static int mvpp2_check_ringparam_valid(struct net_device *dev, static int mvpp2_check_ringparam_valid(struct net_device *dev,
...@@ -7242,6 +7273,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, ...@@ -7242,6 +7273,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
struct mvpp2 *priv) struct mvpp2 *priv)
{ {
struct device_node *phy_node; struct device_node *phy_node;
struct phy *comphy;
struct mvpp2_port *port; struct mvpp2_port *port;
struct mvpp2_port_pcpu *port_pcpu; struct mvpp2_port_pcpu *port_pcpu;
struct net_device *dev; struct net_device *dev;
...@@ -7285,6 +7317,15 @@ static int mvpp2_port_probe(struct platform_device *pdev, ...@@ -7285,6 +7317,15 @@ static int mvpp2_port_probe(struct platform_device *pdev,
goto err_free_netdev; goto err_free_netdev;
} }
comphy = devm_of_phy_get(&pdev->dev, port_node, NULL);
if (IS_ERR(comphy)) {
if (PTR_ERR(comphy) == -EPROBE_DEFER) {
err = -EPROBE_DEFER;
goto err_free_netdev;
}
comphy = NULL;
}
if (of_property_read_u32(port_node, "port-id", &id)) { if (of_property_read_u32(port_node, "port-id", &id)) {
err = -EINVAL; err = -EINVAL;
dev_err(&pdev->dev, "missing port-id value\n"); dev_err(&pdev->dev, "missing port-id value\n");
...@@ -7318,6 +7359,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, ...@@ -7318,6 +7359,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
port->phy_node = phy_node; port->phy_node = phy_node;
port->phy_interface = phy_mode; port->phy_interface = phy_mode;
port->comphy = comphy;
if (priv->hw_version == MVPP21) { if (priv->hw_version == MVPP21) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 2 + id); res = platform_get_resource(pdev, IORESOURCE_MEM, 2 + id);
......
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