@@ -354,6 +354,14 @@ static struct flexcan_devtype_data fsl_imx93_devtype_data = {
354354 FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR ,
355355};
356356
357+ static const struct flexcan_devtype_data fsl_imx95_devtype_data = {
358+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
359+ FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX |
360+ FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SUPPORT_FD |
361+ FLEXCAN_QUIRK_SUPPORT_ECC | FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
362+ FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR | FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI ,
363+ };
364+
357365static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
358366 .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
359367 FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX |
@@ -544,6 +552,13 @@ static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv)
544552 } else if (priv -> devtype_data .quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR ) {
545553 regmap_update_bits (priv -> stm .gpr , priv -> stm .req_gpr ,
546554 1 << priv -> stm .req_bit , 1 << priv -> stm .req_bit );
555+ } else if (priv -> devtype_data .quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI ) {
556+ /* For the SCMI mode, driver do nothing, ATF will send request to
557+ * SM(system manager, M33 core) through SCMI protocol after linux
558+ * suspend. Once SM get this request, it will send IPG_STOP signal
559+ * to Flex_CAN, let CAN in STOP mode.
560+ */
561+ return 0 ;
547562 }
548563
549564 return flexcan_low_power_enter_ack (priv );
@@ -555,7 +570,11 @@ static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv)
555570 u32 reg_mcr ;
556571 int ret ;
557572
558- /* remove stop request */
573+ /* Remove stop request, for FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI,
574+ * do nothing here, because ATF already send request to SM before
575+ * linux resume. Once SM get this request, it will deassert the
576+ * IPG_STOP signal to Flex_CAN.
577+ */
559578 if (priv -> devtype_data .quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW ) {
560579 ret = flexcan_stop_mode_enable_scfw (priv , false);
561580 if (ret < 0 )
@@ -1983,6 +2002,9 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev)
19832002 ret = flexcan_setup_stop_mode_scfw (pdev );
19842003 else if (priv -> devtype_data .quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR )
19852004 ret = flexcan_setup_stop_mode_gpr (pdev );
2005+ else if (priv -> devtype_data .quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI )
2006+ /* ATF will handle all STOP_IPG related work */
2007+ ret = 0 ;
19862008 else
19872009 /* return 0 directly if doesn't support stop mode feature */
19882010 return 0 ;
@@ -2009,6 +2031,7 @@ static const struct of_device_id flexcan_of_match[] = {
20092031 { .compatible = "fsl,imx8qm-flexcan" , .data = & fsl_imx8qm_devtype_data , },
20102032 { .compatible = "fsl,imx8mp-flexcan" , .data = & fsl_imx8mp_devtype_data , },
20112033 { .compatible = "fsl,imx93-flexcan" , .data = & fsl_imx93_devtype_data , },
2034+ { .compatible = "fsl,imx95-flexcan" , .data = & fsl_imx95_devtype_data , },
20122035 { .compatible = "fsl,imx6q-flexcan" , .data = & fsl_imx6q_devtype_data , },
20132036 { .compatible = "fsl,imx28-flexcan" , .data = & fsl_imx28_devtype_data , },
20142037 { .compatible = "fsl,imx53-flexcan" , .data = & fsl_imx25_devtype_data , },
@@ -2309,9 +2332,19 @@ static int __maybe_unused flexcan_noirq_suspend(struct device *device)
23092332 if (device_may_wakeup (device ))
23102333 flexcan_enable_wakeup_irq (priv , true);
23112334
2312- err = pm_runtime_force_suspend (device );
2313- if (err )
2314- return err ;
2335+ /* For FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI, it need ATF to send
2336+ * to SM through SCMI protocol, SM will assert the IPG_STOP
2337+ * signal. But all this works need the CAN clocks keep on.
2338+ * After the CAN module get the IPG_STOP mode, and switch to
2339+ * STOP mode, whether still keep the CAN clocks on or gate them
2340+ * off depend on the Hardware design.
2341+ */
2342+ if (!(device_may_wakeup (device ) &&
2343+ priv -> devtype_data .quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI )) {
2344+ err = pm_runtime_force_suspend (device );
2345+ if (err )
2346+ return err ;
2347+ }
23152348 }
23162349
23172350 return 0 ;
@@ -2325,9 +2358,12 @@ static int __maybe_unused flexcan_noirq_resume(struct device *device)
23252358 if (netif_running (dev )) {
23262359 int err ;
23272360
2328- err = pm_runtime_force_resume (device );
2329- if (err )
2330- return err ;
2361+ if (!(device_may_wakeup (device ) &&
2362+ priv -> devtype_data .quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI )) {
2363+ err = pm_runtime_force_resume (device );
2364+ if (err )
2365+ return err ;
2366+ }
23312367
23322368 if (device_may_wakeup (device ))
23332369 flexcan_enable_wakeup_irq (priv , false);
0 commit comments