U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 1/1] net: dwc_eth_qos: mdio: Implement clause 45
@ 2024-04-23  8:51 Philip Oberfichtner
  2024-04-23 12:52 ` Marek Vasut
  0 siblings, 1 reply; 2+ messages in thread
From: Philip Oberfichtner @ 2024-04-23  8:51 UTC (permalink / raw)
  To: u-boot
  Cc: joe.hershberger, rfried.dev, trini, caleb.connolly,
	neil.armstrong, sumit.garg, sjg, philipp.tomsich, kever.yang,
	patrick.delaunay, patrice.chotard, jonas, marex, leyfoon.tan,
	epsi, xypron.glpk, seanga2, sebastien.szymanski, festevam,
	sebastian.reichel, yanhong.wang, christophe.roullier, pro

Bevor this commit, only clause 22 access was possible. After this commit,
clause 45 direct access will available as well.

Note that there is a slight change of behavior: Before this commit, the
C45E bit was set to whatever value was left in the register from the
previous access. After this commit, we adopt the common practice of
discerning C45 from C22 using the devad argument.

Signed-off-by: Philip Oberfichtner <pro@denx.de>
---

Notes:
    This patch is labeled RFC as there is a slight change of behavior (see
    commit message). I'm not sure in fact if this solution works for
    everybody - this is up for discussion!
    
    My implementation is tested on an Intel Elkhart lake SOC. Driver code
    for dwc_eth_qos_intel coming soon in a separate patch series.

 drivers/net/dwc_eth_qos.c | 66 ++++++++++++++++++++++++++-------------
 drivers/net/dwc_eth_qos.h |  1 +
 2 files changed, 45 insertions(+), 22 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 86d989e244..64a9bff6bb 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -162,6 +162,25 @@ static int eqos_mdio_wait_idle(struct eqos_priv *eqos)
 				 1000000, true);
 }
 
+/* Bitmask common for mdio_read and mdio_write */
+#define EQOS_MDIO_BITFIELD(pa, rda, cr) \
+	(pa  << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT)  | \
+	(rda << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) | \
+	(cr << EQOS_MAC_MDIO_ADDRESS_CR_SHIFT)   | \
+	 EQOS_MAC_MDIO_ADDRESS_GB
+
+static u32 eqos_mdio_bitfield(struct eqos_priv *eqos, int addr, int devad, int reg)
+{
+	int cr = eqos->config->config_mac_mdio;
+	bool c22 = devad == MDIO_DEVAD_NONE ? true : false;
+
+	if (c22)
+		return EQOS_MDIO_BITFIELD(addr, reg, cr);
+	else
+		return EQOS_MDIO_BITFIELD(addr, devad, cr) |
+		       EQOS_MAC_MDIO_ADDRESS_C45E;
+}
+
 static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
 			  int mdio_reg)
 {
@@ -179,15 +198,17 @@ static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
 	}
 
 	val = readl(&eqos->mac_regs->mdio_address);
-	val &= EQOS_MAC_MDIO_ADDRESS_SKAP |
-		EQOS_MAC_MDIO_ADDRESS_C45E;
-	val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
-		(mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
-		(eqos->config->config_mac_mdio <<
-		 EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
-		(EQOS_MAC_MDIO_ADDRESS_GOC_READ <<
-		 EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
-		EQOS_MAC_MDIO_ADDRESS_GB;
+	val &= EQOS_MAC_MDIO_ADDRESS_SKAP;
+
+	val |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) |
+	       EQOS_MAC_MDIO_ADDRESS_GOC_READ <<
+	       EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT;
+
+	if (val & EQOS_MAC_MDIO_ADDRESS_C45E) {
+		writel(mdio_reg << EQOS_MAC_MDIO_DATA_RA_SHIFT,
+		       &eqos->mac_regs->mdio_data);
+	}
+
 	writel(val, &eqos->mac_regs->mdio_address);
 
 	udelay(eqos->config->mdio_wait);
@@ -210,7 +231,8 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
 			   int mdio_reg, u16 mdio_val)
 {
 	struct eqos_priv *eqos = bus->priv;
-	u32 val;
+	u32 v_addr;
+	u32 v_data;
 	int ret;
 
 	debug("%s(dev=%p, addr=%x, reg=%d, val=%x):\n", __func__, eqos->dev,
@@ -222,20 +244,20 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
 		return ret;
 	}
 
-	writel(mdio_val, &eqos->mac_regs->mdio_data);
+	v_addr = readl(&eqos->mac_regs->mdio_address);
+	v_addr &= EQOS_MAC_MDIO_ADDRESS_SKAP;
+
+	v_addr |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) |
+	          EQOS_MAC_MDIO_ADDRESS_GOC_WRITE <<
+	          EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT;
+
+	v_data = mdio_val;
+	if (v_addr & EQOS_MAC_MDIO_ADDRESS_C45E)
+		v_data |=  mdio_reg << EQOS_MAC_MDIO_DATA_RA_SHIFT;
 
-	val = readl(&eqos->mac_regs->mdio_address);
-	val &= EQOS_MAC_MDIO_ADDRESS_SKAP |
-		EQOS_MAC_MDIO_ADDRESS_C45E;
-	val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
-		(mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
-		(eqos->config->config_mac_mdio <<
-		 EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
-		(EQOS_MAC_MDIO_ADDRESS_GOC_WRITE <<
-		 EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
-		EQOS_MAC_MDIO_ADDRESS_GB;
-	writel(val, &eqos->mac_regs->mdio_address);
 
+	writel(v_data, &eqos->mac_regs->mdio_data);
+	writel(v_addr, &eqos->mac_regs->mdio_address);
 	udelay(eqos->config->mdio_wait);
 
 	ret = eqos_mdio_wait_idle(eqos);
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index 8b3d0d464d..d6ed3830be 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -92,6 +92,7 @@ struct eqos_mac_regs {
 #define EQOS_MAC_MDIO_ADDRESS_C45E			BIT(1)
 #define EQOS_MAC_MDIO_ADDRESS_GB			BIT(0)
 
+#define EQOS_MAC_MDIO_DATA_RA_SHIFT			16
 #define EQOS_MAC_MDIO_DATA_GD_MASK			0xffff
 
 #define EQOS_MTL_REGS_BASE 0xd00
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [RFC PATCH 1/1] net: dwc_eth_qos: mdio: Implement clause 45
  2024-04-23  8:51 [RFC PATCH 1/1] net: dwc_eth_qos: mdio: Implement clause 45 Philip Oberfichtner
@ 2024-04-23 12:52 ` Marek Vasut
  0 siblings, 0 replies; 2+ messages in thread
