diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sprite.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 1fa5612a4572..78b621cdd108 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -38,7 +38,8 @@ | |||
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | 39 | ||
40 | static void | 40 | static void |
41 | vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, | 41 | vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, |
42 | struct drm_framebuffer *fb, | ||
42 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, | 43 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
43 | unsigned int crtc_w, unsigned int crtc_h, | 44 | unsigned int crtc_w, unsigned int crtc_h, |
44 | uint32_t x, uint32_t y, | 45 | uint32_t x, uint32_t y, |
@@ -108,14 +109,15 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, | |||
108 | 109 | ||
109 | sprctl |= SP_ENABLE; | 110 | sprctl |= SP_ENABLE; |
110 | 111 | ||
112 | intel_update_sprite_watermarks(dplane, crtc, src_w, pixel_size, true, | ||
113 | src_w != crtc_w || src_h != crtc_h); | ||
114 | |||
111 | /* Sizes are 0 based */ | 115 | /* Sizes are 0 based */ |
112 | src_w--; | 116 | src_w--; |
113 | src_h--; | 117 | src_h--; |
114 | crtc_w--; | 118 | crtc_w--; |
115 | crtc_h--; | 119 | crtc_h--; |
116 | 120 | ||
117 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); | ||
118 | |||
119 | I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); | 121 | I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); |
120 | I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); | 122 | I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); |
121 | 123 | ||
@@ -133,13 +135,13 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, | |||
133 | 135 | ||
134 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); | 136 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
135 | I915_WRITE(SPCNTR(pipe, plane), sprctl); | 137 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
136 | I915_MODIFY_DISPBASE(SPSURF(pipe, plane), obj->gtt_offset + | 138 | I915_MODIFY_DISPBASE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + |
137 | sprsurf_offset); | 139 | sprsurf_offset); |
138 | POSTING_READ(SPSURF(pipe, plane)); | 140 | POSTING_READ(SPSURF(pipe, plane)); |
139 | } | 141 | } |
140 | 142 | ||
141 | static void | 143 | static void |
142 | vlv_disable_plane(struct drm_plane *dplane) | 144 | vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) |
143 | { | 145 | { |
144 | struct drm_device *dev = dplane->dev; | 146 | struct drm_device *dev = dplane->dev; |
145 | struct drm_i915_private *dev_priv = dev->dev_private; | 147 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -152,6 +154,8 @@ vlv_disable_plane(struct drm_plane *dplane) | |||
152 | /* Activate double buffered register update */ | 154 | /* Activate double buffered register update */ |
153 | I915_MODIFY_DISPBASE(SPSURF(pipe, plane), 0); | 155 | I915_MODIFY_DISPBASE(SPSURF(pipe, plane), 0); |
154 | POSTING_READ(SPSURF(pipe, plane)); | 156 | POSTING_READ(SPSURF(pipe, plane)); |
157 | |||
158 | intel_update_sprite_watermarks(dplane, crtc, 0, 0, false, false); | ||
155 | } | 159 | } |
156 | 160 | ||
157 | static int | 161 | static int |
@@ -206,7 +210,8 @@ vlv_get_colorkey(struct drm_plane *dplane, | |||
206 | } | 210 | } |
207 | 211 | ||
208 | static void | 212 | static void |
209 | ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | 213 | ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
214 | struct drm_framebuffer *fb, | ||
210 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, | 215 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
211 | unsigned int crtc_w, unsigned int crtc_h, | 216 | unsigned int crtc_w, unsigned int crtc_h, |
212 | uint32_t x, uint32_t y, | 217 | uint32_t x, uint32_t y, |
@@ -262,14 +267,15 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
262 | if (IS_HASWELL(dev)) | 267 | if (IS_HASWELL(dev)) |
263 | sprctl |= SPRITE_PIPE_CSC_ENABLE; | 268 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
264 | 269 | ||
270 | intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, | ||
271 | src_w != crtc_w || src_h != crtc_h); | ||
272 | |||
265 | /* Sizes are 0 based */ | 273 | /* Sizes are 0 based */ |
266 | src_w--; | 274 | src_w--; |
267 | src_h--; | 275 | src_h--; |
268 | crtc_w--; | 276 | crtc_w--; |
269 | crtc_h--; | 277 | crtc_h--; |
270 | 278 | ||
271 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); | ||
272 | |||
273 | /* | 279 | /* |
274 | * IVB workaround: must disable low power watermarks for at least | 280 | * IVB workaround: must disable low power watermarks for at least |
275 | * one frame before enabling scaling. LP watermarks can be re-enabled | 281 | * one frame before enabling scaling. LP watermarks can be re-enabled |
@@ -308,7 +314,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
308 | if (intel_plane->can_scale) | 314 | if (intel_plane->can_scale) |
309 | I915_WRITE(SPRSCALE(pipe), sprscale); | 315 | I915_WRITE(SPRSCALE(pipe), sprscale); |
310 | I915_WRITE(SPRCTL(pipe), sprctl); | 316 | I915_WRITE(SPRCTL(pipe), sprctl); |
311 | I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset); | 317 | I915_MODIFY_DISPBASE(SPRSURF(pipe), |
318 | i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); | ||
312 | POSTING_READ(SPRSURF(pipe)); | 319 | POSTING_READ(SPRSURF(pipe)); |
313 | 320 | ||
314 | /* potentially re-enable LP watermarks */ | 321 | /* potentially re-enable LP watermarks */ |
@@ -317,7 +324,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
317 | } | 324 | } |
318 | 325 | ||
319 | static void | 326 | static void |
320 | ivb_disable_plane(struct drm_plane *plane) | 327 | ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
321 | { | 328 | { |
322 | struct drm_device *dev = plane->dev; | 329 | struct drm_device *dev = plane->dev; |
323 | struct drm_i915_private *dev_priv = dev->dev_private; | 330 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -335,7 +342,7 @@ ivb_disable_plane(struct drm_plane *plane) | |||
335 | 342 | ||
336 | dev_priv->sprite_scaling_enabled &= ~(1 << pipe); | 343 | dev_priv->sprite_scaling_enabled &= ~(1 << pipe); |
337 | 344 | ||
338 | intel_update_sprite_watermarks(dev, pipe, 0, 0, false); | 345 | intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); |
339 | 346 | ||
340 | /* potentially re-enable LP watermarks */ | 347 | /* potentially re-enable LP watermarks */ |
341 | if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) | 348 | if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) |
@@ -397,7 +404,8 @@ ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) | |||
397 | } | 404 | } |
398 | 405 | ||
399 | static void | 406 | static void |
400 | ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | 407 | ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
408 | struct drm_framebuffer *fb, | ||
401 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, | 409 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
402 | unsigned int crtc_w, unsigned int crtc_h, | 410 | unsigned int crtc_w, unsigned int crtc_h, |
403 | uint32_t x, uint32_t y, | 411 | uint32_t x, uint32_t y, |
@@ -449,14 +457,15 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
449 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ | 457 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
450 | dvscntr |= DVS_ENABLE; | 458 | dvscntr |= DVS_ENABLE; |
451 | 459 | ||
460 | intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, | ||
461 | src_w != crtc_w || src_h != crtc_h); | ||
462 | |||
452 | /* Sizes are 0 based */ | 463 | /* Sizes are 0 based */ |
453 | src_w--; | 464 | src_w--; |
454 | src_h--; | 465 | src_h--; |
455 | crtc_w--; | 466 | crtc_w--; |
456 | crtc_h--; | 467 | crtc_h--; |
457 | 468 | ||
458 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); | ||
459 | |||
460 | dvsscale = 0; | 469 | dvsscale = 0; |
461 | if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) | 470 | if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) |
462 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; | 471 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
@@ -478,12 +487,13 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
478 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); | 487 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
479 | I915_WRITE(DVSSCALE(pipe), dvsscale); | 488 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
480 | I915_WRITE(DVSCNTR(pipe), dvscntr); | 489 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
481 | I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset + dvssurf_offset); | 490 | I915_MODIFY_DISPBASE(DVSSURF(pipe), |
491 | i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); | ||
482 | POSTING_READ(DVSSURF(pipe)); | 492 | POSTING_READ(DVSSURF(pipe)); |
483 | } | 493 | } |
484 | 494 | ||
485 | static void | 495 | static void |
486 | ilk_disable_plane(struct drm_plane *plane) | 496 | ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
487 | { | 497 | { |
488 | struct drm_device *dev = plane->dev; | 498 | struct drm_device *dev = plane->dev; |
489 | struct drm_i915_private *dev_priv = dev->dev_private; | 499 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -496,6 +506,8 @@ ilk_disable_plane(struct drm_plane *plane) | |||
496 | /* Flush double buffered register updates */ | 506 | /* Flush double buffered register updates */ |
497 | I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); | 507 | I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); |
498 | POSTING_READ(DVSSURF(pipe)); | 508 | POSTING_READ(DVSSURF(pipe)); |
509 | |||
510 | intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); | ||
499 | } | 511 | } |
500 | 512 | ||
501 | static void | 513 | static void |
@@ -818,11 +830,11 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
818 | intel_enable_primary(crtc); | 830 | intel_enable_primary(crtc); |
819 | 831 | ||
820 | if (visible) | 832 | if (visible) |
821 | intel_plane->update_plane(plane, fb, obj, | 833 | intel_plane->update_plane(plane, crtc, fb, obj, |
822 | crtc_x, crtc_y, crtc_w, crtc_h, | 834 | crtc_x, crtc_y, crtc_w, crtc_h, |
823 | src_x, src_y, src_w, src_h); | 835 | src_x, src_y, src_w, src_h); |
824 | else | 836 | else |
825 | intel_plane->disable_plane(plane); | 837 | intel_plane->disable_plane(plane, crtc); |
826 | 838 | ||
827 | if (disable_primary) | 839 | if (disable_primary) |
828 | intel_disable_primary(crtc); | 840 | intel_disable_primary(crtc); |
@@ -855,9 +867,14 @@ intel_disable_plane(struct drm_plane *plane) | |||
855 | struct intel_plane *intel_plane = to_intel_plane(plane); | 867 | struct intel_plane *intel_plane = to_intel_plane(plane); |
856 | int ret = 0; | 868 | int ret = 0; |
857 | 869 | ||
858 | if (plane->crtc) | 870 | if (!plane->fb) |
859 | intel_enable_primary(plane->crtc); | 871 | return 0; |
860 | intel_plane->disable_plane(plane); | 872 | |
873 | if (WARN_ON(!plane->crtc)) | ||
874 | return -EINVAL; | ||
875 | |||
876 | intel_enable_primary(plane->crtc); | ||
877 | intel_plane->disable_plane(plane, plane->crtc); | ||
861 | 878 | ||
862 | if (!intel_plane->obj) | 879 | if (!intel_plane->obj) |
863 | goto out; | 880 | goto out; |