/*
 * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
 * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <stdbool.h>

#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <tegra_platform.h>

#include "se_private.h"

/*******************************************************************************
 * Constants and Macros
 ******************************************************************************/
#define ERR_STATUS_SW_CLEAR	U(0xFFFFFFFF)
#define INT_STATUS_SW_CLEAR	U(0xFFFFFFFF)
#define MAX_TIMEOUT_MS		U(100)	/* Timeout in 100ms */
#define NUM_SE_REGS_TO_SAVE	U(4)

/*******************************************************************************
 * Data structure and global variables
 ******************************************************************************/
static uint32_t se_regs[NUM_SE_REGS_TO_SAVE];

/*
 * Check that SE operation has completed after kickoff.
 *
 * This function is invoked after an SE operation has been started,
 * and it checks the following conditions:
 *
 * 1. SE_STATUS = IDLE
 * 2. AHB bus data transfer is complete.
 * 3. SE_ERR_STATUS is clean.
 */
static bool tegra_se_is_operation_complete(void)
{
	uint32_t val = 0, timeout = 0, sha_status, aes_status;
	int32_t ret = 0;
	bool se_is_busy, txn_has_errors, txn_successful;

	/*
	 * Poll the status register to check if the operation
	 * completed.
	 */
	do {
		val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS);
		se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY);

		/* sleep until SE finishes */
		if (se_is_busy) {
			mdelay(1);
			timeout++;
		}

	} while (se_is_busy && (timeout < MAX_TIMEOUT_MS));

	/* any transaction errors? */
	txn_has_errors = (tegra_se_read_32(SHA_ERR_STATUS) != 0U) ||
			 (tegra_se_read_32(AES0_ERR_STATUS) != 0U);

	/* transaction successful? */
	sha_status = tegra_se_read_32(SHA_INT_STATUS) & SHA_SE_OP_DONE;
	aes_status = tegra_se_read_32(AES0_INT_STATUS) & AES0_SE_OP_DONE;
	txn_successful = (sha_status == SHA_SE_OP_DONE) &&
			 (aes_status == AES0_SE_OP_DONE);

	if ((timeout == MAX_TIMEOUT_MS) || txn_has_errors || !txn_successful) {
		ERROR("%s: Atomic context save operation failed!\n",
				__func__);
		ret = -ECANCELED;
	}

	return (ret == 0);
}

/*
 * Wait for SE engine to be idle and clear any pending interrupts, before
 * starting the next SE operation.
 */
static bool tegra_se_is_ready(void)
{
	int32_t ret = 0;
	uint32_t val = 0, timeout = 0;
	bool se_is_ready;

	/* Wait for previous operation to finish */
	do {
		val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS);
		se_is_ready = (val == CTX_SAVE_AUTO_SE_READY);

		/* sleep until SE is ready */
		if (!se_is_ready) {
			mdelay(1);
			timeout++;
		}

	} while (!se_is_ready && (timeout < MAX_TIMEOUT_MS));

	if (timeout == MAX_TIMEOUT_MS) {
		ERROR("%s: SE is not ready!\n", __func__);
		ret = -ETIMEDOUT;
	}

	/* Clear any pending interrupts from previous operation */
	tegra_se_write_32(AES0_INT_STATUS, INT_STATUS_SW_CLEAR);
	tegra_se_write_32(AES1_INT_STATUS, INT_STATUS_SW_CLEAR);
	tegra_se_write_32(RSA_INT_STATUS, INT_STATUS_SW_CLEAR);
	tegra_se_write_32(SHA_INT_STATUS, INT_STATUS_SW_CLEAR);

	/* Clear error status for each engine seen from current port */
	tegra_se_write_32(AES0_ERR_STATUS, ERR_STATUS_SW_CLEAR);
	tegra_se_write_32(AES1_ERR_STATUS, ERR_STATUS_SW_CLEAR);
	tegra_se_write_32(RSA_ERR_STATUS, ERR_STATUS_SW_CLEAR);
	tegra_se_write_32(SHA_ERR_STATUS, ERR_STATUS_SW_CLEAR);

	return (ret == 0);
}

/*
 * During System Suspend, this handler triggers the hardware context
 * save operation.
 */
static int32_t tegra_se_save_context(void)
{
	int32_t ret = -ECANCELED;

	/*
	 * 1. Ensure all SE Driver including RNG1/PKA1 are shut down.
	 *    TSEC/R5s are powergated/idle. All tasks on SE1~SE4, RNG1,
	 *    PKA1 are wrapped up. SE0 is ready for use.
	 * 2. Clear interrupt/error in SE0 status register.
	 * 3. Scrub SE0 register to avoid false failure for illegal
	 *    configuration. Probably not needed, dependent on HW
	 *    implementation.
	 * 4. Check SE is ready for HW CTX_SAVE by polling
	 *    SE_CTX_SAVE_AUTO_STATUS.SE_READY.
	 *
	 *    Steps 1-4 are executed by tegra_se_is_ready().
	 *
	 * 5. Issue context save command.
	 * 6. Check SE is busy with CTX_SAVE, the command in step5 was not
	 *    dropped for ongoing traffic in any of SE port/engine.
	 * 7. Poll SE register or wait for SE APB interrupt for task completion
	 *    a. Polling: Read SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE
	 *    b. Interrupt: After receiving interrupt from SE APB, read
	 *       SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE.
	 * 8. Check AES0 and SHA ERR_STATUS to ensure no error case.
	 * 9. Check AES0 and SHA INT_STATUS to ensure operation has successfully
	 *    completed.
	 *
	 *    Steps 6-9 are executed by tegra_se_is_operation_complete().
	 */
	if (tegra_se_is_ready()) {

		/* Issue context save command */
		tegra_se_write_32(AES0_OPERATION, SE_OP_CTX_SAVE);

		/* Wait for operation to finish */
		if (tegra_se_is_operation_complete()) {
			ret = 0;
		}
	}

	return ret;
}

/*
 * Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This
 * needs to be called only during System Suspend.
 */
int32_t tegra_se_suspend(void)
{
	int32_t ret = 0;

	/* save SE registers */
	se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT);
	se_regs[1] = mmio_read_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL);
	se_regs[2] = mmio_read_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT);
	se_regs[3] = mmio_read_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT);

	/* Save SE context. The BootROM restores it during System Resume */
	ret = tegra_se_save_context();
	if (ret != 0) {
		ERROR("%s: context save failed (%d)\n", __func__, ret);
	}

	return ret;
}

/*
 * Handler to power up the SE hardware block(s) during System Resume.
 */
void tegra_se_resume(void)
{
	/*
	 * When TZ takes over after System Resume, TZ should first reconfigure
	 * SE_MUTEX_WATCHDOG_NS_LIMIT, PKA1_MUTEX_WATCHDOG_NS_LIMIT,
	 * RNG1_MUTEX_WATCHDOG_NS_LIMIT and SE_ENTROPY_SRC_AGE_CTRL before
	 * other operations.
	 */
	mmio_write_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT, se_regs[0]);
	mmio_write_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL, se_regs[1]);
	mmio_write_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[2]);
	mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]);
}
