/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2023 Ventana Micro Systems Inc.
 *
 * Authors:
 *   Anup Patel <apatel@ventanamicro.com>
 */

#include <libfdt.h>
#include <sbi/riscv_asm.h>
#include <sbi/riscv_io.h>
#include <sbi/sbi_byteorder.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_heap.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/regmap/fdt_regmap.h>

enum syscon_regmap_endian {
	SYSCON_ENDIAN_NATIVE = 0,
	SYSCON_ENDIAN_LITTLE,
	SYSCON_ENDIAN_BIG,
	SYSCON_ENDIAN_MAX
};

struct syscon_regmap {
	u32 reg_io_width;
	enum syscon_regmap_endian reg_endian;
	unsigned long addr;
	struct regmap rmap;
};

#define to_syscon_regmap(__rmap)	\
	container_of((__rmap), struct syscon_regmap, rmap)

static int regmap_syscon_read_8(struct regmap *rmap, unsigned int reg,
				unsigned int *val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	*val = readb((volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_write_8(struct regmap *rmap, unsigned int reg,
				 unsigned int val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	writeb(val, (volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_read_16(struct regmap *rmap, unsigned int reg,
				unsigned int *val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	*val = readw((volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_write_16(struct regmap *rmap, unsigned int reg,
				 unsigned int val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	writew(val, (volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_read_32(struct regmap *rmap, unsigned int reg,
				unsigned int *val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	*val = readl((volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_write_32(struct regmap *rmap, unsigned int reg,
				 unsigned int val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	writel(val, (volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_read_le16(struct regmap *rmap, unsigned int reg,
				   unsigned int *val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	*val = le16_to_cpu(readw((volatile void *)(srm->addr + reg)));
	return 0;
}

static int regmap_syscon_write_le16(struct regmap *rmap, unsigned int reg,
				    unsigned int val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	writew(cpu_to_le16(val), (volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_read_le32(struct regmap *rmap, unsigned int reg,
				   unsigned int *val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	*val = le32_to_cpu(readl((volatile void *)(srm->addr + reg)));
	return 0;
}

static int regmap_syscon_write_le32(struct regmap *rmap, unsigned int reg,
				    unsigned int val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	writel(cpu_to_le32(val), (volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_read_be16(struct regmap *rmap, unsigned int reg,
				   unsigned int *val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	*val = be16_to_cpu(readl((volatile void *)(srm->addr + reg)));
	return 0;
}

static int regmap_syscon_write_be16(struct regmap *rmap, unsigned int reg,
				    unsigned int val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	writel(cpu_to_be16(val), (volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_read_be32(struct regmap *rmap, unsigned int reg,
				   unsigned int *val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	*val = be32_to_cpu(readl((volatile void *)(srm->addr + reg)));
	return 0;
}

static int regmap_syscon_write_be32(struct regmap *rmap, unsigned int reg,
				    unsigned int val)
{
	struct syscon_regmap *srm = to_syscon_regmap(rmap);

	writel(cpu_to_be32(val), (volatile void *)(srm->addr + reg));
	return 0;
}

static int regmap_syscon_init(void *fdt, int nodeoff, u32 phandle,
			      const struct fdt_match *match)
{
	struct syscon_regmap *srm;
	uint64_t addr, size;
	const fdt32_t *val;
	int rc, len;

	srm = sbi_zalloc(sizeof(*srm));
	if (!srm)
		return SBI_ENOMEM;

	val = fdt_getprop(fdt, nodeoff, "reg-io-width", &len);
	srm->reg_io_width = val ? fdt32_to_cpu(*val) : 4;

	if (fdt_getprop(fdt, nodeoff, "native-endian", &len))
		srm->reg_endian = SYSCON_ENDIAN_NATIVE;
	else if (fdt_getprop(fdt, nodeoff, "little-endian", &len))
		srm->reg_endian = SYSCON_ENDIAN_LITTLE;
	else if (fdt_getprop(fdt, nodeoff, "big-endian", &len))
		srm->reg_endian = SYSCON_ENDIAN_BIG;
	else
		srm->reg_endian = SYSCON_ENDIAN_NATIVE;

	rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, &size);
	if (rc)
		goto fail_free_syscon;
	srm->addr = addr;

	srm->rmap.id = phandle;
	srm->rmap.reg_shift = 0;
	srm->rmap.reg_stride = srm->reg_io_width * 8;
	srm->rmap.reg_base = 0;
	srm->rmap.reg_max = size / srm->reg_io_width;
	switch (srm->reg_io_width) {
	case 1:
		srm->rmap.reg_read = regmap_syscon_read_8;
		srm->rmap.reg_write = regmap_syscon_write_8;
		break;
	case 2:
		switch (srm->reg_endian) {
		case SYSCON_ENDIAN_NATIVE:
			srm->rmap.reg_read = regmap_syscon_read_16;
			srm->rmap.reg_write = regmap_syscon_write_16;
			break;
		case SYSCON_ENDIAN_LITTLE:
			srm->rmap.reg_read = regmap_syscon_read_le16;
			srm->rmap.reg_write = regmap_syscon_write_le16;
			break;
		case SYSCON_ENDIAN_BIG:
			srm->rmap.reg_read = regmap_syscon_read_be16;
			srm->rmap.reg_write = regmap_syscon_write_be16;
			break;
		default:
			rc = SBI_EINVAL;
			goto fail_free_syscon;
		}
		break;
	case 4:
		switch (srm->reg_endian) {
		case SYSCON_ENDIAN_NATIVE:
			srm->rmap.reg_read = regmap_syscon_read_32;
			srm->rmap.reg_write = regmap_syscon_write_32;
			break;
		case SYSCON_ENDIAN_LITTLE:
			srm->rmap.reg_read = regmap_syscon_read_le32;
			srm->rmap.reg_write = regmap_syscon_write_le32;
			break;
		case SYSCON_ENDIAN_BIG:
			srm->rmap.reg_read = regmap_syscon_read_be32;
			srm->rmap.reg_write = regmap_syscon_write_be32;
			break;
		default:
			rc = SBI_EINVAL;
			goto fail_free_syscon;
		}
		break;
	default:
		rc = SBI_EINVAL;
		goto fail_free_syscon;
	}

	rc = sbi_domain_root_add_memrange(addr, size, PAGE_SIZE,
				(SBI_DOMAIN_MEMREGION_MMIO |
				 SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW));
	if (rc)
		goto fail_free_syscon;

	rc = regmap_add(&srm->rmap);
	if (rc)
		goto fail_free_syscon;

	return 0;

fail_free_syscon:
	sbi_free(srm);
	return rc;
}

static const struct fdt_match regmap_syscon_match[] = {
	{ .compatible = "syscon" },
	{ },
};

struct fdt_regmap fdt_regmap_syscon = {
	.match_table = regmap_syscon_match,
	.init = regmap_syscon_init,
};
