media: rockchip: isp: second frame first run for fast

Change-Id: Ia67acbcf97d2e93fbf688f4d63b7e8d92a15adff
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2022-09-30 17:08:33 +08:00
parent 02a071c6a4
commit 2209baff7f
4 changed files with 91 additions and 40 deletions

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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",