From: Marek Vasut @ 2024-04-23 12:52 UTC (permalink / raw)
  To: Philip Oberfichtner, u-boot
  Cc: joe.hershberger, rfried.dev, trini, caleb.connolly,
	neil.armstrong, sumit.garg, sjg, philipp.tomsich, kever.yang,
	patrick.delaunay, patrice.chotard, jonas, leyfoon.tan, epsi,
	xypron.glpk, seanga2, sebastien.szymanski, festevam,
	sebastian.reichel, yanhong.wang, christophe.roullier

On 4/23/24 10:51 AM, Philip Oberfichtner wrote:
> Bevor this commit, only clause 22 access was possible. After this commit,
> clause 45 direct access will available as well.
> 
> Note that there is a slight change of behavior: Before this commit, the
> C45E bit was set to whatever value was left in the register from the
> previous access. After this commit, we adopt the common practice of
> discerning C45 from C22 using the devad argument.
> 
> Signed-off-by: Philip Oberfichtner <pro@denx.de>
> ---
> 
> Notes:
>      This patch is labeled RFC as there is a slight change of behavior (see
>      commit message). I'm not sure in fact if this solution works for
>      everybody - this is up for discussion!
>      
>      My implementation is tested on an Intel Elkhart lake SOC. Driver code
>      for dwc_eth_qos_intel coming soon in a separate patch series.
> 
>   drivers/net/dwc_eth_qos.c | 66 ++++++++++++++++++++++++++-------------
>   drivers/net/dwc_eth_qos.h |  1 +
>   2 files changed, 45 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
> index 86d989e244..64a9bff6bb 100644
> --- a/drivers/net/dwc_eth_qos.c
> +++ b/drivers/net/dwc_eth_qos.c
> @@ -162,6 +162,25 @@ static int eqos_mdio_wait_idle(struct eqos_priv *eqos)
>   				 1000000, true);
>   }
>   
> +/* Bitmask common for mdio_read and mdio_write */
> +#define EQOS_MDIO_BITFIELD(pa, rda, cr) \
> +	(pa  << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT)  | \

Parenthesis around (pa) are missing, DTTO for the rest of this.

However, better use FIELD_GET/FIELD_PREP macros instead.

[...]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-04-23 13:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-23  8:51 [RFC PATCH 1/1] net: dwc_eth_qos: mdio: Implement clause 45 Philip Oberfichtner
2024-04-23 12:52 ` Marek Vasut

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox