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

#include <arch_helpers.h>
#include <assert.h>
#include <bpmp.h>
#include <common/debug.h>
#include <delay_timer.h>
#include <errno.h>
#include <mmio.h>
#include <platform.h>
#include <stdbool.h>
#include <string.h>
#include <tegra_def.h>

#define BPMP_TIMEOUT	2

static uint32_t channel_base[NR_CHANNELS];
static uint32_t bpmp_init_state = BPMP_INIT_PENDING;

static uint32_t channel_field(unsigned int ch)
{
	return mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET) & CH_MASK(ch);
}

static bool master_free(unsigned int ch)
{
	return channel_field(ch) == MA_FREE(ch);
}

static bool master_acked(unsigned int ch)
{
	return channel_field(ch) == MA_ACKD(ch);
}

static void signal_slave(unsigned int ch)
{
	mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET, CH_MASK(ch));
}

static void free_master(unsigned int ch)
{
	mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET,
		      MA_ACKD(ch) ^ MA_FREE(ch));
}

/* should be called with local irqs disabled */
int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz,
		void *ib_data, int ib_sz)
{
	unsigned int ch = (unsigned int)plat_my_core_pos();
	mb_data_t *p = (mb_data_t *)(uintptr_t)channel_base[ch];
	int32_t ret = -ETIMEDOUT, timeout = 0;

	if (bpmp_init_state == BPMP_INIT_COMPLETE) {

		/* loop until BPMP is free */
		for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
			if (master_free(ch) == true) {
				break;
			}

			mdelay(1);
		}

		if (timeout != BPMP_TIMEOUT) {

			/* generate the command struct */
			p->code = mrq;
			p->flags = DO_ACK;
			(void)memcpy((void *)p->data, ob_data, (size_t)ob_sz);

			/* signal command ready to the BPMP */
			signal_slave(ch);
			mmio_write_32(TEGRA_PRI_ICTLR_BASE + CPU_IEP_FIR_SET,
				      (1U << INT_SHR_SEM_OUTBOX_FULL));

			/* loop until the command is executed */
			for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
				if (master_acked(ch) == true) {
					break;
				}

				mdelay(1);
			}

			if (timeout != BPMP_TIMEOUT) {

				/* get the command response */
				(void)memcpy(ib_data, (const void *)p->data,
					     (size_t)ib_sz);

				/* return error code */
				ret = p->code;

				/* free this channel */
				free_master(ch);
			}
		}

	} else {
		/* return error code */
		ret = -EINVAL;
	}

	if (timeout == BPMP_TIMEOUT) {
		ERROR("Timed out waiting for bpmp's response\n");
	}

	return ret;
}

int tegra_bpmp_init(void)
{
	uint32_t val, base;
	unsigned int ch;
	int ret = 0;

	if (bpmp_init_state != BPMP_INIT_COMPLETE) {

		/* check if the bpmp processor is alive. */
		val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
		if (val != SIGN_OF_LIFE) {
			ERROR("BPMP precessor not available\n");
			ret = -ENOTSUP;
		}

		/* check if clock for the atomics block is enabled */
		val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_ENB_V);
		if ((val & CAR_ENABLE_ATOMICS) == 0) {
			ERROR("Clock to the atomics block is disabled\n");
		}

		/* check if the atomics block is out of reset */
		val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_CLR_V);
		if ((val & CAR_ENABLE_ATOMICS) == CAR_ENABLE_ATOMICS) {
			ERROR("Reset to the atomics block is asserted\n");
		}

		/* base address to get the result from Atomics */
		base = TEGRA_ATOMICS_BASE + RESULT0_REG_OFFSET;

		/* channel area is setup by BPMP before signaling handshake */
		for (ch = 0; ch < NR_CHANNELS; ch++) {

			/* issue command to get the channel base address */
			mmio_write_32(base, (ch << TRIGGER_ID_SHIFT) |
				      ATOMIC_CMD_GET);

			/* get the base address for the channel */
			channel_base[ch] = mmio_read_32(base);

			/* increment result register offset */
			base += 4U;
		}

		/* mark state as "initialized" */
		if (ret == 0)
			bpmp_init_state = BPMP_INIT_COMPLETE;

		/* the channel values have to be visible across all cpus */
		flush_dcache_range((uint64_t)channel_base, sizeof(channel_base));
		flush_dcache_range((uint64_t)&bpmp_init_state,
				   sizeof(bpmp_init_state));

		INFO("%s: done\n", __func__);
	}

	return ret;
}
