Commit c8810470 authored by Marc Kleine-Budde's avatar Marc Kleine-Budde
Browse files

Merge patch series "arm64: dts: imx93: add the Flex-CAN stop mode by GPR"

Adopt FlexCAN stop mode to new A1 revision of imx93 SoCs.

Link: https://lore.kernel.org/all/20230726112458.3524165-1-haibo.chen@nxp.com


Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parents a9967c9a 63ead535
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@
			#size-cells = <1>;
			ranges;

			anomix_ns_gpr: syscon@44210000 {
			aonmix_ns_gpr: syscon@44210000 {
				compatible = "fsl,imx93-aonmix-ns-syscfg", "syscon";
				reg = <0x44210000 0x1000>;
			};
@@ -319,6 +319,7 @@
				assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
				assigned-clock-rates = <40000000>;
				fsl,clk-source = /bits/ 8 <0>;
				fsl,stop-mode = <&aonmix_ns_gpr 0x14 0>;
				status = "disabled";
			};

@@ -591,6 +592,7 @@
				assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
				assigned-clock-rates = <40000000>;
				fsl,clk-source = /bits/ 8 <0>;
				fsl,stop-mode = <&wakeupmix_gpr 0x0c 2>;
				status = "disabled";
			};

+13 −33
Original line number Diff line number Diff line
@@ -348,7 +348,7 @@ static struct flexcan_devtype_data fsl_imx8mp_devtype_data = {
static struct flexcan_devtype_data fsl_imx93_devtype_data = {
	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX |
		FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_AUTO_STOP_MODE |
		FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR |
		FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC |
		FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
		FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR,
@@ -544,11 +544,6 @@ static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv)
	} else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) {
		regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
				   1 << priv->stm.req_bit, 1 << priv->stm.req_bit);
	} else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE) {
		/* For the auto stop mode, software do nothing, hardware will cover
		 * all the operation automatically after system go into low power mode.
		 */
		return 0;
	}

	return flexcan_low_power_enter_ack(priv);
@@ -574,12 +569,6 @@ static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv)
	reg_mcr &= ~FLEXCAN_MCR_SLF_WAK;
	priv->write(reg_mcr, &regs->mcr);

	/* For the auto stop mode, hardware will exist stop mode
	 * automatically after system go out of low power mode.
	 */
	if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)
		return 0;

	return flexcan_low_power_exit_ack(priv);
}

@@ -1994,13 +1983,18 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev)
		ret = flexcan_setup_stop_mode_scfw(pdev);
	else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR)
		ret = flexcan_setup_stop_mode_gpr(pdev);
	else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)
		ret = 0;
	else
		/* return 0 directly if doesn't support stop mode feature */
		return 0;

	if (ret)
	/* If ret is -EINVAL, this means SoC claim to support stop mode, but
	 * dts file lack the stop mode property definition. For this case,
	 * directly return 0, this will skip the wakeup capable setting and
	 * will not block the driver probe.
	 */
	if (ret == -EINVAL)
		return 0;
	else if (ret)
		return ret;

	device_set_wakeup_capable(&pdev->dev, true);
@@ -2320,16 +2314,8 @@ static int __maybe_unused flexcan_noirq_suspend(struct device *device)
	if (netif_running(dev)) {
		int err;

		if (device_may_wakeup(device)) {
		if (device_may_wakeup(device))
			flexcan_enable_wakeup_irq(priv, true);
			/* For auto stop mode, need to keep the clock on before
			 * system go into low power mode. After system go into
			 * low power mode, hardware will config the flexcan into
			 * stop mode, and gate off the clock automatically.
			 */
			if (priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)
				return 0;
		}

		err = pm_runtime_force_suspend(device);
		if (err)
@@ -2347,15 +2333,9 @@ static int __maybe_unused flexcan_noirq_resume(struct device *device)
	if (netif_running(dev)) {
		int err;

		/* For the wakeup in auto stop mode, no need to gate on the
		 * clock here, hardware will do this automatically.
		 */
		if (!(device_may_wakeup(device) &&
		      priv->devtype_data.quirks & FLEXCAN_QUIRK_AUTO_STOP_MODE)) {
		err = pm_runtime_force_resume(device);
		if (err)
			return err;
		}

		if (device_may_wakeup(device))
			flexcan_enable_wakeup_irq(priv, false);
+0 −2
Original line number Diff line number Diff line
@@ -68,8 +68,6 @@
#define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR BIT(15)
/* Device supports RX via FIFO */
#define FLEXCAN_QUIRK_SUPPORT_RX_FIFO BIT(16)
/* auto enter stop mode to support wakeup */
#define FLEXCAN_QUIRK_AUTO_STOP_MODE BIT(17)

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