/*
 * Copyright (c) 2022 BrainCo Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "flash_gd32.h"

#include <zephyr/logging/log.h>
#include <zephyr/kernel.h>
#include <gd32_fmc.h>

LOG_MODULE_DECLARE(flash_gd32);

#define GD32_NV_FLASH_V3_NODE		DT_INST(0, gd_gd32_nv_flash_v3)
#define GD32_NV_FLASH_V3_TIMEOUT	DT_PROP(GD32_NV_FLASH_V3_NODE, max_erase_time_ms)

/**
 * @brief GD32 FMC v3 flash memory layout for GD32F4xx series.
 */
#if defined(CONFIG_FLASH_PAGE_LAYOUT) && \
	defined(CONFIG_SOC_SERIES_GD32F4XX)
#if (PRE_KB(512) == SOC_NV_FLASH_SIZE)
static const struct flash_pages_layout gd32_fmc_v3_layout[] = {
	{.pages_count = 4, .pages_size = KB(16)},
	{.pages_count = 1, .pages_size = KB(64)},
	{.pages_count = 3, .pages_size = KB(128)},
};
#elif (PRE_KB(1024) == SOC_NV_FLASH_SIZE)
static const struct flash_pages_layout gd32_fmc_v3_layout[] = {
	{.pages_count = 4, .pages_size = KB(16)},
	{.pages_count = 1, .pages_size = KB(64)},
	{.pages_count = 7, .pages_size = KB(128)},
};
#elif (PRE_KB(2048) == SOC_NV_FLASH_SIZE)
static const struct flash_pages_layout gd32_fmc_v3_layout[] = {
	{.pages_count = 4, .pages_size = KB(16)},
	{.pages_count = 1, .pages_size = KB(64)},
	{.pages_count = 7, .pages_size = KB(128)},
	{.pages_count = 4, .pages_size = KB(16)},
	{.pages_count = 1, .pages_size = KB(64)},
	{.pages_count = 7, .pages_size = KB(128)},
};
#elif (PRE_KB(3072) == SOC_NV_FLASH_SIZE)
static const struct flash_pages_layout gd32_fmc_v3_layout[] = {
	{.pages_count = 4, .pages_size = KB(16)},
	{.pages_count = 1, .pages_size = KB(64)},
	{.pages_count = 7, .pages_size = KB(128)},
	{.pages_count = 4, .pages_size = KB(16)},
	{.pages_count = 1, .pages_size = KB(64)},
	{.pages_count = 7, .pages_size = KB(128)},
	{.pages_count = 4, .pages_size = KB(256)},
};
#else
#error "Unknown FMC layout for GD32F4xx series."
#endif
#endif /* CONFIG_FLASH_PAGE_LAYOUT */

#define gd32_fmc_v3_WRITE_ERR (FMC_STAT_PGMERR | FMC_STAT_PGSERR | FMC_STAT_WPERR)
#define gd32_fmc_v3_ERASE_ERR FMC_STAT_OPERR

/* SN bits in FMC_CTL are not continue values, use table below to map them. */
static uint8_t gd32_fmc_v3_sectors[] = {
	0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U,
	16U, 17U, 18U, 19U, 20U, 21U, 22U, 23U, 24U, 25U, 26U, 27U,
	12U, 13U, 14U, 15U
};

static inline void gd32_fmc_v3_unlock(void)
{
	FMC_KEY = UNLOCK_KEY0;
	FMC_KEY = UNLOCK_KEY1;
}

static inline void gd32_fmc_v3_lock(void)
{
	FMC_CTL |= FMC_CTL_LK;
}

static int gd32_fmc_v3_wait_idle(void)
{
	const int64_t expired_time = k_uptime_get() + GD32_NV_FLASH_V3_TIMEOUT;

	while (FMC_STAT & FMC_STAT_BUSY) {
		if (k_uptime_get() > expired_time) {
			return -ETIMEDOUT;
		}
	}

	return 0;
}

