// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright 2018-2019 NXP
 *
 * Brief   CAAM Job Rings Hardware Abstration Layer.
 *          Implementation of primitives to access HW
 */
#include <caam_common.h>
#include <caam_hal_jr.h>
#include <caam_io.h>
#include <caam_pwr.h>
#include <caam_utils_delay.h>
#include <registers/ctrl_regs.h>
#include <registers/jr_regs.h>

/*
 * List of common JR registers to save/restore
 */
static const struct reglist jr_backup[] = {
	BACKUP_REG(JRX_IRBAR, 2, 0, 0),
	BACKUP_REG(JRX_IRSR, 1, 0, 0),
	BACKUP_REG(JRX_ORBAR, 2, 0, 0),
	BACKUP_REG(JRX_ORSR, 1, 0, 0),
	BACKUP_REG(JRX_JRCFGR_LS, 1, 0, 0),
};

enum caam_status caam_hal_jr_reset(vaddr_t baseaddr)
{
	uint16_t timeout = 10000;
	uint32_t reg_val = 0;

	/*
	 * Reset is done in 2 steps:
	 *  - Flush all pending jobs (Set RESET bit)
	 *  - Reset the Job Ring (Set RESET bit second time)
	 */

	/* Mask interrupts to poll for reset completion status */
	io_setbits32(baseaddr + JRX_JRCFGR_LS, JRX_JRCFGR_LS_IMSK);

	/* Initiate flush (required prior to reset) */
	io_caam_write32(baseaddr + JRX_JRCR, JRX_JRCR_RESET);

	do {
		caam_udelay(100);
		reg_val = io_caam_read32(baseaddr + JRX_JRINTR);
		reg_val &= BM_JRX_JRINTR_HALT;
	} while ((reg_val == JRINTR_HALT_ONGOING) && --timeout);

	if (!timeout || reg_val != JRINTR_HALT_DONE) {
		EMSG("Failed to flush job ring\n");
		return CAAM_FAILURE;
	}

	/* Initiate reset */
	timeout = 100;
	io_caam_write32(baseaddr + JRX_JRCR, JRX_JRCR_RESET);
	do {
		caam_udelay(100);
		reg_val = io_caam_read32(baseaddr + JRX_JRCR);
	} while ((reg_val & JRX_JRCR_RESET) && --timeout);

	if (!timeout) {
		EMSG("Failed to reset job ring\n");
		return CAAM_FAILURE;
	}

	return CAAM_NO_ERROR;
}

void caam_hal_jr_config(vaddr_t baseaddr, uint8_t nbjobs, uint64_t inrings,
			uint64_t outrings)
{
	uint32_t value = 0;

	/* Setup the JR input queue */
	io_caam_write32(baseaddr + JRX_IRBAR, inrings >> 32);
	io_caam_write32(baseaddr + JRX_IRBAR + 4, inrings);
	io_caam_write32(baseaddr + JRX_IRSR, nbjobs);

	/* Setup the JR output queue */
	io_caam_write32(baseaddr + JRX_ORBAR, outrings >> 32);
	io_caam_write32(baseaddr + JRX_ORBAR + 4, outrings);
	io_caam_write32(baseaddr + JRX_ORSR, nbjobs);

	/* Disable the JR interrupt */
	caam_hal_jr_disable_itr(baseaddr);

	/*
	 * Configure interrupt and disable it:
	 * Optimization to generate an interrupt either when there are
	 *   half of the job done
	 *   or when there is a job done and 10 clock cycles elapsed without
	 *      new job completion
	 */
	value = JRX_JRCFGR_LS_ICTT(10);
	value |= JRX_JRCFGR_LS_ICDCT(nbjobs / 2);
	value |= JRX_JRCFGR_LS_ICEN;
	value |= JRX_JRCFGR_LS_IMSK;
	io_caam_write32(baseaddr + JRX_JRCFGR_LS, value);

#ifdef CFG_NXP_CAAM_RUNTIME_JR
	caam_pwr_add_backup(baseaddr, jr_backup, ARRAY_SIZE(jr_backup));
#endif
}

uint32_t caam_hal_jr_read_nbslot_available(vaddr_t baseaddr)
{
	return io_caam_read32(baseaddr + JRX_IRSAR);
}

