/*
 * drivers/soc/samsung/secmem.c
 *
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/pm_qos.h>
#include <linux/dma-contiguous.h>
#include <linux/exynos_ion.h>
#include <linux/smc.h>

#include <asm/memory.h>
#include <asm/cacheflush.h>

#include <soc/samsung/secmem.h>

#define SECMEM_DEV_NAME	"s5p-smem"


#define DRM_PROT_VER_CHUNK_BASED_PROT	0
#define DRM_PROT_VER_BUFFER_BASED_PROT	1

struct miscdevice secmem;
struct secmem_crypto_driver_ftn *crypto_driver;

uint32_t instance_count;

#if defined(CONFIG_SOC_EXYNOS5433)
static uint32_t secmem_regions[] = {
	ION_EXYNOS_ID_G2D_WFD,
	ION_EXYNOS_ID_VIDEO,
	ION_EXYNOS_ID_SECTBL,
	ION_EXYNOS_ID_MFC_FW,
	ION_EXYNOS_ID_MFC_NFW,
};

static char *secmem_regions_name[] = {
	"g2d_wfd",	/* 0 */
	"video",	/* 1 */
	"sectbl",       /* 2 */
	"mfc_fw",       /* 3 */
	"mfc_nfw",      /* 4 */
	NULL
};
#elif defined(CONFIG_SOC_EXYNOS7420)
static uint32_t secmem_regions[] = {
	ION_EXYNOS_ID_G2D_WFD,
	ION_EXYNOS_ID_VIDEO,
	ION_EXYNOS_ID_VIDEO_EXT,
	ION_EXYNOS_ID_MFC_FW,
	ION_EXYNOS_ID_MFC_NFW,
};

static char *secmem_regions_name[] = {
	"g2d_wfd",	/* 0 */
	"video",	/* 1 */
	"video_ext",	/* 2 */
	"mfc_fw",	/* 3 */
	"mfc_nfw",	/* 4 */
	NULL
};
#endif

static bool drm_onoff;
static DEFINE_MUTEX(drm_lock);
static DEFINE_MUTEX(smc_lock);

struct secmem_info {
	struct device	*dev;
	bool		drm_enabled;
};

struct protect_info {
	uint32_t dev;
	uint32_t enable;
};

#define SECMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))

int drm_enable_locked(struct secmem_info *info, bool enable)
{
	if (drm_onoff == enable) {
		pr_err("%s: DRM is already %s\n", __func__, drm_onoff ? "on" : "off");
		return -EINVAL;
	}

	drm_onoff = enable;
	/*
	 * this will only allow this instance to turn drm_off either by
	 * calling the ioctl or by closing the fd
	 */
	info->drm_enabled = enable;

	return 0;
}

