/*
 * Copyright (c) 2018 Aurelien Jarno
 * Copyright (c) 2023 Bjarki Arge Andreasen
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * This driver defines a page as the erase_block_size.
 * This driver defines a write page as defined by the flash controller
 * This driver defines a section as a contiguous array of bytes
 * This driver defines an area as the entire flash area
 * This driver defines the write block size as the minimum write block size
 */

#define DT_DRV_COMPAT atmel_sam_flash_controller

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

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

#define SAM_FLASH_WRITE_PAGE_SIZE (512)

typedef void (*sam_flash_irq_init_fn_ptr)(void);

struct sam_flash_config {
	Efc *regs;
	sam_flash_irq_init_fn_ptr irq_init;
	off_t area_address;
	off_t area_size;
	struct flash_parameters parameters;
	struct flash_pages_layout *pages_layouts;
	size_t pages_layouts_size;
};

struct sam_flash_erase_data {
	off_t section_start;
	size_t section_end;
	bool succeeded;
};

struct sam_flash_data {
	const struct device *dev;
	struct k_spinlock lock;
	struct sam_flash_erase_data erase_data;
	struct k_sem ready_sem;
};

static bool sam_flash_validate_offset_len(off_t offset, size_t len)
{
	if (offset < 0) {
		return false;
	}

	if ((offset + len) < len) {
		return false;
	}

	return true;
}

static bool sam_flash_aligned(size_t value, size_t alignment)
{
	return (value & (alignment - 1)) == 0;
}

static bool sam_flash_offset_is_on_write_page_boundary(off_t offset)
{
	return sam_flash_aligned(offset, SAM_FLASH_WRITE_PAGE_SIZE);
}

static inline void sam_flash_mask_ready_interrupt(const struct sam_flash_config *config)
{
	Efc *regs = config->regs;

	regs->EEFC_FMR &= ~EEFC_FMR_FRDY;
}

static inline void sam_flash_unmask_ready_interrupt(const struct sam_flash_config *config)
{
	Efc *regs = config->regs;

	regs->EEFC_FMR |= EEFC_FMR_FRDY;
}

static void sam_flash_isr(const struct device *dev)
{
	struct sam_flash_data *data = dev->data;
	const struct sam_flash_config *config = dev->config;

	sam_flash_mask_ready_interrupt(config);
	k_sem_give(&data->ready_sem);
}

static int sam_flash_section_wait_until_ready(const struct device *dev)
{
	struct sam_flash_data *data = dev->data;
	const struct sam_flash_config *config = dev->config;
	Efc *regs = config->regs;
	uint32_t eefc_fsr;

	k_sem_reset(&data->ready_sem);
	sam_flash_unmask_ready_interrupt(config);

	if (k_sem_take(&data->ready_sem, K_MSEC(500)) < 0) {
		LOG_ERR("Command did not execute in time");
		return -EFAULT;
	}

	/* FSR register is cleared on read */
	eefc_fsr = regs->EEFC_FSR;

	if (eefc_fsr & EEFC_FSR_FCMDE) {
		LOG_ERR("Invalid command requested");
		return -EPERM;
	}

	if (eefc_fsr & EEFC_FSR_FLOCKE) {
		LOG_ERR("Tried to modify locked region");
		return -EPERM;
	}

	if (eefc_fsr & EEFC_FSR_FLERR) {
		LOG_ERR("Programming failed");
		return -EPERM;
	}

	return 0;
}

static bool sam_flash_section_is_within_area(const struct device *dev, off_t offset, size_t len)
{
	const struct sam_flash_config *config = dev->config;

	if ((offset + ((off_t)len)) < offset) {
		return false;
	}

	if ((offset >= 0) && ((offset + len) <= config->area_size)) {
		return true;
	}

	LOG_WRN("Section from 0x%x to 0x%x is not within flash area (0x0 to %x)",
		(size_t)offset, (size_t)(offset + len), (size_t)config->area_size);

	return false;
}

