Linux kernel and device drivers for NXP i.MX platforms
 help / color / mirror / Atom feed
* [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver
@ 2026-07-27 13:00 Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 01/11] dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave Frieder Schrempf
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf, Krzysztof Kozlowski

This patchset depends on "firmware: imx: driver for NXP
secure-enclave" [1].

The imx-ocotp-ele.c driver currently uses the limited FSB (fuseblock)
to access the fuse registers. In order to gain full read/write access
to all fuses, we need to use the Edgelock Secure Enclave firmware.

This patchset does:

* Add bindings to reference ELE device in OCOTP driver (patch 1)
* Export ELE API functions (patch 3)
* Let the OCOTP driver use the ELE API (patch 7)
* Extend the devicetree of i.MX91/i.MX93 boards for using the ELE API
  (patch 10/11)

The rest of the patches contain cleanups that were implemented along
the way.

This was tested using the 'crucible' tool and by directly reading
from the nvmem device on i.MX93.

This still lacks support for the i.MX94 and i.MX95 as I don't have
the hardware for testing on these platforms. As the documentations is
incomplete it is hard to get the keepout table right without testing
on the actual hardware. If someone else can provide the data and
testing, I can add it in a future version. If not this can be done
later.

---
Changes in v4:
- Reorder allOf in bindings and extend property description (thanks Krzysztof)
- Add R-b from Krzysztof
- Add R-b from Frank
- Improve scope-based cleanup (thanks Frank)
- Move firmware node from patch 11 to 10
- Link to v3: https://patch.msgid.link/20260723-upstreaming-next-20260609-imx-ocotp-ele-v3-0-e26930345b4c@kontron.de

Changes in v3:
- Fix bindings to correctly ignore the secure-enclave property for SoCs other than i.MX93 (thanks Krzysztof)
- Rebase on latest ELE driver patchset (v29) [1]
- Enable ELE in all board devicetrees (suggested by Francesco)
- Put the reserved memory somewhere in the first 256MB of DDR
- Link to v2: https://patch.msgid.link/20260713-upstreaming-next-20260609-imx-ocotp-ele-v2-0-b8266d93514b@kontron.de

Changes in v2:
- Adjust bindings to allow secure-enclave only for i.MX93 and improve commit message (suggested by Krzysztof)
- Export generic ELE API functions to be used by drivers (suggested by Frank and Peng)
- Move the fuse read/write functions to the NVMEM driver (suggested by Frank and Peng)
- Add patch to use __free(kfree) in imx_ocotp_reg_read() to fix memory leak (reported by Sashiko)
- Use device link to prevent SE device from being unbound while referenced (reported by Sashiko)
- Link to v1: https://patch.msgid.link/20260616-upstreaming-next-20260609-imx-ocotp-ele-v1-0-cb7f3698c3e6@kontron.de

[1] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20260721-imx-se-if-v29-0-04a362f4fcca@nxp.com/

To: Srinivas Kandagatla <srini@kernel.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Frank Li <Frank.Li@nxp.com>
To: Sascha Hauer <s.hauer@pengutronix.de>
To: Pengutronix Kernel Team <kernel@pengutronix.de>
To: Fabio Estevam <festevam@gmail.com>
To: Shawn Guo <shawnguo@kernel.org>
To: Pankaj Gupta <pankaj.gupta@nxp.com>
To: Peng Fan (OSS) <peng.fan@oss.nxp.com>
Cc: devicetree@vger.kernel.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux@ew.tq-group.com

---
Frieder Schrempf (11):
      dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave
      firmware: imx: ele: Fix indentation in ele_base_msg.h
      firmware: imx: ele: Export API functions
      nvmem: imx-ocotp-ele: Add keepout table for i.MX93
      nvmem: imx-ocotp-ele: Remove device-specific reg_read()
      nvmem: imx-ocotp-ele: Use scope-based cleanup helpers in imx_ocotp_reg_read()
      nvmem: imx-ocotp-ele: Support the ELE API
      nvmem: imx-ocotp-ele: Remove the FUSE_ELE type
      nvmem: imx-ocotp-ele: Rename FSB access map
      arm64: dts: Add ELE firmware node and common include
      arm64: dts: Enable EdgeLock Secure Enclave on all i.MX91/i.MX93 boards

 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |  23 +-
 arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts  |   1 +
 .../boot/dts/freescale/imx91-11x11-frdm-s.dts      |   1 +
 arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts |   1 +
 arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts    |   1 +
 .../boot/dts/freescale/imx91-phycore-som.dtsi      |   1 +
 arch/arm64/boot/dts/freescale/imx91-tqma9131.dtsi  |  15 +-
 arch/arm64/boot/dts/freescale/imx91-var-dart.dtsi  |   1 +
 arch/arm64/boot/dts/freescale/imx91-var-som.dtsi   |   1 +
 arch/arm64/boot/dts/freescale/imx91_93_common.dtsi |   9 +
 .../boot/dts/freescale/imx93-11x11-evk-common.dtsi |   1 +
 arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts |   1 +
 arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts  |   1 +
 arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts    |   1 +
 arch/arm64/boot/dts/freescale/imx93-firmware.dtsi  |  28 +++
 .../boot/dts/freescale/imx93-kontron-osm-s.dtsi    |   1 +
 .../boot/dts/freescale/imx93-phycore-som.dtsi      |   1 +
 arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi  |   1 +
 arch/arm64/boot/dts/freescale/imx93-var-dart.dtsi  |   1 +
 arch/arm64/boot/dts/freescale/imx93-var-som.dtsi   |   1 +
 drivers/firmware/imx/ele_base_msg.c                |  42 ++--
 drivers/firmware/imx/ele_base_msg.h                |  16 +-
 drivers/firmware/imx/ele_common.c                  |  35 ++-
 drivers/firmware/imx/ele_common.h                  |  14 --
 drivers/firmware/imx/se_ctrl.c                     |   6 +-
 drivers/firmware/imx/se_ctrl.h                     |  14 +-
 drivers/nvmem/imx-ocotp-ele.c                      | 239 +++++++++++++++++----
 include/linux/firmware/imx/se_api.h                |  78 +++++++
 28 files changed, 428 insertions(+), 107 deletions(-)
---
base-commit: 6946cd5d0aa4dd10a414ddcb7a10844fdb0ad345
change-id: 20260616-upstreaming-next-20260609-imx-ocotp-ele-a512ddf96b03
prerequisite-change-id: 20240507-imx-se-if-a40055093dc6:v30
prerequisite-patch-id: 0996915f031a1d899202c5fba75a969d6ce2a53d
prerequisite-patch-id: dbed47ecb907f6b7f7e284c5c1a3c325566eafd7
prerequisite-patch-id: d27164b5932b6d7f4bd5494e4058c84841db4d77
prerequisite-patch-id: 6a9642b23090d9f1ae18bc8969e30217d053938b
prerequisite-patch-id: cdd5a258a3157d609115ccf8b8606d1fcdf520e8
prerequisite-patch-id: d6a8cd2161ea713eebeff46d12f6ae1255c24561
prerequisite-patch-id: 1d8b2e78db2815eaace41a13d571171fb58e4221

Best regards,
--  
Frieder Schrempf <frieder.schrempf@kontron.de>


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

* [PATCH v4 01/11] dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 02/11] firmware: imx: ele: Fix indentation in ele_base_msg.h Frieder Schrempf
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf, Krzysztof Kozlowski

From: Frieder Schrempf <frieder.schrempf@kontron.de>

The driver currently uses the limited MMIO (FSB) interface to access the
OTPs. The intention is to support the firmware interface alongside the
MMIO interface so the driver can pick the interface that is available
(firmware might not be loaded) and fallback to MMIO.

