diff options
| author | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
|---|---|---|
| committer | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
| commit | 79828b4fa835f73cdaf4bffa48696abdcbea9d02 (patch) | |
| tree | 5e0fa7156acb75ba603022bc807df8f2fedb97a8 /drivers/gpu/drm/i915/intel_sprite.c | |
| parent | 721b51fcf91898299d96f4b72cb9434cda29dce6 (diff) | |
| parent | 8c1a9d6323abf0fb1e5dad96cf3f1c783505ea5a (diff) | |
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-fix-rt5645
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sprite.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 205 | 
1 files changed, 77 insertions, 128 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 8193a35388d7..9d8af2f8a875 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -75,10 +75,8 @@ static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)   * until a subsequent call to intel_pipe_update_end(). That is done to   * avoid random delays. The value written to @start_vbl_count should be   * supplied to intel_pipe_update_end() for error checking. - * - * Return: true if the call was successful   */ -bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count) +void intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)  {  	struct drm_device *dev = crtc->base.dev;  	const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode; @@ -96,13 +94,14 @@ bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)  	min = vblank_start - usecs_to_scanlines(mode, 100);  	max = vblank_start - 1; +	local_irq_disable(); +	*start_vbl_count = 0; +  	if (min <= 0 || max <= 0) -		return false; +		return;  	if (WARN_ON(drm_crtc_vblank_get(&crtc->base))) -		return false; - -	local_irq_disable(); +		return;  	trace_i915_pipe_update_start(crtc, min, max); @@ -138,8 +137,6 @@ bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)  	*start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);  	trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count); - -	return true;  }  /** @@ -161,7 +158,7 @@ void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count)  	local_irq_enable(); -	if (start_vbl_count != end_vbl_count) +	if (start_vbl_count && start_vbl_count != end_vbl_count)  		DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",  			  pipe_name(pipe), start_vbl_count, end_vbl_count);  } @@ -182,7 +179,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,  	const int plane = intel_plane->plane + 1;  	u32 plane_ctl, stride_div, stride;  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); -	const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey; +	const struct drm_intel_sprite_colorkey *key = +		&to_intel_plane_state(drm_plane->state)->ckey;  	unsigned long surf_addr;  	u32 tile_height, plane_offset, plane_size;  	unsigned int rotation; @@ -272,7 +270,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,  }  static void -skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc, bool force) +skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)  {  	struct drm_device *dev = dplane->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; @@ -344,7 +342,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,  	u32 sprctl;  	unsigned long sprsurf_offset, linear_offset;  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); -	const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey; +	const struct drm_intel_sprite_colorkey *key = +		&to_intel_plane_state(dplane->state)->ckey;  	sprctl = SP_ENABLE; @@ -400,10 +399,6 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,  	if (obj->tiling_mode != I915_TILING_NONE)  		sprctl |= SP_TILED; -	intel_update_sprite_watermarks(dplane, crtc, src_w, src_h, -				       pixel_size, true, -				       src_w != crtc_w || src_h != crtc_h); -  	/* Sizes are 0 based */  	src_w--;  	src_h--; @@ -411,7 +406,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,  	crtc_h--;  	linear_offset = y * fb->pitches[0] + x * pixel_size; -	sprsurf_offset = intel_gen4_compute_page_offset(&x, &y, +	sprsurf_offset = intel_gen4_compute_page_offset(dev_priv, +							&x, &y,  							obj->tiling_mode,  							pixel_size,  							fb->pitches[0]); @@ -455,7 +451,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,  }  static void -vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc, bool force) +vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)  {  	struct drm_device *dev = dplane->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; @@ -467,8 +463,6 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc, bool force)  	I915_WRITE(SPSURF(pipe, plane), 0);  	POSTING_READ(SPSURF(pipe, plane)); - -	intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);  }  static void @@ -487,7 +481,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,  	u32 sprctl, sprscale = 0;  	unsigned long sprsurf_offset, linear_offset;  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); -	const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey; +	const struct drm_intel_sprite_colorkey *key = +		&to_intel_plane_state(plane->state)->ckey;  	sprctl = SPRITE_ENABLE; @@ -546,7 +541,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,  	linear_offset = y * fb->pitches[0] + x * pixel_size;  	sprsurf_offset = -		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, +		intel_gen4_compute_page_offset(dev_priv, +					       &x, &y, obj->tiling_mode,  					       pixel_size, fb->pitches[0]);  	linear_offset -= sprsurf_offset; @@ -595,7 +591,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,  }  static void -ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc, bool force) +ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)  {  	struct drm_device *dev = plane->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; @@ -627,7 +623,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,  	unsigned long dvssurf_offset, linear_offset;  	u32 dvscntr, dvsscale;  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); -	const struct drm_intel_sprite_colorkey *key = &intel_plane->ckey; +	const struct drm_intel_sprite_colorkey *key = +		&to_intel_plane_state(plane->state)->ckey;  	dvscntr = DVS_ENABLE; @@ -682,7 +679,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,  	linear_offset = y * fb->pitches[0] + x * pixel_size;  	dvssurf_offset = -		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, +		intel_gen4_compute_page_offset(dev_priv, +					       &x, &y, obj->tiling_mode,  					       pixel_size, fb->pitches[0]);  	linear_offset -= dvssurf_offset; @@ -722,7 +720,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,  }  static void -ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc, bool force) +ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)  {  	struct drm_device *dev = plane->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; @@ -739,11 +737,12 @@ ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc, bool force)  static int  intel_check_sprite_plane(struct drm_plane *plane, +			 struct intel_crtc_state *crtc_state,  			 struct intel_plane_state *state)  {  	struct drm_device *dev = plane->dev; -	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc); -	struct intel_crtc_state *crtc_state; +	struct drm_crtc *crtc = state->base.crtc; +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);  	struct intel_plane *intel_plane = to_intel_plane(plane);  	struct drm_framebuffer *fb = state->base.fb;  	int crtc_x, crtc_y; @@ -756,15 +755,10 @@ intel_check_sprite_plane(struct drm_plane *plane,  	int max_scale, min_scale;  	bool can_scale;  	int pixel_size; -	int ret; - -	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc); -	crtc_state = state->base.state ? -		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;  	if (!fb) {  		state->visible = false; -		goto finish; +		return 0;  	}  	/* Don't modify another pipe's plane */ @@ -782,7 +776,7 @@ intel_check_sprite_plane(struct drm_plane *plane,  	/* setup can_scale, min_scale, max_scale */  	if (INTEL_INFO(dev)->gen >= 9) {  		/* use scaler when colorkey is not required */ -		if (intel_plane->ckey.flags == I915_SET_COLORKEY_NONE) { +		if (state->ckey.flags == I915_SET_COLORKEY_NONE) {  			can_scale = 1;  			min_scale = 1;  			max_scale = skl_max_scale(intel_crtc, crtc_state); @@ -802,7 +796,6 @@ intel_check_sprite_plane(struct drm_plane *plane,  	 * coordinates and sizes. We probably need some way to decide whether  	 * more strict checking should be done instead.  	 */ -  	drm_rect_rotate(src, fb->width << 16, fb->height << 16,  			state->base.rotation); @@ -812,7 +805,7 @@ intel_check_sprite_plane(struct drm_plane *plane,  	vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);  	BUG_ON(vscale < 0); -	state->visible =  drm_rect_clip_scaled(src, dst, clip, hscale, vscale); +	state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);  	crtc_x = dst->x1;  	crtc_y = dst->y1; @@ -917,36 +910,6 @@ intel_check_sprite_plane(struct drm_plane *plane,  	dst->y1 = crtc_y;  	dst->y2 = crtc_y + crtc_h; -finish: -	/* -	 * If the sprite is completely covering the primary plane, -	 * we can disable the primary and save power. -	 */ -	if (intel_crtc->active) { -		intel_crtc->atomic.fb_bits |= -			INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe); - -		if (intel_wm_need_update(plane, &state->base)) -			intel_crtc->atomic.update_wm = true; - -		if (!state->visible) { -			/* -			 * Avoid underruns when disabling the sprite. -			 * FIXME remove once watermark updates are done properly. -			 */ -			intel_crtc->atomic.wait_vblank = true; -			intel_crtc->atomic.update_sprite_watermarks |= -				(1 << drm_plane_index(plane)); -		} -	} - -	if (INTEL_INFO(dev)->gen >= 9) { -		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane, -			state, 0); -		if (ret) -			return ret; -	} -  	return 0;  } @@ -955,34 +918,27 @@ intel_commit_sprite_plane(struct drm_plane *plane,  			  struct intel_plane_state *state)  {  	struct drm_crtc *crtc = state->base.crtc; -	struct intel_crtc *intel_crtc;  	struct intel_plane *intel_plane = to_intel_plane(plane);  	struct drm_framebuffer *fb = state->base.fb; -	int crtc_x, crtc_y; -	unsigned int crtc_w, crtc_h; -	uint32_t src_x, src_y, src_w, src_h;  	crtc = crtc ? crtc : plane->crtc; -	intel_crtc = to_intel_crtc(crtc);  	plane->fb = fb; -	if (intel_crtc->active) { -		if (state->visible) { -			crtc_x = state->dst.x1; -			crtc_y = state->dst.y1; -			crtc_w = drm_rect_width(&state->dst); -			crtc_h = drm_rect_height(&state->dst); -			src_x = state->src.x1 >> 16; -			src_y = state->src.y1 >> 16; -			src_w = drm_rect_width(&state->src) >> 16; -			src_h = drm_rect_height(&state->src) >> 16; -			intel_plane->update_plane(plane, crtc, fb, -						  crtc_x, crtc_y, crtc_w, crtc_h, -						  src_x, src_y, src_w, src_h); -		} else { -			intel_plane->disable_plane(plane, crtc, false); -		} +	if (!crtc->state->active) +		return; + +	if (state->visible) { +		intel_plane->update_plane(plane, crtc, fb, +					  state->dst.x1, state->dst.y1, +					  drm_rect_width(&state->dst), +					  drm_rect_height(&state->dst), +					  state->src.x1 >> 16, +					  state->src.y1 >> 16, +					  drm_rect_width(&state->src) >> 16, +					  drm_rect_height(&state->src) >> 16); +	} else { +		intel_plane->disable_plane(plane, crtc);  	}  } @@ -991,7 +947,9 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,  {  	struct drm_intel_sprite_colorkey *set = data;  	struct drm_plane *plane; -	struct intel_plane *intel_plane; +	struct drm_plane_state *plane_state; +	struct drm_atomic_state *state; +	struct drm_modeset_acquire_ctx ctx;  	int ret = 0;  	/* Make sure we don't try to enable both src & dest simultaneously */ @@ -1002,50 +960,41 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,  	    set->flags & I915_SET_COLORKEY_DESTINATION)  		return -EINVAL; -	drm_modeset_lock_all(dev); -  	plane = drm_plane_find(dev, set->plane_id); -	if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) { -		ret = -ENOENT; -		goto out_unlock; -	} +	if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) +		return -ENOENT; -	intel_plane = to_intel_plane(plane); +	drm_modeset_acquire_init(&ctx, 0); -	if (INTEL_INFO(dev)->gen >= 9) { -		/* plane scaling and colorkey are mutually exclusive */ -		if (to_intel_plane_state(plane->state)->scaler_id >= 0) { -			DRM_ERROR("colorkey not allowed with scaler\n"); -			ret = -EINVAL; -			goto out_unlock; -		} +	state = drm_atomic_state_alloc(plane->dev); +	if (!state) { +		ret = -ENOMEM; +		goto out;  	} +	state->acquire_ctx = &ctx; + +	while (1) { +		plane_state = drm_atomic_get_plane_state(state, plane); +		ret = PTR_ERR_OR_ZERO(plane_state); +		if (!ret) { +			to_intel_plane_state(plane_state)->ckey = *set; +			ret = drm_atomic_commit(state); +		} -	intel_plane->ckey = *set; - -	/* -	 * The only way this could fail would be due to -	 * the current plane state being unsupportable already, -	 * and we dont't consider that an error for the -	 * colorkey ioctl. So just ignore any error. -	 */ -	intel_plane_restore(plane); +		if (ret != -EDEADLK) +			break; -out_unlock: -	drm_modeset_unlock_all(dev); -	return ret; -} +		drm_atomic_state_clear(state); +		drm_modeset_backoff(&ctx); +	} -int intel_plane_restore(struct drm_plane *plane) -{ -	if (!plane->crtc || !plane->state->fb) -		return 0; +	if (ret) +		drm_atomic_state_free(state); -	return drm_plane_helper_update(plane, plane->crtc, plane->state->fb, -				       plane->state->crtc_x, plane->state->crtc_y, -				       plane->state->crtc_w, plane->state->crtc_h, -				       plane->state->src_x, plane->state->src_y, -				       plane->state->src_w, plane->state->src_h); +out: +	drm_modeset_drop_locks(&ctx); +	drm_modeset_acquire_fini(&ctx); +	return ret;  }  static const uint32_t ilk_plane_formats[] = { @@ -1172,9 +1121,9 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)  	intel_plane->pipe = pipe;  	intel_plane->plane = plane; +	intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe);  	intel_plane->check_plane = intel_check_sprite_plane;  	intel_plane->commit_plane = intel_commit_sprite_plane; -	intel_plane->ckey.flags = I915_SET_COLORKEY_NONE;  	possible_crtcs = (1 << pipe);  	ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,  				       &intel_plane_funcs, @@ -1189,6 +1138,6 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)  	drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); - out: +out:  	return ret;  }  |