[PATCH] drm/virtio: Only disable KMS with nomodeset

From: Javier Martinez Canillas
Date: Tue Feb 28 2023 - 04:09:11 EST


The virtio-gpu driver currently fails to probe if either the "nomodeset"
kernel cmdline parameter is used or the module "modeset" parameter used.

But there may be cases where the rendering part of the driver is needed
and only the mode setting part needs to be disabled. So let's change the
logic to only disable the KMS part but still keep the DRM side of it.

Signed-off-by: Javier Martinez Canillas <javierm@xxxxxxxxxx>
---
drivers/gpu/drm/virtio/virtgpu_display.c | 16 +++++++++++++++
drivers/gpu/drm/virtio/virtgpu_drv.c | 23 ++++++++++++++--------
drivers/gpu/drm/virtio/virtgpu_kms.c | 25 +-----------------------
3 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 9ea7611a9e0f..e176e5e8c1a0 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -335,6 +335,22 @@ static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = {
int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
{
int i, ret;
+ u32 num_scanouts;
+
+ if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_EDID)) {
+ vgdev->has_edid = true;
+ }
+
+ /* get display info */
+ virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
+ num_scanouts, &num_scanouts);
+ vgdev->num_scanouts = min_t(uint32_t, num_scanouts,
+ VIRTIO_GPU_MAX_SCANOUTS);
+ if (!vgdev->num_scanouts) {
+ DRM_ERROR("num_scanouts is zero\n");
+ return -EINVAL;
+ }
+ DRM_INFO("number of scanouts: %d\n", num_scanouts);

ret = drmm_mode_config_init(vgdev->ddev);
if (ret)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index ae97b98750b6..979b5b177f49 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -40,7 +40,7 @@

#include "virtgpu_drv.h"

-static const struct drm_driver driver;
+static struct drm_driver driver;

static int virtio_gpu_modeset = -1;

@@ -69,13 +69,12 @@ static int virtio_gpu_pci_quirk(struct drm_device *dev)
static int virtio_gpu_probe(struct virtio_device *vdev)
{
struct drm_device *dev;
+ struct virtio_gpu_device *vgdev;
int ret;

- if (drm_firmware_drivers_only() && virtio_gpu_modeset == -1)
- return -EINVAL;
-
- if (virtio_gpu_modeset == 0)
- return -EINVAL;
+ if ((drm_firmware_drivers_only() && virtio_gpu_modeset == -1) ||
+ (virtio_gpu_modeset == 0))
+ driver.driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC);

/*
* The virtio-gpu device is a virtual device that doesn't have DMA
@@ -98,11 +97,19 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
if (ret)
goto err_free;

+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ vgdev = dev->dev_private;
+ ret = virtio_gpu_modeset_init(vgdev);
+ if (ret)
+ goto err_deinit;
+ }
+
ret = drm_dev_register(dev, 0);
if (ret)
goto err_deinit;

- drm_fbdev_generic_setup(vdev->priv, 32);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_fbdev_generic_setup(vdev->priv, 32);
return 0;

err_deinit:
@@ -171,7 +178,7 @@ MODULE_AUTHOR("Alon Levy");

DEFINE_DRM_GEM_FOPS(virtio_gpu_driver_fops);

-static const struct drm_driver driver = {
+static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC,
.open = virtio_gpu_driver_open,
.postclose = virtio_gpu_driver_postclose,
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 27b7f14dae89..2f5f2aac6b71 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -122,7 +122,7 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
struct virtio_gpu_device *vgdev;
/* this will expand later */
struct virtqueue *vqs[2];
- u32 num_scanouts, num_capsets;
+ u32 num_capsets;
int ret = 0;

if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
@@ -161,9 +161,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_VIRGL))
vgdev->has_virgl_3d = true;
#endif
- if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_EDID)) {
- vgdev->has_edid = true;
- }
if (virtio_has_feature(vgdev->vdev, VIRTIO_RING_F_INDIRECT_DESC)) {
vgdev->has_indirect = true;
}
@@ -218,28 +215,10 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
goto err_vbufs;
}

- /* get display info */
- virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
- num_scanouts, &num_scanouts);
- vgdev->num_scanouts = min_t(uint32_t, num_scanouts,
- VIRTIO_GPU_MAX_SCANOUTS);
- if (!vgdev->num_scanouts) {
- DRM_ERROR("num_scanouts is zero\n");
- ret = -EINVAL;
- goto err_scanouts;
- }
- DRM_INFO("number of scanouts: %d\n", num_scanouts);
-
virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
num_capsets, &num_capsets);
DRM_INFO("number of cap sets: %d\n", num_capsets);

- ret = virtio_gpu_modeset_init(vgdev);
- if (ret) {
- DRM_ERROR("modeset init failed\n");
- goto err_scanouts;
- }
-
virtio_device_ready(vgdev->vdev);

if (num_capsets)
@@ -252,8 +231,6 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
5 * HZ);
return 0;

-err_scanouts:
- virtio_gpu_free_vbufs(vgdev);
err_vbufs:
vgdev->vdev->config->del_vqs(vgdev->vdev);
err_vqs:
--
2.39.2

--
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat