/*
 * Copyright (c) 2018 Google LLC.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(flash_sam0);

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

/*
 * Zephyr and the SAM0 series use different and conflicting names for
 * the erasable units and programmable units:
 *
 * The erase unit is a row, which is a 'page' in Zephyr terms.
 * The program unit is a page, which is a 'write_block' in Zephyr.
 *
 * This file uses the SAM0 names internally and the Zephyr names in
 * any error messages.
 */

/*
 * Number of lock regions.  The number is fixed and the region size
 * grows with the flash size.
 */
#define LOCK_REGIONS 16
#define LOCK_REGION_SIZE (FLASH_SIZE / LOCK_REGIONS)

#define PAGES_PER_ROW 4
#define ROW_SIZE (FLASH_PAGE_SIZE * PAGES_PER_ROW)

#define FLASH_MEM(_a) ((u32_t *)((u8_t *)((_a) + CONFIG_FLASH_BASE_ADDRESS)))

struct flash_sam0_data {
#if CONFIG_SOC_FLASH_SAM0_EMULATE_BYTE_PAGES
	u8_t buf[ROW_SIZE];
	off_t offset;
#endif

	struct k_sem sem;
};

#if CONFIG_FLASH_PAGE_LAYOUT
static const struct flash_pages_layout flash_sam0_pages_layout = {
	.pages_count = CONFIG_FLASH_SIZE * 1024 / ROW_SIZE,
	.pages_size = ROW_SIZE,
};
#endif

static inline void flash_sam0_sem_take(struct device *dev)
{
	struct flash_sam0_data *ctx = dev->driver_data;

	k_sem_take(&ctx->sem, K_FOREVER);
}

static inline void flash_sam0_sem_give(struct device *dev)
{
	struct flash_sam0_data *ctx = dev->driver_data;

	k_sem_give(&ctx->sem);
}

static int flash_sam0_valid_range(off_t offset, size_t len)
{
	if (offset < 0) {
		LOG_WRN("%x: before start of flash", offset);
		return -EINVAL;
	}
	if ((offset + len) > CONFIG_FLASH_SIZE * 1024) {
		LOG_WRN("%x: ends past the end of flash", offset);
		return -EINVAL;
	}

	return 0;
}

static void flash_sam0_wait_ready(void)
{
	while (NVMCTRL->INTFLAG.bit.READY == 0) {
	}
}

static int flash_sam0_check_status(off_t offset)
{
	NVMCTRL_STATUS_Type status;

	flash_sam0_wait_ready();

	status = NVMCTRL->STATUS;
	/* Clear any flags */
	NVMCTRL->STATUS = status;

	if (status.bit.PROGE) {
		LOG_ERR("programming error at 0x%x", offset);
		return -EIO;
	} else if (status.bit.LOCKE) {
		LOG_ERR("lock error at 0x%x", offset);
		return -EROFS;
	} else if (status.bit.NVME) {
		LOG_ERR("NVM error at 0x%x", offset);
		return -EIO;
	}

	return 0;
}

static int flash_sam0_write_page(struct device *dev, off_t offset,
				 const void *data)
{
	const u32_t *src = data;
	const u32_t *end = src + FLASH_PAGE_SIZE / sizeof(*src);
	u32_t *dst = FLASH_MEM(offset);
	int err;

	NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_PBC | NVMCTRL_CTRLA_CMDEX_KEY;
	flash_sam0_wait_ready();

	/* Ensure writes happen 32 bits at a time. */
	for (; src != end; src++, dst++) {
		*dst = *src;
	}

	NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_WP | NVMCTRL_CTRLA_CMDEX_KEY;

	err = flash_sam0_check_status(offset);
	if (err != 0) {
		return err;
	}

	if (memcmp(data, FLASH_MEM(offset), FLASH_PAGE_SIZE) != 0) {
		LOG_ERR("verify error at offset 0x%x", offset);
		return -EIO;
	}

	return 0;
}

static int flash_sam0_erase_row(struct device *dev, off_t offset)
{
	*FLASH_MEM(offset) = 0U;
	NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_ER | NVMCTRL_CTRLA_CMDEX_KEY;

	return flash_sam0_check_status(offset);
}

#if CONFIG_SOC_FLASH_SAM0_EMULATE_BYTE_PAGES

static int flash_sam0_commit(struct device *dev)
{
	struct flash_sam0_data *ctx = dev->driver_data;
	int err;
	int page;
	off_t offset = ctx->offset;

	ctx->offset = 0;

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

	err = flash_sam0_erase_row(dev, offset);
	if (err != 0) {
		return err;
	}

	for (page = 0; page < PAGES_PER_ROW; page++) {
		err = flash_sam0_write_page(
			dev, offset + page * FLASH_PAGE_SIZE,
			&ctx->buf[page * FLASH_PAGE_SIZE]);
		if (err != 0) {
			return err;
		}
	}

	return 0;
}

