// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright 2017-2019 NXP
 *
 * Brief   CAAM Configuration.
 */
#include <caam_common.h>
#include <caam_hal_cfg.h>
#include <caam_hal_jr.h>
#include <caam_jr.h>
#include <kernel/dt.h>
#include <libfdt.h>
#include <mm/core_memprot.h>
#include <mm/core_mmu.h>

static const char *dt_caam_match_table = {
	"fsl,sec-v4.0",
};

static const char *dt_jr_match_table = {
	"fsl,sec-v4.0-job-ring",
};

/*
 * Finds the Job Ring reserved for the Secure Mode in the DTB
 *
 * @fdt         Reference to the Device Tree
 * @status      Status mask flag of the node to found
 * @find_node   [out] Node offset found
 */
static paddr_t find_jr_offset(void *fdt, int status, int *find_node)
{
	paddr_t jr_offset = 0;
	int node = fdt_node_offset_by_compatible(fdt, 0, dt_jr_match_table);

	for (; node != -FDT_ERR_NOTFOUND;
	     node = fdt_node_offset_by_compatible(fdt, node,
						  dt_jr_match_table)) {
		HAL_TRACE("Found Job Ring node status @%" PRId32, node);
		if (_fdt_get_status(fdt, node) == status) {
			HAL_TRACE("Found Job Ring node @%" PRId32, node);
			jr_offset = _fdt_reg_base_address(fdt, node);
			*find_node = node;
			break;
		}
	}

	HAL_TRACE("JR Offset return 0x%" PRIxPTR, jr_offset);
	return jr_offset;
}

void caam_hal_cfg_get_ctrl_dt(void *fdt, vaddr_t *ctrl_base)
{
	ssize_t size = 0;
	int node = 0;
	paddr_t pctrl_base = 0;

	*ctrl_base = 0;
	/* Get the CAAM Node to get the controller base address */
	node = fdt_node_offset_by_compatible(fdt, 0, dt_caam_match_table);

	if (node < 0)
		return;

	/*
	 * Map CAAM controller base address as Secure IO if not
	 * already present in the MMU table.
	 * Then get the virtual address of the CAAM controller
	 */
	pctrl_base = _fdt_reg_base_address(fdt, node);
	if (pctrl_base == DT_INFO_INVALID_REG) {
		HAL_TRACE("CAAM control base address not defined");
		return;
	}

	size = _fdt_reg_size(fdt, node);
	if (size < 0) {
		HAL_TRACE("CAAM control base address size not defined");
		return;
	}

	if (!core_mmu_add_mapping(MEM_AREA_IO_SEC, pctrl_base, size)) {
		EMSG("CAAM control base MMU PA mapping failure");
		return;
	}

	*ctrl_base = (vaddr_t)phys_to_virt(pctrl_base, MEM_AREA_IO_SEC);
	if (!*ctrl_base)
		EMSG("CAAM control base MMU VA mapping failure");

	HAL_TRACE("Map Controller 0x%" PRIxVA, *ctrl_base);
}

void caam_hal_cfg_get_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg)
{
	paddr_t jr_offset = 0;
	int jr_it_num = 0;
	int node = 0;

	jr_offset = find_jr_offset(fdt, DT_STATUS_OK_SEC, &node);
	if (jr_offset) {
		/* Disable JR for Normal World */
		if (dt_enable_secure_status(fdt, node)) {
			EMSG("Not able to disable JR DTB entry");
			return;
		}

		/* Get the job ring interrupt */
		jr_it_num = dt_get_irq(fdt, node);
		if (jr_it_num == DT_INFO_INVALID_INTERRUPT) {
			EMSG("Job Ring interrupt number not defined in DTB");
			return;
		}

		jrcfg->offset = jr_offset;
		/* Add index of the first SPI interrupt */
		jrcfg->it_num = jr_it_num + 32;
	}
}

void caam_hal_cfg_disable_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg)
{
	int node = fdt_node_offset_by_compatible(fdt, 0, dt_jr_match_table);

	for (; node != -FDT_ERR_NOTFOUND;
	     node = fdt_node_offset_by_compatible(fdt, node,
						  dt_jr_match_table)) {
		HAL_TRACE("Found Job Ring node @%" PRId32, node);
		if (_fdt_reg_base_address(fdt, node) == jrcfg->offset) {
			HAL_TRACE("Disable Job Ring node @%" PRId32, node);
			if (dt_enable_secure_status(fdt, node))
				panic();
			break;
		}
	}
}