bool flash_gd32_valid_range(off_t offset, uint32_t len, bool write)
{
	const struct flash_pages_layout *page_layout;
	uint32_t cur = 0U, next = 0U;

	if ((offset > SOC_NV_FLASH_SIZE) ||
	    ((offset + len) > SOC_NV_FLASH_SIZE)) {
		return false;
	}

	if (write) {
		/* Check offset and len aligned to write-block-size. */
		if ((offset % sizeof(flash_prg_t)) ||
		    (len % sizeof(flash_prg_t))) {
			return false;
		}

	} else {
		for (size_t i = 0; i < ARRAY_SIZE(gd32_fmc_v3_layout); i++) {
			page_layout = &gd32_fmc_v3_layout[i];

			for (size_t j = 0; j < page_layout->pages_count; j++) {
				cur = next;

				next += page_layout->pages_size;

				/* Check bad offset. */
				if ((offset > cur) && (offset < next)) {
					return false;
				}

				/* Check bad len. */
				if (((offset + len) > cur) &&
				    ((offset + len) < next)) {
					return false;
				}

				if ((offset + len) == next) {
					return true;
				}
			}
		}
	}

	return true;
}

int flash_gd32_write_range(off_t offset, const void *data, size_t len)
{
	flash_prg_t *prg_flash = (flash_prg_t *)((uint8_t *)SOC_NV_FLASH_ADDR + offset);
	flash_prg_t *prg_data = (flash_prg_t *)data;
	int ret = 0;

	gd32_fmc_v3_unlock();

	if (FMC_STAT & FMC_STAT_BUSY) {
		return -EBUSY;
	}

	FMC_CTL |= FMC_CTL_PG;

	FMC_CTL &= ~FMC_CTL_PSZ;
	FMC_CTL |= CTL_PSZ(sizeof(flash_prg_t) - 1);

	for (size_t i = 0U; i < (len / sizeof(flash_prg_t)); i++) {
		*prg_flash++ = *prg_data++;
	}

	ret = gd32_fmc_v3_wait_idle();
	if (ret < 0) {
		goto expired_out;
	}

	if (FMC_STAT & gd32_fmc_v3_WRITE_ERR) {
		ret = -EIO;
		FMC_STAT |= gd32_fmc_v3_WRITE_ERR;
		LOG_ERR("FMC programming failed");
	}

expired_out:
	FMC_CTL &= ~FMC_CTL_PG;

	gd32_fmc_v3_lock();

	return ret;
}

static int gd32_fmc_v3_sector_erase(uint8_t sector)
{
	int ret = 0;

	gd32_fmc_v3_unlock();

	if (FMC_STAT & FMC_STAT_BUSY) {
		return -EBUSY;
	}

	FMC_CTL |= FMC_CTL_SER;

	FMC_CTL &= ~FMC_CTL_SN;
	FMC_CTL |= CTL_SN(sector);

	FMC_CTL |= FMC_CTL_START;

	ret = gd32_fmc_v3_wait_idle();
	if (ret < 0) {
		goto expired_out;
	}

	if (FMC_STAT & gd32_fmc_v3_ERASE_ERR) {
		ret = -EIO;
		FMC_STAT |= gd32_fmc_v3_ERASE_ERR;
		LOG_ERR("FMC sector %u erase failed", sector);
	}

expired_out:
	FMC_CTL &= ~FMC_CTL_SER;

	gd32_fmc_v3_lock();

	return ret;
}

int flash_gd32_erase_block(off_t offset, size_t size)
{
	const struct flash_pages_layout *page_layout;
	uint32_t erase_offset = 0U;
	uint8_t counter = 0U;
	int ret = 0;

	for (size_t i = 0; i < ARRAY_SIZE(gd32_fmc_v3_layout); i++) {
		page_layout = &gd32_fmc_v3_layout[i];

		for (size_t j = 0; j < page_layout->pages_count; j++) {
			if (erase_offset < offset) {
				counter++;
				erase_offset += page_layout->pages_size;

				continue;
			}

			uint8_t sector = gd32_fmc_v3_sectors[counter++];

			ret = gd32_fmc_v3_sector_erase(sector);
			if (ret < 0) {
				return ret;
			}

			erase_offset += page_layout->pages_size;

			if (erase_offset - offset >= size) {
				return 0;
			}
		}
	}

	return 0;
}

#ifdef CONFIG_FLASH_PAGE_LAYOUT
void flash_gd32_pages_layout(const struct device *dev,
			     const struct flash_pages_layout **layout,
			     size_t *layout_size)
{
	ARG_UNUSED(dev);

	*layout = gd32_fmc_v3_layout;
	*layout_size = ARRAY_SIZE(gd32_fmc_v3_layout);
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
