feat(stm32mp1): new way to access platform OTP

Use dt_find_otp_name() to retrieve platform OTP information
from device tree, directly or through stm32_get_otp_index() and
stm32_get_otp_value() platform services.
String definitions replace hard-coded values, they are used to call
this new function.

Change-Id: I81213e4a9ad08fddadc2c97b064ae057a4c79561
Signed-off-by: Nicolas Le Bayon <nicolas.le.bayon@st.com>
Signed-off-by: Yann Gautier <yann.gautier@st.com>
diff --git a/plat/st/stm32mp1/stm32mp1_boot_device.c b/plat/st/stm32mp1/stm32mp1_boot_device.c
index 6a05707..714ab80 100644
--- a/plat/st/stm32mp1/stm32mp1_boot_device.c
+++ b/plat/st/stm32mp1/stm32mp1_boot_device.c
@@ -20,13 +20,11 @@
 #if STM32MP_RAW_NAND || STM32MP_SPI_NAND
 static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc)
 {
-	int result;
 	uint32_t nand_param;
 
 	/* Check if NAND parameters are stored in OTP */
-	result = bsec_shadow_read_otp(&nand_param, NAND_OTP);
-	if (result != BSEC_OK) {
-		ERROR("BSEC: NAND_OTP Error %i\n", result);
+	if (stm32_get_otp_value(NAND_OTP, &nand_param) != 0) {
+		ERROR("BSEC: NAND_OTP Error\n");
 		return -EACCES;
 	}
 
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 5d41898..fb3e134 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -347,19 +347,18 @@
 
 #define OTP_MAX_SIZE			(STM32MP1_OTP_MAX_ID + 1U)
 
-/* OTP offsets */
-#define DATA0_OTP			U(0)
-#define PART_NUMBER_OTP			U(1)
-#define NAND_OTP			U(9)
-#define UID0_OTP			U(13)
-#define UID1_OTP			U(14)
-#define UID2_OTP			U(15)
-#define PACKAGE_OTP			U(16)
-#define HW2_OTP				U(18)
+/* OTP labels */
+#define CFG0_OTP			"cfg0_otp"
+#define PART_NUMBER_OTP			"part_number_otp"
+#define PACKAGE_OTP			"package_otp"
+#define HW2_OTP				"hw2_otp"
+#define NAND_OTP			"nand_otp"
+#define UID_OTP				"uid_otp"
+#define BOARD_ID_OTP			"board_id"
 
 /* OTP mask */
-/* DATA0 */
-#define DATA0_OTP_SECURED		BIT(6)
+/* CFG0 */
+#define CFG0_CLOSED_DEVICE		BIT(6)
 
 /* PART NUMBER */
 #define PART_NUMBER_OTP_PART_MASK	GENMASK_32(7, 0)
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index ceb7024..075d1d7 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -278,7 +278,7 @@
 		return part_number;
 	}
 
-	if (bsec_shadow_read_otp(&part_number, PART_NUMBER_OTP) != BSEC_OK) {
+	if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
 		panic();
 	}
 
@@ -294,7 +294,7 @@
 {
 	uint32_t package;
 
-	if (bsec_shadow_read_otp(&package, PACKAGE_OTP) != BSEC_OK) {
+	if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
 		panic();
 	}
 
@@ -397,38 +397,12 @@
 
 void stm32mp_print_boardinfo(void)
 {
-	uint32_t board_id;
-	uint32_t board_otp;
-	int bsec_node, bsec_board_id_node;
-	void *fdt;
-	const fdt32_t *cuint;
+	uint32_t board_id = 0;
 
-	if (fdt_get_address(&fdt) == 0) {
-		panic();
-	}
-
-	bsec_node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT);
-	if (bsec_node < 0) {
-		return;
-	}
-
-	bsec_board_id_node = fdt_subnode_offset(fdt, bsec_node, "board_id");
-	if (bsec_board_id_node <= 0) {
+	if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
 		return;
 	}
 
-	cuint = fdt_getprop(fdt, bsec_board_id_node, "reg", NULL);
-	if (cuint == NULL) {
-		panic();
-	}
-
-	board_otp = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
-
-	if (bsec_shadow_read_otp(&board_id, board_otp) != BSEC_OK) {
-		ERROR("BSEC: PART_NUMBER_OTP Error\n");
-		return;
-	}
-
 	if (board_id != 0U) {
 		char rev[2];
 
@@ -462,12 +436,11 @@
 {
 	uint32_t value;
 
-	if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
-	    (bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
+	if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
 		return true;
 	}
 
-	return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
+	return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
 }
 
 uint32_t stm32_iwdg_get_instance(uintptr_t base)
@@ -487,13 +460,7 @@
 	uint32_t iwdg_cfg = 0U;
 	uint32_t otp_value;
 
-#if defined(IMAGE_BL2)
-	if (bsec_shadow_register(HW2_OTP) != BSEC_OK) {
-		panic();
-	}
-#endif
-
-	if (bsec_read_otp(&otp_value, HW2_OTP) != BSEC_OK) {
+	if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
 		panic();
 	}
 
@@ -515,29 +482,34 @@
 #if defined(IMAGE_BL2)
 uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
 {
+	uint32_t otp_value;
 	uint32_t otp;
 	uint32_t result;
 
+	if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
+		panic();
+	}
+
-	if (bsec_shadow_read_otp(&otp, HW2_OTP) != BSEC_OK) {
+	if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
 		panic();
 	}
 
-	if ((flags & IWDG_DISABLE_ON_STOP) != 0U) {
-		otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
+	if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
+		otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
 	}
 
-	if ((flags & IWDG_DISABLE_ON_STANDBY) != 0U) {
-		otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
+	if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
+		otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
 	}
 
-	result = bsec_write_otp(otp, HW2_OTP);
+	result = bsec_write_otp(otp_value, otp);
 	if (result != BSEC_OK) {
 		return result;
 	}
 
 	/* Sticky lock OTP_IWDG (read and write) */
-	if ((bsec_set_sr_lock(HW2_OTP) != BSEC_OK) ||
-	    (bsec_set_sw_lock(HW2_OTP) != BSEC_OK)) {
+	if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
+	    (bsec_set_sw_lock(otp) != BSEC_OK)) {
 		return BSEC_LOCK_FAIL;
 	}
 
diff --git a/plat/st/stm32mp1/stm32mp1_syscfg.c b/plat/st/stm32mp1/stm32mp1_syscfg.c
index 01a6439..3f34af1 100644
--- a/plat/st/stm32mp1/stm32mp1_syscfg.c
+++ b/plat/st/stm32mp1/stm32mp1_syscfg.c
@@ -7,11 +7,11 @@
 #include <common/debug.h>
 #include <drivers/clk.h>
 #include <drivers/delay_timer.h>
-#include <drivers/st/bsec.h>
 #include <drivers/st/stpmic1.h>
 #include <lib/mmio.h>
 
 #include <platform_def.h>
+#include <stm32mp_common.h>
 #include <stm32mp_dt.h>
 #include <stm32mp1_private.h>
 
@@ -116,8 +116,9 @@
 
 static void stm32mp1_syscfg_set_hslv(void)
 {
-	uint32_t otp = 0;
+	uint32_t otp_value;
 	uint32_t vdd_voltage;
+	bool product_below_2v5;
 
 	/*
 	 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
@@ -134,26 +135,26 @@
 	 *   => TF-A enables the low power mode only if VDD < 2.7V (in DT)
 	 *      but this value needs to be consistent with board design.
 	 */
-	if (bsec_read_otp(&otp, HW2_OTP) != BSEC_OK) {
+	if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
 		panic();
 	}
 
-	otp = otp & HW2_OTP_PRODUCT_BELOW_2V5;
+	product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U;
 
 	/* Get VDD supply */
 	vdd_voltage = dt_get_pwr_vdd_voltage();
 
 	/* Check if VDD is Low Voltage */
 	if (vdd_voltage == 0U) {
-		WARN("VDD unknown");
+		WARN("VDD unknown\n");
 	} else if (vdd_voltage < 2700000U) {
 		enable_high_speed_mode_low_voltage();
 
-		if (otp == 0U) {
+		if (!product_below_2v5) {
 			INFO("Product_below_2v5=0: HSLVEN protected by HW\n");
 		}
 	} else {
-		if (otp != 0U) {
+		if (product_below_2v5) {
 			ERROR("Product_below_2v5=1:\n");
 			ERROR("\tHSLVEN update is destructive,\n");
 			ERROR("\tno update as VDD > 2.7V\n");
diff --git a/plat/st/stm32mp1/stm32mp1_usb_dfu.c b/plat/st/stm32mp1/stm32mp1_usb_dfu.c
index 70fbba6..33b12d0 100644
--- a/plat/st/stm32mp1/stm32mp1_usb_dfu.c
+++ b/plat/st/stm32mp1/stm32mp1_usb_dfu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -157,27 +157,28 @@
 static void update_serial_num_string(void)
 {
 	uint8_t i;
-	uint32_t result;
 	char serial_string[SIZ_STRING_SERIAL + 2U];
-	uint32_t deviceserial[UID_WORD_NB];
+	/* serial number is set to 0 */
+	uint32_t deviceserial[UID_WORD_NB] = {0U, 0U, 0U};
+	uint32_t otp;
+	uint32_t len;
 	uint16_t length;
 
-	for (i = 0U; i < UID_WORD_NB; i++) {
-		result = bsec_shadow_register(i + UID0_OTP);
-		if (result != BSEC_OK) {
-			ERROR("BSEC: UID%d Shadowing Error\n", i);
-			break;
-		}
-		result = bsec_read_otp(&deviceserial[i], i + UID0_OTP);
-		if (result != BSEC_OK) {
-			ERROR("BSEC: UID%d Read Error\n", i);
-			break;
-		}
+	if (stm32_get_otp_index(UID_OTP, &otp, &len) != 0) {
+		ERROR("BSEC: Get UID_OTP number Error\n");
+		return;
 	}
-	/* On bsec error: serial number is set to 0 */
-	if (result != BSEC_OK) {
-		for (i = 0; i < UID_WORD_NB; i++) {
-			deviceserial[i] = 0U;
+
+	if ((len / __WORD_BIT) != UID_WORD_NB) {
+		ERROR("BSEC: Get UID_OTP length Error\n");
+		return;
+	}
+
+	for (i = 0; i < UID_WORD_NB; i++) {
+		if (bsec_shadow_read_otp(&deviceserial[i], i + otp) !=
+		    BSEC_OK) {
+			ERROR("BSEC: UID%d Error\n", i);
+			return;
 		}
 	}
 	/* build serial number with OTP value as in ROM code */