linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x
@ 2023-01-18 17:29 Patrick Delaunay
  2023-01-18 17:29 ` [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC Patrick Delaunay
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Patrick Delaunay @ 2023-01-18 17:29 UTC (permalink / raw)
  To: Alexandre TORGUE, Rob Herring, Krzysztof Kozlowski,
	Maxime Coquelin, Srinivas Kandagatla, Arnd Bergmann
  Cc: Etienne CARRIERE, Fabrice GASNIER, Amelie DELAUNAY,
	Lionel DEBIEVE, Patrick Delaunay, devicetree, linux-arm-kernel,
	linux-kernel, linux-stm32


The v5 patchset is rebased on next-20221226.

This serie update the NVMEM BSEC driver to be compatible with STM32MP13x
SoC and the trusted application STM32MP BSEC in OP-TEE

This serie solve issue in initial support of STM32MP131
(using BSEC STM32MP15 compatible) and so it break the STM32MP13x DTS
compatible.

I create this serie for more efficient review, including support for
STM32MP15x.

The first patches of the V1 series is already merged:
"dt-bindings: nvmem: add new stm32mp13 compatible for stm32-romem"

This STM32MP13x DTS break is acceptable as
- the STM32MP13x SoC is not yet available outside STMicroelectronics
  (not official)
- the same patch is already integrated or modifications are in progress in
  the other users (arm-trusted-firmware/TF-A, OP-TEE and U-Boot) of
  stm32mp131 device tree.

It is the good time to correct this issue before the real availability of
the SoC and before full support of STM32MP13x SoC in Linux kernel.

Regards

Patrick

Changes in v6:
- Add reviewed by  Etienne Carierre review
- added reviewed by Etienne Carriere

Changes in v5:
- minor changes after Etienne Carierre review (comments,
  change %x to %#x, remove goto to out_tee_session)
- update the BSEC SMC detection logic in stm32_romem_probe()
  after Etienne Carierre review to support NVMEM probe after OP-TEE probe

Changes in v4:
- fixe warning reported by kernel test robot for 64 bits support in
  drivers/nvmem/stm32-bsec-optee-ta.c:260:18:
  warning: format '%d' expects argument of type 'int',
  but argument 4 has type 'size_t'

Changes in v3:
- add a separate file stm32-bsec-optee-ta.c with STM32MP BSEC TA
  communication functions to avoid #if in romem driver.
- use of_find_compatible_node in optee_presence_check function
  instead of of_find_node_by_path("/firmware/optee")

Changes in v2:
- rebase series on linux-next/master
- minor update after V1 revue

Changes in v1:
- update commit message to indicate DTS break reason.

Patrick Delaunay (3):
  ARM: dts: stm32mp13: fix compatible for BSEC
  nvmem: stm32: add OP-TEE support for STM32MP13x
  nvmem: stm32: detect bsec pta presence for STM32MP15x

 arch/arm/boot/dts/stm32mp131.dtsi   |   2 +-
 drivers/nvmem/Kconfig               |  11 +
 drivers/nvmem/Makefile              |   1 +
 drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
 drivers/nvmem/stm32-bsec-optee-ta.h |  80 ++++++++
 drivers/nvmem/stm32-romem.c         |  84 +++++++-
 6 files changed, 472 insertions(+), 4 deletions(-)
 create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
 create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h

base-commit: c76083fac3bae1a87ae3d005b5cb1cbc761e31d5
prerequisite-patch-id: 5aaa8fffbdd16871143808180b3932d80f4045d0
prerequisite-patch-id: ae711dc528e191e4751cbb7402041fc5f185d6b3
-- 
2.25.1


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

* [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC
  2023-01-18 17:29 [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
@ 2023-01-18 17:29 ` Patrick Delaunay
  2023-01-19 12:06   ` [Linux-stm32] " Ahmad Fatoum
  2023-02-02 12:31   ` Alexandre TORGUE
  2023-01-18 17:29 ` [PATCH v6 2/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 9+ messages in thread
From: Patrick Delaunay @ 2023-01-18 17:29 UTC (permalink / raw)
  To: Alexandre TORGUE, Rob Herring, Krzysztof Kozlowski, Maxime Coquelin
  Cc: Etienne CARRIERE, Fabrice GASNIER, Amelie DELAUNAY,
	Lionel DEBIEVE, Patrick Delaunay, devicetree, linux-arm-kernel,
	linux-kernel, linux-stm32

Use the correct compatible for stm32mp13 support.

The BSEC driver for STM32MP15x is not compatible with STM32MP13x. For
example the proprietary's smc STM32_SMC_BSEC is not supported in
STM32MP13x OP-TEE, it is replaced by SM32MP BSEC Pseudo Trusted
Application in OP-TEE to access to the secured IP BSEC on STM32MP13X SoC.

The correct compatible is already used in U-Boot and in upstream is in
progress for OP-TEE device tree.

As the SoC STM32MP13X is not yet official and it is not available
outside STMicroelectronics, it is the good time to break the DTS
compatibility and to correct the error done in the introduction of
STM32MP131.

Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---
This patch is already sent separately in:
https://lore.kernel.org/all/20221017134437.1.I167a5efc1f8777cce14518c6fa38400ac684de3e@changeid/
https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=685815

I create a serie for more efficient review.

Patrick.

(no changes since v1)

Changes in v1:
- update commit message to indicate DTS break reason.

 arch/arm/boot/dts/stm32mp131.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi
index accc3824f7e9..0b79380cc627 100644
--- a/arch/arm/boot/dts/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/stm32mp131.dtsi
@@ -520,7 +520,7 @@ rtc: rtc@5c004000 {
 		};
 
 		bsec: efuse@5c005000 {
-			compatible = "st,stm32mp15-bsec";
+			compatible = "st,stm32mp13-bsec";
 			reg = <0x5c005000 0x400>;
 			#address-cells = <1>;
 			#size-cells = <1>;
-- 
2.25.1


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

* [PATCH v6 2/3] nvmem: stm32: add OP-TEE support for STM32MP13x
  2023-01-18 17:29 [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
  2023-01-18 17:29 ` [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC Patrick Delaunay
@ 2023-01-18 17:29 ` Patrick Delaunay
  2023-01-20 17:42   ` Srinivas Kandagatla
  2023-01-18 17:29 ` [PATCH v6 3/3] nvmem: stm32: detect bsec pta presence for STM32MP15x Patrick Delaunay
  2023-01-26 21:02 ` [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x Arnd Bergmann
  3 siblings, 1 reply; 9+ messages in thread
From: Patrick Delaunay @ 2023-01-18 17:29 UTC (permalink / raw)
  To: Alexandre TORGUE, Srinivas Kandagatla, Maxime Coquelin
  Cc: Etienne CARRIERE, Fabrice GASNIER, Amelie DELAUNAY,
	Lionel DEBIEVE, Patrick Delaunay, linux-arm-kernel, linux-kernel,
	linux-stm32

For boot with OP-TEE on STM32MP13, the communication with the secure
world no more use STMicroelectronics SMC but communication with the
STM32MP BSEC TA, for data access (read/write) or lock operation:
- all the request are sent to OP-TEE trusted application,
- for upper OTP with ECC protection and with word programming only
  each OTP are permanently locked when programmed to avoid ECC error
  on the second write operation

Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
---

Changes in v6:
- Add reviewed by  Etienne Carierre review

Changes in v5:
- minor changes after Etienne Carierre review (comments,
  change %x to %#x, remove goto to out_tee_session)

Changes in v4:
- fixe warning reported by kernel test robot for 64 bits support in
  drivers/nvmem/stm32-bsec-optee-ta.c:260:18:
  warning: format '%d' expects argument of type 'int',
  but argument 4 has type 'size_t'

Changes in v3:
- add a separate file stm32-bsec-optee-ta.c with STM32MP BSEC TA
  communication functions to avoid #if in romem driver.

Changes in v2:
- rebase series on linux-next/master
- minor update after V1 revue
- add missing sentinel in stm32_romem_of_match()
- reorder function and remove prototypes for stm32_bsec_pta... functions
- change stm32_bsec_pta_find to static
- add return value in dev_err()
- cleanups some comments, which can be on one line
- remove test on priv->ctx in stm32_bsec_pta_remove
- add missing tee_shm_free(shm) in stm32_bsec_pta_write() when
  tee_shm_get_va failed
- return error in stm32_bsec_pta_find when devm_add_action_or_reset failed
- handle driver_register error in stm32_romem_init

 drivers/nvmem/Kconfig               |  11 +
 drivers/nvmem/Makefile              |   1 +
 drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
 drivers/nvmem/stm32-bsec-optee-ta.h |  80 ++++++++
 drivers/nvmem/stm32-romem.c         |  54 ++++-
 5 files changed, 441 insertions(+), 3 deletions(-)
 create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
 create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 755f551426b5..4d262f69a073 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem-sprd-efuse.
 
+config NVMEM_STM32_BSEC_OPTEE_TA
+	bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
+	depends on OPTEE
+	help
+	  Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
+	  trusted application STM32MP BSEC.
+
+	  This library is a used by stm32-romem driver or included in the module
+	  called nvmem-stm32-romem.
+
 config NVMEM_STM32_ROMEM
 	tristate "STMicroelectronics STM32 factory-programmed memory support"
 	depends on ARCH_STM32 || COMPILE_TEST
+	imply NVMEM_STM32_BSEC_OPTEE_TA
 	help
 	  Say y here to enable read-only access for STMicroelectronics STM32
 	  factory-programmed memory area.
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index fa80fe17e567..6a1efffa88f0 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE)		+= nvmem_sprd_efuse.o
 nvmem_sprd_efuse-y			:= sprd-efuse.o
 obj-$(CONFIG_NVMEM_STM32_ROMEM)		+= nvmem_stm32_romem.o
 nvmem_stm32_romem-y 			:= stm32-romem.o
+nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o
 obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvmem_sunplus_ocotp.o
 nvmem_sunplus_ocotp-y			:= sunplus-ocotp.o
 obj-$(CONFIG_NVMEM_SUNXI_SID)		+= nvmem_sunxi_sid.o
diff --git a/drivers/nvmem/stm32-bsec-optee-ta.c b/drivers/nvmem/stm32-bsec-optee-ta.c
new file mode 100644
index 000000000000..f89ce791dd12
--- /dev/null
+++ b/drivers/nvmem/stm32-bsec-optee-ta.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
+ *
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ */
+
+#include <linux/tee_drv.h>
+
+#include "stm32-bsec-optee-ta.h"
+
+/*
+ * Read OTP memory
+ *
+ * [in]		value[0].a		OTP start offset in byte
+ * [in]		value[0].b		Access type (0:shadow, 1:fuse, 2:lock)
+ * [out]	memref[1].buffer	Output buffer to store read values
+ * [out]	memref[1].size		Size of OTP to be read
+ *
+ * Return codes:
+ * TEE_SUCCESS - Invoke command success
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
+ */
+#define PTA_BSEC_READ_MEM		0x0
+
+/*
+ * Write OTP memory
+ *
+ * [in]		value[0].a		OTP start offset in byte
+ * [in]		value[0].b		Access type (0:shadow, 1:fuse, 2:lock)
+ * [in]		memref[1].buffer	Input buffer to read values
+ * [in]		memref[1].size		Size of OTP to be written
+ *
+ * Return codes:
+ * TEE_SUCCESS - Invoke command success
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
+ */
+#define PTA_BSEC_WRITE_MEM		0x1
+
+/* value of PTA_BSEC access type = value[in] b */
+#define SHADOW_ACCESS	0
+#define FUSE_ACCESS	1
+#define LOCK_ACCESS	2
+
+/* Bitfield definition for LOCK status */
+#define LOCK_PERM			BIT(30)
+
+/* OP-TEE STM32MP BSEC TA UUID */
+static const uuid_t stm32mp_bsec_ta_uuid =
+	UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5,
+		  0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03);
+
+/*
+ * Check whether this driver supports the BSEC TA in the TEE instance
+ * represented by the params (ver/data) to this function.
+ */
+static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver,
+				     const void *data)
+{
+	/* Currently this driver only supports GP compliant, OP-TEE based TA */
+	if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
+		(ver->gen_caps & TEE_GEN_CAP_GP))
+		return 1;
+	else
+		return 0;
+}
+
+/* Open a session to OP-TEE for STM32MP BSEC TA */
+static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id)
+{
+	struct tee_ioctl_open_session_arg sess_arg;
+	int rc;
+
+	memset(&sess_arg, 0, sizeof(sess_arg));
+	export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid);
+	sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
+	sess_arg.num_params = 0;
+
+	rc = tee_client_open_session(ctx, &sess_arg, NULL);
+	if ((rc < 0) || (sess_arg.ret != 0)) {
+		pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n",
+		       __func__, sess_arg.ret, rc);
+		if (!rc)
+			rc = -EINVAL;
+	} else {
+		*id = sess_arg.session;
+	}
+
+	return rc;
+}
+
+/* close a session to OP-TEE for STM32MP BSEC TA */
+static void stm32_bsec_ta_close_session(void *ctx, u32 id)
+{
+	tee_client_close_session(ctx, id);
+}
+
+/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */
+int stm32_bsec_optee_ta_open(struct tee_context **ctx)
+{
+	struct tee_context *tee_ctx;
+	u32 session_id;
+	int rc;
+
+	/* Open context with TEE driver */
+	tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL);
+	if (IS_ERR(tee_ctx)) {
+		rc = PTR_ERR(tee_ctx);
+		if (rc == -ENOENT)
+			return -EPROBE_DEFER;
+		pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc);
+
+		return rc;
+	}
+
+	/* Check STM32MP BSEC TA presence */
+	rc = stm32_bsec_ta_open_session(tee_ctx, &session_id);
+	if (rc) {
+		tee_client_close_context(tee_ctx);
+		return rc;
+	}
+
+	stm32_bsec_ta_close_session(tee_ctx, session_id);
+
+	*ctx = tee_ctx;
+
+	return 0;
+}
+
+/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */
+void stm32_bsec_optee_ta_close(void *ctx)
+{
+	tee_client_close_context(ctx);
+}
+
+/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
+			     void *buf, size_t bytes)
+{
+	struct tee_shm *shm;
+	struct tee_ioctl_invoke_arg arg;
+	struct tee_param param[2];
+	u8 *shm_buf;
+	u32 start, num_bytes;
+	int ret;
+	u32 session_id;
+
+	ret = stm32_bsec_ta_open_session(ctx, &session_id);
+	if (ret)
+		return ret;
+
+	memset(&arg, 0, sizeof(arg));
+	memset(&param, 0, sizeof(param));
+
+	arg.func = PTA_BSEC_READ_MEM;
+	arg.session = session_id;
+	arg.num_params = 2;
+
+	/* align access on 32bits */
+	start = ALIGN_DOWN(offset, 4);
+	num_bytes = round_up(offset + bytes - start, 4);
+	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+	param[0].u.value.a = start;
+	param[0].u.value.b = SHADOW_ACCESS;
+
+	shm = tee_shm_alloc_kernel_buf(ctx, num_bytes);
+	if (IS_ERR(shm)) {
+		ret = PTR_ERR(shm);
+		goto out_tee_session;
+	}
+
+	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
+	param[1].u.memref.shm = shm;
+	param[1].u.memref.size = num_bytes;
+
+	ret = tee_client_invoke_func(ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n",
+			arg.ret, ret);
+		if (!ret)
+			ret = -EIO;
+	}
+	if (!ret) {
+		shm_buf = tee_shm_get_va(shm, 0);
+		if (IS_ERR(shm_buf)) {
+			ret = PTR_ERR(shm_buf);
+			pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
+		} else {
+			/* read data from 32 bits aligned buffer */
+			memcpy(buf, &shm_buf[offset % 4], bytes);
+		}
+	}
+
+	tee_shm_free(shm);
+
+out_tee_session:
+	stm32_bsec_ta_close_session(ctx, session_id);
+
+	return ret;
+}
+
+/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
+			      unsigned int offset, void *buf, size_t bytes)
+{	struct tee_shm *shm;
+	struct tee_ioctl_invoke_arg arg;
+	struct tee_param param[2];
+	u8 *shm_buf;
+	int ret;
+	u32 session_id;
+
+	ret = stm32_bsec_ta_open_session(ctx, &session_id);
+	if (ret)
+		return ret;
+
+	/* Allow only writing complete 32-bits aligned words */
+	if ((bytes % 4) || (offset % 4))
+		return -EINVAL;
+
+	memset(&arg, 0, sizeof(arg));
+	memset(&param, 0, sizeof(param));
+
+	arg.func = PTA_BSEC_WRITE_MEM;
+	arg.session = session_id;
+	arg.num_params = 2;
+
+	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+	param[0].u.value.a = offset;
+	param[0].u.value.b = FUSE_ACCESS;
+
+	shm = tee_shm_alloc_kernel_buf(ctx, bytes);
+	if (IS_ERR(shm)) {
+		ret = PTR_ERR(shm);
+		goto out_tee_session;
+	}
+
+	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
+	param[1].u.memref.shm = shm;
+	param[1].u.memref.size = bytes;
+
+	shm_buf = tee_shm_get_va(shm, 0);
+	if (IS_ERR(shm_buf)) {
+		ret = PTR_ERR(shm_buf);
+		pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
+		tee_shm_free(shm);
+
+		goto out_tee_session;
+	}
+
+	memcpy(shm_buf, buf, bytes);
+
+	ret = tee_client_invoke_func(ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
+		if (!ret)
+			ret = -EIO;
+	}
+	pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret);
+
+	/* Lock the upper OTPs with ECC protection, word programming only */
+	if (!ret && ((offset + bytes) >= (lower * 4))) {
+		u32 start, nb_lock;
+		u32 *lock = (u32 *)shm_buf;
+		int i;
+
+		/*
+		 * don't lock the lower OTPs, no ECC protection and incremental
+		 * bit programming, a second write is allowed
+		 */
+		start = max_t(u32, offset, lower * 4);
+		nb_lock = (offset + bytes - start) / 4;
+
+		param[0].u.value.a = start;
+		param[0].u.value.b = LOCK_ACCESS;
+		param[1].u.memref.size = nb_lock * 4;
+
+		for (i = 0; i < nb_lock; i++)
+			lock[i] = LOCK_PERM;
+
+		ret = tee_client_invoke_func(ctx, &arg, param);
+		if (ret < 0 || arg.ret != 0) {
+			pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
+			if (!ret)
+				ret = -EIO;
+		}
+		pr_debug("Lock upper OTPs %d to %d, ret=%d\n",
+			 start / 4, start / 4 + nb_lock, ret);
+	}
+
+	tee_shm_free(shm);
+
+out_tee_session:
+	stm32_bsec_ta_close_session(ctx, session_id);
+
+	return ret;
+}
diff --git a/drivers/nvmem/stm32-bsec-optee-ta.h b/drivers/nvmem/stm32-bsec-optee-ta.h
new file mode 100644
index 000000000000..3966a0535179
--- /dev/null
+++ b/drivers/nvmem/stm32-bsec-optee-ta.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
+ *
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ */
+
+#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA)
+/**
+ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA
+ * @ctx: the OP-TEE context on success
+ *
+ * Return:
+ *	On success, 0. On failure, -errno.
+ */
+int stm32_bsec_optee_ta_open(struct tee_context **ctx);
+
+/**
+ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA
+ * @ctx: the OP-TEE context
+ *
+ * This function used to clean the OP-TEE resources initialized in
+ * stm32_bsec_optee_ta_open(); it can be used as callback to
+ * devm_add_action_or_reset()
+ */
+void stm32_bsec_optee_ta_close(void *ctx);
+
+/**
+ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver
+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
+ * @offset: nvmem offset
+ * @buf: buffer to fill with nvem values
+ * @bytes: number of bytes to read
+ *
+ * Return:
+ *	On success, 0. On failure, -errno.
+ */
+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
+			     void *buf, size_t bytes);
+
+/**
+ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver
+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
+ * @lower: number of lower OTP, not protected by ECC
+ * @offset: nvmem offset
+ * @buf: buffer with nvem values
+ * @bytes: number of bytes to write
+ *
+ * Return:
+ *	On success, 0. On failure, -errno.
+ */
+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
+			      unsigned int offset, void *buf, size_t bytes);
+
+#else
+
+static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void stm32_bsec_optee_ta_close(void *ctx)
+{
+}
+
+static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
+					   unsigned int offset, void *buf,
+					   size_t bytes)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
+					    unsigned int lower,
+					    unsigned int offset, void *buf,
+					    size_t bytes)
+{
+	return -EOPNOTSUPP;
+}
+#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */
diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
index d1d03c2ad081..978a63edf297 100644
--- a/drivers/nvmem/stm32-romem.c
+++ b/drivers/nvmem/stm32-romem.c
@@ -11,6 +11,9 @@
 #include <linux/module.h>
 #include <linux/nvmem-provider.h>
 #include <linux/of_device.h>
