// SPDX-License-Identifier: GPL-2.0
/*
 * board/renesas/rcar-common/common.c
 *
 * Copyright (C) 2013 Renesas Electronics Corporation
 * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
 * Copyright (C) 2015 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
 */

#include <common.h>
#include <dm.h>
#include <fdt_support.h>
#include <hang.h>
#include <init.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>
#include <asm/arch/rmobile.h>
#include <linux/libfdt.h>

#ifdef CONFIG_RCAR_64

DECLARE_GLOBAL_DATA_PTR;

/* If the firmware passed a device tree use it for e.g. U-Boot DRAM setup. */
extern u64 rcar_atf_boot_args[];

#define FDT_RPC_PATH	"/soc/spi@ee200000"

int fdtdec_board_setup(const void *fdt_blob)
{
	void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]);

	if (fdt_magic(atf_fdt_blob) == FDT_MAGIC)
		fdt_overlay_apply_node((void *)fdt_blob, 0, atf_fdt_blob, 0);

	return 0;
}

int dram_init(void)
{
	return fdtdec_setup_mem_size_base();
}

int dram_init_banksize(void)
{
	fdtdec_setup_memory_banksize();

	return 0;
}

#if defined(CONFIG_RCAR_GEN3)
#define RST_BASE	0xE6160000
#define RST_CA57RESCNT	(RST_BASE + 0x40)
#define RST_CA53RESCNT	(RST_BASE + 0x44)
#define RST_RSTOUTCR	(RST_BASE + 0x58)
#define RST_CA57_CODE	0xA5A5000F
#define RST_CA53_CODE	0x5A5A000F

void __weak reset_cpu(void)
{
	unsigned long midr, cputype;

	asm volatile("mrs %0, midr_el1" : "=r" (midr));
	cputype = (midr >> 4) & 0xfff;

	if (cputype == 0xd03)
		writel(RST_CA53_CODE, RST_CA53RESCNT);
	else if (cputype == 0xd07)
		writel(RST_CA57_CODE, RST_CA57RESCNT);
	else
		hang();
}
#elif defined(CONFIG_RCAR_GEN4)
#define RST_BASE	0xE6160000 /* Domain0 */
#define RST_SRESCR0	(RST_BASE + 0x18)
#define RST_SPRES	0x5AA58000

void __weak reset_cpu(void)
{
	writel(RST_SPRES, RST_SRESCR0);
}
#else
#error Neither CONFIG_RCAR_GEN3 nor CONFIG_RCAR_GEN4 are set
#endif

#if defined(CONFIG_OF_BOARD_SETUP)
static int is_mem_overlap(void *blob, int first_mem_node, int curr_mem_node)
{
	struct fdt_resource first_mem_res, curr_mem_res;
	int curr_mem_reg, first_mem_reg = 0;
	int ret;

	for (;;) {
		ret = fdt_get_resource(blob, first_mem_node, "reg",
				       first_mem_reg++, &first_mem_res);
		if (ret) /* No more entries, no overlap found */
			return 0;

		curr_mem_reg = 0;
		for (;;) {
			ret = fdt_get_resource(blob, curr_mem_node, "reg",
					       curr_mem_reg++, &curr_mem_res);
			if (ret) /* No more entries, check next tuple */
				break;

			if (curr_mem_res.end < first_mem_res.start)
				continue;

			if (curr_mem_res.start >= first_mem_res.end)
				continue;

			log_debug("Overlap found: 0x%llx..0x%llx / 0x%llx..0x%llx\n",
				  first_mem_res.start, first_mem_res.end,
				  curr_mem_res.start, curr_mem_res.end);

			return 1;
		}
	}

	return 0;
}

static void scrub_duplicate_memory(void *blob)
{
	/*
	 * Scrub duplicate /memory@* node entries here. Some R-Car DTs might
	 * contain multiple /memory@* nodes, however fdt_fixup_memory_banks()
	 * either generates single /memory node or updates the first /memory
	 * node. Any remaining memory nodes are thus potential duplicates.
	 *
	 * However, it is not possible to delete all the memory nodes right
	 * away, since some of those might not be DRAM memory nodes, but some
	 * sort of other memory. Thus, delete only the memory nodes which are
	 * in the R-Car3 DBSC ranges.
	 */
	int mem = 0, first_mem_node = 0;

	for (;;) {
		mem = fdt_node_offset_by_prop_value(blob, mem,
						    "device_type", "memory", 7);
		if (mem < 0)
			break;
		if (!fdtdec_get_is_enabled(blob, mem))
			continue;

		/* First memory node, patched by U-Boot */
		if (!first_mem_node) {
			first_mem_node = mem;
			continue;
		}

		/* Check the remaining nodes and delete duplicates */
		if (!is_mem_overlap(blob, first_mem_node, mem))
			continue;

		/* Delete duplicate node, start again */
		fdt_del_node(blob, mem);
		first_mem_node = 0;
		mem = 0;
	}
}

static void update_rpc_status(void *blob)
{
	void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]);
	int offset, enabled;

	/*
	 * Check if the DT fragment received from TF-A had its RPC-IF device node
	 * enabled.
	 */
	if (fdt_magic(atf_fdt_blob) != FDT_MAGIC)
		return;

	offset = fdt_path_offset(atf_fdt_blob, FDT_RPC_PATH);
	if (offset < 0)
		return;

	enabled = fdtdec_get_is_enabled(atf_fdt_blob, offset);
	if (!enabled)
		return;

	/*
	 * Find the RPC-IF device node, and enable it if it has a flash subnode.
	 */
	offset = fdt_path_offset(blob, FDT_RPC_PATH);
	if (offset < 0)
		return;

	if (fdt_subnode_offset(blob, offset, "flash") < 0)
		return;

	fdt_status_okay(blob, offset);
}

int ft_board_setup(void *blob, struct bd_info *bd)
{
	scrub_duplicate_memory(blob);
	update_rpc_status(blob);

	return 0;
}
#endif
#endif
