[PATCH 08/22] drm: rcar-du: Restart the DU group when a plane source changes

Laurent Pinchart laurent.pinchart at ideasonboard.com
Sun Dec 27 01:00:07 PST 2015


Hi Daniel,

On Thursday 17 December 2015 10:41:51 Daniel Vetter wrote:
> On Thu, Dec 17, 2015 at 09:11:49AM +0200, Laurent Pinchart wrote:
> > 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.
> 
> Involves a bit of typing, but we allow drivers to subclass
> drm_atomic_state and add whatever they want.

I hadn't noticed it had been introduced, that's very nice.

> The important part is to make sure you get the locking right, i.e. only ever
> duplicate anything when you hold the right locks. For that you have about 3
> options:
> - protect all group state with mode_config->connection_lock. Might
>   unecessarily serialize updates.
> - create a per-group ww_mutex (atomic allows you to throw as many
>   additional ww_mutex locks encapsulated within a drm_modeset_lock as you
>   want).
> - just grab the crtc states (plus locks) for all the crtcs in a group when
>   duplicating a group state
> 
> I highly recommend you follow the patterns laid out in drm_atomic.c and
> only allow your driver to get at the group state through a get_group_state
> helper, like we have for plane/crtc/connector states. That can then take
> care of the locking and everything.

Thanks for the tip, I'll give it a try.

> i915 uses this to keep track of shared resources like dpll and display
> core clock.
> 
> There should be kerneldoc for the individual functions, but I think we
> lack an overview/example section ... hint, hint ;-)

I'll first try to understand it by using it :-)

-- 
Regards,

Laurent Pinchart



More information about the dri-devel mailing list