/*
 * Copyright (c) 2019 Linaro Limited
 * Copyright (c) 2020 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define LOG_DOMAIN flash_stm32wb
#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_DOMAIN);

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <string.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/init.h>
#include <soc.h>
#include <zephyr/sys/__assert.h>

#include "flash_stm32.h"
#include "stm32_hsem.h"
#if defined(CONFIG_BT)
#include "shci.h"
#endif

#define STM32WBX_PAGE_SHIFT	12

/* offset and len must be aligned on 8 for write,
 * positive and not beyond end of flash
 */
bool flash_stm32_valid_range(const struct device *dev, off_t offset,
			     uint32_t len,
			     bool write)
{
	return (!write || (offset % 8 == 0 && len % 8 == 0U)) &&
	       flash_stm32_range_exists(dev, offset, len);
}

/*
 * Up to 255 4K pages
 */
static uint32_t get_page(off_t offset)
{
	return offset >> STM32WBX_PAGE_SHIFT;
}

static inline void flush_cache(FLASH_TypeDef *regs)
{
	if (regs->ACR & FLASH_ACR_DCEN) {
		regs->ACR &= ~FLASH_ACR_DCEN;
		/* Datasheet: DCRST: Data cache reset
		 * This bit can be written only when the data cache is disabled
		 */
		regs->ACR |= FLASH_ACR_DCRST;
		regs->ACR &= ~FLASH_ACR_DCRST;
		regs->ACR |= FLASH_ACR_DCEN;
	}

	if (regs->ACR & FLASH_ACR_ICEN) {
		regs->ACR &= ~FLASH_ACR_ICEN;
		/* Datasheet: ICRST: Instruction cache reset :
		 * This bit can be written only when the instruction cache
		 * is disabled
		 */
		regs->ACR |= FLASH_ACR_ICRST;
		regs->ACR &= ~FLASH_ACR_ICRST;
		regs->ACR |= FLASH_ACR_ICEN;
	}
}

static int write_dword(const struct device *dev, off_t offset, uint64_t val)
{
	volatile uint32_t *flash = (uint32_t *)(offset + CONFIG_FLASH_BASE_ADDRESS);
	FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
	uint32_t tmp;
	int ret, rc;
	uint32_t cpu1_sem_status;
	uint32_t cpu2_sem_status = 0;
	uint32_t key;

	/* if the control register is locked, do not fail silently */
	if (regs->CR & FLASH_CR_LOCK) {
		return -EIO;
	}

	/* Check if this double word is erased */
	if (flash[0] != 0xFFFFFFFFUL ||
	    flash[1] != 0xFFFFFFFFUL) {
		return -EIO;
	}

	ret = flash_stm32_check_status(dev);
	if (ret < 0) {
		return -EIO;
	}

	/* Implementation of STM32 AN5289, proposed in STM32WB Cube Application
	 * BLE_RfWithFlash
	 * https://github.com/STMicroelectronics/STM32CubeWB/tree/master/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash
	 */

	do {
		/**
		 * When the PESD bit mechanism is used by CPU2 to protect its
		 * timing, the PESD bit should be polled here.
		 * If the PESD is set, the CPU1 will be stalled when reading
		 * literals from an ISR that may occur after the flash
		 * processing has been requested but suspended due to the PESD
		 * bit.
		 *
		 * Note: This code is required only when the PESD mechanism is
		 * used to protect the CPU2 timing.
		 * However, keeping that code make it compatible with both
		 * mechanisms.
		 */
		while (LL_FLASH_IsActiveFlag_OperationSuspended()) {
			;
		}

		/* Enter critical section */
		key = irq_lock();

		/**
		 *  Depending on the application implementation, in case a
		 *  multitasking is possible with an OS, it should be checked
		 *  here if another task in the application disallowed flash
		 *  processing to protect some latency in critical code
		 *  execution.
		 *  When flash processing is ongoing, the CPU cannot access the
		 *  flash anymore.Trying to access the flash during that time
		 *  stalls the CPU.
		 *  The only way for CPU1 to disallow flash processing is to
		 *  take CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID.
		 */
		cpu1_sem_status = LL_HSEM_GetStatus(HSEM,
			CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID);
		if (cpu1_sem_status == 0) {
			/**
			 *  Check now if the CPU2 disallows flash processing to
			 *  protect its timing. If the semaphore is locked, the
			 *  CPU2 does not allow flash processing
			 *
			 *  Note: By default, the CPU2 uses the PESD mechanism
			 *  to protect its timing, therefore, it is useless to
			 *  get/release the semaphore.
			 *
			 *  However, keeping that code make it compatible with
			 *  both mechanisms.
			 *  The protection by semaphore is enabled on CPU2 side
			 *  with the command SHCI_C2_SetFlashActivityControl()
			 *
			 */
			cpu2_sem_status = LL_HSEM_1StepLock(HSEM,
				CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID);
			if (cpu2_sem_status == 0) {
				/**
				 * When CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID is
				 * taken, it is allowed to only write one
				 * single 64bits data.
				 * When several 64bits data need to be erased,
				 * the application shall first exit from the
				 * critical section and try again.
				 */
				/* Set the PG bit */
				regs->CR |= FLASH_CR_PG;

				/* Flush the register write */
				tmp = regs->CR;

				/* Perform the data write operation at desired
				 * memory address
				 */
				flash[0] = (uint32_t)val;
				flash[1] = (uint32_t)(val >> 32);

				/**
				 *  Release the semaphore to give the
				 *  opportunity to CPU2 to protect its timing
				 *  versus the next flash operation by taking
				 *  this semaphore.
				 *  Note that the CPU2 is polling on this
				 *  semaphore so CPU1 shall release it as fast
				 *  as possible.
				 *  This is why this code is protected by a
				 *  critical section.
				 */
				LL_HSEM_ReleaseLock(HSEM,
					CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID,
					0);
			}
		}

		/* Exit critical section */
		irq_unlock(key);

	} while (cpu2_sem_status || cpu1_sem_status);

	/* Wait until the BSY bit is cleared */
	rc = flash_stm32_wait_flash_idle(dev);

	/* Clear the PG bit */
	regs->CR &= (~FLASH_CR_PG);

	return rc;
}

