[8/9] net: mdio: ipq4019: add qca8084 configurations

Message ID 20231115032515.4249-9-quic_luoj@quicinc.com
State New
Headers
Series add MDIO changes on ipq5332 platform |

Commit Message

Jie Luo Nov. 15, 2023, 3:25 a.m. UTC
  The PHY & PCS clocks need to be enabled and the reset
sequence needs to be completed to make qca8084 PHY
probeable by MDIO bus.

Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
 drivers/net/mdio/mdio-ipq4019.c | 133 +++++++++++++++++++++++++++++++-
 1 file changed, 132 insertions(+), 1 deletion(-)
  

Comments

Andrew Lunn Nov. 15, 2023, 4:20 p.m. UTC | #1
On Wed, Nov 15, 2023 at 11:25:14AM +0800, Luo Jie wrote:
> The PHY & PCS clocks need to be enabled and the reset
> sequence needs to be completed to make qca8084 PHY
> probeable by MDIO bus.

Is all this guaranteed to be the same between different boards? Can
the board be wired differently and need a different configuration?

    Andrew
  
Konrad Dybcio Nov. 15, 2023, 5:01 p.m. UTC | #2
On 11/15/23 17:20, Andrew Lunn wrote:
> On Wed, Nov 15, 2023 at 11:25:14AM +0800, Luo Jie wrote:
>> The PHY & PCS clocks need to be enabled and the reset
>> sequence needs to be completed to make qca8084 PHY
>> probeable by MDIO bus.
> 
> Is all this guaranteed to be the same between different boards?
No, this looks like a total subsystem overreach, these should be
taken care of from within clk framework and consumed with the clk
APIs.

Konrad
  
Robert Marko Nov. 15, 2023, 5:03 p.m. UTC | #3
On Wed, Nov 15, 2023 at 6:01 PM Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>
>
>
> On 11/15/23 17:20, Andrew Lunn wrote:
> > On Wed, Nov 15, 2023 at 11:25:14AM +0800, Luo Jie wrote:
> >> The PHY & PCS clocks need to be enabled and the reset
> >> sequence needs to be completed to make qca8084 PHY
> >> probeable by MDIO bus.
> >
> > Is all this guaranteed to be the same between different boards?
> No, this looks like a total subsystem overreach, these should be
> taken care of from within clk framework and consumed with the clk
> APIs.
>
> Konrad

There are patches for QCA8084 clocks:
https://patchwork.kernel.org/project/linux-arm-msm/cover/20231104034858.9159-1-quic_luoj@quicinc.com/

I guess all of the clocking should be done there, it isn't really a MDIO issue.

Regards,
Robert
  
Jie Luo Nov. 16, 2023, 10:44 a.m. UTC | #4
On 11/16/2023 1:01 AM, Konrad Dybcio wrote:
> 
> 
> On 11/15/23 17:20, Andrew Lunn wrote:
>> On Wed, Nov 15, 2023 at 11:25:14AM +0800, Luo Jie wrote:
>>> The PHY & PCS clocks need to be enabled and the reset
>>> sequence needs to be completed to make qca8084 PHY
>>> probeable by MDIO bus.
>>
>> Is all this guaranteed to be the same between different boards?
> No, this looks like a total subsystem overreach, these should be
> taken care of from within clk framework and consumed with the clk
> APIs.
> 
> Konrad

Hi Konrad,
As Robert shared the link of the clock provider driver, which is
registered as MDIO device and not available until to the qca8084
initializations completed done here, so i need to do raw read/write
the clock registers in this patch.
  
