[PATCH 08/22] drm: rcar-du: Restart the DU group when a plane source changes
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Wed Dec 16 23:11:49 PST 2015
Hi Daniel,
On Monday 14 September 2015 09:22:13 Daniel Vetter wrote:
> On Mon, Sep 14, 2015 at 01:50:55AM +0300, Laurent Pinchart wrote:
> > Plane sources are configured by the VSPS bit in the PnDDCR4 register.
> > Although the datasheet states that the bit is updated during vertical
> > blanking, it seems that updates only occur when the DU group is held in
> > reset through the DSYSR.DRES bit. Restart the group if the source
> > changes.
> >
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas at ideasonboard.com>
> > ---
> >
> > drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 4 ++++
> > drivers/gpu/drm/rcar-du/rcar_du_group.c | 2 ++
> > drivers/gpu/drm/rcar-du/rcar_du_group.h | 2 ++
> > drivers/gpu/drm/rcar-du/rcar_du_plane.c | 22 ++++++++++++++++++++--
> > 4 files changed, 28 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 48cb19949ca3..7e2f5c26d589
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > @@ -272,6 +272,10 @@ static void rcar_du_crtc_update_planes(struct
> > rcar_du_crtc *rcrtc)
> > rcar_du_group_restart(rcrtc->group);
> > }
> >
> > + /* Restart the group if plane sources have changed. */
> > + if (rcrtc->group->need_restart)
> > + rcar_du_group_restart(rcrtc->group);
> > +
> > mutex_unlock(&rcrtc->group->lock);
> >
> > rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_group.c index
> > 4a44ddd51766..0e2b46dce563 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> > @@ -162,6 +162,8 @@ void rcar_du_group_start_stop(struct rcar_du_group
> > *rgrp, bool start)
> >
> > void rcar_du_group_restart(struct rcar_du_group *rgrp)
> > {
> > + rgrp->need_restart = false;
> > +
> > __rcar_du_group_start_stop(rgrp, false);
> > __rcar_du_group_start_stop(rgrp, true);
> > }
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h
> > b/drivers/gpu/drm/rcar-du/rcar_du_group.h index
> > 4b1952fd4e7d..5e3adc6b31b5 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_group.h
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.h
> > @@ -32,6 +32,7 @@ struct rcar_du_device;
> > * @dptsr_planes: bitmask of planes driven by dot-clock and timing
> > generator 1
> > * @num_planes: number of planes in the group
> > * @planes: planes handled by the group
> > + * @need_restart: the group needs to be restarted due to a configuration
> > change
> > */
> > struct rcar_du_group {
> > struct rcar_du_device *dev;
> > @@ -47,6 +48,7 @@ struct rcar_du_group {
> > unsigned int num_planes;
> > struct rcar_du_plane planes[RCAR_DU_NUM_KMS_PLANES];
> >
> > + bool need_restart;
>
> My recommendation is to keep any of these intermediate values in state
> objects too. The reason is that eventually we want to also support real
> queues of atomic commits,
I like the idea :-)
> and then anything stored globally (well, outside of the state objects) won't
> work. And yes it's ok to push that kind of stuff into helper, this isn't
> really any different than e.g. crtc_state->active_changed and similar
> booleans indicating that something special needs to be done when committing.
I agree with you. There's still a couple of state variables I need to remove
in the driver structures, and that's on my todo list (although not very high
I'm afraid).
The group state is a bit of an oddball. The DU groups CRTCs by two and shares
resources inside a group. Implementing that resource sharing requires storing
group state, which is very difficult without an atomic state object for the
group.
Am I missing an easy way to fix that ? And would it be fine to upstream this
patch as-is in the meantime ? I'd like to get it in v4.6, it's been out for
long enough and is blocking other people.
> > };
> >
> > u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg);
> >
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index
> > 78ca353bfcf0..c7e0535c0e77 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> > @@ -275,9 +275,27 @@ static void rcar_du_plane_atomic_update(struct
> > drm_plane *plane,
> > struct drm_plane_state *old_state)
> > {
> > struct rcar_du_plane *rplane = to_rcar_plane(plane);
> > + struct rcar_du_plane_state *old_rstate;
> > + struct rcar_du_plane_state *new_rstate;
> >
> > - if (plane->state->crtc)
> > - rcar_du_plane_setup(rplane);
> > + if (!plane->state->crtc)
> > + return;
> > +
> > + rcar_du_plane_setup(rplane);
> > +
> > + /* Check whether the source has changed from memory to live source or
> > + * from live source to memory. The source has been configured by the
> > + * VSPS bit in the PnDDCR4 register. Although the datasheet states
> > that
> > + * the bit is updated during vertical blanking, it seems that updates
> > + * only occur when the DU group is held in reset through the
> > DSYSR.DRES
> > + * bit. We thus need to restart the group if the source changes.
> > + */
> > + old_rstate = to_rcar_plane_state(old_state);
> > + new_rstate = to_rcar_plane_state(plane->state);
> > +
> > + if ((old_rstate->source == RCAR_DU_PLANE_MEMORY) !=
> > + (new_rstate->source == RCAR_DU_PLANE_MEMORY))
> > + rplane->group->need_restart = true;
> > }
> >
> > static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = {
--
Regards,
Laurent Pinchart
More information about the dri-devel
mailing list