/*
 * Texas Instruments K3 Secure Proxy Driver
 *   Based on Linux and U-Boot implementation
 *
 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>
#include <debug.h>
#include <errno.h>
#include <mmio.h>
#include <platform_def.h>
#include <stdlib.h>
#include <utils.h>
#include <utils_def.h>

#include "sec_proxy.h"

/* SEC PROXY RT THREAD STATUS */
#define RT_THREAD_STATUS			(0x0)
#define RT_THREAD_STATUS_ERROR_SHIFT		(31)
#define RT_THREAD_STATUS_ERROR_MASK		BIT(31)
#define RT_THREAD_STATUS_CUR_CNT_SHIFT		(0)
#define RT_THREAD_STATUS_CUR_CNT_MASK		GENMASK(7, 0)

/* SEC PROXY SCFG THREAD CTRL */
#define SCFG_THREAD_CTRL			(0x1000)
#define SCFG_THREAD_CTRL_DIR_SHIFT		(31)
#define SCFG_THREAD_CTRL_DIR_MASK		BIT(31)

#define SEC_PROXY_THREAD(base, x)		((base) + (0x1000 * (x)))
#define THREAD_IS_RX				(1)
#define THREAD_IS_TX				(0)

/**
 * struct k3_sec_proxy_desc - Description of secure proxy integration
 * @timeout_us:		Timeout for communication (in Microseconds)
 * @max_msg_size:	Message size in bytes
 * @data_start_offset:	Offset of the First data register of the thread
 * @data_end_offset:	Offset of the Last data register of the thread
 */
struct k3_sec_proxy_desc {
	uint32_t timeout_us;
	uint16_t max_msg_size;
	uint16_t data_start_offset;
	uint16_t data_end_offset;
};

/**
 * struct k3_sec_proxy_thread - Description of a secure proxy Thread
 * @id:		Thread ID
 * @data:	Thread Data path region for target
 * @scfg:	Secure Config Region for Thread
 * @rt:		RealTime Region for Thread
 */
struct k3_sec_proxy_thread {
	uint32_t id;
	uintptr_t data;
	uintptr_t scfg;
	uintptr_t rt;
};

/**
 * struct k3_sec_proxy_mbox - Description of a Secure Proxy Instance
 * @desc:	Description of the SoC integration
 * @chans:	Array for valid thread instances
 */
struct k3_sec_proxy_mbox {
	const struct k3_sec_proxy_desc desc;
	struct k3_sec_proxy_thread threads[];
};

/*
 * Thread ID #0: DMSC notify
 * Thread ID #1: DMSC request response
 * Thread ID #2: DMSC request high priority
 * Thread ID #3: DMSC request low priority
 * Thread ID #4: DMSC notify response
 */
#define SP_THREAD(_x) \
	[_x] = { \
		.id = _x, \
		.data = SEC_PROXY_THREAD(SEC_PROXY_DATA_BASE, _x), \
		.scfg = SEC_PROXY_THREAD(SEC_PROXY_SCFG_BASE, _x), \
		.rt = SEC_PROXY_THREAD(SEC_PROXY_RT_BASE, _x), \
	}

static struct k3_sec_proxy_mbox spm = {
	.desc = {
		.timeout_us = SEC_PROXY_TIMEOUT_US,
		.max_msg_size = SEC_PROXY_MAX_MESSAGE_SIZE,
		.data_start_offset = 0x4,
		.data_end_offset = 0x3C,
	},
	.threads = {
		SP_THREAD(SP_NOTIFY),
		SP_THREAD(SP_RESPONSE),
		SP_THREAD(SP_HIGH_PRIORITY),
		SP_THREAD(SP_LOW_PRIORITY),
		SP_THREAD(SP_NOTIFY_RESP),
	},
};

/**
 * struct sec_msg_hdr - Message header for secure messages and responses
 * @checksum:	CRC of message for integrity checking
 */
union sec_msg_hdr {
	struct {
		uint16_t checksum;
		uint16_t reserved;
	} __packed;
	uint32_t data;
};

/**
 * k3_sec_proxy_verify_thread() - Verify thread status before
 *				  sending/receiving data
 * @spt: Pointer to Secure Proxy thread description
 * @dir: Direction of the thread
 *
 * Return: 0 if all goes well, else appropriate error message
 */
