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

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

#include <kernel.h>
#include <device.h>
#include <string.h>
#include <drivers/flash.h>
#include <init.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;

	__DSB();

	/* 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;

	__DSB();

	*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_DBG("Flash location not erased");
		return -EIO;
	}

	/* Enable writing */
	write_enable(regs);

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

	/* 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;
}

/* offset and len must be aligned on 2 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 % 2 == 0 && len % 2 == 0U)) &&
		flash_stm32_range_exists(dev, offset, len);
}

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);
		__DSB();
		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;
}
