/*
 * Copyright (c) 2017-2018 Nordic Semiconductor ASA
 * Copyright (c) 2016 Linaro Limited
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>

#include <kernel.h>
#include <device.h>
#include <init.h>
#include <soc.h>
#include <flash.h>
#include <string.h>

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
#include <misc/__assert.h>
#include <bluetooth/hci.h>
#include "controller/hal/nrf5/ticker.h"
#include "controller/ticker/ticker.h"
#include "controller/include/ll.h"

#define FLASH_SLOT     FLASH_PAGE_ERASE_MAX_TIME_US
#define FLASH_INTERVAL FLASH_SLOT
#define FLASH_RADIO_ABORT_DELAY_US 500
#define FLASH_TIMEOUT_MS ((FLASH_PAGE_ERASE_MAX_TIME_US)\
			* (FLASH_PAGE_MAX_CNT) / 1000)
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */

#define FLASH_OP_DONE    (0) /* 0 for compliance with the driver API. */
#define FLASH_OP_ONGOING (-1)

struct erase_context {
	u32_t addr; /* Address off the 1st page to erase */
	u32_t size; /* Size off area to erase [B] */
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
	u8_t enable_time_limit; /* execution limited to timeslot */
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
}; /*< Context type for f. @ref erase_op */

struct write_context {
	u32_t data_addr;
	u32_t flash_addr; /* Address off the 1st page to erase */
	u32_t len;        /* Size off data to write [B] */
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
	u8_t  enable_time_limit; /* execution limited to timeslot*/
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
}; /*< Context type for f. @ref write_op */

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
typedef int (*flash_op_handler_t) (void *context);

struct flash_op_desc {
	flash_op_handler_t handler;
	void *context; /* [in,out] */
	int result;
};

/* semaphore for synchronization of flash operations */
static struct k_sem sem_sync;

static int write_op(void *context); /* instance of flash_op_handler_t */
static int write_in_timeslice(off_t addr, const void *data, size_t len);

static int erase_op(void *context); /* instance of flash_op_handler_t */
static int erase_in_timeslice(u32_t addr, u32_t size);
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */

#if defined(CONFIG_MULTITHREADING)
/* semaphore for locking flash resources (tickers) */
static struct k_sem sem_lock;
#define SYNC_INIT() k_sem_init(&sem_lock, 1, 1)
#define SYNC_LOCK() k_sem_take(&sem_lock, K_FOREVER)
#define SYNC_UNLOCK() k_sem_give(&sem_lock)
#else
#define SYNC_INIT()
#define SYNC_LOCK()
#define SYNC_UNLOCK()
#endif

static int write(off_t addr, const void *data, size_t len);
static int erase(u32_t addr, u32_t size);

static inline bool is_aligned_32(u32_t data)
{
	return (data & 0x3) ? false : true;
}

static inline bool is_addr_valid(off_t addr, size_t len)
{
	if (addr + len > NRF_FICR->CODEPAGESIZE * NRF_FICR->CODESIZE ||
			addr < 0) {
		return false;
	}

	return true;
}

static void nvmc_wait_ready(void)
{
	while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
		;
	}
}

static int flash_nrf_read(struct device *dev, off_t addr,
			    void *data, size_t len)
{
	if (!is_addr_valid(addr, len)) {
		return -EINVAL;
	}

	if (!len) {
		return 0;
	}

	memcpy(data, (void *)addr, len);

	return 0;
}

static int flash_nrf_write(struct device *dev, off_t addr,
			     const void *data, size_t len)
{
	int ret;

	if (!is_addr_valid(addr, len)) {
		return -EINVAL;
	}

	if (!len) {
		return 0;
	}

	SYNC_LOCK();

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
	if (ticker_is_initialized(0)) {
		ret = write_in_timeslice(addr, data, len);
	} else
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
	{
		ret = write(addr, data, len);
	}

	SYNC_UNLOCK();

	return ret;
}

