// SPDX-License-Identifier: GPL-2.0+

/**
 * DOC: vkms (Virtual Kernel Modesetting)
 *
 * vkms is a software-only model of a kms driver that is useful for testing,
 * or for running X (or similar) on headless machines and be able to still
 * use the GPU. vkms aims to enable a virtual display without the need for
 * a hardware display capability.
 */

#include <linux/module.h>
#include <linux/platform_device.h>

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_file.h>
#include <drm/drm_gem.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>

#include "vkms_drv.h"

#define DRIVER_NAME	"vkms"
#define DRIVER_DESC	"Virtual Kernel Mode Setting"
#define DRIVER_DATE	"20180514"
#define DRIVER_MAJOR	1
#define DRIVER_MINOR	0

static struct vkms_device *vkms_device;

bool enable_cursor;
module_param_named(enable_cursor, enable_cursor, bool, 0444);
MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");

static const struct file_operations vkms_driver_fops = {
	.owner		= THIS_MODULE,
	.open		= drm_open,
	.mmap		= drm_gem_mmap,
	.unlocked_ioctl	= drm_ioctl,
	.compat_ioctl	= drm_compat_ioctl,
	.poll		= drm_poll,
	.read		= drm_read,
	.llseek		= no_llseek,
	.release	= drm_release,
};

static const struct vm_operations_struct vkms_gem_vm_ops = {
	.fault = vkms_gem_fault,
	.open = drm_gem_vm_open,
	.close = drm_gem_vm_close,
};

static void vkms_release(struct drm_device *dev)
{
	struct vkms_device *vkms = container_of(dev, struct vkms_device, drm);

	platform_device_unregister(vkms->platform);
	drm_mode_config_cleanup(&vkms->drm);
	drm_dev_fini(&vkms->drm);
	destroy_workqueue(vkms->output.composer_workq);
}

static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state)
{
	struct drm_device *dev = old_state->dev;
	struct drm_crtc *crtc;
	struct drm_crtc_state *old_crtc_state;
	int i;

	drm_atomic_helper_commit_modeset_disables(dev, old_state);

	drm_atomic_helper_commit_planes(dev, old_state, 0);

	drm_atomic_helper_commit_modeset_enables(dev, old_state);

	drm_atomic_helper_fake_vblank(old_state);

	drm_atomic_helper_commit_hw_done(old_state);

	drm_atomic_helper_wait_for_vblanks(dev, old_state);

	for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
		struct vkms_crtc_state *vkms_state =
			to_vkms_crtc_state(old_crtc_state);

		flush_work(&vkms_state->composer_work);
	}

	drm_atomic_helper_cleanup_planes(dev, old_state);
}

static struct drm_driver vkms_driver = {
	.driver_features	= DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM,
	.release		= vkms_release,
	.fops			= &vkms_driver_fops,
	.dumb_create		= vkms_dumb_create,
	.gem_vm_ops		= &vkms_gem_vm_ops,
	.gem_free_object_unlocked = vkms_gem_free_object,
	.get_vblank_timestamp	= vkms_get_vblank_timestamp,

	.name			= DRIVER_NAME,
	.desc			= DRIVER_DESC,
	.date			= DRIVER_DATE,
	.major			= DRIVER_MAJOR,
	.minor			= DRIVER_MINOR,
};

static const struct drm_mode_config_funcs vkms_mode_funcs = {
	.fb_create = drm_gem_fb_create,
	.atomic_check = drm_atomic_helper_check,
	.atomic_commit = drm_atomic_helper_commit,
};

static const struct drm_mode_config_helper_funcs vkms_mode_config_helpers = {
	.atomic_commit_tail = vkms_atomic_commit_tail,
};

static int vkms_modeset_init(struct vkms_device *vkmsdev)
{
	struct drm_device *dev = &vkmsdev->drm;

	drm_mode_config_init(dev);
	dev->mode_config.funcs = &vkms_mode_funcs;
	dev->mode_config.min_width = XRES_MIN;
	dev->mode_config.min_height = YRES_MIN;
	dev->mode_config.max_width = XRES_MAX;
	dev->mode_config.max_height = YRES_MAX;
	dev->mode_config.preferred_depth = 24;
	dev->mode_config.helper_private = &vkms_mode_config_helpers;

	return vkms_output_init(vkmsdev, 0);
}

static int __init vkms_init(void)
{
	int ret;

	vkms_device = kzalloc(sizeof(*vkms_device), GFP_KERNEL);
	if (!vkms_device)
		return -ENOMEM;

	vkms_device->platform =
		platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
	if (IS_ERR(vkms_device->platform)) {
		ret = PTR_ERR(vkms_device->platform);
		goto out_free;
	}

	ret = drm_dev_init(&vkms_device->drm, &vkms_driver,
			   &vkms_device->platform->dev);
	if (ret)
		goto out_unregister;

	vkms_device->drm.irq_enabled = true;

	ret = drm_vblank_init(&vkms_device->drm, 1);
	if (ret) {
		DRM_ERROR("Failed to vblank\n");
		goto out_fini;
	}

	ret = vkms_modeset_init(vkms_device);
	if (ret)
		goto out_fini;

	ret = drm_dev_register(&vkms_device->drm, 0);
	if (ret)
		goto out_fini;

	return 0;

out_fini:
	drm_dev_fini(&vkms_device->drm);

out_unregister:
	platform_device_unregister(vkms_device->platform);

out_free:
	kfree(vkms_device);
	return ret;
}

static void __exit vkms_exit(void)
{
	if (!vkms_device) {
		DRM_INFO("vkms_device is NULL.\n");
		return;
	}

	drm_dev_unregister(&vkms_device->drm);
	drm_atomic_helper_shutdown(&vkms_device->drm);
	drm_dev_put(&vkms_device->drm);

	kfree(vkms_device);
}

module_init(vkms_init);
module_exit(vkms_exit);

MODULE_AUTHOR("Haneen Mohammed <hamohammed.sa@gmail.com>");
MODULE_AUTHOR("Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
