/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/of.h>
#include <soc/qcom/scm.h>
#include <soc/qcom/msm_tz_smmu.h>

static const char * const device_id_mappings[] = {
	[TZ_DEVICE_VIDEO] = "VIDEO",
	[TZ_DEVICE_MDSS] = "MDSS",
	[TZ_DEVICE_LPASS] = "LPASS",
	[TZ_DEVICE_MDSS_BOOT] = "MDSS_BOOT",
	[TZ_DEVICE_USB1_HS] = "USB1_HS",
	[TZ_DEVICE_OCMEM] = "OCMEM",
	[TZ_DEVICE_LPASS_CORE] = "LPASS_CORE",
	[TZ_DEVICE_VPU] = "VPU",
	[TZ_DEVICE_COPSS_SMMU] = "COPSS_SMMU",
	[TZ_DEVICE_USB3_0] = "USB3_0",
	[TZ_DEVICE_USB3_1] = "USB3_1",
	[TZ_DEVICE_PCIE_0] = "PCIE_0",
	[TZ_DEVICE_PCIE_1] = "PCIE_1",
	[TZ_DEVICE_BCSS] = "BCSS",
	[TZ_DEVICE_VCAP] = "VCAP",
	[TZ_DEVICE_PCIE20] = "PCIE20",
	[TZ_DEVICE_IPA] = "IPA",
	[TZ_DEVICE_APPS] = "APPS",
	[TZ_DEVICE_GPU] = "GPU",
	[TZ_DEVICE_UFS] = "UFS",
	[TZ_DEVICE_ICE] = "ICE",
	[TZ_DEVICE_ROT] = "ROT",
	[TZ_DEVICE_VFE] = "VFE",
	[TZ_DEVICE_ANOC0] = "ANOC0",
	[TZ_DEVICE_ANOC1] = "ANOC1",
	[TZ_DEVICE_ANOC2] = "ANOC2",
	[TZ_DEVICE_CPP] = "CPP",
	[TZ_DEVICE_JPEG] = "JPEG",
};

#define MAX_DEVICE_ID_NAME_LEN 20

#define TZ_SMMU_PREPARE_ATOS_ID 0x21
#define TZ_SMMU_ATOS_START 1
#define TZ_SMMU_ATOS_END 0

#define SMMU_CHANGE_PAGETABLE_FORMAT    0X01

enum tz_smmu_device_id msm_dev_to_device_id(struct device *dev)
{
	const char *device_id;
	enum tz_smmu_device_id iter;

	if (of_property_read_string(dev->of_node, "qcom,tz-device-id",
					    &device_id)) {
		dev_err(dev, "no qcom,device-id property\n");
		return TZ_DEVICE_MAX;
	}

	for (iter = TZ_DEVICE_START; iter < TZ_DEVICE_MAX; iter++)
		if (!strcmp(device_id_mappings[iter], device_id))
			return iter;

	return TZ_DEVICE_MAX;
}

static int __msm_tz_smmu_atos(struct device *dev, int cb_num, int operation)
{
	int ret;
	struct scm_desc desc = {0};
	enum tz_smmu_device_id devid = msm_dev_to_device_id(dev);

	if (devid == TZ_DEVICE_MAX)
		return -ENODEV;

	desc.args[0] = devid;
	desc.args[1] = cb_num;
	desc.args[2] = operation;
	desc.arginfo = SCM_ARGS(3, SCM_VAL, SCM_VAL, SCM_VAL);

	ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, TZ_SMMU_PREPARE_ATOS_ID),
			&desc);
	if (ret)
		pr_info("%s: TZ SMMU ATOS %s failed, ret = %d\n",
			__func__,
			operation == TZ_SMMU_ATOS_START ? "start" : "end",
			ret);
	return ret;
}

int msm_tz_smmu_atos_start(struct device *dev, int cb_num)
{
	return __msm_tz_smmu_atos(dev, cb_num, TZ_SMMU_ATOS_START);
}

int msm_tz_smmu_atos_end(struct device *dev, int cb_num)
{
	return __msm_tz_smmu_atos(dev, cb_num, TZ_SMMU_ATOS_END);
}

int msm_tz_set_cb_format(enum tz_smmu_device_id sec_id, int cbndx)
{
	struct scm_desc desc = {0};
	int ret = 0;

	desc.args[0] = sec_id;
	desc.args[1] = cbndx;
	desc.args[2] = 1;	/* Enable */
	desc.arginfo = SCM_ARGS(3, SCM_VAL, SCM_VAL, SCM_VAL);

	ret = scm_call2(SCM_SIP_FNID(SCM_SVC_SMMU_PROGRAM,
			SMMU_CHANGE_PAGETABLE_FORMAT), &desc);

	if (ret) {
		WARN(1, "Format change failed for CB %d with ret %d\n",
		     cbndx, ret);
		return ret;
	}

	return 0;
}
