diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index fade9c243d7e..ef8a788de1cf 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -387,9 +387,7 @@ static void update_rawrd(struct rkisp_stream *stream) rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false); } stream->frame_end = false; - if (stream->id == RKISP_STREAM_RAWRD2 && - (stream->out_isp_fmt.fmt_type == FMT_YUV || - dev->dmarx_dev.trigger == T_AUTO)) { + if (stream->id == RKISP_STREAM_RAWRD2 && stream->out_isp_fmt.fmt_type == FMT_YUV) { struct vb2_v4l2_buffer *vbuf = &stream->curr_buf->vb; struct isp2x_csi_trigger trigger = { .frame_timestamp = vbuf->vb2_buf.timestamp, diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.c b/drivers/media/platform/rockchip/isp/isp_params_v32.c index cebb4eefca65..c4450944733c 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -3371,6 +3371,31 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en) return; } + value = priv_val->buf_3dnr_iir.size; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_SIZE); + value = priv_val->buf_3dnr_iir.dma_addr; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE); + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE); + + value = priv_val->buf_3dnr_ds.size; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_SIZE); + value = priv_val->buf_3dnr_ds.dma_addr; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_BASE); + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_RD_BASE); + + value = priv_val->is_sram ? + ispdev->hw_dev->sram.dma_addr : priv_val->buf_3dnr_cur.dma_addr; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_BASE); + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_BASE); + value = priv_val->bay3d_cur_size; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_SIZE); + isp3_param_write(params_vdev, value, ISP32_MI_BAY3D_CUR_RD_SIZE); + value = priv_val->bay3d_cur_wsize; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_LENGTH); + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_LENGTH); + value = priv_val->bay3d_cur_wrap_line << 16 | 28; + isp3_param_write(params_vdev, value, ISP3X_BAY3D_MI_ST); + /* mibuf_size for fifo_cur_full, set to max: (3072 - 2) / 2, 2 align */ value = 0x5fe << 16; isp3_param_set_bits(params_vdev, ISP3X_BAY3D_IN_IRQ_LINECNT, value); @@ -4085,7 +4110,6 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, u32 w = ALIGN(isp_sdev->in_crop.width, 16); u32 h = ALIGN(isp_sdev->in_crop.height, 16); u32 val, wrap_line, wsize, div; - dma_addr_t dma_addr; bool is_alloc; priv_val->is_lo8x8 = (!new_params->others.bay3d_cfg.lo4x8_en && @@ -4120,10 +4144,6 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, goto err_3dnr; } } - isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_IIR_WR_SIZE); - val = priv_val->buf_3dnr_iir.dma_addr; - isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_IIR_WR_BASE); - isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_IIR_RD_BASE); div = priv_val->is_lo8x8 ? 64 : 16; val = w * h / div; @@ -4145,10 +4165,6 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, goto err_3dnr; } } - isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_DS_WR_SIZE); - val = priv_val->buf_3dnr_ds.dma_addr; - isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_DS_WR_BASE); - isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_DS_RD_BASE); wrap_line = priv_val->is_lo8x8 ? 76 : 36; wsize = is_bwopt_dis ? w : w * 2; @@ -4177,22 +4193,13 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, dev_err(dev->dev, "alloc bay3d cur buf fail:%d\n", ret); goto err_3dnr; } - dma_addr = priv_val->buf_3dnr_cur.dma_addr; priv_val->is_sram = false; } else if (val <= dev->hw_dev->sram.size) { - dma_addr = dev->hw_dev->sram.dma_addr; priv_val->is_sram = true; - } else { - dma_addr = priv_val->buf_3dnr_cur.dma_addr; } - isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_CUR_WR_SIZE); - isp3_param_write(params_vdev, val, ISP32_MI_BAY3D_CUR_RD_SIZE); - isp3_param_write(params_vdev, wsize, ISP3X_MI_BAY3D_CUR_WR_LENGTH); - isp3_param_write(params_vdev, wsize, ISP3X_MI_BAY3D_CUR_RD_LENGTH); - isp3_param_write(params_vdev, dma_addr, ISP3X_MI_BAY3D_CUR_WR_BASE); - isp3_param_write(params_vdev, dma_addr, ISP3X_MI_BAY3D_CUR_RD_BASE); - val = wrap_line << 16 | 28; - isp3_param_write(params_vdev, val, ISP3X_BAY3D_MI_ST); + priv_val->bay3d_cur_size = val; + priv_val->bay3d_cur_wsize = wsize; + priv_val->bay3d_cur_wrap_line = wrap_line; } return 0; err_3dnr: @@ -4421,14 +4428,7 @@ rkisp_params_first_cfg_v32(struct rkisp_isp_params_vdev *params_vdev) static void rkisp_save_first_param_v32(struct rkisp_isp_params_vdev *params_vdev, void *param) { - struct rkisp_isp_params_val_v32 *priv_val = - (struct rkisp_isp_params_val_v32 *)params_vdev->priv_val; - memcpy(params_vdev->isp32_params, param, params_vdev->vdev_fmt.fmt.meta.buffersize); - - if (!params_vdev->first_params) - return; - tasklet_enable(&priv_val->lsc_tasklet); rkisp_alloc_internal_buf(params_vdev, params_vdev->isp32_params); } @@ -4718,7 +4718,6 @@ rkisp_params_stream_stop_v32(struct rkisp_isp_params_vdev *params_vdev) int i; priv_val = (struct rkisp_isp_params_val_v32 *)params_vdev->priv_val; - tasklet_disable(&priv_val->lsc_tasklet); rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); @@ -4944,7 +4943,6 @@ int rkisp_init_params_vdev_v32(struct rkisp_isp_params_vdev *params_vdev) tasklet_init(&priv_val->lsc_tasklet, isp_lsc_cfg_sram_task, (unsigned long)params_vdev); - tasklet_disable(&priv_val->lsc_tasklet); priv_val->buf_info_owner = 0; priv_val->buf_info_cnt = 0; priv_val->buf_info_idx = -1; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.h b/drivers/media/platform/rockchip/isp/isp_params_v32.h index 7a3c4d1a15db..540bb6b212f9 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.h @@ -185,6 +185,9 @@ struct rkisp_isp_params_val_v32 { u32 buf_info_cnt; int buf_info_idx; + u32 bay3d_cur_size; + u32 bay3d_cur_wsize; + u32 bay3d_cur_wrap_line; struct rkisp_dummy_buffer buf_3dnr_iir; struct rkisp_dummy_buffer buf_3dnr_cur; struct rkisp_dummy_buffer buf_3dnr_ds; diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index e4468224ba1f..6b7d5b4b22bf 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -722,6 +722,40 @@ run_next: rkisp_unite_write(dev, CSI2RX_CTRL0, val, true, hw->is_unite); } +static void rkisp_fast_switch_rx_buf(struct rkisp_device *dev, bool is_current) +{ + struct rkisp_stream *stream; + struct rkisp_buffer *buf; + u32 i, val; + + for (i = RKISP_STREAM_RAWRD0; i < RKISP_MAX_DMARX_STREAM; i++) { + stream = &dev->dmarx_dev.stream[i]; + if (!stream->ops) + continue; + buf = NULL; + if (is_current) + buf = stream->curr_buf; + else if (!list_empty(&stream->buf_queue)) + buf = list_first_entry(&stream->buf_queue, + struct rkisp_buffer, queue); + if (!buf) + continue; + val = buf->buff_addr[RKISP_PLANE_Y]; + /* f1 -> f0 -> f1 for normal + * L:f1 L:f1 -> L:f0 S:f0 -> L:f1 S:f1 for hdr2 + */ + if (dev->rd_mode == HDR_RDBK_FRAME2 && !is_current && + rkisp_read_reg_cache(dev, ISP3X_HDRMGE_GAIN0) == 0xfff0040) { + if (i == RKISP_STREAM_RAWRD2) + continue; + else + rkisp_write(dev, ISP3X_MI_RAWS_RD_BASE, val, false); + } + rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); + } +} + + static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) { struct rkisp_hw_dev *hw = dev->hw_dev; @@ -766,6 +800,10 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) } } + /* wait 2 frame to start isp for fast */ + if (dev->is_pre_on && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq)) + goto end; + if (max) { v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, "trigger fifo len:%d\n", max); @@ -790,9 +828,10 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) isp->sw_rd_cnt = 1; times = 0; } - if (dev->is_pre_on && t.frame_id == 0) { - dev->is_first_double = true; - dev->skip_frame = 1; + if (isp->is_pre_on && t.frame_id == 0) { + isp->is_first_double = true; + isp->skip_frame = 1; + rkisp_fast_switch_rx_buf(isp, false); } } end: @@ -869,6 +908,7 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq) return; if (dev->is_first_double) { + rkisp_fast_switch_rx_buf(dev, true); dev->skip_frame = 0; dev->irq_ends = 0; return; @@ -2776,9 +2816,16 @@ static void rkisp_rx_qbuf_online(struct rkisp_stream *stream, static void rkisp_rx_qbuf_rdbk(struct rkisp_stream *stream, struct rkisp_rx_buf_pool *pool) { + struct rkisp_device *dev = stream->ispdev; unsigned long lock_flags = 0; struct rkisp_buffer *ispbuf = &pool->buf; - + struct isp2x_csi_trigger trigger = { + .frame_timestamp = ispbuf->vb.vb2_buf.timestamp, + .sof_timestamp = ispbuf->vb.vb2_buf.timestamp, + .frame_id = ispbuf->vb.sequence, + .mode = 0, + .times = 0, + }; spin_lock_irqsave(&stream->vbq_lock, lock_flags); if (list_empty(&stream->buf_queue) && !stream->curr_buf) { stream->curr_buf = ispbuf; @@ -2787,6 +2834,8 @@ static void rkisp_rx_qbuf_rdbk(struct rkisp_stream *stream, list_add_tail(&ispbuf->queue, &stream->buf_queue); } spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); + if (stream->id == RKISP_STREAM_RAWRD2) + rkisp_rdbk_trigger_event(dev, T_CMD_QUEUE, &trigger); } static int rkisp_rx_qbuf(struct rkisp_device *dev, @@ -3645,6 +3694,8 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) if (head->complete != RKISP_TB_OK) { v4l2_err(&isp_dev->v4l2_dev, "wait thunderboot over timeout\n"); } else { + struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev; + void *param = NULL; u32 size = 0; switch (isp_dev->hw_dev->isp_ver) { @@ -3657,13 +3708,14 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) if (size && size < isp_dev->resmem_size) { dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr, size, DMA_FROM_DEVICE); - isp_dev->params_vdev.is_first_cfg = true; + params_vdev->is_first_cfg = true; if (isp_dev->hw_dev->isp_ver == ISP_V32) { struct rkisp32_thunderboot_resmem_head *tmp = resmem_va; - memcpy(isp_dev->params_vdev.isp32_params, &tmp->cfg, - sizeof(struct isp32_isp_params_cfg)); + param = &tmp->cfg; } + if (param) + params_vdev->ops->save_first_param(params_vdev, param); } else if (size > isp_dev->resmem_size) { v4l2_err(&isp_dev->v4l2_dev, "resmem size:%zu no enough for head:%d\n",