imx.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] remoteproc: imx_rproc: Support i.MX95
@ 2025-10-31  2:24 Peng Fan
  2025-10-31  2:24 ` [PATCH v2 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95 Peng Fan
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: Peng Fan @ 2025-10-31  2:24 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan, Frank Li, Krzysztof Kozlowski

This patchset is pick up a previous patchset [1] with rebased on
next-20251030, and some changes applied.
 - Add runtime ops to separate cpu ops and lmm ops
 - added more comments
 - moved some check imx_sm_rproc_detect_mode() from imx_rproc_sm_prepare().

No changes to the dt-binding patch, so R-b/A-b are kept.
More info could be found in commit message of each patch and below.

[1]https://lore.kernel.org/linux-remoteproc/20250821-imx95-rproc-1-v5-0-e93191dfac51@nxp.com/

i.MX95 features a Cortex-M33 core, six Cortex-A55 cores, and
one Cortex-M7 core. The System Control Management Interface(SCMI)
firmware runs on the M33 core. The i.MX95 SCMI firmware named System
Manager(SM) includes vendor extension protocols, Logical Machine
Management(LMM) protocol and CPU protocol and etc.

There are three cases for M7:
(1) M7 in a separate Logical Machine(LM) that Linux couldn't control it.
(2) M7 in a separate Logical Machine that Linux could control it using
    LMM protocol
(3) M7 runs in same Logical Machine as A55, so Linux could control it
    using CPU protocol

In patch 3, Use LMM and CPU protocol to manage M7. More info could be
found in the patch commit log

Current setup relies on pre-Linux software(U-Boot) to do
M7 TCM ECC initialization. In future, we could add the support in Linux

Patchset was tested with below boot images when the patchset based on next-20251030:
imx-boot-variant-rpmsg-imx95-19x19-lpddr5-evk-sd.bin-flash_lpboot_sm_a55 (Use LMM protocol)
imx-boot-variant-alt-imx95-19x19-lpddr5-evk-sd.bin-flash_alt (Use CPU protocol)
imx-boot-imx95-19x19-lpddr5-evk-sd.bin-flash_all (M7 not under A55 control)

Also tested i.MX8MP/8ULP-EVK.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Changes in v2:
- Patch 2: Change to const pointer for ops, update commit log and add R-b from Frank
- Patch 3: New patch, introduce prepare ops
- Patch 4: Rename imx_rproc_sm_prepare to imx_rproc_sm_lmm_prepare
           drop IMX_RPROC_FLAGS_SM_CPU_OP and IMX_RPROC_FLAGS_SM_LMM_OP
           Add a bool for dcfg->lmid and info->lmid check.
	   Provide separate plat ops for lmm and cpu setup.
	   Move LM permission check to a separate function.
- Patch 5: Drop macro IMX95_M7_CPUID and IMX95_M7_LMID
- Link to v1: https://lore.kernel.org/r/20251028-imx95-rproc-2025-10-28-v1-0-ce9e7db9edcb@nxp.com

---
Peng Fan (5):
      dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95
      remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior
      remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
      remoteproc: imx_rproc: Add support for System Manager API
      remoteproc: imx_rproc: Add support for i.MX95

 .../bindings/remoteproc/fsl,imx-rproc.yaml         |   1 +
 drivers/remoteproc/Kconfig                         |   2 +
 drivers/remoteproc/imx_rproc.c                     | 244 +++++++++++++++++++--
 drivers/remoteproc/imx_rproc.h                     |   4 +
 4 files changed, 237 insertions(+), 14 deletions(-)
---
base-commit: 131f3d9446a6075192cdd91f197989d98302faa6
change-id: 20251031-imx95-rproc-2025-10-31-34b7d0587fbd

Best regards,
-- 
Peng Fan <peng.fan@nxp.com>


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95
  2025-10-31  2:24 [PATCH v2 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan
@ 2025-10-31  2:24 ` Peng Fan
  2025-10-31  2:24 ` [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior Peng Fan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Peng Fan @ 2025-10-31  2:24 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan, Frank Li, Krzysztof Kozlowski

Add compatible string for the Cortex-M7 core in i.MX95

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
index 57d75acb0b5e52ca49d1361176fdebc18a0bf7a2..ce8ec0119469c8fc0979a192b6e3d3a03108d7d2 100644
--- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
@@ -28,6 +28,7 @@ properties:
       - fsl,imx8qxp-cm4
       - fsl,imx8ulp-cm33
       - fsl,imx93-cm33
+      - fsl,imx95-cm7
 
   clocks:
     maxItems: 1

-- 
2.37.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior
  2025-10-31  2:24 [PATCH v2 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan
  2025-10-31  2:24 ` [PATCH v2 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95 Peng Fan
@ 2025-10-31  2:24 ` Peng Fan
  2025-11-04  9:43   ` Iuliana Prodan
  2025-11-07  7:54   ` Daniel Baluta
  2025-10-31  2:24 ` [PATCH v2 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg Peng Fan
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 19+ messages in thread
From: Peng Fan @ 2025-10-31  2:24 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan, Frank Li

Structure imx_rproc_dcfg contains a const pointer to imx_rproc_plat_ops,
which defines the start/stop/detect_mode operations for a remote processor.
To preserve the const correctness of the static configuration while
allowing runtime modification of ops behavior, introduce a new
imx_rproc_plat_ops member in struct imx_rproc named `ops`.

During initialization, dcfg->ops is assigned to priv->ops.
Enable the driver to safely override ops at runtime without affecting the
original const configuration.

Improve flexibility for platforms that require dynamic operation switching
(e.g. i.MX95 Logical Machine ops and CPU ops).

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 02e155e967942d745de4ccd96f9008e4211f9b36..82cb8c7866ccb79061c46068d2039f38feebbb3c 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -116,6 +116,7 @@ struct imx_rproc {
 	u32				entry;		/* cpu start address */
 	u32				core_index;
 	struct dev_pm_domain_list	*pd_list;
+	const struct imx_rproc_plat_ops	*ops;
 };
 
 static const struct imx_rproc_att imx_rproc_att_imx93[] = {
@@ -315,7 +316,6 @@ static int imx_rproc_scu_api_start(struct rproc *rproc)
 static int imx_rproc_start(struct rproc *rproc)
 {
 	struct imx_rproc *priv = rproc->priv;
-	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 	struct device *dev = priv->dev;
 	int ret;
 
@@ -323,10 +323,10 @@ static int imx_rproc_start(struct rproc *rproc)
 	if (ret)
 		return ret;
 
-	if (!dcfg->ops || !dcfg->ops->start)
+	if (!priv->ops || !priv->ops->start)
 		return -EOPNOTSUPP;
 
-	ret = dcfg->ops->start(rproc);
+	ret = priv->ops->start(rproc);
 	if (ret)
 		dev_err(dev, "Failed to enable remote core!\n");
 
@@ -372,14 +372,13 @@ static int imx_rproc_scu_api_stop(struct rproc *rproc)
 static int imx_rproc_stop(struct rproc *rproc)
 {
 	struct imx_rproc *priv = rproc->priv;
-	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 	struct device *dev = priv->dev;
 	int ret;
 
-	if (!dcfg->ops || !dcfg->ops->stop)
+	if (!priv->ops || !priv->ops->stop)
 		return -EOPNOTSUPP;
 
-	ret = dcfg->ops->stop(rproc);
+	ret = priv->ops->stop(rproc);
 	if (ret)
 		dev_err(dev, "Failed to stop remote core\n");
 	else
@@ -590,12 +589,11 @@ static int imx_rproc_scu_api_detach(struct rproc *rproc)
 static int imx_rproc_detach(struct rproc *rproc)
 {
 	struct imx_rproc *priv = rproc->priv;
-	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 
-	if (!dcfg->ops || !dcfg->ops->detach)
+	if (!priv->ops || !priv->ops->detach)
 		return -EOPNOTSUPP;
 
-	return dcfg->ops->detach(rproc);
+	return priv->ops->detach(rproc);
 }
 
 static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
@@ -995,18 +993,16 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
 
 static int imx_rproc_detect_mode(struct imx_rproc *priv)
 {
-	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
-
 	/*
 	 * To i.MX{7,8} ULP, Linux is under control of RTOS, no need
-	 * dcfg->ops or dcfg->ops->detect_mode, it is state RPROC_DETACHED.
+	 * priv->ops or priv->ops->detect_mode, it is state RPROC_DETACHED.
 	 */
-	if (!dcfg->ops || !dcfg->ops->detect_mode) {
+	if (!priv->ops || !priv->ops->detect_mode) {
 		priv->rproc->state = RPROC_DETACHED;
 		return 0;
 	}
 
-	return dcfg->ops->detect_mode(priv->rproc);
+	return priv->ops->detect_mode(priv->rproc);
 }
 
 static int imx_rproc_sys_off_handler(struct sys_off_data *data)
@@ -1056,6 +1052,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
 	priv->dcfg = dcfg;
 	priv->dev = dev;
 
+	if (dcfg->ops)
+		priv->ops = dcfg->ops;
+
 	dev_set_drvdata(dev, rproc);
 	priv->workqueue = create_workqueue(dev_name(dev));
 	if (!priv->workqueue) {

-- 
2.37.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
  2025-10-31  2:24 [PATCH v2 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan
  2025-10-31  2:24 ` [PATCH v2 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95 Peng Fan
  2025-10-31  2:24 ` [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior Peng Fan
@ 2025-10-31  2:24 ` Peng Fan
  2025-10-31 19:20   ` Frank Li
  2025-11-07  7:56   ` Daniel Baluta
  2025-10-31  2:24 ` [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan
  2025-10-31  2:24 ` [PATCH v2 5/5] remoteproc: imx_rproc: Add support for i.MX95 Peng Fan
  4 siblings, 2 replies; 19+ messages in thread
From: Peng Fan @ 2025-10-31  2:24 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

Allow each platform to provide its own prepare operations, preparing
for i.MX95 LMM and CPU ops support.

No functional changes.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 5 ++++-
 drivers/remoteproc/imx_rproc.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 82cb8c7866ccb79061c46068d2039f38feebbb3c..232eb91e0b5dc2432131b1c140d6688b073fea1d 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -532,7 +532,10 @@ static int imx_rproc_prepare(struct rproc *rproc)
 		rproc_add_carveout(rproc, mem);
 	}
 
-	return  0;
+	if (priv->ops && priv->ops->prepare)
+		return priv->ops->prepare(rproc);
+
+	return 0;
 }
 
 static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
index aeed08bdfb5619c7afd7201589f417cfd6745818..e4b9ede656506142b260aa7515823f489a168ba4 100644
--- a/drivers/remoteproc/imx_rproc.h
+++ b/drivers/remoteproc/imx_rproc.h
@@ -37,6 +37,7 @@ struct imx_rproc_plat_ops {
 	int (*stop)(struct rproc *rproc);
 	int (*detach)(struct rproc *rproc);
 	int (*detect_mode)(struct rproc *rproc);
+	int (*prepare)(struct rproc *rproc);
 };
 
 struct imx_rproc_dcfg {

-- 
2.37.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API
  2025-10-31  2:24 [PATCH v2 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan
                   ` (2 preceding siblings ...)
  2025-10-31  2:24 ` [PATCH v2 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg Peng Fan
@ 2025-10-31  2:24 ` Peng Fan
  2025-10-31 19:28   ` Frank Li
                     ` (2 more replies)
  2025-10-31  2:24 ` [PATCH v2 5/5] remoteproc: imx_rproc: Add support for i.MX95 Peng Fan
  4 siblings, 3 replies; 19+ messages in thread
From: Peng Fan @ 2025-10-31  2:24 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

i.MX95 features a Cortex-M33 core, six Cortex-A55 cores, and
one Cortex-M7 core. The System Control Management Interface(SCMI)
firmware runs on the M33 core. The i.MX95 SCMI firmware named System
Manager(SM) includes vendor extension protocols, Logical Machine
Management(LMM) protocol and CPU protocol and etc.

There are three cases for M7:
 (1) M7 in a separate Logical Machine(LM) that Linux can't control it.
 (2) M7 in a separate Logical Machine that Linux can control it using
     LMM protocol
 (3) M7 runs in same Logical Machine as A55, so Linux can control it
     using CPU protocol

So extend the driver to using LMM and CPU protocol to manage the M7 core.
 - Compare linux LM ID(got using scmi_imx_lmm_info) and M7 LM ID(the ID
   is fixed as 1 in SM firmware if M7 is in a seprate LM),
   if Linux LM ID equals M7 LM ID(linux and M7 in same LM), use CPU
   protocol to start/stop. Otherwise, use LMM protocol to start/stop.
   Whether using CPU or LMM protocol to start/stop, the M7 status
   detection could use CPU protocol to detect started or not. So
   in imx_rproc_detect_mode, use scmi_imx_cpu_started to check the
   status of M7.
 - For above case (1) and (2), Use SCMI_IMX_LMM_POWER_ON to detect whether
   the M7 LM is under control of A55 LM.
 - For above case , after using SCMI_IMX_LMM_POWER_ON to check
   permission, SCMI_IMX_LMM_SHUTDOWN API should be called to shutdown
   the M7 LM to save power only when M7 LM is going to be started by
   remoteproc framework. Otherwise bypass SCMI_IMX_LMM_SHUTDOWN API if
   M7 LM is started before booting Linux.

Current setup relies on pre-Linux software(U-Boot) to do M7 TCM ECC
initialization. In future, we could add the support in Linux to decouple
U-Boot and Linux.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/Kconfig     |   2 +
 drivers/remoteproc/imx_rproc.c | 192 +++++++++++++++++++++++++++++++++++++++++
 drivers/remoteproc/imx_rproc.h |   3 +
 3 files changed, 197 insertions(+)

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48a0d3a69ed08057716f1e7ea950899f60bbe0cf..ee54436fea5ad08a9c198ce74d44ce7a9aa206de 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -27,6 +27,8 @@ config IMX_REMOTEPROC
 	tristate "i.MX remoteproc support"
 	depends on ARCH_MXC
 	depends on HAVE_ARM_SMCCC
+	depends on IMX_SCMI_CPU_DRV || !IMX_SCMI_CPU_DRV
+	depends on IMX_SCMI_LMM_DRV || !IMX_SCMI_LMM_DRV
 	select MAILBOX
 	help
 	  Say y here to support iMX's remote processors via the remote
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 232eb91e0b5dc2432131b1c140d6688b073fea1d..1fb17701964ca4ee4b73d343b5ec1be8e2ee5fda 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -8,6 +8,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/firmware/imx/sci.h>
+#include <linux/firmware/imx/sm.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mailbox_client.h>
@@ -22,6 +23,7 @@
 #include <linux/reboot.h>
 #include <linux/regmap.h>
 #include <linux/remoteproc.h>
+#include <linux/scmi_imx_protocol.h>
 #include <linux/workqueue.h>
 
 #include "imx_rproc.h"
@@ -92,8 +94,12 @@ struct imx_rproc_mem {
 #define ATT_CORE_MASK   0xffff
 #define ATT_CORE(I)     BIT((I))
 
+/* Linux has permission to handle the Logical Machine of remote cores */
+#define IMX_RPROC_FLAGS_SM_LMM_AVAIL	BIT(0)
+
 static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block);
 static void imx_rproc_free_mbox(void *data);
+static int imx_rproc_sm_detect_mode(struct rproc *rproc);
 
 struct imx_rproc {
 	struct device			*dev;
@@ -117,6 +123,8 @@ struct imx_rproc {
 	u32				core_index;
 	struct dev_pm_domain_list	*pd_list;
 	const struct imx_rproc_plat_ops	*ops;
+	/* For i.MX System Manager based systems */
+	u32				flags;
 };
 
 static const struct imx_rproc_att imx_rproc_att_imx93[] = {
@@ -313,6 +321,44 @@ static int imx_rproc_scu_api_start(struct rproc *rproc)
 	return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry);
 }
 
+static int imx_rproc_sm_cpu_start(struct rproc *rproc)
+{
+	struct imx_rproc *priv = rproc->priv;
+	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+	int ret;
+
+	ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, 0, true, false, false);
+	if (ret) {
+		dev_err(priv->dev, "Failed to set reset vector cpuid(%u): %d\n", dcfg->cpuid, ret);
+		return ret;
+	}
+
+	return scmi_imx_cpu_start(dcfg->cpuid, true);
+}
+
+static int imx_rproc_sm_lmm_start(struct rproc *rproc)
+{
+	struct imx_rproc *priv = rproc->priv;
+	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	int ret;
+
+	ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid, 0, 0);
+	if (ret) {
+		dev_err(dev, "Failed to set reset vector lmid(%u), cpuid(%u): %d\n",
+			dcfg->lmid, dcfg->cpuid, ret);
+		return ret;
+	}
+
+	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_BOOT, 0);
+	if (ret) {
+		dev_err(dev, "Failed to boot lmm(%d): %d\n", dcfg->lmid, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int imx_rproc_start(struct rproc *rproc)
 {
 	struct imx_rproc *priv = rproc->priv;
@@ -369,6 +415,25 @@ static int imx_rproc_scu_api_stop(struct rproc *rproc)
 	return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry);
 }
 
+static int imx_rproc_sm_cpu_stop(struct rproc *rproc)
+{
+	struct imx_rproc *priv = rproc->priv;
+	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+
+	return scmi_imx_cpu_start(dcfg->cpuid, false);
+}
+
+static int imx_rproc_sm_lmm_stop(struct rproc *rproc)
+{
+	struct imx_rproc *priv = rproc->priv;
+	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+
+	if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL))
+		return -EACCES;
+
+	return scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0);
+}
+
 static int imx_rproc_stop(struct rproc *rproc)
 {
 	struct imx_rproc *priv = rproc->priv;
@@ -485,6 +550,37 @@ static int imx_rproc_mem_release(struct rproc *rproc,
 	return 0;
 }
 
+static int imx_rproc_sm_lmm_prepare(struct rproc *rproc)
+{
+	struct imx_rproc *priv = rproc->priv;
+	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+	int ret;
+
+	/*
+	 * IMX_RPROC_FLAGS_SM_LMM_AVAIL not set indicates Linux is not able
+	 * to start/stop rproc LM, then if rproc is not in detached state,
+	 * prepare should fail. If in detached state, this is in rproc_attach()
+	 * path.
+	 */
+	if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL)) {
+		if (rproc->state != RPROC_DETACHED)
+			return -EACCES;
+
+		return 0;
+	}
+
+	/* Power on the Logical Machine to make sure TCM is available. */
+	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
+	if (ret) {
+		dev_err(priv->dev, "Failed to power on lmm(%d): %d\n", dcfg->lmid, ret);
+		return ret;
+	}
+
+	dev_info(priv->dev, "lmm(%d) powered on by Linux\n", dcfg->lmid);
+
+	return 0;
+}
+
 static int imx_rproc_prepare(struct rproc *rproc)
 {
 	struct imx_rproc *priv = rproc->priv;
@@ -994,6 +1090,102 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
 	return 0;
 }
 
+static const struct imx_rproc_plat_ops imx_rproc_ops_sm = {
+	.detect_mode	= imx_rproc_sm_detect_mode,
+	.prepare	= imx_rproc_sm_lmm_prepare,
+	.start		= imx_rproc_sm_lmm_start,
+	.stop		= imx_rproc_sm_lmm_stop,
+};
+
+static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu = {
+	.detect_mode	= imx_rproc_sm_detect_mode,
+	.start		= imx_rproc_sm_cpu_start,
+	.stop		= imx_rproc_sm_cpu_stop,
+};
+
+static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started)
+{
+	struct imx_rproc *priv = rproc->priv;
+	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	int ret;
+
+	/*
+	 * Use power on to do permission check. If rproc is in different LM,
+	 * and linux has permission to handle the LM, set IMX_RPROC_FLAGS_SM_LMM_AVAIL.
+	 */
+	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
+	if (ret != 0) {
+		if (ret == -EACCES) {
+			/* Not under Linux Control, so only do IPC between rproc and Linux */
+			dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);
+			return 0;
+		}
+
+		dev_info(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret);
+		return ret;
+	}
+
+	priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
+
+	/* rproc was started before boot Linux and under control of Linux, directly return */
+	if (started)
+		return 0;
+
+	/* else shutdown the LM to save power */
+	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0);
+	if (ret) {
+		dev_err(dev, "shutdown lmm(%d) failed: %d\n", dcfg->lmid, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int imx_rproc_sm_detect_mode(struct rproc *rproc)
+{
+	struct imx_rproc *priv = rproc->priv;
+	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	struct scmi_imx_lmm_info info;
+	bool started = false;
+	bool is_cpu_ops;
+	int ret;
+
+	ret = scmi_imx_cpu_started(dcfg->cpuid, &started);
+	if (ret) {
+		dev_err(dev, "Failed to detect cpu(%d) status: %d\n", dcfg->cpuid, ret);
+		return ret;
+	}
+
+	if (started)
+		priv->rproc->state = RPROC_DETACHED;
+
+	/* Get current Linux Logical Machine ID */
+	ret = scmi_imx_lmm_info(LMM_ID_DISCOVER, &info);
+	if (ret) {
+		dev_err(dev, "Failed to get current LMM ID err: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * Check whether remote processor is in same Logical Machine as Linux.
+	 * If yes, use CPU protocol API to manage remote processor.
+	 * If no, use Logical Machine API to manage remote processor.
+	 */
+	is_cpu_ops = dcfg->lmid == info.lmid;
+
+	if (is_cpu_ops) {
+		priv->ops = &imx_rproc_ops_sm_cpu;
+		dev_info(dev, "Using CPU Protocol OPS\n");
+		return 0;
+	}
+
+	dev_info(dev, "Using LMM Protocol OPS\n");
+
+	return imx_rproc_sm_lmm_check(rproc, started);
+}
+
 static int imx_rproc_detect_mode(struct imx_rproc *priv)
 {
 	/*
diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
index e4b9ede656506142b260aa7515823f489a168ba4..c05bfc4528f3b7518d4f2272d15fdeab1a68c2a3 100644
--- a/drivers/remoteproc/imx_rproc.h
+++ b/drivers/remoteproc/imx_rproc.h
@@ -52,6 +52,9 @@ struct imx_rproc_dcfg {
 	enum imx_rproc_method		method;
 	u32				flags;
 	const struct imx_rproc_plat_ops	*ops;
+	/* For System Manager(SM) based SoCs, the IDs are from SM firmware */
+	u32				cpuid;
+	u32				lmid;
 };
 
 #endif /* _IMX_RPROC_H */

-- 
2.37.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 5/5] remoteproc: imx_rproc: Add support for i.MX95
  2025-10-31  2:24 [PATCH v2 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan
                   ` (3 preceding siblings ...)
  2025-10-31  2:24 ` [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan
@ 2025-10-31  2:24 ` Peng Fan
  2025-10-31 19:28   ` Frank Li
  2025-11-07  9:13   ` Daniel Baluta
  4 siblings, 2 replies; 19+ messages in thread
From: Peng Fan @ 2025-10-31  2:24 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan

Add imx_rproc_cfg_imx95_m7 and address(TCM and DDR) mapping.
Add i.MX95 of_device_id entry.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 1fb17701964ca4ee4b73d343b5ec1be8e2ee5fda..63f6362c0b8a3eebc92f2d631fe694ca7bd4c03b 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -127,6 +127,18 @@ struct imx_rproc {
 	u32				flags;
 };
 
+static const struct imx_rproc_att imx_rproc_att_imx95_m7[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	/* TCM CODE NON-SECURE */
+	{ 0x00000000, 0x203C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+	/* TCM SYS NON-SECURE*/
+	{ 0x20000000, 0x20400000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+	/* DDR */
+	{ 0x80000000, 0x80000000, 0x50000000, 0 },
+};
+
 static const struct imx_rproc_att imx_rproc_att_imx93[] = {
 	/* dev addr , sys addr  , size	    , flags */
 	/* TCM CODE NON-SECURE */
@@ -1444,6 +1456,15 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
 	.flags		= IMX_RPROC_NEED_CLKS,
 };
 
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = {
+	.att		= imx_rproc_att_imx95_m7,
+	.att_size	= ARRAY_SIZE(imx_rproc_att_imx95_m7),
+	.ops		= &imx_rproc_ops_sm,
+	/* Must align with System Manager Firmware */
+	.cpuid		= 1,
+	.lmid		= 1,
+};
+
 static const struct of_device_id imx_rproc_of_match[] = {
 	{ .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
 	{ .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
@@ -1458,6 +1479,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
 	{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
 	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
 	{ .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
+	{ .compatible = "fsl,imx95-cm7", .data = &imx_rproc_cfg_imx95_m7 },
 	{},
 };
 MODULE_DEVICE_TABLE(of, imx_rproc_of_match);

-- 
2.37.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
  2025-10-31  2:24 ` [PATCH v2 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg Peng Fan
@ 2025-10-31 19:20   ` Frank Li
  2025-11-07  7:56   ` Daniel Baluta
  1 sibling, 0 replies; 19+ messages in thread
From: Frank Li @ 2025-10-31 19:20 UTC (permalink / raw)
  To: Peng Fan
  Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On Fri, Oct 31, 2025 at 10:24:54AM +0800, Peng Fan wrote:
> Allow each platform to provide its own prepare operations, preparing
> for i.MX95 LMM and CPU ops support.
>
> No functional changes.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/remoteproc/imx_rproc.c | 5 ++++-
>  drivers/remoteproc/imx_rproc.h | 1 +
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 82cb8c7866ccb79061c46068d2039f38feebbb3c..232eb91e0b5dc2432131b1c140d6688b073fea1d 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -532,7 +532,10 @@ static int imx_rproc_prepare(struct rproc *rproc)
>  		rproc_add_carveout(rproc, mem);
>  	}
>
> -	return  0;
> +	if (priv->ops && priv->ops->prepare)
> +		return priv->ops->prepare(rproc);
> +
> +	return 0;
>  }
>
>  static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
> diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
> index aeed08bdfb5619c7afd7201589f417cfd6745818..e4b9ede656506142b260aa7515823f489a168ba4 100644
> --- a/drivers/remoteproc/imx_rproc.h
> +++ b/drivers/remoteproc/imx_rproc.h
> @@ -37,6 +37,7 @@ struct imx_rproc_plat_ops {
>  	int (*stop)(struct rproc *rproc);
>  	int (*detach)(struct rproc *rproc);
>  	int (*detect_mode)(struct rproc *rproc);
> +	int (*prepare)(struct rproc *rproc);
>  };
>
>  struct imx_rproc_dcfg {
>
> --
> 2.37.1
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API
  2025-10-31  2:24 ` [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan
@ 2025-10-31 19:28   ` Frank Li
  2025-11-04  4:28     ` Peng Fan
  2025-11-04  9:50   ` Iuliana Prodan
  2025-11-07  9:10   ` Daniel Baluta
  2 siblings, 1 reply; 19+ messages in thread
From: Frank Li @ 2025-10-31 19:28 UTC (permalink / raw)
  To: Peng Fan
  Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On Fri, Oct 31, 2025 at 10:24:55AM +0800, Peng Fan wrote:
> i.MX95 features a Cortex-M33 core, six Cortex-A55 cores, and
> one Cortex-M7 core. The System Control Management Interface(SCMI)
> firmware runs on the M33 core. The i.MX95 SCMI firmware named System
> Manager(SM) includes vendor extension protocols, Logical Machine
> Management(LMM) protocol and CPU protocol and etc.
>
> There are three cases for M7:
>  (1) M7 in a separate Logical Machine(LM) that Linux can't control it.
>  (2) M7 in a separate Logical Machine that Linux can control it using
>      LMM protocol
>  (3) M7 runs in same Logical Machine as A55, so Linux can control it
>      using CPU protocol
>
> So extend the driver to using LMM and CPU protocol to manage the M7 core.
>  - Compare linux LM ID(got using scmi_imx_lmm_info) and M7 LM ID(the ID
>    is fixed as 1 in SM firmware if M7 is in a seprate LM),
>    if Linux LM ID equals M7 LM ID(linux and M7 in same LM), use CPU
>    protocol to start/stop. Otherwise, use LMM protocol to start/stop.
>    Whether using CPU or LMM protocol to start/stop, the M7 status
>    detection could use CPU protocol to detect started or not. So
>    in imx_rproc_detect_mode, use scmi_imx_cpu_started to check the
>    status of M7.
>  - For above case (1) and (2), Use SCMI_IMX_LMM_POWER_ON to detect whether
>    the M7 LM is under control of A55 LM.
>  - For above case , after using SCMI_IMX_LMM_POWER_ON to check
>    permission, SCMI_IMX_LMM_SHUTDOWN API should be called to shutdown
>    the M7 LM to save power only when M7 LM is going to be started by
>    remoteproc framework. Otherwise bypass SCMI_IMX_LMM_SHUTDOWN API if
>    M7 LM is started before booting Linux.
>
> Current setup relies on pre-Linux software(U-Boot) to do M7 TCM ECC
> initialization. In future, we could add the support in Linux to decouple
> U-Boot and Linux.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>  drivers/remoteproc/Kconfig     |   2 +
>  drivers/remoteproc/imx_rproc.c | 192 +++++++++++++++++++++++++++++++++++++++++
>  drivers/remoteproc/imx_rproc.h |   3 +
>  3 files changed, 197 insertions(+)
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 48a0d3a69ed08057716f1e7ea950899f60bbe0cf..ee54436fea5ad08a9c198ce74d44ce7a9aa206de 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -27,6 +27,8 @@ config IMX_REMOTEPROC
>  	tristate "i.MX remoteproc support"
>  	depends on ARCH_MXC
>  	depends on HAVE_ARM_SMCCC
> +	depends on IMX_SCMI_CPU_DRV || !IMX_SCMI_CPU_DRV
> +	depends on IMX_SCMI_LMM_DRV || !IMX_SCMI_LMM_DRV
>  	select MAILBOX
>  	help
>  	  Say y here to support iMX's remote processors via the remote
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 232eb91e0b5dc2432131b1c140d6688b073fea1d..1fb17701964ca4ee4b73d343b5ec1be8e2ee5fda 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -8,6 +8,7 @@
...
> +
> +static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +	struct device *dev = priv->dev;
> +	int ret;
> +
> +	/*
> +	 * Use power on to do permission check. If rproc is in different LM,
> +	 * and linux has permission to handle the LM, set IMX_RPROC_FLAGS_SM_LMM_AVAIL.
> +	 */
> +	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
> +	if (ret != 0) {

	if (!ret)

> +		if (ret == -EACCES) {
> +			/* Not under Linux Control, so only do IPC between rproc and Linux */
> +			dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);
> +			return 0;
> +		}
> +
> +		dev_info(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret);

dev_err()? because it is "... failed"

> +		return ret;
> +	}
> +
> +	priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> +
> +	/* rproc was started before boot Linux and under control of Linux, directly return */
> +	if (started)
> +		return 0;
> +
> +	/* else shutdown the LM to save power */
> +	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0);
> +	if (ret) {
> +		dev_err(dev, "shutdown lmm(%d) failed: %d\n", dcfg->lmid, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_rproc_sm_detect_mode(struct rproc *rproc)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +	struct device *dev = priv->dev;
> +	struct scmi_imx_lmm_info info;
> +	bool started = false;
> +	bool is_cpu_ops;
> +	int ret;
> +
> +	ret = scmi_imx_cpu_started(dcfg->cpuid, &started);
> +	if (ret) {
> +		dev_err(dev, "Failed to detect cpu(%d) status: %d\n", dcfg->cpuid, ret);
> +		return ret;
> +	}
> +
> +	if (started)
> +		priv->rproc->state = RPROC_DETACHED;
> +
> +	/* Get current Linux Logical Machine ID */
> +	ret = scmi_imx_lmm_info(LMM_ID_DISCOVER, &info);
> +	if (ret) {
> +		dev_err(dev, "Failed to get current LMM ID err: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/*
> +	 * Check whether remote processor is in same Logical Machine as Linux.
> +	 * If yes, use CPU protocol API to manage remote processor.
> +	 * If no, use Logical Machine API to manage remote processor.
> +	 */
> +	is_cpu_ops = dcfg->lmid == info.lmid;
> +
> +	if (is_cpu_ops) {
> +		priv->ops = &imx_rproc_ops_sm_cpu;
> +		dev_info(dev, "Using CPU Protocol OPS\n");
> +		return 0;
> +	}

does need else branch to set  priv->ops?

Frank
> +
> +	dev_info(dev, "Using LMM Protocol OPS\n");
> +
> +	return imx_rproc_sm_lmm_check(rproc, started);
> +}
> +
>  static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  {
>  	/*
> diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
> index e4b9ede656506142b260aa7515823f489a168ba4..c05bfc4528f3b7518d4f2272d15fdeab1a68c2a3 100644
> --- a/drivers/remoteproc/imx_rproc.h
> +++ b/drivers/remoteproc/imx_rproc.h
> @@ -52,6 +52,9 @@ struct imx_rproc_dcfg {
>  	enum imx_rproc_method		method;
>  	u32				flags;
>  	const struct imx_rproc_plat_ops	*ops;
> +	/* For System Manager(SM) based SoCs, the IDs are from SM firmware */
> +	u32				cpuid;
> +	u32				lmid;
>  };
>
>  #endif /* _IMX_RPROC_H */
>
> --
> 2.37.1
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 5/5] remoteproc: imx_rproc: Add support for i.MX95
  2025-10-31  2:24 ` [PATCH v2 5/5] remoteproc: imx_rproc: Add support for i.MX95 Peng Fan
@ 2025-10-31 19:28   ` Frank Li
  2025-11-07  9:13   ` Daniel Baluta
  1 sibling, 0 replies; 19+ messages in thread
From: Frank Li @ 2025-10-31 19:28 UTC (permalink / raw)
  To: Peng Fan
  Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On Fri, Oct 31, 2025 at 10:24:56AM +0800, Peng Fan wrote:
> Add imx_rproc_cfg_imx95_m7 and address(TCM and DDR) mapping.
> Add i.MX95 of_device_id entry.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/remoteproc/imx_rproc.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 1fb17701964ca4ee4b73d343b5ec1be8e2ee5fda..63f6362c0b8a3eebc92f2d631fe694ca7bd4c03b 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -127,6 +127,18 @@ struct imx_rproc {
>  	u32				flags;
>  };
>
> +static const struct imx_rproc_att imx_rproc_att_imx95_m7[] = {
> +	/* dev addr , sys addr  , size	    , flags */
> +	/* TCM CODE NON-SECURE */
> +	{ 0x00000000, 0x203C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
> +
> +	/* TCM SYS NON-SECURE*/
> +	{ 0x20000000, 0x20400000, 0x00040000, ATT_OWN | ATT_IOMEM },
> +
> +	/* DDR */
> +	{ 0x80000000, 0x80000000, 0x50000000, 0 },
> +};
> +
>  static const struct imx_rproc_att imx_rproc_att_imx93[] = {
>  	/* dev addr , sys addr  , size	    , flags */
>  	/* TCM CODE NON-SECURE */
> @@ -1444,6 +1456,15 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
>  	.flags		= IMX_RPROC_NEED_CLKS,
>  };
>
> +static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = {
> +	.att		= imx_rproc_att_imx95_m7,
> +	.att_size	= ARRAY_SIZE(imx_rproc_att_imx95_m7),
> +	.ops		= &imx_rproc_ops_sm,
> +	/* Must align with System Manager Firmware */
> +	.cpuid		= 1,
> +	.lmid		= 1,
> +};
> +
>  static const struct of_device_id imx_rproc_of_match[] = {
>  	{ .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
>  	{ .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
> @@ -1458,6 +1479,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
>  	{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
>  	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
>  	{ .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
> +	{ .compatible = "fsl,imx95-cm7", .data = &imx_rproc_cfg_imx95_m7 },
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
>
> --
> 2.37.1
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API
  2025-10-31 19:28   ` Frank Li
@ 2025-11-04  4:28     ` Peng Fan
  0 siblings, 0 replies; 19+ messages in thread
From: Peng Fan @ 2025-11-04  4:28 UTC (permalink / raw)
  To: Frank Li
  Cc: Peng Fan, Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On Fri, Oct 31, 2025 at 03:28:07PM -0400, Frank Li wrote:
>On Fri, Oct 31, 2025 at 10:24:55AM +0800, Peng Fan wrote:
>> i.MX95 features a Cortex-M33 core, six Cortex-A55 cores, and
>> one Cortex-M7 core. The System Control Management Interface(SCMI)
>> firmware runs on the M33 core. The i.MX95 SCMI firmware named System
>> Manager(SM) includes vendor extension protocols, Logical Machine
>> Management(LMM) protocol and CPU protocol and etc.
>>
>> There are three cases for M7:
>>  (1) M7 in a separate Logical Machine(LM) that Linux can't control it.
>>  (2) M7 in a separate Logical Machine that Linux can control it using
>>      LMM protocol
>>  (3) M7 runs in same Logical Machine as A55, so Linux can control it
>>      using CPU protocol
>>
>> So extend the driver to using LMM and CPU protocol to manage the M7 core.
>>  - Compare linux LM ID(got using scmi_imx_lmm_info) and M7 LM ID(the ID
>>    is fixed as 1 in SM firmware if M7 is in a seprate LM),
>>    if Linux LM ID equals M7 LM ID(linux and M7 in same LM), use CPU
>>    protocol to start/stop. Otherwise, use LMM protocol to start/stop.
>>    Whether using CPU or LMM protocol to start/stop, the M7 status
>>    detection could use CPU protocol to detect started or not. So
>>    in imx_rproc_detect_mode, use scmi_imx_cpu_started to check the
>>    status of M7.
>>  - For above case (1) and (2), Use SCMI_IMX_LMM_POWER_ON to detect whether
>>    the M7 LM is under control of A55 LM.
>>  - For above case , after using SCMI_IMX_LMM_POWER_ON to check
>>    permission, SCMI_IMX_LMM_SHUTDOWN API should be called to shutdown
>>    the M7 LM to save power only when M7 LM is going to be started by
>>    remoteproc framework. Otherwise bypass SCMI_IMX_LMM_SHUTDOWN API if
>>    M7 LM is started before booting Linux.
>>
>> Current setup relies on pre-Linux software(U-Boot) to do M7 TCM ECC
>> initialization. In future, we could add the support in Linux to decouple
>> U-Boot and Linux.
>>
>> Signed-off-by: Peng Fan <peng.fan@nxp.com>
>> ---
>>  drivers/remoteproc/Kconfig     |   2 +
>>  drivers/remoteproc/imx_rproc.c | 192 +++++++++++++++++++++++++++++++++++++++++
>>  drivers/remoteproc/imx_rproc.h |   3 +
>>  3 files changed, 197 insertions(+)
>>
>> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
>> index 48a0d3a69ed08057716f1e7ea950899f60bbe0cf..ee54436fea5ad08a9c198ce74d44ce7a9aa206de 100644
>> --- a/drivers/remoteproc/Kconfig
>> +++ b/drivers/remoteproc/Kconfig
>> @@ -27,6 +27,8 @@ config IMX_REMOTEPROC
>>  	tristate "i.MX remoteproc support"
>>  	depends on ARCH_MXC
>>  	depends on HAVE_ARM_SMCCC
>> +	depends on IMX_SCMI_CPU_DRV || !IMX_SCMI_CPU_DRV
>> +	depends on IMX_SCMI_LMM_DRV || !IMX_SCMI_LMM_DRV
>>  	select MAILBOX
>>  	help
>>  	  Say y here to support iMX's remote processors via the remote
>> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
>> index 232eb91e0b5dc2432131b1c140d6688b073fea1d..1fb17701964ca4ee4b73d343b5ec1be8e2ee5fda 100644
>> --- a/drivers/remoteproc/imx_rproc.c
>> +++ b/drivers/remoteproc/imx_rproc.c
>> @@ -8,6 +8,7 @@
>...
>> +
>> +static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started)
>> +{
>> +	struct imx_rproc *priv = rproc->priv;
>> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
>> +	struct device *dev = priv->dev;
>> +	int ret;
>> +
>> +	/*
>> +	 * Use power on to do permission check. If rproc is in different LM,
>> +	 * and linux has permission to handle the LM, set IMX_RPROC_FLAGS_SM_LMM_AVAIL.
>> +	 */
>> +	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
>> +	if (ret != 0) {
>
>	if (!ret)

Fix in next version.

>
>> +		if (ret == -EACCES) {
>> +			/* Not under Linux Control, so only do IPC between rproc and Linux */
>> +			dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);
>> +			return 0;
>> +		}
>> +
>> +		dev_info(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret);
>
>dev_err()? because it is "... failed"

Yeah.

>
>> +		return ret;
>> +	}
>> +	is_cpu_ops = dcfg->lmid == info.lmid;
>> +
>> +	if (is_cpu_ops) {
>> +		priv->ops = &imx_rproc_ops_sm_cpu;
>> +		dev_info(dev, "Using CPU Protocol OPS\n");
>> +		return 0;
>> +	}
>
>does need else branch to set  priv->ops?

The platform default ops should be set to lmm ops, so there is no need
else branch, see patch 5.

Thanks,
Peng

>
>Frank
>> +
>> +	dev_info(dev, "Using LMM Protocol OPS\n");
>> +
>> +	return imx_rproc_sm_lmm_check(rproc, started);
>> +}
>> +
>>  static int imx_rproc_detect_mode(struct imx_rproc *priv)
>>  {
>>  	/*
>> diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
>> index e4b9ede656506142b260aa7515823f489a168ba4..c05bfc4528f3b7518d4f2272d15fdeab1a68c2a3 100644
>> --- a/drivers/remoteproc/imx_rproc.h
>> +++ b/drivers/remoteproc/imx_rproc.h
>> @@ -52,6 +52,9 @@ struct imx_rproc_dcfg {
>>  	enum imx_rproc_method		method;
>>  	u32				flags;
>>  	const struct imx_rproc_plat_ops	*ops;
>> +	/* For System Manager(SM) based SoCs, the IDs are from SM firmware */
>> +	u32				cpuid;
>> +	u32				lmid;
>>  };
>>
>>  #endif /* _IMX_RPROC_H */
>>
>> --
>> 2.37.1
>>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior
  2025-10-31  2:24 ` [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior Peng Fan
@ 2025-11-04  9:43   ` Iuliana Prodan
  2025-11-05  8:47     ` Peng Fan
  2025-11-07  7:54   ` Daniel Baluta
  1 sibling, 1 reply; 19+ messages in thread
From: Iuliana Prodan @ 2025-11-04  9:43 UTC (permalink / raw)
  To: Peng Fan, Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On 10/31/2025 4:24 AM, Peng Fan wrote:
> Structure imx_rproc_dcfg contains a const pointer to imx_rproc_plat_ops,
> which defines the start/stop/detect_mode operations for a remote processor.
> To preserve the const correctness of the static configuration while
> allowing runtime modification of ops behavior, introduce a new
> imx_rproc_plat_ops member in struct imx_rproc named `ops`.
> 
> During initialization, dcfg->ops is assigned to priv->ops.
> Enable the driver to safely override ops at runtime without affecting the
> original const configuration.
> 
> Improve flexibility for platforms that require dynamic operation switching
> (e.g. i.MX95 Logical Machine ops and CPU ops).
> 
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>   drivers/remoteproc/imx_rproc.c | 27 +++++++++++++--------------
>   1 file changed, 13 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 02e155e967942d745de4ccd96f9008e4211f9b36..82cb8c7866ccb79061c46068d2039f38feebbb3c 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -116,6 +116,7 @@ struct imx_rproc {
>   	u32				entry;		/* cpu start address */
>   	u32				core_index;
>   	struct dev_pm_domain_list	*pd_list;
> +	const struct imx_rproc_plat_ops	*ops;
>   };
>   
>   static const struct imx_rproc_att imx_rproc_att_imx93[] = {
> @@ -315,7 +316,6 @@ static int imx_rproc_scu_api_start(struct rproc *rproc)
>   static int imx_rproc_start(struct rproc *rproc)
>   {
>   	struct imx_rproc *priv = rproc->priv;
> -	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
>   	struct device *dev = priv->dev;
>   	int ret;
>   
> @@ -323,10 +323,10 @@ static int imx_rproc_start(struct rproc *rproc)
>   	if (ret)
>   		return ret;
>   
> -	if (!dcfg->ops || !dcfg->ops->start)
> +	if (!priv->ops || !priv->ops->start)
>   		return -EOPNOTSUPP;
>   
> -	ret = dcfg->ops->start(rproc);
> +	ret = priv->ops->start(rproc);
>   	if (ret)
>   		dev_err(dev, "Failed to enable remote core!\n");
>   
> @@ -372,14 +372,13 @@ static int imx_rproc_scu_api_stop(struct rproc *rproc)
>   static int imx_rproc_stop(struct rproc *rproc)
>   {
>   	struct imx_rproc *priv = rproc->priv;
> -	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
>   	struct device *dev = priv->dev;
>   	int ret;
>   
> -	if (!dcfg->ops || !dcfg->ops->stop)
> +	if (!priv->ops || !priv->ops->stop)
>   		return -EOPNOTSUPP;
>   
> -	ret = dcfg->ops->stop(rproc);
> +	ret = priv->ops->stop(rproc);
>   	if (ret)
>   		dev_err(dev, "Failed to stop remote core\n");
>   	else
> @@ -590,12 +589,11 @@ static int imx_rproc_scu_api_detach(struct rproc *rproc)
>   static int imx_rproc_detach(struct rproc *rproc)
>   {
>   	struct imx_rproc *priv = rproc->priv;
> -	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
>   
> -	if (!dcfg->ops || !dcfg->ops->detach)
> +	if (!priv->ops || !priv->ops->detach)
>   		return -EOPNOTSUPP;
>   
> -	return dcfg->ops->detach(rproc);
> +	return priv->ops->detach(rproc);
>   }
>   
>   static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
> @@ -995,18 +993,16 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
>   
>   static int imx_rproc_detect_mode(struct imx_rproc *priv)
>   {
> -	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> -
>   	/*
>   	 * To i.MX{7,8} ULP, Linux is under control of RTOS, no need
> -	 * dcfg->ops or dcfg->ops->detect_mode, it is state RPROC_DETACHED.
> +	 * priv->ops or priv->ops->detect_mode, it is state RPROC_DETACHED.
>   	 */
> -	if (!dcfg->ops || !dcfg->ops->detect_mode) {
> +	if (!priv->ops || !priv->ops->detect_mode) {
>   		priv->rproc->state = RPROC_DETACHED;
>   		return 0;
>   	}
>   
> -	return dcfg->ops->detect_mode(priv->rproc);
> +	return priv->ops->detect_mode(priv->rproc);
>   }
>   
>   static int imx_rproc_sys_off_handler(struct sys_off_data *data)
> @@ -1056,6 +1052,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
>   	priv->dcfg = dcfg;
>   	priv->dev = dev;
>   
> +	if (dcfg->ops)
> +		priv->ops = dcfg->ops;

Will priv->ops ever be modified after initialization in a multi-threaded 
context?
If so, you might need synchronization.

Also, you can remove the NULL check since it's safe to assign NULL.

Iulia

> +
>   	dev_set_drvdata(dev, rproc);
>   	priv->workqueue = create_workqueue(dev_name(dev));
>   	if (!priv->workqueue) {
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API
  2025-10-31  2:24 ` [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan
  2025-10-31 19:28   ` Frank Li
@ 2025-11-04  9:50   ` Iuliana Prodan
  2025-11-05  8:51     ` Peng Fan
  2025-11-07  9:10   ` Daniel Baluta
  2 siblings, 1 reply; 19+ messages in thread
From: Iuliana Prodan @ 2025-11-04  9:50 UTC (permalink / raw)
  To: Peng Fan, Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On 10/31/2025 4:24 AM, Peng Fan wrote:
> i.MX95 features a Cortex-M33 core, six Cortex-A55 cores, and
> one Cortex-M7 core. The System Control Management Interface(SCMI)
> firmware runs on the M33 core. The i.MX95 SCMI firmware named System
> Manager(SM) includes vendor extension protocols, Logical Machine
> Management(LMM) protocol and CPU protocol and etc.
> 
> There are three cases for M7:
>   (1) M7 in a separate Logical Machine(LM) that Linux can't control it.
>   (2) M7 in a separate Logical Machine that Linux can control it using
>       LMM protocol
>   (3) M7 runs in same Logical Machine as A55, so Linux can control it
>       using CPU protocol
> 
> So extend the driver to using LMM and CPU protocol to manage the M7 core.
>   - Compare linux LM ID(got using scmi_imx_lmm_info) and M7 LM ID(the ID
>     is fixed as 1 in SM firmware if M7 is in a seprate LM),
>     if Linux LM ID equals M7 LM ID(linux and M7 in same LM), use CPU
>     protocol to start/stop. Otherwise, use LMM protocol to start/stop.
>     Whether using CPU or LMM protocol to start/stop, the M7 status
>     detection could use CPU protocol to detect started or not. So
>     in imx_rproc_detect_mode, use scmi_imx_cpu_started to check the
>     status of M7.
>   - For above case (1) and (2), Use SCMI_IMX_LMM_POWER_ON to detect whether
>     the M7 LM is under control of A55 LM.
>   - For above case , after using SCMI_IMX_LMM_POWER_ON to check
>     permission, SCMI_IMX_LMM_SHUTDOWN API should be called to shutdown
>     the M7 LM to save power only when M7 LM is going to be started by
>     remoteproc framework. Otherwise bypass SCMI_IMX_LMM_SHUTDOWN API if
>     M7 LM is started before booting Linux.
> 
> Current setup relies on pre-Linux software(U-Boot) to do M7 TCM ECC
> initialization. In future, we could add the support in Linux to decouple
> U-Boot and Linux.
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>   drivers/remoteproc/Kconfig     |   2 +
>   drivers/remoteproc/imx_rproc.c | 192 +++++++++++++++++++++++++++++++++++++++++
>   drivers/remoteproc/imx_rproc.h |   3 +
>   3 files changed, 197 insertions(+)
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 48a0d3a69ed08057716f1e7ea950899f60bbe0cf..ee54436fea5ad08a9c198ce74d44ce7a9aa206de 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -27,6 +27,8 @@ config IMX_REMOTEPROC
>   	tristate "i.MX remoteproc support"
>   	depends on ARCH_MXC
>   	depends on HAVE_ARM_SMCCC
> +	depends on IMX_SCMI_CPU_DRV || !IMX_SCMI_CPU_DRV
> +	depends on IMX_SCMI_LMM_DRV || !IMX_SCMI_LMM_DRV

This always evaluates to true.
If you want to ensure that when a dependency is m, imx_rproc must also 
be a m, you use:
depends on IMX_SCMI_CPU_DRV
depends on IMX_SCMI_LMM_DRV

>   	select MAILBOX
>   	help
>   	  Say y here to support iMX's remote processors via the remote
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 232eb91e0b5dc2432131b1c140d6688b073fea1d..1fb17701964ca4ee4b73d343b5ec1be8e2ee5fda 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -8,6 +8,7 @@
>   #include <linux/clk.h>
>   #include <linux/err.h>
>   #include <linux/firmware/imx/sci.h>
> +#include <linux/firmware/imx/sm.h>
>   #include <linux/interrupt.h>
>   #include <linux/kernel.h>
>   #include <linux/mailbox_client.h>
> @@ -22,6 +23,7 @@
>   #include <linux/reboot.h>
>   #include <linux/regmap.h>
>   #include <linux/remoteproc.h>
> +#include <linux/scmi_imx_protocol.h>
>   #include <linux/workqueue.h>
>   
>   #include "imx_rproc.h"
> @@ -92,8 +94,12 @@ struct imx_rproc_mem {
>   #define ATT_CORE_MASK   0xffff
>   #define ATT_CORE(I)     BIT((I))
>   
> +/* Linux has permission to handle the Logical Machine of remote cores */
> +#define IMX_RPROC_FLAGS_SM_LMM_AVAIL	BIT(0)
> +
>   static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block);
>   static void imx_rproc_free_mbox(void *data);
> +static int imx_rproc_sm_detect_mode(struct rproc *rproc);
>   
>   struct imx_rproc {
>   	struct device			*dev;
> @@ -117,6 +123,8 @@ struct imx_rproc {
>   	u32				core_index;
>   	struct dev_pm_domain_list	*pd_list;
>   	const struct imx_rproc_plat_ops	*ops;
> +	/* For i.MX System Manager based systems */
> +	u32				flags;

Add some info about how and why this new field is used/needed.

>   };
>   
>   static const struct imx_rproc_att imx_rproc_att_imx93[] = {
> @@ -313,6 +321,44 @@ static int imx_rproc_scu_api_start(struct rproc *rproc)
>   	return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry);
>   }
>   
> +static int imx_rproc_sm_cpu_start(struct rproc *rproc)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +	int ret;
> +
> +	ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, 0, true, false, false);
> +	if (ret) {
> +		dev_err(priv->dev, "Failed to set reset vector cpuid(%u): %d\n", dcfg->cpuid, ret);
> +		return ret;
> +	}
> +
> +	return scmi_imx_cpu_start(dcfg->cpuid, true);
> +}
> +
> +static int imx_rproc_sm_lmm_start(struct rproc *rproc)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +	struct device *dev = priv->dev;
> +	int ret;
> +
> +	ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid, 0, 0);
> +	if (ret) {
> +		dev_err(dev, "Failed to set reset vector lmid(%u), cpuid(%u): %d\n",
> +			dcfg->lmid, dcfg->cpuid, ret);
> +		return ret;
> +	}
> +
> +	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_BOOT, 0);
> +	if (ret) {
> +		dev_err(dev, "Failed to boot lmm(%d): %d\n", dcfg->lmid, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
>   static int imx_rproc_start(struct rproc *rproc)
>   {
>   	struct imx_rproc *priv = rproc->priv;
> @@ -369,6 +415,25 @@ static int imx_rproc_scu_api_stop(struct rproc *rproc)
>   	return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry);
>   }
>   
> +static int imx_rproc_sm_cpu_stop(struct rproc *rproc)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +
> +	return scmi_imx_cpu_start(dcfg->cpuid, false);
> +}
> +
> +static int imx_rproc_sm_lmm_stop(struct rproc *rproc)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +
> +	if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL))
> +		return -EACCES;
> +
> +	return scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0);
> +}
> +
>   static int imx_rproc_stop(struct rproc *rproc)
>   {
>   	struct imx_rproc *priv = rproc->priv;
> @@ -485,6 +550,37 @@ static int imx_rproc_mem_release(struct rproc *rproc,
>   	return 0;
>   }
>   
> +static int imx_rproc_sm_lmm_prepare(struct rproc *rproc)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +	int ret;
> +
> +	/*
> +	 * IMX_RPROC_FLAGS_SM_LMM_AVAIL not set indicates Linux is not able
> +	 * to start/stop rproc LM, then if rproc is not in detached state,
> +	 * prepare should fail. If in detached state, this is in rproc_attach()
> +	 * path.
> +	 */
> +	if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL)) {
> +		if (rproc->state != RPROC_DETACHED)
> +			return -EACCES;
> +
> +		return 0;
> +	}
> +

IMO is simpler this way:
if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL))
	return (rproc->state == RPROC_DETACHED) ? 0 : -EACCES;

> +	/* Power on the Logical Machine to make sure TCM is available. */
> +	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
> +	if (ret) {
> +		dev_err(priv->dev, "Failed to power on lmm(%d): %d\n", dcfg->lmid, ret);
> +		return ret;
> +	}
> +
> +	dev_info(priv->dev, "lmm(%d) powered on by Linux\n", dcfg->lmid);
> +
> +	return 0;
> +}
> +
>   static int imx_rproc_prepare(struct rproc *rproc)
>   {
>   	struct imx_rproc *priv = rproc->priv;
> @@ -994,6 +1090,102 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
>   	return 0;
>   }
>   
> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm = {
> +	.detect_mode	= imx_rproc_sm_detect_mode,
> +	.prepare	= imx_rproc_sm_lmm_prepare,
> +	.start		= imx_rproc_sm_lmm_start,
> +	.stop		= imx_rproc_sm_lmm_stop,
> +};
> +
> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu = {
> +	.detect_mode	= imx_rproc_sm_detect_mode,
> +	.start		= imx_rproc_sm_cpu_start,
> +	.stop		= imx_rproc_sm_cpu_stop,
> +};
> +
> +static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +	struct device *dev = priv->dev;
> +	int ret;
> +
> +	/*
> +	 * Use power on to do permission check. If rproc is in different LM,
> +	 * and linux has permission to handle the LM, set IMX_RPROC_FLAGS_SM_LMM_AVAIL.
> +	 */
> +	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
> +	if (ret != 0) {
> +		if (ret == -EACCES) {
> +			/* Not under Linux Control, so only do IPC between rproc and Linux */
> +			dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);
> +			return 0;
> +		}
> +
> +		dev_info(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret);
> +		return ret;
> +	}
> +
> +	priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> +
> +	/* rproc was started before boot Linux and under control of Linux, directly return */
> +	if (started)
> +		return 0;
> +
> +	/* else shutdown the LM to save power */
> +	ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0);
> +	if (ret) {
> +		dev_err(dev, "shutdown lmm(%d) failed: %d\n", dcfg->lmid, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_rproc_sm_detect_mode(struct rproc *rproc)
> +{
> +	struct imx_rproc *priv = rproc->priv;
> +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +	struct device *dev = priv->dev;
> +	struct scmi_imx_lmm_info info;
> +	bool started = false;
> +	bool is_cpu_ops;
> +	int ret;
> +
> +	ret = scmi_imx_cpu_started(dcfg->cpuid, &started);
> +	if (ret) {
> +		dev_err(dev, "Failed to detect cpu(%d) status: %d\n", dcfg->cpuid, ret);
> +		return ret;
> +	}
> +
> +	if (started)
> +		priv->rproc->state = RPROC_DETACHED;
> +
> +	/* Get current Linux Logical Machine ID */
> +	ret = scmi_imx_lmm_info(LMM_ID_DISCOVER, &info);
> +	if (ret) {
> +		dev_err(dev, "Failed to get current LMM ID err: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/*
> +	 * Check whether remote processor is in same Logical Machine as Linux.
> +	 * If yes, use CPU protocol API to manage remote processor.
> +	 * If no, use Logical Machine API to manage remote processor.
> +	 */
> +	is_cpu_ops = dcfg->lmid == info.lmid;
> +
> +	if (is_cpu_ops) {
> +		priv->ops = &imx_rproc_ops_sm_cpu;
> +		dev_info(dev, "Using CPU Protocol OPS\n");
> +		return 0;
> +	}
> +
> +	dev_info(dev, "Using LMM Protocol OPS\n");
> +
> +	return imx_rproc_sm_lmm_check(rproc, started);
> +}
> +
>   static int imx_rproc_detect_mode(struct imx_rproc *priv)
>   {
>   	/*
> diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
> index e4b9ede656506142b260aa7515823f489a168ba4..c05bfc4528f3b7518d4f2272d15fdeab1a68c2a3 100644
> --- a/drivers/remoteproc/imx_rproc.h
> +++ b/drivers/remoteproc/imx_rproc.h
> @@ -52,6 +52,9 @@ struct imx_rproc_dcfg {
>   	enum imx_rproc_method		method;
>   	u32				flags;
>   	const struct imx_rproc_plat_ops	*ops;
> +	/* For System Manager(SM) based SoCs, the IDs are from SM firmware */
> +	u32				cpuid;
> +	u32				lmid;
>   };
>   
>   #endif /* _IMX_RPROC_H */
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior
  2025-11-04  9:43   ` Iuliana Prodan
@ 2025-11-05  8:47     ` Peng Fan
  0 siblings, 0 replies; 19+ messages in thread
From: Peng Fan @ 2025-11-05  8:47 UTC (permalink / raw)
  To: Iuliana Prodan, Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc@vger.kernel.org, devicetree@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org

> Subject: Re: [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops
> copy to support dynamic behavior
> 
> > -1056,6 +1052,9 @@ static int imx_rproc_probe(struct
> platform_device *pdev)
> >   	priv->dcfg = dcfg;
> >   	priv->dev = dev;
> >
> > +	if (dcfg->ops)
> > +		priv->ops = dcfg->ops;
> 
> Will priv->ops ever be modified after initialization in a multi-threaded
> context?
> If so, you might need synchronization.

This is in probe phase, no multi-thread context.

> 
> Also, you can remove the NULL check since it's safe to assign NULL.

Yes.

Thanks,
Peng.

> 
> Iulia
> 
> > +
> >   	dev_set_drvdata(dev, rproc);
> >   	priv->workqueue = create_workqueue(dev_name(dev));
> >   	if (!priv->workqueue) {
> >


^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API
  2025-11-04  9:50   ` Iuliana Prodan
@ 2025-11-05  8:51     ` Peng Fan
  0 siblings, 0 replies; 19+ messages in thread
From: Peng Fan @ 2025-11-05  8:51 UTC (permalink / raw)
  To: Iuliana Prodan, Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li
  Cc: linux-remoteproc@vger.kernel.org, devicetree@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org

Hi Iuliana,

> Subject: Re: [PATCH v2 4/5] remoteproc: imx_rproc: Add support for
> System Manager API
> 
> >   	depends on HAVE_ARM_SMCCC
> > +	depends on IMX_SCMI_CPU_DRV || !IMX_SCMI_CPU_DRV
> > +	depends on IMX_SCMI_LMM_DRV || !IMX_SCMI_LMM_DRV
> 
> This always evaluates to true.
> If you want to ensure that when a dependency is m, imx_rproc must
> also be a m, you use:
> depends on IMX_SCMI_CPU_DRV
> depends on IMX_SCMI_LMM_DRV

No, this does not work. We need support non-SCMI platform.

I followed what Arnd did, see
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index ad20dc8506f9..6b497dd87562 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2297,6 +2297,7 @@ config SENSORS_TMP103
config SENSORS_TMP108
        tristate "Texas Instruments TMP108"
        depends on I2C
+       depends on I3C || !I3C


>
...
 
> > +	/* For i.MX System Manager based systems */
> > +	u32				flags;
> 
> Add some info about how and why this new field is used/needed.

ok. Will add that in above comment area.

> 
> >   };
> >
> >   static const struct imx_rproc_att imx_rproc_att_imx93[] = { @@
> > -313,6 +321,44 @@ static int imx_rproc_scu_api_start(struct rproc
> *rproc)
> >   	return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id,
> true, priv->entry);
> >   }
> >
> > +static int imx_rproc_sm_cpu_start(struct rproc *rproc) {
> > +	struct imx_rproc *priv = rproc->priv;
> > +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> > +	int ret;
> > +
> > +	ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, 0, true, false,
> false);
> > +	if (ret) {
> > +		dev_err(priv->dev, "Failed to set reset vector
> cpuid(%u): %d\n", dcfg->cpuid, ret);
> > +		return ret;
> > +	}
> > +
> > +	return scmi_imx_cpu_start(dcfg->cpuid, true); }
> > +
> > +static int imx_rproc_sm_lmm_start(struct rproc *rproc) {
> > +	struct imx_rproc *priv = rproc->priv;
> > +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> > +	struct device *dev = priv->dev;
> > +	int ret;
> > +
> > +	ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid,
> 0, 0);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to set reset vector lmid(%u),
> cpuid(%u): %d\n",
> > +			dcfg->lmid, dcfg->cpuid, ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = scmi_imx_lmm_operation(dcfg->lmid,
> SCMI_IMX_LMM_BOOT, 0);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to boot lmm(%d): %d\n", dcfg-
> >lmid, ret);
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >   static int imx_rproc_start(struct rproc *rproc)
> >   {
> >   	struct imx_rproc *priv = rproc->priv; @@ -369,6 +415,25 @@
> static
> > int imx_rproc_scu_api_stop(struct rproc *rproc)
> >   	return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id,
> false, priv->entry);
> >   }
> >
> > +static int imx_rproc_sm_cpu_stop(struct rproc *rproc) {
> > +	struct imx_rproc *priv = rproc->priv;
> > +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> > +
> > +	return scmi_imx_cpu_start(dcfg->cpuid, false); }
> > +
> > +static int imx_rproc_sm_lmm_stop(struct rproc *rproc) {
> > +	struct imx_rproc *priv = rproc->priv;
> > +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> > +
> > +	if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL))
> > +		return -EACCES;
> > +
> > +	return scmi_imx_lmm_operation(dcfg->lmid,
> SCMI_IMX_LMM_SHUTDOWN, 0);
> > +}
> > +
> >   static int imx_rproc_stop(struct rproc *rproc)
> >   {
> >   	struct imx_rproc *priv = rproc->priv; @@ -485,6 +550,37 @@
> static
> > int imx_rproc_mem_release(struct rproc *rproc,
> >   	return 0;
> >   }
> >
> > +static int imx_rproc_sm_lmm_prepare(struct rproc *rproc) {
> > +	struct imx_rproc *priv = rproc->priv;
> > +	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> > +	int ret;
> > +
> > +	/*
> > +	 * IMX_RPROC_FLAGS_SM_LMM_AVAIL not set indicates Linux
> is not able
> > +	 * to start/stop rproc LM, then if rproc is not in detached state,
> > +	 * prepare should fail. If in detached state, this is in
> rproc_attach()
> > +	 * path.
> > +	 */
> > +	if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL)) {
> > +		if (rproc->state != RPROC_DETACHED)
> > +			return -EACCES;
> > +
> > +		return 0;
> > +	}
> > +
> 
> IMO is simpler this way:
> if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL))
> 	return (rproc->state == RPROC_DETACHED) ? 0 : -EACCES;

Yeah. Thanks.

Thanks,
Peng

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior
  2025-10-31  2:24 ` [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior Peng Fan
  2025-11-04  9:43   ` Iuliana Prodan
@ 2025-11-07  7:54   ` Daniel Baluta
  1 sibling, 0 replies; 19+ messages in thread
From: Daniel Baluta @ 2025-11-07  7:54 UTC (permalink / raw)
  To: Peng Fan
  Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On Fri, Oct 31, 2025 at 4:27 AM Peng Fan <peng.fan@nxp.com> wrote:
>
> Structure imx_rproc_dcfg contains a const pointer to imx_rproc_plat_ops,
> which defines the start/stop/detect_mode operations for a remote processor.
> To preserve the const correctness of the static configuration while
> allowing runtime modification of ops behavior, introduce a new
> imx_rproc_plat_ops member in struct imx_rproc named `ops`.
>
> During initialization, dcfg->ops is assigned to priv->ops.
> Enable the driver to safely override ops at runtime without affecting the
> original const configuration.
>
> Improve flexibility for platforms that require dynamic operation switching
> (e.g. i.MX95 Logical Machine ops and CPU ops).
>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>


Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
  2025-10-31  2:24 ` [PATCH v2 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg Peng Fan
  2025-10-31 19:20   ` Frank Li
@ 2025-11-07  7:56   ` Daniel Baluta
  1 sibling, 0 replies; 19+ messages in thread
From: Daniel Baluta @ 2025-11-07  7:56 UTC (permalink / raw)
  To: Peng Fan
  Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On Fri, Oct 31, 2025 at 4:28 AM Peng Fan <peng.fan@nxp.com> wrote:
>
> Allow each platform to provide its own prepare operations, preparing
> for i.MX95 LMM and CPU ops support.
>
> No functional changes.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>

Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API
  2025-10-31  2:24 ` [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan
  2025-10-31 19:28   ` Frank Li
  2025-11-04  9:50   ` Iuliana Prodan
@ 2025-11-07  9:10   ` Daniel Baluta
  2025-11-07 13:49     ` Peng Fan
  2 siblings, 1 reply; 19+ messages in thread
From: Daniel Baluta @ 2025-11-07  9:10 UTC (permalink / raw)
  To: Peng Fan
  Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

Hi Peng,

Some comments inline to make this easier to understand:

On Fri, Oct 31, 2025 at 4:26 AM Peng Fan <peng.fan@nxp.com> wrote:
>
> i.MX95 features a Cortex-M33 core, six Cortex-A55 cores, and
> one Cortex-M7 core. The System Control Management Interface(SCMI)
> firmware runs on the M33 core. The i.MX95 SCMI firmware named System
> Manager(SM) includes vendor extension protocols, Logical Machine
> Management(LMM) protocol and CPU protocol and etc.
>
> There are three cases for M7:

Here we should specify how M7 gets into these three situations, is it
via the ATF configuration?

e.g

Depending on ATF configuration, M7 can be used as follows:

>  (1) M7 in a separate Logical Machine(LM) that Linux can't control it.

Here we should make it clear from who is M7 separate.

e.g

(1) M7 in a separate Logical Machine (LM) from A55 cores, that Linux
can't control

>  (2) M7 in a separate Logical Machine that Linux can control it using
>      LMM protocol

(2) M7 in a separate LM from A55 cores that Linux can control using
LMM protocol.

>  (3) M7 runs in same Logical Machine as A55, so Linux can control it
>      using CPU protocol
>


> So extend the driver to using LMM and CPU protocol to manage the M7 core.


>  - Compare linux LM ID(got using scmi_imx_lmm_info) and M7 LM ID(the ID
>    is fixed as 1 in SM firmware if M7 is in a seprate LM),

s/seprate/separate

One question here: Is it OK to call scmi_imx_lmm_info no matter the
context are we in?

If this call fails is it safe to assume that we are in the case (1)
describe above? E.g Linux
cannot reach the M7 core through LMM protocol  or CPU protocol?



>    if Linux LM ID equals M7 LM ID(linux and M7 in same LM), use CPU
>    protocol to start/stop. Otherwise, use LMM protocol to start/stop.
>    Whether using CPU or LMM protocol to start/stop, the M7 status
>    detection could use CPU protocol to detect started or not. So
>    in imx_rproc_detect_mode, use scmi_imx_cpu_started to check the
>    status of M7.
>  - For above case (1) and (2), Use SCMI_IMX_LMM_POWER_ON to detect whether
>    the M7 LM is under control of A55 LM.
>  - For above case , after using SCMI_IMX_LMM_POWER_ON to check
>    permission, SCMI_IMX_LMM_SHUTDOWN API should be called to shutdown
>    the M7 LM to save power only when M7 LM is going to be started by
>    remoteproc framework. Otherwise bypass SCMI_IMX_LMM_SHUTDOWN API if
>    M7 LM is started before booting Linux.
>
> Current setup relies on pre-Linux software(U-Boot) to do M7 TCM ECC
> initialization. In future, we could add the support in Linux to decouple
> U-Boot and Linux.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>  drivers/remoteproc/Kconfig     |   2 +
>  drivers/remoteproc/imx_rproc.c | 192 +++++++++++++++++++++++++++++++++++++++++
>  drivers/remoteproc/imx_rproc.h |   3 +
>  3 files changed, 197 insertions(+)
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 48a0d3a69ed08057716f1e7ea950899f60bbe0cf..ee54436fea5ad08a9c198ce74d44ce7a9aa206de 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -27,6 +27,8 @@ config IMX_REMOTEPROC
>         tristate "i.MX remoteproc support"
>         depends on ARCH_MXC
>         depends on HAVE_ARM_SMCCC
> +       depends on IMX_SCMI_CPU_DRV || !IMX_SCMI_CPU_DRV
> +       depends on IMX_SCMI_LMM_DRV || !IMX_SCMI_LMM_DRV
>         select MAILBOX
>         help
>           Say y here to support iMX's remote processors via the remote
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 232eb91e0b5dc2432131b1c140d6688b073fea1d..1fb17701964ca4ee4b73d343b5ec1be8e2ee5fda 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -8,6 +8,7 @@
>  #include <linux/clk.h>
>  #include <linux/err.h>
>  #include <linux/firmware/imx/sci.h>
> +#include <linux/firmware/imx/sm.h>
>  #include <linux/interrupt.h>
>  #include <linux/kernel.h>
>  #include <linux/mailbox_client.h>
> @@ -22,6 +23,7 @@
>  #include <linux/reboot.h>
>  #include <linux/regmap.h>
>  #include <linux/remoteproc.h>
> +#include <linux/scmi_imx_protocol.h>
>  #include <linux/workqueue.h>
>
>  #include "imx_rproc.h"
> @@ -92,8 +94,12 @@ struct imx_rproc_mem {
>  #define ATT_CORE_MASK   0xffff
>  #define ATT_CORE(I)     BIT((I))
>
> +/* Linux has permission to handle the Logical Machine of remote cores */
> +#define IMX_RPROC_FLAGS_SM_LMM_AVAIL   BIT(0)
> +
>  static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block);
>  static void imx_rproc_free_mbox(void *data);
> +static int imx_rproc_sm_detect_mode(struct rproc *rproc);
>
>  struct imx_rproc {
>         struct device                   *dev;
> @@ -117,6 +123,8 @@ struct imx_rproc {
>         u32                             core_index;
>         struct dev_pm_domain_list       *pd_list;
>         const struct imx_rproc_plat_ops *ops;
> +       /* For i.MX System Manager based systems */
> +       u32                             flags;

<snip>

>  static int imx_rproc_prepare(struct rproc *rproc)
>  {
>         struct imx_rproc *priv = rproc->priv;
> @@ -994,6 +1090,102 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
>         return 0;
>  }
>
> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm = {

I think this should be called imx_rproc_ops_sm_lmm.

> +       .detect_mode    = imx_rproc_sm_detect_mode,
> +       .prepare        = imx_rproc_sm_lmm_prepare,
> +       .start          = imx_rproc_sm_lmm_start,
> +       .stop           = imx_rproc_sm_lmm_stop,
> +};
> +
> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu = {
> +       .detect_mode    = imx_rproc_sm_detect_mode,
> +       .start          = imx_rproc_sm_cpu_start,
> +       .stop           = imx_rproc_sm_cpu_stop,
> +};
> +
> +static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started)
> +{
> +       struct imx_rproc *priv = rproc->priv;
> +       const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> +       struct device *dev = priv->dev;
> +       int ret;
> +
> +       /*
> +        * Use power on to do permission check. If rproc is in different LM,
> +        * and linux has permission to handle the LM, set IMX_RPROC_FLAGS_SM_LMM_AVAIL.
> +        */
> +       ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);

I wonder if there is a better call to check if Linux has permissions
to handle to other LMM. This is a bit
strange but if no other option we can go witi it.
> +       if (ret != 0) {
> +               if (ret == -EACCES) {
> +                       /* Not under Linux Control, so only do IPC between rproc and Linux */
> +                       dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);

Would this be an error? So if Linux cannot interact with the other LMM
via LMM API how IPC is possible?
via CPU protocol?

Maybe we need a better explanation here.


> +                       return 0;
> +               }


> +
> +               dev_info(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret);
> +               return ret;
> +       }
> +
> +       priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> +
> +       /* rproc was started before boot Linux and under control of Linux, directly return */
> +       if (started)
> +               return 0;
> +
> +       /* else shutdown the LM to save power */
> +       ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0);
> +       if (ret) {
> +               dev_err(dev, "shutdown lmm(%d) failed: %d\n", dcfg->lmid, ret);

do we care to restore the flags field here on case of error?

> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static int imx_rproc_sm_detect_mode(struct rproc *rproc)
> +{

<snip>

> +
> +       ret = scmi_imx_cpu_started(dcfg->cpuid, &started);

Is this CPU protocol call? So we can still use this even if Host core
and remote core are in different LMMs?

> +       if (ret) {
> +               dev_err(dev, "Failed to detect cpu(%d) status: %d\n", dcfg->cpuid, ret);
> +               return ret;
> +       }
> +
> +       if (started)
> +               priv->rproc->state = RPROC_DETACHED;
> +
> +       /* Get current Linux Logical Machine ID */
> +       ret = scmi_imx_lmm_info(LMM_ID_DISCOVER, &info);
> +       if (ret) {
> +               dev_err(dev, "Failed to get current LMM ID err: %d\n", ret);
> +               return ret;
> +       }
> +
> +       /*
> +        * Check whether remote processor is in same Logical Machine as Linux.

Is in same -> is in the same. We need to always try to be consistent.

Remote processor is a hardware part while Linux is a software part.

So always use the same object types: e.g /*check whether remote
processor is in the same LM as host core (running Linux) */

> +        * If yes, use CPU protocol API to manage remote processor.
> +        * If no, use Logical Machine API to manage remote processor.
> +        */
> +       is_cpu_ops = dcfg->lmid == info.lmid;

No need for is_cpu_ops.

Just go if(dcfg->lmid == info.lmid)


> +
> +       if (is_cpu_ops) {
> +               priv->ops = &imx_rproc_ops_sm_cpu;
> +               dev_info(dev, "Using CPU Protocol OPS\n");

I'm not sure we want to go with dev_info here. It it pollute the log
and at least confuse people.
But if you feel a strong need for this you can keep it.

Also, shouldn't be here an else case where priv->ops gets set to LMM ops?

> +               return 0;
> +       }
> +
> +       dev_info(dev, "Using LMM Protocol OPS\n");
> +
> +       return imx_rproc_sm_lmm_check(rproc, started);

If this check fails is the info message above still valid? It will
confuse people.

<snip>

> @@ -52,6 +52,9 @@ struct imx_rproc_dcfg {
>         enum imx_rproc_method           method;
>         u32                             flags;
>         const struct imx_rproc_plat_ops *ops;
> +       /* For System Manager(SM) based SoCs, the IDs are from SM firmware */

Keep here:

/* For System Manager(SM) based SoCs */

Then comment for each of the fields:
> +       u32                             cpuid; /* TODO.... CPU Id of the remote core? */

> +       u32                             lmid;

But how these fields are set? Are they the cpuid and lmid of the
remote core or local core (a55)?

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 5/5] remoteproc: imx_rproc: Add support for i.MX95
  2025-10-31  2:24 ` [PATCH v2 5/5] remoteproc: imx_rproc: Add support for i.MX95 Peng Fan
  2025-10-31 19:28   ` Frank Li
@ 2025-11-07  9:13   ` Daniel Baluta
  1 sibling, 0 replies; 19+ messages in thread
From: Daniel Baluta @ 2025-11-07  9:13 UTC (permalink / raw)
  To: Peng Fan
  Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

On Fri, Oct 31, 2025 at 4:27 AM Peng Fan <peng.fan@nxp.com> wrote:
>
> Add imx_rproc_cfg_imx95_m7 and address(TCM and DDR) mapping.
> Add i.MX95 of_device_id entry.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>

With the minor comment below, you can add my:

Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>

<snip>

> +static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = {
> +       .att            = imx_rproc_att_imx95_m7,
> +       .att_size       = ARRAY_SIZE(imx_rproc_att_imx95_m7),
> +       .ops            = &imx_rproc_ops_sm,
> +       /* Must align with System Manager Firmware */

I would add a comment here like this:

> +       .cpuid          = 1, /* Use 1 as default cpu id for M7 core */
> +       .lmid           = 1, /* Use 1 as default Logical Machine where M7 resides */
> +};
> +

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API
  2025-11-07  9:10   ` Daniel Baluta
@ 2025-11-07 13:49     ` Peng Fan
  0 siblings, 0 replies; 19+ messages in thread
From: Peng Fan @ 2025-11-07 13:49 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: Peng Fan, Bjorn Andersson, Mathieu Poirier, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta, Frank Li,
	linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel

Hi Daniel,

On Fri, Nov 07, 2025 at 11:10:15AM +0200, Daniel Baluta wrote:
>> There are three cases for M7:
>
>Here we should specify how M7 gets into these three situations, is it
>via the ATF configuration?

It is not ATF configuration. This is configured in System Manager.

>
>e.g
>
>Depending on ATF configuration, M7 can be used as follows:

I will use:
"Depending on System Manager configuration, M7 can be used as follows:"

>
>>  (1) M7 in a separate Logical Machine(LM) that Linux can't control it.
>
>Here we should make it clear from who is M7 separate.
>
>e.g
>
>(1) M7 in a separate Logical Machine (LM) from A55 cores, that Linux
>can't control
>
>>  (2) M7 in a separate Logical Machine that Linux can control it using
>>      LMM protocol
>
>(2) M7 in a separate LM from A55 cores that Linux can control using
>LMM protocol.
>
>>  (3) M7 runs in same Logical Machine as A55, so Linux can control it
>>      using CPU protocol
>>
>
>
>> So extend the driver to using LMM and CPU protocol to manage the M7 core.
>
>
>>  - Compare linux LM ID(got using scmi_imx_lmm_info) and M7 LM ID(the ID
>>    is fixed as 1 in SM firmware if M7 is in a seprate LM),
>
>s/seprate/separate
>
>One question here: Is it OK to call scmi_imx_lmm_info no matter the
>context are we in?

Yes. With LMM_ID_DISCOVER as parameter, this API will not fail in permission
check. It will always return current LM ID.

>
>If this call fails is it safe to assume that we are in the case (1)
>describe above? E.g Linux
>cannot reach the M7 core through LMM protocol  or CPU protocol?

Sadly no. See above.

>
>
>>
...
>> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm = {
>
>I think this should be called imx_rproc_ops_sm_lmm.

ok.

>
>> +       .detect_mode    = imx_rproc_sm_detect_mode,
>> +       .prepare        = imx_rproc_sm_lmm_prepare,
>> +       .start          = imx_rproc_sm_lmm_start,
>> +       .stop           = imx_rproc_sm_lmm_stop,
>> +};
>> +
...
>> +       /*
>> +        * Use power on to do permission check. If rproc is in different LM,
>> +        * and linux has permission to handle the LM, set IMX_RPROC_FLAGS_SM_LMM_AVAIL.
>> +        */
>> +       ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
>
>I wonder if there is a better call to check if Linux has permissions
>to handle to other LMM. This is a bit
>strange but if no other option we can go witi it.

Per doc drivers/firmware/arm_scmi/vendors/imx95.rst, this is the only one
that could be used for runtime detection.

>> +       if (ret != 0) {
>> +               if (ret == -EACCES) {
>> +                       /* Not under Linux Control, so only do IPC between rproc and Linux */
>> +                       dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);
>
>Would this be an error? So if Linux cannot interact with the other LMM
>via LMM API how IPC is possible?
>via CPU protocol?

When M7 is in a different LM, this means it is booted by ROM/SM, so
there is only IPC between M7 and Linux.

>
>Maybe we need a better explanation here.

"RPROC LM is booted before Linux and not under Linux Control, so only
do IPC between RPROC and Linux, not return failure"

>
>
>> +                       return 0;
>> +               }
>> +       /* else shutdown the LM to save power */

...

>> +       ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0);
>> +       if (ret) {
>> +               dev_err(dev, "shutdown lmm(%d) failed: %d\n", dcfg->lmid, ret);
>
>do we care to restore the flags field here on case of error?

keep or clear, both should be fine. But restore the flags should be better
code practice. I will add that.

>
>> +               return ret;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int imx_rproc_sm_detect_mode(struct rproc *rproc)
>> +{
>
><snip>
>
>> +
>> +       ret = scmi_imx_cpu_started(dcfg->cpuid, &started);
>
>Is this CPU protocol call?

Yes.

>So we can still use this even if Host core
>and remote core are in different LMMs?

Yes. SM supports this.

>
>> +       if (ret) {
>> +               dev_err(dev, "Failed to detect cpu(%d) status: %d\n", dcfg->cpuid, ret);
>> +               return ret;
>> +       }
>> +
>> +       if (started)
>> +               priv->rproc->state = RPROC_DETACHED;
>> +
>> +       /* Get current Linux Logical Machine ID */
>> +       ret = scmi_imx_lmm_info(LMM_ID_DISCOVER, &info);
>> +       if (ret) {
>> +               dev_err(dev, "Failed to get current LMM ID err: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       /*
>> +        * Check whether remote processor is in same Logical Machine as Linux.
>
>Is in same -> is in the same. We need to always try to be consistent.
>
>Remote processor is a hardware part while Linux is a software part.
>
>So always use the same object types: e.g /*check whether remote
>processor is in the same LM as host core (running Linux) */
>
>> +        * If yes, use CPU protocol API to manage remote processor.
>> +        * If no, use Logical Machine API to manage remote processor.
>> +        */
>> +       is_cpu_ops = dcfg->lmid == info.lmid;
>
>No need for is_cpu_ops.
>
>Just go if(dcfg->lmid == info.lmid)

ok.

>
>
>> +
>> +       if (is_cpu_ops) {
>> +               priv->ops = &imx_rproc_ops_sm_cpu;
>> +               dev_info(dev, "Using CPU Protocol OPS\n");
>
>I'm not sure we want to go with dev_info here. It it pollute the log
>and at least confuse people.
>But if you feel a strong need for this you can keep it.
>
>Also, shouldn't be here an else case where priv->ops gets set to LMM ops?

Frank has same comment :)
This LMM ops is assigned to dcfg->ops, see patch 5.

But since both of you asked, adding else seems make it clear.

>
>> +               return 0;
>> +       }
>> +
>> +       dev_info(dev, "Using LMM Protocol OPS\n");
>> +
>> +       return imx_rproc_sm_lmm_check(rproc, started);
>
>If this check fails is the info message above still valid? It will
>confuse people.

I prefer to keep the message above, imx_rproc_sm_lmm_check() will
print out error message if there are any failures.

>
><snip>
>
>> @@ -52,6 +52,9 @@ struct imx_rproc_dcfg {
>>         enum imx_rproc_method           method;
>>         u32                             flags;
>>         const struct imx_rproc_plat_ops *ops;
>> +       /* For System Manager(SM) based SoCs, the IDs are from SM firmware */
>
>Keep here:
>
>/* For System Manager(SM) based SoCs */
>
>Then comment for each of the fields:
>> +       u32                             cpuid; /* TODO.... CPU Id of the remote core? */
>
>> +       u32                             lmid;
>
>But how these fields are set? Are they the cpuid and lmid of the
>remote core or local core (a55)?

Both are for remote core. These fields are hard-coded in System Manager.

Thanks
Peng


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2025-11-07 13:49 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-31  2:24 [PATCH v2 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan
2025-10-31  2:24 ` [PATCH v2 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95 Peng Fan
2025-10-31  2:24 ` [PATCH v2 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior Peng Fan
2025-11-04  9:43   ` Iuliana Prodan
2025-11-05  8:47     ` Peng Fan
2025-11-07  7:54   ` Daniel Baluta
2025-10-31  2:24 ` [PATCH v2 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg Peng Fan
2025-10-31 19:20   ` Frank Li
2025-11-07  7:56   ` Daniel Baluta
2025-10-31  2:24 ` [PATCH v2 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan
2025-10-31 19:28   ` Frank Li
2025-11-04  4:28     ` Peng Fan
2025-11-04  9:50   ` Iuliana Prodan
2025-11-05  8:51     ` Peng Fan
2025-11-07  9:10   ` Daniel Baluta
2025-11-07 13:49     ` Peng Fan
2025-10-31  2:24 ` [PATCH v2 5/5] remoteproc: imx_rproc: Add support for i.MX95 Peng Fan
2025-10-31 19:28   ` Frank Li
2025-11-07  9:13   ` Daniel Baluta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).