From: Yang Xiwen <[email protected]>

setbits() only sets the specified bits and leave other bits untouched.
This is incorrect for ETH_REG_0_TX_PHASE and ETH_REG_0_TX_RATIO fields
assignment. They contain multiple bits and should be cleared before
setting new bits. Otherwize the old value is OR'ed with the new value.
(e.g. 0x2 | 0x4 becomes 0x6)

Signed-off-by: Yang Xiwen <[email protected]>
---
 drivers/net/dwmac_meson8b.c | 48 ++++++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/net/dwmac_meson8b.c b/drivers/net/dwmac_meson8b.c
index fde4aabbacec..b1a3946ce684 100644
--- a/drivers/net/dwmac_meson8b.c
+++ b/drivers/net/dwmac_meson8b.c
@@ -16,7 +16,9 @@
 #define ETH_REG_3              0x1c
 
 #define GX_ETH_REG_0_PHY_INTF          BIT(0)
+#define GX_ETH_REG_0_TX_PHASE_MASK     GENMASK(6, 5)
 #define GX_ETH_REG_0_TX_PHASE(x)       (((x) & 3) << 5)
+#define GX_ETH_REG_0_TX_RATIO_MASK     GENMASK(9, 7)
 #define GX_ETH_REG_0_TX_RATIO(x)       (((x) & 7) << 7)
 #define GX_ETH_REG_0_PHY_CLK_EN        BIT(10)
 #define GX_ETH_REG_0_INVERT_RMII_CLK   BIT(11)
@@ -24,7 +26,9 @@
 
 #define AXG_ETH_REG_0_PHY_INTF_RGMII   BIT(0)
 #define AXG_ETH_REG_0_PHY_INTF_RMII    BIT(2)
+#define AXG_ETH_REG_0_TX_PHASE_MASK    GENMASK(6, 5)
 #define AXG_ETH_REG_0_TX_PHASE(x)      (((x) & 3) << 5)
+#define AXG_ETH_REG_0_TX_RATIO_MASK    GENMASK(9, 7)
 #define AXG_ETH_REG_0_TX_RATIO(x)      (((x) & 7) << 7)
 #define AXG_ETH_REG_0_PHY_CLK_EN       BIT(10)
 #define AXG_ETH_REG_0_INVERT_RMII_CLK  BIT(11)
@@ -59,20 +63,24 @@ static int dwmac_setup_axg(struct udevice *dev, struct 
eth_pdata *edata)
        case PHY_INTERFACE_MODE_RGMII:
        case PHY_INTERFACE_MODE_RGMII_ID:
                /* Set RGMII mode */
-               setbits_le32(plat->regs + ETH_REG_0, 
AXG_ETH_REG_0_PHY_INTF_RGMII |
-                                                    AXG_ETH_REG_0_TX_PHASE(1) |
-                                                    AXG_ETH_REG_0_TX_RATIO(4) |
-                                                    AXG_ETH_REG_0_PHY_CLK_EN |
-                                                    AXG_ETH_REG_0_CLK_EN);
+               clrsetbits_le32(plat->regs + ETH_REG_0,
+                               AXG_ETH_REG_0_TX_PHASE_MASK | 
AXG_ETH_REG_0_TX_RATIO_MASK,
+                               AXG_ETH_REG_0_PHY_INTF_RGMII |
+                               AXG_ETH_REG_0_TX_PHASE(1) |
+                               AXG_ETH_REG_0_TX_RATIO(4) |
+                               AXG_ETH_REG_0_PHY_CLK_EN |
+                               AXG_ETH_REG_0_CLK_EN);
                break;
 
        case PHY_INTERFACE_MODE_RGMII_RXID:
        case PHY_INTERFACE_MODE_RGMII_TXID:
                /* TOFIX: handle amlogic,tx-delay-ns & rx-internal-delay-ps 
from DT */
-               setbits_le32(plat->regs + ETH_REG_0, 
AXG_ETH_REG_0_PHY_INTF_RGMII |
-                                                    AXG_ETH_REG_0_TX_RATIO(4) |
-                                                    AXG_ETH_REG_0_PHY_CLK_EN |
-                                                    AXG_ETH_REG_0_CLK_EN);
+               clrsetbits_le32(plat->regs + ETH_REG_0,
+                               AXG_ETH_REG_0_TX_PHASE_MASK | 
AXG_ETH_REG_0_TX_RATIO_MASK,
+                               AXG_ETH_REG_0_PHY_INTF_RGMII |
+                               AXG_ETH_REG_0_TX_RATIO(4) |
+                               AXG_ETH_REG_0_PHY_CLK_EN |
+                               AXG_ETH_REG_0_CLK_EN);
                break;
 
        case PHY_INTERFACE_MODE_RMII:
@@ -97,21 +105,25 @@ static int dwmac_setup_gx(struct udevice *dev, struct 
eth_pdata *edata)
        case PHY_INTERFACE_MODE_RGMII:
        case PHY_INTERFACE_MODE_RGMII_ID:
                /* Set RGMII mode */
-               setbits_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
-                                                    GX_ETH_REG_0_TX_PHASE(1) |
-                                                    GX_ETH_REG_0_TX_RATIO(4) |
-                                                    GX_ETH_REG_0_PHY_CLK_EN |
-                                                    GX_ETH_REG_0_CLK_EN);
+               clrsetbits_le32(plat->regs + ETH_REG_0,
+                               GX_ETH_REG_0_TX_PHASE_MASK | 
GX_ETH_REG_0_TX_RATIO_MASK,
+                               GX_ETH_REG_0_PHY_INTF |
+                               GX_ETH_REG_0_TX_PHASE(1) |
+                               GX_ETH_REG_0_TX_RATIO(4) |
+                               GX_ETH_REG_0_PHY_CLK_EN |
+                               GX_ETH_REG_0_CLK_EN);
 
                break;
 
        case PHY_INTERFACE_MODE_RGMII_RXID:
        case PHY_INTERFACE_MODE_RGMII_TXID:
                /* TOFIX: handle amlogic,tx-delay-ns & rx-internal-delay-ps 
from DT */
-               setbits_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
-                                                    GX_ETH_REG_0_TX_RATIO(4) |
-                                                    GX_ETH_REG_0_PHY_CLK_EN |
-                                                    GX_ETH_REG_0_CLK_EN);
+               clrsetbits_le32(plat->regs + ETH_REG_0,
+                               GX_ETH_REG_0_TX_PHASE_MASK | 
GX_ETH_REG_0_TX_RATIO_MASK,
+                               GX_ETH_REG_0_PHY_INTF |
+                               GX_ETH_REG_0_TX_RATIO(4) |
+                               GX_ETH_REG_0_PHY_CLK_EN |
+                               GX_ETH_REG_0_CLK_EN);
 
                break;
 

-- 
2.43.0


Reply via email to