net: mdio-mux-meson-g12a: force internal PHY off on mux switch
[ Upstream commit7083df59ab] 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:7090425104("net: phy: add amlogic g12a mdio mux support") Suggested-by: Qi Duan <qi.duan@amlogic.com> Co-developed-by: Heiner Kallweit <hkallweit1@gmail.com> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> Link: https://lore.kernel.org/r/20230124101157.232234-1-jbrunet@baylibre.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
62a0806eb4
commit
7ff8128bb1
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/bitfield.h>
|
#include <linux/bitfield.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/device.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)
|
static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)
|
||||||
{
|
{
|
||||||
|
u32 value;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Enable the phy clock */
|
/* Enable the phy clock */
|
||||||
@@ -163,18 +165,25 @@ static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)
|
|||||||
|
|
||||||
/* Initialize ephy control */
|
/* Initialize ephy control */
|
||||||
writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0);
|
writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0);
|
||||||
writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
|
|
||||||
FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
|
/* Make sure we get a 0 -> 1 transition on the enable bit */
|
||||||
FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
|
value = FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
|
||||||
PHY_CNTL1_CLK_EN |
|
FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
|
||||||
PHY_CNTL1_CLKFREQ |
|
FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
|
||||||
PHY_CNTL1_PHY_ENB,
|
PHY_CNTL1_CLK_EN |
|
||||||
priv->regs + ETH_PHY_CNTL1);
|
PHY_CNTL1_CLKFREQ;
|
||||||
|
writel(value, priv->regs + ETH_PHY_CNTL1);
|
||||||
writel(PHY_CNTL2_USE_INTERNAL |
|
writel(PHY_CNTL2_USE_INTERNAL |
|
||||||
PHY_CNTL2_SMI_SRC_MAC |
|
PHY_CNTL2_SMI_SRC_MAC |
|
||||||
PHY_CNTL2_RX_CLK_EPHY,
|
PHY_CNTL2_RX_CLK_EPHY,
|
||||||
priv->regs + ETH_PHY_CNTL2);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user