Hi Kieran, Thank you for the patch. On Sunday 05 Mar 2017 16:00:03 Kieran Bingham wrote: > To be able to perform page flips in DRM without flicker we need to be > able to notify the rcar-du module when the VSP has completed its > processing. > > We must not have bidirectional dependencies on the two components to > maintain support for loadable modules, thus we extend the API to allow > a callback to be registered within the VSP DRM interface. > > Signed-off-by: Kieran Bingham <kieran.bingham+renesas@xxxxxxxxxxxxxxxx> > --- > drivers/media/platform/vsp1/vsp1_drm.c | 17 +++++++++++++++++ > drivers/media/platform/vsp1/vsp1_drm.h | 11 +++++++++++ > include/media/vsp1.h | 13 +++++++++++++ > 3 files changed, 41 insertions(+) > > diff --git a/drivers/media/platform/vsp1/vsp1_drm.c > b/drivers/media/platform/vsp1/vsp1_drm.c index 4ee437c7ff0c..d93bf7d3a39e > 100644 > --- a/drivers/media/platform/vsp1/vsp1_drm.c > +++ b/drivers/media/platform/vsp1/vsp1_drm.c > @@ -37,6 +37,14 @@ void vsp1_drm_display_start(struct vsp1_device *vsp1) > vsp1_dlm_irq_display_start(vsp1->drm->pipe.output->dlm); > } > > +static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe) > +{ > + struct vsp1_drm *drm = to_vsp1_drm(pipe); > + > + if (drm->du_complete) > + drm->du_complete(drm->du_private); > +} > + > /* ------------------------------------------------------------------------ > * DU Driver API > */ > @@ -96,6 +104,7 @@ int vsp1_du_setup_lif(struct device *dev, const struct > vsp1_du_lif_config *cfg) } > > pipe->num_inputs = 0; > + vsp1->drm->du_complete = NULL; > > vsp1_dlm_reset(pipe->output->dlm); > vsp1_device_put(vsp1); > @@ -200,6 +209,13 @@ int vsp1_du_setup_lif(struct device *dev, const struct > vsp1_du_lif_config *cfg) if (ret < 0) > return ret; > > + /* > + * Register a callback to allow us to notify the DRM framework of frame s/framework/driver/ > + * completion events. > + */ > + vsp1->drm->du_complete = cfg->callback; > + vsp1->drm->du_private = cfg->callback_data; > + > ret = media_pipeline_start(&pipe->output->entity.subdev.entity, > &pipe->pipe); > if (ret < 0) { > @@ -607,6 +623,7 @@ int vsp1_drm_init(struct vsp1_device *vsp1) > pipe->lif = &vsp1->lif->entity; > pipe->output = vsp1->wpf[0]; > pipe->output->pipe = pipe; > + pipe->frame_end = vsp1_du_pipeline_frame_end; > > return 0; > } > diff --git a/drivers/media/platform/vsp1/vsp1_drm.h > b/drivers/media/platform/vsp1/vsp1_drm.h index c8d2f88fc483..3de2095cb0ce > 100644 > --- a/drivers/media/platform/vsp1/vsp1_drm.h > +++ b/drivers/media/platform/vsp1/vsp1_drm.h > @@ -23,6 +23,8 @@ > * @num_inputs: number of active pipeline inputs at the beginning of an > update > * @inputs: source crop rectangle, destination compose rectangle and > z-order > * position for every input > + * @du_complete: frame completion callback for the DU driver (optional) > + * @du_private: data to be passed to the du_complete callback > */ > struct vsp1_drm { > struct vsp1_pipeline pipe; > @@ -33,8 +35,17 @@ struct vsp1_drm { > struct v4l2_rect compose; > unsigned int zpos; > } inputs[VSP1_MAX_RPF]; > + > + /* Frame syncronisation */ s/syncronisation/synchronisation/ > + void (*du_complete)(void *); > + void *du_private; > }; > > +static inline struct vsp1_drm *to_vsp1_drm(struct vsp1_pipeline *pipe) > +{ > + return container_of(pipe, struct vsp1_drm, pipe); > +} > + > int vsp1_drm_init(struct vsp1_device *vsp1); > void vsp1_drm_cleanup(struct vsp1_device *vsp1); > int vsp1_drm_create_links(struct vsp1_device *vsp1); > diff --git a/include/media/vsp1.h b/include/media/vsp1.h > index bfc701f04f3f..d59d0adf560d 100644 > --- a/include/media/vsp1.h > +++ b/include/media/vsp1.h > @@ -20,9 +20,22 @@ struct device; > > int vsp1_du_init(struct device *dev); > > +/** > + * struct vsp1_du_lif_config - VSP LIF configuration > + * @width: output frame width > + * @height: output frame height > + * @callback: frame completion callback function (optional) > + * @callback_data: data to be passed to the frame completion callback > + * > + * When the optional callback is provided to the VSP1, the VSP1 must > guarantee > + * that one completion callback is performed after every > vsp1_du_atomic_flush() This paragraph should be part of the @callback documentation. I would phrase it as * @callback: frame completion callback function (optional). When a callback * is provided, the VSP driver guarantees that it will be called * once and only once for each vsp1_du_atomic_flush() call. With this fixed, Reviewed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> If you're fine with the above changes there's no need to resubmit, I'll fix when applying the patch. > + */ > struct vsp1_du_lif_config { > unsigned int width; > unsigned int height; > + > + void (*callback)(void *); > + void *callback_data; > }; > > int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config > *cfg); -- Regards, Laurent Pinchart