// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2015 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <linux/libfdt.h>
#include <malloc.h>
#include <mapmem.h>
#include <regmap.h>
#include <asm/io.h>
#include <dm/of_addr.h>
#include <linux/ioport.h>

DECLARE_GLOBAL_DATA_PTR;

/**
 * regmap_alloc() - Allocate a regmap with a given number of ranges.
 *
 * @count: Number of ranges to be allocated for the regmap.
 * Return: A pointer to the newly allocated regmap, or NULL on error.
 */
static struct regmap *regmap_alloc(int count)
{
	struct regmap *map;

	map = malloc(sizeof(*map) + sizeof(map->ranges[0]) * count);
	if (!map)
		return NULL;
	map->range_count = count;

	return map;
}

#if CONFIG_IS_ENABLED(OF_PLATDATA)
int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count,
			     struct regmap **mapp)
{
	struct regmap_range *range;
	struct regmap *map;

	map = regmap_alloc(count);
	if (!map)
		return -ENOMEM;

	for (range = map->ranges; count > 0; reg += 2, range++, count--) {
		range->start = *reg;
		range->size = reg[1];
	}

	*mapp = map;

	return 0;
}
#else
/**
 * init_range() - Initialize a single range of a regmap
 * @node:     Device node that will use the map in question
 * @range:    Pointer to a regmap_range structure that will be initialized
 * @addr_len: The length of the addr parts of the reg property
 * @size_len: The length of the size parts of the reg property
 * @index:    The index of the range to initialize
 *
 * This function will read the necessary 'reg' information from the device tree
 * (the 'addr' part, and the 'length' part), and initialize the range in
 * quesion.
 *
 * Return: 0 if OK, -ve on error
 */
static int init_range(ofnode node, struct regmap_range *range, int addr_len,
		      int size_len, int index)
{
	fdt_size_t sz;
	struct resource r;

	if (of_live_active()) {
		int ret;

		ret = of_address_to_resource(ofnode_to_np(node),
					     index, &r);
		if (ret) {
			debug("%s: Could not read resource of range %d (ret = %d)\n",
			      ofnode_get_name(node), index, ret);
			return ret;
		}

		range->start = r.start;
		range->size = r.end - r.start + 1;
	} else {
		int offset = ofnode_to_offset(node);

		range->start = fdtdec_get_addr_size_fixed(gd->fdt_blob, offset,
							  "reg", index,
							  addr_len, size_len,
							  &sz, true);
		if (range->start == FDT_ADDR_T_NONE) {
			debug("%s: Could not read start of range %d\n",
			      ofnode_get_name(node), index);
			return -EINVAL;
		}

		range->size = sz;
	}

	return 0;
}

int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index)
{
	struct regmap *map;
	int addr_len, size_len;
	int ret;

	addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
	if (addr_len < 0) {
		debug("%s: Error while reading the addr length (ret = %d)\n",
		      ofnode_get_name(node), addr_len);
		return addr_len;
	}

	size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node));
	if (size_len < 0) {
		debug("%s: Error while reading the size length: (ret = %d)\n",
		      ofnode_get_name(node), size_len);
		return size_len;
	}

	map = regmap_alloc(1);
	if (!map)
		return -ENOMEM;

	ret = init_range(node, map->ranges, addr_len, size_len, index);
	if (ret)
		return ret;

	if (ofnode_read_bool(node, "little-endian"))
		map->endianness = REGMAP_LITTLE_ENDIAN;
	else if (ofnode_read_bool(node, "big-endian"))
		map->endianness = REGMAP_BIG_ENDIAN;
	else if (ofnode_read_bool(node, "native-endian"))
		map->endianness = REGMAP_NATIVE_ENDIAN;
	else /* Default: native endianness */
		map->endianness = REGMAP_NATIVE_ENDIAN;

	*mapp = map;

	return ret;
}

