Re: [PATCH 10/10] drm/i915: Make all plane disables use 'update_plane' (v5)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Reviewed-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@xxxxxxxxx>

On 12/04/2014 08:27 PM, Matt Roper wrote:
> If we extend the commit_plane handlers for each plane type to be able to
> handle fb=0, then we can easily implement plane disable via the
> update_plane handler.  The cursor plane already works this way, and this
> is the direction we need to go to integrate with the atomic plane
> handler.  We can now kill off the type-specific disable functions, as
> well as the redundant intel_plane_disable() (not to be confused with
> intel_disable_plane()).
> 
> Note that prepare_plane_fb() only gets called as part of update_plane
> when fb!=NULL (by design, to match the semantics of the atomic plane
> helpers); this means that our commit_plane handlers need to handle the
> frontbuffer tracking for the disable case, even though they don't handle
> it for normal updates.
> 
> v2:
>   - Change BUG_ON to WARN_ON (Ander/Daniel)
> 
> v3:
>   - Drop unnecessary plane->crtc check since a previous patch to plane
>     update ensures that plane->crtc will always be non-NULL, even for
>     disable calls that might pass NULL from userspace.  (Ander)
>   - Drop a s/crtc/plane->crtc/ hunk that was unnecessary.  (Ander)
> 
> v4:
>   - Fix missing whitespace (Ander)
> 
> v5:
>   - Use state's crtc rather than plane's crtc in
>     intel_check_primary_plane().  plane->crtc could be NULL, but we've
>     already fixed up state->crtc to ensure it's non-NULL (even if
>     userspace passed it as NULL during a disable call).  (Ander)
> 
> Signed-off-by: Matt Roper <matthew.d.roper@xxxxxxxxx>
> Reviewed-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@xxxxxxxxx>
> ---
>   drivers/gpu/drm/i915/intel_display.c | 89 ++++++++++++++----------------------
>   drivers/gpu/drm/i915/intel_drv.h     |  2 +-
>   drivers/gpu/drm/i915/intel_sprite.c  | 71 ++++++++--------------------
>   3 files changed, 54 insertions(+), 108 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index d13015c..7e53994 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4060,7 +4060,7 @@ static void intel_disable_planes(struct drm_crtc *crtc)
>   	drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
>   		intel_plane = to_intel_plane(plane);
>   		if (intel_plane->pipe == pipe)
> -			intel_plane_disable(&intel_plane->base);
> +			plane->funcs->disable_plane(plane);
>   	}
>   }
>   
> @@ -11605,43 +11605,6 @@ static void intel_shared_dpll_init(struct drm_device *dev)
>   	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
>   }
>   
> -static int
> -intel_primary_plane_disable(struct drm_plane *plane)
> -{
> -	struct drm_device *dev = plane->dev;
> -	struct intel_crtc *intel_crtc;
> -
> -	if (!plane->fb)
> -		return 0;
> -
> -	BUG_ON(!plane->crtc);
> -
> -	intel_crtc = to_intel_crtc(plane->crtc);
> -
> -	/*
> -	 * Even though we checked plane->fb above, it's still possible that
> -	 * the primary plane has been implicitly disabled because the crtc
> -	 * coordinates given weren't visible, or because we detected
> -	 * that it was 100% covered by a sprite plane.  Or, the CRTC may be
> -	 * off and we've set a fb, but haven't actually turned on the CRTC yet.
> -	 * In either case, we need to unpin the FB and let the fb pointer get
> -	 * updated, but otherwise we don't need to touch the hardware.
> -	 */
> -	if (intel_crtc->primary_enabled) {
> -		intel_crtc_wait_for_pending_flips(plane->crtc);
> -		intel_disable_primary_hw_plane(plane, plane->crtc);
> -	}
> -
> -	mutex_lock(&dev->struct_mutex);
> -	i915_gem_track_fb(intel_fb_obj(plane->fb), NULL,
> -			  INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe));
> -	intel_unpin_fb_obj(intel_fb_obj(plane->fb));
> -	mutex_unlock(&dev->struct_mutex);
> -	plane->fb = NULL;
> -
> -	return 0;
> -}
> -
>   /**
>    * intel_prepare_plane_fb - Prepare fb for usage on plane
>    * @plane: drm plane to prepare for
> @@ -11763,12 +11726,23 @@ intel_commit_primary_plane(struct drm_plane *plane,
>   	struct drm_device *dev = plane->dev;
>   	struct drm_i915_private *dev_priv = dev->dev_private;
>   	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	enum pipe pipe = intel_crtc->pipe;
>   	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
>   	struct intel_plane *intel_plane = to_intel_plane(plane);
>   	struct drm_rect *src = &state->src;
> +	enum pipe pipe = intel_plane->pipe;
>   
> -	crtc->primary->fb = fb;
> +	if (!fb) {
> +		/*
> +		 * 'prepare' is never called when plane is being disabled, so
> +		 * we need to handle frontbuffer tracking here
> +		 */
> +		mutex_lock(&dev->struct_mutex);
> +		i915_gem_track_fb(intel_fb_obj(plane->fb), NULL,
> +				  INTEL_FRONTBUFFER_PRIMARY(pipe));
> +		mutex_unlock(&dev->struct_mutex);
> +	}
> +
> +	plane->fb = fb;
>   	crtc->x = src->x1 >> 16;
>   	crtc->y = src->y1 >> 16;
>   
> @@ -11897,6 +11871,25 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>   	return 0;
>   }
>   
> +/**
> + * intel_disable_plane - disable a plane
> + * @plane: plane to disable
> + *
> + * General disable handler for all plane types.
> + */
> +int
> +intel_disable_plane(struct drm_plane *plane)
> +{
> +	if (!plane->fb)
> +		return 0;
> +
> +	if (WARN_ON(!plane->crtc))
> +		return -EINVAL;
> +
> +	return plane->funcs->update_plane(plane, plane->crtc, NULL,
> +					  0, 0, 0, 0, 0, 0, 0, 0);
> +}
> +
>   /* Common destruction function for both primary and cursor planes */
>   static void intel_plane_destroy(struct drm_plane *plane)
>   {
> @@ -11907,7 +11900,7 @@ static void intel_plane_destroy(struct drm_plane *plane)
>   
>   static const struct drm_plane_funcs intel_primary_plane_funcs = {
>   	.update_plane = intel_update_plane,
> -	.disable_plane = intel_primary_plane_disable,
> +	.disable_plane = intel_disable_plane,
>   	.destroy = intel_plane_destroy,
>   	.set_property = intel_plane_set_property
>   };
> @@ -11962,18 +11955,6 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>   }
>   
>   static int
> -intel_cursor_plane_disable(struct drm_plane *plane)
> -{
> -	if (!plane->fb)
> -		return 0;
> -
> -	BUG_ON(!plane->crtc);
> -
> -	return plane->funcs->update_plane(plane, plane->crtc, NULL,
> -					  0, 0, 0, 0, 0, 0, 0, 0);
> -}
> -
> -static int
>   intel_check_cursor_plane(struct drm_plane *plane,
>   			 struct intel_plane_state *state)
>   {
> @@ -12097,7 +12078,7 @@ update:
>   
>   static const struct drm_plane_funcs intel_cursor_plane_funcs = {
>   	.update_plane = intel_update_plane,
> -	.disable_plane = intel_cursor_plane_disable,
> +	.disable_plane = intel_disable_plane,
>   	.destroy = intel_plane_destroy,
>   	.set_property = intel_plane_set_property,
>   };
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index f7b6619..53b696e 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1020,6 +1020,7 @@ int intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>   		       unsigned int crtc_w, unsigned int crtc_h,
>   		       uint32_t src_x, uint32_t src_y,
>   		       uint32_t src_w, uint32_t src_h);
> +int intel_disable_plane(struct drm_plane *plane);
>   
>   /* intel_dp_mst.c */
>   int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
> @@ -1201,7 +1202,6 @@ int intel_plane_set_property(struct drm_plane *plane,
>   			     struct drm_property *prop,
>   			     uint64_t val);
>   int intel_plane_restore(struct drm_plane *plane);
> -void intel_plane_disable(struct drm_plane *plane);
>   int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>   			      struct drm_file *file_priv);
>   int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index bfd5270..bc5834b 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1109,7 +1109,12 @@ intel_check_sprite_plane(struct drm_plane *plane,
>   	const struct drm_rect *clip = &state->clip;
>   	int hscale, vscale;
>   	int max_scale, min_scale;
> -	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> +	int pixel_size;
> +
> +	if (!fb) {
> +		state->visible = false;
> +		return 0;
> +	}
>   
>   	/* Don't modify another pipe's plane */
>   	if (intel_plane->pipe != intel_crtc->pipe) {
> @@ -1232,6 +1237,7 @@ intel_check_sprite_plane(struct drm_plane *plane,
>   		if (src_w < 3 || src_h < 3)
>   			state->visible = false;
>   
> +		pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>   		width_bytes = ((src_x * pixel_size) & 63) +
>   					src_w * pixel_size;
>   
> @@ -1276,6 +1282,17 @@ intel_commit_sprite_plane(struct drm_plane *plane,
>   	bool primary_enabled;
>   
>   	/*
> +	 * 'prepare' is never called when plane is being disabled, so we need
> +	 * to handle frontbuffer tracking here
> +	 */
> +	if (!fb) {
> +		mutex_lock(&dev->struct_mutex);
> +		i915_gem_track_fb(intel_fb_obj(plane->fb), NULL,
> +				  INTEL_FRONTBUFFER_SPRITE(pipe));
> +		mutex_unlock(&dev->struct_mutex);
> +	}
> +
> +	/*
>   	 * If the sprite is completely covering the primary plane,
>   	 * we can disable the primary and save power.
>   	 */
> @@ -1327,50 +1344,6 @@ intel_commit_sprite_plane(struct drm_plane *plane,
>   	}
>   }
>   
> -static int
> -intel_disable_plane(struct drm_plane *plane)
> -{
> -	struct drm_device *dev = plane->dev;
> -	struct intel_plane *intel_plane = to_intel_plane(plane);
> -	struct intel_crtc *intel_crtc;
> -	enum pipe pipe;
> -
> -	if (!plane->fb)
> -		return 0;
> -
> -	if (WARN_ON(!plane->crtc))
> -		return -EINVAL;
> -
> -	intel_crtc = to_intel_crtc(plane->crtc);
> -	pipe = intel_crtc->pipe;
> -
> -	if (intel_crtc->active) {
> -		bool primary_was_enabled = intel_crtc->primary_enabled;
> -
> -		intel_crtc->primary_enabled = true;
> -
> -		intel_plane->disable_plane(plane, plane->crtc);
> -
> -		if (!primary_was_enabled && intel_crtc->primary_enabled)
> -			intel_post_enable_primary(plane->crtc);
> -	}
> -
> -	if (intel_plane->obj) {
> -		if (intel_crtc->active)
> -			intel_wait_for_vblank(dev, intel_plane->pipe);
> -
> -		mutex_lock(&dev->struct_mutex);
> -		intel_unpin_fb_obj(intel_plane->obj);
> -		i915_gem_track_fb(intel_plane->obj, NULL,
> -				  INTEL_FRONTBUFFER_SPRITE(pipe));
> -		mutex_unlock(&dev->struct_mutex);
> -
> -		intel_plane->obj = NULL;
> -	}
> -
> -	return 0;
> -}
> -
>   static void intel_destroy_plane(struct drm_plane *plane)
>   {
>   	struct intel_plane *intel_plane = to_intel_plane(plane);
> @@ -1478,14 +1451,6 @@ int intel_plane_restore(struct drm_plane *plane)
>   				  intel_plane->src_w, intel_plane->src_h);
>   }
>   
> -void intel_plane_disable(struct drm_plane *plane)
> -{
> -	if (!plane->crtc || !plane->fb)
> -		return;
> -
> -	intel_disable_plane(plane);
> -}
> -
>   static const struct drm_plane_funcs intel_plane_funcs = {
>   	.update_plane = intel_update_plane,
>   	.disable_plane = intel_disable_plane,
> 

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux