media: rockchip: isp: 2 readback for support multishot large resolution

Change-Id: Idffbb0836c9981cc8390881ef82e7040ca5c1f05
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2022-07-05 11:30:37 +08:00
committed by Tao Huang
parent b3260da5e9
commit a8b7cd32f2
13 changed files with 197 additions and 44 deletions

View File

@@ -1050,7 +1050,7 @@ static int mi_frame_start(struct rkisp_stream *stream, u32 mis)
rkisp_stream_config_rsz(stream, false);
stream->is_crop_upd = false;
}
/* update buf for mulit sensor at readback */
/* update buf for multi sensor at readback */
if (!mis && !stream->ispdev->hw_dev->is_single &&
!stream->curr_buf &&
!list_empty(&stream->buf_queue)) {

View File

@@ -402,7 +402,7 @@ static int rkisp_create_links(struct rkisp_device *dev)
return ret;
}
static int _set_pipeline_default_fmt(struct rkisp_device *dev)
static int _set_pipeline_default_fmt(struct rkisp_device *dev, bool is_init)
{
struct v4l2_subdev *isp;
struct v4l2_subdev_format fmt;
@@ -415,7 +415,8 @@ static int _set_pipeline_default_fmt(struct rkisp_device *dev)
if (dev->active_sensor) {
fmt = dev->active_sensor->fmt[0];
if (fmt.format.code == dev->isp_sdev.in_frm.code &&
if (!is_init &&
fmt.format.code == dev->isp_sdev.in_frm.code &&
fmt.format.width == dev->isp_sdev.in_frm.width &&
fmt.format.height == dev->isp_sdev.in_frm.height)
return 0;
@@ -546,7 +547,7 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
dev->is_hw_link = true;
}
ret = _set_pipeline_default_fmt(dev);
ret = _set_pipeline_default_fmt(dev, true);
if (ret < 0)
goto unlock;
@@ -953,7 +954,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
/* power on to config default format from sensor */
if (isp_dev->isp_inp & (INP_CSI | INP_DVP | INP_LVDS | INP_CIF) &&
rkisp_update_sensor_info(isp_dev) >= 0)
_set_pipeline_default_fmt(isp_dev);
_set_pipeline_default_fmt(isp_dev, false);
isp_dev->cap_dev.wait_line = rkisp_wait_line;
isp_dev->cap_dev.wrap_line = rkisp_wrap_line;

View File

@@ -235,6 +235,7 @@ struct rkisp_device {
int rdbk_cnt_x2;
int rdbk_cnt_x3;
u32 rd_mode;
int sw_rd_cnt;
struct rkisp_rx_buf_pool pv_pool[RKISP_RX_BUF_POOL_MAX];

View File

@@ -905,6 +905,8 @@ static int rkisp_hw_probe(struct platform_device *pdev)
hw_dev->dev_link_num = 0;
hw_dev->cur_dev_id = 0;
hw_dev->mipi_dev_id = 0;
hw_dev->pre_dev_id = 0;
hw_dev->is_multi_overflow = false;
hw_dev->isp_ver = match_data->isp_ver;
hw_dev->is_unite = match_data->unite;
mutex_init(&hw_dev->dev_lock);
@@ -966,8 +968,9 @@ static int __maybe_unused rkisp_runtime_suspend(struct device *dev)
{
struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
hw_dev->is_single = true;
hw_dev->dev_link_num = 0;
hw_dev->is_single = true;
hw_dev->is_multi_overflow = false;
disable_sys_clk(hw_dev);
return pinctrl_pm_select_sleep_state(dev);
}

View File

@@ -65,6 +65,7 @@ struct rkisp_hw_dev {
int dev_num;
int dev_link_num;
int cur_dev_id;
int pre_dev_id;
int mipi_dev_id;
struct max_input max_in;
/* lock for multi dev */
@@ -97,6 +98,7 @@ struct rkisp_hw_dev {
bool is_buf_init;
bool is_shutdown;
bool is_unite;
bool is_multi_overflow;
};
int rkisp_register_irq(struct rkisp_hw_dev *dev);

View File

@@ -3806,6 +3806,16 @@ rkisp_params_check_bigmode_v21(struct rkisp_isp_params_vdev *params_vdev)
int i = 0, j = 0;
bool is_bigmode = false;
multi_overflow:
if (hw->is_multi_overflow) {
ispdev->multi_index = 0;
ispdev->multi_mode = 0;
bigmode_max_w = ISP21_AUTO_BIGMODE_WIDTH;
bigmode_max_size = ISP21_NOBIG_OVERFLOW_SIZE;
dev_warn(dev, "over virtual isp max resolution, force to 2 readback\n");
goto end;
}
switch (hw->dev_link_num) {
case 4:
bigmode_max_w = ISP21_VIR4_AUTO_BIGMODE_WIDTH;
@@ -3824,10 +3834,10 @@ rkisp_params_check_bigmode_v21(struct rkisp_isp_params_vdev *params_vdev)
if (hw->isp_size[i].w <= ISP21_VIR4_MAX_WIDTH &&
hw->isp_size[i].size <= ISP21_VIR4_MAX_SIZE)
continue;
dev_err(dev, "four virtual isp max:1920x1080, isp%d:%dx%d\n",
i, hw->isp_size[i].w, hw->isp_size[i].h);
is_bigmode = true;
break;
dev_warn(dev, "isp%d %dx%d over four vir isp max:1920x1080\n",
i, hw->isp_size[i].w, hw->isp_size[i].h);
hw->is_multi_overflow = true;
goto multi_overflow;
}
break;
case 3:
@@ -3865,7 +3875,10 @@ rkisp_params_check_bigmode_v21(struct rkisp_isp_params_vdev *params_vdev)
is_bigmode = true;
if (k != 1 ||
(hw->isp_size[idx1[0]].size > ISP21_VIR4_MAX_SIZE * 2)) {
dev_err(dev, "three virtual isp max:1920x1080\n");
dev_warn(dev, "isp%d %dx%d over three vir isp max:1920x1080\n",
idx1[0], hw->isp_size[idx1[0]].h, hw->isp_size[idx1[0]].w);
hw->is_multi_overflow = true;
goto multi_overflow;
} else {
if (idx1[0] == ispdev->dev_id) {
ispdev->multi_mode = 0;
@@ -3920,7 +3933,10 @@ rkisp_params_check_bigmode_v21(struct rkisp_isp_params_vdev *params_vdev)
is_bigmode = true;
if (k == 2 || j ||
hw->isp_size[idx1[k - 1]].size > ISP21_VIR4_MAX_SIZE * 3) {
dev_err(dev, "two virtual isp max:3840x2160\n");
dev_warn(dev, "isp%d %dx%d over two vir isp max:3840x2160\n",
idx1[k - 1], hw->isp_size[idx1[k - 1]].w, hw->isp_size[idx1[k - 1]].h);
hw->is_multi_overflow = true;
goto multi_overflow;
} else {
if (idx1[0] == ispdev->dev_id) {
ispdev->multi_mode = 0;
@@ -3945,6 +3961,7 @@ rkisp_params_check_bigmode_v21(struct rkisp_isp_params_vdev *params_vdev)
break;
}
end:
if (!is_bigmode &&
(width > bigmode_max_w || size > bigmode_max_size))
is_bigmode = true;

View File

@@ -4190,6 +4190,16 @@ rkisp_params_check_bigmode_v32(struct rkisp_isp_params_vdev *params_vdev)
int i = 0, j = 0;
bool is_bigmode = false;
multi_overflow:
if (hw->is_multi_overflow) {
ispdev->multi_index = 0;
ispdev->multi_mode = 0;
bigmode_max_w = ISP32_AUTO_BIGMODE_WIDTH;
bigmode_max_size = ISP32_NOBIG_OVERFLOW_SIZE;
dev_warn(dev, "over virtual isp max resolution, force to 2 readback\n");
goto end;
}
switch (hw->dev_link_num) {
case 4:
bigmode_max_w = ISP32_VIR4_AUTO_BIGMODE_WIDTH;
@@ -4208,9 +4218,10 @@ rkisp_params_check_bigmode_v32(struct rkisp_isp_params_vdev *params_vdev)
if (hw->isp_size[i].w <= ISP32_VIR4_MAX_WIDTH &&
hw->isp_size[i].size <= ISP32_VIR4_MAX_SIZE)
continue;
dev_err(dev, "four virtual isp max:1280x800\n");
is_bigmode = true;
break;
dev_warn(dev, "isp%d %dx%d over four vir isp max:1280x800\n",
i, hw->isp_size[i].w, hw->isp_size[i].h);
hw->is_multi_overflow = true;
goto multi_overflow;
}
break;
case 3:
@@ -4248,7 +4259,10 @@ rkisp_params_check_bigmode_v32(struct rkisp_isp_params_vdev *params_vdev)
is_bigmode = true;
if (k != 1 ||
(hw->isp_size[idx1[0]].size > ISP32_VIR4_MAX_SIZE * 2)) {
dev_err(dev, "three virtual isp max:1280x800\n");
dev_warn(dev, "isp%d %dx%d over three vir isp max:1280x800\n",
idx1[0], hw->isp_size[idx1[0]].w, hw->isp_size[idx1[0]].h);
hw->is_multi_overflow = true;
goto multi_overflow;
} else {
if (idx1[0] == ispdev->dev_id) {
ispdev->multi_mode = 0;
@@ -4303,7 +4317,10 @@ rkisp_params_check_bigmode_v32(struct rkisp_isp_params_vdev *params_vdev)
is_bigmode = true;
if (k == 2 || j ||
hw->isp_size[idx1[k - 1]].size > ISP32_VIR4_MAX_SIZE * 3) {
dev_err(dev, "two virtual isp max:1920x1080\n");
dev_warn(dev, "isp%d %dx%d over two vir isp max:1920x1080\n",
idx1[k - 1], hw->isp_size[idx1[k - 1]].w, hw->isp_size[idx1[k - 1]].h);
hw->is_multi_overflow = true;
goto multi_overflow;
} else {
if (idx1[0] == ispdev->dev_id) {
ispdev->multi_mode = 0;
@@ -4328,6 +4345,7 @@ rkisp_params_check_bigmode_v32(struct rkisp_isp_params_vdev *params_vdev)
break;
}
end:
if (!is_bigmode &&
(width > bigmode_max_w || size > bigmode_max_size))
is_bigmode = true;
@@ -4808,8 +4826,9 @@ rkisp_params_clear_fstflg(struct rkisp_isp_params_vdev *params_vdev)
value &= (ISP3X_YNR_FST_FRAME | ISP3X_ADRC_FST_FRAME |
ISP3X_DHAZ_FST_FRAME | ISP3X_CNR_FST_FRAME |
ISP3X_RAW3D_FST_FRAME);
if (value)
if (value) {
isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value);
}
}
static void
@@ -4839,7 +4858,7 @@ rkisp_params_isr_v32(struct rkisp_isp_params_vdev *params_vdev,
}
}
if (isp_mis & CIF_ISP_FRAME)
if ((isp_mis & CIF_ISP_FRAME) && !params_vdev->rdbk_times)
rkisp_params_clear_fstflg(params_vdev);
if ((isp_mis & CIF_ISP_FRAME) && !IS_HDR_RDBK(dev->rd_mode))

View File

@@ -4223,6 +4223,16 @@ rkisp_params_check_bigmode_v3x(struct rkisp_isp_params_vdev *params_vdev)
int i = 0, j = 0;
bool is_bigmode = false;
multi_overflow:
if (hw->is_multi_overflow) {
ispdev->multi_index = 0;
ispdev->multi_mode = 0;
bigmode_max_w = ISP3X_AUTO_BIGMODE_WIDTH;
bigmode_max_size = ISP3X_NOBIG_OVERFLOW_SIZE;
dev_warn(dev, "over virtual isp max resolution, force to 2 readback\n");
goto end;
}
switch (hw->dev_link_num) {
case 4:
bigmode_max_w = ISP3X_VIR4_AUTO_BIGMODE_WIDTH;
@@ -4241,10 +4251,11 @@ rkisp_params_check_bigmode_v3x(struct rkisp_isp_params_vdev *params_vdev)
if (hw->isp_size[i].w <= ISP3X_VIR4_MAX_WIDTH &&
hw->isp_size[i].size <= ISP3X_VIR4_MAX_SIZE)
continue;
dev_err(dev, "four virtual isp max:%dx1536\n",
hw->is_unite ? (2560 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 2560);
is_bigmode = true;
break;
dev_warn(dev, "isp%d %dx%d over four vir isp max:%dx1536\n",
i, hw->isp_size[i].w, hw->isp_size[i].h,
hw->is_unite ? (2560 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 2560);
hw->is_multi_overflow = true;
goto multi_overflow;
}
break;
case 3:
@@ -4282,8 +4293,11 @@ rkisp_params_check_bigmode_v3x(struct rkisp_isp_params_vdev *params_vdev)
is_bigmode = true;
if (k != 1 ||
(hw->isp_size[idx1[0]].size > ISP3X_VIR4_MAX_SIZE * 2)) {
dev_err(dev, "three virtual isp max:%dx1536\n",
hw->is_unite ? (2560 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 2560);
dev_warn(dev, "isp%d %dx%d over three vir isp max:%dx1536\n",
idx1[0], hw->isp_size[idx1[0]].w, hw->isp_size[idx1[0]].h,
hw->is_unite ? (2560 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 2560);
hw->is_multi_overflow = true;
goto multi_overflow;
} else {
if (idx1[0] == ispdev->dev_id) {
ispdev->multi_mode = 0;
@@ -4338,8 +4352,11 @@ rkisp_params_check_bigmode_v3x(struct rkisp_isp_params_vdev *params_vdev)
is_bigmode = true;
if (k == 2 || j ||
hw->isp_size[idx1[k - 1]].size > ISP3X_VIR4_MAX_SIZE * 3) {
dev_err(dev, "two virtual isp max:%dx2160\n",
hw->is_unite ? (3840 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 3840);
dev_warn(dev, "isp%d %dx%d over two vir isp max:%dx2160\n",
idx1[k - 1], hw->isp_size[idx1[k - 1]].w, hw->isp_size[idx1[k - 1]].h,
hw->is_unite ? (3840 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 3840);
hw->is_multi_overflow = true;
goto multi_overflow;
} else {
if (idx1[0] == ispdev->dev_id) {
ispdev->multi_mode = 0;
@@ -4366,6 +4383,7 @@ rkisp_params_check_bigmode_v3x(struct rkisp_isp_params_vdev *params_vdev)
break;
}
end:
if (!is_bigmode &&
(width > bigmode_max_w || size > bigmode_max_size))
is_bigmode = true;

View File

@@ -203,6 +203,7 @@ rkisp_stats_vb2_start_streaming(struct vb2_queue *queue,
{
struct rkisp_isp_stats_vdev *stats_vdev = queue->drv_priv;
stats_vdev->rdbk_drop = false;
stats_vdev->cur_buf = NULL;
stats_vdev->ops->rdbk_enable(stats_vdev, false);
stats_vdev->streamon = true;

View File

@@ -65,6 +65,7 @@ struct rkisp_isp_stats_vdev {
u32 wr_buf_idx;
bool rd_stats_from_ddr;
bool rdbk_drop;
bool rdbk_mode;
u32 isp_rdbk;
u32 isp3a_rdbk;

View File

@@ -512,15 +512,19 @@ rkisp_stats_send_meas_v32(struct rkisp_isp_stats_vdev *stats_vdev,
u32 size = sizeof(struct rkisp32_isp_stat_buffer);
int ret = 0;
/* config buf for next frame */
stats_vdev->cur_buf = NULL;
if (stats_vdev->nxt_buf) {
stats_vdev->cur_buf = stats_vdev->nxt_buf;
stats_vdev->nxt_buf = NULL;
}
rkisp_stats_update_buf(stats_vdev);
if (!stats_vdev->rdbk_drop) {
/* config buf for next frame */
stats_vdev->cur_buf = NULL;
if (stats_vdev->nxt_buf) {
stats_vdev->cur_buf = stats_vdev->nxt_buf;
stats_vdev->nxt_buf = NULL;
}
rkisp_stats_update_buf(stats_vdev);
cur_frame_id = meas_work->frame_id;
cur_frame_id = meas_work->frame_id;
} else {
cur_buf = NULL;
}
if (cur_buf) {
cur_stat_buf =

View File

@@ -859,7 +859,7 @@ static int isp_show(struct seq_file *p, void *v)
if (!(dev->isp_state & ISP_START))
return 0;
if (IS_HDR_RDBK(dev->hdr.op_mode))
if (IS_HDR_RDBK(dev->hdr.op_mode)) {
seq_printf(p, "%-10s mode:frame%d (frame:%d rate:%dms %s time:%dms frameloss:%d) cnt(total:%d X1:%d X2:%d X3:%d)\n",
"Isp Read",
dev->rd_mode - 3,
@@ -872,14 +872,17 @@ static int isp_show(struct seq_file *p, void *v)
dev->rdbk_cnt_x1,
dev->rdbk_cnt_x2,
dev->rdbk_cnt_x3);
else
seq_printf(p, "\t hw link:%d idle:%d vir(mode:%d index:%d)\n",
dev->hw_dev->dev_link_num, dev->hw_dev->is_idle,
dev->multi_mode, dev->multi_index);
} else {
seq_printf(p, "%-10s frame:%d %s time:%dms v-blank:%dus\n",
"Isp online",
sdev->dbg.id,
(dev->isp_state & ISP_FRAME_END) ? "idle" : "working",
sdev->dbg.interval / 1000 / 1000,
sdev->dbg.delay / 1000);
}
if (dev->br_dev.en)
seq_printf(p, "%-10s rkispp%d Format:%s%s Size:%dx%d (frame:%d rate:%dms frameloss:%d)\n",
"Output",
@@ -940,7 +943,7 @@ static int isp_show(struct seq_file *p, void *v)
break;
}
seq_printf(p, "%-10s %s Cnt:%d\n",
seq_printf(p, "%-10s %s Cnt:%d\n\n",
"Monitor",
dev->hw_dev->monitor.is_en ? "ON" : "OFF",
dev->hw_dev->monitor.retry);

View File

@@ -501,6 +501,49 @@ u32 rkisp_mbus_pixelcode_to_v4l2(u32 pixelcode)
return pixelformat;
}
static void rkisp_multi_overflow_hdl(struct rkisp_device *dev, bool on)
{
struct rkisp_hw_dev *hw = dev->hw_dev;
if (on) {
/* enable bay3d and mi */
rkisp_update_regs(dev, ISP3X_MI_WR_CTRL, ISP3X_MI_WR_CTRL);
rkisp_update_regs(dev, ISP3X_ISP_CTRL1, ISP3X_ISP_CTRL1);
if (dev->isp_ver == ISP_V21) {
rkisp_update_regs(dev, ISP21_BAY3D_CTRL, ISP21_BAY3D_CTRL);
} else if (dev->isp_ver == ISP_V30) {
rkisp_update_regs(dev, ISP3X_MPFBC_CTRL, ISP3X_MPFBC_CTRL);
rkisp_update_regs(dev, ISP3X_MI_BP_WR_CTRL, ISP3X_MI_BP_WR_CTRL);
rkisp_update_regs(dev, ISP3X_BAY3D_CTRL, ISP3X_BAY3D_CTRL);
} else if (dev->isp_ver == ISP_V32) {
rkisp_update_regs(dev, ISP3X_MI_BP_WR_CTRL, ISP3X_MI_BP_WR_CTRL);
rkisp_update_regs(dev, ISP32_MI_BPDS_WR_CTRL, ISP32_MI_BPDS_WR_CTRL);
rkisp_update_regs(dev, ISP32_MI_MPDS_WR_CTRL, ISP32_MI_MPDS_WR_CTRL);
rkisp_update_regs(dev, ISP3X_BAY3D_CTRL, ISP3X_BAY3D_CTRL);
}
} else {
/* disabled bay3d and mi */
writel(0, hw->base_addr + ISP3X_MI_WR_CTRL);
if (dev->isp_ver == ISP_V21) {
writel(0, hw->base_addr + ISP21_BAY3D_CTRL);
} else if (dev->isp_ver == ISP_V30) {
writel(0, hw->base_addr + ISP3X_MPFBC_CTRL);
writel(0, hw->base_addr + ISP3X_MI_BP_WR_CTRL);
writel(0, hw->base_addr + ISP3X_BAY3D_CTRL);
if (hw->is_unite) {
writel(0, hw->base_next_addr + ISP3X_MPFBC_CTRL);
writel(0, hw->base_next_addr + ISP3X_MI_BP_WR_CTRL);
writel(0, hw->base_next_addr + ISP3X_BAY3D_CTRL);
}
} else if (dev->isp_ver == ISP_V32) {
writel(0, hw->base_addr + ISP3X_MI_BP_WR_CTRL);
writel(0, hw->base_addr + ISP32_MI_BPDS_WR_CTRL);
writel(0, hw->base_addr + ISP32_MI_MPDS_WR_CTRL);
writel(0, hw->base_addr + ISP3X_BAY3D_CTRL);
}
}
rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true, hw->is_unite);
}
/*
* for hdr read back mode, rawrd read back data
@@ -509,6 +552,7 @@ u32 rkisp_mbus_pixelcode_to_v4l2(u32 pixelcode)
void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, bool is_try)
{
struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev;
struct rkisp_isp_stats_vdev *stats_vdev = &dev->stats_vdev;
struct rkisp_hw_dev *hw = dev->hw_dev;
u32 val, cur_frame_id, tmp, rd_mode;
u64 iq_feature = hw->iq_feature;
@@ -518,6 +562,9 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
hw->cur_dev_id = dev->dev_id;
rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true);
if (hw->is_multi_overflow && is_try)
goto run_next;
val = 0;
if (mode & (T_START_X1 | T_START_C)) {
rd_mode = HDR_RDBK_FRAME1;
@@ -638,7 +685,7 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
dma2frm = 2;
if (dma2frm == 2)
dev->rdbk_cnt_x3++;
else if (dma2frm == 1)
else if (dma2frm == 1 || dev->sw_rd_cnt)
dev->rdbk_cnt_x2++;
else
dev->rdbk_cnt_x1++;
@@ -647,6 +694,20 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
rkisp_params_cfgsram(params_vdev);
params_vdev->rdbk_times = dma2frm + 1;
run_next:
if (hw->is_multi_overflow) {
stats_vdev->rdbk_drop = false;
if (dev->sw_rd_cnt) {
rkisp_multi_overflow_hdl(dev, false);
params_vdev->rdbk_times += dev->sw_rd_cnt;
stats_vdev->rdbk_drop = true;
is_upd = true;
} else if (is_try) {
rkisp_multi_overflow_hdl(dev, true);
is_upd = true;
}
}
/* read 3d lut at frame end */
if (hw->is_single && is_upd &&
rkisp_read_reg_cache(dev, ISP_3DLUT_UPDATE) & 0x1) {
@@ -668,7 +729,7 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
"readback frame:%d time:%d 0x%x\n",
cur_frame_id, dma2frm + 1, val);
if (!dma2frm)
if (!dma2frm && !dev->sw_rd_cnt)
rkisp_bridge_update_mi(dev, 0);
if (!hw->is_shutdown)
rkisp_unite_write(dev, CSI2RX_CTRL0, val, true, hw->is_unite);
@@ -683,10 +744,20 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
int i, times = -1, max = 0, id = 0;
int len[DEV_MAX] = { 0 };
u32 mode = 0;
bool is_try = false;
spin_lock_irqsave(&hw->rdbk_lock, lock_flags);
if (cmd == T_CMD_END)
if (cmd == T_CMD_END) {
if (dev->sw_rd_cnt) {
dev->sw_rd_cnt--;
isp = dev;
is_try = true;
times = 0;
goto end;
}
hw->is_idle = true;
hw->pre_dev_id = dev->dev_id;
}
if (hw->is_shutdown)
hw->is_idle = false;
if (!hw->is_idle)
@@ -724,11 +795,16 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
times = t.times;
hw->cur_dev_id = id;
hw->is_idle = false;
isp->sw_rd_cnt = 0;
if (hw->is_multi_overflow && (hw->pre_dev_id != id)) {
isp->sw_rd_cnt = 1;
times = 0;
}
}
end:
spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags);
if (times >= 0)
rkisp_trigger_read_back(isp, times, mode, false);
rkisp_trigger_read_back(isp, times, mode, is_try);
}
int rkisp_rdbk_trigger_event(struct rkisp_device *dev, u32 cmd, void *arg)
@@ -783,6 +859,11 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
{
u32 val = 0;
if (dev->hw_dev->is_multi_overflow &&
dev->sw_rd_cnt &&
irq & ISP_FRAME_END)
goto end;
dev->irq_ends |= (irq & dev->irq_ends_mask);
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
"%s irq:0x%x ends:0x%x mask:0x%x\n",
@@ -813,7 +894,6 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
}
val = 0;
dev->irq_ends = 0;
switch (dev->rd_mode) {
case HDR_RDBK_FRAME3://for rd1 rd0 rd2
val |= RAW1_RD_FRAME;
@@ -826,6 +906,8 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
/* FALLTHROUGH */
}
rkisp2_rawrd_isr(val, dev);
end:
dev->irq_ends = 0;
if (dev->dmarx_dev.trigger == T_MANUAL)
tasklet_schedule(&dev->rdbk_tasklet);
}
@@ -1898,6 +1980,7 @@ static int rkisp_isp_stop(struct rkisp_device *dev)
end:
dev->irq_ends_mask = 0;
dev->hdr.op_mode = 0;
dev->sw_rd_cnt = 0;
rkisp_set_state(&dev->isp_state, ISP_STOP);
if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21 ||