aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-03-13 19:42:34 -0400
committerDave Airlie <airlied@redhat.com>2016-03-13 19:46:02 -0400
commit9b61c0fcdf0cfd20a85d9856d46142e7f297de0a (patch)
treed4abe6aa3f4e1e088f9da1d0597e078b1fe58912 /drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
parent550e3b23a53c88adfa46e64f9d442743e65d47da (diff)
parent125234dc8b1cc862f52d8bd5b37c36cc59b2cb86 (diff)
Merge drm-fixes into drm-next.
Nouveau wanted this to avoid some worse conflicts when I merge that.
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 2cb53c24dec0..f0ed974bd4e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -70,8 +70,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
70 70
71 struct drm_crtc *crtc = &amdgpuCrtc->base; 71 struct drm_crtc *crtc = &amdgpuCrtc->base;
72 unsigned long flags; 72 unsigned long flags;
73 unsigned i; 73 unsigned i, repcnt = 4;
74 int vpos, hpos, stat, min_udelay; 74 int vpos, hpos, stat, min_udelay = 0;
75 struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id]; 75 struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
76 76
77 if (amdgpu_flip_handle_fence(work, &work->excl)) 77 if (amdgpu_flip_handle_fence(work, &work->excl))
@@ -97,7 +97,7 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
97 * In practice this won't execute very often unless on very fast 97 * In practice this won't execute very often unless on very fast
98 * machines because the time window for this to happen is very small. 98 * machines because the time window for this to happen is very small.
99 */ 99 */
100 for (;;) { 100 while (amdgpuCrtc->enabled && --repcnt) {
101 /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank 101 /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
102 * start in hpos, and to the "fudged earlier" vblank start in 102 * start in hpos, and to the "fudged earlier" vblank start in
103 * vpos. 103 * vpos.
@@ -113,12 +113,24 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
113 break; 113 break;
114 114
115 /* Sleep at least until estimated real start of hw vblank */ 115 /* Sleep at least until estimated real start of hw vblank */
116 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
117 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); 116 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
117 if (min_udelay > vblank->framedur_ns / 2000) {
118 /* Don't wait ridiculously long - something is wrong */
119 repcnt = 0;
120 break;
121 }
122 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
118 usleep_range(min_udelay, 2 * min_udelay); 123 usleep_range(min_udelay, 2 * min_udelay);
119 spin_lock_irqsave(&crtc->dev->event_lock, flags); 124 spin_lock_irqsave(&crtc->dev->event_lock, flags);
120 }; 125 };
121 126
127 if (!repcnt)
128 DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, "
129 "framedur %d, linedur %d, stat %d, vpos %d, "
130 "hpos %d\n", work->crtc_id, min_udelay,
131 vblank->framedur_ns / 1000,
132 vblank->linedur_ns / 1000, stat, vpos, hpos);
133
122 /* set the flip status */ 134 /* set the flip status */
123 amdgpuCrtc->pflip_status = AMDGPU_FLIP_SUBMITTED; 135 amdgpuCrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
124 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 136 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);