The Qualcomm SGMII SerDes PHY requires two regulators to function
properly. If both of these are not enabled, the following error is
observed:
[ 77.105651] qcom-dwmac-sgmii-phy 8909000.phy: QSERDES_COM_C_READY_STATUS timed-out
[ 77.113447] qcom-ethqos 23040000.ethernet eth0: __stmmac_open: Serdes powerup failed
Therefore, add support for handling the additional regulator in the
driver.
Fixes: 601d06277007 ("phy: qcom: add the SGMII SerDes PHY driver")
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index 5b1c82459c126fe3a046a89601483d8c73090fd3..5044f244762f4bb2318618b83bd94324d445b62d 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -10,6 +10,7 @@
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include "phy-qcom-qmp-pcs-sgmii.h"
#include "phy-qcom-qmp-qserdes-com-v5.h"
@@ -26,6 +27,7 @@
#define QSERDES_COM_C_PLL_LOCKED BIT(1)
struct qcom_dwmac_sgmii_phy_data {
+ struct regulator *vdda_0p9;
struct regmap *regmap;
struct clk *refclk;
int speed;
@@ -266,9 +268,23 @@ static int qcom_dwmac_sgmii_phy_calibrate(struct phy *phy)
static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
{
+ int ret;
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
- return clk_prepare_enable(data->refclk);
+ ret = regulator_enable(data->vdda_0p9);
+ if (ret)
+ goto out_ret;
+
+ ret = clk_prepare_enable(data->refclk);
+ if (ret)
+ goto out_reg_disable;
+
+ return 0;
+
+out_reg_disable:
+ regulator_disable(data->vdda_0p9);
+out_ret:
+ return ret;
}
static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
@@ -283,6 +299,8 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
clk_disable_unprepare(data->refclk);
+ regulator_disable(data->vdda_0p9);
+
return 0;
}
@@ -343,6 +361,10 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
if (IS_ERR(data->refclk))
return PTR_ERR(data->refclk);
+ data->vdda_0p9 = devm_regulator_get(dev, "vdda-0p9");
+ if (IS_ERR(data->vdda_0p9))
+ return PTR_ERR(data->vdda_0p9);
+
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (IS_ERR(provider))
return PTR_ERR(provider);
--
2.34.1