Jie Luo Nov. 16, 2023, 10:45 a.m. UTC | #5
On 11/16/2023 1:03 AM, Robert Marko wrote:
> On Wed, Nov 15, 2023 at 6:01 PM Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>>
>>
>>
>> On 11/15/23 17:20, Andrew Lunn wrote:
>>> On Wed, Nov 15, 2023 at 11:25:14AM +0800, Luo Jie wrote:
>>>> The PHY & PCS clocks need to be enabled and the reset
>>>> sequence needs to be completed to make qca8084 PHY
>>>> probeable by MDIO bus.
>>>
>>> Is all this guaranteed to be the same between different boards?
>> No, this looks like a total subsystem overreach, these should be
>> taken care of from within clk framework and consumed with the clk
>> APIs.
>>
>> Konrad
> 
> There are patches for QCA8084 clocks:
> https://patchwork.kernel.org/project/linux-arm-msm/cover/20231104034858.9159-1-quic_luoj@quicinc.com/
> 
> I guess all of the clocking should be done there, it isn't really a MDIO issue.
> 
> Regards,
> Robert
> 

Thanks Robert for the link of this patch.

Yes, the clock driver of qca8084 is probed as the MDIO device, the
configuration sequence here to lighten the qca8084 PHY need to
be completed before the clock APIs available to call.
  
Jie Luo Nov. 16, 2023, 10:47 a.m. UTC | #6
On 11/16/2023 12:20 AM, Andrew Lunn wrote:
> On Wed, Nov 15, 2023 at 11:25:14AM +0800, Luo Jie wrote:
>> The PHY & PCS clocks need to be enabled and the reset
>> sequence needs to be completed to make qca8084 PHY
>> probeable by MDIO bus.
> 
> Is all this guaranteed to be the same between different boards? Can
> the board be wired differently and need a different configuration?
> 
>      Andrew

Hi Andrew,
This configuration sequence is specified to the qca8084 chip,
not related with the platform(such as ipq5332).

All these configured registers are located in qca8084 chip, we need
to complete these configurations to make MDIO bus being able to
scan the qca8084 PHY(PHY registers can be accessed).
  
Andrew Lunn Nov. 16, 2023, 5:08 p.m. UTC | #7
> Yes, the clock driver of qca8084 is probed as the MDIO device, the
> configuration sequence here to lighten the qca8084 PHY need to
> be completed before the clock APIs available to call.

Please cleanly separate clock from MDIO. The MDIO driver should only
use the common clock framework API calls. If the clock driver is not
loaded yet, trying to get a clock should return -EPROBE_DEFER. The
MDIO driver should return that from its probe function. The driver
core will then try to probe the MDIO driver later, by which time the
clock driver should of loaded.

      Andrew
  
Andrew Lunn Nov. 16, 2023, 5:12 p.m. UTC | #8
On Thu, Nov 16, 2023 at 06:47:08PM +0800, Jie Luo wrote:
> 
> 
> On 11/16/2023 12:20 AM, Andrew Lunn wrote:
> > On Wed, Nov 15, 2023 at 11:25:14AM +0800, Luo Jie wrote:
> > > The PHY & PCS clocks need to be enabled and the reset
> > > sequence needs to be completed to make qca8084 PHY
> > > probeable by MDIO bus.
> > 
> > Is all this guaranteed to be the same between different boards? Can
> > the board be wired differently and need a different configuration?
> > 
> >      Andrew
> 
> Hi Andrew,
> This configuration sequence is specified to the qca8084 chip,
> not related with the platform(such as ipq5332).
> 
> All these configured registers are located in qca8084 chip, we need
> to complete these configurations to make MDIO bus being able to
> scan the qca8084 PHY(PHY registers can be accessed).

So nothing here has anything to do with the actual PHYs on the bus?
The only clock exposed here is MDC, and that runs at the standard
2.5MHz? All the clock tree configuration is completely internal to the
SOC?

What we don't want is some hard coded configuration which only works
for one specific reference design.

	Andrew
  
Jie Luo Nov. 17, 2023, 10:05 a.m. UTC | #9
On 11/17/2023 1:08 AM, Andrew Lunn wrote:
>> Yes, the clock driver of qca8084 is probed as the MDIO device, the
>> configuration sequence here to lighten the qca8084 PHY need to
>> be completed before the clock APIs available to call.
> 
> Please cleanly separate clock from MDIO. The MDIO driver should only
> use the common clock framework API calls. If the clock driver is not
> loaded yet, trying to get a clock should return -EPROBE_DEFER. The
> MDIO driver should return that from its probe function. The driver
> core will then try to probe the MDIO driver later, by which time the
> clock driver should of loaded.
> 
>        Andrew
> 

