[Patch 4/4] drm/omap: Add virtual plane support to omap_plane

Tomi Valkeinen tomi.valkeinen at ti.com
Wed Mar 14 11:56:17 UTC 2018


Hi Benoit,

On 02/03/18 15:48, Benoit Parrot wrote:
> Add virtual plane support by adding an array to contain
> all of the actual plane_id a "omap_plane" correspond to.

"plane_ids", "an", "corresponds"

> When at least one 'plane' child node is present in DT then
> omap_plane_init will only used the plane described in DT.

"use"

> Some of these nodes may be a virtual plane if they are defined
> as two physical planes.
> Planes can also be associated with various crtcs independently.
> Therefore we can restrict the use of virtual plane to specific
> CRTC/video port if need be, if crtc_mask is not specified then
> the plane will be available to all available crtcs.
> Physical plane which are not described will essentially be hidden

"planes"

> from the driver.
> 
> If no 'plane' child node exist then the existing plane

"nodes"

> allocation will take place.

Maybe "normal plane allocation"?

> 
> Signed-off-by: Benoit Parrot <bparrot at ti.com>
> ---
>  drivers/gpu/drm/omapdrm/omap_drv.c   |  18 +++--
>  drivers/gpu/drm/omapdrm/omap_fb.c    |  66 +++++++++++------
>  drivers/gpu/drm/omapdrm/omap_fb.h    |   4 +-
>  drivers/gpu/drm/omapdrm/omap_plane.c | 139 +++++++++++++++++++++++++----------
>  drivers/gpu/drm/omapdrm/omap_plane.h |   3 +-
>  5 files changed, 162 insertions(+), 68 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> index dd68b2556f5b..73796364a592 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -188,10 +188,9 @@ static int omap_connect_dssdevs(void)
>  	return r;
>  }
>  
> -static int omap_modeset_init_properties(struct drm_device *dev)
> +static int omap_modeset_init_properties(struct drm_device *dev, u32 num_planes)
>  {
>  	struct omap_drm_private *priv = dev->dev_private;
> -	unsigned int num_planes = priv->dispc_ops->get_num_ovls();
>  
>  	priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0,
>  						      num_planes - 1);
> @@ -210,10 +209,19 @@ static int omap_modeset_init(struct drm_device *dev)
>  	int num_crtcs, crtc_idx, plane_idx;
>  	int ret;
>  	u32 plane_crtc_mask;
> +	struct dispc_plane_mappings plane_mappings = {0};
>  
>  	drm_mode_config_init(dev);
>  
> -	ret = omap_modeset_init_properties(dev);
> +	ret = priv->dispc_ops->get_plane_mapping(&plane_mappings);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* use plane mappings info */
> +	if (plane_mappings.num_planes)
> +		num_ovls = plane_mappings.num_planes;
> +
> +	ret = omap_modeset_init_properties(dev, num_ovls);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -266,7 +274,7 @@ static int omap_modeset_init(struct drm_device *dev)
>  			return -ENOMEM;
>  
>  		plane = omap_plane_init(dev, plane_idx, DRM_PLANE_TYPE_PRIMARY,
> -					plane_crtc_mask);
> +					plane_crtc_mask, &plane_mappings);
>  		if (IS_ERR(plane))
>  			return PTR_ERR(plane);
>  
> @@ -296,7 +304,7 @@ static int omap_modeset_init(struct drm_device *dev)
>  			return -EINVAL;
>  
>  		plane = omap_plane_init(dev, plane_idx, DRM_PLANE_TYPE_OVERLAY,
> -			plane_crtc_mask);
> +					plane_crtc_mask, &plane_mappings);
>  		if (IS_ERR(plane))
>  			return PTR_ERR(plane);
>  
> diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
> index b2539a90e1a4..80b29b7f5696 100644
> --- a/drivers/gpu/drm/omapdrm/omap_fb.c
> +++ b/drivers/gpu/drm/omapdrm/omap_fb.c
> @@ -153,25 +153,27 @@ static uint32_t drm_rotation_to_tiler(unsigned int drm_rot)
>  /* update ovl info for scanout, handles cases of multi-planar fb's, etc.
>   */
>  void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
> -		struct drm_plane_state *state, struct omap_overlay_info *info)
> +		struct drm_plane_state *state,
> +		struct omap_overlay_info *main_info,
> +		struct omap_overlay_info *aux_info)
>  {
>  	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
>  	const struct drm_format_info *format = omap_fb->format;
>  	struct plane *plane = &omap_fb->planes[0];
>  	uint32_t x, y, orient = 0;
>  
> -	info->fourcc = fb->format->format;
> +	main_info->fourcc = fb->format->format;
>  
> -	info->pos_x      = state->crtc_x;
> -	info->pos_y      = state->crtc_y;
> -	info->out_width  = state->crtc_w;
> -	info->out_height = state->crtc_h;
> -	info->width      = state->src_w >> 16;
> -	info->height     = state->src_h >> 16;
> +	main_info->pos_x      = state->crtc_x;
> +	main_info->pos_y      = state->crtc_y;
> +	main_info->out_width  = state->crtc_w;
> +	main_info->out_height = state->crtc_h;
> +	main_info->width      = state->src_w >> 16;
> +	main_info->height     = state->src_h >> 16;
>  
>  	/* DSS driver wants the w & h in rotated orientation */
>  	if (drm_rotation_90_or_270(state->rotation))
> -		swap(info->width, info->height);
> +		swap(main_info->width, main_info->height);
>  
>  	x = state->src_x >> 16;
>  	y = state->src_y >> 16;
> @@ -202,11 +204,12 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
>  
>  		/* Note: x and y are in TILER units, not pixels */
>  		omap_gem_rotated_dma_addr(plane->bo, orient, x, y,
> -					  &info->paddr);
> -		info->rotation_type = OMAP_DSS_ROT_TILER;
> -		info->rotation = state->rotation ?: DRM_MODE_ROTATE_0;
> +					  &main_info->paddr);
> +		main_info->rotation_type = OMAP_DSS_ROT_TILER;
> +		main_info->rotation = state->rotation ?: DRM_MODE_ROTATE_0;
>  		/* Note: stride in TILER units, not pixels */
> -		info->screen_width  = omap_gem_tiled_stride(plane->bo, orient);
> +		main_info->screen_width  =
> +				omap_gem_tiled_stride(plane->bo, orient);
>  	} else {
>  		switch (state->rotation & DRM_MODE_ROTATE_MASK) {
>  		case 0:
> @@ -221,27 +224,46 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
>  			break;
>  		}
>  
> -		info->paddr         = get_linear_addr(plane, format, 0, x, y);
> -		info->rotation_type = OMAP_DSS_ROT_NONE;
> -		info->rotation      = DRM_MODE_ROTATE_0;
> -		info->screen_width  = plane->pitch;
> +		main_info->paddr = get_linear_addr(plane, format, 0, x, y);
> +		main_info->rotation_type = OMAP_DSS_ROT_NONE;
> +		main_info->rotation = DRM_MODE_ROTATE_0;
> +		main_info->screen_width = plane->pitch;
>  	}
>  
>  	/* convert to pixels: */
> -	info->screen_width /= format->cpp[0];
> +	main_info->screen_width /= format->cpp[0];
>  
>  	if (fb->format->format == DRM_FORMAT_NV12) {
>  		plane = &omap_fb->planes[1];
>  
> -		if (info->rotation_type == OMAP_DSS_ROT_TILER) {
> +		if (main_info->rotation_type == OMAP_DSS_ROT_TILER) {
>  			WARN_ON(!(omap_gem_flags(plane->bo) & OMAP_BO_TILED));
>  			omap_gem_rotated_dma_addr(plane->bo, orient, x/2, y/2,
> -						  &info->p_uv_addr);
> +						  &main_info->p_uv_addr);
>  		} else {
> -			info->p_uv_addr = get_linear_addr(plane, format, 1, x, y);
> +			main_info->p_uv_addr =
> +				get_linear_addr(plane, format, 1, x, y);
>  		}
>  	} else {
> -		info->p_uv_addr = 0;
> +		main_info->p_uv_addr = 0;
> +	}
> +
> +	if (aux_info) {
> +		main_info->width /= 2;
> +		main_info->out_width /= 2;
> +
> +		*aux_info = *main_info;
> +
> +		aux_info->pos_x = main_info->pos_x + main_info->out_width;
> +
> +		aux_info->paddr =
> +				get_linear_addr(&omap_fb->planes[0], format, 0,
> +						x + main_info->width, y);
> +		if (fb->format->format == DRM_FORMAT_NV12) {
> +			aux_info->p_uv_addr =
> +				get_linear_addr(&omap_fb->planes[1], format, 1,
> +						x + main_info->width, y);
> +		}
>  	}
>  }
>  
> diff --git a/drivers/gpu/drm/omapdrm/omap_fb.h b/drivers/gpu/drm/omapdrm/omap_fb.h
> index 94ad5f9e4404..f68e81353288 100644
> --- a/drivers/gpu/drm/omapdrm/omap_fb.h
> +++ b/drivers/gpu/drm/omapdrm/omap_fb.h
> @@ -37,7 +37,9 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
>  int omap_framebuffer_pin(struct drm_framebuffer *fb);
>  void omap_framebuffer_unpin(struct drm_framebuffer *fb);
>  void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
> -		struct drm_plane_state *state, struct omap_overlay_info *info);
> +		struct drm_plane_state *state,
> +		struct omap_overlay_info *main_info,
> +		struct omap_overlay_info *aux_info);
>  struct drm_connector *omap_framebuffer_get_next_connector(
>  		struct drm_framebuffer *fb, struct drm_connector *from);
>  bool omap_framebuffer_supports_rotation(struct drm_framebuffer *fb);
> diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
> index 7d789d1551a1..e3e6623c405d 100644
> --- a/drivers/gpu/drm/omapdrm/omap_plane.c
> +++ b/drivers/gpu/drm/omapdrm/omap_plane.c
> @@ -30,10 +30,14 @@
>  
>  struct omap_plane {
>  	struct drm_plane base;
> -	enum omap_plane_id id;
> +	enum omap_plane_id main_id;
> +	enum omap_plane_id aux_id;
>  	const char *name;
> +	bool virtual_plane;
>  };
>  
> +static const char *plane_id_to_name[];
> +
>  static int omap_plane_prepare_fb(struct drm_plane *plane,
>  				 struct drm_plane_state *new_state)
>  {
> @@ -56,38 +60,70 @@ static void omap_plane_atomic_update(struct drm_plane *plane,
>  	struct omap_drm_private *priv = plane->dev->dev_private;
>  	struct omap_plane *omap_plane = to_omap_plane(plane);
>  	struct drm_plane_state *state = plane->state;
> -	struct omap_overlay_info info;
> +	struct omap_overlay_info main_info, aux_info;
>  	int ret;
> +	bool dual_plane = omap_plane->virtual_plane;
>  
>  	DBG("%s, crtc=%p fb=%p", omap_plane->name, state->crtc, state->fb);
>  
> -	memset(&info, 0, sizeof(info));
> -	info.rotation_type = OMAP_DSS_ROT_NONE;
> -	info.rotation = DRM_MODE_ROTATE_0;
> -	info.global_alpha = 0xff;
> -	info.zorder = state->zpos;
> +	memset(&main_info, 0, sizeof(main_info));
> +	main_info.rotation_type = OMAP_DSS_ROT_NONE;
> +	main_info.rotation = DRM_MODE_ROTATE_0;
> +	main_info.global_alpha = 0xff;
> +	main_info.zorder = state->zpos;
>  
> -	/* update scanout: */
> -	omap_framebuffer_update_scanout(state->fb, state, &info);
> +	aux_info = main_info;
>  
> -	DBG("%dx%d -> %dx%d (%d)", info.width, info.height,
> -			info.out_width, info.out_height,
> -			info.screen_width);
> -	DBG("%d,%d %pad %pad", info.pos_x, info.pos_y,
> -			&info.paddr, &info.p_uv_addr);
> +	/* update scanout: */
> +	omap_framebuffer_update_scanout(state->fb, state, &main_info,
> +					dual_plane ? &aux_info : NULL);
> +
> +	DBG("%s: %dx%d -> %dx%d (%d)",
> +	    plane_id_to_name[omap_plane->main_id],
> +	    main_info.width, main_info.height,
> +	    main_info.out_width, main_info.out_height,
> +	    main_info.screen_width);
> +	DBG("%d,%d %pad %pad", main_info.pos_x, main_info.pos_y,
> +	    &main_info.paddr, &main_info.p_uv_addr);
> +
> +	if (dual_plane) {
> +		aux_info.zorder = main_info.zorder + 1; // XXX

This is broken, and it's even marked as such with the XXX. For example,
this fails:

kmstest -c 0 -p 400x400 -Pzpos=0 -p 300x300 -Pzpos=1 -p 200x200 -Pzpos=2

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


More information about the dri-devel mailing list