+#include <linux/tee_drv.h>
+
+#include "stm32-bsec-optee-ta.h"
 
 /* BSEC secure service access from non-secure */
 #define STM32_SMC_BSEC			0x82001003
@@ -25,12 +28,14 @@
 struct stm32_romem_cfg {
 	int size;
 	u8 lower;
+	bool ta;
 };
 
 struct stm32_romem_priv {
 	void __iomem *base;
 	struct nvmem_config cfg;
 	u8 lower;
+	struct tee_context *ctx;
 };
 
 static int stm32_romem_read(void *context, unsigned int offset, void *buf,
@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *context, unsigned int offset, void *buf,
 	return 0;
 }
 
+static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
+			       size_t bytes)
+{
+	struct stm32_romem_priv *priv = context;
+
+	return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
+}
+
+static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
+				size_t bytes)
+{
+	struct stm32_romem_priv *priv = context;
+
+	return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
+}
+
 static int stm32_romem_probe(struct platform_device *pdev)
 {
 	const struct stm32_romem_cfg *cfg;
 	struct device *dev = &pdev->dev;
 	struct stm32_romem_priv *priv;
 	struct resource *res;
+	int rc;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct platform_device *pdev)
 	} else {
 		priv->cfg.size = cfg->size;
 		priv->lower = cfg->lower;
-		priv->cfg.reg_read = stm32_bsec_read;
-		priv->cfg.reg_write = stm32_bsec_write;
+		if (cfg->ta) {
+			rc = stm32_bsec_optee_ta_open(&priv->ctx);
+			/* wait for OP-TEE client driver to be up and ready */
+			if (rc)
+				return rc;
+		}
+		if (priv->ctx) {
+			rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
+			if (rc) {
+				dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc);
+				return rc;
+			}
+			priv->cfg.reg_read = stm32_bsec_pta_read;
+			priv->cfg.reg_write = stm32_bsec_pta_write;
+		} else {
+			priv->cfg.reg_read = stm32_bsec_read;
+			priv->cfg.reg_write = stm32_bsec_write;
+		}
 	}
 
 	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
 }
 
 /*
- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
+ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
  * => 96 x 32-bits data words
  * - Lower: 1K bits, 2:1 redundancy, incremental bit programming
  *   => 32 (x 32-bits) lower shadow registers = words 0 to 31
@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct platform_device *pdev)
 static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
 	.size = 384,
 	.lower = 32,
+	.ta = false,
+};
+
+static const struct stm32_romem_cfg stm32mp13_bsec_cfg = {
+	.size = 384,
+	.lower = 32,
+	.ta = true,
 };
 
 static const struct of_device_id stm32_romem_of_match[] = {
@@ -198,7 +243,10 @@ static const struct of_device_id stm32_romem_of_match[] = {
 		.compatible = "st,stm32mp15-bsec",
 		.data = (void *)&stm32mp15_bsec_cfg,
 	}, {
+		.compatible = "st,stm32mp13-bsec",
+		.data = (void *)&stm32mp13_bsec_cfg,
 	},
+	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
 
-- 
2.25.1


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

* [PATCH v6 3/3] nvmem: stm32: detect bsec pta presence for STM32MP15x
  2023-01-18 17:29 [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
  2023-01-18 17:29 ` [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC Patrick Delaunay
  2023-01-18 17:29 ` [PATCH v6 2/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
@ 2023-01-18 17:29 ` Patrick Delaunay
  2023-01-20 17:42   ` Srinivas Kandagatla
  2023-01-26 21:02 ` [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x Arnd Bergmann
  3 siblings, 1 reply; 9+ messages in thread
From: Patrick Delaunay @ 2023-01-18 17:29 UTC (permalink / raw)
  To: Alexandre TORGUE, Srinivas Kandagatla, Maxime Coquelin
  Cc: Etienne CARRIERE, Fabrice GASNIER, Amelie DELAUNAY,
	Lionel DEBIEVE, Patrick Delaunay, linux-arm-kernel, linux-kernel,
	linux-stm32

On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used;
the PTA BSEC should be used as it is done on STM32MP13x platform,
but the BSEC SMC can be also used: it is a legacy mode in OP-TEE,
not recommended but used in previous OP-TEE firmware.

The presence of OP-TEE is dynamically detected in STM32MP15x device tree
and the supported NVMEM backend is dynamically detected:
- PTA with stm32_bsec_pta_find
- SMC with stm32_bsec_check

With OP-TEE but without PTA and SMC detection, the probe is deferred for
STM32MP15x devices.

On STM32MP13x platform, only the PTA is supported with cfg->ta = true
and this detection is skipped.

Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
---

Changes in v6:
- added reviewed by Etienne Carriere

Changes in v5:
- update the BSEC SMC detection logic in stm32_romem_probe()
  after Etienne Carierre review to support NVMEM probe after OP-TEE probe

Changes in v3:
- use of_find_compatible_node in optee_presence_check function
  instead of of_find_node_by_path("/firmware/optee")

Changes in v2:
- Added patch in the serie for BSEC PTA support on STM32MP15x
  with dynamic detection of OP-TEE presence and SMC support (legacy mode)

 drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
index 978a63edf297..ba779e26937a 100644
--- a/drivers/nvmem/stm32-romem.c
+++ b/drivers/nvmem/stm32-romem.c
@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
 	return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
 }
 
+static bool stm32_bsec_smc_check(void)
+{
+	u32 val;
+	int ret;
+
+	/* check that the OP-TEE support the BSEC SMC (legacy mode) */
+	ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val);
+
+	return !ret;
+}
+
+static bool optee_presence_check(void)
+{
+	struct device_node *np;
+	bool tee_detected = false;
+
+	/* check that the OP-TEE node is present and available. */
+	np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz");
+	if (np && of_device_is_available(np))
+		tee_detected = true;
+	of_node_put(np);
+
+	return tee_detected;
+}
+
 static int stm32_romem_probe(struct platform_device *pdev)
 {
 	const struct stm32_romem_cfg *cfg;
@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct platform_device *pdev)
 	} else {
 		priv->cfg.size = cfg->size;
 		priv->lower = cfg->lower;
-		if (cfg->ta) {
+		if (cfg->ta || optee_presence_check()) {
 			rc = stm32_bsec_optee_ta_open(&priv->ctx);
-			/* wait for OP-TEE client driver to be up and ready */
-			if (rc)
-				return rc;
+			if (rc) {
+				/* wait for OP-TEE client driver to be up and ready */
+				if (rc == -EPROBE_DEFER)
+					return -EPROBE_DEFER;
+				/* BSEC PTA is required or SMC not supported */
+				if (cfg->ta || !stm32_bsec_smc_check())
+					return rc;
+			}
 		}
 		if (priv->ctx) {
 			rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
-- 
2.25.1


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

* Re: [Linux-stm32] [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC
  2023-01-18 17:29 ` [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC Patrick Delaunay
@ 2023-01-19 12:06   ` Ahmad Fatoum
  2023-02-02 12:31   ` Alexandre TORGUE
  1 sibling, 0 replies; 9+ messages in thread
From: Ahmad Fatoum @ 2023-01-19 12:06 UTC (permalink / raw)
  To: Patrick Delaunay, Alexandre TORGUE, Rob Herring,
	Krzysztof Kozlowski, Maxime Coquelin
  Cc: devicetree, linux-kernel, Etienne CARRIERE, linux-stm32,
	linux-arm-kernel

On 18.01.23 18:29, Patrick Delaunay wrote:
> Use the correct compatible for stm32mp13 support.
> 
> The BSEC driver for STM32MP15x is not compatible with STM32MP13x. For
> example the proprietary's smc STM32_SMC_BSEC is not supported in
> STM32MP13x OP-TEE, it is replaced by SM32MP BSEC Pseudo Trusted
> Application in OP-TEE to access to the secured IP BSEC on STM32MP13X SoC.
> 
> The correct compatible is already used in U-Boot and in upstream is in
> progress for OP-TEE device tree.
> 
> As the SoC STM32MP13X is not yet official and it is not available
> outside STMicroelectronics, it is the good time to break the DTS
> compatibility and to correct the error done in the introduction of
> STM32MP131.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
> This patch is already sent separately in:
> https://lore.kernel.org/all/20221017134437.1.I167a5efc1f8777cce14518c6fa38400ac684de3e@changeid/
> https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=685815
> 
> I create a serie for more efficient review.
> 
> Patrick.
> 
> (no changes since v1)
> 
> Changes in v1:
> - update commit message to indicate DTS break reason.
> 
>  arch/arm/boot/dts/stm32mp131.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi
> index accc3824f7e9..0b79380cc627 100644
> --- a/arch/arm/boot/dts/stm32mp131.dtsi
> +++ b/arch/arm/boot/dts/stm32mp131.dtsi
> @@ -520,7 +520,7 @@ rtc: rtc@5c004000 {
>  		};
>  
>  		bsec: efuse@5c005000 {
> -			compatible = "st,stm32mp15-bsec";
> +			compatible = "st,stm32mp13-bsec";
>  			reg = <0x5c005000 0x400>;
>  			#address-cells = <1>;
>  			#size-cells = <1>;

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


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

* Re: [PATCH v6 2/3] nvmem: stm32: add OP-TEE support for STM32MP13x
  2023-01-18 17:29 ` [PATCH v6 2/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
@ 2023-01-20 17:42   ` Srinivas Kandagatla
  0 siblings, 0 replies; 9+ messages in thread
From: Srinivas Kandagatla @ 2023-01-20 17:42 UTC (permalink / raw)
  To: Patrick Delaunay, Alexandre TORGUE, Maxime Coquelin
  Cc: Etienne CARRIERE, Fabrice GASNIER, Amelie DELAUNAY,
	Lionel DEBIEVE, linux-arm-kernel, linux-kernel, linux-stm32



On 18/01/2023 17:29, Patrick Delaunay wrote:
> For boot with OP-TEE on STM32MP13, the communication with the secure
> world no more use STMicroelectronics SMC but communication with the
> STM32MP BSEC TA, for data access (read/write) or lock operation:
> - all the request are sent to OP-TEE trusted application,
> - for upper OTP with ECC protection and with word programming only
>    each OTP are permanently locked when programmed to avoid ECC error
>    on the second write operation
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
> ---

Applied thanks,

--srini
> 
> Changes in v6:
> - Add reviewed by  Etienne Carierre review
> 
> Changes in v5:
> - minor changes after Etienne Carierre review (comments,
>    change %x to %#x, remove goto to out_tee_session)
> 
> Changes in v4:
> - fixe warning reported by kernel test robot for 64 bits support in
>    drivers/nvmem/stm32-bsec-optee-ta.c:260:18:
>    warning: format '%d' expects argument of type 'int',
>    but argument 4 has type 'size_t'
> 
> Changes in v3:
> - add a separate file stm32-bsec-optee-ta.c with STM32MP BSEC TA
>    communication functions to avoid #if in romem driver.
> 
> Changes in v2:
> - rebase series on linux-next/master
> - minor update after V1 revue
> - add missing sentinel in stm32_romem_of_match()
> - reorder function and remove prototypes for stm32_bsec_pta... functions
> - change stm32_bsec_pta_find to static
> - add return value in dev_err()
> - cleanups some comments, which can be on one line
> - remove test on priv->ctx in stm32_bsec_pta_remove
> - add missing tee_shm_free(shm) in stm32_bsec_pta_write() when
>    tee_shm_get_va failed
> - return error in stm32_bsec_pta_find when devm_add_action_or_reset failed
> - handle driver_register error in stm32_romem_init
> 
>   drivers/nvmem/Kconfig               |  11 +
>   drivers/nvmem/Makefile              |   1 +
>   drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
>   drivers/nvmem/stm32-bsec-optee-ta.h |  80 ++++++++
>   drivers/nvmem/stm32-romem.c         |  54 ++++-
>   5 files changed, 441 insertions(+), 3 deletions(-)
>   create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
>   create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h
> 
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 755f551426b5..4d262f69a073 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE
>   	  This driver can also be built as a module. If so, the module
>   	  will be called nvmem-sprd-efuse.
>   
> +config NVMEM_STM32_BSEC_OPTEE_TA
> +	bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
> +	depends on OPTEE
> +	help
> +	  Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
> +	  trusted application STM32MP BSEC.
> +
> +	  This library is a used by stm32-romem driver or included in the module
> +	  called nvmem-stm32-romem.
> +
>   config NVMEM_STM32_ROMEM
>   	tristate "STMicroelectronics STM32 factory-programmed memory support"
>   	depends on ARCH_STM32 || COMPILE_TEST
> +	imply NVMEM_STM32_BSEC_OPTEE_TA
>   	help
>   	  Say y here to enable read-only access for STMicroelectronics STM32
>   	  factory-programmed memory area.
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index fa80fe17e567..6a1efffa88f0 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE)		+= nvmem_sprd_efuse.o
>   nvmem_sprd_efuse-y			:= sprd-efuse.o
>   obj-$(CONFIG_NVMEM_STM32_ROMEM)		+= nvmem_stm32_romem.o
>   nvmem_stm32_romem-y 			:= stm32-romem.o
> +nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o
>   obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvmem_sunplus_ocotp.o
>   nvmem_sunplus_ocotp-y			:= sunplus-ocotp.o
>   obj-$(CONFIG_NVMEM_SUNXI_SID)		+= nvmem_sunxi_sid.o
> diff --git a/drivers/nvmem/stm32-bsec-optee-ta.c b/drivers/nvmem/stm32-bsec-optee-ta.c
> new file mode 100644
> index 000000000000..f89ce791dd12
> --- /dev/null
> +++ b/drivers/nvmem/stm32-bsec-optee-ta.c
> @@ -0,0 +1,298 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
> + *
> + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
> + */
> +
> +#include <linux/tee_drv.h>
> +
> +#include "stm32-bsec-optee-ta.h"
> +
> +/*
> + * Read OTP memory
> + *
> + * [in]		value[0].a		OTP start offset in byte
> + * [in]		value[0].b		Access type (0:shadow, 1:fuse, 2:lock)
> + * [out]	memref[1].buffer	Output buffer to store read values
> + * [out]	memref[1].size		Size of OTP to be read
> + *
> + * Return codes:
> + * TEE_SUCCESS - Invoke command success
> + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
> + * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
> + */
> +#define PTA_BSEC_READ_MEM		0x0
> +
> +/*
> + * Write OTP memory
> + *
> + * [in]		value[0].a		OTP start offset in byte
> + * [in]		value[0].b		Access type (0:shadow, 1:fuse, 2:lock)
> + * [in]		memref[1].buffer	Input buffer to read values
> + * [in]		memref[1].size		Size of OTP to be written
> + *
> + * Return codes:
> + * TEE_SUCCESS - Invoke command success
> + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
> + * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
> + */
> +#define PTA_BSEC_WRITE_MEM		0x1
> +
> +/* value of PTA_BSEC access type = value[in] b */
> +#define SHADOW_ACCESS	0
> +#define FUSE_ACCESS	1
> +#define LOCK_ACCESS	2
> +
> +/* Bitfield definition for LOCK status */
> +#define LOCK_PERM			BIT(30)
> +
> +/* OP-TEE STM32MP BSEC TA UUID */
> +static const uuid_t stm32mp_bsec_ta_uuid =
> +	UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5,
> +		  0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03);
> +
> +/*
> + * Check whether this driver supports the BSEC TA in the TEE instance
> + * represented by the params (ver/data) to this function.
> + */
> +static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver,
> +				     const void *data)
> +{
> +	/* Currently this driver only supports GP compliant, OP-TEE based TA */
> +	if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
> +		(ver->gen_caps & TEE_GEN_CAP_GP))
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +/* Open a session to OP-TEE for STM32MP BSEC TA */
> +static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id)
> +{
> +	struct tee_ioctl_open_session_arg sess_arg;
> +	int rc;
> +
> +	memset(&sess_arg, 0, sizeof(sess_arg));
> +	export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid);
> +	sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
> +	sess_arg.num_params = 0;
> +
> +	rc = tee_client_open_session(ctx, &sess_arg, NULL);
> +	if ((rc < 0) || (sess_arg.ret != 0)) {
> +		pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n",
> +		       __func__, sess_arg.ret, rc);
> +		if (!rc)
> +			rc = -EINVAL;
> +	} else {
> +		*id = sess_arg.session;
> +	}
> +
> +	return rc;
> +}
> +
> +/* close a session to OP-TEE for STM32MP BSEC TA */
> +static void stm32_bsec_ta_close_session(void *ctx, u32 id)
> +{
> +	tee_client_close_session(ctx, id);
> +}
> +
> +/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */
> +int stm32_bsec_optee_ta_open(struct tee_context **ctx)
> +{
> +	struct tee_context *tee_ctx;
> +	u32 session_id;
> +	int rc;
> +
> +	/* Open context with TEE driver */
> +	tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL);
> +	if (IS_ERR(tee_ctx)) {
> +		rc = PTR_ERR(tee_ctx);
> +		if (rc == -ENOENT)
> +			return -EPROBE_DEFER;
> +		pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc);
> +
> +		return rc;
> +	}
> +
> +	/* Check STM32MP BSEC TA presence */
> +	rc = stm32_bsec_ta_open_session(tee_ctx, &session_id);
> +	if (rc) {
> +		tee_client_close_context(tee_ctx);
> +		return rc;
> +	}
> +
> +	stm32_bsec_ta_close_session(tee_ctx, session_id);
> +
> +	*ctx = tee_ctx;
> +
> +	return 0;
> +}
> +
> +/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */
> +void stm32_bsec_optee_ta_close(void *ctx)
> +{
> +	tee_client_close_context(ctx);
> +}
> +
> +/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
> +int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
> +			     void *buf, size_t bytes)
> +{
> +	struct tee_shm *shm;
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[2];
> +	u8 *shm_buf;
> +	u32 start, num_bytes;
> +	int ret;
> +	u32 session_id;
> +
> +	ret = stm32_bsec_ta_open_session(ctx, &session_id);
> +	if (ret)
> +		return ret;
> +
> +	memset(&arg, 0, sizeof(arg));
> +	memset(&param, 0, sizeof(param));
> +
> +	arg.func = PTA_BSEC_READ_MEM;
> +	arg.session = session_id;
> +	arg.num_params = 2;
> +
> +	/* align access on 32bits */
> +	start = ALIGN_DOWN(offset, 4);
> +	num_bytes = round_up(offset + bytes - start, 4);
> +	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> +	param[0].u.value.a = start;
> +	param[0].u.value.b = SHADOW_ACCESS;
> +
> +	shm = tee_shm_alloc_kernel_buf(ctx, num_bytes);
> +	if (IS_ERR(shm)) {
> +		ret = PTR_ERR(shm);
> +		goto out_tee_session;
> +	}
> +
> +	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
> +	param[1].u.memref.shm = shm;
> +	param[1].u.memref.size = num_bytes;
> +
> +	ret = tee_client_invoke_func(ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n",
> +			arg.ret, ret);
> +		if (!ret)
> +			ret = -EIO;
> +	}
> +	if (!ret) {
> +		shm_buf = tee_shm_get_va(shm, 0);
> +		if (IS_ERR(shm_buf)) {
> +			ret = PTR_ERR(shm_buf);
> +			pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
> +		} else {
> +			/* read data from 32 bits aligned buffer */
> +			memcpy(buf, &shm_buf[offset % 4], bytes);
> +		}
> +	}
> +
> +	tee_shm_free(shm);
> +
> +out_tee_session:
> +	stm32_bsec_ta_close_session(ctx, session_id);
> +
> +	return ret;
> +}
> +
> +/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
> +int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
> +			      unsigned int offset, void *buf, size_t bytes)
> +{	struct tee_shm *shm;
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[2];
> +	u8 *shm_buf;
> +	int ret;
> +	u32 session_id;
> +
> +	ret = stm32_bsec_ta_open_session(ctx, &session_id);
> +	if (ret)
> +		return ret;
> +
> +	/* Allow only writing complete 32-bits aligned words */
> +	if ((bytes % 4) || (offset % 4))
> +		return -EINVAL;
> +
> +	memset(&arg, 0, sizeof(arg));
> +	memset(&param, 0, sizeof(param));
> +
> +	arg.func = PTA_BSEC_WRITE_MEM;
> +	arg.session = session_id;
> +	arg.num_params = 2;
> +
> +	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> +	param[0].u.value.a = offset;
> +	param[0].u.value.b = FUSE_ACCESS;
> +
> +	shm = tee_shm_alloc_kernel_buf(ctx, bytes);
> +	if (IS_ERR(shm)) {
> +		ret = PTR_ERR(shm);
> +		goto out_tee_session;
> +	}
> +
> +	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> +	param[1].u.memref.shm = shm;
> +	param[1].u.memref.size = bytes;
> +
> +	shm_buf = tee_shm_get_va(shm, 0);
> +	if (IS_ERR(shm_buf)) {
> +		ret = PTR_ERR(shm_buf);
> +		pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
> +		tee_shm_free(shm);
> +
> +		goto out_tee_session;
> +	}
> +
> +	memcpy(shm_buf, buf, bytes);
> +
> +	ret = tee_client_invoke_func(ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
> +		if (!ret)
> +			ret = -EIO;
> +	}
> +	pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret);
> +
> +	/* Lock the upper OTPs with ECC protection, word programming only */
> +	if (!ret && ((offset + bytes) >= (lower * 4))) {
> +		u32 start, nb_lock;
> +		u32 *lock = (u32 *)shm_buf;
> +		int i;
> +
> +		/*
> +		 * don't lock the lower OTPs, no ECC protection and incremental
> +		 * bit programming, a second write is allowed
> +		 */
> +		start = max_t(u32, offset, lower * 4);
> +		nb_lock = (offset + bytes - start) / 4;
> +
> +		param[0].u.value.a = start;
> +		param[0].u.value.b = LOCK_ACCESS;
> +		param[1].u.memref.size = nb_lock * 4;
> +
> +		for (i = 0; i < nb_lock; i++)
> +			lock[i] = LOCK_PERM;
> +
> +		ret = tee_client_invoke_func(ctx, &arg, param);
> +		if (ret < 0 || arg.ret != 0) {
> +			pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
> +			if (!ret)
> +				ret = -EIO;
> +		}
> +		pr_debug("Lock upper OTPs %d to %d, ret=%d\n",
> +			 start / 4, start / 4 + nb_lock, ret);
> +	}
> +
> +	tee_shm_free(shm);
> +
> +out_tee_session:
> +	stm32_bsec_ta_close_session(ctx, session_id);
> +
> +	return ret;
> +}
> diff --git a/drivers/nvmem/stm32-bsec-optee-ta.h b/drivers/nvmem/stm32-bsec-optee-ta.h
> new file mode 100644
> index 000000000000..3966a0535179
> --- /dev/null
> +++ b/drivers/nvmem/stm32-bsec-optee-ta.h
> @@ -0,0 +1,80 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
> + *
> + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
> + */
> +
> +#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA)
> +/**
> + * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA
> + * @ctx: the OP-TEE context on success
> + *
> + * Return:
> + *	On success, 0. On failure, -errno.
> + */
> +int stm32_bsec_optee_ta_open(struct tee_context **ctx);
> +
> +/**
> + * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA
> + * @ctx: the OP-TEE context
> + *
> + * This function used to clean the OP-TEE resources initialized in
> + * stm32_bsec_optee_ta_open(); it can be used as callback to
> + * devm_add_action_or_reset()
> + */
> +void stm32_bsec_optee_ta_close(void *ctx);
> +
> +/**
> + * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver
> + * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
> + * @offset: nvmem offset
> + * @buf: buffer to fill with nvem values
> + * @bytes: number of bytes to read
> + *
> + * Return:
> + *	On success, 0. On failure, -errno.
> + */
> +int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
> +			     void *buf, size_t bytes);
> +
> +/**
> + * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver
> + * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
> + * @lower: number of lower OTP, not protected by ECC
> + * @offset: nvmem offset
> + * @buf: buffer with nvem values
> + * @bytes: number of bytes to write
> + *
> + * Return:
> + *	On success, 0. On failure, -errno.
> + */
> +int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
> +			      unsigned int offset, void *buf, size_t bytes);
> +
> +#else
> +
> +static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline void stm32_bsec_optee_ta_close(void *ctx)
> +{
> +}
> +
> +static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
> +					   unsigned int offset, void *buf,
> +					   size_t bytes)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
> +					    unsigned int lower,
> +					    unsigned int offset, void *buf,
> +					    size_t bytes)
> +{
> +	return -EOPNOTSUPP;
> +}
> +#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */
> diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
> index d1d03c2ad081..978a63edf297 100644
> --- a/drivers/nvmem/stm32-romem.c
> +++ b/drivers/nvmem/stm32-romem.c
> @@ -11,6 +11,9 @@
>   #include <linux/module.h>
>   #include <linux/nvmem-provider.h>
>   #include <linux/of_device.h>
> +#include <linux/tee_drv.h>
> +
> +#include "stm32-bsec-optee-ta.h"
>   
>   /* BSEC secure service access from non-secure */
>   #define STM32_SMC_BSEC			0x82001003
> @@ -25,12 +28,14 @@
>   struct stm32_romem_cfg {
>   	int size;
>   	u8 lower;
> +	bool ta;
>   };
>   
>   struct stm32_romem_priv {
>   	void __iomem *base;
>   	struct nvmem_config cfg;
>   	u8 lower;
> +	struct tee_context *ctx;
>   };
>   
>   static int stm32_romem_read(void *context, unsigned int offset, void *buf,
> @@ -138,12 +143,29 @@ static int stm32_bsec_write(void *context, unsigned int offset, void *buf,
>   	return 0;
>   }
>   
> +static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
> +			       size_t bytes)
> +{
> +	struct stm32_romem_priv *priv = context;
> +
> +	return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
> +}
> +
> +static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
> +				size_t bytes)
> +{
> +	struct stm32_romem_priv *priv = context;
> +
> +	return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
> +}
> +
>   static int stm32_romem_probe(struct platform_device *pdev)
>   {
>   	const struct stm32_romem_cfg *cfg;
>   	struct device *dev = &pdev->dev;
>   	struct stm32_romem_priv *priv;
>   	struct resource *res;
> +	int rc;
>   
>   	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>   	if (!priv)
> @@ -173,15 +195,31 @@ static int stm32_romem_probe(struct platform_device *pdev)
>   	} else {
>   		priv->cfg.size = cfg->size;
>   		priv->lower = cfg->lower;
> -		priv->cfg.reg_read = stm32_bsec_read;
> -		priv->cfg.reg_write = stm32_bsec_write;
> +		if (cfg->ta) {
> +			rc = stm32_bsec_optee_ta_open(&priv->ctx);
> +			/* wait for OP-TEE client driver to be up and ready */
> +			if (rc)
> +				return rc;
> +		}
> +		if (priv->ctx) {
> +			rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
> +			if (rc) {
> +				dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc);
> +				return rc;
> +			}
> +			priv->cfg.reg_read = stm32_bsec_pta_read;
> +			priv->cfg.reg_write = stm32_bsec_pta_write;
> +		} else {
> +			priv->cfg.reg_read = stm32_bsec_read;
> +			priv->cfg.reg_write = stm32_bsec_write;
> +		}
>   	}
>   
>   	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
>   }
>   
>   /*
> - * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
> + * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
>    * => 96 x 32-bits data words
>    * - Lower: 1K bits, 2:1 redundancy, incremental bit programming
>    *   => 32 (x 32-bits) lower shadow registers = words 0 to 31
> @@ -191,6 +229,13 @@ static int stm32_romem_probe(struct platform_device *pdev)
>   static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
>   	.size = 384,
>   	.lower = 32,
> +	.ta = false,
> +};
> +
> +static const struct stm32_romem_cfg stm32mp13_bsec_cfg = {
> +	.size = 384,
> +	.lower = 32,
> +	.ta = true,
>   };
>   
>   static const struct of_device_id stm32_romem_of_match[] = {
> @@ -198,7 +243,10 @@ static const struct of_device_id stm32_romem_of_match[] = {
>   		.compatible = "st,stm32mp15-bsec",
>   		.data = (void *)&stm32mp15_bsec_cfg,
>   	}, {
> +		.compatible = "st,stm32mp13-bsec",
> +		.data = (void *)&stm32mp13_bsec_cfg,
>   	},
> +	{ /* sentinel */ },
>   };
>   MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
>   

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

* Re: [PATCH v6 3/3] nvmem: stm32: detect bsec pta presence for STM32MP15x
  2023-01-18 17:29 ` [PATCH v6 3/3] nvmem: stm32: detect bsec pta presence for STM32MP15x Patrick Delaunay
@ 2023-01-20 17:42   ` Srinivas Kandagatla
  0 siblings, 0 replies; 9+ messages in thread
From: Srinivas Kandagatla @ 2023-01-20 17:42 UTC (permalink / raw)
  To: Patrick Delaunay, Alexandre TORGUE, Maxime Coquelin
  Cc: Etienne CARRIERE, Fabrice GASNIER, Amelie DELAUNAY,
	Lionel DEBIEVE, linux-arm-kernel, linux-kernel, linux-stm32



On 18/01/2023 17:29, Patrick Delaunay wrote:
> On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used;
> the PTA BSEC should be used as it is done on STM32MP13x platform,
> but the BSEC SMC can be also used: it is a legacy mode in OP-TEE,
> not recommended but used in previous OP-TEE firmware.
> 
> The presence of OP-TEE is dynamically detected in STM32MP15x device tree
> and the supported NVMEM backend is dynamically detected:
> - PTA with stm32_bsec_pta_find
> - SMC with stm32_bsec_check
> 
> With OP-TEE but without PTA and SMC detection, the probe is deferred for
> STM32MP15x devices.
> 
> On STM32MP13x platform, only the PTA is supported with cfg->ta = true
> and this detection is skipped.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
> ---


Applied thanks,

--srini

> 
> Changes in v6:
> - added reviewed by Etienne Carriere
> 
> Changes in v5:
> - update the BSEC SMC detection logic in stm32_romem_probe()
>    after Etienne Carierre review to support NVMEM probe after OP-TEE probe
> 
> Changes in v3:
> - use of_find_compatible_node in optee_presence_check function
>    instead of of_find_node_by_path("/firmware/optee")
> 
> Changes in v2:
> - Added patch in the serie for BSEC PTA support on STM32MP15x
>    with dynamic detection of OP-TEE presence and SMC support (legacy mode)
> 
>   drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++----
>   1 file changed, 34 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
> index 978a63edf297..ba779e26937a 100644
> --- a/drivers/nvmem/stm32-romem.c
> +++ b/drivers/nvmem/stm32-romem.c
> @@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
>   	return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
>   }
>   
> +static bool stm32_bsec_smc_check(void)
> +{
> +	u32 val;
> +	int ret;
> +
> +	/* check that the OP-TEE support the BSEC SMC (legacy mode) */
> +	ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val);
> +
> +	return !ret;
> +}
> +
> +static bool optee_presence_check(void)
> +{
> +	struct device_node *np;
> +	bool tee_detected = false;
> +
> +	/* check that the OP-TEE node is present and available. */
> +	np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz");
> +	if (np && of_device_is_available(np))
> +		tee_detected = true;
> +	of_node_put(np);
> +
> +	return tee_detected;
> +}
> +
>   static int stm32_romem_probe(struct platform_device *pdev)
>   {
>   	const struct stm32_romem_cfg *cfg;
> @@ -195,11 +220,16 @@ static int stm32_romem_probe(struct platform_device *pdev)
>   	} else {
>   		priv->cfg.size = cfg->size;
>   		priv->lower = cfg->lower;
> -		if (cfg->ta) {
> +		if (cfg->ta || optee_presence_check()) {
>   			rc = stm32_bsec_optee_ta_open(&priv->ctx);
> -			/* wait for OP-TEE client driver to be up and ready */
> -			if (rc)
> -				return rc;
> +			if (rc) {
> +				/* wait for OP-TEE client driver to be up and ready */
> +				if (rc == -EPROBE_DEFER)
> +					return -EPROBE_DEFER;
> +				/* BSEC PTA is required or SMC not supported */
> +				if (cfg->ta || !stm32_bsec_smc_check())
> +					return rc;
> +			}
>   		}
>   		if (priv->ctx) {
>   			rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);

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

* Re: [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x
  2023-01-18 17:29 [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
                   ` (2 preceding siblings ...)
  2023-01-18 17:29 ` [PATCH v6 3/3] nvmem: stm32: detect bsec pta presence for STM32MP15x Patrick Delaunay
@ 2023-01-26 21:02 ` Arnd Bergmann
  3 siblings, 0 replies; 9+ messages in thread
From: Arnd Bergmann @ 2023-01-26 21:02 UTC (permalink / raw)
  To: Patrick Delaunay, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Maxime Coquelin, Srinivas Kandagatla
  Cc: Etienne CARRIERE, Fabrice GASNIER, Amelie DELAUNAY,
	Lionel DEBIEVE, devicetree, linux-arm-kernel, linux-kernel,
	linux-stm32

On Wed, Jan 18, 2023, at 18:29, Patrick Delaunay wrote:
> 
> +config NVMEM_STM32_BSEC_OPTEE_TA
> +	bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
> +	depends on OPTEE
> +	help
> +	  Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
> +	  trusted application STM32MP BSEC.
> +
> +	  This library is a used by stm32-romem driver or included in the 
> module
> +	  called nvmem-stm32-romem.
> +
>  config NVMEM_STM32_ROMEM
>  	tristate "STMicroelectronics STM32 factory-programmed memory support"
>  	depends on ARCH_STM32 || COMPILE_TEST
> +	imply NVMEM_STM32_BSEC_OPTEE_TA
>  	help
>  	  Say y here to enable read-only access for STMicroelectronics STM32
>  	  factory-programmed memory area.

This is now causing a link failure with CONFIG_OPTEE=m if
NVMEM_STM32_ROMEM is built-in. My guess is that you saw something
like that earlier and someone recommended using the 'imply' keyword
without understanding what it does (no worries, nobody understands it).

I've prepared a patch now based on the most likely interpretation
of what you actually meant here:

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index ed8ef7460be2..ae2c5257ed97 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -295,8 +295,7 @@ config NVMEM_SPRD_EFUSE
          will be called nvmem-sprd-efuse.
 
 config NVMEM_STM32_BSEC_OPTEE_TA
-       bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
-       depends on OPTEE
+       def_bool NVMEM_STM32_ROMEM && OPTEE
        help
          Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
          trusted application STM32MP BSEC.
@@ -307,7 +306,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA
 config NVMEM_STM32_ROMEM
        tristate "STMicroelectronics STM32 factory-programmed memory support"
        depends on ARCH_STM32 || COMPILE_TEST
-       imply NVMEM_STM32_BSEC_OPTEE_TA
+       depends on OPTEE || !OPTEE
        help
          Say y here to enable read-only access for STMicroelectronics STM32
          factory-programmed memory area.

This enables NVMEM_STM32_BSEC_OPTEE_TA whenever OPTEE is
available, but prevents the link error by forcing NVMEM_STM32_ROMEM
to also be a loadable module if that is how OPTEE is built.

I'll send that if it passes the randconfig builds over night.

      Arnd

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

* Re: [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC
  2023-01-18 17:29 ` [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC Patrick Delaunay
  2023-01-19 12:06   ` [Linux-stm32] " Ahmad Fatoum
@ 2023-02-02 12:31   ` Alexandre TORGUE
  1 sibling, 0 replies; 9+ messages in thread
From: Alexandre TORGUE @ 2023-02-02 12:31 UTC (permalink / raw)
  To: Patrick Delaunay, Rob Herring, Krzysztof Kozlowski, Maxime Coquelin
  Cc: Etienne CARRIERE, Fabrice GASNIER, Amelie DELAUNAY,
	Lionel DEBIEVE, devicetree, linux-arm-kernel, linux-kernel,
	linux-stm32

On 1/18/23 18:29, Patrick Delaunay wrote:
> Use the correct compatible for stm32mp13 support.
> 
> The BSEC driver for STM32MP15x is not compatible with STM32MP13x. For
> example the proprietary's smc STM32_SMC_BSEC is not supported in
> STM32MP13x OP-TEE, it is replaced by SM32MP BSEC Pseudo Trusted
> Application in OP-TEE to access to the secured IP BSEC on STM32MP13X SoC.
> 
> The correct compatible is already used in U-Boot and in upstream is in
> progress for OP-TEE device tree.
> 
> As the SoC STM32MP13X is not yet official and it is not available
> outside STMicroelectronics, it is the good time to break the DTS
> compatibility and to correct the error done in the introduction of
> STM32MP131.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
> This patch is already sent separately in:
> https://lore.kernel.org/all/20221017134437.1.I167a5efc1f8777cce14518c6fa38400ac684de3e@changeid/
> https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=685815
> 
> I create a serie for more efficient review.
> 
> Patrick.
> 
> (no changes since v1)
> 
> Changes in v1:
> - update commit message to indicate DTS break reason.
> 
>   arch/arm/boot/dts/stm32mp131.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi
> index accc3824f7e9..0b79380cc627 100644
> --- a/arch/arm/boot/dts/stm32mp131.dtsi
> +++ b/arch/arm/boot/dts/stm32mp131.dtsi
> @@ -520,7 +520,7 @@ rtc: rtc@5c004000 {
>   		};
>   
>   		bsec: efuse@5c005000 {
> -			compatible = "st,stm32mp15-bsec";
> +			compatible = "st,stm32mp13-bsec";
>   			reg = <0x5c005000 0x400>;
>   			#address-cells = <1>;
>   			#size-cells = <1>;

Applied on stm32-next.

Thanks.
Alex

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

end of thread, other threads:[~2023-02-02 12:31 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-18 17:29 [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
2023-01-18 17:29 ` [PATCH v6 1/3] ARM: dts: stm32mp13: fix compatible for BSEC Patrick Delaunay
2023-01-19 12:06   ` [Linux-stm32] " Ahmad Fatoum
2023-02-02 12:31   ` Alexandre TORGUE
2023-01-18 17:29 ` [PATCH v6 2/3] nvmem: stm32: add OP-TEE support for STM32MP13x Patrick Delaunay
2023-01-20 17:42   ` Srinivas Kandagatla
2023-01-18 17:29 ` [PATCH v6 3/3] nvmem: stm32: detect bsec pta presence for STM32MP15x Patrick Delaunay
2023-01-20 17:42   ` Srinivas Kandagatla
2023-01-26 21:02 ` [PATCH v6 0/3] nvmem: stm32: add OP-TEE support for STM32MP13x Arnd Bergmann

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).