[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