aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/dce_virtual.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index c7da45c2c8fe..ace52a342e64 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -32,6 +32,7 @@
32#endif 32#endif
33#include "dce_v10_0.h" 33#include "dce_v10_0.h"
34#include "dce_v11_0.h" 34#include "dce_v11_0.h"
35#include "dce_virtual.h"
35 36
36static void dce_virtual_set_display_funcs(struct amdgpu_device *adev); 37static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
37static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev); 38static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
@@ -642,16 +643,44 @@ static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
642 adev->mode_info.funcs = &dce_virtual_display_funcs; 643 adev->mode_info.funcs = &dce_virtual_display_funcs;
643} 644}
644 645
646static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer)
647{
648 struct amdgpu_mode_info *mode_info = container_of(vblank_timer, struct amdgpu_mode_info ,vblank_timer);
649 struct amdgpu_device *adev = container_of(mode_info, struct amdgpu_device ,mode_info);
650 unsigned crtc = 0;
651 adev->ddev->vblank[0].count++;
652 drm_handle_vblank(adev->ddev, crtc);
653 hrtimer_start(vblank_timer, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD), HRTIMER_MODE_REL);
654 return HRTIMER_NORESTART;
655}
656
645static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev, 657static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
646 int crtc, 658 int crtc,
647 enum amdgpu_interrupt_state state) 659 enum amdgpu_interrupt_state state)
648{ 660{
649 if (crtc >= adev->mode_info.num_crtc) { 661 if (crtc >= adev->mode_info.num_crtc) {
650 DRM_DEBUG("invalid crtc %d\n", crtc); 662 DRM_DEBUG("invalid crtc %d\n", crtc);
651 return; 663 return;
652 } 664 }
665
666 if (state && !adev->mode_info.vsync_timer_enabled) {
667 DRM_DEBUG("Enable software vsync timer\n");
668 hrtimer_init(&adev->mode_info.vblank_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
669 hrtimer_set_expires(&adev->mode_info.vblank_timer, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD));
670 adev->mode_info.vblank_timer.function = dce_virtual_vblank_timer_handle;
671 hrtimer_start(&adev->mode_info.vblank_timer, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD), HRTIMER_MODE_REL);
672 } else if (!state && adev->mode_info.vsync_timer_enabled) {
673 DRM_DEBUG("Disable software vsync timer\n");
674 hrtimer_cancel(&adev->mode_info.vblank_timer);
675 }
676
677 if (!state || (state && !adev->mode_info.vsync_timer_enabled))
678 adev->ddev->vblank[0].count = 0;
679 adev->mode_info.vsync_timer_enabled = state;
680 DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc, state);
653} 681}
654 682
683
655static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev, 684static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev,
656 struct amdgpu_irq_src *source, 685 struct amdgpu_irq_src *source,
657 unsigned type, 686 unsigned type,