/*
 * Copyright 2022-2023 Arm Limited and/or its affiliates
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

/****************************************************************************
 * Includes
 ****************************************************************************/

#include "ethosu_capabilities.h"

#include "ethosu_core_rpmsg.h"
#include "ethosu_device.h"

#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>

/****************************************************************************
 * Defines
 ****************************************************************************/

#define CAPABILITIES_RESP_TIMEOUT_MS 2000

/****************************************************************************
 * Functions
 ****************************************************************************/

static inline int ethosu_capabilities_send(struct ethosu_capabilities *cap,
					   struct ethosu_mailbox *mailbox)
{
	return ethosu_mailbox_capabilities_request(mailbox,
						   &cap->msg);
}

static void ethosu_capabilities_fail(struct ethosu_mailbox_msg *msg)
{
	struct ethosu_capabilities *cap =
		container_of(msg, typeof(*cap), msg);

	if (completion_done(&cap->done))
		return;

	cap->errno = -EFAULT;
	complete(&cap->done);
}

void ethosu_capability_rsp(struct ethosu_mailbox *mailbox,
			   int msg_id,
			   struct ethosu_core_msg_capabilities_rsp *rsp)
{
	struct device *dev = mailbox->dev;
	struct ethosu_mailbox_msg *msg;
	struct ethosu_capabilities *cap;

	msg = ethosu_mailbox_find(mailbox, msg_id,
				  ETHOSU_CORE_MSG_CAPABILITIES_REQ);
	if (IS_ERR(msg)) {
		dev_warn(dev,
			 "Id for capabilities msg not found. Id=0x%0x: %ld\n",
			 msg_id, PTR_ERR(msg));

		return;
	}

	cap = container_of(msg, typeof(*cap), msg);

	if (completion_done(&cap->done))
		return;

	cap->uapi->hw_id.version_status = rsp->version_status;
	cap->uapi->hw_id.version_minor = rsp->version_minor;
	cap->uapi->hw_id.version_major = rsp->version_major;
	cap->uapi->hw_id.product_major = rsp->product_major;
	cap->uapi->hw_id.arch_patch_rev = rsp->arch_patch_rev;
	cap->uapi->hw_id.arch_minor_rev = rsp->arch_minor_rev;
	cap->uapi->hw_id.arch_major_rev = rsp->arch_major_rev;
	cap->uapi->driver_patch_rev = rsp->driver_patch_rev;
	cap->uapi->driver_minor_rev = rsp->driver_minor_rev;
	cap->uapi->driver_major_rev = rsp->driver_major_rev;
	cap->uapi->hw_cfg.macs_per_cc = rsp->macs_per_cc;
	cap->uapi->hw_cfg.cmd_stream_version = rsp->cmd_stream_version;
	cap->uapi->hw_cfg.custom_dma = rsp->custom_dma;

	cap->errno = 0;
	complete(&cap->done);
}

int ethosu_capabilities_request(struct device *dev,
				struct ethosu_mailbox *mailbox,
				struct ethosu_uapi_device_capabilities *uapi)
{
	struct ethosu_capabilities *cap;
	int ret;
	int timeout;

	cap = devm_kzalloc(dev, sizeof(struct ethosu_capabilities),
			   GFP_KERNEL);
	if (!cap)
		return -ENOMEM;

	cap->dev = dev;
	cap->uapi = uapi;
	init_completion(&cap->done);
	cap->msg.fail = ethosu_capabilities_fail;

	ret = ethosu_mailbox_register(mailbox, &cap->msg);
	if (ret < 0)
		goto kfree;

	dev_info(dev, "Capabilities create. Id=%d, handle=0x%p\n",
		 cap->msg.id, cap);

	ret = ethosu_capabilities_send(cap, mailbox);
	if (0 != ret)
		goto deregister;

	/* Unlock the mutex before going to block on the condition */
	device_unlock(dev);

	/* wait for response to arrive back */
	timeout = wait_for_completion_timeout(&cap->done,
					      msecs_to_jiffies(
						      CAPABILITIES_RESP_TIMEOUT_MS));

	/* take back the mutex before resuming to do anything */
	device_lock(dev);

	if (0 == timeout) {
		dev_warn(dev, "Capabilities response timeout");
		ret = -ETIME;
		goto deregister;
	}

	if (cap->errno) {
		ret = cap->errno;
		goto deregister;
	}

deregister:
	ethosu_mailbox_deregister(mailbox, &cap->msg);

kfree:
	dev_info(dev, "Capabilities destroy. Id=%d, handle=0x%p\n",
		 cap->msg.id, cap);
	devm_kfree(dev, cap);

	return ret;
}