void caam_hal_jr_add_newjob(vaddr_t baseaddr)
{
	io_caam_write32(baseaddr + JRX_IRJAR, 1);
}

uint32_t caam_hal_jr_get_nbjob_done(vaddr_t baseaddr)
{
	return io_caam_read32(baseaddr + JRX_ORSFR);
}

void caam_hal_jr_del_job(vaddr_t baseaddr)
{
	io_caam_write32(baseaddr + JRX_ORJRR, 1);
}

void caam_hal_jr_disable_itr(vaddr_t baseaddr)
{
	io_setbits32(baseaddr + JRX_JRCFGR_LS, JRX_JRCFGR_LS_IMSK);
	io_setbits32(baseaddr + JRX_JRINTR, JRX_JRINTR_JRI);
}

void caam_hal_jr_enable_itr(vaddr_t baseaddr)
{
	io_mask32(baseaddr + JRX_JRCFGR_LS, ~JRX_JRCFGR_LS_IMSK,
		  JRX_JRCFGR_LS_IMSK);
}

bool caam_hal_jr_check_ack_itr(vaddr_t baseaddr)
{
	uint32_t val = 0;

	val = io_caam_read32(baseaddr + JRX_JRINTR);

	if ((val & JRX_JRINTR_JRI) == JRX_JRINTR_JRI) {
		/* Acknowledge interrupt */
		io_setbits32(baseaddr + JRX_JRINTR, JRX_JRINTR_JRI);
		return true;
	}

	return false;
}

enum caam_status caam_hal_jr_halt(vaddr_t baseaddr)
{
	uint16_t timeout = 10000;
	uint32_t val = 0;

	/* Mask interrupts to poll for completion status */
	io_setbits32(baseaddr + JRX_JRCFGR_LS, JRX_JRCFGR_LS_IMSK);

	/* Request Job ring halt */
	io_caam_write32(baseaddr + JRX_JRCR, JRX_JRCR_PARK);

	/* Check if there is a job running */
	val = io_caam_read32(baseaddr + JRX_IRSR);
	if ((caam_hal_jr_read_nbslot_available(baseaddr) == val) &&
	    (io_caam_read32(baseaddr + JRX_CSTA) != JRX_CSTA_BSY))
		return CAAM_NO_ERROR;

	/* Wait until all jobs complete */
	do {
		caam_udelay(10);
		val = io_caam_read32(baseaddr + JRX_JRINTR);
		val &= BM_JRX_JRINTR_HALT;
	} while ((val != JRINTR_HALT_DONE) && --timeout);

	if (!timeout)
		return CAAM_BUSY;

	return CAAM_NO_ERROR;
}

enum caam_status caam_hal_jr_flush(vaddr_t baseaddr)
{
	uint16_t timeout = 10000;
	uint32_t val = 0;

	/* Mask interrupts to poll for completion status */
	io_setbits32(baseaddr + JRX_JRCFGR_LS, JRX_JRCFGR_LS_IMSK);

	/* Request Job ring to flush input queue */
	io_caam_write32(baseaddr + JRX_JRCR, JRX_JRCR_RESET);

	/* Check if there is a job running */
	val = io_caam_read32(baseaddr + JRX_IRSR);
	if ((caam_hal_jr_read_nbslot_available(baseaddr) == val) &&
	    (io_caam_read32(baseaddr + JRX_CSTA) != JRX_CSTA_BSY))
		return CAAM_NO_ERROR;

	/* Wait until all jobs complete */
	do {
		caam_udelay(10);
		val = io_caam_read32(baseaddr + JRX_JRINTR);
		val &= BM_JRX_JRINTR_HALT;
	} while ((val == JRINTR_HALT_DONE) && --timeout);

	if (!timeout)
		return CAAM_BUSY;

	return CAAM_NO_ERROR;
}

void caam_hal_jr_resume(vaddr_t baseaddr)
{
	io_caam_write32(baseaddr + JRX_JRINTR, JRINTR_HALT_RESUME);

	caam_hal_jr_enable_itr(baseaddr);
}

uint8_t caam_hal_jr_input_index(vaddr_t baseaddr)
{
	return io_caam_read32(baseaddr + JRX_IRRIR) >> 2;
}

uint8_t caam_hal_jr_output_index(vaddr_t baseaddr)
{
	return io_caam_read32(baseaddr + JRX_ORWIR) >> 3;
}
