/*
 * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdbool.h>
#include <string.h>

#include <common/debug.h>
#include <drivers/generic_delay_timer.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables.h>
#include <plat_ipi.h>
#include <plat_private.h>
#include <plat/common/platform.h>

#include "pm_api_sys.h"

/*
 * Table of regions to map using the MMU.
 * This doesn't include TZRAM as the 'mem_layout' argument passed to
 * configure_mmu_elx() will give the available subset of that,
 */
const mmap_region_t plat_arm_mmap[] = {
	{ DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
	{ DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
	{ CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
	{0}
};

static uint32_t zynqmp_get_silicon_ver(void)
{
	static unsigned int ver;

	if (!ver) {
		ver = mmio_read_32(ZYNQMP_CSU_BASEADDR +
				   ZYNQMP_CSU_VERSION_OFFSET);
		ver &= ZYNQMP_SILICON_VER_MASK;
		ver >>= ZYNQMP_SILICON_VER_SHIFT;
	}

	return ver;
}

uint32_t zynqmp_get_uart_clk(void)
{
	unsigned int ver = zynqmp_get_silicon_ver();

	if (ver == ZYNQMP_CSU_VERSION_QEMU) {
		return 133000000;
	} else {
		return 100000000;
	}
}

#if LOG_LEVEL >= LOG_LEVEL_NOTICE
static const struct {
	uint32_t id;
	uint32_t ver;
	char *name;
	bool evexists;
} zynqmp_devices[] = {
	{
		.id = 0x10,
		.name = "XCZU3EG",
	},
	{
		.id = 0x10,
		.ver = 0x2c,
		.name = "XCZU3CG",
	},
	{
		.id = 0x11,
		.name = "XCZU2EG",
	},
	{
		.id = 0x11,
		.ver = 0x2c,
		.name = "XCZU2CG",
	},
	{
		.id = 0x20,
		.name = "XCZU5EV",
		.evexists = true,
	},
	{
		.id = 0x20,
		.ver = 0x100,
		.name = "XCZU5EG",
		.evexists = true,
	},
	{
		.id = 0x20,
		.ver = 0x12c,
		.name = "XCZU5CG",
	},
	{
		.id = 0x21,
		.name = "XCZU4EV",
		.evexists = true,
	},
	{
		.id = 0x21,
		.ver = 0x100,
		.name = "XCZU4EG",
		.evexists = true,
	},
	{
		.id = 0x21,
		.ver = 0x12c,
		.name = "XCZU4CG",
	},
	{
		.id = 0x30,
		.name = "XCZU7EV",
		.evexists = true,
	},
	{
		.id = 0x30,
		.ver = 0x100,
		.name = "XCZU7EG",
		.evexists = true,
	},
	{
		.id = 0x30,
		.ver = 0x12c,
		.name = "XCZU7CG",
	},
	{
		.id = 0x38,
		.name = "XCZU9EG",
	},
	{
		.id = 0x38,
		.ver = 0x2c,
		.name = "XCZU9CG",
	},
	{
		.id = 0x39,
		.name = "XCZU6EG",
	},
	{
		.id = 0x39,
		.ver = 0x2c,
		.name = "XCZU6CG",
	},
	{
		.id = 0x40,
		.name = "XCZU11EG",
	},
	{
		.id = 0x50,
		.name = "XCZU15EG",
	},
	{
		.id = 0x58,
		.name = "XCZU19EG",
	},
	{
		.id = 0x59,
		.name = "XCZU17EG",
	},
	{
		.id = 0x60,
		.name = "XCZU28DR",
	},
	{
		.id = 0x61,
		.name = "XCZU21DR",
	},
	{
		.id = 0x62,
		.name = "XCZU29DR",
	},
	{
		.id = 0x63,
		.name = "XCZU23DR",
	},
	{
		.id = 0x64,
		.name = "XCZU27DR",
	},
	{
		.id = 0x65,
		.name = "XCZU25DR",
	},
	{
		.id = 0x66,
		.name = "XCZU39DR",
	},
	{
		.id = 0x7d,
		.name = "XCZU43DR",
	},
	{
		.id = 0x78,
		.name = "XCZU46DR",
	},
	{
		.id = 0x7f,
		.name = "XCZU47DR",
	},
	{
		.id = 0x7b,
		.name = "XCZU48DR",
	},
	{
		.id = 0x7e,
		.name = "XCZU49DR",
	},
};

#define ZYNQMP_PL_STATUS_BIT	9
#define ZYNQMP_PL_STATUS_MASK	BIT(ZYNQMP_PL_STATUS_BIT)
#define ZYNQMP_CSU_VERSION_MASK	~(ZYNQMP_PL_STATUS_MASK)

#define SILICON_ID_XCK24	0x4714093
#define SILICON_ID_XCK26	0x4724093

static char *zynqmp_get_silicon_idcode_name(void)
{
	uint32_t id, ver, chipid[2];
	size_t i, j, len;
	const char *name = "EG/EV";

#ifdef IMAGE_BL32
	/*
	 * For BL32, get the chip id info directly by reading corresponding
	 * registers instead of making pm call. This has limitation
	 * that these registers should be configured to have access
	 * from APU which is default case.
	 */
	chipid[0] = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
	chipid[1] = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
#else
	if (pm_get_chipid(chipid) != PM_RET_SUCCESS) {
		return "XCZUUNKN";
	}
#endif

	id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
			  ZYNQMP_CSU_IDCODE_SVD_MASK);
	id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
	ver = chipid[1] >> ZYNQMP_EFUSE_IPDISABLE_SHIFT;

	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
		if (zynqmp_devices[i].id == id &&
		    zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK)) {
			break;
		}
	}

	if (i >= ARRAY_SIZE(zynqmp_devices)) {
		switch (chipid[0]) {
		case SILICON_ID_XCK24:
			return "XCK24";
		case SILICON_ID_XCK26:
			return "XCK26";
		default:
			return "XCZUUNKN";
		}
	}

	if (!zynqmp_devices[i].evexists) {
		return zynqmp_devices[i].name;
	}

	if ((ver & ZYNQMP_PL_STATUS_MASK) != 0U) {
		return zynqmp_devices[i].name;
	}

	len = strlen(zynqmp_devices[i].name) - 2;
	for (j = 0; j < strlen(name); j++) {
		zynqmp_devices[i].name[len] = name[j];
		len++;
	}
	zynqmp_devices[i].name[len] = '\0';

	return zynqmp_devices[i].name;
}

