// SPDX-License-Identifier: GPL-2.0+
/*
 * Device addresses
 *
 * Copyright (c) 2017 Google, Inc
 *
 * (C) Copyright 2012
 * Pavel Herrmann <morpheus.ibis@gmail.com>
 */

#include <common.h>
#include <dm.h>
#include <fdt_support.h>
#include <asm/io.h>
#include <dm/device-internal.h>

DECLARE_GLOBAL_DATA_PTR;

fdt_addr_t devfdt_get_addr_index(struct udevice *dev, int index)
{
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
	fdt_addr_t addr;

	if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
		const fdt32_t *reg;
		int len = 0;
		int na, ns;

		na = fdt_address_cells(gd->fdt_blob,
				       dev_of_offset(dev->parent));
		if (na < 1) {
			debug("bad #address-cells\n");
			return FDT_ADDR_T_NONE;
		}

		ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent));
		if (ns < 0) {
			debug("bad #size-cells\n");
			return FDT_ADDR_T_NONE;
		}

		reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg",
				  &len);
		if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) {
			debug("Req index out of range\n");
			return FDT_ADDR_T_NONE;
		}

		reg += index * (na + ns);

		if (ns) {
			/*
			 * Use the full-fledged translate function for complex
			 * bus setups.
			 */
			addr = fdt_translate_address((void *)gd->fdt_blob,
						     dev_of_offset(dev), reg);
		} else {
			/* Non translatable if #size-cells == 0 */
			addr = fdt_read_number(reg, na);
		}
	} else {
		/*
		 * Use the "simple" translate function for less complex
		 * bus setups.
		 */
		addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
				dev_of_offset(dev->parent), dev_of_offset(dev),
				"reg", index, NULL, false);
		if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
			if (device_get_uclass_id(dev->parent) ==
			    UCLASS_SIMPLE_BUS)
				addr = simple_bus_translate(dev->parent, addr);
		}
	}

	/*
	 * Some platforms need a special address translation. Those
	 * platforms (e.g. mvebu in SPL) can configure a translation
	 * offset in the DM by calling dm_set_translation_offset() that
	 * will get added to all addresses returned by devfdt_get_addr().
	 */
	addr += dm_get_translation_offset();

	return addr;
#else
	return FDT_ADDR_T_NONE;
#endif
}

fdt_addr_t devfdt_get_addr_size_index(struct udevice *dev, int index,
				   fdt_size_t *size)
{
#if CONFIG_IS_ENABLED(OF_CONTROL)
	/*
	 * Only get the size in this first call. We'll get the addr in the
	 * next call to the exisiting dev_get_xxx function which handles
	 * all config options.
	 */
	fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev_of_offset(dev),
					   "reg", index, size, false);

	/*
	 * Get the base address via the existing function which handles
	 * all Kconfig cases
	 */
	return devfdt_get_addr_index(dev, index);
#else
	return FDT_ADDR_T_NONE;
#endif
}

fdt_addr_t devfdt_get_addr_name(struct udevice *dev, const char *name)
{
#if CONFIG_IS_ENABLED(OF_CONTROL)
	int index;

	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
				      "reg-names", name);
	if (index < 0)
		return index;

	return devfdt_get_addr_index(dev, index);
#else
	return FDT_ADDR_T_NONE;
#endif
}

fdt_addr_t devfdt_get_addr(struct udevice *dev)
{
	return devfdt_get_addr_index(dev, 0);
}

void *devfdt_get_addr_ptr(struct udevice *dev)
{
	return (void *)(uintptr_t)devfdt_get_addr_index(dev, 0);
}

void *devfdt_remap_addr_index(struct udevice *dev, int index)
{
	fdt_addr_t addr = devfdt_get_addr_index(dev, index);

	if (addr == FDT_ADDR_T_NONE)
		return NULL;

	return map_physmem(addr, 0, MAP_NOCACHE);
}

void *devfdt_remap_addr_name(struct udevice *dev, const char *name)
{
	fdt_addr_t addr = devfdt_get_addr_name(dev, name);

	if (addr == FDT_ADDR_T_NONE)
		return NULL;

	return map_physmem(addr, 0, MAP_NOCACHE);
}

void *devfdt_remap_addr(struct udevice *dev)
{
	return devfdt_remap_addr_index(dev, 0);
}

void *devfdt_map_physmem(struct udevice *dev, unsigned long size)
{
	fdt_addr_t addr = devfdt_get_addr(dev);

	if (addr == FDT_ADDR_T_NONE)
		return NULL;

	return map_physmem(addr, size, MAP_NOCACHE);
}
