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@xxxxxx> > --- > 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 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html