Message ID | 20230123135037.195157-1-jbrunet@baylibre.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [net] net: mdio-mux-meson-g12a: force internal PHY off on mux switch | expand |
On Mon, Jan 23, 2023 at 02:50:37PM +0100, Jerome Brunet wrote: > 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: 7090425104db ("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> > --- > > The initial discussion about this change can be found here: > https://lore.kernel.org/all/1j4jslwen5.fsf@starbuckisacylon.baylibre.com/ > > drivers/net/mdio/mdio-mux-meson-g12a.c | 23 ++++++++++++++++------- > 1 file changed, 16 insertions(+), 7 deletions(-) > > diff --git a/drivers/net/mdio/mdio-mux-meson-g12a.c b/drivers/net/mdio/mdio-mux-meson-g12a.c > index 4a2e94faf57e..da61f00a6666 100644 > --- a/drivers/net/mdio/mdio-mux-meson-g12a.c > +++ b/drivers/net/mdio/mdio-mux-meson-g12a.c > @@ -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> > @@ -151,6 +152,7 @@ static const struct clk_ops g12a_ephy_pll_ops = { > static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv) > { > int ret; > + u32 value; Reverse Christmas tree please. Longest first, shortest last. Andrew
diff --git a/drivers/net/mdio/mdio-mux-meson-g12a.c b/drivers/net/mdio/mdio-mux-meson-g12a.c index 4a2e94faf57e..da61f00a6666 100644 --- a/drivers/net/mdio/mdio-mux-meson-g12a.c +++ b/drivers/net/mdio/mdio-mux-meson-g12a.c @@ -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> @@ -151,6 +152,7 @@ static const struct clk_ops g12a_ephy_pll_ops = { static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv) { int ret; + u32 value; /* Enable the phy clock */ if (!priv->pll_is_enabled) { @@ -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) | - 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); + + /* 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; + 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; }