/*
 * Copyright 2017 NXP
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <debug.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <platform_def.h>
#include <utils_def.h>
#include <imx_rdc.h>
#include <mmio.h>

/*
 * Read RDC settings for one peripheral
 * read the given domains field and lock bit
 * for the given PDAP index [0..118]
 */
int imx_rdc_get_pdap(struct rdc_pdap_conf *p)
{
	struct imx_rdc_regs *imx_rdc = (struct imx_rdc_regs *)IMX_RDC_BASE;
	uint32_t reg = 0;

	reg = mmio_read_32((uintptr_t)&imx_rdc->pdap[p->index]);
	p->lock = (reg & RDC_PDAP_LCK_MASK) >> RDC_PDAP_LCK_SHIFT;
	p->domains = reg & 0xFF;

	return 0;
}

/*
 * Write RDC settings for one peripheral
 * Check before write if is already locked then skip
 */
int imx_rdc_set_pdap(struct rdc_pdap_conf *p)
{
	struct imx_rdc_regs *imx_rdc = (struct imx_rdc_regs *)IMX_RDC_BASE;
	struct rdc_pdap_conf r;
	uint32_t i, reg = 0;
	uint8_t multi_domain = 0;

	/* Check if locked */
	r.index = p->index;
	imx_rdc_get_pdap(&r);
	if (r.lock) {
		WARN("RDC_PDAPn %d is already locked \n", p->index);
		return -ENOENT;
	}

	/* Check if no domain assigned */
	if (p->domains == 0)
		return -EINVAL;
	reg |= p->domains;

	/* Check if SREQ is needed */
	for (i = 0; i < 7; i += 2)
		multi_domain += ((p->domains >> i) & 0x3) ? 1 : 0;
	if (multi_domain > 1)
		reg |= RDC_PDAP_SREQ_MASK;
	/* Setup Lock from input */
	reg |= p->lock << RDC_PDAP_LCK_SHIFT;

	NOTICE("imx_rdc_set_pdap(): write addr=0x%p, reg=0x%x\n",
			&imx_rdc->pdap[p->index], reg);

	mmio_write_32((uintptr_t)&imx_rdc->pdap[p->index], reg);

	return 0;
}

/*
 * Setup RDC settings for multiple peripherals
 */
int imx_rdc_set_peripherals(struct rdc_pdap_conf *peripherals_list,
				uint32_t count)
{
	int i, ret;

	for (i = 0; i < count; i++) {
		ret = imx_rdc_set_pdap(&peripherals_list[i]);
		if (ret)
			return ret;
	}

	return 0;
}

/*
 * Read RDC setting for one master
 * For the given index in p.index it returns the lock bit
 * and the domain field into p structure.
 */
int imx_rdc_get_mda(struct rdc_mda_conf *p)
{
	struct imx_rdc_regs *imx_rdc = (struct imx_rdc_regs *)IMX_RDC_BASE;
	uint32_t reg = 0;

	reg = mmio_read_32((uintptr_t)&imx_rdc->mda[p->index]);
	p->domain = reg & RDC_MDA_DID_MASK;
	p->lock = (reg & RDC_MDA_LCK_MASK) >> RDC_MDA_LCK_SHIFT;
	return 0;
}

/*
 * Write RDC setting for one master
 */
int imx_rdc_set_mda(struct rdc_mda_conf *p)
{
	struct imx_rdc_regs *imx_rdc = (struct imx_rdc_regs *)IMX_RDC_BASE;
	struct rdc_mda_conf r;
	uint32_t reg = 0;
	int ret = 0;

	/* Check if it is locked */
	r.index = p->index;
	imx_rdc_get_mda(&r);
	if (!r.lock) {
	reg = (p->domain & RDC_MDA_DID_MASK)
		| ((p->lock << RDC_MDA_LCK_SHIFT) & RDC_MDA_LCK_MASK);
	NOTICE("imx_rdc_setup_mda(): write addr=%p, reg=0x%x\n",
			&imx_rdc->mda[p->index], reg);
	mmio_write_32((uintptr_t)&imx_rdc->mda[p->index], reg);
	} else {
		WARN("RDC_MDAn %d is already locked \n", p->index);
		ret = -ENOENT;
	}

	return ret;
}

/*
 * Setup RDC settings for multiple masters
 */
int imx_rdc_set_masters(struct rdc_mda_conf *masters_list, uint32_t count)
{
	int i, ret;

	for (i = 0; i < count; i++) {
		ret = imx_rdc_set_mda(&masters_list[i]);
		if (ret)
			break;
	}

	return ret;
}

#if defined (CSU_RDC_TEST)
/* Default peripherals settings as an example */
static struct rdc_pdap_conf periph_config[] = {
	{RDC_PDAP_CSU, 0x30, 0},
};


/* Default masters settings as an example */
static struct rdc_mda_conf masters_config[] = {
	{RDC_MDA_A53, 0, 0},
};
#else
/* Default peripherals settings as an example */
static struct rdc_pdap_conf periph_config[] = {
	{RDC_PDAP_GPU_EXSC, 0x0C, 0},
	{RDC_PDAP_VPU_SEC, 0x33, 0},
};

/* Default masters settings as an example */
static struct rdc_mda_conf masters_config[] = {
	{RDC_MDA_A53, 0, 1},
	{RDC_MDA_CAAM, 0, 1},
	{RDC_MDA_GPU, 1, 1},
	{RDC_MDA_VPU_DEC, 2, 1},
	{RDC_MDA_DCSS, 3, 1},
};
#endif
void imx_rdc_set_peripherals_default(void)
{
	imx_rdc_set_peripherals(periph_config, ARRAY_SIZE(periph_config));
}

void imx_rdc_set_masters_default(void)
{
	imx_rdc_set_masters(masters_config, ARRAY_SIZE(masters_config));
}
#if defined (CSU_RDC_TEST)
void rdc_test(void)
{
	imx_rdc_set_peripherals_default();
	imx_rdc_set_masters_default();
}
#endif