Some SoCs like the i.MX9 family allow full access to the fuses only
through the secure enclave firmware API. Add a property to reference
the secure enclave node and let the driver use the API.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 .../devicetree/bindings/nvmem/imx-ocotp.yaml       | 23 ++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
index a8076d0e2737..f154856bcdec 100644
--- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
+++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
@@ -17,10 +17,6 @@ description: |
   i.MX7D/S, i.MX7ULP, i.MX8MQ, i.MX8MM, i.MX8MN i.MX8MP, i.MX93, i.MX94,
   and i.MX95.
 
-allOf:
-  - $ref: nvmem.yaml#
-  - $ref: nvmem-deprecated-cells.yaml#
-
 properties:
   compatible:
     oneOf:
@@ -56,12 +52,31 @@ properties:
   clocks:
     maxItems: 1
 
+  secure-enclave:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: A phandle to the secure enclave node for full access to
+                 the fuses through firmware API.
+
 required:
   - "#address-cells"
   - "#size-cells"
   - compatible
   - reg
 
+allOf:
+  - $ref: nvmem.yaml#
+  - $ref: nvmem-deprecated-cells.yaml#
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - fsl,imx93-ocotp
+    then:
+      properties:
+        secure-enclave: false
+
 unevaluatedProperties: false
 
 examples:

-- 
2.55.0


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

* [PATCH v4 02/11] firmware: imx: ele: Fix indentation in ele_base_msg.h
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 01/11] dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 03/11] firmware: imx: ele: Export API functions Frieder Schrempf
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

The file uses mixed indentation characters. Use tabs everywhere.

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/firmware/imx/ele_base_msg.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/imx/ele_base_msg.h b/drivers/firmware/imx/ele_base_msg.h
index 475074580dd7..5c128bf56e88 100644
--- a/drivers/firmware/imx/ele_base_msg.h
+++ b/drivers/firmware/imx/ele_base_msg.h
@@ -28,19 +28,19 @@
 #define ELE_GEN_KEY_BLOB_REQ		0xaf
 #define ELE_GET_FW_STATUS_REQ		0xc5
 #define ELE_XIP_DECRYPT_REQ		0xc6
-#define ELE_WRITE_FUSE                  0xd6
-#define ELE_DEV_ATTEST_REQ              0xdb
-#define ELE_WRITE_SHADOW_FUSE_REQ       0xf2
-#define ELE_READ_SHADOW_FUSE_REQ        0xf3
+#define ELE_WRITE_FUSE			0xd6
+#define ELE_DEV_ATTEST_REQ		0xdb
+#define ELE_WRITE_SHADOW_FUSE_REQ	0xf2
+#define ELE_READ_SHADOW_FUSE_REQ	0xf3
 
 #define ELE_GET_INFO_REQ		0xda
 #define ELE_GET_INFO_REQ_MSG_SZ		0x10
 #define ELE_GET_INFO_RSP_MSG_SZ		0x08
 
-#define MAX_UID_SIZE                     (16)
-#define DEV_GETINFO_ROM_PATCH_SHA_SZ     (32)
-#define DEV_GETINFO_FW_SHA_SZ            (32)
-#define DEV_GETINFO_OEM_SRKH_SZ          (64)
+#define MAX_UID_SIZE			(16)
+#define DEV_GETINFO_ROM_PATCH_SHA_SZ	(32)
+#define DEV_GETINFO_FW_SHA_SZ		(32)
+#define DEV_GETINFO_OEM_SRKH_SZ		(64)
 #define DEV_GETINFO_MIN_VER_MASK	0xff
 #define DEV_GETINFO_MAJ_VER_MASK	0xff00
 #define ELE_DEV_INFO_EXTRA_SZ		0x60

-- 
2.55.0


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

* [PATCH v4 03/11] firmware: imx: ele: Export API functions
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 01/11] dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 02/11] firmware: imx: ele: Fix indentation in ele_base_msg.h Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 04/11] nvmem: imx-ocotp-ele: Add keepout table for i.MX93 Frieder Schrempf
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Export generic ELE API functions to send and receive messages. This
allows drivers to implement functions based on the ELE API.

Assisted-by: Claude:claude-opus-4-8
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/firmware/imx/ele_base_msg.c | 42 ++++++++++----------
 drivers/firmware/imx/ele_common.c   | 35 ++++++++++++++++-
 drivers/firmware/imx/ele_common.h   | 14 -------
 drivers/firmware/imx/se_ctrl.c      |  6 +--
 drivers/firmware/imx/se_ctrl.h      | 14 +------
 include/linux/firmware/imx/se_api.h | 78 +++++++++++++++++++++++++++++++++++++
 6 files changed, 137 insertions(+), 52 deletions(-)

diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
index 28b835f2880f..a4ab45efdd63 100644
--- a/drivers/firmware/imx/ele_base_msg.c
+++ b/drivers/firmware/imx/ele_base_msg.c
@@ -8,6 +8,7 @@
 #include <linux/cleanup.h>
 #include <linux/completion.h>
 #include <linux/dma-mapping.h>
+#include <linux/firmware/imx/se_api.h>
 #include <linux/genalloc.h>
 
 #include "ele_base_msg.h"
@@ -106,8 +107,8 @@ int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info)
 		}
 	}
 
-	se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
-			    ELE_GET_INFO_REQ, ELE_GET_INFO_REQ_MSG_SZ, true);
+	imx_se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
+				ELE_GET_INFO_REQ, ELE_GET_INFO_REQ_MSG_SZ, true);
 
 	tx_msg->data[0] = upper_32_bits(get_info_addr);
 	tx_msg->data[1] = lower_32_bits(get_info_addr);
@@ -120,8 +121,8 @@ int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info)
 		return ret;
 	}
 
-	ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_GET_INFO_REQ,
-				      ELE_GET_INFO_RSP_MSG_SZ, true);
+	ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_GET_INFO_REQ,
+					  ELE_GET_INFO_RSP_MSG_SZ, true);
 	if (ret < 0) {
 		ele_get_info_cleanup(priv, get_info_data, get_info_addr, get_info_len);
 		return ret;
@@ -156,16 +157,16 @@ int ele_ping(struct se_if_priv *priv)
 	if (!rx_msg)
 		return -ENOMEM;
 
-	se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
-			    ELE_PING_REQ, ELE_PING_REQ_SZ, true);
+	imx_se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
+				ELE_PING_REQ, ELE_PING_REQ_SZ, true);
 
 	ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_PING_REQ_SZ,
 			       rx_msg, ELE_PING_RSP_SZ);
 	if (ret < 0)
 		return ret;
 
-	ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_PING_REQ,
-				      ELE_PING_RSP_SZ, true);
+	ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_PING_REQ,
+					  ELE_PING_RSP_SZ, true);
 
 	return ret;
 }
@@ -196,8 +197,9 @@ int ele_service_swap(struct se_if_priv *priv,
 	if (!rx_msg)
 		return -ENOMEM;
 
-	se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
-			    ELE_SERVICE_SWAP_REQ, ELE_SERVICE_SWAP_REQ_MSG_SZ, true);
+	imx_se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
+				ELE_SERVICE_SWAP_REQ, ELE_SERVICE_SWAP_REQ_MSG_SZ,
+				true);
 
 	tx_msg->data[0] = flag;
 	tx_msg->data[1] = addr_size;
@@ -212,8 +214,8 @@ int ele_service_swap(struct se_if_priv *priv,
 	if (ret < 0)
 		return ret;
 
-	ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_SERVICE_SWAP_REQ,
-				      ELE_SERVICE_SWAP_RSP_MSG_SZ, true);
+	ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_SERVICE_SWAP_REQ,
+					  ELE_SERVICE_SWAP_RSP_MSG_SZ, true);
 	if (ret)
 		return ret;
 