Ok, will update the patches to take this solution using the clock
consume APIs. Thanks Andrew for the suggestion.
  
Jie Luo Nov. 17, 2023, 10:15 a.m. UTC | #10
On 11/17/2023 1:12 AM, Andrew Lunn wrote:
> On Thu, Nov 16, 2023 at 06:47:08PM +0800, Jie Luo wrote:
>>
>>
>> On 11/16/2023 12:20 AM, Andrew Lunn wrote:
>>> On Wed, Nov 15, 2023 at 11:25:14AM +0800, Luo Jie wrote:
>>>> The PHY & PCS clocks need to be enabled and the reset
>>>> sequence needs to be completed to make qca8084 PHY
>>>> probeable by MDIO bus.
>>>
>>> Is all this guaranteed to be the same between different boards? Can
>>> the board be wired differently and need a different configuration?
>>>
>>>       Andrew
>>
>> Hi Andrew,
>> This configuration sequence is specified to the qca8084 chip,
>> not related with the platform(such as ipq5332).
>>
>> All these configured registers are located in qca8084 chip, we need
>> to complete these configurations to make MDIO bus being able to
>> scan the qca8084 PHY(PHY registers can be accessed).
> 
> So nothing here has anything to do with the actual PHYs on the bus?
> The only clock exposed here is MDC, and that runs at the standard
> 2.5MHz? All the clock tree configuration is completely internal to the
> SOC?
> 
> What we don't want is some hard coded configuration which only works
> for one specific reference design.
> 
> 	Andrew

These configured registers are related with PHYs, which is located in
the qca8084 PHY chip, qca8084 PHY chip includes the GCC register that
is not from the SOC(ipq5332), is a internal part of qca8084 PHY.

qca8084 PHY works on 6.25MHZ and other clock rates below 6.25MHZ.

will move these clock configurations using the clock APIs into the PHY
probe function in the next patch set, since it is the internal configs
of qca8084 PHY.
  

Patch

diff --git a/drivers/net/mdio/mdio-ipq4019.c b/drivers/net/mdio/mdio-ipq4019.c
index 1c461c243ae0..9bdd49be2361 100644
--- a/drivers/net/mdio/mdio-ipq4019.c
+++ b/drivers/net/mdio/mdio-ipq4019.c
@@ -70,6 +70,30 @@ 
 #define QCA8084_PHY_ADDR_MASK			GENMASK(19, 0)
 #define QCA8084_PCS_ADDR_MASK			GENMASK(14, 0)
 
