diff --git a/drivers/st/bsec/bsec.c b/drivers/st/bsec/bsec.c
new file mode 100644
index 0000000..aaecf1f
--- /dev/null
+++ b/drivers/st/bsec/bsec.c
@@ -0,0 +1,913 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+
+#define BSEC_IP_VERSION_1_0	0x10
+#define BSEC_COMPAT		"st,stm32mp15-bsec"
+
+#define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
+
+static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused;
+
+static uint32_t bsec_power_safmem(bool power);
+
+/* BSEC access protection */
+static spinlock_t bsec_spinlock;
+static uintptr_t bsec_base;
+
+static void bsec_lock(void)
+{
+	const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
+
+	/* Lock is currently required only when MMU and cache are enabled */
+	if ((read_sctlr() & mask) == mask) {
+		spin_lock(&bsec_spinlock);
+	}
+}
+
+static void bsec_unlock(void)
+{
+	const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
+
+	/* Unlock is required only when MMU and cache are enabled */
+	if ((read_sctlr() & mask) == mask) {
+		spin_unlock(&bsec_spinlock);
+	}
+}
+
+static int bsec_get_dt_node(struct dt_node_info *info)
+{
+	int node;
+
+	node = dt_get_node(info, -1, BSEC_COMPAT);
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return node;
+}
+
+#if defined(IMAGE_BL32)
+static void enable_non_secure_access(uint32_t otp)
+{
+	otp_nsec_access[otp / __WORD_BIT] |= BIT(otp % __WORD_BIT);
+
+	if (bsec_shadow_register(otp) != BSEC_OK) {
+		panic();
+	}
+}
+
+static bool non_secure_can_access(uint32_t otp)
+{
+	return (otp_nsec_access[otp / __WORD_BIT] &
+		BIT(otp % __WORD_BIT)) != 0;
+}
+
+static int bsec_dt_otp_nsec_access(void *fdt, int bsec_node)
+{
+	int bsec_subnode;
+
+	fdt_for_each_subnode(bsec_subnode, fdt, bsec_node) {
+		const fdt32_t *cuint;
+		uint32_t reg;
+		uint32_t i;
+		uint32_t size;
+		uint8_t status;
+
+		cuint = fdt_getprop(fdt, bsec_subnode, "reg", NULL);
+		if (cuint == NULL) {
+			panic();
+		}
+
+		reg = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
+		if (reg < STM32MP1_UPPER_OTP_START) {
+			continue;
+		}
+
+		status = fdt_get_status(bsec_subnode);
+		if ((status & DT_NON_SECURE) == 0U)  {
+			continue;
+		}
+
+		size = fdt32_to_cpu(*(cuint + 1)) / sizeof(uint32_t);
+
+		if ((fdt32_to_cpu(*(cuint + 1)) % sizeof(uint32_t)) != 0) {
+			size++;
+		}
+
+		for (i = reg; i < (reg + size); i++) {
+			enable_non_secure_access(i);
+		}
+	}
+
+	return 0;
+}
+#endif
+
+static uint32_t otp_bank_offset(uint32_t otp)
+{
+	assert(otp <= STM32MP1_OTP_MAX_ID);
+
+	return ((otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT) *
+	       sizeof(uint32_t);
+}
+
+static uint32_t bsec_check_error(uint32_t otp)
+{
+	uint32_t bit = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank = otp_bank_offset(otp);
+
+	if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
+		return BSEC_DISTURBED;
+	}
+
+	if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) {
+		return BSEC_ERROR;
+	}
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_probe: initialize BSEC driver.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_probe(void)
+{
+	void *fdt;
+	int node;
+	struct dt_node_info bsec_info;
+
+	if (fdt_get_address(&fdt) == 0) {
+		panic();
+	}
+
+	node = bsec_get_dt_node(&bsec_info);
+	if (node < 0) {
+		panic();
+	}
+
+	bsec_base = bsec_info.base;
+
+#if defined(IMAGE_BL32)
+	bsec_dt_otp_nsec_access(fdt, node);
+#endif
+	return BSEC_OK;
+}
+
+/*
+ * bsec_get_base: return BSEC base address.
+ */
+uint32_t bsec_get_base(void)
+{
+	return bsec_base;
+}
+
+/*
+ * bsec_set_config: enable and configure BSEC.
+ * cfg: pointer to param structure used to set register.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_config(struct bsec_config *cfg)
+{
+	uint32_t value;
+	int32_t result;
+
+	value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) &
+						BSEC_CONF_FRQ_MASK) |
+		 (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) &
+						BSEC_CONF_PRG_WIDTH_MASK) |
+		 (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) &
+						BSEC_CONF_TREAD_MASK));
+
+	bsec_lock();
+
+	mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value);
+
+	bsec_unlock();
+
+	result = bsec_power_safmem((bool)cfg->power &
+				   BSEC_CONF_POWER_UP_MASK);
+	if (result != BSEC_OK) {
+		return result;
+	}
+
+	value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) &
+						UPPER_OTP_LOCK_MASK) |
+		 (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) &
+						DENREG_LOCK_MASK) |
+		 (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) &
+						GPLOCK_LOCK_MASK));
+
+	bsec_lock();
+
+	mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value);
+
+	bsec_unlock();
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_get_config: return config parameters set in BSEC registers.
+ * cfg: config param return.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_get_config(struct bsec_config *cfg)
+{
+	uint32_t value;
+
+	if (cfg == NULL) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+	cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >>
+						BSEC_CONF_POWER_UP_SHIFT);
+	cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >>
+						BSEC_CONF_FRQ_SHIFT);
+	cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >>
+						BSEC_CONF_PRG_WIDTH_SHIFT);
+	cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >>
+						BSEC_CONF_TREAD_SHIFT);
+
+	value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF);
+	cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >>
+						UPPER_OTP_LOCK_SHIFT);
+	cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >>
+						DENREG_LOCK_SHIFT);
+	cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >>
+						GPLOCK_LOCK_SHIFT);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_register(uint32_t otp)
+{
+	uint32_t result;
+	bool power_up = false;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	/* Check if shadowing of OTP is locked */
+	if (bsec_read_sr_lock(otp)) {
+		VERBOSE("BSEC: OTP %i is locked and will not be refreshed\n",
+			otp);
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+		result = bsec_power_safmem(true);
+
+		if (result != BSEC_OK) {
+			return result;
+		}
+
+		power_up = true;
+	}
+
+	bsec_lock();
+
+	/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
+
+	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+		;
+	}
+
+	result = bsec_check_error(otp);
+
+	bsec_unlock();
+
+	if (power_up) {
+		if (bsec_power_safmem(false) != BSEC_OK) {
+			panic();
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_read_otp: read an OTP data value.
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
+{
+	uint32_t result;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	bsec_lock();
+
+	*val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF +
+			    (otp * sizeof(uint32_t)));
+
+	result = bsec_check_error(otp);
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_write_otp: write value in BSEC data register.
+ * val: value to write.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
+{
+	uint32_t result;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	/* Check if programming of OTP is locked */
+	if (bsec_read_sw_lock(otp)) {
+		VERBOSE("BSEC: OTP %i is locked and write will be ignored\n",
+			otp);
+	}
+
+	bsec_lock();
+
+	mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF +
+		      (otp * sizeof(uint32_t)), val);
+
+	result = bsec_check_error(otp);
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_program_otp: program a bit in SAFMEM after the prog.
+ *	The OTP data is not refreshed.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
+{
+	uint32_t result;
+	bool power_up = false;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	/* Check if programming of OTP is locked */
+	if (bsec_read_sp_lock(otp)) {
+		WARN("BSEC: OTP locked, prog will be ignored\n");
+	}
+
+	if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) &
+	     BIT(BSEC_LOCK_PROGRAM)) != 0U) {
+		WARN("BSEC: GPLOCK activated, prog will be ignored\n");
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+		result = bsec_power_safmem(true);
+
+		if (result != BSEC_OK) {
+			return result;
+		}
+
+		power_up = true;
+	}
+
+	bsec_lock();
+
+	/* Set value in write register */
+	mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val);
+
+	/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
+
+	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+		;
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+		result = BSEC_PROG_FAIL;
+	} else {
+		result = bsec_check_error(otp);
+	}
+
+	bsec_unlock();
+
+	if (power_up) {
+		if (bsec_power_safmem(false) != BSEC_OK) {
+			panic();
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_permanent_lock_otp: permanent lock of OTP in SAFMEM.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_permanent_lock_otp(uint32_t otp)
+{
+	uint32_t result;
+	bool power_up = false;
+	uint32_t data;
+	uint32_t addr;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+		result = bsec_power_safmem(true);
+
+		if (result != BSEC_OK) {
+			return result;
+		}
+
+		power_up = true;
+	}
+
+	if (otp < STM32MP1_UPPER_OTP_START) {
+		addr = otp >> ADDR_LOWER_OTP_PERLOCK_SHIFT;
+		data = DATA_LOWER_OTP_PERLOCK_BIT <<
+		       ((otp & DATA_LOWER_OTP_PERLOCK_MASK) << 1U);
+	} else {
+		addr = (otp >> ADDR_UPPER_OTP_PERLOCK_SHIFT) + 2U;
+		data = DATA_UPPER_OTP_PERLOCK_BIT <<
+		       (otp & DATA_UPPER_OTP_PERLOCK_MASK);
+	}
+
+	bsec_lock();
+
+	/* Set value in write register */
+	mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data);
+
+	/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF,
+		      addr | BSEC_WRITE | BSEC_LOCK);
+
+	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+		;
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+		result = BSEC_PROG_FAIL;
+	} else {
+		result = bsec_check_error(otp);
+	}
+
+	bsec_unlock();
+
+	if (power_up) {
+		if (bsec_power_safmem(false) != BSEC_OK) {
+			panic();
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_write_debug_conf: write value in debug feature
+ *	to enable/disable debug service.
+ * val: value to write.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_debug_conf(uint32_t val)
+{
+	uint32_t result = BSEC_ERROR;
+	uint32_t masked_val = val & BSEC_DEN_ALL_MSK;
+
+	bsec_lock();
+
+	mmio_write_32(bsec_base + BSEC_DEN_OFF, masked_val);
+
+	if ((mmio_read_32(bsec_base + BSEC_DEN_OFF) ^ masked_val) == 0U) {
+		result = BSEC_OK;
+	}
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_read_debug_conf: read debug configuration.
+ */
+uint32_t bsec_read_debug_conf(void)
+{
+	return mmio_read_32(bsec_base + BSEC_DEN_OFF);
+}
+
+/*
+ * bsec_get_status: return status register value.
+ */
+uint32_t bsec_get_status(void)
+{
+	return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF);
+}
+
+/*
+ * bsec_get_hw_conf: return hardware configuration.
+ */
+uint32_t bsec_get_hw_conf(void)
+{
+	return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF);
+}
+
+/*
+ * bsec_get_version: return BSEC version.
+ */
+uint32_t bsec_get_version(void)
+{
+	return mmio_read_32(bsec_base + BSEC_IPVR_OFF);
+}
+
+/*
+ * bsec_get_id: return BSEC ID.
+ */
+uint32_t bsec_get_id(void)
+{
+	return mmio_read_32(bsec_base + BSEC_IP_ID_OFF);
+}
+
+/*
+ * bsec_get_magic_id: return BSEC magic number.
+ */
+uint32_t bsec_get_magic_id(void)
+{
+	return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF);
+}
+
+/*
+ * bsec_write_sr_lock: write shadow-read lock.
+ * otp: OTP number.
+ * value: value to write in the register.
+ *	Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sr_lock(uint32_t otp, uint32_t value)
+{
+	bool result = false;
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t bank_value;
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+
+	bsec_lock();
+
+	bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+
+	if ((bank_value & otp_mask) == value) {
+		/*
+		 * In case of write don't need to write,
+		 * the lock is already set.
+		 */
+		if (value != 0U) {
+			result = true;
+		}
+	} else {
+		if (value != 0U) {
+			bank_value = bank_value | otp_mask;
+		} else {
+			bank_value = bank_value & ~otp_mask;
+		}
+
+		/*
+		 * We can write 0 in all other OTP
+		 * if the lock is activated in one of other OTP.
+		 * Write 0 has no effect.
+		 */
+		mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, bank_value);
+		result = true;
+	}
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_read_sr_lock: read shadow-read lock.
+ * otp: OTP number.
+ * return: true if otp is locked, else false.
+ */
+bool bsec_read_sr_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+
+	return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_write_sw_lock: write shadow-write lock.
+ * otp: OTP number.
+ * value: Value to write in the register.
+ *	Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sw_lock(uint32_t otp, uint32_t value)
+{
+	bool result = false;
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank_value;
+
+	bsec_lock();
+
+	bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+
+	if ((bank_value & otp_mask) == value) {
+		/*
+		 * In case of write don't need to write,
+		 * the lock is already set.
+		 */
+		if (value != 0U) {
+			result = true;
+		}
+	} else {
+		if (value != 0U) {
+			bank_value = bank_value | otp_mask;
+		} else {
+			bank_value = bank_value & ~otp_mask;
+		}
+
+		/*
+		 * We can write 0 in all other OTP
+		 * if the lock is activated in one of other OTP.
+		 * Write 0 has no effect.
+		 */
+		mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, bank_value);
+		result = true;
+	}
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_read_sw_lock: read shadow-write lock.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_read_sw_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+
+	return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_write_sp_lock: write shadow-program lock.
+ * otp: OTP number.
+ * value: Value to write in the register.
+ *	Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sp_lock(uint32_t otp, uint32_t value)
+{
+	bool result = false;
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t bank_value;
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+
+	bsec_lock();
+
+	bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+
+	if ((bank_value & otp_mask) == value) {
+		/*
+		 * In case of write don't need to write,
+		 * the lock is already set.
+		 */
+		if (value != 0U) {
+			result = true;
+		}
+	} else {
+		if (value != 0U) {
+			bank_value = bank_value | otp_mask;
+		} else {
+			bank_value = bank_value & ~otp_mask;
+		}
+
+		/*
+		 * We can write 0 in all other OTP
+		 * if the lock is activated in one of other OTP.
+		 * Write 0 has no effect.
+		 */
+		mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, bank_value);
+		result = true;
+	}
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_read_sp_lock: read shadow-program lock.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_read_sp_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+
+	return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_wr_lock: Read permanent lock status.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_wr_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t lock_bit = BIT(otp & BSEC_OTP_MASK);
+
+	if ((mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank) &
+	     lock_bit) != 0U) {
+		/*
+		 * In case of write don't need to write,
+		 * the lock is already set.
+		 */
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * bsec_otp_lock: Lock Upper OTP or Global programming or debug enable
+ * service: Service to lock see header file.
+ * value: Value to write must always set to 1 (only use for debug purpose).
+ * return: BSEC_OK if succeed.
+ */
+uint32_t bsec_otp_lock(uint32_t service, uint32_t value)
+{
+	uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF;
+
+	switch (service) {
+	case BSEC_LOCK_UPPER_OTP:
+		mmio_write_32(reg, value << BSEC_LOCK_UPPER_OTP);
+		break;
+	case BSEC_LOCK_DEBUG:
+		mmio_write_32(reg, value << BSEC_LOCK_DEBUG);
+		break;
+	case BSEC_LOCK_PROGRAM:
+		mmio_write_32(reg, value << BSEC_LOCK_PROGRAM);
+		break;
+	default:
+		return BSEC_INVALID_PARAM;
+	}
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_power_safmem: Activate or deactivate SAFMEM power.
+ * power: true to power up, false to power down.
+ * return: BSEC_OK if succeed.
+ */
+static uint32_t bsec_power_safmem(bool power)
+{
+	uint32_t register_val;
+	uint32_t timeout = BSEC_TIMEOUT_VALUE;
+
+	bsec_lock();
+
+	register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+
+	if (power) {
+		register_val |= BSEC_CONF_POWER_UP_MASK;
+	} else {
+		register_val &= ~BSEC_CONF_POWER_UP_MASK;
+	}
+
+	mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val);
+
+	/* Waiting loop */
+	if (power) {
+		while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) &&
+		       (timeout != 0U)) {
+			timeout--;
+		}
+	} else {
+		while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) &&
+		       (timeout != 0U)) {
+			timeout--;
+		}
+	}
+
+	bsec_unlock();
+
+	if (timeout == 0U) {
+		return BSEC_TIMEOUT;
+	}
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_mode_is_closed_device: read OTP secure sub-mode.
+ * return: false if open_device and true of closed_device.
+ */
+bool bsec_mode_is_closed_device(void)
+{
+	uint32_t value;
+
+	if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
+	    (bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
+		return true;
+	}
+
+	return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
+}
+
+/*
+ * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
+ * otp_value: read value.
+ * word: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
+{
+	uint32_t result;
+
+	result = bsec_shadow_register(word);
+	if (result != BSEC_OK) {
+		ERROR("BSEC: %u Shadowing Error %i\n", word, result);
+		return result;
+	}
+
+	result = bsec_read_otp(otp_value, word);
+	if (result != BSEC_OK) {
+		ERROR("BSEC: %u Read Error %i\n", word, result);
+	}
+
+	return result;
+}
+
+/*
+ * bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
+ * otp: OTP number.
+ * return: BSEC_OK if authorized access.
+ */
+uint32_t bsec_check_nsec_access_rights(uint32_t otp)
+{
+#if defined(IMAGE_BL32)
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	if (otp >= STM32MP1_UPPER_OTP_START) {
+		/* Check if BSEC is in OTP-SECURED closed_device state. */
+		if (bsec_mode_is_closed_device()) {
+			if (!non_secure_can_access(otp)) {
+				return BSEC_ERROR;
+			}
+		}
+	}
+#endif
+
+	return BSEC_OK;
+}
+
