diff options
author | Emily Deng <Emily.Deng@amd.com> | 2016-08-07 23:35:39 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-08-08 14:07:18 -0400 |
commit | 46ac3622437692c371f3e647dc29f99e14b4f596 (patch) | |
tree | 57aa5896cfe1f21ba7696f8bd5ed991f6c342419 | |
parent | 83c9b0253b1136b1312fd2a0bfd173f625c65091 (diff) |
drm/amdgpu: Use software timer to generate vsync interrupt.
For virtual display feature, use the software timer to
simulate the vsync interrupt.
Signed-off-by: Emily Deng <Emily.Deng@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_virtual.h | 2 |
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 | ||
43 | struct amdgpu_bo; | 45 | struct amdgpu_bo; |
44 | struct amdgpu_device; | 46 | struct 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 | ||
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, |
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 | ||
27 | extern const struct amd_ip_funcs dce_virtual_ip_funcs; | 27 | extern const struct amd_ip_funcs dce_virtual_ip_funcs; |
28 | #define DCE_VIRTUAL_VBLANK_PERIOD 16666666 | ||
29 | |||
28 | #endif | 30 | #endif |
29 | 31 | ||