Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: flexcan: remove the auto stop mode for IMX93

IMX93 A0 chip involve the internal q-channel handshake in LPCG and
CCM to automatically handle the Flex-CAN IPG STOP signal. Only after
FLEX-CAN enter stop mode then can support the self-wakeup feature.
But meet issue when do the continue system PM stress test. When config
the CAN as wakeup source, the first time after system suspend, any data
on CAN bus can wakeup the system, this is as expect. But the second time
when system suspend, data on CAN bus can't wakeup the system. If continue
this test, we find in odd time system enter suspend, CAN can wakeup the
system, but in even number system enter suspend, CAN can't wakeup the
system. IC find a bug in the auto stop mode logic, and can't fix it easily.
So for the new imx93 A1, IC drop the auto stop mode and involve the
GPR to support stop mode (used before). IC define a bit in GPR which can
trigger the IPG STOP signal to Flex-CAN, let it go into stop mode.
And NXP claim to drop IMX93 A0, and only support IMX93 A1. So this patch
remove the auto stop mode, and add flag FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR
to imx93.

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Link: https://lore.kernel.org/all/20230726112458.3524165-2-haibo.chen@nxp.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Haibo Chen and committed by
Marc Kleine-Budde
63ead535 23ed2be5

+13 -35
+13 -33
drivers/net/can/flexcan/flexcan-core.c
··· 348 348 static struct flexcan_devtype_data fsl_imx93_devtype_data = { 349 349 .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | 350 350 FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX | 351 - FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_AUTO_STOP_MODE | 351 + FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR | 352 352 FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC | 353 353 FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX | 354 354 FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR, ··· 544 544 } else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) { 545 545 regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, 546 546 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); 547 - } else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE) { 548 - /* For the auto stop mode, software do nothing, hardware will cover 549 - * all the operation automatically after system go into low power mode. 550 - */ 551 - return 0; 552 547 } 553 548 554 549 return flexcan_low_power_enter_ack(priv); ··· 568 573 reg_mcr = priv->read(&regs->mcr); 569 574 reg_mcr &= ~FLEXCAN_MCR_SLF_WAK; 570 575 priv->write(reg_mcr, &regs->mcr); 571 - 572 - /* For the auto stop mode, hardware will exist stop mode 573 - * automatically after system go out of low power mode. 574 - */ 575 - if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE) 576 - return 0; 577 576 578 577 return flexcan_low_power_exit_ack(priv); 579 578 } ··· 1983 1994 ret = flexcan_setup_stop_mode_scfw(pdev); 1984 1995 else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) 1985 1996 ret = flexcan_setup_stop_mode_gpr(pdev); 1986 - else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE) 1987 - ret = 0; 1988 1997 else 1989 1998 /* return 0 directly if doesn't support stop mode feature */ 1990 1999 return 0; 1991 2000 1992 - if (ret) 2001 + /* If ret is -EINVAL, this means SoC claim to support stop mode, but 2002 + * dts file lack the stop mode property definition. For this case, 2003 + * directly return 0, this will skip the wakeup capable setting and 2004 + * will not block the driver probe. 2005 + */ 2006 + if (ret == -EINVAL) 2007 + return 0; 2008 + else if (ret) 1993 2009 return ret; 1994 2010 1995 2011 device_set_wakeup_capable(&pdev->dev, true); ··· 2314 2320 if (netif_running(dev)) { 2315 2321 int err; 2316 2322 2317 - if (device_may_wakeup(device)) { 2323 + if (device_may_wakeup(device)) 2318 2324 flexcan_enable_wakeup_irq(priv, true); 2319 - /* For auto stop mode, need to keep the clock on before 2320 - * system go into low power mode. After system go into 2321 - * low power mode, hardware will config the flexcan into 2322 - * stop mode, and gate off the clock automatically. 2323 - */ 2324 - if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE) 2325 - return 0; 2326 - } 2327 2325 2328 2326 err = pm_runtime_force_suspend(device); 2329 2327 if (err) ··· 2333 2347 if (netif_running(dev)) { 2334 2348 int err; 2335 2349 2336 - /* For the wakeup in auto stop mode, no need to gate on the 2337 - * clock here, hardware will do this automatically. 2338 - */ 2339 - if (!(device_may_wakeup(device) && 2340 - priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)) { 2341 - err = pm_runtime_force_resume(device); 2342 - if (err) 2343 - return err; 2344 - } 2350 + err = pm_runtime_force_resume(device); 2351 + if (err) 2352 + return err; 2345 2353 2346 2354 if (device_may_wakeup(device)) 2347 2355 flexcan_enable_wakeup_irq(priv, false);
-2
drivers/net/can/flexcan/flexcan.h
··· 68 68 #define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR BIT(15) 69 69 /* Device supports RX via FIFO */ 70 70 #define FLEXCAN_QUIRK_SUPPORT_RX_FIFO BIT(16) 71 - /* auto enter stop mode to support wakeup */ 72 - #define FLEXCAN_QUIRK_AUTO_STOP_MODE BIT(17) 73 71 74 72 struct flexcan_devtype_data { 75 73 u32 quirks; /* quirks needed for different IP cores */