aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.h2
3 files changed, 37 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 6b1d7d306564..b1ae33bdbd84 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -39,6 +39,8 @@
39#include <drm/drm_plane_helper.h> 39#include <drm/drm_plane_helper.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/i2c-algo-bit.h> 41#include <linux/i2c-algo-bit.h>
42#include <linux/hrtimer.h>
43#include "amdgpu_irq.h"
42 44
43struct amdgpu_bo; 45struct amdgpu_bo;
44struct amdgpu_device; 46struct amdgpu_device;
@@ -339,6 +341,8 @@ struct amdgpu_mode_info {
339 int num_dig; /* number of dig blocks */ 341 int num_dig; /* number of dig blocks */
340 int disp_priority; 342 int disp_priority;
341 const struct amdgpu_display_funcs *funcs; 343 const struct amdgpu_display_funcs *funcs;
344 struct hrtimer vblank_timer;
345 enum amdgpu_interrupt_state vsync_timer_enabled;
342}; 346};
343 347
344#define AMDGPU_MAX_BL_LEVEL 0xFF 348#define AMDGPU_MAX_BL_LEVEL 0xFF
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,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h b/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
index d205d7f6f6ab..e239243f6ebc 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
@@ -25,5 +25,7 @@
25#define __DCE_VIRTUAL_H__ 25#define __DCE_VIRTUAL_H__
26 26
27extern const struct amd_ip_funcs dce_virtual_ip_funcs; 27extern const struct amd_ip_funcs dce_virtual_ip_funcs;
28#define DCE_VIRTUAL_VBLANK_PERIOD 16666666
29
28#endif 30#endif
29 31