/*
 * 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)
{
	if (stm32mp_lock_available()) {
		spin_lock(&bsec_spinlock);
	}
}

static void bsec_unlock(void)
{
	if (stm32mp_lock_available()) {
		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;
}

