summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c31
-rw-r--r--drivers/phy/qualcomm/phy-qcom-sgmii-eth.c73
2 files changed, 41 insertions, 63 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index ad5b5d950fff..cb1c074c2053 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -105,7 +105,6 @@ struct qcom_ethqos {
struct clk *link_clk;
struct phy *serdes_phy;
- int serdes_speed;
phy_interface_t phy_mode;
const struct ethqos_emac_por *rgmii_por;
@@ -591,14 +590,6 @@ static void ethqos_configure_rgmii(struct qcom_ethqos *ethqos,
ethqos_rgmii_macro_init(ethqos, speed);
}
-static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
-{
- if (ethqos->serdes_speed != speed) {
- phy_set_speed(ethqos->serdes_phy, speed);
- ethqos->serdes_speed = speed;
- }
-}
-
static void ethqos_pcs_set_inband(struct stmmac_priv *priv, bool enable)
{
stmmac_pcs_ctrl_ane(priv, enable, 0);
@@ -656,16 +647,8 @@ static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv)
return ret;
ret = phy_power_on(ethqos->serdes_phy);
- if (ret) {
- phy_exit(ethqos->serdes_phy);
- return ret;
- }
-
- ret = phy_set_speed(ethqos->serdes_phy, ethqos->serdes_speed);
- if (ret) {
- phy_power_off(ethqos->serdes_phy);
+ if (ret)
phy_exit(ethqos->serdes_phy);
- }
return ret;
}
@@ -683,15 +666,16 @@ static int ethqos_mac_finish_serdes(struct net_device *ndev, void *priv,
phy_interface_t interface)
{
struct qcom_ethqos *ethqos = priv;
+ int ret = 0;
qcom_ethqos_set_sgmii_loopback(ethqos, false);
- if (interface == PHY_INTERFACE_MODE_SGMII)
- ethqos_set_serdes_speed(ethqos, SPEED_1000);
- else if (interface == PHY_INTERFACE_MODE_2500BASEX)
- ethqos_set_serdes_speed(ethqos, SPEED_2500);
+ if (interface == PHY_INTERFACE_MODE_SGMII ||
+ interface == PHY_INTERFACE_MODE_2500BASEX)
+ ret = phy_set_mode_ext(ethqos->serdes_phy, PHY_MODE_ETHERNET,
+ interface);
- return 0;
+ return ret;
}
static int ethqos_clks_config(void *priv, bool enabled)
@@ -819,7 +803,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(ethqos->serdes_phy),
"Failed to get serdes phy\n");
- ethqos->serdes_speed = SPEED_1000;
ethqos_set_clk_tx_rate(ethqos, NULL, plat_dat->phy_interface,
SPEED_1000);
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index 4ea3dce7719f..f48faa2929a6 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -29,7 +29,7 @@
struct qcom_dwmac_sgmii_phy_data {
struct regmap *regmap;
struct clk *refclk;
- int speed;
+ phy_interface_t interface;
};
static void qcom_dwmac_sgmii_phy_init_1g(struct regmap *regmap)
@@ -223,15 +223,18 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
struct device *dev = phy->dev.parent;
- switch (data->speed) {
- case SPEED_10:
- case SPEED_100:
- case SPEED_1000:
+ switch (data->interface) {
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ /* 1.25Gbps mode */
qcom_dwmac_sgmii_phy_init_1g(data->regmap);
break;
- case SPEED_2500:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ /* 3.125Gbps mode */
qcom_dwmac_sgmii_phy_init_2p5g(data->regmap);
break;
+ default:
+ return -EINVAL;
}
if (qcom_dwmac_sgmii_phy_poll_status(data->regmap,
@@ -268,8 +271,17 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
{
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
+ int ret;
+
+ ret = clk_prepare_enable(data->refclk);
+ if (ret < 0)
+ return ret;
+
+ ret = qcom_dwmac_sgmii_phy_calibrate(phy);
+ if (ret < 0)
+ clk_disable_unprepare(data->refclk);
- return clk_prepare_enable(data->refclk);
+ return ret;
}
static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
@@ -287,17 +299,17 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
return 0;
}
-static int qcom_dwmac_sgmii_phy_speed(enum phy_mode mode, int submode)
+static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
+ int submode,
+ union phy_configure_opts *opts)
{
if (mode != PHY_MODE_ETHERNET)
return -EINVAL;
if (submode == PHY_INTERFACE_MODE_SGMII ||
- submode == PHY_INTERFACE_MODE_1000BASEX)
- return SPEED_1000;
-
- if (submode == PHY_INTERFACE_MODE_2500BASEX)
- return SPEED_2500;
+ submode == PHY_INTERFACE_MODE_1000BASEX ||
+ submode == PHY_INTERFACE_MODE_2500BASEX)
+ return 0;
return -EINVAL;
}
@@ -306,42 +318,25 @@ static int qcom_dwmac_sgmii_phy_set_mode(struct phy *phy, enum phy_mode mode,
int submode)
{
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
- int speed;
-
- speed = qcom_dwmac_sgmii_phy_speed(mode, submode);
- if (speed < 0)
- return speed;
+ int ret;
- if (speed != data->speed)
- data->speed = speed;
-
- return qcom_dwmac_sgmii_phy_calibrate(phy);
-}
+ ret = qcom_dwmac_sgmii_phy_validate(phy, mode, submode, NULL);
+ if (ret)
+ return ret;
-static int qcom_dwmac_sgmii_phy_set_speed(struct phy *phy, int speed)
-{
- struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
+ if (submode != data->interface)
+ data->interface = submode;
- if (speed != data->speed)
- data->speed = speed;
+ if (phy->power_count == 0)
+ return 0;
return qcom_dwmac_sgmii_phy_calibrate(phy);
}
-static int qcom_dwmac_sgmii_phy_validate(struct phy *phy, enum phy_mode mode,
- int submode,
- union phy_configure_opts *opts)
-{
- int ret = qcom_dwmac_sgmii_phy_speed(mode, submode);
-
- return ret < 0 ? ret : 0;
-}
-
static const struct phy_ops qcom_dwmac_sgmii_phy_ops = {
.power_on = qcom_dwmac_sgmii_phy_power_on,
.power_off = qcom_dwmac_sgmii_phy_power_off,
.set_mode = qcom_dwmac_sgmii_phy_set_mode,
- .set_speed = qcom_dwmac_sgmii_phy_set_speed,
.validate = qcom_dwmac_sgmii_phy_validate,
.calibrate = qcom_dwmac_sgmii_phy_calibrate,
.owner = THIS_MODULE,
@@ -367,7 +362,7 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
- data->speed = SPEED_10;
+ data->interface = PHY_INTERFACE_MODE_SGMII;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))