static bool sam_flash_section_is_aligned_with_write_block_size(const struct device *dev,
							       off_t offset, size_t len)
{
	const struct sam_flash_config *config = dev->config;

	if (sam_flash_aligned(offset, config->parameters.write_block_size) &&
	    sam_flash_aligned(len, config->parameters.write_block_size)) {
		return true;
	}

	LOG_WRN("Section from 0x%x to 0x%x is not aligned with write block size (%u)",
		(size_t)offset, (size_t)(offset + len), config->parameters.write_block_size);

	return false;
}

static bool sam_flash_section_is_aligned_with_pages(const struct device *dev, off_t offset,
						    size_t len)
{
	const struct sam_flash_config *config = dev->config;
	struct flash_pages_info pages_info;

	/* Get the page offset points to */
	if (flash_get_page_info_by_offs(dev, offset, &pages_info) < 0) {
		return false;
	}

	/* Validate offset points to start of page */
	if (offset != pages_info.start_offset) {
		return false;
	}

	/* Check if end of section is aligned with end of area */
	if ((offset + len) == (config->area_size)) {
		return true;
	}

	/* Get the page pointed to by end of section */
	if (flash_get_page_info_by_offs(dev, offset + len, &pages_info) < 0) {
		return false;
	}

	/* Validate offset points to start of page */
	if ((offset + len) != pages_info.start_offset) {
		return false;
	}

	return true;
}

static int sam_flash_read(const struct device *dev, off_t offset, void *data, size_t len)
{
	struct sam_flash_data *sam_data = dev->data;
	const struct sam_flash_config *sam_config = dev->config;
	k_spinlock_key_t key;

	if (len == 0) {
		return 0;
	}

	if (!sam_flash_validate_offset_len(offset, len)) {
		return -EINVAL;
	}

	if (!sam_flash_section_is_within_area(dev, offset, len)) {
		return -EINVAL;
	}

	key = k_spin_lock(&sam_data->lock);
	memcpy(data, (uint8_t *)(sam_config->area_address + offset), len);
	k_spin_unlock(&sam_data->lock, key);
	return 0;
}

static int sam_flash_write_latch_buffer_to_page(const struct device *dev, off_t offset)
{
	const struct sam_flash_config *sam_config = dev->config;
	Efc *regs = sam_config->regs;
	uint32_t page = offset / SAM_FLASH_WRITE_PAGE_SIZE;

	regs->EEFC_FCR = EEFC_FCR_FCMD_WP | EEFC_FCR_FARG(page) | EEFC_FCR_FKEY_PASSWD;
	sam_flash_section_wait_until_ready(dev);
	return 0;
}

static int sam_flash_write_latch_buffer_to_previous_page(const struct device *dev, off_t offset)
{
	return sam_flash_write_latch_buffer_to_page(dev, offset - SAM_FLASH_WRITE_PAGE_SIZE);
}

static void sam_flash_write_dword_to_latch_buffer(off_t offset, uint32_t dword)
{
	*((uint32_t *)offset) = dword;
	barrier_dsync_fence_full();
}

static int sam_flash_write_dwords_to_flash(const struct device *dev, off_t offset,
					   const uint32_t *dwords, size_t size)
{
	for (size_t i = 0; i < size; i++) {
		sam_flash_write_dword_to_latch_buffer(offset, dwords[i]);
		offset += sizeof(uint32_t);
		if (sam_flash_offset_is_on_write_page_boundary(offset)) {
			sam_flash_write_latch_buffer_to_previous_page(dev, offset);
		}
	}

	if (!sam_flash_offset_is_on_write_page_boundary(offset)) {
		sam_flash_write_latch_buffer_to_page(dev, offset);
	}

	return 0;
}

static int sam_flash_write(const struct device *dev, off_t offset, const void *data, size_t len)
{
	struct sam_flash_data *sam_data = dev->data;
	k_spinlock_key_t key;

	if (len == 0) {
		return 0;
	}

	if (!sam_flash_validate_offset_len(offset, len)) {
		return -EINVAL;
	}

	if (!sam_flash_section_is_aligned_with_write_block_size(dev, offset, len)) {
		return -EINVAL;
	}

	LOG_DBG("Writing sector from 0x%x to 0x%x", (size_t)offset, (size_t)(offset + len));

	key = k_spin_lock(&sam_data->lock);
	if (sam_flash_write_dwords_to_flash(dev, offset, data, len / sizeof(uint32_t)) < 0) {
		k_spin_unlock(&sam_data->lock, key);
		return -EAGAIN;
	}

	k_spin_unlock(&sam_data->lock, key);
	return 0;
}

