/*
 * 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_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_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
