This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new b3f75dfe7b1 arch/arm/src/imx9: scmi: Add BBM GPR get and set.
b3f75dfe7b1 is described below
commit b3f75dfe7b135e890f0b59a309c0c4d750a8b4ac
Author: Phil-Engljaehringer <[email protected]>
AuthorDate: Wed Oct 28 11:09:21 2026 +0100
arch/arm/src/imx9: scmi: Add BBM GPR get and set.
Add imx9_scmi_bbmgprset() and imx9_scmi_bbmgprget(), which write and
read a battery-backed BBNSM general purpose register through the System
Manager using the SCMI BBM protocol (BBM_GPR_SET 0x3, BBM_GPR_GET 0x4).
Also add the SCMI status codes (SCMI_ERR_*) so callers can check the
status the request functions pass through, e.g. SCMI_ERR_DENIED.
The GPRs keep their value across resets of any logical machine, so a
core can use them to store a word that survives its own reset and that
the System Manager can read too.
The System Manager configuration must grant the agent access to the
GPR (GET or higher to read, EXCLUSIVE or higher to write), otherwise
the request returns SCMI_ERR_DENIED.
Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Phil-Engljaehringer <[email protected]>
---
arch/arm/src/imx9/imx9_scmi.c | 137 ++++++++++++++++++++++++++++++++++++++++++
arch/arm/src/imx9/imx9_scmi.h | 67 +++++++++++++++++++++
2 files changed, 204 insertions(+)
diff --git a/arch/arm/src/imx9/imx9_scmi.c b/arch/arm/src/imx9/imx9_scmi.c
index ce7278ea172..b8409257be5 100644
--- a/arch/arm/src/imx9/imx9_scmi.c
+++ b/arch/arm/src/imx9/imx9_scmi.c
@@ -105,6 +105,11 @@
#define SCMI_MSG_LMM_NOTIFY 0x9u /* Configure LM notifications */
+/* SCMI BBM protocol message IDs */
+
+#define SCMI_MSG_BBM_GPR_SET 0x3u /* Write a GPR value */
+#define SCMI_MSG_BBM_GPR_GET 0x4u /* Read a GPR value */
+
/* SCMI message type of a P2A notification */
#define SCMI_MSG_TYPE_NOTIFY 3u
@@ -1303,4 +1308,136 @@ int32_t imx9_scmi_lmmevent(uint32_t *lmid, uint32_t
*eventlm,
return status;
}
+int32_t imx9_scmi_bbmgprset(uint32_t channel, uint32_t index,
+ uint32_t value)
+{
+ int32_t status;
+ uint32_t header;
+ void *msg;
+
+ /* Acquire lock */
+
+ SCMI_A2P_LOCK(channel);
+
+ /* Init buffer */
+
+ status = imx9_scmi_bufinit(channel, &msg);
+
+ /* Send request */
+
+ if (status == OK)
+ {
+ /* Request message structure */
+
+ typedef struct
+ {
+ uint32_t header;
+ uint32_t index;
+ uint32_t value;
+ } msg_tbbmd3_t;
+
+ msg_tbbmd3_t *msgtx = (msg_tbbmd3_t *)msg;
+
+ /* Fill in parameters */
+
+ msgtx->index = index;
+ msgtx->value = value;
+
+ /* Send message */
+
+ status = imx9_scmi_a2ptx(channel, SCMI_PROTOCOL_BBM,
+ SCMI_MSG_BBM_GPR_SET, sizeof(msg_tbbmd3_t),
+ &header);
+ }
+
+ /* Receive response */
+
+ if (status == OK)
+ {
+ status = imx9_scmi_a2prx(channel, sizeof(msg_status_t), header);
+ }
+
+ /* Release lock */
+
+ SCMI_A2P_UNLOCK(channel);
+
+ /* Return status */
+
+ return status;
+}
+
+int32_t imx9_scmi_bbmgprget(uint32_t channel, uint32_t index,
+ uint32_t *value)
+{
+ int32_t status;
+ uint32_t header;
+ void *msg;
+
+ /* Response message structure */
+
+ typedef struct
+ {
+ uint32_t header;
+ int32_t status;
+ uint32_t value;
+ } msg_rbbmd4_t;
+
+ /* Acquire lock */
+
+ SCMI_A2P_LOCK(channel);
+
+ /* Init buffer */
+
+ status = imx9_scmi_bufinit(channel, &msg);
+
+ /* Send request */
+
+ if (status == OK)
+ {
+ /* Request message structure */
+
+ typedef struct
+ {
+ uint32_t header;
+ uint32_t index;
+ } msg_tbbmd4_t;
+
+ msg_tbbmd4_t *msgtx = (msg_tbbmd4_t *)msg;
+
+ /* Fill in parameters */
+
+ msgtx->index = index;
+
+ /* Send message */
+
+ status = imx9_scmi_a2ptx(channel, SCMI_PROTOCOL_BBM,
+ SCMI_MSG_BBM_GPR_GET, sizeof(msg_tbbmd4_t),
+ &header);
+ }
+
+ /* Receive response */
+
+ if (status == OK)
+ {
+ status = imx9_scmi_a2prx(channel, sizeof(msg_rbbmd4_t), header);
+ }
+
+ /* Copy out if no error */
+
+ if (status == OK && value != NULL)
+ {
+ const msg_rbbmd4_t *msgrx = (const msg_rbbmd4_t *)msg;
+
+ *value = msgrx->value;
+ }
+
+ /* Release lock */
+
+ SCMI_A2P_UNLOCK(channel);
+
+ /* Return status */
+
+ return status;
+}
+
#endif /* CONFIG_IMX9_SCMI */
diff --git a/arch/arm/src/imx9/imx9_scmi.h b/arch/arm/src/imx9/imx9_scmi.h
index 0e86b41ab06..8fc84a1dbff 100644
--- a/arch/arm/src/imx9/imx9_scmi.h
+++ b/arch/arm/src/imx9/imx9_scmi.h
@@ -55,6 +55,21 @@
#define SCMI_PROTOCOL_FUSA 0x83u /* FuSa protocol */
#define SCMI_PROTOCOL_MISC 0x84u /* Misc protocol */
+/* SCMI status codes returned by the System Manager. The request functions
+ * pass these through unchanged; they overlap with negated errno values.
+ */
+
+#define SCMI_ERR_NOT_SUPPORTED (-1)
+#define SCMI_ERR_INVALID_PARAMETERS (-2)
+#define SCMI_ERR_DENIED (-3)
+#define SCMI_ERR_NOT_FOUND (-4)
+#define SCMI_ERR_OUT_OF_RANGE (-5)
+#define SCMI_ERR_BUSY (-6)
+#define SCMI_ERR_COMMS_ERROR (-7)
+#define SCMI_ERR_GENERIC_ERROR (-8)
+#define SCMI_ERR_HARDWARE_ERROR (-9)
+#define SCMI_ERR_PROTOCOL_ERROR (-10)
+
/* SCMI LMM notification message ID and event flags */
#define SCMI_MSG_LMM_EVENT 0x0u
@@ -285,4 +300,56 @@ int32_t imx9_scmi_lmmnotify(uint32_t channel, uint32_t
lmid, uint32_t flags);
int32_t imx9_scmi_lmmevent(uint32_t *lmid, uint32_t *eventlm,
uint32_t *flags);
+/****************************************************************************
+ * Name: imx9_scmi_bbmgprset
+ *
+ * Description:
+ * Write a battery-backed general purpose register (BBNSM GPR) via the
+ * SCMI BBM protocol. The agent needs EXCLUSIVE or higher access to the
+ * GPR in the System Manager configuration. Blocks until the System
+ * Manager responds, must not be called from interrupt context.
+ *
+ * Input Parameters:
+ * channel - SCMI channel to use for the request
+ * index - Index of the GPR to write
+ * value - 32-bit value to write
+ *
+ * Returned Value:
+ * OK on success, SCMI_ERR_NOT_FOUND if the index is not valid,
+ * SCMI_ERR_DENIED if the agent may not write the GPR, another SCMI
+ * status or a negated errno value on other failures. A CRC error on the
+ * response returns -EIO, which has the same value as
+ * SCMI_ERR_OUT_OF_RANGE.
+ *
+ ****************************************************************************/
+
+int32_t imx9_scmi_bbmgprset(uint32_t channel, uint32_t index,
+ uint32_t value);
+
+/****************************************************************************
+ * Name: imx9_scmi_bbmgprget
+ *
+ * Description:
+ * Read a battery-backed general purpose register (BBNSM GPR) via the
+ * SCMI BBM protocol. The agent needs GET or higher access to the GPR in
+ * the System Manager configuration. Blocks until the System Manager
+ * responds, must not be called from interrupt context.
+ *
+ * Input Parameters:
+ * channel - SCMI channel to use for the request
+ * index - Index of the GPR to read
+ * value - Returned 32-bit GPR value, may be NULL
+ *
+ * Returned Value:
+ * OK on success, SCMI_ERR_NOT_FOUND if the index is not valid,
+ * SCMI_ERR_DENIED if the agent may not read the GPR, another SCMI
+ * status or a negated errno value on other failures. A CRC error on the
+ * response returns -EIO, which has the same value as
+ * SCMI_ERR_OUT_OF_RANGE.
+ *
+ ****************************************************************************/
+
+int32_t imx9_scmi_bbmgprget(uint32_t channel, uint32_t index,
+ uint32_t *value);
+
#endif /* __ARCH_ARM_SRC_IMX9_IMX9_SCMI_H */