// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2019 MediaTek Inc.

#include <asm/barrier.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/remoteproc/mtk_scp.h>

#include "mtk_common.h"

/**
 * scp_ipi_register() - register an ipi function
 *
 * @scp:	mtk_scp structure
 * @id:		IPI ID
 * @handler:	IPI handler
 * @priv:	private data for IPI handler
 *
 * Register an ipi function to receive ipi interrupt from SCP.
 *
 * Returns 0 if ipi registers successfully, -error on error.
 */
int scp_ipi_register(struct mtk_scp *scp,
		     u32 id,
		     scp_ipi_handler_t handler,
		     void *priv)
{
	if (!scp)
		return -EPROBE_DEFER;

	if (WARN_ON(id >= SCP_IPI_MAX) || WARN_ON(handler == NULL))
		return -EINVAL;

	scp_ipi_lock(scp, id);
	scp->ipi_desc[id].handler = handler;
	scp->ipi_desc[id].priv = priv;
	scp_ipi_unlock(scp, id);

	return 0;
}
EXPORT_SYMBOL_GPL(scp_ipi_register);

/**
 * scp_ipi_unregister() - unregister an ipi function
 *
 * @scp:	mtk_scp structure
 * @id:		IPI ID
 *
 * Unregister an ipi function to receive ipi interrupt from SCP.
 */
void scp_ipi_unregister(struct mtk_scp *scp, u32 id)
{
	if (!scp)
		return;

	if (WARN_ON(id >= SCP_IPI_MAX))
		return;

	scp_ipi_lock(scp, id);
	scp->ipi_desc[id].handler = NULL;
	scp->ipi_desc[id].priv = NULL;
	scp_ipi_unlock(scp, id);
}
EXPORT_SYMBOL_GPL(scp_ipi_unregister);

/*
 * scp_memcpy_aligned() - Copy src to dst, where dst is in SCP SRAM region.
 *
 * @dst:	Pointer to the destination buffer, should be in SCP SRAM region.
 * @src:	Pointer to the source buffer.
 * @len:	Length of the source buffer to be copied.
 *
 * Since AP access of SCP SRAM don't support byte write, this always write a
 * full word at a time, and may cause some extra bytes to be written at the
 * beginning & ending of dst.
 */
void scp_memcpy_aligned(void __iomem *dst, const void *src, unsigned int len)
{
	void __iomem *ptr;
	u32 val;
	unsigned int i = 0, remain;

	if (!IS_ALIGNED((unsigned long)dst, 4)) {
		ptr = (void __iomem *)ALIGN_DOWN((unsigned long)dst, 4);
		i = 4 - (dst - ptr);
		val = readl_relaxed(ptr);
		memcpy((u8 *)&val + (4 - i), src, i);
		writel_relaxed(val, ptr);
	}

	__iowrite32_copy(dst + i, src + i, (len - i) / 4);
	remain = (len - i) % 4;

	if (remain > 0) {
		val = readl_relaxed(dst + len - remain);
		memcpy(&val, src + len - remain, remain);
		writel_relaxed(val, dst + len - remain);
	}
}
EXPORT_SYMBOL_GPL(scp_memcpy_aligned);

/**
 * scp_ipi_lock() - Lock before operations of an IPI ID
 *
 * @scp:	mtk_scp structure
 * @id:		IPI ID
 *
 * Note: This should not be used by drivers other than mtk_scp.
 */
void scp_ipi_lock(struct mtk_scp *scp, u32 id)
{
	if (WARN_ON(id >= SCP_IPI_MAX))
		return;
	mutex_lock(&scp->ipi_desc[id].lock);
}
EXPORT_SYMBOL_GPL(scp_ipi_lock);

/**
 * scp_ipi_lock() - Unlock after operations of an IPI ID
 *
 * @scp:	mtk_scp structure
 * @id:		IPI ID
 *
 * Note: This should not be used by drivers other than mtk_scp.
 */
void scp_ipi_unlock(struct mtk_scp *scp, u32 id)
{
	if (WARN_ON(id >= SCP_IPI_MAX))
		return;
	mutex_unlock(&scp->ipi_desc[id].lock);
}
EXPORT_SYMBOL_GPL(scp_ipi_unlock);

/**
 * scp_ipi_send() - send data from AP to scp.
 *
 * @scp:	mtk_scp structure
 * @id:		IPI ID
 * @buf:	the data buffer
 * @len:	the data buffer length
 * @wait:	number of msecs to wait for ack. 0 to skip waiting.
 *
 * This function is thread-safe. When this function returns,
 * SCP has received the data and starts the processing.
 * When the processing completes, IPI handler registered
 * by scp_ipi_register will be called in interrupt context.
 *
 * Returns 0 if sending data successfully, -error on error.
 **/
int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len,
		 unsigned int wait)
{
	struct mtk_share_obj __iomem *send_obj = scp->send_buf;
	unsigned long timeout;
	int ret;

	if (WARN_ON(id <= SCP_IPI_INIT) || WARN_ON(id >= SCP_IPI_MAX) ||
	    WARN_ON(id == SCP_IPI_NS_SERVICE) ||
	    WARN_ON(len > sizeof(send_obj->share_buf)) || WARN_ON(!buf))
		return -EINVAL;

	ret = clk_prepare_enable(scp->clk);
	if (ret) {
		dev_err(scp->dev, "failed to enable clock\n");
		return ret;
	}

	mutex_lock(&scp->send_lock);

	 /* Wait until SCP receives the last command */
	timeout = jiffies + msecs_to_jiffies(2000);
	do {
		if (time_after(jiffies, timeout)) {
			dev_err(scp->dev, "%s: IPI timeout!\n", __func__);
			ret = -ETIMEDOUT;
			goto unlock_mutex;
		}
	} while (readl(scp->reg_base + scp->data->host_to_scp_reg));

	scp_memcpy_aligned(send_obj->share_buf, buf, len);

	writel(len, &send_obj->len);
	writel(id, &send_obj->id);

	scp->ipi_id_ack[id] = false;
	/* send the command to SCP */
	writel(scp->data->host_to_scp_int_bit,
	       scp->reg_base + scp->data->host_to_scp_reg);

	if (wait) {
		/* wait for SCP's ACK */
		timeout = msecs_to_jiffies(wait);
		ret = wait_event_timeout(scp->ack_wq,
					 scp->ipi_id_ack[id],
					 timeout);
		scp->ipi_id_ack[id] = false;
		if (WARN(!ret, "scp ipi %d ack time out !", id))
			ret = -EIO;
		else
			ret = 0;
	}

unlock_mutex:
	mutex_unlock(&scp->send_lock);
	clk_disable_unprepare(scp->clk);

	return ret;
}
EXPORT_SYMBOL_GPL(scp_ipi_send);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek scp IPI interface");
