@@ -897,6 +897,84 @@ static int qca8084_parse_dt(struct phy_device *phydev)
return 0;
}
+static int qca8084_clock_config(struct phy_device *phydev)
+{
+ struct at803x_priv *priv;
+ int ret = 0;
+
+ /* The ethernet clock IDs are only defined in one PHY device
+ * tree node, and these ethernet clocks only needs to be configured
+ * one time, which work on the clock rate 25MHZ.
+ */
+ priv = phydev->priv;
+ if (!priv->clk[SRDS0_SYS_CLK])
+ return 0;
+
+ ret = clk_set_rate(priv->clk[SRDS0_SYS_CLK], 25000000);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(priv->clk[SRDS0_SYS_CLK]);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(priv->clk[SRDS1_SYS_CLK]);
+ if (ret)
+ return ret;
+
+ /* Reset PCS system clocks */
+ reset_control_assert(priv->reset[SRDS0_SYS_RESET]);
+ reset_control_assert(priv->reset[SRDS1_SYS_RESET]);
+ fsleep(20000);
+
+ reset_control_deassert(priv->reset[SRDS0_SYS_RESET]);
+ reset_control_deassert(priv->reset[SRDS1_SYS_RESET]);
+
+ ret = clk_prepare_enable(priv->clk[GEPHY0_SYS_CLK]);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(priv->clk[GEPHY1_SYS_CLK]);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(priv->clk[GEPHY2_SYS_CLK]);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(priv->clk[GEPHY3_SYS_CLK]);
+ if (ret)
+ return ret;
+
+ /* Reset ethernet system clocks */
+ reset_control_assert(priv->reset[GEPHY0_SYS_RESET]);
+ reset_control_assert(priv->reset[GEPHY1_SYS_RESET]);
+ reset_control_assert(priv->reset[GEPHY2_SYS_RESET]);
+ reset_control_assert(priv->reset[GEPHY3_SYS_RESET]);
+ fsleep(20000);
+
+ reset_control_deassert(priv->reset[GEPHY0_SYS_RESET]);
+ reset_control_deassert(priv->reset[GEPHY1_SYS_RESET]);
+ reset_control_deassert(priv->reset[GEPHY2_SYS_RESET]);
+ reset_control_deassert(priv->reset[GEPHY3_SYS_RESET]);
+
+ /* Release ethernet DSP reset */
+ reset_control_deassert(priv->reset[GEPHY0_RESET]);
+ reset_control_deassert(priv->reset[GEPHY1_RESET]);
+ reset_control_deassert(priv->reset[GEPHY2_RESET]);
+ reset_control_deassert(priv->reset[GEPHY3_RESET]);
+ reset_control_deassert(priv->reset[GEPHY_DSP_RESET]);
+
+ /* Enable efuse loading into analog circuit */
+ ret = qca8084_mii_modify(phydev, QCA8084_EPHY_CFG,
+ QCA8084_EPHY_LDO_EN, 0);
+ if (ret)
+ return ret;
+
+ fsleep(10000);
+ return 0;
+}
+
static int qca8084_probe(struct phy_device *phydev)
{
int ret;
@@ -905,7 +983,11 @@ static int qca8084_probe(struct phy_device *phydev)
if (ret)
return ret;
- return qca8084_parse_and_set_phyaddr(phydev);
+ ret = qca8084_parse_and_set_phyaddr(phydev);
+ if (ret)
+ return ret;
+
+ return qca8084_clock_config(phydev);
}
static int at803x_probe(struct phy_device *phydev)
After GPIO reset, these Ethernet clock sequence needs to be configured before reading the features of PHY, the Ethernet system clock works on 25MHZ. Signed-off-by: Luo Jie <quic_luoj@quicinc.com> --- drivers/net/phy/at803x.c | 84 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)