From bd01d85285ccb62437df4d2c7f922e1afc5a1f07 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 10 Aug 2021 08:56:18 +0800 Subject: [PATCH] media: rockchip: ispp: first frame handle for multi dev Change-Id: Ie4bc4c8b8a7486fca6bd6b55ca395eb774997120 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/ispp/dev.h | 3 ++ drivers/media/platform/rockchip/ispp/hw.c | 1 - drivers/media/platform/rockchip/ispp/hw.h | 1 - drivers/media/platform/rockchip/ispp/ispp.c | 28 +++++----- drivers/media/platform/rockchip/ispp/stream.c | 52 +++++++++++++------ 5 files changed, 54 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/rockchip/ispp/dev.h b/drivers/media/platform/rockchip/ispp/dev.h index d55413b7337f..b39e2a5b1945 100644 --- a/drivers/media/platform/rockchip/ispp/dev.h +++ b/drivers/media/platform/rockchip/ispp/dev.h @@ -56,5 +56,8 @@ struct rkispp_device { bool stream_sync; void (*irq_hdl)(u32 mis, struct rkispp_device *dev); + + u32 first_frame_dma; + bool is_first; }; #endif diff --git a/drivers/media/platform/rockchip/ispp/hw.c b/drivers/media/platform/rockchip/ispp/hw.c index 5c608738e129..06262702b205 100644 --- a/drivers/media/platform/rockchip/ispp/hw.c +++ b/drivers/media/platform/rockchip/ispp/hw.c @@ -329,7 +329,6 @@ static int rkispp_hw_probe(struct platform_device *pdev) hw_dev->is_dma_sg_ops = false; hw_dev->is_shutdown = false; hw_dev->is_first = true; - hw_dev->first_frame_dma = -1; hw_dev->is_mmu = is_iommu_enable(dev); ret = of_reserved_mem_device_init(dev); if (ret) { diff --git a/drivers/media/platform/rockchip/ispp/hw.h b/drivers/media/platform/rockchip/ispp/hw.h index d750dae270e6..8eb2585ecb71 100644 --- a/drivers/media/platform/rockchip/ispp/hw.h +++ b/drivers/media/platform/rockchip/ispp/hw.h @@ -53,7 +53,6 @@ struct rkispp_hw_dev { atomic_t refcnt; const struct vb2_mem_ops *mem_ops; struct rkisp_ispp_reg *reg_buf; - u32 first_frame_dma; bool is_mmu; bool is_idle; bool is_single; diff --git a/drivers/media/platform/rockchip/ispp/ispp.c b/drivers/media/platform/rockchip/ispp/ispp.c index 4490f3432bd4..ad9a12025c71 100644 --- a/drivers/media/platform/rockchip/ispp/ispp.c +++ b/drivers/media/platform/rockchip/ispp/ispp.c @@ -273,6 +273,8 @@ static int rkispp_sd_s_stream(struct v4l2_subdev *sd, int on) "s_stream on:%d\n", on); if (on) { + dev->is_first = true; + dev->first_frame_dma = -1; ispp_sdev->state = ISPP_START; ispp_sdev->frm_sync_seq = -1; ispp_sdev->frame_timestamp = 0; @@ -457,28 +459,28 @@ static long rkispp_compat_ioctl32(struct v4l2_subdev *sd, switch (cmd) { case RKISPP_CMD_GET_FECBUF_INFO: ret = rkispp_ioctl(sd, cmd, &fecbuf); - if (!ret) - ret = copy_to_user(up, &fecbuf, sizeof(fecbuf)); + if (!ret && copy_to_user(up, &fecbuf, sizeof(fecbuf))) + ret = -EFAULT; break; case RKISPP_CMD_SET_FECBUF_SIZE: - ret = copy_from_user(&fecsize, up, sizeof(fecsize)); - if (!ret) - ret = rkispp_ioctl(sd, cmd, &fecsize); + if (copy_from_user(&fecsize, up, sizeof(fecsize))) + return -EFAULT; + ret = rkispp_ioctl(sd, cmd, &fecsize); break; case RKISPP_CMD_TRIGGER_YNRRUN: - ret = copy_from_user(&tnr_inf, up, sizeof(tnr_inf)); - if (!ret) - ret = rkispp_ioctl(sd, cmd, &tnr_inf); + if (copy_from_user(&tnr_inf, up, sizeof(tnr_inf))) + return -EFAULT; + ret = rkispp_ioctl(sd, cmd, &tnr_inf); break; case RKISPP_CMD_GET_TNRBUF_FD: ret = rkispp_ioctl(sd, cmd, &idxfd); - if (!ret) - ret = copy_to_user(up, &idxfd, sizeof(idxfd)); + if (!ret && copy_to_user(up, &idxfd, sizeof(idxfd))) + ret = -EFAULT; break; case RKISPP_CMD_TRIGGER_MODE: - ret = copy_from_user(&t_mode, up, sizeof(t_mode)); - if (!ret) - ret = rkispp_ioctl(sd, cmd, &t_mode); + if (copy_from_user(&t_mode, up, sizeof(t_mode))) + return -EFAULT; + ret = rkispp_ioctl(sd, cmd, &t_mode); break; default: ret = -ENOIOCTLCMD; diff --git a/drivers/media/platform/rockchip/ispp/stream.c b/drivers/media/platform/rockchip/ispp/stream.c index 9de507df5591..78b2e247b5c0 100644 --- a/drivers/media/platform/rockchip/ispp/stream.c +++ b/drivers/media/platform/rockchip/ispp/stream.c @@ -2383,13 +2383,6 @@ static void restart_module(struct rkispp_device *dev) rkispp_set_bits(dev, RKISPP_TNR_CTRL, 0, SW_TNR_1ST_FRM); monitor->tnr.is_err = false; } - if (monitor->restart_module & MONITOR_NR && monitor->nr.is_err) { - rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y, - readl(base + RKISPP_NR_ADDR_BASE_Y_SHD)); - rkispp_write(dev, RKISPP_NR_ADDR_BASE_UV, - readl(base + RKISPP_NR_ADDR_BASE_UV_SHD)); - monitor->nr.is_err = false; - } rkispp_soft_reset(dev->hw_dev); rkispp_update_regs(dev, RKISPP_CTRL_QUICK, RKISPP_FEC_CROP); writel(ALL_FORCE_UPD, base + RKISPP_CTRL_UPDATE); @@ -2404,6 +2397,32 @@ static void restart_module(struct rkispp_device *dev) complete(&monitor->tnr.cmpl); } if (monitor->restart_module & MONITOR_NR) { + if (monitor->nr.is_err) { + struct rkispp_stream_vdev *vdev = &dev->stream_vdev; + struct v4l2_subdev *sd = dev->ispp_sdev.remote_sd; + struct rkispp_buffer *inbuf; + + if (vdev->nr.cur_rd) { + if (vdev->nr.cur_rd->is_isp) { + v4l2_subdev_call(sd, video, s_rx_buffer, + vdev->nr.cur_rd, NULL); + } else if (!vdev->nr.cur_rd->priv) { + list_add_tail(&vdev->nr.cur_rd->list, + &vdev->tnr.list_wr); + } else { + inbuf = vdev->nr.cur_rd->priv; + vb2_buffer_done(&inbuf->vb.vb2_buf, VB2_BUF_STATE_DONE); + } + vdev->nr.cur_rd = NULL; + } + rkispp_set_bits(dev, RKISPP_TNR_CTRL, 0, SW_TNR_1ST_FRM); + vdev->nr.is_end = true; + monitor->nr.is_err = false; + monitor->is_restart = false; + monitor->restart_module = 0; + rkispp_event_handle(dev, CMD_QUEUE_DMABUF, NULL); + goto end; + } val |= NR_SHP_ST; monitor->monitoring_module |= MONITOR_NR; if (!completion_done(&monitor->nr.cmpl)) @@ -2801,9 +2820,10 @@ static void nr_work_event(struct rkispp_device *dev, dbuf = vdev->nr.cur_rd->dbuf[GROUP_BUF_PIC]; dummy = dbuf_to_dummy(dbuf, &vdev->tnr.buf.iir, size); val = dummy->dma_addr; - if (dev->hw_dev->is_first && dev->hw_dev->first_frame_dma != -1) { - val = dev->hw_dev->first_frame_dma; - dev->hw_dev->first_frame_dma = -1; + if (dev->is_first && dev->first_frame_dma != -1) { + val = dev->first_frame_dma; + dev->first_frame_dma = -1; + dev->is_first = false; } rkispp_write(dev, RKISPP_NR_ADDR_BASE_Y, val); val += vdev->nr.uv_offset; @@ -3002,10 +3022,11 @@ static void tnr_work_event(struct rkispp_device *dev, if (!buf_rd && !buf_wr && is_isr) { vdev->tnr.is_end = true; - if (dev->hw_dev->is_first && vdev->tnr.nxt_rd) { + if (dev->is_first && vdev->tnr.nxt_rd) { struct rkispp_isp_buf_pool *tbuf = get_pool_buf(dev, vdev->tnr.nxt_rd); - dev->hw_dev->first_frame_dma = tbuf->dma[GROUP_BUF_PIC]; + dev->first_frame_dma = tbuf->dma[GROUP_BUF_PIC]; + rkispp_set_bits(dev, RKISPP_TNR_CTRL, 0, SW_TNR_1ST_FRM); } if (vdev->tnr.cur_rd) { @@ -3088,8 +3109,7 @@ static void tnr_work_event(struct rkispp_device *dev, vdev->tnr.cur_rd = vdev->tnr.nxt_rd; vdev->tnr.nxt_rd = buf_rd; /* first buf for 3to1 using twice */ - if (!is_3to1 || - (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM)) + if (!is_3to1 || dev->is_first) vdev->tnr.cur_rd = vdev->tnr.nxt_rd; } else if (vdev->tnr.is_end && !list_empty(list)) { /* tnr read buf from list @@ -3148,7 +3168,7 @@ static void tnr_work_event(struct rkispp_device *dev, val = buf->dma[GROUP_BUF_GAIN]; rkispp_write(dev, RKISPP_TNR_GAIN_NXT_Y_BASE, val); - if (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM) + if (dev->is_first) vdev->tnr.cur_rd = NULL; } } @@ -3454,7 +3474,7 @@ void rkispp_isr(u32 mis_val, struct rkispp_device *dev) (dev->isp_mode & ISP_ISPP_QUICK)) ++dev->ispp_sdev.frm_sync_seq; - if (mis_val & TNR_INT && !dev->hw_dev->is_first) + if (mis_val & TNR_INT) if (rkispp_read(dev, RKISPP_TNR_CTRL) & SW_TNR_1ST_FRM) rkispp_clear_bits(dev, RKISPP_TNR_CTRL, SW_TNR_1ST_FRM);