@@ -248,8 +250,8 @@ int ele_fw_authenticate(struct se_if_priv *priv, dma_addr_t contnr_addr,
 	if (!rx_msg)
 		return -ENOMEM;
 
-	se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
-			    ELE_FW_AUTH_REQ, ELE_FW_AUTH_REQ_SZ, true);
+	imx_se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
+				ELE_FW_AUTH_REQ, ELE_FW_AUTH_REQ_SZ, true);
 
 	tx_msg->data[0] = lower_32_bits(contnr_addr);
 	tx_msg->data[1] = 0;
@@ -260,8 +262,8 @@ int ele_fw_authenticate(struct se_if_priv *priv, dma_addr_t contnr_addr,
 	if (ret < 0)
 		return ret;
 
-	ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_FW_AUTH_REQ,
-				      ELE_FW_AUTH_RSP_MSG_SZ, true);
+	ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_FW_AUTH_REQ,
+					  ELE_FW_AUTH_RSP_MSG_SZ, true);
 
 	return ret;
 }
@@ -286,8 +288,8 @@ int ele_debug_dump(struct se_if_priv *priv)
 	if (!rx_msg)
 		return -ENOMEM;
 
-	se_fill_cmd_msg_hdr(priv, &tx_msg->header, ELE_DEBUG_DUMP_REQ,
-			    ELE_DEBUG_DUMP_REQ_SZ, true);
+	imx_se_fill_cmd_msg_hdr(priv, &tx_msg->header, ELE_DEBUG_DUMP_REQ,
+				ELE_DEBUG_DUMP_REQ_SZ, true);
 
 	msg_ex_cnt = 0;
 	do {
@@ -298,8 +300,8 @@ int ele_debug_dump(struct se_if_priv *priv)
 		if (ret < 0)
 			return ret;
 
-		ret = se_val_rsp_hdr_n_status(priv, rx_msg, ELE_DEBUG_DUMP_REQ,
-					      ELE_DEBUG_DUMP_RSP_SZ, true);
+		ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_DEBUG_DUMP_REQ,
+						  ELE_DEBUG_DUMP_RSP_SZ, true);
 		if (ret) {
 			dev_err(priv->dev, "Dump_Debug_Buffer Error: %x.", ret);
 			break;
diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
index fbb6e584341a..f9c56fd42af0 100644
--- a/drivers/firmware/imx/ele_common.c
+++ b/drivers/firmware/imx/ele_common.c
@@ -3,11 +3,26 @@
  * Copyright 2025 NXP
  */
 
+#include <linux/export.h>
+
 #include "ele_base_msg.h"
 #include "ele_common.h"
 #include "ele_fw_api.h"
 #include "se_ctrl.h"
 
+/* Fill a command message header with a given command ID and length in bytes. */
+int imx_se_fill_cmd_msg_hdr(struct se_if_priv *priv, struct se_msg_hdr *hdr,
+			u8 cmd, u32 len, bool is_base_api)
+{
+	hdr->tag = priv->if_defs->cmd_tag;
+	hdr->ver = (is_base_api) ? priv->if_defs->base_api_ver : priv->if_defs->fw_api_ver;
+	hdr->command = cmd;
+	hdr->size = len >> 2;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imx_se_fill_cmd_msg_hdr);
+
 int se_chk_tx_msg_hdr(struct se_if_device_ctx *dev_ctx, struct se_msg_hdr *header)
 {
 	struct se_if_priv *priv = dev_ctx->priv;
@@ -261,6 +276,21 @@ int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx, void *tx_msg,
 	return err;
 }
 
+/*
+ * Send/receive blocking call for external drivers, operating on the SE
+ * interface private data (the misc device context is resolved internally).
+ */
+int imx_se_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz,
+			void *rx_msg, int exp_rx_msg_sz)
+{
+	if (!priv)
+		return -EINVAL;
+
+	return ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, tx_msg_sz,
+				rx_msg, exp_rx_msg_sz);
+}
+EXPORT_SYMBOL_GPL(imx_se_msg_send_rcv);
+
 static bool check_hdr_exception_for_sz(struct se_if_priv *priv,
 				       struct se_msg_hdr *header)
 {
@@ -402,8 +432,8 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
 	}
 }
 
-int se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
-			    u8 msg_id, u8 sz, bool is_base_api)
+int imx_se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
+				u8 msg_id, u8 sz, bool is_base_api)
 {
 	struct se_msg_hdr *header = &msg->header;
 	u32 status;
@@ -450,6 +480,7 @@ int se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(imx_se_val_rsp_hdr_n_status);
 
 int se_save_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem)
 {
diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
index b63a3fbf087a..8f0739960d4d 100644
--- a/drivers/firmware/imx/ele_common.h
+++ b/drivers/firmware/imx/ele_common.h
@@ -28,20 +28,6 @@ int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx, void *tx_msg,
 		     int tx_msg_sz, void *rx_msg, int exp_rx_msg_sz);
 
 void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg);
-
-int se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
-			    u8 msg_id, u8 sz, bool is_base_api);
-
-/* Fill a command message header with a given command ID and length in bytes. */
-static inline void se_fill_cmd_msg_hdr(struct se_if_priv *priv, struct se_msg_hdr *hdr,
-				       u8 cmd, u32 len, bool is_base_api)
-{
-	hdr->tag = priv->if_defs->cmd_tag;
-	hdr->ver = (is_base_api) ? priv->if_defs->base_api_ver : priv->if_defs->fw_api_ver;
-	hdr->command = cmd;
-	hdr->size = len >> 2;
-}
-
 int se_save_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem);
 
 int se_restore_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem);
diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c
index 3c14964830a6..53f252d2f111 100644
--- a/drivers/firmware/imx/se_ctrl.c
+++ b/drivers/firmware/imx/se_ctrl.c
@@ -911,9 +911,9 @@ static int se_ioctl_cmd_snd_rcv_rsp_handler(struct se_if_device_ctx *dev_ctx,
 		"message received, start transmit to user");
 
 	rsp_status_err =
