Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

+55 -2
+14
drivers/media/platform/vsp1/vsp1_dl.c
··· 958 958 * 959 959 * The VSP1_DL_FRAME_END_INTERNAL flag indicates that the display list that just 960 960 * became active had been queued with the internal notification flag. 961 + * 962 + * The VSP1_DL_FRAME_END_WRITEBACK flag indicates that the previously active 963 + * display list had been queued with the writeback flag. 961 964 */ 962 965 unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm) 963 966 { ··· 997 994 */ 998 995 if (status & VI6_STATUS_FLD_STD(dlm->index)) 999 996 goto done; 997 + 998 + /* 999 + * If the active display list has the writeback flag set, the frame 1000 + * completion marks the end of the writeback capture. Return the 1001 + * VSP1_DL_FRAME_END_WRITEBACK flag and reset the display list's 1002 + * writeback flag. 1003 + */ 1004 + if (dlm->active && (dlm->active->flags & VSP1_DL_FRAME_END_WRITEBACK)) { 1005 + flags |= VSP1_DL_FRAME_END_WRITEBACK; 1006 + dlm->active->flags &= ~VSP1_DL_FRAME_END_WRITEBACK; 1007 + } 1000 1008 1001 1009 /* 1002 1010 * The device starts processing the queued display list right after the
+2 -1
drivers/media/platform/vsp1/vsp1_dl.h
··· 19 19 20 20 /* Keep these flags in sync with VSP1_DU_STATUS_* in include/media/vsp1.h. */ 21 21 #define VSP1_DL_FRAME_END_COMPLETED BIT(0) 22 - #define VSP1_DL_FRAME_END_INTERNAL BIT(1) 22 + #define VSP1_DL_FRAME_END_WRITEBACK BIT(1) 23 + #define VSP1_DL_FRAME_END_INTERNAL BIT(2) 23 24 24 25 /** 25 26 * struct vsp1_dl_ext_cmd - Extended Display command
+24 -1
drivers/media/platform/vsp1/vsp1_drm.c
··· 37 37 38 38 if (drm_pipe->du_complete) { 39 39 struct vsp1_entity *uif = drm_pipe->uif; 40 - unsigned int status = completion & VSP1_DU_STATUS_COMPLETE; 40 + unsigned int status = completion 41 + & (VSP1_DU_STATUS_COMPLETE | 42 + VSP1_DU_STATUS_WRITEBACK); 41 43 u32 crc; 42 44 43 45 crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0; ··· 543 541 544 542 if (drm_pipe->force_brx_release) 545 543 dl_flags |= VSP1_DL_FRAME_END_INTERNAL; 544 + if (pipe->output->writeback) 545 + dl_flags |= VSP1_DL_FRAME_END_WRITEBACK; 546 546 547 547 dl = vsp1_dl_list_get(pipe->output->dlm); 548 548 dlb = vsp1_dl_list_get_body0(dl); ··· 874 870 struct vsp1_device *vsp1 = dev_get_drvdata(dev); 875 871 struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index]; 876 872 struct vsp1_pipeline *pipe = &drm_pipe->pipe; 873 + int ret; 877 874 878 875 drm_pipe->crc = cfg->crc; 879 876 880 877 mutex_lock(&vsp1->drm->lock); 878 + 879 + if (cfg->writeback.pixelformat) { 880 + const struct vsp1_du_writeback_config *wb_cfg = &cfg->writeback; 881 + 882 + ret = vsp1_du_pipeline_set_rwpf_format(vsp1, pipe->output, 883 + wb_cfg->pixelformat, 884 + wb_cfg->pitch); 885 + if (WARN_ON(ret < 0)) 886 + goto done; 887 + 888 + pipe->output->mem.addr[0] = wb_cfg->mem[0]; 889 + pipe->output->mem.addr[1] = wb_cfg->mem[1]; 890 + pipe->output->mem.addr[2] = wb_cfg->mem[2]; 891 + pipe->output->writeback = true; 892 + } 893 + 881 894 vsp1_du_pipeline_setup_inputs(vsp1, pipe); 882 895 vsp1_du_pipeline_configure(pipe); 896 + 897 + done: 883 898 mutex_unlock(&vsp1->drm->lock); 884 899 } 885 900 EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
+15
include/media/vsp1.h
··· 18 18 int vsp1_du_init(struct device *dev); 19 19 20 20 #define VSP1_DU_STATUS_COMPLETE BIT(0) 21 + #define VSP1_DU_STATUS_WRITEBACK BIT(1) 21 22 22 23 /** 23 24 * struct vsp1_du_lif_config - VSP LIF configuration ··· 85 84 }; 86 85 87 86 /** 87 + * struct vsp1_du_writeback_config - VSP writeback configuration parameters 88 + * @pixelformat: plane pixel format (V4L2 4CC) 89 + * @pitch: line pitch in bytes for the first plane 90 + * @mem: DMA memory address for each plane of the frame buffer 91 + */ 92 + struct vsp1_du_writeback_config { 93 + u32 pixelformat; 94 + unsigned int pitch; 95 + dma_addr_t mem[3]; 96 + }; 97 + 98 + /** 88 99 * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters 89 100 * @crc: CRC computation configuration 101 + * @writeback: writeback configuration 90 102 */ 91 103 struct vsp1_du_atomic_pipe_config { 92 104 struct vsp1_du_crc_config crc; 105 + struct vsp1_du_writeback_config writeback; 93 106 }; 94 107 95 108 void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);