MLK-18439: ISI: fix image tearing issue
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Mon, 16 Jul 2018 01:03:19 +0000 (09:03 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
When there is no free buffer in driver as isi output, isi
will still write buffer which has been dequeue to userspace
and the buffer maybe is being scanning out by DC. So add a
temporary buffer as its output when the case happen

Signed-off-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
Reviewed-by: Robby.Cai <robby.cai@nxp.com>
drivers/media/platform/imx8/mxc-isi-hw.c

index 5712024..cfb3665 100644 (file)
@@ -108,31 +108,42 @@ void mxc_isi_channel_set_outbuf(struct mxc_isi_dev *mxc_isi, struct mxc_isi_buff
 {
        struct vb2_buffer *vb2_buf = &buf->v4l2_buf.vb2_buf;
        struct frame_addr *paddr = &buf->paddr;
+       struct v4l2_pix_format_mplane *pix = &mxc_isi->pix;
        u32 framecount = buf->v4l2_buf.sequence;
        int val = 0;
 
-       paddr->y = vb2_dma_contig_plane_dma_addr(vb2_buf, 0);
+       if (buf->discard) {
+               paddr->y = mxc_isi->discard_buffer_dma[0];
+               if (pix->num_planes == 2)
+                       paddr->cb = mxc_isi->discard_buffer_dma[1];
+               if (pix->num_planes == 3) {
+                       paddr->cb = mxc_isi->discard_buffer_dma[1];
+                       paddr->cr = mxc_isi->discard_buffer_dma[2];
+               }
+       } else {
+               paddr->y = vb2_dma_contig_plane_dma_addr(vb2_buf, 0);
 
-       if (vb2_buf->num_planes == 2)
-               paddr->cb = vb2_dma_contig_plane_dma_addr(vb2_buf, 1);
-       if (vb2_buf->num_planes == 3) {
-               paddr->cb = vb2_dma_contig_plane_dma_addr(vb2_buf, 1);
-               paddr->cr = vb2_dma_contig_plane_dma_addr(vb2_buf, 2);
+               if (vb2_buf->num_planes == 2)
+                       paddr->cb = vb2_dma_contig_plane_dma_addr(vb2_buf, 1);
+               if (vb2_buf->num_planes == 3) {
+                       paddr->cb = vb2_dma_contig_plane_dma_addr(vb2_buf, 1);
+                       paddr->cr = vb2_dma_contig_plane_dma_addr(vb2_buf, 2);
+               }
        }
 
        val = readl(mxc_isi->regs + CHNL_OUT_BUF_CTRL);
-       if (framecount % 2 == 1) {
-               writel(paddr->y, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_Y);
-               writel(paddr->cb, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_U);
-               writel(paddr->cr, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_V);
-               val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF2_ADDR_MASK;
-       } else {
+       if (framecount % 2 == 0) {
                writel(paddr->y, mxc_isi->regs + CHNL_OUT_BUF1_ADDR_Y);
                writel(paddr->cb, mxc_isi->regs + CHNL_OUT_BUF1_ADDR_U);
                writel(paddr->cr, mxc_isi->regs + CHNL_OUT_BUF1_ADDR_V);
                val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF1_ADDR_MASK;
+       } else if (framecount % 2 == 1) {
+               writel(paddr->y, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_Y);
+               writel(paddr->cb, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_U);
+               writel(paddr->cr, mxc_isi->regs + CHNL_OUT_BUF2_ADDR_V);
+               val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF2_ADDR_MASK;
        }
-       writel(val,     mxc_isi->regs + CHNL_OUT_BUF_CTRL);
+       writel(val, mxc_isi->regs + CHNL_OUT_BUF_CTRL);
 }
 
 void mxc_isi_channel_hw_reset(struct mxc_isi_dev *mxc_isi)
@@ -543,6 +554,7 @@ void mxc_isi_channel_enable(struct mxc_isi_dev *mxc_isi)
        val |= 0xff << CHNL_CTRL_BLANK_PXL_OFFSET;
        writel(val, mxc_isi->regs + CHNL_CTRL);
 
+       mxc_isi_clean_irq_status(mxc_isi, 0);
        mxc_isi_enable_irq(mxc_isi);
        msleep(300);
        dump_isi_regs(mxc_isi);
@@ -585,7 +597,7 @@ void  mxc_isi_enable_irq(struct mxc_isi_dev *mxc_isi)
 
 void mxc_isi_disable_irq(struct mxc_isi_dev *mxc_isi)
 {
-       writel(0, mxc_isi->regs + CHNL_CTRL);
+       writel(0, mxc_isi->regs + CHNL_IER);
 }
 
 u32 mxc_isi_get_irq_status(struct mxc_isi_dev *mxc_isi)