/*
 * Copyright (c) 2017 BayLibre, SAS
 * Copyright (c) 2019 Linaro Limited
 * Copyright (c) 2020 Andreas Sandberg
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(flash_stm32generic, CONFIG_FLASH_LOG_LEVEL);

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

#include "flash_stm32.h"

#if FLASH_STM32_WRITE_BLOCK_SIZE == 8
typedef uint64_t flash_prg_t;
#elif FLASH_STM32_WRITE_BLOCK_SIZE == 4
typedef uint32_t flash_prg_t;
#elif FLASH_STM32_WRITE_BLOCK_SIZE == 2
typedef uint16_t flash_prg_t;
#else
#error Unknown write block size
#endif

#if defined(FLASH_CR_PER)
#define FLASH_ERASED_VALUE ((flash_prg_t)-1)
#elif defined(FLASH_PECR_ERASE)
#define FLASH_ERASED_VALUE 0
#else
#error Unknown erase value
#endif

static unsigned int get_page(off_t offset)
{
	return offset / FLASH_PAGE_SIZE;
}

#if defined(FLASH_CR_PER)
static int is_flash_locked(FLASH_TypeDef *regs)
{
	return !!(regs->CR & FLASH_CR_LOCK);
}

static void write_enable(FLASH_TypeDef *regs)
{
	regs->CR |= FLASH_CR_PG;
}

static void write_disable(FLASH_TypeDef *regs)
{
	regs->CR &= (~FLASH_CR_PG);
}

static void erase_page_begin(FLASH_TypeDef *regs, unsigned int page)
{
	/* Set the PER bit and select the page you wish to erase */
	regs->CR |= FLASH_CR_PER;
	regs->AR = CONFIG_FLASH_BASE_ADDRESS + page * FLASH_PAGE_SIZE;

	barrier_dsync_fence_full();

	/* Set the STRT bit */
	regs->CR |= FLASH_CR_STRT;
}

static void erase_page_end(FLASH_TypeDef *regs)
{
	regs->CR &= ~FLASH_CR_PER;
}

#else

static int is_flash_locked(FLASH_TypeDef *regs)
{
	return !!(regs->PECR & FLASH_PECR_PRGLOCK);
}

static void write_enable(FLASH_TypeDef *regs)
{
	/* Only used for half-page programming on L1x */
#if !defined(CONFIG_SOC_SERIES_STM32L1X)
	regs->PECR |= FLASH_PECR_PROG;
#endif
}

static void write_disable(FLASH_TypeDef *regs)
{
	/* Clear the PG bit */
	regs->PECR &= ~FLASH_PECR_PROG;
}

static void erase_page_begin(FLASH_TypeDef *regs, unsigned int page)
{
	volatile flash_prg_t *page_base = (flash_prg_t *)(
		CONFIG_FLASH_BASE_ADDRESS + page * FLASH_PAGE_SIZE);
	/* Enable programming in erase mode. An erase is triggered by
	 * writing 0 to the first word of a page.
	 */
	regs->PECR |= FLASH_PECR_ERASE;
	regs->PECR |= FLASH_PECR_PROG;

	barrier_dsync_fence_full();

	*page_base = 0;
}

static void erase_page_end(FLASH_TypeDef *regs)
{
	/* Disable programming */
	regs->PECR &= ~FLASH_PECR_PROG;
	regs->PECR &= ~FLASH_PECR_ERASE;
}
#endif

static int write_value(const struct device *dev, off_t offset,
		       flash_prg_t val)
{
	volatile flash_prg_t *flash = (flash_prg_t *)(
		offset + CONFIG_FLASH_BASE_ADDRESS);
	FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
	int rc;

	/* if the control register is locked, do not fail silently */
	if (is_flash_locked(regs)) {
		LOG_ERR("Flash is locked");
		return -EIO;
	}

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

	/* Check if this half word is erased */
	if (*flash != FLASH_ERASED_VALUE) {
		LOG_ERR("Flash location not erased");
		return -EIO;
	}

	/* Enable writing */
	write_enable(regs);

	/* Make sure the register write has taken effect */
	barrier_dsync_fence_full();

	/* Perform the data write operation at the desired memory address */
	*flash = val;

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

	/* Disable writing */
	write_disable(regs);

	return rc;
}

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

	/* if the control register is locked, do not fail silently */
	if (is_flash_locked(regs)) {
		LOG_ERR("Flash is locked");
		return -EIO;
	}

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

	for (i = get_page(offset); i <= get_page(offset + len - 1); ++i) {
		erase_page_begin(regs, i);
		barrier_dsync_fence_full();
		rc = flash_stm32_wait_flash_idle(dev);
		erase_page_end(regs);

		if (rc < 0) {
			break;
		}
	}

	return rc;
}

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

	for (i = 0; i < len / sizeof(flash_prg_t); i++) {
		memcpy(&value,
		       (const uint8_t *)data + i * sizeof(flash_prg_t),
		       sizeof(flash_prg_t));
		rc = write_value(dev, offset + i * sizeof(flash_prg_t), value);
		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 flash_layout = {
		.pages_count = 0,
		.pages_size = 0,
	};

	ARG_UNUSED(dev);

	if (flash_layout.pages_count == 0) {
#if defined(CONFIG_SOC_SERIES_STM32F3X)
		flash_layout.pages_count =
			DT_REG_SIZE(DT_INST(0, soc_nv_flash)) / FLASH_PAGE_SIZE;
#else
		flash_layout.pages_count = (CONFIG_FLASH_SIZE * 1024) /
			FLASH_PAGE_SIZE;
#endif
		flash_layout.pages_size = FLASH_PAGE_SIZE;
	}

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