/*
 * Copyright 2017 NXP
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * 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 <drm/drmP.h>
#include <drm/imx_drm.h>
#include <linux/component.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <video/dpu.h>

#include "imx-drm.h"

struct imx_drm_dpu_bliteng {
	struct dpu_bliteng *dpu_be;
	struct list_head list;
};

static DEFINE_MUTEX(imx_drm_dpu_bliteng_lock);
static LIST_HEAD(imx_drm_dpu_bliteng_list);

static int imx_dpu_num;

static struct imx_drm_dpu_bliteng *imx_drm_dpu_bliteng_find_by_id(s32 id)
{
	struct imx_drm_dpu_bliteng *bliteng;

	mutex_lock(&imx_drm_dpu_bliteng_lock);

	list_for_each_entry(bliteng, &imx_drm_dpu_bliteng_list, list) {
		if (id == dpu_bliteng_get_id(bliteng->dpu_be)) {
			mutex_unlock(&imx_drm_dpu_bliteng_lock);
			return bliteng;
		}
	}

	mutex_unlock(&imx_drm_dpu_bliteng_lock);

	return NULL;
}

static int imx_drm_dpu_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
					  struct drm_file *file)
{
	struct drm_imx_dpu_set_cmdlist *req;
	struct imx_drm_dpu_bliteng *bliteng;
	struct dpu_bliteng *dpu_be;
	u32 cmd_nr, *cmd, *cmd_list;
	void *user_data;
	s32 id = 0;
	struct drm_imx_dpu_frame_info frame_info;
	int ret;

	req = data;
	user_data = (void *)(unsigned long)req->user_data;
	if (copy_from_user(&id, (void __user *)user_data,
		sizeof(id))) {
		return -EFAULT;
	}

	if (id != 0 && id != 1)
		return -EINVAL;

	user_data += sizeof(id);
	if (copy_from_user(&frame_info, (void __user *)user_data,
		sizeof(frame_info))) {
		return -EFAULT;
	}

	bliteng = imx_drm_dpu_bliteng_find_by_id(id);
	if (!bliteng) {
		DRM_ERROR("Failed to get dpu_bliteng\n");
		return -ENODEV;
	}

	dpu_be = bliteng->dpu_be;

	ret = dpu_be_get(dpu_be);

	cmd_nr = req->cmd_nr;
	cmd = (u32 *)(unsigned long)req->cmd;
	cmd_list = dpu_bliteng_get_cmd_list(dpu_be);

	if (copy_from_user(cmd_list, (void __user *)cmd,
			sizeof(*cmd) * cmd_nr)) {
		ret = -EFAULT;
		goto err;
	}

	dpu_be_configure_prefetch(dpu_be, frame_info.width, frame_info.height,
				  frame_info.x_offset, frame_info.y_offset,
				  frame_info.stride, frame_info.format,
				  frame_info.modifier, frame_info.baddr,
				  frame_info.uv_addr);

	ret = dpu_be_blit(dpu_be, cmd_list, cmd_nr);

err:
	dpu_be_put(dpu_be);

	return ret;
}

static int imx_drm_dpu_wait_ioctl(struct drm_device *drm_dev, void *data,
				  struct drm_file *file)
{
	struct drm_imx_dpu_wait *wait;
	struct imx_drm_dpu_bliteng *bliteng;
	struct dpu_bliteng *dpu_be;
	void *user_data;
	s32 id = 0;
	int ret;

	wait = data;
	user_data = (void *)(unsigned long)wait->user_data;
	if (copy_from_user(&id, (void __user *)user_data,
		sizeof(id))) {
		return -EFAULT;
	}

	if (id != 0 && id != 1)
		return -EINVAL;

	bliteng = imx_drm_dpu_bliteng_find_by_id(id);
	if (!bliteng) {
		DRM_ERROR("Failed to get dpu_bliteng\n");
		return -ENODEV;
	}

	dpu_be = bliteng->dpu_be;

	ret = dpu_be_get(dpu_be);

	dpu_be_wait(dpu_be);

	dpu_be_put(dpu_be);

	return ret;
}

static int imx_drm_dpu_get_param_ioctl(struct drm_device *drm_dev, void *data,
				       struct drm_file *file)
{
	enum drm_imx_dpu_param *param = data;
	int ret;

	switch (*param) {
	case (DRM_IMX_MAX_DPUS):
		ret = imx_dpu_num;
		break;
	default:
		ret = -EINVAL;
		DRM_ERROR("Unknown param![%d]\n", *param);
		break;
	}

	return ret;
}

static struct drm_ioctl_desc imx_drm_dpu_ioctls[] = {
	DRM_IOCTL_DEF_DRV(IMX_DPU_SET_CMDLIST, imx_drm_dpu_set_cmdlist_ioctl,
			DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(IMX_DPU_WAIT, imx_drm_dpu_wait_ioctl,
			DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(IMX_DPU_GET_PARAM, imx_drm_dpu_get_param_ioctl,
			DRM_RENDER_ALLOW),
};

static int dpu_bliteng_bind(struct device *dev, struct device *master,
			    void *data)
{
	struct drm_device *drm = (struct drm_device *)data;
	struct imx_drm_dpu_bliteng *bliteng;
	struct dpu_bliteng *dpu_bliteng = NULL;
	int ret;

	bliteng = devm_kzalloc(dev, sizeof(*bliteng), GFP_KERNEL);
	if (!bliteng)
		return -ENOMEM;

	INIT_LIST_HEAD(&bliteng->list);

	ret = dpu_bliteng_get_empty_instance(&dpu_bliteng, dev);
	if (ret)
		return ret;

	dpu_bliteng_set_id(dpu_bliteng, imx_dpu_num);
	dpu_bliteng_set_dev(dpu_bliteng, dev);

	ret = dpu_bliteng_init(dpu_bliteng);
	if (ret)
		return ret;

	mutex_lock(&imx_drm_dpu_bliteng_lock);
	bliteng->dpu_be = dpu_bliteng;
	list_add_tail(&bliteng->list, &imx_drm_dpu_bliteng_list);
	mutex_unlock(&imx_drm_dpu_bliteng_lock);

	dev_set_drvdata(dev, dpu_bliteng);

	imx_dpu_num++;

	if (drm->driver->num_ioctls == 0) {
		drm->driver->ioctls = imx_drm_dpu_ioctls;
		drm->driver->num_ioctls = ARRAY_SIZE(imx_drm_dpu_ioctls);
	}

	return 0;
}

static void dpu_bliteng_unbind(struct device *dev, struct device *master,
			       void *data)
{
	struct drm_device *drm = (struct drm_device *)data;
	struct imx_drm_dpu_bliteng *bliteng;
	struct dpu_bliteng *dpu_bliteng = dev_get_drvdata(dev);
	s32 id = dpu_bliteng_get_id(dpu_bliteng);

	bliteng = imx_drm_dpu_bliteng_find_by_id(id);
	list_del(&bliteng->list);

	dpu_bliteng_fini(dpu_bliteng);
	dev_set_drvdata(dev, NULL);

	imx_dpu_num--;

	if (drm->driver->num_ioctls != 0) {
		drm->driver->ioctls = NULL;
		drm->driver->num_ioctls = 0;
	}
}

static const struct component_ops dpu_bliteng_ops = {
	.bind = dpu_bliteng_bind,
	.unbind = dpu_bliteng_unbind,
};

static int dpu_bliteng_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;

	if (!dev->platform_data)
		return -EINVAL;

	return component_add(dev, &dpu_bliteng_ops);
}

static int dpu_bliteng_remove(struct platform_device *pdev)
{
	component_del(&pdev->dev, &dpu_bliteng_ops);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int dpu_bliteng_suspend(struct device *dev)
{
	struct dpu_bliteng *dpu_bliteng = dev_get_drvdata(dev);
	int ret;

	if (dpu_bliteng == NULL)
		return 0;

	ret = dpu_be_get(dpu_bliteng);

	dpu_be_wait(dpu_bliteng);

	dpu_be_put(dpu_bliteng);

	dpu_bliteng_fini(dpu_bliteng);

	return 0;
}

static int dpu_bliteng_resume(struct device *dev)
{
	struct dpu_bliteng *dpu_bliteng = dev_get_drvdata(dev);

	if (dpu_bliteng != NULL)
		dpu_bliteng_init(dpu_bliteng);

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(dpu_bliteng_pm_ops,
			 dpu_bliteng_suspend, dpu_bliteng_resume);

struct platform_driver dpu_bliteng_driver = {
	.driver = {
		.name = "imx-drm-dpu-bliteng",
		.pm = &dpu_bliteng_pm_ops,
	},
	.probe = dpu_bliteng_probe,
	.remove = dpu_bliteng_remove,
};

module_platform_driver(dpu_bliteng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NXP Semiconductor");
MODULE_DESCRIPTION("i.MX DRM DPU BLITENG");
