/*
 * Copyright 2021 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 *
 */
#include <linux/debugfs.h>
#include <linux/pm_runtime.h>

#include "amdgpu.h"
#include "amdgpu_securedisplay.h"

/**
 * DOC: AMDGPU SECUREDISPLAY debugfs test interface
 *
 * how to use?
 * echo opcode <value> > <debugfs_dir>/dri/xxx/securedisplay_test
 * eg. echo 1 > <debugfs_dir>/dri/xxx/securedisplay_test
 * eg. echo 2 phy_id > <debugfs_dir>/dri/xxx/securedisplay_test
 *
 * opcode:
 * 1：Query whether TA is responding used only for validation pupose
 * 2: Send region of Interest and CRC value to I2C. (uint32)phy_id is
 * send to determine which DIO scratch register should be used to get
 * ROI and receive i2c_buf as the output.
 *
 * You can refer more detail from header file ta_securedisplay_if.h
 *
 */

void psp_securedisplay_parse_resp_status(struct psp_context *psp,
	enum ta_securedisplay_status status)
{
	switch (status) {
	case TA_SECUREDISPLAY_STATUS__SUCCESS:
		break;
	case TA_SECUREDISPLAY_STATUS__GENERIC_FAILURE:
		dev_err(psp->adev->dev, "Secure display: Generic Failure.");
		break;
	case TA_SECUREDISPLAY_STATUS__INVALID_PARAMETER:
		dev_err(psp->adev->dev, "Secure display: Invalid Parameter.");
		break;
	case TA_SECUREDISPLAY_STATUS__NULL_POINTER:
		dev_err(psp->adev->dev, "Secure display: Null Pointer.");
		break;
	case TA_SECUREDISPLAY_STATUS__I2C_WRITE_ERROR:
		dev_err(psp->adev->dev, "Secure display: Failed to write to I2C.");
		break;
	case TA_SECUREDISPLAY_STATUS__READ_DIO_SCRATCH_ERROR:
		dev_err(psp->adev->dev, "Secure display: Failed to Read DIO Scratch Register.");
		break;
	case TA_SECUREDISPLAY_STATUS__READ_CRC_ERROR:
		dev_err(psp->adev->dev, "Secure display: Failed to Read CRC");
		break;
	case TA_SECUREDISPLAY_STATUS__I2C_INIT_ERROR:
		dev_err(psp->adev->dev, "Secure display: Failed to initialize I2C.");
		break;
	default:
		dev_err(psp->adev->dev, "Secure display: Failed to parse status: %d\n", status);
	}
}

void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct ta_securedisplay_cmd **cmd,
	enum ta_securedisplay_command command_id)
{
	*cmd = (struct ta_securedisplay_cmd *)psp->securedisplay_context.context.mem_context.shared_buf;
	memset(*cmd, 0, sizeof(struct ta_securedisplay_cmd));
	(*cmd)->status = TA_SECUREDISPLAY_STATUS__GENERIC_FAILURE;
	(*cmd)->cmd_id = command_id;
}

#if defined(CONFIG_DEBUG_FS)

static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __user *buf,
		size_t size, loff_t *pos)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
	struct psp_context *psp = &adev->psp;
	struct ta_securedisplay_cmd *securedisplay_cmd;
	struct drm_device *dev = adev_to_drm(adev);
	uint32_t phy_id;
	uint32_t op;
	char str[64];
	long len;
	ssize_t write_ret = size;
	int ret, nargs;

	if (*pos)
		return -EINVAL;

	len = strncpy_from_user(str, buf, sizeof(str));
	if (len < 0)
		return -EFAULT;
	if (len == 0 || len >= sizeof(str))
		return -EINVAL;

	ret = pm_runtime_get_sync(dev->dev);
	if (ret < 0) {
		pm_runtime_put_autosuspend(dev->dev);
		return ret;
	}

	if (len < 3)
		nargs = sscanf(str, "%u", &op);
	else
		nargs = sscanf(str, "%u %u", &op, &phy_id);
	if (nargs < 1) {
		write_ret = -EINVAL;
		goto out;
	}

	switch (op) {
	case 1:
		mutex_lock(&psp->securedisplay_context.mutex);
		psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
			TA_SECUREDISPLAY_COMMAND__QUERY_TA);
		ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__QUERY_TA);
		if (!ret) {
			if (securedisplay_cmd->status == TA_SECUREDISPLAY_STATUS__SUCCESS)
				dev_info(adev->dev, "SECUREDISPLAY: query securedisplay TA ret is 0x%X\n",
					securedisplay_cmd->securedisplay_out_message.query_ta.query_cmd_ret);
			else
				psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);
		}
		mutex_unlock(&psp->securedisplay_context.mutex);
		break;
	case 2:
		if (nargs < 2 || phy_id >= TA_SECUREDISPLAY_MAX_PHY) {
			dev_err(adev->dev, "Invalid input: %s\n", str);
			write_ret = -EINVAL;
			break;
		}
		mutex_lock(&psp->securedisplay_context.mutex);
		psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
			TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
		securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = phy_id;
		ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
		if (!ret) {
			if (securedisplay_cmd->status == TA_SECUREDISPLAY_STATUS__SUCCESS) {
				dev_info(adev->dev, "SECUREDISPLAY: I2C buffer out put is: %*ph\n",
					 TA_SECUREDISPLAY_I2C_BUFFER_SIZE,
					 securedisplay_cmd->securedisplay_out_message.send_roi_crc.i2c_buf);
			} else {
				psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);
			}
		}
		mutex_unlock(&psp->securedisplay_context.mutex);
		break;
	default:
		dev_err(adev->dev, "Invalid input: %s\n", str);
		write_ret = -EINVAL;
		break;
	}

out:
	pm_runtime_put_autosuspend(dev->dev);

	return write_ret;
}

static const struct file_operations amdgpu_securedisplay_debugfs_ops = {
	.owner = THIS_MODULE,
	.read = NULL,
	.write = amdgpu_securedisplay_debugfs_write,
	.llseek = default_llseek
};

#endif

void amdgpu_securedisplay_debugfs_init(struct amdgpu_device *adev)
{
#if defined(CONFIG_DEBUG_FS)

	if (!adev->psp.securedisplay_context.context.initialized)
		return;

	debugfs_create_file("securedisplay_test", S_IWUSR, adev_to_drm(adev)->primary->debugfs_root,
				adev, &amdgpu_securedisplay_debugfs_ops);
#endif
}
