Commit 3c219cc2 authored by Jerome Brunet's avatar Jerome Brunet Committed by sanglipeng
Browse files

net: mdio-mux-meson-g12a: force internal PHY off on mux switch

stable inclusion
from stable-v5.10.166
commit 7ff8128bb11651dde6cb45821bd2665790a173b6
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7TH9O

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7ff8128bb11651dde6cb45821bd2665790a173b6



--------------------------------

[ Upstream commit 7083df59 ]

Force the internal PHY off then on when switching to the internal path.
This fixes problems where the PHY ID is not properly set.

Fixes: 70904251 ("net: phy: add amlogic g12a mdio mux support")
Suggested-by: default avatarQi Duan <qi.duan@amlogic.com>
Co-developed-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: default avatarJerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20230124101157.232234-1-jbrunet@baylibre.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarsanglipeng <sanglipeng1@jd.com>
parent 00f52ee1
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 */

#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
@@ -150,6 +151,7 @@ static const struct clk_ops g12a_ephy_pll_ops = {

static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)
{
	u32 value;
	int ret;

	/* Enable the phy clock */
@@ -163,18 +165,25 @@ static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)

	/* Initialize ephy control */
	writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0);
	writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |

	/* Make sure we get a 0 -> 1 transition on the enable bit */
	value = FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
		FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
		FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
		PHY_CNTL1_CLK_EN |
	       PHY_CNTL1_CLKFREQ |
	       PHY_CNTL1_PHY_ENB,
	       priv->regs + ETH_PHY_CNTL1);
		PHY_CNTL1_CLKFREQ;
	writel(value, priv->regs + ETH_PHY_CNTL1);
	writel(PHY_CNTL2_USE_INTERNAL |
	       PHY_CNTL2_SMI_SRC_MAC |
	       PHY_CNTL2_RX_CLK_EPHY,
	       priv->regs + ETH_PHY_CNTL2);

	value |= PHY_CNTL1_PHY_ENB;
	writel(value, priv->regs + ETH_PHY_CNTL1);

	/* The phy needs a bit of time to power up */
	mdelay(10);

	return 0;
}