static int flash_sam0_write(struct device *dev, off_t offset,
			    const void *data, size_t len)
{
	struct flash_sam0_data *ctx = dev->driver_data;
	const u8_t *pdata = data;
	off_t addr;
	int err;

	LOG_DBG("%x: len %u", offset, len);

	err = flash_sam0_valid_range(offset, len);
	if (err != 0) {
		return err;
	}

	flash_sam0_sem_take(dev);

	for (addr = offset; addr < offset + len; addr++) {
		off_t base = addr & ~(ROW_SIZE - 1);

		if (base != ctx->offset) {
			/* Started a new row.  Flush any pending ones. */
			flash_sam0_commit(dev);
			memcpy(ctx->buf, (void *)base, sizeof(ctx->buf));
			ctx->offset = base;
		}

		ctx->buf[addr % ROW_SIZE] = *pdata++;
	}

	flash_sam0_commit(dev);
	flash_sam0_sem_give(dev);

	return 0;
}

#else /* CONFIG_SOC_FLASH_SAM0_EMULATE_BYTE_PAGES */

static int flash_sam0_write(struct device *dev, off_t offset,
			    const void *data, size_t len)
{
	const u8_t *pdata = data;
	int err;
	size_t idx;

	err = flash_sam0_valid_range(offset, len);
	if (err != 0) {
		return err;
	}

	if ((offset % FLASH_PAGE_SIZE) != 0) {
		LOG_WRN("%x: not on a write block boundrary", offset);
		return -EINVAL;
	}

	if ((len % FLASH_PAGE_SIZE) != 0) {
		LOG_WRN("%x: not a integer number of write blocks", len);
		return -EINVAL;
	}

	flash_sam0_sem_take(dev);

	for (idx = 0; idx < len; idx += FLASH_PAGE_SIZE) {
		err = flash_sam0_write_page(dev, offset + idx, &pdata[idx]);
		if (err != 0) {
			goto done;
		}
	}

done:
	flash_sam0_sem_give(dev);

	return err;
}

#endif

static int flash_sam0_read(struct device *dev, off_t offset, void *data,
			   size_t len)
{
	int err;

	err = flash_sam0_valid_range(offset, len);
	if (err != 0) {
		return err;
	}

	memcpy(data, (u8_t *)CONFIG_FLASH_BASE_ADDRESS + offset, len);

	return 0;
}

static int flash_sam0_erase(struct device *dev, off_t offset, size_t size)
{
	int err;

	err = flash_sam0_valid_range(offset, ROW_SIZE);
	if (err != 0) {
		return err;
	}

	if ((offset % ROW_SIZE) != 0) {
		LOG_WRN("%x: not on a page boundrary", offset);
		return -EINVAL;
	}

	if ((size % ROW_SIZE) != 0) {
		LOG_WRN("%x: not a integer number of pages", size);
		return -EINVAL;
	}

	flash_sam0_sem_take(dev);

	for (size_t addr = offset; addr < offset + size; addr += ROW_SIZE) {
		err = flash_sam0_erase_row(dev, addr);
		if (err != 0) {
			goto done;
		}
	}

done:
	flash_sam0_sem_give(dev);

	return err;
}

static int flash_sam0_write_protection(struct device *dev, bool enable)
{
	off_t offset;
	int err;

	flash_sam0_sem_take(dev);

	for (offset = 0; offset < CONFIG_FLASH_SIZE * 1024;
	     offset += LOCK_REGION_SIZE) {
		*FLASH_MEM(offset) = 0U;

		if (enable) {
			NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_LR |
					     NVMCTRL_CTRLA_CMDEX_KEY;
		} else {
			NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_UR |
					     NVMCTRL_CTRLA_CMDEX_KEY;
		}
		err = flash_sam0_check_status(offset);
		if (err != 0) {
			goto done;
		}
	}

done:
	flash_sam0_sem_give(dev);

	return err;
}

#if CONFIG_FLASH_PAGE_LAYOUT
void flash_sam0_page_layout(struct device *dev,
			    const struct flash_pages_layout **layout,
			    size_t *layout_size)
{
	*layout = &flash_sam0_pages_layout;
	*layout_size = 1;
}
#endif

static int flash_sam0_init(struct device *dev)
{
	struct flash_sam0_data *ctx = dev->driver_data;

	k_sem_init(&ctx->sem, 1, 1);

	/* Ensure the clock is on. */
	PM->APBBMASK.bit.NVMCTRL_ = 1;
	/* Require an explicit write command */
	NVMCTRL->CTRLB.bit.MANW = 1;

	return flash_sam0_write_protection(dev, false);
}

static const struct flash_driver_api flash_sam0_api = {
	.write_protection = flash_sam0_write_protection,
	.erase = flash_sam0_erase,
	.write = flash_sam0_write,
	.read = flash_sam0_read,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
	.page_layout = flash_sam0_page_layout,
#endif
	.write_block_size = FLASH_PAGE_SIZE,
};

static struct flash_sam0_data flash_sam0_data_0;

DEVICE_AND_API_INIT(flash_sam0, DT_FLASH_DEV_NAME,
		    flash_sam0_init, &flash_sam0_data_0, NULL, POST_KERNEL,
		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &flash_sam0_api);