static int secmem_open(struct inode *inode, struct file *file)
{
	struct miscdevice *miscdev = file->private_data;
	struct device *dev = miscdev->this_device;
	struct secmem_info *info;

	info = kzalloc(sizeof(struct secmem_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->dev = dev;
	file->private_data = info;

	mutex_lock(&drm_lock);
	instance_count++;
	mutex_unlock(&drm_lock);

	return 0;
}

static int secmem_release(struct inode *inode, struct file *file)
{
	struct secmem_info *info = file->private_data;

	/* disable drm if we were the one to turn it on */
	mutex_lock(&drm_lock);
	instance_count--;
	if (instance_count == 0) {
		if (info->drm_enabled) {
			int ret;
			ret = drm_enable_locked(info, false);
			if (ret < 0)
				pr_err("fail to lock/unlock drm status. lock = %d\n", false);
		}
	}

	mutex_unlock(&drm_lock);

	kfree(info);
	return 0;
}

static long secmem_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct secmem_info *info = filp->private_data;

	switch (cmd) {
#if defined(CONFIG_ION) || defined(CONFIG_ION_EXYNOS)
	case (uint32_t)SECMEM_IOC_GET_FD_PHYS_ADDR:
	{
		struct ion_client *client;
		struct secfd_info fd_info;
		struct ion_fd_data data;
		struct ion_handle *ion_handle;
		size_t len;

		if (copy_from_user(&fd_info, (int __user *)arg,
					sizeof(fd_info)))
			return -EFAULT;

		client = exynos_ion_client_create("DRM");
		if (IS_ERR(client)) {
			pr_err("%s: Failed to get ion_client of DRM\n",
				__func__);
			return -ENOMEM;
		}

		data.fd = fd_info.fd;
		ion_handle = ion_import_dma_buf(client, data.fd);
		pr_debug("%s: fd from user space = %d\n",
				__func__, fd_info.fd);
		if (IS_ERR(ion_handle)) {
			pr_err("%s: Failed to get ion_handle of DRM\n",
				__func__);
			ion_client_destroy(client);
			return -ENOMEM;
		}

		if (ion_phys(client, ion_handle, &fd_info.phys, &len)) {
			pr_err("%s: Failed to get phys. addr of DRM\n",
				__func__);
			ion_free(client, ion_handle);
			ion_client_destroy(client);
			return -ENOMEM;
		}

		pr_debug("%s: physical addr from kernel space = 0x%08x\n",
				__func__, (unsigned int)fd_info.phys);

		ion_free(client, ion_handle);
		ion_client_destroy(client);

		if (copy_to_user((void __user *)arg, &fd_info, sizeof(fd_info)))
			return -EFAULT;
		break;
	}
#endif
	case (uint32_t)SECMEM_IOC_GET_DRM_ONOFF:
		smp_rmb();
		if (copy_to_user((void __user *)arg, &drm_onoff, sizeof(int)))
			return -EFAULT;
		break;
	case (uint32_t)SECMEM_IOC_SET_DRM_ONOFF:
	{
		int ret, val = 0;

		if (copy_from_user(&val, (int __user *)arg, sizeof(int)))
			return -EFAULT;

		mutex_lock(&drm_lock);
		if ((info->drm_enabled && !val) ||
		    (!info->drm_enabled && val)) {
			/*
			 * 1. if we enabled drm, then disable it
			 * 2. if we don't already hdrm enabled,
			 *    try to enable it.
			 */
			ret = drm_enable_locked(info, val);
			if (ret < 0)
				pr_err("fail to lock/unlock drm status. lock = %d\n", val);
		}
		mutex_unlock(&drm_lock);
		break;
	}
	case (uint32_t)SECMEM_IOC_GET_CRYPTO_LOCK:
	{
		break;
	}
	case (uint32_t)SECMEM_IOC_RELEASE_CRYPTO_LOCK:
	{
		break;
	}
	case (uint32_t)SECMEM_IOC_SET_TZPC:
	{
		break;
	}
	case (uint32_t)SECMEM_IOC_SET_VIDEO_EXT_PROC:
	{
		int val, ret;

		if (copy_from_user(&val, (int __user *)arg, sizeof(int)))
			return -EFAULT;
		mutex_lock(&smc_lock);
		ret = exynos_smc((uint32_t)(SMC_DRM_VIDEO_PROC), val, 0, 0);
		if (ret) {
			pr_err("Failed to control VIDEO EXT region protection. prot = %d\n", val);
			mutex_unlock(&smc_lock);
			return -ENOMEM;
		}

		mutex_unlock(&smc_lock);
		break;
	}
	case (uint32_t)SECMEM_IOC_GET_DRM_PROT_VER:
	{
		int val;

		val = DRM_PROT_VER_BUFFER_BASED_PROT;
		if (copy_to_user((void __user *)arg, &val, sizeof(int)))
			return -EFAULT;

		break;
	}
	default:
		return -ENOTTY;
	}

	return 0;
}

#if 0
void secmem_crypto_register(struct secmem_crypto_driver_ftn *ftn)
{
	crypto_driver = ftn;
}
EXPORT_SYMBOL(secmem_crypto_register);

void secmem_crypto_deregister(void)
{
	crypto_driver = NULL;
}
EXPORT_SYMBOL(secmem_crypto_deregister);
#endif

static const struct file_operations secmem_fops = {
	.owner		= THIS_MODULE,
	.open		= secmem_open,
	.release	= secmem_release,
	.compat_ioctl = secmem_ioctl,
	.unlocked_ioctl = secmem_ioctl,
};

struct miscdevice secmem = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name	= SECMEM_DEV_NAME,
	.fops	= &secmem_fops,
};

static int __init secmem_init(void)
{
	int ret;

	ret = misc_register(&secmem);
	if (ret) {
		pr_err("%s: SECMEM can't register misc on minor=%d\n",
			__func__, MISC_DYNAMIC_MINOR);
		return ret;
	}

	crypto_driver = NULL;

	return 0;
}

static void __exit secmem_exit(void)
{
	misc_deregister(&secmem);
}

module_init(secmem_init);
module_exit(secmem_exit);
