This patch introduces Virtual Kernel Mode-Setting (VKMS) driver. It creates a very basic kms driver with 1 crtc/encoder/connector/plane.
VKMS driver would be useful for testing, or for running X (or similar) on headless machines and be able to still use the GPU. Thus it enables a virtual display without the need for hardware display capability.
Signed-off-by: Haneen Mohammed hamohammed.sa@gmail.com --- drivers/gpu/drm/Kconfig | 6 ++ drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/vkms/Makefile | 3 + drivers/gpu/drm/vkms/vkms_drv.c | 146 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.h | 13 +++ 5 files changed, 169 insertions(+) create mode 100644 drivers/gpu/drm/vkms/Makefile create mode 100644 drivers/gpu/drm/vkms/vkms_drv.c create mode 100644 drivers/gpu/drm/vkms/vkms_drv.h
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 2a72d2feb76d..7db3d82cbb27 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -213,6 +213,12 @@ config DRM_VGEM as used by Mesa's software renderer for enhanced performance. If M is selected the module will be called vgem.
+config DRM_VKMS + tristate "Virtual KMS" + depends on DRM + help + Choose this option to get a virtual kernal mode-setting driver. + If M is selected the module will be called vkms.
source "drivers/gpu/drm/exynos/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index ef9f3dab287f..8873d4769116 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_DRM_SAVAGE)+= savage/ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ obj-$(CONFIG_DRM_VIA) +=via/ obj-$(CONFIG_DRM_VGEM) += vgem/ +obj-$(CONFIG_DRM_VKMS) += vkms/ obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ obj-$(CONFIG_DRM_EXYNOS) +=exynos/ obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/ diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile new file mode 100644 index 000000000000..2aef948d3a34 --- /dev/null +++ b/drivers/gpu/drm/vkms/Makefile @@ -0,0 +1,3 @@ +vkms-y := vkms_drv.o + +obj-$(CONFIG_DRM_VKMS) += vkms.o diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c new file mode 100644 index 000000000000..b1df08ed23a0 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -0,0 +1,146 @@ +/* + * 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. + */ + +#include <linux/module.h> +#include <drm/drmP.h> +#include <drm/drm_gem.h> +#include <drm/drm_crtc_helper.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; + +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 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); +} + +struct drm_driver vkms_driver = { + .driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM, + .release = vkms_release, + .fops = &vkms_driver_fops, + + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, +}; + +static const u32 vkms_formats[] = { + DRM_FORMAT_XRGB8888, +}; + +static void vkms_connector_destroy(struct drm_connector *connector) +{ + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static const struct drm_connector_funcs vkms_connector_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = vkms_connector_destroy, +}; + +static int __init vkms_init(void) +{ + int ret; + + vkms_device = kzalloc(sizeof(*vkms_device), GFP_KERNEL); + if (!vkms_device) + return -ENOMEM; + + ret = drm_dev_init(&vkms_device->drm, &vkms_driver, NULL); + if (ret) + goto out_free; + + 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_fini; + } + + drm_mode_config_init(&vkms_device->drm); + + ret = drm_connector_init(&vkms_device->drm, &vkms_device->connector, + &vkms_connector_funcs, + DRM_MODE_CONNECTOR_VIRTUAL); + if (ret < 0) { + DRM_ERROR("Failed to init connector\n"); + goto out_unregister; + } + + ret = drm_simple_display_pipe_init(&vkms_device->drm, + &vkms_device->pipe, + NULL, + vkms_formats, + ARRAY_SIZE(vkms_formats), + NULL, + &vkms_device->connector); + if (ret < 0) { + DRM_ERROR("Cannot setup simple display pipe\n"); + goto out_unregister; + } + + ret = drm_dev_register(&vkms_device->drm, 0); + if (ret) + goto out_unregister; + + drm_connector_register(&vkms_device->connector); + + return 0; + +out_unregister: + platform_device_unregister(vkms_device->platform); +out_fini: + drm_dev_fini(&vkms_device->drm); +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_dev_put(&vkms_device->drm); + + kfree(vkms_device); +} + +module_init(vkms_init); +module_exit(vkms_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h new file mode 100644 index 000000000000..c77c5bf5032a --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -0,0 +1,13 @@ +#ifndef _VKMS_DRV_H_ +#define _VKMS_DRV_H_ + +#include <drm/drm_simple_kms_helper.h> + +struct vkms_device { + struct drm_device drm; + struct platform_device *platform; + struct drm_simple_display_pipe pipe; + struct drm_connector connector; +}; + +#endif /* _VKMS_DRV_H_ */
Hi Haneen,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on drm/drm-next] [also build test WARNING on v4.17-rc5 next-20180514] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Haneen-Mohammed/drm-vkms-Introduce-... base: git://people.freedesktop.org/~airlied/linux.git drm-next reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
drivers/gpu/drm/vkms/vkms_drv.c:43:19: sparse: symbol 'vkms_driver' was not declared. Should it be static?
Please review and possibly fold the followup patch.
--- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Fixes: 58d8108f080c ("drm/vkms: Introduce basic VKMS driver") Signed-off-by: Fengguang Wu fengguang.wu@intel.com --- vkms_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index b1df08e..35517b09 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -40,7 +40,7 @@ static void vkms_release(struct drm_device *dev) drm_dev_fini(&vkms->drm); }
-struct drm_driver vkms_driver = { +static struct drm_driver vkms_driver = { .driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM, .release = vkms_release, .fops = &vkms_driver_fops,
On Tue, May 15, 2018 at 07:30:52PM +0800, kbuild test robot wrote:
Fixes: 58d8108f080c ("drm/vkms: Introduce basic VKMS driver") Signed-off-by: Fengguang Wu fengguang.wu@intel.com
vkms_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index b1df08e..35517b09 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -40,7 +40,7 @@ static void vkms_release(struct drm_device *dev) drm_dev_fini(&vkms->drm); }
-struct drm_driver vkms_driver = { +static struct drm_driver vkms_driver = { .driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM, .release = vkms_release, .fops = &vkms_driver_fops,
Looks good to me.
- Haneen
On Tue, May 15, 2018 at 07:30:52PM +0800, kbuild test robot wrote:
Fixes: 58d8108f080c ("drm/vkms: Introduce basic VKMS driver") Signed-off-by: Fengguang Wu fengguang.wu@intel.com
One thing I noticed while applying this: Your author (as recorded in the From: line) and your s-o-b don't match. Now I know that you're behind 0day, so it's ok, but our script gets annoyed and I need to overrule it with an -f flag.
Can you perhaps get the From: and S-o-b: lines into agreement so that a simple comparison works?
Thanks, Daniel
vkms_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index b1df08e..35517b09 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -40,7 +40,7 @@ static void vkms_release(struct drm_device *dev) drm_dev_fini(&vkms->drm); }
-struct drm_driver vkms_driver = { +static struct drm_driver vkms_driver = { .driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM, .release = vkms_release, .fops = &vkms_driver_fops,
Subject: Re: [kbuild-all] [RFC PATCH] drm/vkms: vkms_driver can be static
On Tue, May 15, 2018 at 07:30:52PM +0800, kbuild test robot wrote:
Fixes: 58d8108f080c ("drm/vkms: Introduce basic VKMS driver") Signed-off-by: Fengguang Wu fengguang.wu@intel.com
One thing I noticed while applying this: Your author (as recorded in the From: line) and your s-o-b don't match. Now I know that you're behind 0day, so it's ok, but our script gets annoyed and I need to overrule it with an -f flag.
Can you perhaps get the From: and S-o-b: lines into agreement so that a simple comparison works?
thanks for input, we the bot team has decided to use uniform From with the address lkp recently, while the auto generated script is still using specific author's signed-off-by.
Thanks, Daniel
vkms_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c
b/drivers/gpu/drm/vkms/vkms_drv.c
index b1df08e..35517b09 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -40,7 +40,7 @@ static void vkms_release(struct drm_device *dev) drm_dev_fini(&vkms->drm); }
-struct drm_driver vkms_driver = { +static struct drm_driver vkms_driver = { .driver_features = DRIVER_MODESET | DRIVER_ATOMIC |
DRIVER_GEM,
.release = vkms_release, .fops = &vkms_driver_fops,
-- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ kbuild-all mailing list kbuild-all@lists.01.org https://lists.01.org/mailman/listinfo/kbuild-all
On Mon, May 14, 2018 at 05:33:46PM +0300, Haneen Mohammed wrote:
This patch introduces Virtual Kernel Mode-Setting (VKMS) driver. It creates a very basic kms driver with 1 crtc/encoder/connector/plane.
VKMS driver would be useful for testing, or for running X (or similar) on headless machines and be able to still use the GPU. Thus it enables a virtual display without the need for hardware display capability.
Signed-off-by: Haneen Mohammed hamohammed.sa@gmail.com
Created a new topic branch topic/vkms in drm-misc and pushed it there.
Thanks, Daniel
drivers/gpu/drm/Kconfig | 6 ++ drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/vkms/Makefile | 3 + drivers/gpu/drm/vkms/vkms_drv.c | 146 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_drv.h | 13 +++ 5 files changed, 169 insertions(+) create mode 100644 drivers/gpu/drm/vkms/Makefile create mode 100644 drivers/gpu/drm/vkms/vkms_drv.c create mode 100644 drivers/gpu/drm/vkms/vkms_drv.h
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 2a72d2feb76d..7db3d82cbb27 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -213,6 +213,12 @@ config DRM_VGEM as used by Mesa's software renderer for enhanced performance. If M is selected the module will be called vgem.
+config DRM_VKMS
- tristate "Virtual KMS"
- depends on DRM
- help
Choose this option to get a virtual kernal mode-setting driver.
If M is selected the module will be called vkms.
source "drivers/gpu/drm/exynos/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index ef9f3dab287f..8873d4769116 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_DRM_SAVAGE)+= savage/ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ obj-$(CONFIG_DRM_VIA) +=via/ obj-$(CONFIG_DRM_VGEM) += vgem/ +obj-$(CONFIG_DRM_VKMS) += vkms/ obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ obj-$(CONFIG_DRM_EXYNOS) +=exynos/ obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/ diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile new file mode 100644 index 000000000000..2aef948d3a34 --- /dev/null +++ b/drivers/gpu/drm/vkms/Makefile @@ -0,0 +1,3 @@ +vkms-y := vkms_drv.o
+obj-$(CONFIG_DRM_VKMS) += vkms.o diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c new file mode 100644 index 000000000000..b1df08ed23a0 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -0,0 +1,146 @@ +/*
- 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.
- */
+#include <linux/module.h> +#include <drm/drmP.h> +#include <drm/drm_gem.h> +#include <drm/drm_crtc_helper.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;
+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 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);
+}
+struct drm_driver vkms_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM,
- .release = vkms_release,
- .fops = &vkms_driver_fops,
- .name = DRIVER_NAME,
- .desc = DRIVER_DESC,
- .date = DRIVER_DATE,
- .major = DRIVER_MAJOR,
- .minor = DRIVER_MINOR,
+};
+static const u32 vkms_formats[] = {
- DRM_FORMAT_XRGB8888,
+};
+static void vkms_connector_destroy(struct drm_connector *connector) +{
- drm_connector_unregister(connector);
- drm_connector_cleanup(connector);
+}
+static const struct drm_connector_funcs vkms_connector_funcs = {
- .fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = vkms_connector_destroy,
+};
+static int __init vkms_init(void) +{
- int ret;
- vkms_device = kzalloc(sizeof(*vkms_device), GFP_KERNEL);
- if (!vkms_device)
return -ENOMEM;
- ret = drm_dev_init(&vkms_device->drm, &vkms_driver, NULL);
- if (ret)
goto out_free;
- 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_fini;
- }
- drm_mode_config_init(&vkms_device->drm);
- ret = drm_connector_init(&vkms_device->drm, &vkms_device->connector,
&vkms_connector_funcs,
DRM_MODE_CONNECTOR_VIRTUAL);
- if (ret < 0) {
DRM_ERROR("Failed to init connector\n");
goto out_unregister;
- }
- ret = drm_simple_display_pipe_init(&vkms_device->drm,
&vkms_device->pipe,
NULL,
vkms_formats,
ARRAY_SIZE(vkms_formats),
NULL,
&vkms_device->connector);
- if (ret < 0) {
DRM_ERROR("Cannot setup simple display pipe\n");
goto out_unregister;
- }
- ret = drm_dev_register(&vkms_device->drm, 0);
- if (ret)
goto out_unregister;
- drm_connector_register(&vkms_device->connector);
- return 0;
+out_unregister:
- platform_device_unregister(vkms_device->platform);
+out_fini:
- drm_dev_fini(&vkms_device->drm);
+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_dev_put(&vkms_device->drm);
- kfree(vkms_device);
+}
+module_init(vkms_init); +module_exit(vkms_exit);
+MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h new file mode 100644 index 000000000000..c77c5bf5032a --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -0,0 +1,13 @@ +#ifndef _VKMS_DRV_H_ +#define _VKMS_DRV_H_
+#include <drm/drm_simple_kms_helper.h>
+struct vkms_device {
- struct drm_device drm;
- struct platform_device *platform;
- struct drm_simple_display_pipe pipe;
- struct drm_connector connector;
+};
+#endif /* _VKMS_DRV_H_ */
2.17.0
dri-devel@lists.freedesktop.org