static int sam_flash_unlock_write_page(const struct device *dev, uint16_t page_index)
{
	const struct sam_flash_config *sam_config = dev->config;
	Efc *regs = sam_config->regs;

	/* Perform unlock command of write page */
	regs->EEFC_FCR = EEFC_FCR_FCMD_CLB
		       | EEFC_FCR_FARG(page_index)
		       | EEFC_FCR_FKEY_PASSWD;

	return sam_flash_section_wait_until_ready(dev);
}

static int sam_flash_unlock_page(const struct device *dev, const struct flash_pages_info *info)
{
	uint16_t page_index_start;
	uint16_t page_index_end;
	int ret;

	/* Convert from page offset and size to write page index and count */
	page_index_start = info->start_offset / SAM_FLASH_WRITE_PAGE_SIZE;
	page_index_end = page_index_start + (info->size / SAM_FLASH_WRITE_PAGE_SIZE);

	for (uint16_t i = page_index_start; i < page_index_end; i++) {
		ret = sam_flash_unlock_write_page(dev, i);
		if (ret < 0) {
			return ret;
		}
	}

	return 0;
}

static int sam_flash_erase_page(const struct device *dev, const struct flash_pages_info *info)
{
	const struct sam_flash_config *sam_config = dev->config;
	Efc *regs = sam_config->regs;
	uint32_t page_index;
	int ret;

	/* Convert from page offset to write page index */
	page_index = info->start_offset / SAM_FLASH_WRITE_PAGE_SIZE;

	LOG_DBG("Erasing page at 0x%x of size 0x%x", (size_t)info->start_offset, info->size);

	/* Perform erase command of page */
	switch (info->size) {
	case 0x800:
		regs->EEFC_FCR = EEFC_FCR_FCMD_EPA
			       | EEFC_FCR_FARG(page_index)
			       | EEFC_FCR_FKEY_PASSWD;
		break;

	case 0x1000:
		regs->EEFC_FCR = EEFC_FCR_FCMD_EPA
			       | EEFC_FCR_FARG(page_index | 1)
			       | EEFC_FCR_FKEY_PASSWD;
		break;

	case 0x2000:
		regs->EEFC_FCR = EEFC_FCR_FCMD_EPA
			       | EEFC_FCR_FARG(page_index | 2)
			       | EEFC_FCR_FKEY_PASSWD;
		break;

	case 0x4000:
		regs->EEFC_FCR = EEFC_FCR_FCMD_EPA
			       | EEFC_FCR_FARG(page_index | 3)
			       | EEFC_FCR_FKEY_PASSWD;
		break;

	default:
		return -EINVAL;
	}

	ret = sam_flash_section_wait_until_ready(dev);
	if (ret == 0) {
		return ret;
	}

	LOG_ERR("Failed to erase page at 0x%x of size 0x%x", (size_t)info->start_offset,
		info->size);

	return ret;
}

static bool sam_flash_erase_foreach_page(const struct flash_pages_info *info, void *data)
{
	struct sam_flash_data *sam_data = data;
	const struct device *dev = sam_data->dev;
	struct sam_flash_erase_data *erase_data = &sam_data->erase_data;

	/* Validate we reached first page to erase */
	if (info->start_offset < erase_data->section_start) {
		/* Next page */
		return true;
	}

	/* Check if we've reached the end of pages to erase */
	if (info->start_offset >= erase_data->section_end) {
		/* Succeeded, stop iterating */
		return false;
	}

	if (sam_flash_unlock_page(dev, info) || sam_flash_erase_page(dev, info)) {
		/* Failed to unlock page and erase page, stop iterating */
		erase_data->succeeded = false;
		return false;
	}

	/* Next page */
	return true;
}