static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt,
					     uint32_t dir)
{
	/* Check for any errors already available */
	if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
	    RT_THREAD_STATUS_ERROR_MASK) {
		ERROR("Thread %d is corrupted, cannot send data\n", spt->id);
		return -EINVAL;
	}

	/* Make sure thread is configured for right direction */
	if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)
	    != (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) {
		if (dir)
			ERROR("Trying to receive data on tx Thread %d\n",
			      spt->id);
		else
			ERROR("Trying to send data on rx Thread %d\n",
			      spt->id);
		return -EINVAL;
	}

	/* Check the message queue before sending/receiving data */
	uint32_t tick_start = (uint32_t)read_cntpct_el0();
	uint32_t ticks_per_us = SYS_COUNTER_FREQ_IN_TICKS / 1000000;
	while (!(mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK)) {
		VERBOSE("Waiting for thread %d to clear\n", spt->id);
		if (((uint32_t)read_cntpct_el0() - tick_start) >
		    (spm.desc.timeout_us * ticks_per_us)) {
			ERROR("Timeout waiting for thread %d to clear\n", spt->id);
			return -ETIMEDOUT;
		}
	}

	return 0;
}

/**
 * k3_sec_proxy_send() - Send data over a Secure Proxy thread
 * @id: Channel Identifier
 * @msg: Pointer to k3_sec_proxy_msg
 *
 * Return: 0 if all goes well, else appropriate error message
 */
int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_msg *msg)
{
	struct k3_sec_proxy_thread *spt = &spm.threads[id];
	union sec_msg_hdr secure_header;
	int num_words, trail_bytes, i, ret;
	uintptr_t data_reg;

	ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_TX);
	if (ret) {
		ERROR("Thread %d verification failed (%d)\n", spt->id, ret);
		return ret;
	}

	/* Check the message size */
	if (msg->len + sizeof(secure_header) > spm.desc.max_msg_size) {
		ERROR("Thread %d message length %lu > max msg size\n",
		      spt->id, msg->len);
		return -EINVAL;
	}

	/* TODO: Calculate checksum */
	secure_header.checksum = 0;

	/* Send the secure header */
	data_reg = spm.desc.data_start_offset;
	mmio_write_32(spt->data + data_reg, secure_header.data);
	data_reg += sizeof(uint32_t);

	/* Send whole words */
	num_words = msg->len / sizeof(uint32_t);
	for (i = 0; i < num_words; i++) {
		mmio_write_32(spt->data + data_reg, ((uint32_t *)msg->buf)[i]);
		data_reg += sizeof(uint32_t);
	}

	/* Send remaining bytes */
	trail_bytes = msg->len % sizeof(uint32_t);
	if (trail_bytes) {
		uint32_t data_trail = 0;

		i = msg->len - trail_bytes;
		while (trail_bytes--) {
			data_trail <<= 8;
			data_trail |= msg->buf[i++];
		}

		mmio_write_32(spt->data + data_reg, data_trail);
		data_reg += sizeof(uint32_t);
	}
	/*
	 * 'data_reg' indicates next register to write. If we did not already
	 * write on tx complete reg(last reg), we must do so for transmit
	 */
	if (data_reg <= spm.desc.data_end_offset)
		mmio_write_32(spt->data + spm.desc.data_end_offset, 0);

	VERBOSE("Message successfully sent on thread %ud\n", id);

	return 0;
}

/**
 * k3_sec_proxy_recv() - Receive data from a Secure Proxy thread
 * @id: Channel Identifier
 * @msg: Pointer to k3_sec_proxy_msg
 *
 * Return: 0 if all goes well, else appropriate error message
 */
int k3_sec_proxy_recv(uint32_t id, struct k3_sec_proxy_msg *msg)
{
	struct k3_sec_proxy_thread *spt = &spm.threads[id];
	union sec_msg_hdr secure_header;
	uintptr_t data_reg;
	int num_words, trail_bytes, i, ret;

	ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_RX);
	if (ret) {
		ERROR("Thread %d verification failed (%d)\n", spt->id, ret);
		return ret;
	}

	/* Read secure header */
	data_reg = spm.desc.data_start_offset;
	secure_header.data = mmio_read_32(spt->data + data_reg);
	data_reg += sizeof(uint32_t);

	/* Read whole words */
	num_words = msg->len / sizeof(uint32_t);
	for (i = 0; i < num_words; i++) {
		((uint32_t *)msg->buf)[i] = mmio_read_32(spt->data + data_reg);
		data_reg += sizeof(uint32_t);
	}

	/* Read remaining bytes */
	trail_bytes = msg->len % sizeof(uint32_t);
	if (trail_bytes) {
		uint32_t data_trail = mmio_read_32(spt->data + data_reg);
		data_reg += sizeof(uint32_t);

		i = msg->len - trail_bytes;
		while (trail_bytes--) {
			msg->buf[i] = data_trail & 0xff;
			data_trail >>= 8;
		}
	}

	/*
	 * 'data_reg' indicates next register to read. If we did not already
	 * read on rx complete reg(last reg), we must do so for receive
	 */
	if (data_reg <= spm.desc.data_end_offset)
		mmio_read_32(spt->data + spm.desc.data_end_offset);

	/* TODO: Verify checksum */
	(void)secure_header.checksum;

	VERBOSE("Message successfully received from thread %ud\n", id);

	return 0;
}