int regmap_init_mem(ofnode node, struct regmap **mapp)
{
	struct regmap_range *range;
	struct regmap *map;
	int count;
	int addr_len, size_len, both_len;
	int len;
	int index;

	addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
	if (addr_len < 0) {
		debug("%s: Error while reading the addr length (ret = %d)\n",
		      ofnode_get_name(node), addr_len);
		return addr_len;
	}

	size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node));
	if (size_len < 0) {
		debug("%s: Error while reading the size length: (ret = %d)\n",
		      ofnode_get_name(node), size_len);
		return size_len;
	}

	both_len = addr_len + size_len;
	if (!both_len) {
		debug("%s: Both addr and size length are zero\n",
		      ofnode_get_name(node));
		return -EINVAL;
	}

	len = ofnode_read_size(node, "reg");
	if (len < 0) {
		debug("%s: Error while reading reg size (ret = %d)\n",
		      ofnode_get_name(node), len);
		return len;
	}
	len /= sizeof(fdt32_t);
	count = len / both_len;
	if (!count) {
		debug("%s: Not enough data in reg property\n",
		      ofnode_get_name(node));
		return -EINVAL;
	}

	map = regmap_alloc(count);
	if (!map)
		return -ENOMEM;

	for (range = map->ranges, index = 0; count > 0;
	     count--, range++, index++) {
		int ret = init_range(node, range, addr_len, size_len, index);

		if (ret)
			return ret;
	}

	if (ofnode_read_bool(node, "little-endian"))
		map->endianness = REGMAP_LITTLE_ENDIAN;
	else if (ofnode_read_bool(node, "big-endian"))
		map->endianness = REGMAP_BIG_ENDIAN;
	else if (ofnode_read_bool(node, "native-endian"))
		map->endianness = REGMAP_NATIVE_ENDIAN;
	else /* Default: native endianness */
		map->endianness = REGMAP_NATIVE_ENDIAN;

	*mapp = map;

	return 0;
}
#endif

void *regmap_get_range(struct regmap *map, unsigned int range_num)
{
	struct regmap_range *range;

	if (range_num >= map->range_count)
		return NULL;
	range = &map->ranges[range_num];

	return map_sysmem(range->start, range->size);
}

int regmap_uninit(struct regmap *map)
{
	free(map);

	return 0;
}

static inline u8 __read_8(u8 *addr, enum regmap_endianness_t endianness)
{
	return readb(addr);
}

static inline u16 __read_16(u16 *addr, enum regmap_endianness_t endianness)
{
	switch (endianness) {
	case REGMAP_LITTLE_ENDIAN:
		return in_le16(addr);
	case REGMAP_BIG_ENDIAN:
		return in_be16(addr);
	case REGMAP_NATIVE_ENDIAN:
		return readw(addr);
	}

	return readw(addr);
}

static inline u32 __read_32(u32 *addr, enum regmap_endianness_t endianness)
{
	switch (endianness) {
	case REGMAP_LITTLE_ENDIAN:
		return in_le32(addr);
	case REGMAP_BIG_ENDIAN:
		return in_be32(addr);
	case REGMAP_NATIVE_ENDIAN:
		return readl(addr);
	}

	return readl(addr);
}

#if defined(in_le64) && defined(in_be64) && defined(readq)
static inline u64 __read_64(u64 *addr, enum regmap_endianness_t endianness)
{
	switch (endianness) {
	case REGMAP_LITTLE_ENDIAN:
		return in_le64(addr);
	case REGMAP_BIG_ENDIAN:
		return in_be64(addr);
	case REGMAP_NATIVE_ENDIAN:
		return readq(addr);
	}

	return readq(addr);
}
#endif

int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
			  void *valp, size_t val_len)
{
	struct regmap_range *range;
	void *ptr;

	if (range_num >= map->range_count) {
		debug("%s: range index %d larger than range count\n",
		      __func__, range_num);
		return -ERANGE;
	}
	range = &map->ranges[range_num];

	ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE);

	if (offset + val_len > range->size) {
		debug("%s: offset/size combination invalid\n", __func__);
		return -ERANGE;
	}

	switch (val_len) {
	case REGMAP_SIZE_8:
		*((u8 *)valp) = __read_8(ptr, map->endianness);
		break;
	case REGMAP_SIZE_16:
		*((u16 *)valp) = __read_16(ptr, map->endianness);
		break;
	case REGMAP_SIZE_32:
		*((u32 *)valp) = __read_32(ptr, map->endianness);
		break;
#if defined(in_le64) && defined(in_be64) && defined(readq)
	case REGMAP_SIZE_64:
		*((u64 *)valp) = __read_64(ptr, map->endianness);
		break;
#endif
	default:
		debug("%s: regmap size %zu unknown\n", __func__, val_len);
		return -EINVAL;
	}

	return 0;
}