+/* QCA8084 GCC & security control registers */
+/* LDO control, BIT20 for PHY0 and PHY1, BIT21 for PHY2 and PHY3 */
+#define EPHY_CFG				0xC90F018
+#define EPHY_CFG_LDO_CTRL			GENMASK(21, 20)
+
+/* GEPHY TX&RX clock control register starts from GEPHY0_TX,
+ * end with GEPHY3_RX, the gap is 0x20.
+ */
+#define GEPHY0_TX_CBCR				0xC800058
+#define GEPHY3_RX_CBCR				0xC800138
+#define GEPHY_CBCR_GAP				0x20
+
+#define SRDS0_SYS_CBCR				0xC8001A8
+#define SRDS1_SYS_CBCR				0xC8001AC
+#define EPHY0_SYS_CBCR				0xC8001B0
+#define EPHY1_SYS_CBCR				0xC8001B4
+#define EPHY2_SYS_CBCR				0xC8001B8
+#define EPHY3_SYS_CBCR				0xC8001BC
+#define CLK_EN					BIT(0)
+#define CLK_RESET				BIT(2)
+
+#define GCC_GEPHY_MISC				0xC800304
+#define GCC_GEPHY_MISC_DSP_RESET		GENMASK(4, 0)
+
 enum mdio_clk_id {
 	MDIO_CLK_MDIO_AHB,
 	MDIO_CLK_UNIPHY0_AHB,
@@ -412,14 +436,121 @@  static int ipq_phy_addr_fixup(struct mii_bus *bus, struct device_node *mdio_node
 	return 0;
 }
 
+static inline int qca8084_clock_en_set(struct mii_bus *bus, u32 reg, bool enable)
+{
+	return qca8084_modify(bus, reg, CLK_EN, enable ? CLK_EN : 0);
+}
+
+static inline int qca8084_clock_reset(struct mii_bus *bus, u32 reg)
+{
+	int ret;
+
+	ret = qca8084_modify(bus, reg, CLK_RESET, CLK_RESET);
+	if (ret)
+		return ret;
+
+	usleep_range(20000, 21000);
+	return qca8084_modify(bus, reg, CLK_RESET, 0);
+}
+
+static int qca8084_clock_config(struct mii_bus *bus)
+{
+	u32 reg;
+	int ret;
+
+	/* Enable PCS */
+	ret = qca8084_clock_en_set(bus, SRDS0_SYS_CBCR, true);
+	if (ret)
+		return ret;
+
+	ret = qca8084_clock_en_set(bus, SRDS1_SYS_CBCR, true);
+	if (ret)
+		return ret;
+
+	/* Reset PCS */
+	ret = qca8084_clock_reset(bus, SRDS0_SYS_CBCR);
+	if (ret)
+		return ret;
+
+	ret = qca8084_clock_reset(bus, SRDS1_SYS_CBCR);
+	if (ret)
+		return ret;
+
+	/* Disable EPHY GMII RX & TX clock */
+	reg = GEPHY0_TX_CBCR;
+	while (reg <= GEPHY3_RX_CBCR) {
+		ret = qca8084_clock_en_set(bus, reg, false);
+		if (ret)
+			return ret;
+
+		reg += GEPHY_CBCR_GAP;
+	}
+
+	/* Enable EPHY */
+	ret = qca8084_clock_en_set(bus, EPHY0_SYS_CBCR, true);
+	if (ret)
+		return ret;
+
+	ret = qca8084_clock_en_set(bus, EPHY1_SYS_CBCR, true);
+	if (ret)
+		return ret;
+
+	ret = qca8084_clock_en_set(bus, EPHY2_SYS_CBCR, true);
+	if (ret)
+		return ret;
+
+	ret = qca8084_clock_en_set(bus, EPHY3_SYS_CBCR, true);
+	if (ret)
+		return ret;
+
+	/* Reset EPHY */
+	ret = qca8084_clock_reset(bus, EPHY0_SYS_CBCR);
+	if (ret)
+		return ret;
+
+	ret = qca8084_clock_reset(bus, EPHY1_SYS_CBCR);
+	if (ret)
+		return ret;
+
+	ret = qca8084_clock_reset(bus, EPHY2_SYS_CBCR);
+	if (ret)
+		return ret;
+
+	ret = qca8084_clock_reset(bus, EPHY3_SYS_CBCR);
+	if (ret)
+		return ret;
+
+	/* Deassert EPHY DSP */
+	ret = qca8084_modify(bus, GCC_GEPHY_MISC, GCC_GEPHY_MISC_DSP_RESET, 0);
+	if (ret)
+		return ret;
+
+	/* Enable efuse loading into analog circuit */
+	ret = qca8084_modify(bus, EPHY_CFG, EPHY_CFG_LDO_CTRL, 0);
+	if (ret)
+		return ret;
+
+	/* Sleep 10ms */
+	usleep_range(10000, 11000);
+	return 0;
+}
+
 static int ipq_mdio_preinit(struct mii_bus *bus)
 {
+	int ret;
 	struct device_node *mdio_node = dev_of_node(&bus->dev);
 
 	if (!mdio_node)
 		return 0;
 
-	return ipq_phy_addr_fixup(bus, mdio_node);
+	ret = ipq_phy_addr_fixup(bus, mdio_node);
+	if (ret)
+		return ret;
+
+	if (of_property_read_bool(mdio_node, "mdio-clk-fixup"))
+		ret = qca8084_clock_config(bus);
+
+	return ret;
 }
 
 /* For the CMN PLL block, the reference clock can be configured according to