Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Fix sprite_scaling_enabled for multiple sprites

We have more than one sprite, so a boolean simply won't cut it.
Turn sprite_scaling_enabled into a bitmask and track the state
of sprite scaler for each sprite independently.

Also don't re-enable LP watermarks until the sprite registers
have actually been written, and thus sprite scaling has really
been disabled.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

authored by

Ville Syrjälä and committed by
Daniel Vetter
2c6602df 26739f12

+17 -12
+1 -1
drivers/gpu/drm/i915/i915_drv.h
··· 925 925 926 926 /* overlay */ 927 927 struct intel_overlay *overlay; 928 - bool sprite_scaling_enabled; 928 + unsigned int sprite_scaling_enabled; 929 929 930 930 /* LVDS info */ 931 931 int backlight_level; /* restore backlight to this value */
+16 -11
drivers/gpu/drm/i915/intel_sprite.c
··· 50 50 u32 sprctl, sprscale = 0; 51 51 unsigned long sprsurf_offset, linear_offset; 52 52 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 53 + bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; 53 54 54 55 sprctl = I915_READ(SPRCTL(pipe)); 55 56 ··· 104 103 * when scaling is disabled. 105 104 */ 106 105 if (crtc_w != src_w || crtc_h != src_h) { 107 - if (!dev_priv->sprite_scaling_enabled) { 108 - dev_priv->sprite_scaling_enabled = true; 106 + dev_priv->sprite_scaling_enabled |= 1 << pipe; 107 + 108 + if (!scaling_was_enabled) { 109 109 intel_update_watermarks(dev); 110 110 intel_wait_for_vblank(dev, pipe); 111 111 } 112 112 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 113 - } else { 114 - if (dev_priv->sprite_scaling_enabled) { 115 - dev_priv->sprite_scaling_enabled = false; 116 - /* potentially re-enable LP watermarks */ 117 - intel_update_watermarks(dev); 118 - } 119 - } 113 + } else 114 + dev_priv->sprite_scaling_enabled &= ~(1 << pipe); 120 115 121 116 I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); 122 117 I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); ··· 138 141 I915_WRITE(SPRCTL(pipe), sprctl); 139 142 I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset); 140 143 POSTING_READ(SPRSURF(pipe)); 144 + 145 + /* potentially re-enable LP watermarks */ 146 + if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) 147 + intel_update_watermarks(dev); 141 148 } 142 149 143 150 static void ··· 151 150 struct drm_i915_private *dev_priv = dev->dev_private; 152 151 struct intel_plane *intel_plane = to_intel_plane(plane); 153 152 int pipe = intel_plane->pipe; 153 + bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; 154 154 155 155 I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); 156 156 /* Can't leave the scaler enabled... */ ··· 161 159 I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); 162 160 POSTING_READ(SPRSURF(pipe)); 163 161 164 - dev_priv->sprite_scaling_enabled = false; 165 - intel_update_watermarks(dev); 162 + dev_priv->sprite_scaling_enabled &= ~(1 << pipe); 163 + 164 + /* potentially re-enable LP watermarks */ 165 + if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) 166 + intel_update_watermarks(dev); 166 167 } 167 168 168 169 static int