summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2023-11-16 10:36:32 +0100
committerMarek Szyprowski <m.szyprowski@samsung.com>2024-06-03 11:33:39 +0200
commit542274e94852ccdca0459808349d48b7d6f33255 (patch)
tree9cffe40e28b965a43476be2056d7afa1a83290b9
parentfd1e8b9abaa1df3984078c9f12ca37ee0ab341dc (diff)
downloademulator-kernel-sandbox/mmajewski2/4.9.tar.gz
emulator-kernel-sandbox/mmajewski2/4.9.tar.bz2
emulator-kernel-sandbox/mmajewski2/4.9.zip
drm: virtio_gpu: add fake timer based vblank handlersandbox/mmajewski2/4.9
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c65
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h5
3 files changed, 67 insertions, 7 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 58048709c34e..1ea7f2185571 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -38,6 +38,50 @@
#define XRES_MAX 8192
#define YRES_MAX 8192
+#define FAKE_VBLANK_TIME (1000 / 50)
+
+static void virio_gpu_fake_vblank_timer(unsigned long arg)
+{
+ struct virtio_gpu_device *vgdev = (void *)arg;
+ struct virtio_gpu_output *output = vgdev->outputs + 0;
+
+ if (drm_crtc_handle_vblank(&output->crtc))
+ mod_timer(&vgdev->fake_vblank_timer,
+ jiffies + msecs_to_jiffies(FAKE_VBLANK_TIME) - 1);
+}
+
+int virtio_gpu_enable_vblank(struct drm_device *dev, unsigned int num)
+{
+ struct virtio_gpu_device *vgdev = dev->dev_private;
+
+ mod_timer(&vgdev->fake_vblank_timer,
+ jiffies + msecs_to_jiffies(FAKE_VBLANK_TIME) - 1);
+
+ return 0;
+}
+
+void virtio_gpu_disable_vblank(struct drm_device *dev, unsigned int num)
+{
+}
+
+static void virtio_gpu_crtc_handle_event(struct drm_crtc *crtc)
+{
+ struct drm_pending_vblank_event *event = crtc->state->event;
+ unsigned long flags;
+
+ if (!event)
+ return;
+
+ crtc->state->event = NULL;
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ if (drm_crtc_vblank_get(crtc) == 0)
+ drm_crtc_arm_vblank_event(crtc, event);
+ else
+ drm_crtc_send_vblank_event(crtc, event);
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+}
+
static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = drm_crtc_cleanup,
@@ -114,6 +158,7 @@ static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc)
static void virtio_gpu_crtc_enable(struct drm_crtc *crtc)
{
+ drm_crtc_vblank_on(crtc);
}
static void virtio_gpu_crtc_disable(struct drm_crtc *crtc)
@@ -122,6 +167,14 @@ static void virtio_gpu_crtc_disable(struct drm_crtc *crtc)
struct virtio_gpu_device *vgdev = dev->dev_private;
struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc);
+ spin_lock_irq(&dev->event_lock);
+ if (crtc->state->event) {
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ }
+ spin_unlock_irq(&dev->event_lock);
+
+ drm_crtc_vblank_off(crtc);
virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, 0, 0, 0, 0);
}
@@ -134,13 +187,7 @@ static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc,
static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
- unsigned long flags;
-
- spin_lock_irqsave(&crtc->dev->event_lock, flags);
- if (crtc->state->event)
- drm_crtc_send_vblank_event(crtc, crtc->state->event);
- crtc->state->event = NULL;
- spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ virtio_gpu_crtc_handle_event(crtc);
}
static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = {
@@ -358,9 +405,11 @@ static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = {
int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
{
+ struct drm_device *dev = vgdev->ddev;
int i;
drm_mode_config_init(vgdev->ddev);
+ setup_timer(&vgdev->fake_vblank_timer, virio_gpu_fake_vblank_timer, (unsigned long)vgdev);
vgdev->ddev->mode_config.funcs = &virtio_gpu_mode_funcs;
vgdev->ddev->mode_config.helper_private = &virtio_mode_config_helpers;
@@ -374,6 +423,8 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
vgdev_output_init(vgdev, i);
drm_mode_config_reset(vgdev->ddev);
+ drm_vblank_init(dev, dev->mode_config.num_crtc);
+
return 0;
}
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 5820b7020ae5..128ef4a281cc 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -127,6 +127,10 @@ static struct drm_driver driver = {
.dumb_map_offset = virtio_gpu_mode_dumb_mmap,
.dumb_destroy = virtio_gpu_mode_dumb_destroy,
+ .get_vblank_counter = drm_vblank_no_hw_counter,
+ .enable_vblank = virtio_gpu_enable_vblank,
+ .disable_vblank = virtio_gpu_disable_vblank,
+
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = virtio_gpu_debugfs_init,
.debugfs_cleanup = virtio_gpu_debugfs_takedown,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 3949b688c714..d3b714848179 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -205,6 +205,8 @@ struct virtio_gpu_device {
struct virtio_gpu_drv_capset *capsets;
uint32_t num_capsets;
struct list_head cap_cache;
+
+ struct timer_list fake_vblank_timer;
};
struct virtio_gpu_fpriv {
@@ -428,4 +430,7 @@ static inline void virtio_gpu_object_unreserve(struct virtio_gpu_object *bo)
int virtio_gpu_debugfs_init(struct drm_minor *minor);
void virtio_gpu_debugfs_takedown(struct drm_minor *minor);
+int virtio_gpu_enable_vblank(struct drm_device *, unsigned int);
+void virtio_gpu_disable_vblank(struct drm_device *, unsigned int);
+
#endif