can: mcp251xfd: mcp251xfd_chip_wait_for_osc_ready(): prepare for PLL support
authorMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 22 Oct 2020 21:13:42 +0000 (23:13 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 24 Feb 2022 07:46:58 +0000 (08:46 +0100)
The function mcp251xfd_chip_wait_for_osc_ready() polls the Oscillator
Control Register for the oscillator to get ready. By passing the
appropriate parameters (osc_reference and osc_mask) it can also poll
for PLL ready.

This patch adjusts the error message if the Oscillator and/or PLL fail
to get ready.

Link: https://lore.kernel.org/all/20220207131047.282110-9-mkl@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c

index 68518e8410dde2ec632dac4763fb0f4130645a44..f2aac990d28578c128aa0bc0722904276dd6be7d 100644 (file)
@@ -112,6 +112,22 @@ static const char *mcp251xfd_get_mode_str(const u8 mode)
        return "<unknown>";
 }
 
+static const char *
+mcp251xfd_get_osc_str(const u32 osc, const u32 osc_reference)
+{
+       switch (~osc & osc_reference &
+               (MCP251XFD_REG_OSC_OSCRDY | MCP251XFD_REG_OSC_PLLRDY)) {
+       case MCP251XFD_REG_OSC_PLLRDY:
+               return "PLL";
+       case MCP251XFD_REG_OSC_OSCRDY:
+               return "Oscillator";
+       case MCP251XFD_REG_OSC_PLLRDY | MCP251XFD_REG_OSC_OSCRDY:
+               return "Oscillator/PLL";
+       }
+
+       return "<unknown>";
+}
+
 static inline int mcp251xfd_vdd_enable(const struct mcp251xfd_priv *priv)
 {
        if (!priv->reg_vdd)
@@ -269,8 +285,9 @@ mcp251xfd_chip_wait_for_osc_ready(const struct mcp251xfd_priv *priv,
        }
 
        netdev_err(priv->ndev,
-                  "Timeout waiting for Oscillator Ready (osc=0x%08x, osc_reference=0x%08x)\n",
-                  osc, osc_reference);
+                  "Timeout waiting for %s ready (osc=0x%08x, osc_reference=0x%08x, osc_mask=0x%08x).\n",
+                  mcp251xfd_get_osc_str(osc, osc_reference),
+                  osc, osc_reference, osc_mask);
 
        return -ETIMEDOUT;
 }
@@ -298,6 +315,10 @@ static int mcp251xfd_chip_clock_enable(const struct mcp251xfd_priv *priv)
        if (err)
                return err;
 
+       /* Sometimes the PLL is stuck enabled, the controller never
+        * sets the OSC Ready bit, and we get an -ETIMEDOUT. Our
+        * caller takes care of retry.
+        */
        return mcp251xfd_chip_wait_for_osc_ready(priv, osc_reference, osc_mask);
 }