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

