From 09e513e390eab1f2db4d4242ef209cbe0c39c444 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 21 Feb 2019 03:38:06 +0200 Subject: media: vsp1: drm: Extend frame completion API to the DU driver The VSP1 driver will need to pass extra flags to the DU through the frame completion API. Replace the completed bool flag by a bitmask to support this. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Mauro Carvalho Chehab --- include/media/vsp1.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/media') diff --git a/include/media/vsp1.h b/include/media/vsp1.h index 1cf868360701..877496936487 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -17,6 +17,8 @@ struct device; int vsp1_du_init(struct device *dev); +#define VSP1_DU_STATUS_COMPLETE BIT(0) + /** * struct vsp1_du_lif_config - VSP LIF configuration * @width: output frame width @@ -32,7 +34,7 @@ struct vsp1_du_lif_config { unsigned int height; bool interlaced; - void (*callback)(void *data, bool completed, u32 crc); + void (*callback)(void *data, unsigned int status, u32 crc); void *callback_data; }; -- cgit v1.2.3-55-g7522 From a63722aeb76c65f39c98c66a1e730a2f3da123ab Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 21 Feb 2019 03:46:42 +0200 Subject: media: vsp1: drm: Implement writeback support Extend the vsp1_du_atomic_flush() API with writeback support by adding format, pitch and memory addresses of the writeback framebuffer. Writeback completion is reported through the existing frame completion callback with a new VSP1_DU_STATUS_WRITEBACK status flag. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_dl.c | 14 ++++++++++++++ drivers/media/platform/vsp1/vsp1_dl.h | 3 ++- drivers/media/platform/vsp1/vsp1_drm.c | 25 ++++++++++++++++++++++++- include/media/vsp1.h | 15 +++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) (limited to 'include/media') diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index ed7cda4130f2..104b6f514536 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -958,6 +958,9 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, unsigned int dl_flags) * * The VSP1_DL_FRAME_END_INTERNAL flag indicates that the display list that just * became active had been queued with the internal notification flag. + * + * The VSP1_DL_FRAME_END_WRITEBACK flag indicates that the previously active + * display list had been queued with the writeback flag. */ unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm) { @@ -995,6 +998,17 @@ unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm) if (status & VI6_STATUS_FLD_STD(dlm->index)) goto done; + /* + * If the active display list has the writeback flag set, the frame + * completion marks the end of the writeback capture. Return the + * VSP1_DL_FRAME_END_WRITEBACK flag and reset the display list's + * writeback flag. + */ + if (dlm->active && (dlm->active->flags & VSP1_DL_FRAME_END_WRITEBACK)) { + flags |= VSP1_DL_FRAME_END_WRITEBACK; + dlm->active->flags &= ~VSP1_DL_FRAME_END_WRITEBACK; + } + /* * The device starts processing the queued display list right after the * frame end interrupt. The display list thus becomes active. diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h index 079ba5af0315..bebe16483ca5 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.h +++ b/drivers/media/platform/vsp1/vsp1_dl.h @@ -19,7 +19,8 @@ struct vsp1_dl_manager; /* Keep these flags in sync with VSP1_DU_STATUS_* in include/media/vsp1.h. */ #define VSP1_DL_FRAME_END_COMPLETED BIT(0) -#define VSP1_DL_FRAME_END_INTERNAL BIT(1) +#define VSP1_DL_FRAME_END_WRITEBACK BIT(1) +#define VSP1_DL_FRAME_END_INTERNAL BIT(2) /** * struct vsp1_dl_ext_cmd - Extended Display command diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index bd95683c1cd9..a4a45d68a6ef 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -37,7 +37,9 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe, if (drm_pipe->du_complete) { struct vsp1_entity *uif = drm_pipe->uif; - unsigned int status = completion & VSP1_DU_STATUS_COMPLETE; + unsigned int status = completion + & (VSP1_DU_STATUS_COMPLETE | + VSP1_DU_STATUS_WRITEBACK); u32 crc; crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0; @@ -541,6 +543,8 @@ static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe) if (drm_pipe->force_brx_release) dl_flags |= VSP1_DL_FRAME_END_INTERNAL; + if (pipe->output->writeback) + dl_flags |= VSP1_DL_FRAME_END_WRITEBACK; dl = vsp1_dl_list_get(pipe->output->dlm); dlb = vsp1_dl_list_get_body0(dl); @@ -870,12 +874,31 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index, struct vsp1_device *vsp1 = dev_get_drvdata(dev); struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index]; struct vsp1_pipeline *pipe = &drm_pipe->pipe; + int ret; drm_pipe->crc = cfg->crc; mutex_lock(&vsp1->drm->lock); + + if (cfg->writeback.pixelformat) { + const struct vsp1_du_writeback_config *wb_cfg = &cfg->writeback; + + ret = vsp1_du_pipeline_set_rwpf_format(vsp1, pipe->output, + wb_cfg->pixelformat, + wb_cfg->pitch); + if (WARN_ON(ret < 0)) + goto done; + + pipe->output->mem.addr[0] = wb_cfg->mem[0]; + pipe->output->mem.addr[1] = wb_cfg->mem[1]; + pipe->output->mem.addr[2] = wb_cfg->mem[2]; + pipe->output->writeback = true; + } + vsp1_du_pipeline_setup_inputs(vsp1, pipe); vsp1_du_pipeline_configure(pipe); + +done: mutex_unlock(&vsp1->drm->lock); } EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush); diff --git a/include/media/vsp1.h b/include/media/vsp1.h index 877496936487..cc1b0d42ce95 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -18,6 +18,7 @@ struct device; int vsp1_du_init(struct device *dev); #define VSP1_DU_STATUS_COMPLETE BIT(0) +#define VSP1_DU_STATUS_WRITEBACK BIT(1) /** * struct vsp1_du_lif_config - VSP LIF configuration @@ -83,12 +84,26 @@ struct vsp1_du_crc_config { unsigned int index; }; +/** + * struct vsp1_du_writeback_config - VSP writeback configuration parameters + * @pixelformat: plane pixel format (V4L2 4CC) + * @pitch: line pitch in bytes for the first plane + * @mem: DMA memory address for each plane of the frame buffer + */ +struct vsp1_du_writeback_config { + u32 pixelformat; + unsigned int pitch; + dma_addr_t mem[3]; +}; + /** * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters * @crc: CRC computation configuration + * @writeback: writeback configuration */ struct vsp1_du_atomic_pipe_config { struct vsp1_du_crc_config crc; + struct vsp1_du_writeback_config writeback; }; void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index); -- cgit v1.2.3-55-g7522