diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2023-11-16 10:36:32 +0100 |
---|---|---|
committer | Marek Szyprowski <m.szyprowski@samsung.com> | 2024-06-03 11:33:39 +0200 |
commit | 542274e94852ccdca0459808349d48b7d6f33255 (patch) | |
tree | 9cffe40e28b965a43476be2056d7afa1a83290b9 | |
parent | fd1e8b9abaa1df3984078c9f12ca37ee0ab341dc (diff) | |
download | emulator-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.c | 65 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 5 |
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 |