/*
 * Copyright (c) 2023 Ambiq Micro Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ambiq_flash_controller

#include <zephyr/kernel.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/logging/log.h>

#include <am_mcu_apollo.h>

LOG_MODULE_REGISTER(flash_ambiq, CONFIG_FLASH_LOG_LEVEL);

#define SOC_NV_FLASH_NODE      DT_INST(0, soc_nv_flash)
#define SOC_NV_FLASH_ADDR      DT_REG_ADDR(SOC_NV_FLASH_NODE)
#define SOC_NV_FLASH_SIZE      DT_REG_SIZE(SOC_NV_FLASH_NODE)
#define MIN_WRITE_SIZE         16
#define FLASH_WRITE_BLOCK_SIZE MAX(DT_PROP(SOC_NV_FLASH_NODE, write_block_size), MIN_WRITE_SIZE)
#define FLASH_ERASE_BLOCK_SIZE DT_PROP(SOC_NV_FLASH_NODE, erase_block_size)

BUILD_ASSERT((FLASH_WRITE_BLOCK_SIZE & (MIN_WRITE_SIZE - 1)) == 0,
	     "The flash write block size must be a multiple of 16!");

#define FLASH_ERASE_BYTE 0xFF
#define FLASH_ERASE_WORD                                                                           \
	(((uint32_t)(FLASH_ERASE_BYTE << 24)) | ((uint32_t)(FLASH_ERASE_BYTE << 16)) |             \
	 ((uint32_t)(FLASH_ERASE_BYTE << 8)) | ((uint32_t)FLASH_ERASE_BYTE))

#if defined(CONFIG_MULTITHREADING)
static struct k_sem flash_ambiq_sem;
#define FLASH_SEM_INIT() k_sem_init(&flash_ambiq_sem, 1, 1)
#define FLASH_SEM_TAKE() k_sem_take(&flash_ambiq_sem, K_FOREVER)
#define FLASH_SEM_GIVE() k_sem_give(&flash_ambiq_sem)
#else
#define FLASH_SEM_INIT()
#define FLASH_SEM_TAKE()
#define FLASH_SEM_GIVE()
#endif /* CONFIG_MULTITHREADING */

static const struct flash_parameters flash_ambiq_parameters = {
	.write_block_size = FLASH_WRITE_BLOCK_SIZE,
	.erase_value = FLASH_ERASE_BYTE,
};

static bool flash_ambiq_valid_range(off_t offset, size_t len)
{
	if ((offset < 0) || offset >= SOC_NV_FLASH_SIZE || (SOC_NV_FLASH_SIZE - offset) < len) {
		return false;
	}

	return true;
}

static int flash_ambiq_read(const struct device *dev, off_t offset, void *data, size_t len)
{
	ARG_UNUSED(dev);

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

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

	memcpy(data, (uint8_t *)(SOC_NV_FLASH_ADDR + offset), len);

	return 0;
}

static int flash_ambiq_write(const struct device *dev, off_t offset, const void *data, size_t len)
{
	ARG_UNUSED(dev);

	int ret = 0;
	uint32_t critical = 0;
	uint32_t aligned[FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t)] = {0};
	uint32_t *src = (uint32_t *)data;

	/* write address must be block size aligned and the write length must be multiple of block
	 * size.
	 */
	if (!flash_ambiq_valid_range(offset, len) ||
	    ((uint32_t)offset & (FLASH_WRITE_BLOCK_SIZE - 1)) ||
	    (len & (FLASH_WRITE_BLOCK_SIZE - 1))) {
		return -EINVAL;
	}

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

	FLASH_SEM_TAKE();

	critical = am_hal_interrupt_master_disable();
	for (int i = 0; i < len / FLASH_WRITE_BLOCK_SIZE; i++) {
		for (int j = 0; j < FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t); j++) {
			/* Make sure the source data is 4-byte aligned. */
			aligned[j] = UNALIGNED_GET((uint32_t *)src);
			src++;
		}
		ret = am_hal_mram_main_program(
			AM_HAL_MRAM_PROGRAM_KEY, aligned,
			(uint32_t *)(SOC_NV_FLASH_ADDR + offset + i * FLASH_WRITE_BLOCK_SIZE),
			FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t));
		if (ret) {
			break;
		}
	}
	am_hal_interrupt_master_set(critical);

	FLASH_SEM_GIVE();

	return ret;
}

static int flash_ambiq_erase(const struct device *dev, off_t offset, size_t len)
{
	ARG_UNUSED(dev);

	int ret = 0;

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

	/* The erase address and length alignment check will be done in HAL.*/

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

	FLASH_SEM_TAKE();

	ret = am_hal_mram_main_fill(AM_HAL_MRAM_PROGRAM_KEY, FLASH_ERASE_WORD,
				    (uint32_t *)(SOC_NV_FLASH_ADDR + offset),
				    (len / sizeof(uint32_t)));

	FLASH_SEM_GIVE();

	return ret;
}

static const struct flash_parameters *flash_ambiq_get_parameters(const struct device *dev)
{
	ARG_UNUSED(dev);

	return &flash_ambiq_parameters;
}

#if CONFIG_FLASH_PAGE_LAYOUT
static const struct flash_pages_layout pages_layout = {
	.pages_count = SOC_NV_FLASH_SIZE / FLASH_ERASE_BLOCK_SIZE,
	.pages_size = FLASH_ERASE_BLOCK_SIZE,
};

static void flash_ambiq_pages_layout(const struct device *dev,
				     const struct flash_pages_layout **layout, size_t *layout_size)
{
	ARG_UNUSED(dev);

	*layout = &pages_layout;
	*layout_size = 1;
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */

static const struct flash_driver_api flash_ambiq_driver_api = {
	.read = flash_ambiq_read,
	.write = flash_ambiq_write,
	.erase = flash_ambiq_erase,
	.get_parameters = flash_ambiq_get_parameters,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
	.page_layout = flash_ambiq_pages_layout,
#endif
};

static int flash_ambiq_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	FLASH_SEM_INIT();

	return 0;
}

DEVICE_DT_INST_DEFINE(0, flash_ambiq_init, NULL, NULL, NULL, POST_KERNEL,
		      CONFIG_FLASH_INIT_PRIORITY, &flash_ambiq_driver_api);
