> > From: Benoit Parrot <bparrot@xxxxxx> > > If the drm_plane has a source width that's greater than the max width > supported by a single hw overlay, then we assign a 'r_overlay' to it in > omap_plane_atomic_check(). > > Both overlays should have the capabilities required to handle the source > framebuffer. The only parameters that vary between the left and right > hwoverlays are the src_w, crtc_w, src_x and crtc_x as we just even chop > the fb into left and right halves. > > We also take care of not creating odd width size when dealing with YUV > formats. > > Since both halves need to be 'appear' side by side the zpos is > recalculated when dealing with dual overlay cases so that the other > planes zpos is consistent. > > Depending on user space usage it is possible that on occasion the number > of requested planes exceeds the numbers of overlays required to display > them. In that case a failure would be returned for the plane that cannot > be handled at that time. It is up to user space to make sure the H/W > resource are not over-subscribed. > > Signed-off-by: Benoit Parrot <bparrot@xxxxxx> > Signed-off-by: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > --- > drivers/gpu/drm/omapdrm/omap_drv.c | 98 ++++++++++++++++++++- > drivers/gpu/drm/omapdrm/omap_fb.c | 33 ++++++- > drivers/gpu/drm/omapdrm/omap_fb.h | 4 +- > drivers/gpu/drm/omapdrm/omap_overlay.c | 23 ++++- > drivers/gpu/drm/omapdrm/omap_overlay.h | 3 +- > drivers/gpu/drm/omapdrm/omap_plane.c | 117 +++++++++++++++++++++++-- > drivers/gpu/drm/omapdrm/omap_plane.h | 1 + > 7 files changed, 267 insertions(+), 12 deletions(-) > > ... > > diff --git a/drivers/gpu/drm/omapdrm/omap_overlay.c b/drivers/gpu/drm/omapdrm/omap_overlay.c > index afb2b44fdf86..10730c9b2752 100644 > --- a/drivers/gpu/drm/omapdrm/omap_overlay.c > +++ b/drivers/gpu/drm/omapdrm/omap_overlay.c > @@ -67,12 +67,13 @@ omap_plane_find_free_overlay(struct drm_device *dev, struct drm_plane *hwoverlay > * next global overlay_map to be enabled when atomic transaction is valid. > */ > int omap_overlay_assign(struct drm_atomic_state *s, struct drm_plane *plane, > - u32 caps, u32 fourcc, struct omap_hw_overlay **overlay) > + u32 caps, u32 fourcc, struct omap_hw_overlay **overlay, > + struct omap_hw_overlay **r_overlay) > { > /* Get the global state of the current atomic transaction */ > struct omap_global_state *state = omap_get_global_state(s); > struct drm_plane **overlay_map = state->hwoverlay_to_plane; > - struct omap_hw_overlay *ovl; > + struct omap_hw_overlay *ovl, *r_ovl; > > ovl = omap_plane_find_free_overlay(s->dev, overlay_map, caps, fourcc); > if (!ovl) > @@ -81,8 +82,26 @@ int omap_overlay_assign(struct drm_atomic_state *s, struct drm_plane *plane, > overlay_map[ovl->idx] = plane; > *overlay = ovl; > > + if (r_overlay) { > + r_ovl = omap_plane_find_free_overlay(s->dev, overlay_map, > + caps, fourcc); > + if (!r_ovl) { > + overlay_map[r_ovl->idx] = NULL; Hi, a null derefrence "r_ovl->idx" when "r_ovl" is null, in inner if clause.