-		se_val_rsp_hdr_n_status(priv, rx_msg, tx_msg->header.command,
-					cmd_snd_rcv_rsp_info.rx_buf_sz,
-					tx_msg->header.ver == priv->if_defs->base_api_ver);
+		imx_se_val_rsp_hdr_n_status(priv, rx_msg, tx_msg->header.command,
+					    cmd_snd_rcv_rsp_info.rx_buf_sz,
+					    tx_msg->header.ver == priv->if_defs->base_api_ver);
 
 	if (!rsp_status_err) {
 		err = se_dev_ctx_cpy_out_data(dev_ctx);
diff --git a/drivers/firmware/imx/se_ctrl.h b/drivers/firmware/imx/se_ctrl.h
index af7738ad76cd..76082e8b977c 100644
--- a/drivers/firmware/imx/se_ctrl.h
+++ b/drivers/firmware/imx/se_ctrl.h
@@ -7,6 +7,7 @@
 #define SE_CTRL_H
 
 #include <linux/bitfield.h>
+#include <linux/firmware/imx/se_api.h>
 #include <linux/miscdevice.h>
 #include <linux/mailbox_client.h>
 #include <linux/semaphore.h>
@@ -95,22 +96,9 @@ struct se_if_device_ctx {
 	struct kref refcount;
 };
 
-/* Header of the messages exchange with the EdgeLock Enclave */
-struct se_msg_hdr {
-	u8 ver;
-	u8 size;
-	u8 command;
-	u8 tag;
-}  __packed;
-
 #define SE_MU_HDR_SZ		4
 #define SE_MU_HDR_WORD_SZ	1
 
-struct se_api_msg {
-	struct se_msg_hdr header;
-	u32 data[];
-};
-
 struct se_if_defines {
 	const u8 se_if_type;
 	u8 cmd_tag;
diff --git a/include/linux/firmware/imx/se_api.h b/include/linux/firmware/imx/se_api.h
index b1c4c9115d7b..90104ecaaede 100644
--- a/include/linux/firmware/imx/se_api.h
+++ b/include/linux/firmware/imx/se_api.h
@@ -11,4 +11,82 @@
 #define SOC_ID_OF_IMX8ULP		0x084d
 #define SOC_ID_OF_IMX93			0x9300
 
+/**
+ * struct se_msg_hdr - Header of the messages exchanged with the secure enclave.
+ * @ver: API version the message conforms to (base or firmware API version).
+ * @size: Message size in 32-bit words, including the header.
+ * @command: Command identifier.
+ * @tag: Message tag identifying it as a command or a response.
+ */
+struct se_msg_hdr {
+	u8 ver;
+	u8 size;
+	u8 command;
+	u8 tag;
+}  __packed;
+
+/**
+ * struct se_api_msg - A message exchanged with the secure enclave.
+ * @header: Message header describing the command and its length.
+ * @data: Command or response payload, sized per @header.size.
+ */
+struct se_api_msg {
+	struct se_msg_hdr header;
+	u32 data[];
+};
+
+/* Opaque handle to a secure-enclave interface instance. */
+struct se_if_priv;
+
+/**
+ * imx_se_fill_cmd_msg_hdr() - Populate the header of a command message.
+ * @priv: Secure-enclave interface instance the command targets.
+ * @hdr: Message header to be filled in.
+ * @cmd: Command identifier to place in the header.
+ * @len: Total message length in bytes, including the header.
+ * @is_base_api: %true to tag the message with the base API version, %false to
+ *               use the firmware API version.
+ *
+ * Fill in the tag, version, command and size fields of @hdr so that the message
+ * can be sent to the secure enclave.
+ *
+ * Return: 0 on success.
+ */
+int imx_se_fill_cmd_msg_hdr(struct se_if_priv *priv, struct se_msg_hdr *hdr,
+			    u8 cmd, u32 len, bool is_base_api);
+
+/**
+ * imx_se_msg_send_rcv() - Send a command to the secure enclave and wait for the
+ *                         response.
+ * @priv: Secure-enclave interface instance to communicate with.
+ * @tx_msg: Buffer holding the command message to send.
+ * @tx_msg_sz: Size of the command message in bytes.
+ * @rx_msg: Buffer receiving the response message.
+ * @exp_rx_msg_sz: Expected size of the response message in bytes.
+ *
+ * Blocking send/receive helper for external drivers. The transaction is
+ * serialized internally and the misc device context is resolved from @priv.
+ *
+ * Return: number of bytes received on success, or a negative error code.
+ */
+int imx_se_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz,
+			void *rx_msg, int exp_rx_msg_sz);
+
+/**
+ * imx_se_val_rsp_hdr_n_status() - Validate a response header and status code.
+ * @priv: Secure-enclave interface instance the response came from.
+ * @msg: Response message to validate.
+ * @msg_id: Command identifier the response is expected to match.
+ * @sz: Expected response size in bytes.
+ * @is_base_api: %true if the command used the base API version, %false if it
+ *               used the firmware API version.
+ *
+ * Check that the response tag, command identifier, size and API version match
+ * the expectations, and that the enclave reported a successful status.
+ *
+ * Return: 0 if the response is valid and successful, or a negative error code.
+ */
+int imx_se_val_rsp_hdr_n_status(struct se_if_priv *priv, struct se_api_msg *msg,
+				u8 msg_id, u8 sz, bool is_base_api);
+
 #endif /* __SE_API_H__ */

-- 
2.55.0


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

* [PATCH v4 04/11] nvmem: imx-ocotp-ele: Add keepout table for i.MX93
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (2 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 03/11] firmware: imx: ele: Export API functions Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 05/11] nvmem: imx-ocotp-ele: Remove device-specific reg_read() Frieder Schrempf
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Add an overall keepout table to describe which fuse registers are
invalid and not accessible. No functional changes intended.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/nvmem/imx-ocotp-ele.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index a0d2985c6d03..dadec19ca252 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -34,6 +34,8 @@ struct ocotp_devtype_data {
 	u32 num_entry;
 	u32 flag;
 	nvmem_reg_read_t reg_read;
+	const struct nvmem_keepout *keepout;
+	unsigned int nkeepout;
 	struct ocotp_map_entry entry[];
 };
 
@@ -163,6 +165,12 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	priv->config.read_only = true;
 	priv->config.add_legacy_fixed_of_cells = true;
 	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
+
+	if (priv->data->nkeepout) {
+		priv->config.keepout = priv->data->keepout;
+		priv->config.nkeepout = priv->data->nkeepout;
+	}
+
 	mutex_init(&priv->lock);
 
 	nvmem = devm_nvmem_register(dev, &priv->config);
@@ -172,6 +180,14 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct nvmem_keepout imx93_ocotp_keepout[] = {
+	{.start = 208, .end = 252},
+	{.start = 256, .end = 512},
+	{.start = 576, .end = 728},
+	{.start = 732, .end = 752},
+	{.start = 756, .end = 1248},
+};
+
 static const struct ocotp_devtype_data imx93_ocotp_data = {
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
@@ -185,6 +201,8 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
 		{ 188, 1, FUSE_ELE },
 		{ 312, 200, FUSE_FSB }
 	},