static int sam_flash_erase(const struct device *dev, off_t offset, size_t size)
{
	struct sam_flash_data *sam_data = dev->data;
	k_spinlock_key_t key;

	if (size == 0) {
		return 0;
	}

	if (!sam_flash_validate_offset_len(offset, size)) {
		return -EINVAL;
	}

	if (!sam_flash_section_is_aligned_with_pages(dev, offset, size)) {
		return -EINVAL;
	}

	LOG_DBG("Erasing sector from 0x%x to 0x%x", (size_t)offset, (size_t)(offset + size));

	key = k_spin_lock(&sam_data->lock);
	sam_data->erase_data.section_start = offset;
	sam_data->erase_data.section_end = offset + size;
	sam_data->erase_data.succeeded = true;
	flash_page_foreach(dev, sam_flash_erase_foreach_page, sam_data);
	if (!sam_data->erase_data.succeeded) {
		k_spin_unlock(&sam_data->lock, key);
		return -EFAULT;
	}

	k_spin_unlock(&sam_data->lock, key);
	return 0;
}

static const struct flash_parameters *sam_flash_get_parameters(const struct device *dev)
{
	const struct sam_flash_config *config = dev->config;

	return &config->parameters;
}

static void sam_flash_api_pages_layout(const struct device *dev,
				       const struct flash_pages_layout **layout,
				       size_t *layout_size)
{
	const struct sam_flash_config *config = dev->config;

	*layout = config->pages_layouts;
	*layout_size = config->pages_layouts_size;
}

static DEVICE_API(flash, sam_flash_api) = {
	.read = sam_flash_read,
	.write = sam_flash_write,
	.erase = sam_flash_erase,
	.get_parameters = sam_flash_get_parameters,
	.page_layout = sam_flash_api_pages_layout,
};

static int sam_flash_init(const struct device *dev)
{
	struct sam_flash_data *sam_data = dev->data;
	const struct sam_flash_config *sam_config = dev->config;

	sam_data->dev = dev;
	k_sem_init(&sam_data->ready_sem, 0, 1);
	sam_flash_mask_ready_interrupt(sam_config);
	sam_config->irq_init();
	return 0;
}

#define SAM_FLASH_DEVICE DT_INST(0, atmel_sam_flash)

#define SAM_FLASH_PAGES_LAYOUT(node_id, prop, idx)						\
	{											\
		.pages_count = DT_PHA_BY_IDX(node_id, prop, idx, pages_count),			\
		.pages_size = DT_PHA_BY_IDX(node_id, prop, idx, pages_size),			\
	}

#define SAM_FLASH_PAGES_LAYOUTS									\
	DT_FOREACH_PROP_ELEM_SEP(SAM_FLASH_DEVICE, erase_blocks, SAM_FLASH_PAGES_LAYOUT, (,))

#define SAM_FLASH_CONTROLLER(inst)								\
	struct flash_pages_layout sam_flash_pages_layouts##inst[] = {				\
		SAM_FLASH_PAGES_LAYOUTS								\
	};											\
												\
	static void sam_flash_irq_init_##inst(void)						\
	{											\
		IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority),			\
			    sam_flash_isr, DEVICE_DT_INST_GET(inst), 0);			\
		irq_enable(DT_INST_IRQN(inst));							\
												\
	}											\
												\
	static const struct sam_flash_config sam_flash_config##inst = {				\
		.regs = (Efc *)DT_INST_REG_ADDR(inst),						\
		.irq_init = sam_flash_irq_init_##inst,						\
		.area_address = DT_REG_ADDR(SAM_FLASH_DEVICE),					\
		.area_size = DT_REG_SIZE(SAM_FLASH_DEVICE),					\
		.parameters = {									\
			.write_block_size = DT_PROP(SAM_FLASH_DEVICE, write_block_size),	\
			.erase_value = 0xFF,							\
		},										\
		.pages_layouts = sam_flash_pages_layouts##inst,					\
		.pages_layouts_size = ARRAY_SIZE(sam_flash_pages_layouts##inst),		\
	};											\
												\
	static struct sam_flash_data sam_flash_data##inst;					\
												\
	DEVICE_DT_INST_DEFINE(inst, sam_flash_init, NULL, &sam_flash_data##inst,		\
			      &sam_flash_config##inst, POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY,	\
			      &sam_flash_api);

SAM_FLASH_CONTROLLER(0)