static unsigned int zynqmp_get_rtl_ver(void)
{
	uint32_t ver;

	ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
	ver &= ZYNQMP_RTL_VER_MASK;
	ver >>= ZYNQMP_RTL_VER_SHIFT;

	return ver;
}

static char *zynqmp_print_silicon_idcode(void)
{
	uint32_t id, maskid, tmp;

	id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);

	tmp = id;
	tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
	       ZYNQMP_CSU_IDCODE_FAMILY_MASK;
	maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
		 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
	if (tmp != maskid) {
		ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
		return "UNKN";
	}
	VERBOSE("Xilinx IDCODE 0x%x\n", id);
	return zynqmp_get_silicon_idcode_name();
}

static uint32_t zynqmp_get_ps_ver(void)
{
	uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);

	ver &= ZYNQMP_PS_VER_MASK;
	ver >>= ZYNQMP_PS_VER_SHIFT;

	return ver + 1;
}

static void zynqmp_print_platform_name(void)
{
	uint32_t ver = zynqmp_get_silicon_ver();
	uint32_t rtl = zynqmp_get_rtl_ver();
	char *label = "Unknown";

	switch (ver) {
	case ZYNQMP_CSU_VERSION_QEMU:
		label = "QEMU";
		break;
	case ZYNQMP_CSU_VERSION_SILICON:
		label = "silicon";
		break;
	default:
		/* Do nothing in default case */
		break;
	}

	VERBOSE("TF-A running on %s/%s at 0x%x\n",
		zynqmp_print_silicon_idcode(), label, BL31_BASE);
	VERBOSE("TF-A running on v%d/RTL%d.%d\n",
	       zynqmp_get_ps_ver(), (rtl & 0xf0) >> 4, rtl & 0xf);
}
#else
static inline void zynqmp_print_platform_name(void) { }
#endif

uint32_t zynqmp_get_bootmode(void)
{
	uint32_t r;
	unsigned int ret;

	ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);

	if (ret != PM_RET_SUCCESS) {
		r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
	}

	return r & CRL_APB_BOOT_MODE_MASK;
}

void zynqmp_config_setup(void)
{
	uint64_t counter_freq;

	/* Configure IPI data for ZynqMP */
	zynqmp_ipi_config_table_init();

	zynqmp_print_platform_name();

	/* Configure counter frequency */
	counter_freq = read_cntfrq_el0();
	if (counter_freq == ZYNQMP_DEFAULT_COUNTER_FREQ) {
		write_cntfrq_el0(plat_get_syscnt_freq2());
	}

	generic_delay_timer_init();
}

uint32_t plat_get_syscnt_freq2(void)
{
	uint32_t ver = zynqmp_get_silicon_ver();

	if (ver == ZYNQMP_CSU_VERSION_QEMU) {
		return 65000000;
	} else {
		return mmio_read_32(IOU_SCNTRS_BASEFREQ);
	}
}