+	.keepout = imx93_ocotp_keepout,
+	.nkeepout = ARRAY_SIZE(imx93_ocotp_keepout),
 };
 
 static const struct ocotp_devtype_data imx94_ocotp_data = {

-- 
2.55.0


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

* [PATCH v4 05/11] nvmem: imx-ocotp-ele: Remove device-specific reg_read()
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (3 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 04/11] nvmem: imx-ocotp-ele: Add keepout table for i.MX93 Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 06/11] nvmem: imx-ocotp-ele: Use scope-based cleanup helpers in imx_ocotp_reg_read() Frieder Schrempf
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Remove .reg_read() callback in the device data all devices use the
same implementation.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/nvmem/imx-ocotp-ele.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index dadec19ca252..9d3f94e35508 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -33,7 +33,6 @@ struct ocotp_devtype_data {
 	u32 size;
 	u32 num_entry;
 	u32 flag;
-	nvmem_reg_read_t reg_read;
 	const struct nvmem_keepout *keepout;
 	unsigned int nkeepout;
 	struct ocotp_map_entry entry[];
@@ -158,7 +157,7 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	priv->config.id = NVMEM_DEVID_AUTO;
 	priv->config.owner = THIS_MODULE;
 	priv->config.size = priv->data->size;
-	priv->config.reg_read = priv->data->reg_read;
+	priv->config.reg_read = imx_ocotp_reg_read;
 	priv->config.word_size = 1;
 	priv->config.stride = 1;
 	priv->config.priv = priv;
@@ -190,7 +189,6 @@ static const struct nvmem_keepout imx93_ocotp_keepout[] = {
 
 static const struct ocotp_devtype_data imx93_ocotp_data = {
 	.reg_off = 0x8000,
-	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,
 	.num_entry = 6,
 	.entry = {
@@ -207,7 +205,6 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
 
 static const struct ocotp_devtype_data imx94_ocotp_data = {
 	.reg_off = 0x8000,
-	.reg_read = imx_ocotp_reg_read,
 	.size = 3296, /* 103 Banks */
 	.num_entry = 10,
 	.entry = {
@@ -226,7 +223,6 @@ static const struct ocotp_devtype_data imx94_ocotp_data = {
 
 static const struct ocotp_devtype_data imx95_ocotp_data = {
 	.reg_off = 0x8000,
-	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,
 	.num_entry = 12,
 	.entry = {

-- 
2.55.0


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

* [PATCH v4 06/11] nvmem: imx-ocotp-ele: Use scope-based cleanup helpers in imx_ocotp_reg_read()
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (4 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 05/11] nvmem: imx-ocotp-ele: Remove device-specific reg_read() Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 07/11] nvmem: imx-ocotp-ele: Support the ELE API Frieder Schrempf
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

This simplifies the code and makes sure that buffers are cleared and
locks are released at the end of the function scope.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/nvmem/imx-ocotp-ele.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index 9d3f94e35508..010b53001323 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -5,6 +5,7 @@
  * Copyright 2023 NXP
  */
 
+#include <linux/cleanup.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -71,7 +72,6 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 	u32 count, index, num_bytes;
 	enum fuse_type type;
 	u32 *buf;
-	void *p;
 	int i;
 	u8 skipbytes;
 
@@ -83,11 +83,11 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 	num_bytes = round_up(bytes + skipbytes, 4);
 	count = num_bytes >> 2;
 
-	p = kzalloc(num_bytes, GFP_KERNEL);
+	void *p __free(kfree) = kzalloc(num_bytes, GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;
 
-	mutex_lock(&priv->lock);
+	guard(mutex)(&priv->lock);
 
 	buf = p;
 
@@ -106,10 +106,6 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 
 	memcpy(val, ((u8 *)p) + skipbytes, bytes);
 
-	mutex_unlock(&priv->lock);
-
-	kfree(p);
-
 	return 0;
 };
 

-- 
2.55.0


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

* [PATCH v4 07/11] nvmem: imx-ocotp-ele: Support the ELE API
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (5 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 06/11] nvmem: imx-ocotp-ele: Use scope-based cleanup helpers in imx_ocotp_reg_read() Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 08/11] nvmem: imx-ocotp-ele: Remove the FUSE_ELE type Frieder Schrempf
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

The fuses inside the Edgelock Secure Enclave are currently not
accessed via its API but through the FSB block which provides
limited access to some fuses.

The ELE API allows us to access all fuses with read/write
permissions. Therefore use it as primary method and only fall
back to the limited FSB if the ELE API is not available.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/nvmem/imx-ocotp-ele.c | 168 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 167 insertions(+), 1 deletion(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index 010b53001323..23e91775be5d 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -7,10 +7,12 @@
 
 #include <linux/cleanup.h>
 #include <linux/device.h>
+#include <linux/firmware/imx/se_api.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/nvmem-provider.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/if_ether.h>	/* ETH_ALEN */
@@ -45,8 +47,109 @@ struct imx_ocotp_priv {
 	struct nvmem_config config;
 	struct mutex lock;
 	const struct ocotp_devtype_data *data;
+	struct se_if_priv *se_data;
 };
 
+/* ELE commands and message sizes used for OCOTP fuse access. */
+#define ELE_READ_FUSE_REQ		0x97
+#define ELE_READ_FUSE_REQ_MSG_SZ	0x08
+#define ELE_READ_FUSE_RSP_MSG_SZ	0x0c
+
+#define ELE_WRITE_FUSE			0xd6
+#define ELE_WRITE_FUSE_REQ_MSG_SZ	0x0c
+#define ELE_WRITE_FUSE_RSP_MSG_SZ	0x0c
+
+/*
+ * imx_ocotp_se_read_fuse() - Request the secure enclave FW to read a fuse.
+ * @priv: handle to the secure-enclave interface.
+ * @fuse_id: fuse identifier to read.
+ * @value: location to store the read fuse value.
+ *
+ * Secure enclaves like the EdgeLock Enclave manage the fuses. This requests
+ * the FW to read the fuse and returns the value reported by the FW.
+ *
+ * Return: 0 on success, a negative error code otherwise.
+ */
+static int imx_ocotp_se_read_fuse(struct se_if_priv *priv, u16 fuse_id, u32 *value)
+{
+	int ret;
+
+	if (!priv)
+		return -EINVAL;
+
+	struct se_api_msg *tx_msg __free(kfree) = kzalloc(ELE_READ_FUSE_REQ_MSG_SZ, GFP_KERNEL);
+	if (!tx_msg)
+		return -ENOMEM;
+
+	struct se_api_msg *rx_msg __free(kfree) = kzalloc(ELE_READ_FUSE_RSP_MSG_SZ, GFP_KERNEL);
+	if (!rx_msg)
+		return -ENOMEM;
+
+	ret = imx_se_fill_cmd_msg_hdr(priv, &tx_msg->header, ELE_READ_FUSE_REQ,
+				      ELE_READ_FUSE_REQ_MSG_SZ, true);
+	if (ret)
+		return ret;
+
+	tx_msg->data[0] = fuse_id;
+
+	ret = imx_se_msg_send_rcv(priv, tx_msg, ELE_READ_FUSE_REQ_MSG_SZ,
+				  rx_msg, ELE_READ_FUSE_RSP_MSG_SZ);
+	if (ret < 0)
+		return ret;
+
+	ret = imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_READ_FUSE_REQ,
+					  ELE_READ_FUSE_RSP_MSG_SZ, true);
+	if (ret)
+		return ret;
+
+	*value = rx_msg->data[1];
+
+	return 0;
+}
+
+/*
+ * imx_ocotp_se_write_fuse() - Request the secure enclave FW to write a fuse.
+ * @priv: handle to the secure-enclave interface.
+ * @fuse_id: fuse identifier to write to.
+ * @value: value to write to the fuse.
+ *
+ * Secure enclaves like the EdgeLock Enclave manage the fuses. This requests
+ * the FW to program the fuse with the given value.
+ *
+ * Return: 0 on success, a negative error code otherwise.
+ */
+static int imx_ocotp_se_write_fuse(struct se_if_priv *priv, u16 fuse_id, u32 value)
+{
+	int ret;
+
+	if (!priv)
+		return -EINVAL;
+
+	struct se_api_msg *tx_msg __free(kfree) = kzalloc(ELE_WRITE_FUSE_REQ_MSG_SZ, GFP_KERNEL);
+	if (!tx_msg)
+		return -ENOMEM;
+
+	struct se_api_msg *rx_msg __free(kfree) = kzalloc(ELE_WRITE_FUSE_RSP_MSG_SZ, GFP_KERNEL);
+	if (!rx_msg)
+		return -ENOMEM;
+
+	ret = imx_se_fill_cmd_msg_hdr(priv, &tx_msg->header, ELE_WRITE_FUSE,
+				      ELE_WRITE_FUSE_REQ_MSG_SZ, true);
+	if (ret)
+		return ret;
+
+	tx_msg->data[0] = (32 << 16) | (fuse_id << 5);
+	tx_msg->data[1] = value;
+
+	ret = imx_se_msg_send_rcv(priv, tx_msg, ELE_WRITE_FUSE_REQ_MSG_SZ,
+				  rx_msg, ELE_WRITE_FUSE_RSP_MSG_SZ);
+	if (ret < 0)
+		return ret;
+
+	return imx_se_val_rsp_hdr_n_status(priv, rx_msg, ELE_WRITE_FUSE,
+					   ELE_WRITE_FUSE_RSP_MSG_SZ, true);
+}
+
 static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index)
 {
 	struct imx_ocotp_priv *priv = context;
@@ -72,6 +175,7 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 	u32 count, index, num_bytes;
 	enum fuse_type type;
 	u32 *buf;
+	int ret;
 	int i;
 	u8 skipbytes;
 
@@ -92,6 +196,18 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 	buf = p;
 
 	for (i = index; i < (index + count); i++) {
+		/*
+		 * All fuse registers can be read via ELE. If the SE device is
+		 * available, always prefer it.
+		 */
+		if (priv->se_data) {
+			ret = imx_ocotp_se_read_fuse(priv->se_data, i, buf++);
+			if (ret)
+				return ret;
+
+			continue;
+		}
+
 		type = imx_ocotp_fuse_type(context, i);
 		if (type == FUSE_INVALID || type == FUSE_ELE) {
 			*buf++ = 0;
@@ -109,6 +225,29 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 	return 0;
 };
 
+static int imx_ocotp_reg_write(void *context, unsigned int offset, void *val, size_t bytes)
+{
+	struct imx_ocotp_priv *priv = context;
+	u32 word = offset >> 2;
+	u32 *buf = val;
+
+	/* allow only writing one complete OTP word at a time */
+	if ((bytes != 4) || (offset % 4 != 0))
+		return -EINVAL;
+
+	/*
+	 * The ELE API returns an error when writing an all-zero value. As
+	 * OTP fuse bits can not be switched from 1 to 0 anyway, skip these
+	 * values.
+	 */
+	if (!*buf)
+		return 0;
+
+	guard(mutex)(&priv->lock);
+
+	return imx_ocotp_se_write_fuse(priv->se_data, word, *buf);
+}
+
 static int imx_ocotp_cell_pp(void *context, const char *id, int index,
 			     unsigned int offset, void *data, size_t bytes)
 {
@@ -135,6 +274,7 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
 static int imx_ele_ocotp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct platform_device *se_pdev;
 	struct imx_ocotp_priv *priv;
 	struct nvmem_device *nvmem;
 
@@ -148,16 +288,39 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	if (IS_ERR(priv->base))
 		return PTR_ERR(priv->base);
 
+	struct device_node *np __free(device_node) = of_parse_phandle(pdev->dev.of_node,
+								      "secure-enclave", 0);
+	if (!np) {
+		dev_info(dev, "missing or invalid SE handle, using readonly FSB\n");
+	} else {
+		se_pdev = of_find_device_by_node(np);
+		if (!se_pdev)
+			return dev_err_probe(dev, -ENODEV, "failed to find SE device\n");
+
+		priv->se_data = platform_get_drvdata(se_pdev);
+		if (!priv->se_data) {
+			put_device(&se_pdev->dev);
+			return dev_err_probe(dev, -EPROBE_DEFER, "SE device not ready\n");
+		}
+
+		if (!device_link_add(dev, &se_pdev->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
+			put_device(&se_pdev->dev);
+			return dev_err_probe(dev, -EINVAL, "failed to link to SE device\n");
+		}
+
+		put_device(&se_pdev->dev);
+	}
+
 	priv->config.dev = dev;
 	priv->config.name = "ELE-OCOTP";
 	priv->config.id = NVMEM_DEVID_AUTO;
 	priv->config.owner = THIS_MODULE;
 	priv->config.size = priv->data->size;
 	priv->config.reg_read = imx_ocotp_reg_read;
+	priv->config.reg_write = imx_ocotp_reg_write;
 	priv->config.word_size = 1;
 	priv->config.stride = 1;
 	priv->config.priv = priv;
-	priv->config.read_only = true;
 	priv->config.add_legacy_fixed_of_cells = true;
 	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
 
@@ -166,6 +329,9 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 		priv->config.nkeepout = priv->data->nkeepout;
 	}
 
+	if (!priv->se_data)
+		priv->config.read_only = true;
+
 	mutex_init(&priv->lock);
 
 	nvmem = devm_nvmem_register(dev, &priv->config);

-- 
2.55.0


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

* [PATCH v4 08/11] nvmem: imx-ocotp-ele: Remove the FUSE_ELE type
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (6 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 07/11] nvmem: imx-ocotp-ele: Support the ELE API Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 09/11] nvmem: imx-ocotp-ele: Rename FSB access map Frieder Schrempf
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

There is no use in tracking the fuses that are only accessible via
ELE API and the current lists are incomplete. If the ELE API is
available it will be used as primary access method anyway, otherwise
the fuses not listed as accessible through the FSB can be considered
invalid.

No functional changes intended.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/nvmem/imx-ocotp-ele.c | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index 23e91775be5d..f691ad0cd1a1 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -19,8 +19,7 @@
 
 enum fuse_type {
 	FUSE_FSB = BIT(0),
-	FUSE_ELE = BIT(1),
-	FUSE_ECC = BIT(2),
+	FUSE_ECC = BIT(1),
 	FUSE_INVALID = -1
 };
 
@@ -209,7 +208,7 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 		}
 
 		type = imx_ocotp_fuse_type(context, i);
-		if (type == FUSE_INVALID || type == FUSE_ELE) {
+		if (type == FUSE_INVALID) {
 			*buf++ = 0;
 			continue;
 		}
@@ -352,13 +351,9 @@ static const struct nvmem_keepout imx93_ocotp_keepout[] = {
 static const struct ocotp_devtype_data imx93_ocotp_data = {
 	.reg_off = 0x8000,
 	.size = 2048,
-	.num_entry = 6,
+	.num_entry = 2,
 	.entry = {
 		{ 0, 52, FUSE_FSB },
-		{ 63, 1, FUSE_ELE},
-		{ 128, 16, FUSE_ELE },
-		{ 182, 1, FUSE_ELE },
-		{ 188, 1, FUSE_ELE },
 		{ 312, 200, FUSE_FSB }
 	},
 	.keepout = imx93_ocotp_keepout,
@@ -368,7 +363,7 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
 static const struct ocotp_devtype_data imx94_ocotp_data = {
 	.reg_off = 0x8000,
 	.size = 3296, /* 103 Banks */
-	.num_entry = 10,
+	.num_entry = 9,
 	.entry = {
 		{ 0, 1, FUSE_FSB | FUSE_ECC },
 		{ 7, 1, FUSE_FSB | FUSE_ECC },
@@ -376,7 +371,6 @@ static const struct ocotp_devtype_data imx94_ocotp_data = {
 		{ 12, 24, FUSE_FSB },
 		{ 36, 2, FUSE_FSB  | FUSE_ECC },
 		{ 38, 14, FUSE_FSB },
-		{ 59, 1, FUSE_ELE },
 		{ 525, 2, FUSE_FSB | FUSE_ECC },
 		{ 528, 7, FUSE_FSB },
 		{ 536, 280, FUSE_FSB },
@@ -386,7 +380,7 @@ static const struct ocotp_devtype_data imx94_ocotp_data = {
 static const struct ocotp_devtype_data imx95_ocotp_data = {
 	.reg_off = 0x8000,
 	.size = 2048,
-	.num_entry = 12,
+	.num_entry = 9,
 	.entry = {
 		{ 0, 1, FUSE_FSB | FUSE_ECC },
 		{ 7, 1, FUSE_FSB | FUSE_ECC },
@@ -394,9 +388,6 @@ static const struct ocotp_devtype_data imx95_ocotp_data = {
 		{ 12, 24, FUSE_FSB },
 		{ 36, 2, FUSE_FSB  | FUSE_ECC },
 		{ 38, 14, FUSE_FSB },
-		{ 63, 1, FUSE_ELE },
-		{ 128, 16, FUSE_ELE },
-		{ 188, 1, FUSE_ELE },
 		{ 317, 2, FUSE_FSB | FUSE_ECC },
 		{ 320, 7, FUSE_FSB },
 		{ 328, 184, FUSE_FSB }

-- 
2.55.0


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

* [PATCH v4 09/11] nvmem: imx-ocotp-ele: Rename FSB access map
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (7 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 08/11] nvmem: imx-ocotp-ele: Remove the FUSE_ELE type Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 10/11] arm64: dts: Add ELE firmware node and common include Frieder Schrempf
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

The table is used to declare which fuse registers are accessible
through the FSB block. Name it accordingly to make this clearer for
the reader.

No functional changes intended.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 drivers/nvmem/imx-ocotp-ele.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index f691ad0cd1a1..e9b579753c78 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -33,11 +33,11 @@ struct ocotp_devtype_data {
 	u32 reg_off;
 	char *name;
 	u32 size;
-	u32 num_entry;
+	u32 num_fsb_map;
 	u32 flag;
 	const struct nvmem_keepout *keepout;
 	unsigned int nkeepout;
-	struct ocotp_map_entry entry[];
+	struct ocotp_map_entry fsb_map[];
 };
 
 struct imx_ocotp_priv {
@@ -156,12 +156,12 @@ static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index)
 	u32 start, end;
 	int i;
 
-	for (i = 0; i < data->num_entry; i++) {
-		start = data->entry[i].start;
-		end = data->entry[i].start + data->entry[i].num;
+	for (i = 0; i < data->num_fsb_map; i++) {
+		start = data->fsb_map[i].start;
+		end = data->fsb_map[i].start + data->fsb_map[i].num;
 
 		if (index >= start && index < end)
-			return data->entry[i].type;
+			return data->fsb_map[i].type;
 	}
 
 	return FUSE_INVALID;
@@ -351,8 +351,8 @@ static const struct nvmem_keepout imx93_ocotp_keepout[] = {
 static const struct ocotp_devtype_data imx93_ocotp_data = {
 	.reg_off = 0x8000,
 	.size = 2048,
-	.num_entry = 2,
-	.entry = {
+	.num_fsb_map = 2,
+	.fsb_map = {
 		{ 0, 52, FUSE_FSB },
 		{ 312, 200, FUSE_FSB }
 	},
@@ -363,8 +363,8 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
 static const struct ocotp_devtype_data imx94_ocotp_data = {
 	.reg_off = 0x8000,
 	.size = 3296, /* 103 Banks */
-	.num_entry = 9,
-	.entry = {
+	.num_fsb_map = 9,
+	.fsb_map = {
 		{ 0, 1, FUSE_FSB | FUSE_ECC },
 		{ 7, 1, FUSE_FSB | FUSE_ECC },
 		{ 9, 3, FUSE_FSB | FUSE_ECC },
@@ -380,8 +380,8 @@ static const struct ocotp_devtype_data imx94_ocotp_data = {
 static const struct ocotp_devtype_data imx95_ocotp_data = {
 	.reg_off = 0x8000,
 	.size = 2048,
-	.num_entry = 9,
-	.entry = {
+	.num_fsb_map = 9,
+	.fsb_map = {
 		{ 0, 1, FUSE_FSB | FUSE_ECC },
 		{ 7, 1, FUSE_FSB | FUSE_ECC },
 		{ 9, 3, FUSE_FSB | FUSE_ECC },

-- 
2.55.0


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

* [PATCH v4 10/11] arm64: dts: Add ELE firmware node and common include
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (8 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 09/11] nvmem: imx-ocotp-ele: Rename FSB access map Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 13:00 ` [PATCH v4 11/11] arm64: dts: Enable EdgeLock Secure Enclave on all i.MX91/i.MX93 boards Frieder Schrempf
  2026-07-27 14:42 ` [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frank Li
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Add the firmware node to SoC dtsi and to make it easier for boards to
configure the EdgeLock Secure Enclave on i.MX93, add a common include
file that contains sane defaults. It specifies the memory node,
enables the ELE firmware node and adds a reference to NVMEM OCOTP
driver.

The 1MB memory area required for the firmware is placed in the first
256MB of the DDR. Boards that require a more specific alignment can
override this accordingly.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 arch/arm64/boot/dts/freescale/imx91_93_common.dtsi |  9 +++++++
 arch/arm64/boot/dts/freescale/imx93-firmware.dtsi  | 28 ++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi b/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi
index a1a7e6a0571b..60798b216438 100644
--- a/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi
@@ -46,6 +46,15 @@ A55_0: cpu@0 {
 		};
 	};
 
+	firmware {
+		hsm0: secure-enclave {
+			compatible = "fsl,imx93-se-ele-hsm";
+			mbox-names = "tx", "rx";
+			mboxes = <&s4muap 0 0>, <&s4muap 1 0>;
+			status = "disabled";
+		};
+	};
+
 	osc_32k: clock-osc-32k {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
diff --git a/arch/arm64/boot/dts/freescale/imx93-firmware.dtsi b/arch/arm64/boot/dts/freescale/imx93-firmware.dtsi
new file mode 100644
index 000000000000..58614158ef90
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx93-firmware.dtsi
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2026 Kontron Electronics GmbH
+ */
+
+/{
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		ele_memory: ele-memory {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0 0x80000000 0 0x10000000>;
+			size = <0 0x100000>;
+			no-map;
+		};
+	};
+};
+
+&hsm0 {
+	status = "okay";
+	memory-region = <&ele_memory>;
+};
+
+&ocotp {
+	secure-enclave = <&hsm0>;
+};

-- 
2.55.0


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

* [PATCH v4 11/11] arm64: dts: Enable EdgeLock Secure Enclave on all i.MX91/i.MX93 boards
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (9 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 10/11] arm64: dts: Add ELE firmware node and common include Frieder Schrempf
@ 2026-07-27 13:00 ` Frieder Schrempf
  2026-07-27 14:42 ` [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frank Li
  11 siblings, 0 replies; 13+ messages in thread
From: Frieder Schrempf @ 2026-07-27 13:00 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS)
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf

From: Frieder Schrempf <frieder.schrempf@kontron.de>

Include the common dtsi to enable the firmware node for all boards
based on the i.MX91 or i.MX93 SoC.

For the TQ-Systems i.MX91 TQMa91xxCA / TQMa91xxLA SOM that already has
a node for the reserved memory, keep the current settings.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
 arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts         |  1 +
 arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts      |  1 +
 arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts        |  1 +
 arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts           |  1 +
 arch/arm64/boot/dts/freescale/imx91-phycore-som.dtsi      |  1 +
 arch/arm64/boot/dts/freescale/imx91-tqma9131.dtsi         | 15 ++++++++-------
 arch/arm64/boot/dts/freescale/imx91-var-dart.dtsi         |  1 +
 arch/arm64/boot/dts/freescale/imx91-var-som.dtsi          |  1 +
 arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi |  1 +
 arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts        |  1 +
 arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts         |  1 +
 arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts           |  1 +
 arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi    |  1 +
 arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi      |  1 +
 arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi         |  1 +
 arch/arm64/boot/dts/freescale/imx93-var-dart.dtsi         |  1 +
 arch/arm64/boot/dts/freescale/imx93-var-som.dtsi          |  1 +
 17 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts
index 5716febb5a50..7813a3cf215b 100644
--- a/arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/usb/pd.h>
 #include "imx91.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	compatible = "fsl,imx91-11x11-evk", "fsl,imx91";
diff --git a/arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts b/arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts
index 62dc1dedfb0e..b5a042a58b57 100644
--- a/arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts
+++ b/arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/usb/pd.h>
 #include "imx91.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	compatible = "fsl,imx91-11x11-frdm-s", "fsl,imx91";
diff --git a/arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts b/arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts
index c25561574d3f..20c7e4989367 100644
--- a/arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts
+++ b/arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/usb/pd.h>
 #include "imx91.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	compatible = "fsl,imx91-11x11-frdm", "fsl,imx91";
diff --git a/arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts b/arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts
index ea8cf14e0bc6..430c0402138b 100644
--- a/arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts
+++ b/arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/usb/pd.h>
 #include "imx91.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	compatible = "fsl,imx91-9x9-qsb", "fsl,imx91";
diff --git a/arch/arm64/boot/dts/freescale/imx91-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx91-phycore-som.dtsi
index 8b8cb3daecbb..509d869a216b 100644
--- a/arch/arm64/boot/dts/freescale/imx91-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx91-phycore-som.dtsi
@@ -11,6 +11,7 @@
 #include <dt-bindings/regulator/nxp,pca9450-regulator.h>
 
 #include "imx91.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	model = "PHYTEC phyCORE-i.MX91";
diff --git a/arch/arm64/boot/dts/freescale/imx91-tqma9131.dtsi b/arch/arm64/boot/dts/freescale/imx91-tqma9131.dtsi
index c99d7bc16848..ad66fea4099a 100644
--- a/arch/arm64/boot/dts/freescale/imx91-tqma9131.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx91-tqma9131.dtsi
@@ -7,6 +7,7 @@
  */
 
 #include "imx91.dtsi"
+#include "imx93-firmware.dtsi"
 
 /{
 	model = "TQ-Systems i.MX91 TQMa91xxCA / TQMa91xxLA SOM";
@@ -31,13 +32,6 @@ linux,cma {
 			size = <0 0x10000000>;
 			linux,cma-default;
 		};
-
-		/* EdgeLock secure enclave  */
-		ele_reserved: ele-reserved@a4120000 {
-			compatible = "shared-dma-pool";
-			reg = <0 0xa4120000 0 0x100000>;
-			no-map;
-		};
 	};
 
 	/* SD2 RST# via PMIC SW_EN */
@@ -58,6 +52,13 @@ &adc1 {
 	vref-supply = <&buck5>;
 };
 
+&ele_memory {
+	/delete-property/alloc-ranges;
+	/delete-property/size;
+	reg = <0 0xa4120000 0 0x100000>;
+	no-map;
+};
+
 &flexspi1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexspi1>;
diff --git a/arch/arm64/boot/dts/freescale/imx91-var-dart.dtsi b/arch/arm64/boot/dts/freescale/imx91-var-dart.dtsi
index a9e44efad13f..2e1830c33012 100644
--- a/arch/arm64/boot/dts/freescale/imx91-var-dart.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx91-var-dart.dtsi
@@ -13,6 +13,7 @@
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/usb/pd.h>
 #include "imx91.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	model = "Variscite DART-MX91 Module";
diff --git a/arch/arm64/boot/dts/freescale/imx91-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx91-var-som.dtsi
index b30a0d8a81ba..87db0abb8257 100644
--- a/arch/arm64/boot/dts/freescale/imx91-var-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx91-var-som.dtsi
@@ -11,6 +11,7 @@
 /dts-v1/;
 
 #include "imx91.dtsi"
+#include "imx93-firmware.dtsi"
 
 /{
 	model = "Variscite VAR-SOM-MX91 module";
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi
index f48e7947cf64..65db986fc7ba 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/usb/pd.h>
+#include "imx93-firmware.dtsi"
 
 / {
 	aliases {
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
index bd14ba28690c..0bd19988ce9f 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
@@ -3,6 +3,7 @@
 
 #include <dt-bindings/usb/pd.h>
 #include "imx93.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	compatible = "fsl,imx93-11x11-frdm", "fsl,imx93";
diff --git a/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts b/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts
index ec78c03f4788..0e5c7d1ed4ee 100644
--- a/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/usb/pd.h>
 #include "imx93.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	model = "NXP i.MX93 14X14 EVK board";
diff --git a/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts b/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts
index 01c11c517986..694f114aef36 100644
--- a/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/usb/pd.h>
 #include "imx93.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	model = "NXP i.MX93 9x9 Quick Start Board";
diff --git a/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
index c79b1df339db..c9aa764cc3b8 100644
--- a/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
@@ -5,6 +5,7 @@
 
 #include <dt-bindings/interrupt-controller/irq.h>
 #include "imx93.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	model = "Kontron OSM-S i.MX93";
diff --git a/arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi
index 325e465d0056..076716cc2095 100644
--- a/arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi
@@ -12,6 +12,7 @@
 #include <dt-bindings/regulator/nxp,pca9450-regulator.h>
 
 #include "imx93.dtsi"
+#include "imx93-firmware.dtsi"
 
 /{
 	model = "PHYTEC phyCORE-i.MX93";
diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
index ce34a296495c..159be0d5dfde 100644
--- a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
@@ -6,6 +6,7 @@
  */
 
 #include "imx93.dtsi"
+#include "imx93-firmware.dtsi"
 
 /{
 	model = "TQ-Systems i.MX93 TQMa93xxLA/TQMa93xxCA SOM";
diff --git a/arch/arm64/boot/dts/freescale/imx93-var-dart.dtsi b/arch/arm64/boot/dts/freescale/imx93-var-dart.dtsi
index 69495bb7fc9f..122a8a091c80 100644
--- a/arch/arm64/boot/dts/freescale/imx93-var-dart.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-var-dart.dtsi
@@ -12,6 +12,7 @@
 
 #include <dt-bindings/usb/pd.h>
 #include "imx93.dtsi"
+#include "imx93-firmware.dtsi"
 
 / {
 	model = "Variscite DART-MX93 Module";
diff --git a/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
index 24063bf8183d..50aec264f87c 100644
--- a/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "imx93.dtsi"
+#include "imx93-firmware.dtsi"
 
 /{
 	model = "Variscite VAR-SOM-MX93 module";

-- 
2.55.0


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

* Re: [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver
  2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
                   ` (10 preceding siblings ...)
  2026-07-27 13:00 ` [PATCH v4 11/11] arm64: dts: Enable EdgeLock Secure Enclave on all i.MX91/i.MX93 boards Frieder Schrempf
@ 2026-07-27 14:42 ` Frank Li
  11 siblings, 0 replies; 13+ messages in thread
From: Frank Li @ 2026-07-27 14:42 UTC (permalink / raw)
  To: Frieder Schrempf
  Cc: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Shawn Guo, Pankaj Gupta, Peng Fan (OSS),
	devicetree, imx, linux-arm-kernel, linux-kernel, linux,
	Frieder Schrempf, Krzysztof Kozlowski

On Mon, Jul 27, 2026 at 03:00:43PM +0200, Frieder Schrempf wrote:
...
>
> ---
> Frieder Schrempf (11):
>       dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave
>       firmware: imx: ele: Fix indentation in ele_base_msg.h
>       firmware: imx: ele: Export API functions

Srinivas Kandagatl:

	There are depedence with firmware ele. what's plan to pick this
patch set?
	Will you take firmware: imx: ele: with my Ack/review-by?

Frank


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

end of thread, other threads:[~2026-07-27 14:43 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27 13:00 [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 01/11] dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 02/11] firmware: imx: ele: Fix indentation in ele_base_msg.h Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 03/11] firmware: imx: ele: Export API functions Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 04/11] nvmem: imx-ocotp-ele: Add keepout table for i.MX93 Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 05/11] nvmem: imx-ocotp-ele: Remove device-specific reg_read() Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 06/11] nvmem: imx-ocotp-ele: Use scope-based cleanup helpers in imx_ocotp_reg_read() Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 07/11] nvmem: imx-ocotp-ele: Support the ELE API Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 08/11] nvmem: imx-ocotp-ele: Remove the FUSE_ELE type Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 09/11] nvmem: imx-ocotp-ele: Rename FSB access map Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 10/11] arm64: dts: Add ELE firmware node and common include Frieder Schrempf
2026-07-27 13:00 ` [PATCH v4 11/11] arm64: dts: Enable EdgeLock Secure Enclave on all i.MX91/i.MX93 boards Frieder Schrempf
2026-07-27 14:42 ` [PATCH v4 00/11] Support ELE API in i.MX OCOTP NVMEM driver Frank Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox