diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sprite.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 52 | 
1 files changed, 29 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 827dcd4edf1c..1b6eb76beb7c 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -50,6 +50,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,  	u32 sprctl, sprscale = 0;  	unsigned long sprsurf_offset, linear_offset;  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); +	bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;  	sprctl = I915_READ(SPRCTL(pipe)); @@ -89,6 +90,9 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,  	sprctl |= SPRITE_TRICKLE_FEED_DISABLE;  	sprctl |= SPRITE_ENABLE; +	if (IS_HASWELL(dev)) +		sprctl |= SPRITE_PIPE_CSC_ENABLE; +  	/* Sizes are 0 based */  	src_w--;  	src_h--; @@ -103,28 +107,23 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,  	 * when scaling is disabled.  	 */  	if (crtc_w != src_w || crtc_h != src_h) { -		if (!dev_priv->sprite_scaling_enabled) { -			dev_priv->sprite_scaling_enabled = true; +		dev_priv->sprite_scaling_enabled |= 1 << pipe; + +		if (!scaling_was_enabled) {  			intel_update_watermarks(dev);  			intel_wait_for_vblank(dev, pipe);  		}  		sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; -	} else { -		if (dev_priv->sprite_scaling_enabled) { -			dev_priv->sprite_scaling_enabled = false; -			/* potentially re-enable LP watermarks */ -			intel_update_watermarks(dev); -		} -	} +	} else +		dev_priv->sprite_scaling_enabled &= ~(1 << pipe);  	I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);  	I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); -	linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); +	linear_offset = y * fb->pitches[0] + x * pixel_size;  	sprsurf_offset = -		intel_gen4_compute_offset_xtiled(&x, &y, -						 fb->bits_per_pixel / 8, -						 fb->pitches[0]); +		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, +					       pixel_size, fb->pitches[0]);  	linear_offset -= sprsurf_offset;  	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET @@ -142,6 +141,10 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,  	I915_WRITE(SPRCTL(pipe), sprctl);  	I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset);  	POSTING_READ(SPRSURF(pipe)); + +	/* potentially re-enable LP watermarks */ +	if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) +		intel_update_watermarks(dev);  }  static void @@ -151,6 +154,7 @@ ivb_disable_plane(struct drm_plane *plane)  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct intel_plane *intel_plane = to_intel_plane(plane);  	int pipe = intel_plane->pipe; +	bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;  	I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);  	/* Can't leave the scaler enabled... */ @@ -160,8 +164,11 @@ ivb_disable_plane(struct drm_plane *plane)  	I915_MODIFY_DISPBASE(SPRSURF(pipe), 0);  	POSTING_READ(SPRSURF(pipe)); -	dev_priv->sprite_scaling_enabled = false; -	intel_update_watermarks(dev); +	dev_priv->sprite_scaling_enabled &= ~(1 << pipe); + +	/* potentially re-enable LP watermarks */ +	if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) +		intel_update_watermarks(dev);  }  static int @@ -286,11 +293,10 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,  	I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);  	I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); -	linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); +	linear_offset = y * fb->pitches[0] + x * pixel_size;  	dvssurf_offset = -		intel_gen4_compute_offset_xtiled(&x, &y, -						 fb->bits_per_pixel / 8, -						 fb->pitches[0]); +		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, +					       pixel_size, fb->pitches[0]);  	linear_offset -= dvssurf_offset;  	if (obj->tiling_mode != I915_TILING_NONE) @@ -595,7 +601,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,  	if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))  		return -EINVAL; -	mutex_lock(&dev->mode_config.mutex); +	drm_modeset_lock_all(dev);  	obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);  	if (!obj) { @@ -608,7 +614,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,  	ret = intel_plane->update_colorkey(plane, set);  out_unlock: -	mutex_unlock(&dev->mode_config.mutex); +	drm_modeset_unlock_all(dev);  	return ret;  } @@ -624,7 +630,7 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,  	if (!drm_core_check_feature(dev, DRIVER_MODESET))  		return -ENODEV; -	mutex_lock(&dev->mode_config.mutex); +	drm_modeset_lock_all(dev);  	obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);  	if (!obj) { @@ -637,7 +643,7 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,  	intel_plane->get_colorkey(plane, get);  out_unlock: -	mutex_unlock(&dev->mode_config.mutex); +	drm_modeset_unlock_all(dev);  	return ret;  }  |