static int erase_page(const struct device *dev, uint32_t page)
{
	uint32_t cpu1_sem_status;
	uint32_t cpu2_sem_status = 0;
	uint32_t key;

	FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
	int rc;

	/* if the control register is locked, do not fail silently */
	if (regs->CR & FLASH_CR_LOCK) {
		return -EIO;
	}

	/* Check that no Flash memory operation is ongoing */
	rc = flash_stm32_wait_flash_idle(dev);
	if (rc < 0) {
		return rc;
	}

	/*
	 * If an erase operation in Flash memory also concerns data in the data
	 * or instruction cache, the user has to ensure that these data
	 * are rewritten before they are accessed during code execution.
	 */
	flush_cache(regs);

	/* Implementation of STM32 AN5289, proposed in STM32WB Cube Application
	 * BLE_RfWithFlash
	 * https://github.com/STMicroelectronics/STM32CubeWB/tree/master/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash
	 */

	do {
		/**
		 * When the PESD bit mechanism is used by CPU2 to protect its
		 * timing, the PESD bit should be polled here.
		 * If the PESD is set, the CPU1 will be stalled when reading
		 * literals from an ISR that may occur after the flash
		 * processing has been requested but suspended due to the PESD
		 * bit.
		 *
		 * Note: This code is required only when the PESD mechanism is
		 * used to protect the CPU2 timing.
		 * However, keeping that code make it compatible with both
		 * mechanisms.
		 */
		while (LL_FLASH_IsActiveFlag_OperationSuspended()) {
			;
		}

		/* Enter critical section */
		key = irq_lock();

		/**
		 *  Depending on the application implementation, in case a
		 *  multitasking is possible with an OS, it should be checked
		 *  here if another task in the application disallowed flash
		 *  processing to protect some latency in critical code
		 *  execution.
		 *  When flash processing is ongoing, the CPU cannot access the
		 *  flash anymore.Trying to access the flash during that time
		 *  stalls the CPU.
		 *  The only way for CPU1 to disallow flash processing is to
		 *  take CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID.
		 */
		cpu1_sem_status = LL_HSEM_GetStatus(HSEM,
			CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID);
		if (cpu1_sem_status == 0) {
			/**
			 *  Check now if the CPU2 disallows flash processing to
			 *  protect its timing. If the semaphore is locked, the
			 *  CPU2 does not allow flash processing
			 *
			 *  Note: By default, the CPU2 uses the PESD mechanism
			 *  to protect its timing, therefore, it is useless to
			 *  get/release the semaphore.
			 *
			 *  However, keeping that code make it compatible with
			 *  both mechanisms.
			 *  The protection by semaphore is enabled on CPU2 side
			 *  with the command SHCI_C2_SetFlashActivityControl()
			 *
			 */
			cpu2_sem_status = LL_HSEM_1StepLock(HSEM,
				CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID);
			if (cpu2_sem_status == 0) {
				/**
				 * When CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID is
				 * taken, it is allowed to only erase one
				 * sector.
				 * When several sectors need to be erased,
				 * the application shall first exit from the
				 * critical section and try again.
				 */
				regs->CR |= FLASH_CR_PER;
				regs->CR &= ~FLASH_CR_PNB_Msk;
				regs->CR |= page << FLASH_CR_PNB_Pos;

				regs->CR |= FLASH_CR_STRT;

				/**
				 *  Release the semaphore to give the
				 *  opportunity to CPU2 to protect its timing
				 *  versus the next flash operation by taking
				 *  this semaphore.
				 *  Note that the CPU2 is polling on this
				 *  semaphore so CPU1 shall release it as fast
				 *  as possible.
				 *  This is why this code is protected by a
				 *  critical section.
				 */
				LL_HSEM_ReleaseLock(HSEM,
					CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID,
					0);
			}
		}

		/* Exit critical section */
		irq_unlock(key);

	} while (cpu2_sem_status || cpu1_sem_status);


	/* Wait for the BSY bit */
	rc = flash_stm32_wait_flash_idle(dev);

	regs->CR &= ~FLASH_CR_PER;

	return rc;
}

