aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-12-23 13:22:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-12-23 13:22:16 -0500
commit5b726e06d6e8309e5c9ef4109a32caf27c71dfc8 (patch)
treeadb05b238921b3631063ba54c0077f00b85c375b /drivers/gpu
parent2bfd43d80679db786e4349dc4711e2075a66d46b (diff)
parenta98728e0bb978fbe9246c93ea89198de612c22e6 (diff)
Merge tag 'drm-intel-fixes-2015-12-23' of git://anongit.freedesktop.org/drm-intel
Pull i915 drm fixes from Jani Nikula: "Here's a batch of i915 fixes all around. It may be slightly bigger than one would hope for at this stage, but they've all been through testing in our -next before being picked up for v4.4. Also, I missed Dave's fixes pull earlier today just because I wanted an extra testing round on this. So I'm fairly confident. Wishing you all the things it is customary to wish this time of the year" * tag 'drm-intel-fixes-2015-12-23' of git://anongit.freedesktop.org/drm-intel: drm/i915: Correct max delay for HDMI hotplug live status checking drm/i915: mdelay(10) considered harmful drm/i915: Kill intel_crtc->cursor_bo drm/i915: Workaround CHV pipe C cursor fail drm/i915: Only spin whilst waiting on the current request drm/i915: Limit the busy wait on requests to 5us not 10ms! drm/i915: Break busywaiting for requests on pending signals drm/i915: Disable primary plane if we fail to reconstruct BIOS fb (v2) drm/i915: Set the map-and-fenceable flag for preallocated objects drm/i915: Drop the broken cursor base==0 special casing
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h28
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c111
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c1
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c66
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c7
7 files changed, 154 insertions, 61 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a01e51581c4c..f4af19a0d569 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2193,8 +2193,17 @@ struct drm_i915_gem_request {
2193 struct drm_i915_private *i915; 2193 struct drm_i915_private *i915;
2194 struct intel_engine_cs *ring; 2194 struct intel_engine_cs *ring;
2195 2195
2196 /** GEM sequence number associated with this request. */ 2196 /** GEM sequence number associated with the previous request,
2197 uint32_t seqno; 2197 * when the HWS breadcrumb is equal to this the GPU is processing
2198 * this request.
2199 */
2200 u32 previous_seqno;
2201
2202 /** GEM sequence number associated with this request,
2203 * when the HWS breadcrumb is equal or greater than this the GPU
2204 * has finished processing this request.
2205 */
2206 u32 seqno;
2198 2207
2199 /** Position in the ringbuffer of the start of the request */ 2208 /** Position in the ringbuffer of the start of the request */
2200 u32 head; 2209 u32 head;
@@ -2839,6 +2848,7 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
2839 2848
2840int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, 2849int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
2841 u32 flags); 2850 u32 flags);
2851void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
2842int __must_check i915_vma_unbind(struct i915_vma *vma); 2852int __must_check i915_vma_unbind(struct i915_vma *vma);
2843/* 2853/*
2844 * BEWARE: Do not use the function below unless you can _absolutely_ 2854 * BEWARE: Do not use the function below unless you can _absolutely_
@@ -2910,15 +2920,17 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
2910 return (int32_t)(seq1 - seq2) >= 0; 2920 return (int32_t)(seq1 - seq2) >= 0;
2911} 2921}
2912 2922
2923static inline bool i915_gem_request_started(struct drm_i915_gem_request *req,
2924 bool lazy_coherency)
2925{
2926 u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
2927 return i915_seqno_passed(seqno, req->previous_seqno);
2928}
2929
2913static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req, 2930static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
2914 bool lazy_coherency) 2931 bool lazy_coherency)
2915{ 2932{
2916 u32 seqno; 2933 u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
2917
2918 BUG_ON(req == NULL);
2919
2920 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
2921
2922 return i915_seqno_passed(seqno, req->seqno); 2934 return i915_seqno_passed(seqno, req->seqno);
2923} 2935}
2924 2936
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 32e6aade6223..f56af0aaafde 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1146,23 +1146,74 @@ static bool missed_irq(struct drm_i915_private *dev_priv,
1146 return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings); 1146 return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
1147} 1147}
1148 1148
1149static int __i915_spin_request(struct drm_i915_gem_request *req) 1149static unsigned long local_clock_us(unsigned *cpu)
1150{
1151 unsigned long t;
1152
1153 /* Cheaply and approximately convert from nanoseconds to microseconds.
1154 * The result and subsequent calculations are also defined in the same
1155 * approximate microseconds units. The principal source of timing
1156 * error here is from the simple truncation.
1157 *
1158 * Note that local_clock() is only defined wrt to the current CPU;
1159 * the comparisons are no longer valid if we switch CPUs. Instead of
1160 * blocking preemption for the entire busywait, we can detect the CPU
1161 * switch and use that as indicator of system load and a reason to
1162 * stop busywaiting, see busywait_stop().
1163 */
1164 *cpu = get_cpu();
1165 t = local_clock() >> 10;
1166 put_cpu();
1167
1168 return t;
1169}
1170
1171static bool busywait_stop(unsigned long timeout, unsigned cpu)
1172{
1173 unsigned this_cpu;
1174
1175 if (time_after(local_clock_us(&this_cpu), timeout))
1176 return true;
1177
1178 return this_cpu != cpu;
1179}
1180
1181static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
1150{ 1182{
1151 unsigned long timeout; 1183 unsigned long timeout;
1184 unsigned cpu;
1185
1186 /* When waiting for high frequency requests, e.g. during synchronous
1187 * rendering split between the CPU and GPU, the finite amount of time
1188 * required to set up the irq and wait upon it limits the response
1189 * rate. By busywaiting on the request completion for a short while we
1190 * can service the high frequency waits as quick as possible. However,
1191 * if it is a slow request, we want to sleep as quickly as possible.
1192 * The tradeoff between waiting and sleeping is roughly the time it
1193 * takes to sleep on a request, on the order of a microsecond.
1194 */
1152 1195
1153 if (i915_gem_request_get_ring(req)->irq_refcount) 1196 if (req->ring->irq_refcount)
1154 return -EBUSY; 1197 return -EBUSY;
1155 1198
1156 timeout = jiffies + 1; 1199 /* Only spin if we know the GPU is processing this request */
1200 if (!i915_gem_request_started(req, true))
1201 return -EAGAIN;
1202
1203 timeout = local_clock_us(&cpu) + 5;
1157 while (!need_resched()) { 1204 while (!need_resched()) {
1158 if (i915_gem_request_completed(req, true)) 1205 if (i915_gem_request_completed(req, true))
1159 return 0; 1206 return 0;
1160 1207
1161 if (time_after_eq(jiffies, timeout)) 1208 if (signal_pending_state(state, current))
1209 break;
1210
1211 if (busywait_stop(timeout, cpu))
1162 break; 1212 break;
1163 1213
1164 cpu_relax_lowlatency(); 1214 cpu_relax_lowlatency();
1165 } 1215 }
1216
1166 if (i915_gem_request_completed(req, false)) 1217 if (i915_gem_request_completed(req, false))
1167 return 0; 1218 return 0;
1168 1219
@@ -1197,6 +1248,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
1197 struct drm_i915_private *dev_priv = dev->dev_private; 1248 struct drm_i915_private *dev_priv = dev->dev_private;
1198 const bool irq_test_in_progress = 1249 const bool irq_test_in_progress =
1199 ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring); 1250 ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
1251 int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
1200 DEFINE_WAIT(wait); 1252 DEFINE_WAIT(wait);
1201 unsigned long timeout_expire; 1253 unsigned long timeout_expire;
1202 s64 before, now; 1254 s64 before, now;
@@ -1229,7 +1281,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
1229 before = ktime_get_raw_ns(); 1281 before = ktime_get_raw_ns();
1230 1282
1231 /* Optimistic spin for the next jiffie before touching IRQs */ 1283 /* Optimistic spin for the next jiffie before touching IRQs */
1232 ret = __i915_spin_request(req); 1284 ret = __i915_spin_request(req, state);
1233 if (ret == 0) 1285 if (ret == 0)
1234 goto out; 1286 goto out;
1235 1287
@@ -1241,8 +1293,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
1241 for (;;) { 1293 for (;;) {
1242 struct timer_list timer; 1294 struct timer_list timer;
1243 1295
1244 prepare_to_wait(&ring->irq_queue, &wait, 1296 prepare_to_wait(&ring->irq_queue, &wait, state);
1245 interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
1246 1297
1247 /* We need to check whether any gpu reset happened in between 1298 /* We need to check whether any gpu reset happened in between
1248 * the caller grabbing the seqno and now ... */ 1299 * the caller grabbing the seqno and now ... */
@@ -1260,7 +1311,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
1260 break; 1311 break;
1261 } 1312 }
1262 1313
1263 if (interruptible && signal_pending(current)) { 1314 if (signal_pending_state(state, current)) {
1264 ret = -ERESTARTSYS; 1315 ret = -ERESTARTSYS;
1265 break; 1316 break;
1266 } 1317 }
@@ -2554,6 +2605,7 @@ void __i915_add_request(struct drm_i915_gem_request *request,
2554 request->batch_obj = obj; 2605 request->batch_obj = obj;
2555 2606
2556 request->emitted_jiffies = jiffies; 2607 request->emitted_jiffies = jiffies;
2608 request->previous_seqno = ring->last_submitted_seqno;
2557 ring->last_submitted_seqno = request->seqno; 2609 ring->last_submitted_seqno = request->seqno;
2558 list_add_tail(&request->list, &ring->request_list); 2610 list_add_tail(&request->list, &ring->request_list);
2559 2611
@@ -4080,6 +4132,29 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags)
4080 return false; 4132 return false;
4081} 4133}
4082 4134
4135void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)
4136{
4137 struct drm_i915_gem_object *obj = vma->obj;
4138 bool mappable, fenceable;
4139 u32 fence_size, fence_alignment;
4140
4141 fence_size = i915_gem_get_gtt_size(obj->base.dev,
4142 obj->base.size,
4143 obj->tiling_mode);
4144 fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
4145 obj->base.size,
4146 obj->tiling_mode,
4147 true);
4148
4149 fenceable = (vma->node.size == fence_size &&
4150 (vma->node.start & (fence_alignment - 1)) == 0);
4151
4152 mappable = (vma->node.start + fence_size <=
4153 to_i915(obj->base.dev)->gtt.mappable_end);
4154
4155 obj->map_and_fenceable = mappable && fenceable;
4156}
4157
4083static int 4158static int
4084i915_gem_object_do_pin(struct drm_i915_gem_object *obj, 4159i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
4085 struct i915_address_space *vm, 4160 struct i915_address_space *vm,
@@ -4147,25 +4222,7 @@ i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
4147 4222
4148 if (ggtt_view && ggtt_view->type == I915_GGTT_VIEW_NORMAL && 4223 if (ggtt_view && ggtt_view->type == I915_GGTT_VIEW_NORMAL &&
4149 (bound ^ vma->bound) & GLOBAL_BIND) { 4224 (bound ^ vma->bound) & GLOBAL_BIND) {
4150 bool mappable, fenceable; 4225 __i915_vma_set_map_and_fenceable(vma);
4151 u32 fence_size, fence_alignment;
4152
4153 fence_size = i915_gem_get_gtt_size(obj->base.dev,
4154 obj->base.size,
4155 obj->tiling_mode);
4156 fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
4157 obj->base.size,
4158 obj->tiling_mode,
4159 true);
4160
4161 fenceable = (vma->node.size == fence_size &&
4162 (vma->node.start & (fence_alignment - 1)) == 0);
4163
4164 mappable = (vma->node.start + fence_size <=
4165 dev_priv->gtt.mappable_end);
4166
4167 obj->map_and_fenceable = mappable && fenceable;
4168
4169 WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable); 4226 WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable);
4170 } 4227 }
4171 4228
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 43f35d12b677..86c7500454b4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2676,6 +2676,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
2676 return ret; 2676 return ret;
2677 } 2677 }
2678 vma->bound |= GLOBAL_BIND; 2678 vma->bound |= GLOBAL_BIND;
2679 __i915_vma_set_map_and_fenceable(vma);
2679 list_add_tail(&vma->mm_list, &ggtt_vm->inactive_list); 2680 list_add_tail(&vma->mm_list, &ggtt_vm->inactive_list);
2680 } 2681 }
2681 2682
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index cdacf3f5b77a..87e919a06b27 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -687,6 +687,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
687 } 687 }
688 688
689 vma->bound |= GLOBAL_BIND; 689 vma->bound |= GLOBAL_BIND;
690 __i915_vma_set_map_and_fenceable(vma);
690 list_add_tail(&vma->mm_list, &ggtt->inactive_list); 691 list_add_tail(&vma->mm_list, &ggtt->inactive_list);
691 } 692 }
692 693
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 62211abe4922..beb0374a19f1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -116,6 +116,7 @@ static void skylake_pfit_enable(struct intel_crtc *crtc);
116static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force); 116static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
117static void ironlake_pfit_enable(struct intel_crtc *crtc); 117static void ironlake_pfit_enable(struct intel_crtc *crtc);
118static void intel_modeset_setup_hw_state(struct drm_device *dev); 118static void intel_modeset_setup_hw_state(struct drm_device *dev);
119static void intel_pre_disable_primary(struct drm_crtc *crtc);
119 120
120typedef struct { 121typedef struct {
121 int min, max; 122 int min, max;
@@ -2607,6 +2608,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
2607 struct drm_i915_gem_object *obj; 2608 struct drm_i915_gem_object *obj;
2608 struct drm_plane *primary = intel_crtc->base.primary; 2609 struct drm_plane *primary = intel_crtc->base.primary;
2609 struct drm_plane_state *plane_state = primary->state; 2610 struct drm_plane_state *plane_state = primary->state;
2611 struct drm_crtc_state *crtc_state = intel_crtc->base.state;
2612 struct intel_plane *intel_plane = to_intel_plane(primary);
2610 struct drm_framebuffer *fb; 2613 struct drm_framebuffer *fb;
2611 2614
2612 if (!plane_config->fb) 2615 if (!plane_config->fb)
@@ -2643,6 +2646,18 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
2643 } 2646 }
2644 } 2647 }
2645 2648
2649 /*
2650 * We've failed to reconstruct the BIOS FB. Current display state
2651 * indicates that the primary plane is visible, but has a NULL FB,
2652 * which will lead to problems later if we don't fix it up. The
2653 * simplest solution is to just disable the primary plane now and
2654 * pretend the BIOS never had it enabled.
2655 */
2656 to_intel_plane_state(plane_state)->visible = false;
2657 crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
2658 intel_pre_disable_primary(&intel_crtc->base);
2659 intel_plane->disable_plane(primary, &intel_crtc->base);
2660
2646 return; 2661 return;
2647 2662
2648valid_fb: 2663valid_fb:
@@ -9910,14 +9925,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
9910 return true; 9925 return true;
9911} 9926}
9912 9927
9913static void i845_update_cursor(struct drm_crtc *crtc, u32 base) 9928static void i845_update_cursor(struct drm_crtc *crtc, u32 base, bool on)
9914{ 9929{
9915 struct drm_device *dev = crtc->dev; 9930 struct drm_device *dev = crtc->dev;
9916 struct drm_i915_private *dev_priv = dev->dev_private; 9931 struct drm_i915_private *dev_priv = dev->dev_private;
9917 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 9932 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
9918 uint32_t cntl = 0, size = 0; 9933 uint32_t cntl = 0, size = 0;
9919 9934
9920 if (base) { 9935 if (on) {
9921 unsigned int width = intel_crtc->base.cursor->state->crtc_w; 9936 unsigned int width = intel_crtc->base.cursor->state->crtc_w;
9922 unsigned int height = intel_crtc->base.cursor->state->crtc_h; 9937 unsigned int height = intel_crtc->base.cursor->state->crtc_h;
9923 unsigned int stride = roundup_pow_of_two(width) * 4; 9938 unsigned int stride = roundup_pow_of_two(width) * 4;
@@ -9972,16 +9987,15 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
9972 } 9987 }
9973} 9988}
9974 9989
9975static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) 9990static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, bool on)
9976{ 9991{
9977 struct drm_device *dev = crtc->dev; 9992 struct drm_device *dev = crtc->dev;
9978 struct drm_i915_private *dev_priv = dev->dev_private; 9993 struct drm_i915_private *dev_priv = dev->dev_private;
9979 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 9994 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
9980 int pipe = intel_crtc->pipe; 9995 int pipe = intel_crtc->pipe;
9981 uint32_t cntl; 9996 uint32_t cntl = 0;
9982 9997
9983 cntl = 0; 9998 if (on) {
9984 if (base) {
9985 cntl = MCURSOR_GAMMA_ENABLE; 9999 cntl = MCURSOR_GAMMA_ENABLE;
9986 switch (intel_crtc->base.cursor->state->crtc_w) { 10000 switch (intel_crtc->base.cursor->state->crtc_w) {
9987 case 64: 10001 case 64:
@@ -10032,18 +10046,17 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
10032 int y = cursor_state->crtc_y; 10046 int y = cursor_state->crtc_y;
10033 u32 base = 0, pos = 0; 10047 u32 base = 0, pos = 0;
10034 10048
10035 if (on) 10049 base = intel_crtc->cursor_addr;
10036 base = intel_crtc->cursor_addr;
10037 10050
10038 if (x >= intel_crtc->config->pipe_src_w) 10051 if (x >= intel_crtc->config->pipe_src_w)
10039 base = 0; 10052 on = false;
10040 10053
10041 if (y >= intel_crtc->config->pipe_src_h) 10054 if (y >= intel_crtc->config->pipe_src_h)
10042 base = 0; 10055 on = false;
10043 10056
10044 if (x < 0) { 10057 if (x < 0) {
10045 if (x + cursor_state->crtc_w <= 0) 10058 if (x + cursor_state->crtc_w <= 0)
10046 base = 0; 10059 on = false;
10047 10060
10048 pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; 10061 pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
10049 x = -x; 10062 x = -x;
@@ -10052,16 +10065,13 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
10052 10065
10053 if (y < 0) { 10066 if (y < 0) {
10054 if (y + cursor_state->crtc_h <= 0) 10067 if (y + cursor_state->crtc_h <= 0)
10055 base = 0; 10068 on = false;
10056 10069
10057 pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; 10070 pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
10058 y = -y; 10071 y = -y;
10059 } 10072 }
10060 pos |= y << CURSOR_Y_SHIFT; 10073 pos |= y << CURSOR_Y_SHIFT;
10061 10074
10062 if (base == 0 && intel_crtc->cursor_base == 0)
10063 return;
10064
10065 I915_WRITE(CURPOS(pipe), pos); 10075 I915_WRITE(CURPOS(pipe), pos);
10066 10076
10067 /* ILK+ do this automagically */ 10077 /* ILK+ do this automagically */
@@ -10072,9 +10082,9 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
10072 } 10082 }
10073 10083
10074 if (IS_845G(dev) || IS_I865G(dev)) 10084 if (IS_845G(dev) || IS_I865G(dev))
10075 i845_update_cursor(crtc, base); 10085 i845_update_cursor(crtc, base, on);
10076 else 10086 else
10077 i9xx_update_cursor(crtc, base); 10087 i9xx_update_cursor(crtc, base, on);
10078} 10088}
10079 10089
10080static bool cursor_size_ok(struct drm_device *dev, 10090static bool cursor_size_ok(struct drm_device *dev,
@@ -13718,6 +13728,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
13718 struct drm_crtc *crtc = crtc_state->base.crtc; 13728 struct drm_crtc *crtc = crtc_state->base.crtc;
13719 struct drm_framebuffer *fb = state->base.fb; 13729 struct drm_framebuffer *fb = state->base.fb;
13720 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 13730 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
13731 enum pipe pipe = to_intel_plane(plane)->pipe;
13721 unsigned stride; 13732 unsigned stride;
13722 int ret; 13733 int ret;
13723 13734
@@ -13751,6 +13762,22 @@ intel_check_cursor_plane(struct drm_plane *plane,
13751 return -EINVAL; 13762 return -EINVAL;
13752 } 13763 }
13753 13764
13765 /*
13766 * There's something wrong with the cursor on CHV pipe C.
13767 * If it straddles the left edge of the screen then
13768 * moving it away from the edge or disabling it often
13769 * results in a pipe underrun, and often that can lead to
13770 * dead pipe (constant underrun reported, and it scans
13771 * out just a solid color). To recover from that, the
13772 * display power well must be turned off and on again.
13773 * Refuse the put the cursor into that compromised position.
13774 */
13775 if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C &&
13776 state->visible && state->base.crtc_x < 0) {
13777 DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
13778 return -EINVAL;
13779 }
13780
13754 return 0; 13781 return 0;
13755} 13782}
13756 13783
@@ -13774,9 +13801,6 @@ intel_commit_cursor_plane(struct drm_plane *plane,
13774 crtc = crtc ? crtc : plane->crtc; 13801 crtc = crtc ? crtc : plane->crtc;
13775 intel_crtc = to_intel_crtc(crtc); 13802 intel_crtc = to_intel_crtc(crtc);
13776 13803
13777 if (intel_crtc->cursor_bo == obj)
13778 goto update;
13779
13780 if (!obj) 13804 if (!obj)
13781 addr = 0; 13805 addr = 0;
13782 else if (!INTEL_INFO(dev)->cursor_needs_physical) 13806 else if (!INTEL_INFO(dev)->cursor_needs_physical)
@@ -13785,9 +13809,7 @@ intel_commit_cursor_plane(struct drm_plane *plane,
13785 addr = obj->phys_handle->busaddr; 13809 addr = obj->phys_handle->busaddr;
13786 13810
13787 intel_crtc->cursor_addr = addr; 13811 intel_crtc->cursor_addr = addr;
13788 intel_crtc->cursor_bo = obj;
13789 13812
13790update:
13791 if (crtc->state->active) 13813 if (crtc->state->active)
13792 intel_crtc_update_cursor(crtc, state->visible); 13814 intel_crtc_update_cursor(crtc, state->visible);
13793} 13815}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f2a1142bff34..0d00f07b7163 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -550,7 +550,6 @@ struct intel_crtc {
550 int adjusted_x; 550 int adjusted_x;
551 int adjusted_y; 551 int adjusted_y;
552 552
553 struct drm_i915_gem_object *cursor_bo;
554 uint32_t cursor_addr; 553 uint32_t cursor_addr;
555 uint32_t cursor_cntl; 554 uint32_t cursor_cntl;
556 uint32_t cursor_size; 555 uint32_t cursor_size;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 81cdd9ff3892..64086f2d4e26 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1374,17 +1374,18 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
1374 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); 1374 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
1375 struct drm_i915_private *dev_priv = to_i915(connector->dev); 1375 struct drm_i915_private *dev_priv = to_i915(connector->dev);
1376 bool live_status = false; 1376 bool live_status = false;
1377 unsigned int retry = 3; 1377 unsigned int try;
1378 1378
1379 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", 1379 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1380 connector->base.id, connector->name); 1380 connector->base.id, connector->name);
1381 1381
1382 intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); 1382 intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
1383 1383
1384 while (!live_status && --retry) { 1384 for (try = 0; !live_status && try < 4; try++) {
1385 if (try)
1386 msleep(10);
1385 live_status = intel_digital_port_connected(dev_priv, 1387 live_status = intel_digital_port_connected(dev_priv,
1386 hdmi_to_dig_port(intel_hdmi)); 1388 hdmi_to_dig_port(intel_hdmi));
1387 mdelay(10);
1388 } 1389 }
1389 1390
1390 if (!live_status) 1391 if (!live_status)