Skip to content

Commit 72e5f5a

Browse files
Merge patch series "can: fsl,flexcan: add imx95 wakeup"
The flexcan in iMX95 is not compatible with imx93 because wakeup method is difference. Link: https://lore.kernel.org/all/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
2 parents ef5e8d3 + 5b512f4 commit 72e5f5a

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ properties:
1717
compatible:
1818
oneOf:
1919
- enum:
20+
- fsl,imx95-flexcan
2021
- fsl,imx93-flexcan
2122
- fsl,imx8qm-flexcan
2223
- fsl,imx8mp-flexcan
@@ -38,9 +39,6 @@ properties:
3839
- fsl,imx6ul-flexcan
3940
- fsl,imx6sx-flexcan
4041
- const: fsl,imx6q-flexcan
41-
- items:
42-
- const: fsl,imx95-flexcan
43-
- const: fsl,imx93-flexcan
4442
- items:
4543
- enum:
4644
- fsl,ls1028ar1-flexcan

drivers/net/can/flexcan/flexcan-core.c

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
357365
static 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);

drivers/net/can/flexcan/flexcan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
#define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR BIT(15)
6969
/* Device supports RX via FIFO */
7070
#define FLEXCAN_QUIRK_SUPPORT_RX_FIFO BIT(16)
71+
/* Setup stop mode with ATF SCMI protocol to support wakeup */
72+
#define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI BIT(17)
7173

7274
struct flexcan_devtype_data {
7375
u32 quirks; /* quirks needed for different IP cores */

0 commit comments

Comments
 (0)