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.c203
1 files changed, 119 insertions, 84 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index ad6ec4b39005..b9fabf826f7d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -260,14 +260,14 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
260 if (obj->tiling_mode != I915_TILING_NONE) 260 if (obj->tiling_mode != I915_TILING_NONE)
261 sprctl |= SPRITE_TILED; 261 sprctl |= SPRITE_TILED;
262 262
263 if (IS_HASWELL(dev)) 263 if (IS_HASWELL(dev) || IS_BROADWELL(dev))
264 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; 264 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
265 else 265 else
266 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 266 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
267 267
268 sprctl |= SPRITE_ENABLE; 268 sprctl |= SPRITE_ENABLE;
269 269
270 if (IS_HASWELL(dev)) 270 if (IS_HASWELL(dev) || IS_BROADWELL(dev))
271 sprctl |= SPRITE_PIPE_CSC_ENABLE; 271 sprctl |= SPRITE_PIPE_CSC_ENABLE;
272 272
273 intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, 273 intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true,
@@ -288,7 +288,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
288 dev_priv->sprite_scaling_enabled |= 1 << pipe; 288 dev_priv->sprite_scaling_enabled |= 1 << pipe;
289 289
290 if (!scaling_was_enabled) { 290 if (!scaling_was_enabled) {
291 intel_update_watermarks(dev); 291 intel_update_watermarks(crtc);
292 intel_wait_for_vblank(dev, pipe); 292 intel_wait_for_vblank(dev, pipe);
293 } 293 }
294 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 294 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
@@ -306,7 +306,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
306 306
307 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 307 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
308 * register */ 308 * register */
309 if (IS_HASWELL(dev)) 309 if (IS_HASWELL(dev) || IS_BROADWELL(dev))
310 I915_WRITE(SPROFFSET(pipe), (y << 16) | x); 310 I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
311 else if (obj->tiling_mode != I915_TILING_NONE) 311 else if (obj->tiling_mode != I915_TILING_NONE)
312 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); 312 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
@@ -323,7 +323,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
323 323
324 /* potentially re-enable LP watermarks */ 324 /* potentially re-enable LP watermarks */
325 if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) 325 if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
326 intel_update_watermarks(dev); 326 intel_update_watermarks(crtc);
327} 327}
328 328
329static void 329static void
@@ -349,7 +349,7 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
349 349
350 /* potentially re-enable LP watermarks */ 350 /* potentially re-enable LP watermarks */
351 if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) 351 if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
352 intel_update_watermarks(dev); 352 intel_update_watermarks(crtc);
353} 353}
354 354
355static int 355static int
@@ -521,13 +521,28 @@ intel_enable_primary(struct drm_crtc *crtc)
521 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 521 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
522 int reg = DSPCNTR(intel_crtc->plane); 522 int reg = DSPCNTR(intel_crtc->plane);
523 523
524 if (!intel_crtc->primary_disabled) 524 if (intel_crtc->primary_enabled)
525 return; 525 return;
526 526
527 intel_crtc->primary_disabled = false; 527 intel_crtc->primary_enabled = true;
528 intel_update_fbc(dev);
529 528
530 I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); 529 I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
530 intel_flush_primary_plane(dev_priv, intel_crtc->plane);
531
532 /*
533 * FIXME IPS should be fine as long as one plane is
534 * enabled, but in practice it seems to have problems
535 * when going from primary only to sprite only and vice
536 * versa.
537 */
538 if (intel_crtc->config.ips_enabled) {
539 intel_wait_for_vblank(dev, intel_crtc->pipe);
540 hsw_enable_ips(intel_crtc);
541 }
542
543 mutex_lock(&dev->struct_mutex);
544 intel_update_fbc(dev);
545 mutex_unlock(&dev->struct_mutex);
531} 546}
532 547
533static void 548static void
@@ -538,13 +553,26 @@ intel_disable_primary(struct drm_crtc *crtc)
538 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 553 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
539 int reg = DSPCNTR(intel_crtc->plane); 554 int reg = DSPCNTR(intel_crtc->plane);
540 555
541 if (intel_crtc->primary_disabled) 556 if (!intel_crtc->primary_enabled)
542 return; 557 return;
543 558
544 I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); 559 intel_crtc->primary_enabled = false;
545 560
546 intel_crtc->primary_disabled = true; 561 mutex_lock(&dev->struct_mutex);
547 intel_update_fbc(dev); 562 if (dev_priv->fbc.plane == intel_crtc->plane)
563 intel_disable_fbc(dev);
564 mutex_unlock(&dev->struct_mutex);
565
566 /*
567 * FIXME IPS should be fine as long as one plane is
568 * enabled, but in practice it seems to have problems
569 * when going from primary only to sprite only and vice
570 * versa.
571 */
572 hsw_disable_ips(intel_crtc);
573
574 I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
575 intel_flush_primary_plane(dev_priv, intel_crtc->plane);
548} 576}
549 577
550static int 578static int
@@ -623,15 +651,12 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
623 uint32_t src_w, uint32_t src_h) 651 uint32_t src_w, uint32_t src_h)
624{ 652{
625 struct drm_device *dev = plane->dev; 653 struct drm_device *dev = plane->dev;
626 struct drm_i915_private *dev_priv = dev->dev_private;
627 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 654 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
628 struct intel_plane *intel_plane = to_intel_plane(plane); 655 struct intel_plane *intel_plane = to_intel_plane(plane);
629 struct intel_framebuffer *intel_fb; 656 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
630 struct drm_i915_gem_object *obj, *old_obj; 657 struct drm_i915_gem_object *obj = intel_fb->obj;
631 int pipe = intel_plane->pipe; 658 struct drm_i915_gem_object *old_obj = intel_plane->obj;
632 enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, 659 int ret;
633 pipe);
634 int ret = 0;
635 bool disable_primary = false; 660 bool disable_primary = false;
636 bool visible; 661 bool visible;
637 int hscale, vscale; 662 int hscale, vscale;
@@ -652,29 +677,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
652 .y2 = crtc_y + crtc_h, 677 .y2 = crtc_y + crtc_h,
653 }; 678 };
654 const struct drm_rect clip = { 679 const struct drm_rect clip = {
655 .x2 = crtc->mode.hdisplay, 680 .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
656 .y2 = crtc->mode.vdisplay, 681 .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
682 };
683 const struct {
684 int crtc_x, crtc_y;
685 unsigned int crtc_w, crtc_h;
686 uint32_t src_x, src_y, src_w, src_h;
687 } orig = {
688 .crtc_x = crtc_x,
689 .crtc_y = crtc_y,
690 .crtc_w = crtc_w,
691 .crtc_h = crtc_h,
692 .src_x = src_x,
693 .src_y = src_y,
694 .src_w = src_w,
695 .src_h = src_h,
657 }; 696 };
658
659 intel_fb = to_intel_framebuffer(fb);
660 obj = intel_fb->obj;
661
662 old_obj = intel_plane->obj;
663
664 intel_plane->crtc_x = crtc_x;
665 intel_plane->crtc_y = crtc_y;
666 intel_plane->crtc_w = crtc_w;
667 intel_plane->crtc_h = crtc_h;
668 intel_plane->src_x = src_x;
669 intel_plane->src_y = src_y;
670 intel_plane->src_w = src_w;
671 intel_plane->src_h = src_h;
672
673 /* Pipe must be running... */
674 if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) {
675 DRM_DEBUG_KMS("Pipe disabled\n");
676 return -EINVAL;
677 }
678 697
679 /* Don't modify another pipe's plane */ 698 /* Don't modify another pipe's plane */
680 if (intel_plane->pipe != intel_crtc->pipe) { 699 if (intel_plane->pipe != intel_crtc->pipe) {
@@ -810,7 +829,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
810 * we can disable the primary and save power. 829 * we can disable the primary and save power.
811 */ 830 */
812 disable_primary = drm_rect_equals(&dst, &clip); 831 disable_primary = drm_rect_equals(&dst, &clip);
813 WARN_ON(disable_primary && !visible); 832 WARN_ON(disable_primary && !visible && intel_crtc->active);
814 833
815 mutex_lock(&dev->struct_mutex); 834 mutex_lock(&dev->struct_mutex);
816 835
@@ -820,27 +839,40 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
820 * the sprite planes only require 128KiB alignment and 32 PTE padding. 839 * the sprite planes only require 128KiB alignment and 32 PTE padding.
821 */ 840 */
822 ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); 841 ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
823 if (ret)
824 goto out_unlock;
825 842
826 intel_plane->obj = obj; 843 mutex_unlock(&dev->struct_mutex);
827
828 /*
829 * Be sure to re-enable the primary before the sprite is no longer
830 * covering it fully.
831 */
832 if (!disable_primary)
833 intel_enable_primary(crtc);
834 844
835 if (visible) 845 if (ret)
836 intel_plane->update_plane(plane, crtc, fb, obj, 846 return ret;
837 crtc_x, crtc_y, crtc_w, crtc_h, 847
838 src_x, src_y, src_w, src_h); 848 intel_plane->crtc_x = orig.crtc_x;
839 else 849 intel_plane->crtc_y = orig.crtc_y;
840 intel_plane->disable_plane(plane, crtc); 850 intel_plane->crtc_w = orig.crtc_w;
851 intel_plane->crtc_h = orig.crtc_h;
852 intel_plane->src_x = orig.src_x;
853 intel_plane->src_y = orig.src_y;
854 intel_plane->src_w = orig.src_w;
855 intel_plane->src_h = orig.src_h;
856 intel_plane->obj = obj;
841 857
842 if (disable_primary) 858 if (intel_crtc->active) {
843 intel_disable_primary(crtc); 859 /*
860 * Be sure to re-enable the primary before the sprite is no longer
861 * covering it fully.
862 */
863 if (!disable_primary)
864 intel_enable_primary(crtc);
865
866 if (visible)
867 intel_plane->update_plane(plane, crtc, fb, obj,
868 crtc_x, crtc_y, crtc_w, crtc_h,
869 src_x, src_y, src_w, src_h);
870 else
871 intel_plane->disable_plane(plane, crtc);
872
873 if (disable_primary)
874 intel_disable_primary(crtc);
875 }
844 876
845 /* Unpin old obj after new one is active to avoid ugliness */ 877 /* Unpin old obj after new one is active to avoid ugliness */
846 if (old_obj) { 878 if (old_obj) {
@@ -850,17 +882,15 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
850 * wait for vblank to avoid ugliness, we only need to 882 * wait for vblank to avoid ugliness, we only need to
851 * do the pin & ref bookkeeping. 883 * do the pin & ref bookkeeping.
852 */ 884 */
853 if (old_obj != obj) { 885 if (old_obj != obj && intel_crtc->active)
854 mutex_unlock(&dev->struct_mutex); 886 intel_wait_for_vblank(dev, intel_crtc->pipe);
855 intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); 887
856 mutex_lock(&dev->struct_mutex); 888 mutex_lock(&dev->struct_mutex);
857 }
858 intel_unpin_fb_obj(old_obj); 889 intel_unpin_fb_obj(old_obj);
890 mutex_unlock(&dev->struct_mutex);
859 } 891 }
860 892
861out_unlock: 893 return 0;
862 mutex_unlock(&dev->struct_mutex);
863 return ret;
864} 894}
865 895
866static int 896static int
@@ -868,7 +898,7 @@ intel_disable_plane(struct drm_plane *plane)
868{ 898{
869 struct drm_device *dev = plane->dev; 899 struct drm_device *dev = plane->dev;
870 struct intel_plane *intel_plane = to_intel_plane(plane); 900 struct intel_plane *intel_plane = to_intel_plane(plane);
871 int ret = 0; 901 struct intel_crtc *intel_crtc;
872 902
873 if (!plane->fb) 903 if (!plane->fb)
874 return 0; 904 return 0;
@@ -876,21 +906,25 @@ intel_disable_plane(struct drm_plane *plane)
876 if (WARN_ON(!plane->crtc)) 906 if (WARN_ON(!plane->crtc))
877 return -EINVAL; 907 return -EINVAL;
878 908
879 intel_enable_primary(plane->crtc); 909 intel_crtc = to_intel_crtc(plane->crtc);
880 intel_plane->disable_plane(plane, plane->crtc);
881 910
882 if (!intel_plane->obj) 911 if (intel_crtc->active) {
883 goto out; 912 intel_enable_primary(plane->crtc);
913 intel_plane->disable_plane(plane, plane->crtc);
914 }
884 915
885 intel_wait_for_vblank(dev, intel_plane->pipe); 916 if (intel_plane->obj) {
917 if (intel_crtc->active)
918 intel_wait_for_vblank(dev, intel_plane->pipe);
886 919
887 mutex_lock(&dev->struct_mutex); 920 mutex_lock(&dev->struct_mutex);
888 intel_unpin_fb_obj(intel_plane->obj); 921 intel_unpin_fb_obj(intel_plane->obj);
889 intel_plane->obj = NULL; 922 mutex_unlock(&dev->struct_mutex);
890 mutex_unlock(&dev->struct_mutex);
891out:
892 923
893 return ret; 924 intel_plane->obj = NULL;
925 }
926
927 return 0;
894} 928}
895 929
896static void intel_destroy_plane(struct drm_plane *plane) 930static void intel_destroy_plane(struct drm_plane *plane)
@@ -921,7 +955,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
921 955
922 obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); 956 obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
923 if (!obj) { 957 if (!obj) {
924 ret = -EINVAL; 958 ret = -ENOENT;
925 goto out_unlock; 959 goto out_unlock;
926 } 960 }
927 961
@@ -950,7 +984,7 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
950 984
951 obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); 985 obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
952 if (!obj) { 986 if (!obj) {
953 ret = -EINVAL; 987 ret = -ENOENT;
954 goto out_unlock; 988 goto out_unlock;
955 } 989 }
956 990
@@ -1034,7 +1068,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1034 if (INTEL_INFO(dev)->gen < 5) 1068 if (INTEL_INFO(dev)->gen < 5)
1035 return -ENODEV; 1069 return -ENODEV;
1036 1070
1037 intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); 1071 intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
1038 if (!intel_plane) 1072 if (!intel_plane)
1039 return -ENOMEM; 1073 return -ENOMEM;
1040 1074
@@ -1058,6 +1092,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1058 break; 1092 break;
1059 1093
1060 case 7: 1094 case 7:
1095 case 8:
1061 if (IS_IVYBRIDGE(dev)) { 1096 if (IS_IVYBRIDGE(dev)) {
1062 intel_plane->can_scale = true; 1097 intel_plane->can_scale = true;
1063 intel_plane->max_downscale = 2; 1098 intel_plane->max_downscale = 2;