/*
 * 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) {
			return -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" */
		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;
}
