/*
 * Copyright (c) 2021 Google Inc
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it8xxx2_bbram

#include <errno.h>

#include <zephyr/drivers/bbram.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>

#ifndef CONFIG_BBRAM_IT8XXX2_EMUL
#include <chip_chipregs.h>
#else
/* Emulation register values */
enum bram_indices {
	BRAM_IDX_VALID_FLAGS0,
	BRAM_IDX_VALID_FLAGS1,
	BRAM_IDX_VALID_FLAGS2,
	BRAM_IDX_VALID_FLAGS3,
};
#endif

#include "it8xxx2.h"

LOG_MODULE_REGISTER(it8xxx2_bbram, CONFIG_BBRAM_LOG_LEVEL);

#define BRAM_VALID_MAGIC        0x4252414D /* "BRAM" */
#define BRAM_VALID_MAGIC_FIELD0 (BRAM_VALID_MAGIC & 0xff)
#define BRAM_VALID_MAGIC_FIELD1 ((BRAM_VALID_MAGIC >> 8) & 0xff)
#define BRAM_VALID_MAGIC_FIELD2 ((BRAM_VALID_MAGIC >> 16) & 0xff)
#define BRAM_VALID_MAGIC_FIELD3 ((BRAM_VALID_MAGIC >> 24) & 0xff)

static int bbram_it8xxx2_read(const struct device *dev, size_t offset, size_t size, uint8_t *data)
{
	const struct bbram_it8xxx2_config *config = dev->config;

	if (size < 1 || offset + size > config->size) {
		return -EINVAL;
	}

	bytecpy(data, ((uint8_t *)config->base_addr + offset), size);
	return 0;
}

static int bbram_it8xxx2_write(const struct device *dev, size_t offset, size_t size,
			       const uint8_t *data)
{
	const struct bbram_it8xxx2_config *config = dev->config;

	if (size < 1 || offset + size > config->size) {
		return -EINVAL;
	}

	bytecpy(((uint8_t *)config->base_addr + offset), data, size);
	return 0;
}

static int bbram_it8xxx2_size(const struct device *dev, size_t *size)
{
	const struct bbram_it8xxx2_config *config = dev->config;

	*size = config->size;
	return 0;
}

static const struct bbram_driver_api bbram_it8xxx2_driver_api = {
	.read = bbram_it8xxx2_read,
	.write = bbram_it8xxx2_write,
	.get_size = bbram_it8xxx2_size,
};

static int bbram_it8xxx2_init(const struct device *dev)
{
	const struct bbram_it8xxx2_config *config = dev->config;
	uint8_t *base_addr = (uint8_t *)config->base_addr;
	uint8_t *bram_valid_flag0 = base_addr + BRAM_IDX_VALID_FLAGS0;
	uint8_t *bram_valid_flag1 = base_addr + BRAM_IDX_VALID_FLAGS1;
	uint8_t *bram_valid_flag2 = base_addr + BRAM_IDX_VALID_FLAGS2;
	uint8_t *bram_valid_flag3 = base_addr + BRAM_IDX_VALID_FLAGS3;

	if ((*bram_valid_flag0 != BRAM_VALID_MAGIC_FIELD0) ||
	    (*bram_valid_flag1 != BRAM_VALID_MAGIC_FIELD1) ||
	    (*bram_valid_flag2 != BRAM_VALID_MAGIC_FIELD2) ||
	    (*bram_valid_flag3 != BRAM_VALID_MAGIC_FIELD3)) {
		/*
		 * Magic does not match, so BRAM must be uninitialized. Clear
		 * entire Bank0 BRAM, and set magic value.
		 */
		for (int i = 0; i < BRAM_IDX_VALID_FLAGS0; i++) {
			*(base_addr + i) = 0;
		}

		*bram_valid_flag0 = BRAM_VALID_MAGIC_FIELD0;
		*bram_valid_flag1 = BRAM_VALID_MAGIC_FIELD1;
		*bram_valid_flag2 = BRAM_VALID_MAGIC_FIELD2;
		*bram_valid_flag3 = BRAM_VALID_MAGIC_FIELD3;
	}

	return 0;
}

#define BBRAM_INIT(inst)                                                                           \
	BBRAM_IT8XXX2_DECL_CONFIG(inst);                                                           \
	DEVICE_DT_INST_DEFINE(inst, bbram_it8xxx2_init, NULL, NULL, &bbram_cfg_##inst,             \
			      PRE_KERNEL_1, CONFIG_BBRAM_INIT_PRIORITY,                            \
			      &bbram_it8xxx2_driver_api);

DT_INST_FOREACH_STATUS_OKAY(BBRAM_INIT);
