/*
 * 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;
	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=0x%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_GPIO4, 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_GPIO1, 0x3, 0},
	{RDC_PDAP_GPIO2, 0x3, 0},
	{RDC_PDAP_GPIO3, 0x3, 0},
	{RDC_PDAP_GPIO4, 0x3, 0},
	{RDC_PDAP_GPIO5, 0x3, 0},
};

/* Default masters settings as an example */
static struct rdc_mda_conf masters_config[] = {
	{RDC_MDA_A53, 0, 0},
	{RDC_MDA_CAAM, 0, 0},
};
#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