int regmap_raw_read(struct regmap *map, uint offset, void *valp, size_t val_len)
{
	return regmap_raw_read_range(map, 0, offset, valp, val_len);
}

int regmap_read(struct regmap *map, uint offset, uint *valp)
{
	return regmap_raw_read(map, offset, valp, REGMAP_SIZE_32);
}

static inline void __write_8(u8 *addr, const u8 *val,
			     enum regmap_endianness_t endianness)
{
	writeb(*val, addr);
}

static inline void __write_16(u16 *addr, const u16 *val,
			      enum regmap_endianness_t endianness)
{
	switch (endianness) {
	case REGMAP_NATIVE_ENDIAN:
		writew(*val, addr);
		break;
	case REGMAP_LITTLE_ENDIAN:
		out_le16(addr, *val);
		break;
	case REGMAP_BIG_ENDIAN:
		out_be16(addr, *val);
		break;
	}
}

static inline void __write_32(u32 *addr, const u32 *val,
			      enum regmap_endianness_t endianness)
{
	switch (endianness) {
	case REGMAP_NATIVE_ENDIAN:
		writel(*val, addr);
		break;
	case REGMAP_LITTLE_ENDIAN:
		out_le32(addr, *val);
		break;
	case REGMAP_BIG_ENDIAN:
		out_be32(addr, *val);
		break;
	}
}

#if defined(out_le64) && defined(out_be64) && defined(writeq)
static inline void __write_64(u64 *addr, const u64 *val,
			      enum regmap_endianness_t endianness)
{
	switch (endianness) {
	case REGMAP_NATIVE_ENDIAN:
		writeq(*val, addr);
		break;
	case REGMAP_LITTLE_ENDIAN:
		out_le64(addr, *val);
		break;
	case REGMAP_BIG_ENDIAN:
		out_be64(addr, *val);
		break;
	}
}
#endif

int regmap_raw_write_range(struct regmap *map, uint range_num, uint offset,
			   const void *val, size_t val_len)
{
	struct regmap_range *range;
	void *ptr;

	if (range_num >= map->range_count) {
		debug("%s: range index %d larger than range count\n",
		      __func__, range_num);
		return -ERANGE;
	}
	range = &map->ranges[range_num];

	ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE);

	if (offset + val_len > range->size) {
		debug("%s: offset/size combination invalid\n", __func__);
		return -ERANGE;
	}

	switch (val_len) {
	case REGMAP_SIZE_8:
		__write_8(ptr, val, map->endianness);
		break;
	case REGMAP_SIZE_16:
		__write_16(ptr, val, map->endianness);
		break;
	case REGMAP_SIZE_32:
		__write_32(ptr, val, map->endianness);
		break;
#if defined(out_le64) && defined(out_be64) && defined(writeq)
	case REGMAP_SIZE_64:
		__write_64(ptr, val, map->endianness);
		break;
#endif
	default:
		debug("%s: regmap size %zu unknown\n", __func__, val_len);
		return -EINVAL;
	}

	return 0;
}

int regmap_raw_write(struct regmap *map, uint offset, const void *val,
		     size_t val_len)
{
	return regmap_raw_write_range(map, 0, offset, val, val_len);
}

int regmap_write(struct regmap *map, uint offset, uint val)
{
	return regmap_raw_write(map, offset, &val, REGMAP_SIZE_32);
}

int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val)
{
	uint reg;
	int ret;

	ret = regmap_read(map, offset, &reg);
	if (ret)
		return ret;

	reg &= ~mask;

	return regmap_write(map, offset, reg | val);
}
