diff --git a/drivers/media/platform/rockchip/isp/bridge.c b/drivers/media/platform/rockchip/isp/bridge.c index 23bc8ee42aec..10ac7afd299c 100644 --- a/drivers/media/platform/rockchip/isp/bridge.c +++ b/drivers/media/platform/rockchip/isp/bridge.c @@ -20,34 +20,6 @@ struct rkisp_bridge_buf *to_bridge_buf(struct rkisp_ispp_buf *dbufs) return container_of(dbufs, struct rkisp_bridge_buf, dbufs); } -static void update_mi(struct rkisp_bridge_device *dev) -{ - struct rkisp_hw_dev *hw = dev->ispdev->hw_dev; - struct rkisp_bridge_buf *buf; - u32 val; - - if (hw->nxt_buf) { - buf = to_bridge_buf(hw->nxt_buf); - val = buf->dummy[GROUP_BUF_PIC].dma_addr; - rkisp_write(dev->ispdev, - dev->cfg->reg.y0_base, val, true); - val += dev->cfg->offset; - rkisp_write(dev->ispdev, - dev->cfg->reg.uv0_base, val, true); - val = buf->dummy[GROUP_BUF_GAIN].dma_addr; - rkisp_write(dev->ispdev, - dev->cfg->reg.g0_base, val, true); - } - - v4l2_dbg(3, rkisp_debug, &dev->sd, - "%s pic(shd:0x%x base:0x%x) gain(shd:0x%x base:0x%x)\n", - __func__, - rkisp_read(dev->ispdev, dev->cfg->reg.y0_base_shd, true), - rkisp_read(dev->ispdev, dev->cfg->reg.y0_base, true), - rkisp_read(dev->ispdev, dev->cfg->reg.g0_base_shd, true), - rkisp_read(dev->ispdev, dev->cfg->reg.g0_base, true)); -} - static void dump_dbg_reg(struct rkisp_bridge_device *dev, struct rkisp_ispp_reg *reg_buf) { struct rkisp_isp2x_stat_buffer *tmp_statsbuf; @@ -586,16 +558,6 @@ static int frame_end(struct rkisp_bridge_device *dev, bool en) hw->nxt_buf = NULL; } - spin_lock_irqsave(&hw->buf_lock, lock_flags); - if (!list_empty(&hw->list)) { - hw->nxt_buf = list_first_entry(&hw->list, - struct rkisp_ispp_buf, list); - list_del(&hw->nxt_buf->list); - } - spin_unlock_irqrestore(&hw->buf_lock, lock_flags); - - update_mi(dev); - return 0; } @@ -1003,9 +965,6 @@ static int bridge_start(struct rkisp_bridge_device *dev) rkisp_config_dmatx_valid_buf(dev->ispdev); force_cfg_update(dev->ispdev); rkisp_update_spstream_buf(sp_stream); - - if (!(dev->work_mode & ISP_ISPP_QUICK)) - update_mi(dev); hdr_update_dmatx_buf(dev->ispdev); } dev->ispdev->skip_frame = 0; @@ -1434,6 +1393,44 @@ void rkisp_bridge_stop_spstream(struct rkisp_device *dev) spin_unlock_irqrestore(&hw->buf_lock, lock_flags); } +void rkisp_bridge_update_mi(struct rkisp_device *dev) +{ + struct rkisp_bridge_device *br = &dev->br_dev; + struct rkisp_hw_dev *hw = dev->hw_dev; + struct rkisp_bridge_buf *buf; + unsigned long lock_flags = 0; + u32 val; + + if (dev->isp_ver != ISP_V20 || !br->en || + br->work_mode & ISP_ISPP_QUICK) + return; + + spin_lock_irqsave(&hw->buf_lock, lock_flags); + if (!hw->nxt_buf && !list_empty(&hw->list)) { + hw->nxt_buf = list_first_entry(&hw->list, + struct rkisp_ispp_buf, list); + list_del(&hw->nxt_buf->list); + } + spin_unlock_irqrestore(&hw->buf_lock, lock_flags); + + if (hw->nxt_buf) { + buf = to_bridge_buf(hw->nxt_buf); + val = buf->dummy[GROUP_BUF_PIC].dma_addr; + rkisp_write(dev, br->cfg->reg.y0_base, val, true); + val += br->cfg->offset; + rkisp_write(dev, br->cfg->reg.uv0_base, val, true); + val = buf->dummy[GROUP_BUF_GAIN].dma_addr; + rkisp_write(dev, br->cfg->reg.g0_base, val, true); + } + + v4l2_dbg(2, rkisp_debug, &br->sd, + "update pic(shd:0x%x base:0x%x) gain(shd:0x%x base:0x%x)\n", + rkisp_read(dev, br->cfg->reg.y0_base_shd, true), + rkisp_read(dev, br->cfg->reg.y0_base, true), + rkisp_read(dev, br->cfg->reg.g0_base_shd, true), + rkisp_read(dev, br->cfg->reg.g0_base, true)); +} + void rkisp_bridge_isr(u32 *mis_val, struct rkisp_device *dev) { struct rkisp_bridge_device *bridge = &dev->br_dev; @@ -1486,7 +1483,8 @@ int rkisp_register_bridge_subdev(struct rkisp_device *dev, v4l2_subdev_init(sd, &bridge_v4l2_ops); //sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; sd->entity.obj_type = 0; - snprintf(sd->name, sizeof(sd->name), BRIDGE_DEV_NAME); + snprintf(sd->name, sizeof(sd->name), + "%s%d", BRIDGE_DEV_NAME, dev->dev_id); bridge->pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&sd->entity, 1, &bridge->pad); if (ret < 0) diff --git a/drivers/media/platform/rockchip/isp/bridge.h b/drivers/media/platform/rockchip/isp/bridge.h index 0e5dfa074dc4..f8dbe291b52a 100644 --- a/drivers/media/platform/rockchip/isp/bridge.h +++ b/drivers/media/platform/rockchip/isp/bridge.h @@ -66,6 +66,7 @@ void rkisp_bridge_isr(u32 *mis_val, struct rkisp_device *dev); void rkisp_bridge_sendtopp_buffer(struct rkisp_device *dev, u32 dev_id, u32 buf_idx); void rkisp_bridge_save_spbuf(struct rkisp_device *dev, struct rkisp_buffer *sp_buf); void rkisp_bridge_stop_spstream(struct rkisp_device *dev); +void rkisp_bridge_update_mi(struct rkisp_device *dev); void rkisp_get_bridge_sd(struct platform_device *dev, struct v4l2_subdev **sd); #endif diff --git a/drivers/media/platform/rockchip/isp/csi.c b/drivers/media/platform/rockchip/isp/csi.c index 3e65068c894b..f67ca02c716c 100644 --- a/drivers/media/platform/rockchip/isp/csi.c +++ b/drivers/media/platform/rockchip/isp/csi.c @@ -470,6 +470,7 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) rkisp_set_bits(dev, CTRL_SWS_CFG, 0, SW_MPIP_DROP_FRM_DIS, true); } + memset(dev->csi_dev.filt_state, 0, sizeof(dev->csi_dev.filt_state)); dev->csi_dev.frame_cnt = -1; dev->csi_dev.frame_cnt_x1 = -1; dev->csi_dev.frame_cnt_x2 = -1; @@ -579,6 +580,9 @@ void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm, u32 mode) rkisp_write(dev, ISP_CTRL, val, true); } + memset(csi->filt_state, 0, sizeof(csi->filt_state)); + csi->filt_state[CSI_F_VS] = dma2frm; + val = rkisp_read(dev, CSI2RX_CTRL0, true); val &= ~SW_IBUF_OP_MODE(0xf); tmp = SW_IBUF_OP_MODE(csi->rd_mode); diff --git a/drivers/media/platform/rockchip/isp/csi.h b/drivers/media/platform/rockchip/isp/csi.h index c49c2328faa5..a73c455d8f51 100644 --- a/drivers/media/platform/rockchip/isp/csi.h +++ b/drivers/media/platform/rockchip/isp/csi.h @@ -70,6 +70,7 @@ struct sink_info { * rdbk_kfifo: read back event fifo * rdbk_lock: lock for read back event * mipi_di: Data Identifier (vc[7:6],dt[5:0]) + * filt_state: multiframe read back mode to filt irq event * tx_first: flags for dmatx first Y_STATE irq * memory: compact or big/little endian byte order for tx/rx */ @@ -87,6 +88,7 @@ struct rkisp_csi_device { int frame_cnt_x3; u32 rd_mode; u8 mipi_di[CSI_PAD_MAX - 1]; + u8 filt_state[CSI_F_MAX]; u8 tx_first[HDR_DMA_MAX]; u8 memory; }; diff --git a/drivers/media/platform/rockchip/isp/isp_ispp.h b/drivers/media/platform/rockchip/isp/isp_ispp.h index ccbd10ebcef7..a86e3543e347 100644 --- a/drivers/media/platform/rockchip/isp/isp_ispp.h +++ b/drivers/media/platform/rockchip/isp/isp_ispp.h @@ -10,7 +10,7 @@ #include #include -#define RKISP_BUF_MAX 3 +#define RKISP_BUF_MAX 2 #define RKISPP_BUF_MAX 2 #define RKISP_ISPP_BUF_MAX (RKISP_BUF_MAX + RKISPP_BUF_MAX + (2 * (DEV_MAX - 1))) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index fcb310a451a1..6895384fea80 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -2294,6 +2294,11 @@ void rkisp_isp_isr(unsigned int isp_mis, rkisp_set_state(dev, ISP_FRAME_VS); if (IS_HDR_RDBK(dev->hdr.op_mode)) { rkisp_stats_rdbk_enable(&dev->stats_vdev, true); + /* last readback to config next buf */ + if (!dev->csi_dev.filt_state[CSI_F_VS]) + rkisp_bridge_update_mi(dev); + else + dev->csi_dev.filt_state[CSI_F_VS]--; goto vs_skip; } if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) {