aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sprite.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sprite.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c86
1 files changed, 50 insertions, 36 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index b9fabf826f7d..716a3c9c0751 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -104,6 +104,12 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
104 break; 104 break;
105 } 105 }
106 106
107 /*
108 * Enable gamma to match primary/cursor plane behaviour.
109 * FIXME should be user controllable via propertiesa.
110 */
111 sprctl |= SP_GAMMA_ENABLE;
112
107 if (obj->tiling_mode != I915_TILING_NONE) 113 if (obj->tiling_mode != I915_TILING_NONE)
108 sprctl |= SP_TILED; 114 sprctl |= SP_TILED;
109 115
@@ -135,8 +141,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
135 141
136 I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); 142 I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
137 I915_WRITE(SPCNTR(pipe, plane), sprctl); 143 I915_WRITE(SPCNTR(pipe, plane), sprctl);
138 I915_MODIFY_DISPBASE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + 144 I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
139 sprsurf_offset); 145 sprsurf_offset);
140 POSTING_READ(SPSURF(pipe, plane)); 146 POSTING_READ(SPSURF(pipe, plane));
141} 147}
142 148
@@ -152,7 +158,7 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
152 I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & 158 I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) &
153 ~SP_ENABLE); 159 ~SP_ENABLE);
154 /* Activate double buffered register update */ 160 /* Activate double buffered register update */
155 I915_MODIFY_DISPBASE(SPSURF(pipe, plane), 0); 161 I915_WRITE(SPSURF(pipe, plane), 0);
156 POSTING_READ(SPSURF(pipe, plane)); 162 POSTING_READ(SPSURF(pipe, plane));
157 163
158 intel_update_sprite_watermarks(dplane, crtc, 0, 0, false, false); 164 intel_update_sprite_watermarks(dplane, crtc, 0, 0, false, false);
@@ -224,7 +230,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
224 u32 sprctl, sprscale = 0; 230 u32 sprctl, sprscale = 0;
225 unsigned long sprsurf_offset, linear_offset; 231 unsigned long sprsurf_offset, linear_offset;
226 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 232 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
227 bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
228 233
229 sprctl = I915_READ(SPRCTL(pipe)); 234 sprctl = I915_READ(SPRCTL(pipe));
230 235
@@ -257,6 +262,12 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
257 BUG(); 262 BUG();
258 } 263 }
259 264
265 /*
266 * Enable gamma to match primary/cursor plane behaviour.
267 * FIXME should be user controllable via propertiesa.
268 */
269 sprctl |= SPRITE_GAMMA_ENABLE;
270
260 if (obj->tiling_mode != I915_TILING_NONE) 271 if (obj->tiling_mode != I915_TILING_NONE)
261 sprctl |= SPRITE_TILED; 272 sprctl |= SPRITE_TILED;
262 273
@@ -279,21 +290,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
279 crtc_w--; 290 crtc_w--;
280 crtc_h--; 291 crtc_h--;
281 292
282 /* 293 if (crtc_w != src_w || crtc_h != src_h)
283 * IVB workaround: must disable low power watermarks for at least
284 * one frame before enabling scaling. LP watermarks can be re-enabled
285 * when scaling is disabled.
286 */
287 if (crtc_w != src_w || crtc_h != src_h) {
288 dev_priv->sprite_scaling_enabled |= 1 << pipe;
289
290 if (!scaling_was_enabled) {
291 intel_update_watermarks(crtc);
292 intel_wait_for_vblank(dev, pipe);
293 }
294 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 294 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
295 } else
296 dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
297 295
298 I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); 296 I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
299 I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 297 I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
@@ -317,13 +315,9 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
317 if (intel_plane->can_scale) 315 if (intel_plane->can_scale)
318 I915_WRITE(SPRSCALE(pipe), sprscale); 316 I915_WRITE(SPRSCALE(pipe), sprscale);
319 I915_WRITE(SPRCTL(pipe), sprctl); 317 I915_WRITE(SPRCTL(pipe), sprctl);
320 I915_MODIFY_DISPBASE(SPRSURF(pipe), 318 I915_WRITE(SPRSURF(pipe),
321 i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); 319 i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
322 POSTING_READ(SPRSURF(pipe)); 320 POSTING_READ(SPRSURF(pipe));
323
324 /* potentially re-enable LP watermarks */
325 if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
326 intel_update_watermarks(crtc);
327} 321}
328 322
329static void 323static void
@@ -333,23 +327,22 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
333 struct drm_i915_private *dev_priv = dev->dev_private; 327 struct drm_i915_private *dev_priv = dev->dev_private;
334 struct intel_plane *intel_plane = to_intel_plane(plane); 328 struct intel_plane *intel_plane = to_intel_plane(plane);
335 int pipe = intel_plane->pipe; 329 int pipe = intel_plane->pipe;
336 bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
337 330
338 I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); 331 I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
339 /* Can't leave the scaler enabled... */ 332 /* Can't leave the scaler enabled... */
340 if (intel_plane->can_scale) 333 if (intel_plane->can_scale)
341 I915_WRITE(SPRSCALE(pipe), 0); 334 I915_WRITE(SPRSCALE(pipe), 0);
342 /* Activate double buffered register update */ 335 /* Activate double buffered register update */
343 I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); 336 I915_WRITE(SPRSURF(pipe), 0);
344 POSTING_READ(SPRSURF(pipe)); 337 POSTING_READ(SPRSURF(pipe));
345 338
346 dev_priv->sprite_scaling_enabled &= ~(1 << pipe); 339 /*
340 * Avoid underruns when disabling the sprite.
341 * FIXME remove once watermark updates are done properly.
342 */
343 intel_wait_for_vblank(dev, pipe);
347 344
348 intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); 345 intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false);
349
350 /* potentially re-enable LP watermarks */
351 if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
352 intel_update_watermarks(crtc);
353} 346}
354 347
355static int 348static int
@@ -453,6 +446,12 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
453 BUG(); 446 BUG();
454 } 447 }
455 448
449 /*
450 * Enable gamma to match primary/cursor plane behaviour.
451 * FIXME should be user controllable via propertiesa.
452 */
453 dvscntr |= DVS_GAMMA_ENABLE;
454
456 if (obj->tiling_mode != I915_TILING_NONE) 455 if (obj->tiling_mode != I915_TILING_NONE)
457 dvscntr |= DVS_TILED; 456 dvscntr |= DVS_TILED;
458 457
@@ -470,7 +469,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
470 crtc_h--; 469 crtc_h--;
471 470
472 dvsscale = 0; 471 dvsscale = 0;
473 if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) 472 if (crtc_w != src_w || crtc_h != src_h)
474 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; 473 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
475 474
476 I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); 475 I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
@@ -490,8 +489,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
490 I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 489 I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
491 I915_WRITE(DVSSCALE(pipe), dvsscale); 490 I915_WRITE(DVSSCALE(pipe), dvsscale);
492 I915_WRITE(DVSCNTR(pipe), dvscntr); 491 I915_WRITE(DVSCNTR(pipe), dvscntr);
493 I915_MODIFY_DISPBASE(DVSSURF(pipe), 492 I915_WRITE(DVSSURF(pipe),
494 i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); 493 i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
495 POSTING_READ(DVSSURF(pipe)); 494 POSTING_READ(DVSSURF(pipe));
496} 495}
497 496
@@ -507,9 +506,15 @@ ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
507 /* Disable the scaler */ 506 /* Disable the scaler */
508 I915_WRITE(DVSSCALE(pipe), 0); 507 I915_WRITE(DVSSCALE(pipe), 0);
509 /* Flush double buffered register updates */ 508 /* Flush double buffered register updates */
510 I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); 509 I915_WRITE(DVSSURF(pipe), 0);
511 POSTING_READ(DVSSURF(pipe)); 510 POSTING_READ(DVSSURF(pipe));
512 511
512 /*
513 * Avoid underruns when disabling the sprite.
514 * FIXME remove once watermark updates are done properly.
515 */
516 intel_wait_for_vblank(dev, pipe);
517
513 intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); 518 intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false);
514} 519}
515 520
@@ -643,6 +648,15 @@ format_is_yuv(uint32_t format)
643 } 648 }
644} 649}
645 650
651static bool colorkey_enabled(struct intel_plane *intel_plane)
652{
653 struct drm_intel_sprite_colorkey key;
654
655 intel_plane->get_colorkey(&intel_plane->base, &key);
656
657 return key.flags != I915_SET_COLORKEY_NONE;
658}
659
646static int 660static int
647intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 661intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
648 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 662 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -828,7 +842,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
828 * If the sprite is completely covering the primary plane, 842 * If the sprite is completely covering the primary plane,
829 * we can disable the primary and save power. 843 * we can disable the primary and save power.
830 */ 844 */
831 disable_primary = drm_rect_equals(&dst, &clip); 845 disable_primary = drm_rect_equals(&dst, &clip) && !colorkey_enabled(intel_plane);
832 WARN_ON(disable_primary && !visible && intel_crtc->active); 846 WARN_ON(disable_primary && !visible && intel_crtc->active);
833 847
834 mutex_lock(&dev->struct_mutex); 848 mutex_lock(&dev->struct_mutex);