static int flash_nrf_erase(struct device *dev, off_t addr, size_t size)
{
	u32_t pg_size = NRF_FICR->CODEPAGESIZE;
	u32_t n_pages = size / pg_size;
	int ret;

	/* Erase can only be done per page */
	if (((addr % pg_size) != 0) || ((size % pg_size) != 0)) {
		return -EINVAL;
	}

	if (!is_addr_valid(addr, size)) {
		return -EINVAL;
	}

	if (!n_pages) {
		return 0;
	}

	SYNC_LOCK();

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
	if (ticker_is_initialized(0)) {
		ret = erase_in_timeslice(addr, size);
	} else
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
	{
		ret = erase(addr, size);
	}

	SYNC_UNLOCK();

	return ret;
}

static int flash_nrf_write_protection(struct device *dev, bool enable)
{
	SYNC_LOCK();

	if (enable) {
		NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
	} else {
		NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
	}
	nvmc_wait_ready();

	SYNC_UNLOCK();

	return 0;
}

#if defined(CONFIG_FLASH_PAGE_LAYOUT)
static struct flash_pages_layout dev_layout;

static void flash_nrf_pages_layout(struct device *dev,
				     const struct flash_pages_layout **layout,
				     size_t *layout_size)
{
	*layout = &dev_layout;
	*layout_size = 1;
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */

static const struct flash_driver_api flash_nrf_api = {
	.read = flash_nrf_read,
	.write = flash_nrf_write,
	.erase = flash_nrf_erase,
	.write_protection = flash_nrf_write_protection,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
	.page_layout = flash_nrf_pages_layout,
#endif
	.write_block_size = 1,
};

static int nrf_flash_init(struct device *dev)
{
	dev->driver_api = &flash_nrf_api;

	SYNC_INIT();

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
	k_sem_init(&sem_sync, 0, 1);
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */

#if defined(CONFIG_FLASH_PAGE_LAYOUT)
	dev_layout.pages_count = NRF_FICR->CODESIZE;
	dev_layout.pages_size = NRF_FICR->CODEPAGESIZE;
#endif

	return 0;
}

DEVICE_INIT(nrf_flash, FLASH_DEV_NAME, nrf_flash_init,
	     NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)

static void time_slot_callback_work(u32_t ticks_at_expire, u32_t remainder,
				    u16_t lazy, void *context)
{
	struct flash_op_desc *op_desc;
	u8_t instance_index;
	u8_t ticker_id;
	int result;

	__ASSERT(ll_radio_state_is_idle(),
		 "Radio is on during flash operation.\n");

	op_desc = context;
	if (op_desc->handler(op_desc->context) == FLASH_OP_DONE) {
		ll_timeslice_ticker_id_get(&instance_index, &ticker_id);

		/* Stop the time slot ticker */
		result = ticker_stop(instance_index,
				     0,
				     ticker_id,
				     NULL,
				     NULL);

		if (result != TICKER_STATUS_SUCCESS &&
		    result != TICKER_STATUS_BUSY) {
			__ASSERT(0, "Failed to stop ticker.\n");
		}

		((struct flash_op_desc *)context)->result = 0;

		/* notify thread that data is available */
		k_sem_give(&sem_sync);
	}
}

static void time_slot_callback_helper(u32_t ticks_at_expire, u32_t remainder,
		u16_t lazy, void *context)
{
	u8_t instance_index;
	u8_t ticker_id;
	int err;

	ll_radio_state_abort();

	ll_timeslice_ticker_id_get(&instance_index, &ticker_id);

	/* start a secondary one-shot ticker after ~ 500 us, */
	/* this will let any radio role to gracefully release the Radio h/w */

	err = ticker_start(instance_index, /* Radio instance ticker */
			   0, /* user_id */
			   0, /* ticker_id */
			   ticks_at_expire, /* current tick */
			   HAL_TICKER_US_TO_TICKS(FLASH_RADIO_ABORT_DELAY_US),
			   0, /* periodic (on-shot) */
			   0, /* per. remaind. (on-shot) */
			   0, /* lazy, voluntary skips */
			   0,
			   time_slot_callback_work, /* handler for executing */
						    /* the flash operation */
			   context, /* the context for the flash operation */
			   NULL, /* no op callback */
			   NULL);

	if (err != TICKER_STATUS_SUCCESS && err != TICKER_STATUS_BUSY) {
		((struct flash_op_desc *)context)->result = -ECANCELED;

		/* abort flash timeslots */
		err = ticker_stop(instance_index, 0, ticker_id, NULL, NULL);
		if (err != TICKER_STATUS_SUCCESS &&
		    err != TICKER_STATUS_BUSY) {
			__ASSERT(0, "Failed to stop ticker.\n");
		}

		/* notify thread that data is available */
		k_sem_give(&sem_sync);
	}
}

static int work_in_time_slice(struct flash_op_desc *p_flash_op_desc)
{
	u8_t instance_index;
	u8_t ticker_id;
	int result;
	u32_t err;

	ll_timeslice_ticker_id_get(&instance_index, &ticker_id);

	err = ticker_start(instance_index,
			   3, /* user id for thread mode */
			      /* (MAYFLY_CALL_ID_PROGRAM) */
			   ticker_id, /* flash ticker id */
			   ticker_ticks_now_get(), /* current tick */
			   0, /* first int. immediately */
			   HAL_TICKER_US_TO_TICKS(FLASH_INTERVAL), /* period */
			   HAL_TICKER_REMAINDER(FLASH_INTERVAL), /* per. rem.*/
			   0, /* lazy, voluntary skips */
			   HAL_TICKER_US_TO_TICKS(FLASH_SLOT),
			   time_slot_callback_helper,
			   p_flash_op_desc,
			   NULL, /* no op callback */
			   NULL);

	if (err != TICKER_STATUS_SUCCESS && err != TICKER_STATUS_BUSY) {
		result = -ECANCELED;
	} else if (k_sem_take(&sem_sync, K_MSEC(FLASH_TIMEOUT_MS)) != 0) {
		/* wait for operation's complete overrun*/
		result = -ETIMEDOUT;
	} else {
		result = p_flash_op_desc->result;
	}

	return result;
}

static int erase_in_timeslice(u32_t addr, u32_t size)
{
	struct erase_context context = {
		.addr = addr,
		.size = size,
		.enable_time_limit = 1 /* enable time limit */
	};

	struct flash_op_desc flash_op_desc = {
		.handler = erase_op,
		.context = &context
	};

	return work_in_time_slice(&flash_op_desc);
}

static int write_in_timeslice(off_t addr, const void *data, size_t len)
{
	struct write_context context = {
		.data_addr = (u32_t) data,
		.flash_addr = addr,
		.len = len,
		.enable_time_limit = 1 /* enable time limit */
	};

	struct flash_op_desc flash_op_desc = {
		.handler = write_op,
		.context = &context
	};

	return  work_in_time_slice(&flash_op_desc);
}

#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */

static int erase_op(void *context)
{
	u32_t prev_nvmc_cfg = NRF_NVMC->CONFIG;
	u32_t pg_size = NRF_FICR->CODEPAGESIZE;
	struct erase_context *e_ctx = context;

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
	u32_t ticks_begin = 0;
	u32_t ticks_diff;
	u32_t i = 0;

	if (e_ctx->enable_time_limit) {
		ticks_begin = ticker_ticks_now_get();
	}
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */

	/* Erase uses a specific configuration register */
	NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos;
	nvmc_wait_ready();

	do {
		NRF_NVMC->ERASEPAGE = e_ctx->addr;
		nvmc_wait_ready();

		e_ctx->size -= pg_size;
		e_ctx->addr += pg_size;

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
		i++;

		if (e_ctx->enable_time_limit) {
			ticks_diff =
				ticker_ticks_diff_get(ticker_ticks_now_get(),
						      ticks_begin);
			if (ticks_diff + ticks_diff/i >
			    HAL_TICKER_US_TO_TICKS(FLASH_SLOT)) {
				break;
			}
		}
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */

	} while (e_ctx->size > 0);

	NRF_NVMC->CONFIG = prev_nvmc_cfg;
	nvmc_wait_ready();

	return (e_ctx->size > 0) ? FLASH_OP_ONGOING : FLASH_OP_DONE;
}

static void shift_write_context(u32_t shift, struct write_context *w_ctx)
{
	w_ctx->flash_addr += shift;
	w_ctx->data_addr += shift;
	w_ctx->len -= shift;
}

static int write_op(void *context)
{
	struct write_context *w_ctx = context;
	u32_t addr_word;
	u32_t tmp_word;
	u32_t count;

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
	u32_t ticks_begin = 0;
	u32_t ticks_diff;
	u32_t i = 1;

	if (w_ctx->enable_time_limit) {
		ticks_begin = ticker_ticks_now_get();
	}
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */

	/* Start with a word-aligned address and handle the offset */
	addr_word = (u32_t)w_ctx->flash_addr & ~0x3;

	/* If not aligned, read first word, update and write it back */
	if (!is_aligned_32(w_ctx->flash_addr)) {
		tmp_word = *(u32_t *)(addr_word);

		count = sizeof(u32_t) - (w_ctx->flash_addr & 0x3);
		if (count > w_ctx->len) {
			count = w_ctx->len;
		}

		memcpy((u8_t *)&tmp_word + (w_ctx->flash_addr & 0x3),
		       (void *)w_ctx->data_addr,
		       count);
		nvmc_wait_ready();
		*(u32_t *)addr_word = tmp_word;

		shift_write_context(count, w_ctx);

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
		if (w_ctx->enable_time_limit) {
			ticks_diff =
				ticker_ticks_diff_get(ticker_ticks_now_get(),
						      ticks_begin);
			if (2 * ticks_diff >
			    HAL_TICKER_US_TO_TICKS(FLASH_SLOT)) {
				nvmc_wait_ready();
				return FLASH_OP_ONGOING;
			}
		}
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
	}

	/* Write all the 4-byte aligned data */
	while (w_ctx->len >= sizeof(u32_t)) {
		nvmc_wait_ready();
		*(u32_t *)w_ctx->flash_addr =
				UNALIGNED_GET((u32_t *)w_ctx->data_addr);

		shift_write_context(sizeof(u32_t), w_ctx);

#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
		i++;

		if (w_ctx->enable_time_limit) {
			ticks_diff =
				ticker_ticks_diff_get(ticker_ticks_now_get(),
						      ticks_begin);
			if (ticks_diff + ticks_diff/i >
			    HAL_TICKER_US_TO_TICKS(FLASH_SLOT)) {
				nvmc_wait_ready();
				return FLASH_OP_ONGOING;
			}
		}
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
	}

	/* Write remaining data */
	if (w_ctx->len) {
		tmp_word = *(u32_t *)(w_ctx->flash_addr);
		memcpy((u8_t *)&tmp_word, (void *)w_ctx->data_addr, w_ctx->len);
		nvmc_wait_ready();
		*(u32_t *)w_ctx->flash_addr = tmp_word;

		shift_write_context(w_ctx->len, w_ctx);
	}

	nvmc_wait_ready();

	return FLASH_OP_DONE;
}

static int erase(u32_t addr, u32_t size)
{
	struct erase_context context = {
		.addr = addr,
		.size = size,
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
		.enable_time_limit = 0 /* disable time limit */
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
	};

	return	erase_op(&context);
}

static int write(off_t addr, const void *data, size_t len)
{
	struct write_context context = {
		.data_addr = (u32_t) data,
		.flash_addr = addr,
		.len = len,
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
		.enable_time_limit = 0 /* disable time limit */
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
	};

	return write_op(&context);
}