int flash_stm32_block_erase_loop(const struct device *dev,
				 unsigned int offset,
				 unsigned int len)
{
	int i, rc = 0;

#if defined(CONFIG_BT)
	/**
	 *  Notify the CPU2 that some flash erase activity may be executed
	 *  On reception of this command, the CPU2 enables the BLE timing
	 *  protection versus flash erase processing.
	 *  The Erase flash activity will be executed only when the BLE RF is
	 *  idle for at least 25ms.
	 *  The CPU2 will prevent all flash activity (write or erase) in all
	 *  cases when the BL RF Idle is shorter than 25ms.
	 */
	SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
#endif /* CONFIG_BT */

	i = get_page(offset);
	for (; i <= get_page(offset + len - 1) ; ++i) {
		rc = erase_page(dev, i);
		if (rc < 0) {
			break;
		}
	}

#if defined(CONFIG_BT)
	/**
	 *  Notify the CPU2 there will be no request anymore to erase the flash
	 *  On reception of this command, the CPU2 disables the BLE timing
	 *  protection versus flash erase processing
	 */
	SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
#endif /* CONFIG_BT */

	return rc;
}

int flash_stm32_write_range(const struct device *dev, unsigned int offset,
			    const void *data, unsigned int len)
{
	int i, rc = 0;

	for (i = 0; i < len; i += 8, offset += 8U) {
		rc = write_dword(dev, offset,
				UNALIGNED_GET((const uint64_t *) data + (i >> 3)));
		if (rc < 0) {
			return rc;
		}
	}

	return rc;
}

void flash_stm32_page_layout(const struct device *dev,
			     const struct flash_pages_layout **layout,
			     size_t *layout_size)
{
	static struct flash_pages_layout stm32wb_flash_layout = {
		.pages_count = 0,
		.pages_size = 0,
	};

	ARG_UNUSED(dev);

	if (stm32wb_flash_layout.pages_count == 0) {
		stm32wb_flash_layout.pages_count = FLASH_SIZE / FLASH_PAGE_SIZE;
		stm32wb_flash_layout.pages_size = FLASH_PAGE_SIZE;
	}

	*layout = &stm32wb_flash_layout;
	*layout_size = 1;
}

int flash_stm32_check_status(const struct device *dev)
{
	FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
	uint32_t error = 0;

	/* Save Flash errors */
	error = (regs->SR & FLASH_FLAG_SR_ERRORS);
	error |= (regs->ECCR & FLASH_FLAG_ECCC);

	/* Clear systematic Option and Engineering bits validity error */
	if (error & FLASH_FLAG_OPTVERR) {
		regs->SR |= FLASH_FLAG_SR_ERRORS;
		return 0;
	}

	if (error) {
		return -EIO;
	}

	return 0;
}
