* [PATCH v5 0/5] remoteproc: imx_rproc: Support i.MX95
@ 2025-12-18 5:17 Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95 Peng Fan (OSS)
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Peng Fan (OSS) @ 2025-12-18 5:17 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Frank Li, Daniel Baluta
Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
Peng Fan, 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 v5:
- Add R-b from Daniel for patch 4
- Patch 4, per Mathieu's comments:
Move imx_rproc_ops_sm_lmm and imx_rproc_ops_sm_cpu to bottom of the file.
Set IMX_RPROC_FLAGS_SM_LMM_AVAIL when scmi_imx_lmm_operation(shutdown)
pass or m7 is started before Linux.
- Link to v4: https://lore.kernel.org/r/20251216-imx95-rproc-2025-12-15-v4-0-bf1064ea8daf@nxp.com
Changes in V4:
- Rebased to 6.19-rc1 to resolve conflicts.
- Address Frank's comment patch 4 regarding "if (ret != 0)" -> "if (ret)"
- Link to v3: https://lore.kernel.org/linux-remoteproc/20251122-imx95-rproc-2025-11-20-v3-0-9ae6ee619a78@nxp.com/#t
Changes in v3:
- Add R-b for patch 2,3,5
- Patch 4:
Rename imx_rproc_ops_sm to imx_rproc_ops_sm_lmm.
Add more comments in code
Simplify if check in imx_rproc_sm_lmm_prepare()
Update commit log
Use dev_err for failure path
- Link to v2: https://lore.kernel.org/linux-remoteproc/20251031-imx95-rproc-2025-10-31-v2-0-758b2e547a55@nxp.com/T/#t
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 | 250 +++++++++++++++++++--
drivers/remoteproc/imx_rproc.h | 4 +
4 files changed, 244 insertions(+), 13 deletions(-)
---
base-commit: 12b95d29eb979e5c4f4f31bb05817bc935c52050
change-id: 20251218-imx95-rproc-2025-12-18-644d2e105017
Best regards,
--
Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v5 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95
2025-12-18 5:17 [PATCH v5 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan (OSS)
@ 2025-12-18 5:17 ` Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior Peng Fan (OSS)
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Peng Fan (OSS) @ 2025-12-18 5:17 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Frank Li, Daniel Baluta
Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
Peng Fan, Krzysztof Kozlowski
From: Peng Fan <peng.fan@nxp.com>
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] 11+ messages in thread
* [PATCH v5 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior
2025-12-18 5:17 [PATCH v5 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95 Peng Fan (OSS)
@ 2025-12-18 5:17 ` Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg Peng Fan (OSS)
` (2 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Peng Fan (OSS) @ 2025-12-18 5:17 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Frank Li, Daniel Baluta
Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
Peng Fan
From: Peng Fan <peng.fan@nxp.com>
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>
Reviewed-by: Daniel Baluta <daniel.baluta@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 33f21ab24c921135319728ead3d24f1833ea1d64..78659c8fb84d95f3d258c21af76cefea1c82850e 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
@@ -584,12 +583,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)
@@ -979,18 +977,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)
@@ -1040,6 +1036,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] 11+ messages in thread
* [PATCH v5 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
2025-12-18 5:17 [PATCH v5 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95 Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior Peng Fan (OSS)
@ 2025-12-18 5:17 ` Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 5/5] remoteproc: imx_rproc: Add support for i.MX95 Peng Fan (OSS)
4 siblings, 0 replies; 11+ messages in thread
From: Peng Fan (OSS) @ 2025-12-18 5:17 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Frank Li, Daniel Baluta
Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Allow each platform to provide its own prepare operations, preparing
for i.MX95 LMM and CPU ops support.
No functional changes.
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/remoteproc/imx_rproc.c | 5 +++++
drivers/remoteproc/imx_rproc.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 78659c8fb84d95f3d258c21af76cefea1c82850e..b0857a1a9660503ee7cd5473c06dacb5262286b8 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -527,6 +527,11 @@ static int imx_rproc_prepare(struct rproc *rproc)
rproc_coredump_add_segment(rproc, da, resource_size(&res));
rproc_add_carveout(rproc, mem);
}
+
+ 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 1b2d9f4d6d19dcdc215be97f7e2ab3488281916a..37417568a0ade2ae4d6a4e3d0f139ea52b185254 100644
--- a/drivers/remoteproc/imx_rproc.h
+++ b/drivers/remoteproc/imx_rproc.h
@@ -24,6 +24,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] 11+ messages in thread
* [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API
2025-12-18 5:17 [PATCH v5 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan (OSS)
` (2 preceding siblings ...)
2025-12-18 5:17 ` [PATCH v5 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg Peng Fan (OSS)
@ 2025-12-18 5:17 ` Peng Fan (OSS)
2025-12-18 15:37 ` Frank Li
2026-01-07 18:41 ` Mathieu Poirier
2025-12-18 5:17 ` [PATCH v5 5/5] remoteproc: imx_rproc: Add support for i.MX95 Peng Fan (OSS)
4 siblings, 2 replies; 11+ messages in thread
From: Peng Fan (OSS) @ 2025-12-18 5:17 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Frank Li, Daniel Baluta
Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
Peng Fan
From: Peng Fan <peng.fan@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.
Depending on SM configuration, M7 can be used as follows:
(1) M7 in a separate Logical Machine (LM) from A55 cores, that Linux
can't control
(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 cores, 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 separate 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.
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/remoteproc/Kconfig | 2 +
drivers/remoteproc/imx_rproc.c | 198 +++++++++++++++++++++++++++++++++++++++++
drivers/remoteproc/imx_rproc.h | 3 +
3 files changed, 203 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 b0857a1a9660503ee7cd5473c06dacb5262286b8..ae3183ad996462ad0815889a2291d320ce7a1e8f 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,9 +94,16 @@ 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);
+/* Forward declarations for platform operations */
+static const struct imx_rproc_plat_ops imx_rproc_ops_sm_lmm;
+static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu;
+
struct imx_rproc {
struct device *dev;
struct regmap *regmap;
@@ -117,6 +126,11 @@ 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
+ * BIT 0: IMX_RPROC_FLAGS_SM_LMM_AVAIL(RPROC LM is under Linux control )
+ */
+ u32 flags;
};
static const struct imx_rproc_att imx_rproc_att_imx93[] = {
@@ -313,6 +327,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 +421,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 +556,33 @@ 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))
+ 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;
@@ -980,6 +1078,93 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
return 0;
}
+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) {
+ if (ret == -EACCES) {
+ /*
+ * rproc LM is booted before Linux and not under Linux Control, so only
+ * do IPC between RPROC and Linux, not return failure
+ */
+ dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);
+ return 0;
+ }
+
+ dev_err(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret);
+ return ret;
+ }
+
+
+ /* rproc was started before boot Linux and under control of Linux, directly return */
+ if (started) {
+ priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
+ 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;
+ }
+
+ priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
+
+ 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;
+ 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 rproc is in the same LM as host core(running Linux)
+ * If yes, use CPU protocol API to manage rproc.
+ * If no, use Logical Machine API to manage rproc.
+ */
+ if (dcfg->lmid == info.lmid) {
+ priv->ops = &imx_rproc_ops_sm_cpu;
+ dev_info(dev, "Using CPU Protocol OPS\n");
+ return 0;
+ }
+
+ priv->ops = &imx_rproc_ops_sm_lmm;
+ 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)
{
/*
@@ -1155,6 +1340,19 @@ static const struct imx_rproc_plat_ops imx_rproc_ops_scu_api = {
.detect_mode = imx_rproc_scu_api_detect_mode,
};
+static const struct imx_rproc_plat_ops 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 const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = {
.src_reg = IMX7D_SRC_SCR,
.src_mask = IMX7D_M4_RST_MASK,
diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
index 37417568a0ade2ae4d6a4e3d0f139ea52b185254..d37e6f90548cec727b4aeb874680b42af85bdbb4 100644
--- a/drivers/remoteproc/imx_rproc.h
+++ b/drivers/remoteproc/imx_rproc.h
@@ -38,6 +38,9 @@ struct imx_rproc_dcfg {
size_t att_size;
u32 flags;
const struct imx_rproc_plat_ops *ops;
+ /* For System Manager(SM) based SoCs */
+ u32 cpuid; /* ID of the remote core */
+ u32 lmid; /* ID of the Logcial Machine */
};
#endif /* _IMX_RPROC_H */
--
2.37.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 5/5] remoteproc: imx_rproc: Add support for i.MX95
2025-12-18 5:17 [PATCH v5 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan (OSS)
` (3 preceding siblings ...)
2025-12-18 5:17 ` [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan (OSS)
@ 2025-12-18 5:17 ` Peng Fan (OSS)
4 siblings, 0 replies; 11+ messages in thread
From: Peng Fan (OSS) @ 2025-12-18 5:17 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Frank Li, Daniel Baluta
Cc: linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Add imx_rproc_cfg_imx95_m7 and address(TCM and DDR) mapping.
Add i.MX95 of_device_id entry.
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
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 ae3183ad996462ad0815889a2291d320ce7a1e8f..61e3f1affee54181bf35110e4ad565edba4c7d06 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -133,6 +133,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 */
@@ -1436,6 +1448,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_lmm,
+ /* Must align with System Manager Firmware */
+ .cpuid = 1, /* Use 1 as cpu id for M7 core */
+ .lmid = 1, /* Use 1 as Logical Machine ID where M7 resides */
+};
+
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 },
@@ -1450,6 +1471,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] 11+ messages in thread
* Re: [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API
2025-12-18 5:17 ` [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan (OSS)
@ 2025-12-18 15:37 ` Frank Li
2026-01-07 18:41 ` Mathieu Poirier
1 sibling, 0 replies; 11+ messages in thread
From: Frank Li @ 2025-12-18 15:37 UTC (permalink / raw)
To: Peng Fan (OSS)
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,
Peng Fan
On Thu, Dec 18, 2025 at 01:17:38PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@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.
>
> Depending on SM configuration, M7 can be used as follows:
> (1) M7 in a separate Logical Machine (LM) from A55 cores, that Linux
> can't control
> (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 cores, 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 separate 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.
>
> Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/remoteproc/Kconfig | 2 +
> drivers/remoteproc/imx_rproc.c | 198 +++++++++++++++++++++++++++++++++++++++++
> drivers/remoteproc/imx_rproc.h | 3 +
> 3 files changed, 203 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 b0857a1a9660503ee7cd5473c06dacb5262286b8..ae3183ad996462ad0815889a2291d320ce7a1e8f 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,9 +94,16 @@ 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);
>
> +/* Forward declarations for platform operations */
> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_lmm;
> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu;
> +
> struct imx_rproc {
> struct device *dev;
> struct regmap *regmap;
> @@ -117,6 +126,11 @@ 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
> + * BIT 0: IMX_RPROC_FLAGS_SM_LMM_AVAIL(RPROC LM is under Linux control )
> + */
> + u32 flags;
> };
>
> static const struct imx_rproc_att imx_rproc_att_imx93[] = {
> @@ -313,6 +327,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 +421,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 +556,33 @@ 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))
> + 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;
> @@ -980,6 +1078,93 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
> return 0;
> }
>
> +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) {
> + if (ret == -EACCES) {
> + /*
> + * rproc LM is booted before Linux and not under Linux Control, so only
> + * do IPC between RPROC and Linux, not return failure
> + */
> + dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);
> + return 0;
> + }
> +
> + dev_err(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret);
> + return ret;
> + }
> +
> +
> + /* rproc was started before boot Linux and under control of Linux, directly return */
> + if (started) {
> + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> + 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;
> + }
> +
> + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> +
> + 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;
> + 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 rproc is in the same LM as host core(running Linux)
> + * If yes, use CPU protocol API to manage rproc.
> + * If no, use Logical Machine API to manage rproc.
> + */
> + if (dcfg->lmid == info.lmid) {
> + priv->ops = &imx_rproc_ops_sm_cpu;
> + dev_info(dev, "Using CPU Protocol OPS\n");
> + return 0;
> + }
> +
> + priv->ops = &imx_rproc_ops_sm_lmm;
> + 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)
> {
> /*
> @@ -1155,6 +1340,19 @@ static const struct imx_rproc_plat_ops imx_rproc_ops_scu_api = {
> .detect_mode = imx_rproc_scu_api_detect_mode,
> };
>
> +static const struct imx_rproc_plat_ops 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 const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = {
> .src_reg = IMX7D_SRC_SCR,
> .src_mask = IMX7D_M4_RST_MASK,
> diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
> index 37417568a0ade2ae4d6a4e3d0f139ea52b185254..d37e6f90548cec727b4aeb874680b42af85bdbb4 100644
> --- a/drivers/remoteproc/imx_rproc.h
> +++ b/drivers/remoteproc/imx_rproc.h
> @@ -38,6 +38,9 @@ struct imx_rproc_dcfg {
> size_t att_size;
> u32 flags;
> const struct imx_rproc_plat_ops *ops;
> + /* For System Manager(SM) based SoCs */
> + u32 cpuid; /* ID of the remote core */
> + u32 lmid; /* ID of the Logcial Machine */
> };
>
> #endif /* _IMX_RPROC_H */
>
> --
> 2.37.1
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API
2025-12-18 5:17 ` [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan (OSS)
2025-12-18 15:37 ` Frank Li
@ 2026-01-07 18:41 ` Mathieu Poirier
2026-01-08 10:29 ` Peng Fan
1 sibling, 1 reply; 11+ messages in thread
From: Mathieu Poirier @ 2026-01-07 18:41 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Frank Li, Daniel Baluta, linux-remoteproc, devicetree, imx,
linux-arm-kernel, linux-kernel, Peng Fan
On Thu, Dec 18, 2025 at 01:17:38PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan@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.
>
> Depending on SM configuration, M7 can be used as follows:
> (1) M7 in a separate Logical Machine (LM) from A55 cores, that Linux
> can't control
> (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 cores, 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 separate 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.
>
> Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> drivers/remoteproc/Kconfig | 2 +
> drivers/remoteproc/imx_rproc.c | 198 +++++++++++++++++++++++++++++++++++++++++
> drivers/remoteproc/imx_rproc.h | 3 +
> 3 files changed, 203 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 b0857a1a9660503ee7cd5473c06dacb5262286b8..ae3183ad996462ad0815889a2291d320ce7a1e8f 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,9 +94,16 @@ 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)
> +
This should be named IMX_RPROC_FLAGS_SM_LMM_CTRL.
> static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block);
> static void imx_rproc_free_mbox(void *data);
>
> +/* Forward declarations for platform operations */
> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_lmm;
> +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu;
> +
> struct imx_rproc {
> struct device *dev;
> struct regmap *regmap;
> @@ -117,6 +126,11 @@ 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
> + * BIT 0: IMX_RPROC_FLAGS_SM_LMM_AVAIL(RPROC LM is under Linux control )
> + */
> + u32 flags;
> };
>
> static const struct imx_rproc_att imx_rproc_att_imx93[] = {
> @@ -313,6 +327,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;
> +
A comment is needed here to say that if the remoteproc core can't start the M7,
it will already be handled in imx_rproc_sm_lmm_prepare()
> + 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 +421,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 +556,33 @@ 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))
> + return rproc->state == RPROC_DETACHED ? 0 : -EACCES;
<<<<<<<<<<<
if (rproc->state == RPROC_DETACHED)
return 0;
if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL))
return -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;
> @@ -980,6 +1078,93 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
> return 0;
> }
>
> +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.
> + */
Two things here:
(1) This whole comment describes what this function does rather than what the
code is doing in the next few lines. As such it needs to be moved above the
function declaration.
(2) We know the M7 is in a different LM, otherwise "dcfg->lmid == info.lmid" in
imx_rproc_sm_detect_mode() and we would not be here. As such the comment is
wrong. The only thing this code is doing is check if the remoteproc core is
responsible for the M7 lifecycle.
> + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
> + if (ret) {
> + if (ret == -EACCES) {
> + /*
> + * rproc LM is booted before Linux and not under Linux Control, so only
> + * do IPC between RPROC and Linux, not return failure
> + */
> + dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid);
> + return 0;
> + }
> +
> + dev_err(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret);
> + return ret;
> + }
> +
> +
>>>>>>>>>>>
> + /* rproc was started before boot Linux and under control of Linux, directly return */
> + if (started) {
> + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> + 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;
> + }
> +
> + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
<<<<<<<<<<<
/* Shutdown remote processor if not started */
if (!started) {
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;
}
}
priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
<<<<<<<<<<<
This patchset would be a lot easier to digest if you had split the support for
CPU and LMM protocols in diffent patches.
> +
> + 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;
> + 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 rproc is in the same LM as host core(running Linux)
> + * If yes, use CPU protocol API to manage rproc.
> + * If no, use Logical Machine API to manage rproc.
> + */
> + if (dcfg->lmid == info.lmid) {
> + priv->ops = &imx_rproc_ops_sm_cpu;
> + dev_info(dev, "Using CPU Protocol OPS\n");
> + return 0;
> + }
> +
> + priv->ops = &imx_rproc_ops_sm_lmm;
> + 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)
> {
> /*
> @@ -1155,6 +1340,19 @@ static const struct imx_rproc_plat_ops imx_rproc_ops_scu_api = {
> .detect_mode = imx_rproc_scu_api_detect_mode,
> };
>
> +static const struct imx_rproc_plat_ops 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 const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = {
> .src_reg = IMX7D_SRC_SCR,
> .src_mask = IMX7D_M4_RST_MASK,
> diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
> index 37417568a0ade2ae4d6a4e3d0f139ea52b185254..d37e6f90548cec727b4aeb874680b42af85bdbb4 100644
> --- a/drivers/remoteproc/imx_rproc.h
> +++ b/drivers/remoteproc/imx_rproc.h
> @@ -38,6 +38,9 @@ struct imx_rproc_dcfg {
> size_t att_size;
> u32 flags;
> const struct imx_rproc_plat_ops *ops;
> + /* For System Manager(SM) based SoCs */
> + u32 cpuid; /* ID of the remote core */
> + u32 lmid; /* ID of the Logcial Machine */
> };
>
> #endif /* _IMX_RPROC_H */
>
> --
> 2.37.1
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API
2026-01-07 18:41 ` Mathieu Poirier
@ 2026-01-08 10:29 ` Peng Fan
2026-01-08 15:10 ` Mathieu Poirier
0 siblings, 1 reply; 11+ messages in thread
From: Peng Fan @ 2026-01-08 10:29 UTC (permalink / raw)
To: Mathieu Poirier
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Frank Li, Daniel Baluta, linux-remoteproc, devicetree, imx,
linux-arm-kernel, linux-kernel, Peng Fan
Hi Mathieu,
On Wed, Jan 07, 2026 at 11:41:07AM -0700, Mathieu Poirier wrote:
>On Thu, Dec 18, 2025 at 01:17:38PM +0800, Peng Fan (OSS) wrote:
>> From: Peng Fan <peng.fan@nxp.com>
>>
...
>> +/* Linux has permission to handle the Logical Machine of remote cores */
>> +#define IMX_RPROC_FLAGS_SM_LMM_AVAIL BIT(0)
>> +
>
>This should be named IMX_RPROC_FLAGS_SM_LMM_CTRL.
Fix in V6.
>
>> 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_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;
>> +
>
>A comment is needed here to say that if the remoteproc core can't start the M7,
>it will already be handled in imx_rproc_sm_lmm_prepare()
Add in V6:
/*
* If the remoteproc core can't start the LM, it will already be
* handled in imx_rproc_sm_lmm_prepare().
*/
>
>> + 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;
>> + }
>> +
>>
...
>> +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))
>> + return rproc->state == RPROC_DETACHED ? 0 : -EACCES;
>
><<<<<<<<<<<
>
> if (rproc->state == RPROC_DETACHED)
> return 0;
>
> if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL))
> return -EACCES;
>
><<<<<<<<<<<
Update in v6 with your code snippets.
>> +
>> + /* 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;
>> @@ -980,6 +1078,93 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
>> return 0;
>> }
>>
>> +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.
>> + */
>
>Two things here:
>(1) This whole comment describes what this function does rather than what the
>code is doing in the next few lines. As such it needs to be moved above the
>function declaration.
>(2) We know the M7 is in a different LM, otherwise "dcfg->lmid == info.lmid" in
>imx_rproc_sm_detect_mode() and we would not be here. As such the comment is
>wrong. The only thing this code is doing is check if the remoteproc core is
>responsible for the M7 lifecycle.
Update in v6:
/* Check whether remoteproc core is responsible for LM lifecycle */
static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started)
>
>> + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
>> + if (ret) {
...
>> +
>> +
>
>>>>>>>>>>>>
>
>> + /* rproc was started before boot Linux and under control of Linux, directly return */
>> + if (started) {
>> + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
>> + 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;
>> + }
>> +
>> + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
>
><<<<<<<<<<<
>
> /* Shutdown remote processor if not started */
> if (!started) {
> 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;
> }
> }
>
> priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
>
><<<<<<<<<<<
Thanks for your code snippets. Update in v6.
>
>This patchset would be a lot easier to digest if you had split the support for
>CPU and LMM protocols in diffent patches.
I appreciate your detailed review and the code snippets you provided. Please
let me know if you'd prefer that I split the support for LMM
and CPU into separate patches in v6, or keep them combined as they are.
Thanks,
Peng.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API
2026-01-08 10:29 ` Peng Fan
@ 2026-01-08 15:10 ` Mathieu Poirier
2026-01-09 6:31 ` Peng Fan
0 siblings, 1 reply; 11+ messages in thread
From: Mathieu Poirier @ 2026-01-08 15:10 UTC (permalink / raw)
To: Peng Fan
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Frank Li, Daniel Baluta, linux-remoteproc, devicetree, imx,
linux-arm-kernel, linux-kernel, Peng Fan
On Thu, Jan 08, 2026 at 06:29:36PM +0800, Peng Fan wrote:
> Hi Mathieu,
>
> On Wed, Jan 07, 2026 at 11:41:07AM -0700, Mathieu Poirier wrote:
> >On Thu, Dec 18, 2025 at 01:17:38PM +0800, Peng Fan (OSS) wrote:
> >> From: Peng Fan <peng.fan@nxp.com>
> >>
> ...
> >> +/* Linux has permission to handle the Logical Machine of remote cores */
> >> +#define IMX_RPROC_FLAGS_SM_LMM_AVAIL BIT(0)
> >> +
> >
> >This should be named IMX_RPROC_FLAGS_SM_LMM_CTRL.
>
> Fix in V6.
>
> >
> >> 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_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;
> >> +
> >
> >A comment is needed here to say that if the remoteproc core can't start the M7,
> >it will already be handled in imx_rproc_sm_lmm_prepare()
>
> Add in V6:
> /*
> * If the remoteproc core can't start the LM, it will already be
The remoteproc core starts a remote processor, which in this case is the M7.
I'm not sure why you are referring to the logical machine (LM).
> * handled in imx_rproc_sm_lmm_prepare().
> */
>
> >
> >> + 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;
> >> + }
> >> +
> >>
> ...
> >> +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))
> >> + return rproc->state == RPROC_DETACHED ? 0 : -EACCES;
> >
> ><<<<<<<<<<<
> >
> > if (rproc->state == RPROC_DETACHED)
> > return 0;
> >
> > if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_AVAIL))
> > return -EACCES;
> >
> ><<<<<<<<<<<
>
> Update in v6 with your code snippets.
>
> >> +
> >> + /* 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;
> >> @@ -980,6 +1078,93 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
> >> return 0;
> >> }
> >>
> >> +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.
> >> + */
> >
> >Two things here:
> >(1) This whole comment describes what this function does rather than what the
> >code is doing in the next few lines. As such it needs to be moved above the
> >function declaration.
> >(2) We know the M7 is in a different LM, otherwise "dcfg->lmid == info.lmid" in
> >imx_rproc_sm_detect_mode() and we would not be here. As such the comment is
> >wrong. The only thing this code is doing is check if the remoteproc core is
> >responsible for the M7 lifecycle.
>
> Update in v6:
> /* Check whether remoteproc core is responsible for LM lifecycle */
Same comment as above.
> static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started)
>
> >
> >> + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0);
> >> + if (ret) {
> ...
> >> +
> >> +
> >
> >>>>>>>>>>>>
> >
> >> + /* rproc was started before boot Linux and under control of Linux, directly return */
> >> + if (started) {
> >> + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> >> + 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;
> >> + }
> >> +
> >> + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> >
> ><<<<<<<<<<<
> >
> > /* Shutdown remote processor if not started */
> > if (!started) {
> > 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;
> > }
> > }
> >
> > priv->flags |= IMX_RPROC_FLAGS_SM_LMM_AVAIL;
> >
> ><<<<<<<<<<<
>
> Thanks for your code snippets. Update in v6.
>
> >
> >This patchset would be a lot easier to digest if you had split the support for
> >CPU and LMM protocols in diffent patches.
>
> I appreciate your detailed review and the code snippets you provided. Please
> let me know if you'd prefer that I split the support for LMM
> and CPU into separate patches in v6, or keep them combined as they are.
Please split.
>
> Thanks,
> Peng.
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API
2026-01-08 15:10 ` Mathieu Poirier
@ 2026-01-09 6:31 ` Peng Fan
0 siblings, 0 replies; 11+ messages in thread
From: Peng Fan @ 2026-01-09 6:31 UTC (permalink / raw)
To: Mathieu Poirier, Peng Fan (OSS)
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Frank Li, Daniel Baluta, 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 v5 4/5] remoteproc: imx_rproc: Add support for
> System Manager API
>
> > >imx_rproc_sm_lmm_prepare()
> >
> > Add in V6:
> > /*
> > * If the remoteproc core can't start the LM, it will already
> > be
>
> The remoteproc core starts a remote processor, which in this case is
> the M7.
> I'm not sure why you are referring to the logical machine (LM).
I was thinking to align with function name. I will use M7 in v6.
> >
> > I appreciate your detailed review and the code snippets you provided.
> > Please let me know if you'd prefer that I split the support for LMM
> > and CPU into separate patches in v6, or keep them combined as they
> are.
>
> Please split.
ok. v6 will have them separated.
Thanks,
Peng.
>
> >
> > Thanks,
> > Peng.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-01-09 6:31 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-18 5:17 [PATCH v5 0/5] remoteproc: imx_rproc: Support i.MX95 Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 1/5] dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95 Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 2/5] remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 3/5] remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg Peng Fan (OSS)
2025-12-18 5:17 ` [PATCH v5 4/5] remoteproc: imx_rproc: Add support for System Manager API Peng Fan (OSS)
2025-12-18 15:37 ` Frank Li
2026-01-07 18:41 ` Mathieu Poirier
2026-01-08 10:29 ` Peng Fan
2026-01-08 15:10 ` Mathieu Poirier
2026-01-09 6:31 ` Peng Fan
2025-12-18 5:17 ` [PATCH v5 5/5] remoteproc: imx_rproc: Add support for i.MX95 Peng Fan (OSS)
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).