diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/dce_virtual.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 33 |
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 | ||
36 | static void dce_virtual_set_display_funcs(struct amdgpu_device *adev); | 37 | static void dce_virtual_set_display_funcs(struct amdgpu_device *adev); |
37 | static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev); | 38 | static 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 | ||
646 | static 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 | |||
645 | static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev, | 657 | static 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 | |||
655 | static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev, | 684 | static 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, |