From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/media/platform/rockchip/isp/rkisp.c | 721 +++++++++++++++++++++++++++++++------------------------
1 files changed, 405 insertions(+), 316 deletions(-)
diff --git a/kernel/drivers/media/platform/rockchip/isp/rkisp.c b/kernel/drivers/media/platform/rockchip/isp/rkisp.c
index 1d69fab..ac40adf 100644
--- a/kernel/drivers/media/platform/rockchip/isp/rkisp.c
+++ b/kernel/drivers/media/platform/rockchip/isp/rkisp.c
@@ -87,12 +87,6 @@
static void rkisp_config_cmsk(struct rkisp_device *dev);
-struct backup_reg {
- const u32 base;
- const u32 shd;
- u32 val;
-};
-
static inline struct rkisp_device *sd_to_isp_dev(struct v4l2_subdev *sd)
{
return container_of(sd->v4l2_dev, struct rkisp_device, v4l2_dev);
@@ -213,17 +207,16 @@
max_h = CIF_ISP_INPUT_H_MAX_V21;
break;
case ISP_V30:
- if (dev->hw_dev->is_unite) {
- max_w = CIF_ISP_INPUT_W_MAX_V30_UNITE;
- max_h = CIF_ISP_INPUT_H_MAX_V30_UNITE;
- } else {
- max_w = CIF_ISP_INPUT_W_MAX_V30;
- max_h = CIF_ISP_INPUT_H_MAX_V30;
- }
+ max_w = dev->hw_dev->unite ?
+ CIF_ISP_INPUT_W_MAX_V30_UNITE : CIF_ISP_INPUT_W_MAX_V30;
+ max_h = dev->hw_dev->unite ?
+ CIF_ISP_INPUT_H_MAX_V30_UNITE : CIF_ISP_INPUT_H_MAX_V30;
break;
case ISP_V32:
- max_w = CIF_ISP_INPUT_W_MAX_V32;
- max_h = CIF_ISP_INPUT_H_MAX_V32;
+ max_w = dev->hw_dev->unite ?
+ CIF_ISP_INPUT_W_MAX_V32_UNITE : CIF_ISP_INPUT_W_MAX_V32;
+ max_h = dev->hw_dev->unite ?
+ CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32;
break;
case ISP_V32_L:
max_w = CIF_ISP_INPUT_W_MAX_V32_L;
@@ -518,7 +511,9 @@
do_div(data_rate, 1000 * 1000);
/* increase margin: 25% * num */
data_rate += (data_rate >> 2) * num;
-
+ /* one frame two-run, data double */
+ if (hw->is_multi_overflow && num > 1)
+ data_rate *= 2;
/* compare with isp clock adjustment table */
for (i = 0; i < hw->num_clk_rate_tbl; i++)
if (data_rate <= hw->clk_rate_tbl[i].clk_rate)
@@ -528,7 +523,7 @@
/* set isp clock rate */
rkisp_set_clk_rate(hw->clks[0], hw->clk_rate_tbl[i].clk_rate * 1000000UL);
- if (hw->is_unite)
+ if (hw->unite == ISP_UNITE_TWO)
rkisp_set_clk_rate(hw->clks[5], hw->clk_rate_tbl[i].clk_rate * 1000000UL);
/* aclk equal to core clk */
if (dev->isp_ver == ISP_V32)
@@ -541,48 +536,39 @@
struct rkisp_hw_dev *hw = dev->hw_dev;
if (on) {
- /* enable bay3d and mi */
+ /* enable 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) {
+ 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);
rkisp_update_regs(dev, ISP3X_SWS_CFG, ISP3X_SWS_CFG);
} 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. rv1106 sdmmc workaround, 3a_wr no close */
+ /* disabled mi. rv1106 sdmmc workaround, 3a_wr no close */
writel(CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_CTRL_INIT_BASE_EN,
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) {
+ 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);
writel(0xc, hw->base_addr + ISP3X_SWS_CFG);
- if (hw->is_unite) {
+ if (hw->unite == ISP_UNITE_TWO) {
writel(0, hw->base_next_addr + ISP3X_MI_WR_CTRL);
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);
writel(0xc, hw->base_next_addr + ISP3X_SWS_CFG);
}
} 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);
+ rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true);
}
/*
@@ -602,7 +588,8 @@
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)
+ /* isp process the same frame */
+ if (is_try)
goto run_next;
val = 0;
@@ -632,13 +619,12 @@
}
if (rd_mode != dev->rd_mode) {
- rkisp_unite_set_bits(dev, ISP_HDRMGE_BASE, ISP_HDRMGE_MODE_MASK,
- val, false, hw->is_unite);
+ rkisp_unite_set_bits(dev, ISP_HDRMGE_BASE, ISP_HDRMGE_MODE_MASK, val, false);
dev->skip_frame = 2;
is_upd = true;
}
- if (dev->isp_ver == ISP_V20 && dev->dmarx_dev.trigger == T_MANUAL && !is_try) {
+ if (dev->isp_ver == ISP_V20 && dev->dmarx_dev.trigger == T_MANUAL) {
if (dev->rd_mode != rd_mode && dev->br_dev.en) {
tmp = dev->isp_sdev.in_crop.height;
val = rkisp_read(dev, CIF_DUAL_CROP_CTRL, false);
@@ -659,12 +645,15 @@
}
dev->rd_mode = rd_mode;
- rkisp_params_first_cfg(&dev->params_vdev, &dev->isp_sdev.in_fmt,
- dev->isp_sdev.quantization);
- rkisp_params_cfg(params_vdev, cur_frame_id);
- rkisp_config_cmsk(dev);
- rkisp_stream_frame_start(dev, 0);
- if (!hw->is_single && !is_try) {
+ if (hw->unite != ISP_UNITE_ONE || dev->unite_index == ISP_UNITE_LEFT) {
+ rkisp_params_first_cfg(&dev->params_vdev, &dev->isp_sdev.in_fmt,
+ dev->isp_sdev.quantization);
+ rkisp_params_cfg(params_vdev, cur_frame_id);
+ rkisp_config_cmsk(dev);
+ rkisp_stream_frame_start(dev, 0);
+ }
+
+ if (!hw->is_single) {
/* multi sensor need to reset isp resize mode if scale up */
val = 0;
if (rkisp_read(dev, ISP3X_MAIN_RESIZE_CTRL, true) & 0xf0)
@@ -700,7 +689,7 @@
} else {
if (dev->isp_ver == ISP_V32_L)
rkisp_write(dev, ISP32_SELF_SCALE_UPDATE, ISP32_SCALE_FORCE_UPD, true);
- rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true, hw->is_unite);
+ rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true);
}
/* sensor mode & index */
if (dev->isp_ver >= ISP_V21) {
@@ -711,7 +700,7 @@
else
val |= ISP21_SENSOR_MODE(dev->multi_mode);
writel(val, hw->base_addr + ISP_ACQ_H_OFFS);
- if (hw->is_unite)
+ if (hw->unite == ISP_UNITE_TWO)
writel(val, hw->base_next_addr + ISP_ACQ_H_OFFS);
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
"sensor mode:%d index:%d | 0x%x\n",
@@ -731,36 +720,98 @@
else
dev->rdbk_cnt_x1++;
dev->rdbk_cnt++;
-
- rkisp_params_cfgsram(params_vdev);
- params_vdev->rdbk_times = dma2frm + 1;
+ if (dev->isp_ver == ISP_V20)
+ params_vdev->rdbk_times = dma2frm + 1;
run_next:
- if (hw->is_multi_overflow && !dev->is_first_double) {
- 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_params_cfgsram(params_vdev, true);
+ stats_vdev->rdbk_drop = false;
+ if (dev->is_frame_double) {
+ is_upd = true;
+ if (is_try) {
+ /* the frame second running to on mi */
rkisp_multi_overflow_hdl(dev, true);
- is_upd = true;
+ rkisp_update_regs(dev, ISP_LDCH_BASE, ISP_LDCH_BASE);
+
+ val = ISP3X_YNR_FST_FRAME | ISP3X_DHAZ_FST_FRAME | ISP3X_CNR_FST_FRAME;
+ if (dev->isp_ver == ISP_V32)
+ val |= ISP32_SHP_FST_FRAME;
+ else
+ val |= ISP3X_CNR_FST_FRAME;
+ rkisp_unite_clear_bits(dev, ISP3X_ISP_CTRL1, val, false);
+ val = rkisp_read_reg_cache(dev, ISP3X_DRC_IIRWG_GAIN);
+ writel(val, hw->base_addr + ISP3X_DRC_IIRWG_GAIN);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(val, hw->base_next_addr + ISP3X_DRC_IIRWG_GAIN);
+ val = rkisp_read_reg_cache(dev, ISP3X_DRC_EXPLRATIO);
+ writel(val, hw->base_addr + ISP3X_DRC_EXPLRATIO);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(val, hw->base_next_addr + ISP3X_DRC_EXPLRATIO);
+ val = rkisp_read_reg_cache(dev, ISP3X_YNR_GLOBAL_CTRL);
+ writel(val, hw->base_addr + ISP3X_YNR_GLOBAL_CTRL);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(val, hw->base_next_addr + ISP3X_YNR_GLOBAL_CTRL);
+ if (dev->isp_ver == ISP_V21 || dev->isp_ver == ISP_V30) {
+ val = rkisp_read_reg_cache(dev, ISP3X_CNR_CTRL);
+ writel(val, hw->base_addr + ISP3X_CNR_CTRL);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(val, hw->base_next_addr + ISP3X_CNR_CTRL);
+ }
+ } else {
+ /* the frame first running to off mi to save bandwidth */
+ rkisp_multi_overflow_hdl(dev, false);
+
+ /* FST_FRAME no to read sram thumb */
+ val = ISP3X_YNR_FST_FRAME | ISP3X_DHAZ_FST_FRAME;
+ if (dev->isp_ver == ISP_V32)
+ val |= ISP32_SHP_FST_FRAME;
+ else
+ val |= ISP3X_CNR_FST_FRAME;
+ rkisp_unite_set_bits(dev, ISP3X_ISP_CTRL1, 0, val, false);
+ /* ADRC low iir thumb weight for first sensor switch */
+ val = rkisp_read_reg_cache(dev, ISP3X_DRC_IIRWG_GAIN);
+ val &= ~ISP3X_DRC_IIR_WEIGHT_MASK;
+ writel(val, hw->base_addr + ISP3X_DRC_IIRWG_GAIN);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(val, hw->base_next_addr + ISP3X_DRC_IIRWG_GAIN);
+ /* ADRC iir5x5 and cur3x3 weight */
+ val = rkisp_read_reg_cache(dev, ISP3X_DRC_EXPLRATIO);
+ val &= ~ISP3X_DRC_WEIPRE_FRAME_MASK;
+ writel(val, hw->base_addr + ISP3X_DRC_EXPLRATIO);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(val, hw->base_next_addr + ISP3X_DRC_EXPLRATIO);
+ /* YNR_THUMB_MIX_CUR_EN for thumb read addr to 0 */
+ val = rkisp_read_reg_cache(dev, ISP3X_YNR_GLOBAL_CTRL);
+ val |= ISP3X_YNR_THUMB_MIX_CUR_EN;
+ writel(val, hw->base_addr + ISP3X_YNR_GLOBAL_CTRL);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(val, hw->base_next_addr + ISP3X_YNR_GLOBAL_CTRL);
+ if (dev->isp_ver == ISP_V21 || dev->isp_ver == ISP_V30) {
+ /* CNR_THUMB_MIX_CUR_EN for thumb read addr to 0 */
+ val = rkisp_read_reg_cache(dev, ISP3X_CNR_CTRL);
+ val |= ISP3X_CNR_THUMB_MIX_CUR_EN;
+ writel(val, hw->base_addr + ISP3X_CNR_CTRL);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(val, hw->base_next_addr + ISP3X_CNR_CTRL);
+ }
+ stats_vdev->rdbk_drop = true;
}
}
- /* read 3d lut at frame end */
+ /* disable isp force update to read 3dlut
+ * 3dlut auto update at frame end for single sensor
+ */
if (hw->is_single && is_upd &&
rkisp_read_reg_cache(dev, ISP_3DLUT_UPDATE) & 0x1) {
- rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 0, true, hw->is_unite);
+ rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 0, true);
is_3dlut_upd = true;
}
if (is_upd) {
val = rkisp_read(dev, ISP_CTRL, false);
val |= CIF_ISP_CTRL_ISP_CFG_UPD;
- rkisp_unite_write(dev, ISP_CTRL, val, true, hw->is_unite);
+ rkisp_unite_write(dev, ISP_CTRL, val, true);
/* bayer pat after ISP_CFG_UPD for multi sensor to read lsc r/g/b table */
- rkisp_update_regs(dev, ISP_ACQ_PROP, ISP_ACQ_PROP);
+ rkisp_update_regs(dev, ISP3X_ISP_CTRL1, ISP3X_ISP_CTRL1);
/* fix ldch multi sensor case:
* ldch will pre-read data when en and isp force upd or frame end,
* udelay for ldch pre-read data.
@@ -771,12 +822,12 @@
udelay(50);
val &= ~(BIT(0) | BIT(31));
writel(val, hw->base_addr + ISP_LDCH_BASE);
- if (hw->is_unite)
+ if (hw->unite == ISP_UNITE_TWO)
writel(val, hw->base_next_addr + ISP_LDCH_BASE);
}
}
if (is_3dlut_upd)
- rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 1, true, hw->is_unite);
+ rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 1, true);
/* if output stream enable, wait it end */
val = rkisp_read(dev, CIF_MI_CTRL_SHD, true);
@@ -807,11 +858,13 @@
val &= ~SW_IBUF_OP_MODE(0xf);
tmp = SW_IBUF_OP_MODE(dev->rd_mode);
val |= tmp | SW_CSI2RX_EN | SW_DMA_2FRM_MODE(dma2frm);
+ if (dev->isp_ver > ISP_V20)
+ dma2frm = dev->sw_rd_cnt;
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
- "readback frame:%d time:%d 0x%x\n",
- cur_frame_id, dma2frm + 1, val);
+ "readback frame:%d time:%d 0x%x try:%d\n",
+ cur_frame_id, dma2frm + 1, val, is_try);
if (!hw->is_shutdown)
- rkisp_unite_write(dev, CSI2RX_CTRL0, val, true, hw->is_unite);
+ rkisp_unite_write(dev, CSI2RX_CTRL0, val, true);
}
static void rkisp_fast_switch_rx_buf(struct rkisp_device *dev, bool is_current)
@@ -819,6 +872,9 @@
struct rkisp_stream *stream;
struct rkisp_buffer *buf;
u32 i, val;
+
+ if (!dev->is_rtt_first)
+ return;
for (i = RKISP_STREAM_RAWRD0; i < RKISP_MAX_DMARX_STREAM; i++) {
stream = &dev->dmarx_dev.stream[i];
@@ -865,6 +921,12 @@
isp = dev;
is_try = true;
times = 0;
+ if (hw->unite == ISP_UNITE_ONE) {
+ if (dev->sw_rd_cnt < 2)
+ isp->unite_index = ISP_UNITE_RIGHT;
+ if (!hw->is_multi_overflow || (dev->sw_rd_cnt & 0x1))
+ is_try = false;
+ }
goto end;
}
hw->is_idle = true;
@@ -878,11 +940,16 @@
goto end;
if (!IS_HDR_RDBK(dev->rd_mode))
goto end;
+ if (dev->is_suspend) {
+ if (dev->suspend_sync)
+ complete(&dev->pm_cmpl);
+ goto end;
+ }
for (i = 0; i < hw->dev_num; i++) {
isp = hw->isp[i];
if (!isp ||
- (isp && !(isp->isp_state & ISP_START)))
+ (isp && (!(isp->isp_state & ISP_START) || isp->is_suspend)))
continue;
rkisp_rdbk_trigger_event(isp, T_CMD_LEN, &len[i]);
if (max < len[i]) {
@@ -892,7 +959,7 @@
}
/* wait 2 frame to start isp for fast */
- if (dev->is_pre_on && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq))
+ if (dev->is_rtt_first && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq))
goto end;
if (max) {
@@ -914,17 +981,42 @@
times = t.times;
hw->cur_dev_id = id;
hw->is_idle = false;
+ /* this frame will read count by isp */
isp->sw_rd_cnt = 0;
- if (hw->is_multi_overflow && (hw->pre_dev_id != id)) {
+ /* frame double for multi camera resolution out of hardware limit
+ * first for HW save this camera information, and second to output image
+ */
+ isp->is_frame_double = false;
+ if (hw->is_multi_overflow &&
+ (hw->unite == ISP_UNITE_ONE ||
+ (hw->pre_dev_id != -1 && hw->pre_dev_id != id))) {
+ isp->is_frame_double = true;
isp->sw_rd_cnt = 1;
times = 0;
}
- if (isp->is_pre_on && t.frame_id == 0) {
+ /* resolution out of hardware limit
+ * frame is vertically divided into left and right
+ */
+ isp->unite_index = ISP_UNITE_LEFT;
+ if (hw->unite == ISP_UNITE_ONE) {
+ isp->sw_rd_cnt *= 2;
+ isp->sw_rd_cnt += 1;
+ }
+ /* first frame handle twice for thunderboot
+ * first output stats to AIQ and wait new params to run second
+ */
+ if (isp->is_rtt_first && t.frame_id == 0) {
isp->is_first_double = true;
isp->skip_frame = 1;
- isp->sw_rd_cnt = 0;
+ if (hw->unite != ISP_UNITE_ONE) {
+ isp->sw_rd_cnt = 0;
+ isp->is_frame_double = false;
+ }
rkisp_fast_switch_rx_buf(isp, false);
+ } else {
+ isp->is_rtt_first = false;
}
+ isp->params_vdev.rdbk_times = isp->sw_rd_cnt + 1;
}
end:
spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags);
@@ -982,12 +1074,6 @@
{
u32 val = 0;
- if (dev->hw_dev->is_multi_overflow &&
- dev->sw_rd_cnt &&
- irq & ISP_FRAME_END &&
- !dev->is_first_double)
- 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",
@@ -1002,8 +1088,12 @@
!IS_HDR_RDBK(dev->rd_mode))
return;
+ if (dev->sw_rd_cnt)
+ goto end;
+
if (dev->is_first_double) {
rkisp_fast_switch_rx_buf(dev, true);
+ dev->is_rtt_first = false;
dev->skip_frame = 0;
dev->irq_ends = 0;
return;
@@ -1068,26 +1158,25 @@
{
struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop;
u32 width = out_crop->width, mult = 1;
- bool is_unite = dev->hw_dev->is_unite;
+ u32 unite = dev->hw_dev->unite;
/* isp2.0 no ism */
if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21 ||
dev->isp_ver == ISP_V32_L)
return;
- if (is_unite)
+ if (unite)
width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
- rkisp_unite_write(dev, CIF_ISP_IS_RECENTER, 0, false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_IS_MAX_DX, 0, false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_IS_MAX_DY, 0, false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_IS_DISPLACE, 0, false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_IS_H_OFFS, out_crop->left, false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_IS_V_OFFS, out_crop->top, false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_IS_H_SIZE, width, false, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_IS_RECENTER, 0, false);
+ rkisp_unite_write(dev, CIF_ISP_IS_MAX_DX, 0, false);
+ rkisp_unite_write(dev, CIF_ISP_IS_MAX_DY, 0, false);
+ rkisp_unite_write(dev, CIF_ISP_IS_DISPLACE, 0, false);
+ rkisp_unite_write(dev, CIF_ISP_IS_H_OFFS, out_crop->left, false);
+ rkisp_unite_write(dev, CIF_ISP_IS_V_OFFS, out_crop->top, false);
+ rkisp_unite_write(dev, CIF_ISP_IS_H_SIZE, width, false);
if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced)
mult = 2;
- rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height / mult,
- false, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height / mult, false);
if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32)
return;
@@ -1096,86 +1185,19 @@
rkisp_write(dev, CIF_ISP_IS_CTRL, 1, false);
}
-static int rkisp_reset_handle_v2x(struct rkisp_device *dev)
+static int rkisp_reset_handle(struct rkisp_device *dev)
{
- void __iomem *base = dev->base_addr;
- void *reg_buf = NULL;
- u32 *reg, *reg1, i;
- struct backup_reg backup[] = {
- {
- .base = MI_MP_WR_Y_BASE,
- .shd = MI_MP_WR_Y_BASE_SHD,
- }, {
- .base = MI_MP_WR_CB_BASE,
- .shd = MI_MP_WR_CB_BASE_SHD,
- }, {
- .base = MI_MP_WR_CR_BASE,
- .shd = MI_MP_WR_CR_BASE_SHD,
- }, {
- .base = MI_SP_WR_Y_BASE,
- .shd = MI_SP_WR_Y_BASE_SHD,
- }, {
- .base = MI_SP_WR_CB_BASE,
- .shd = MI_SP_WR_CB_BASE_AD_SHD,
- }, {
- .base = MI_SP_WR_CR_BASE,
- .shd = MI_SP_WR_CR_BASE_AD_SHD,
- }, {
- .base = MI_RAW0_WR_BASE,
- .shd = MI_RAW0_WR_BASE_SHD,
- }, {
- .base = MI_RAW1_WR_BASE,
- .shd = MI_RAW1_WR_BASE_SHD,
- }, {
- .base = MI_RAW2_WR_BASE,
- .shd = MI_RAW2_WR_BASE_SHD,
- }, {
- .base = MI_RAW3_WR_BASE,
- .shd = MI_RAW3_WR_BASE_SHD,
- }, {
- .base = MI_RAW0_RD_BASE,
- .shd = MI_RAW0_RD_BASE_SHD,
- }, {
- .base = MI_RAW1_RD_BASE,
- .shd = MI_RAW1_RD_BASE_SHD,
- }, {
- .base = MI_RAW2_RD_BASE,
- .shd = MI_RAW2_RD_BASE_SHD,
- }, {
- .base = MI_GAIN_WR_BASE,
- .shd = MI_GAIN_WR_BASE_SHD,
- }
- };
-
- reg_buf = kzalloc(RKISP_ISP_SW_REG_SIZE, GFP_KERNEL);
- if (!reg_buf)
- return -ENOMEM;
+ u32 val;
dev_info(dev->dev, "%s enter\n", __func__);
+ rkisp_hw_reg_save(dev->hw_dev);
- memcpy_fromio(reg_buf, base, RKISP_ISP_SW_REG_SIZE);
rkisp_soft_reset(dev->hw_dev, true);
- /* process special reg */
- reg = reg_buf + ISP_CTRL;
- *reg &= ~(CIF_ISP_CTRL_ISP_ENABLE |
- CIF_ISP_CTRL_ISP_INFORM_ENABLE |
- CIF_ISP_CTRL_ISP_CFG_UPD);
- reg = reg_buf + MI_WR_INIT;
- *reg = 0;
- reg = reg_buf + CSI2RX_CTRL0;
- *reg &= ~SW_CSI2RX_EN;
- /* skip mmu range */
- memcpy_toio(base, reg_buf, ISP21_MI_BAY3D_RD_BASE_SHD);
- memcpy_toio(base + CSI2RX_CTRL0, reg_buf + CSI2RX_CTRL0,
- RKISP_ISP_SW_REG_SIZE - CSI2RX_CTRL0);
- /* config shd_reg to base_reg */
- for (i = 0; i < ARRAY_SIZE(backup); i++) {
- reg = reg_buf + backup[i].base;
- reg1 = reg_buf + backup[i].shd;
- backup[i].val = *reg;
- writel(*reg1, base + backup[i].base);
- }
+ rkisp_hw_reg_restore(dev->hw_dev);
+
+ val = CIF_ISP_DATA_LOSS | CIF_ISP_PIC_SIZE_ERROR;
+ rkisp_unite_set_bits(dev, CIF_ISP_IMSC, 0, val, true);
/* clear state */
dev->isp_err_cnt = 0;
@@ -1183,40 +1205,12 @@
rkisp_set_state(&dev->isp_state, ISP_FRAME_END);
dev->hw_dev->monitor.state = ISP_FRAME_END;
- /* update module */
- reg = reg_buf + DUAL_CROP_CTRL;
- if (*reg & 0xf)
- writel(*reg | CIF_DUAL_CROP_CFG_UPD, base + DUAL_CROP_CTRL);
- reg = reg_buf + SELF_RESIZE_CTRL;
- if (*reg & 0xf)
- writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + SELF_RESIZE_CTRL);
- reg = reg_buf + MAIN_RESIZE_CTRL;
- if (*reg & 0xf)
- writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + MAIN_RESIZE_CTRL);
-
- /* update mi and isp, base_reg will update to shd_reg */
- force_cfg_update(dev);
- reg = reg_buf + ISP_CTRL;
- *reg |= CIF_ISP_CTRL_ISP_ENABLE |
- CIF_ISP_CTRL_ISP_INFORM_ENABLE |
- CIF_ISP_CTRL_ISP_CFG_UPD;
- writel(*reg, base + ISP_CTRL);
- udelay(50);
- /* config base_reg */
- for (i = 0; i < ARRAY_SIZE(backup); i++)
- writel(backup[i].val, base + backup[i].base);
- /* mpfbc base_reg = shd_reg, write is base but read is shd */
- if (dev->isp_ver == ISP_V20)
- writel(rkisp_read_reg_cache(dev, ISP_MPFBC_HEAD_PTR),
- base + ISP_MPFBC_HEAD_PTR);
- rkisp_set_bits(dev, CIF_ISP_IMSC, 0, CIF_ISP_DATA_LOSS | CIF_ISP_PIC_SIZE_ERROR, true);
if (IS_HDR_RDBK(dev->hdr.op_mode)) {
if (!dev->hw_dev->is_idle)
rkisp_trigger_read_back(dev, 1, 0, true);
else
rkisp_rdbk_trigger_event(dev, T_CMD_QUEUE, NULL);
}
- kfree(reg_buf);
dev_info(dev->dev, "%s exit\n", __func__);
return 0;
}
@@ -1230,11 +1224,6 @@
struct rkisp_pipeline *p;
int ret, i, j, timeout = 5, mipi_irq_cnt = 0;
- if (!monitor->reset_handle) {
- monitor->is_en = false;
- return;
- }
-
dev_info(hw->dev, "%s enter\n", __func__);
while (!(monitor->state & ISP_STOP) && monitor->is_en) {
ret = wait_for_completion_timeout(&monitor->cmpl,
@@ -1242,8 +1231,11 @@
/* isp stop to exit
* isp err to reset
* mipi err wait isp idle, then reset
+ * online vicap if isp err, notify vicap reset, then vicap notify isp reset
+ * by ioctl RKISP_VICAP_CMD_SET_STREAM
*/
if (monitor->state & ISP_STOP ||
+ monitor->state & ISP_CIF_RESET ||
(ret && !(monitor->state & ISP_ERROR)) ||
(!ret &&
monitor->state & ISP_FRAME_END &&
@@ -1292,10 +1284,22 @@
/* restart isp */
isp = hw->isp[hw->cur_dev_id];
- ret = monitor->reset_handle(isp);
- if (ret) {
- monitor->is_en = false;
- break;
+ if (!IS_HDR_RDBK(isp->hdr.op_mode) && isp->isp_ver >= ISP_V30) {
+ struct v4l2_subdev *remote = NULL;
+ struct v4l2_subdev *isp_subdev = NULL;
+
+ isp_subdev = &(isp->isp_sdev.sd);
+ remote = get_remote_sensor(isp_subdev);
+ v4l2_subdev_call(remote, core, ioctl,
+ RKISP_VICAP_CMD_SET_RESET, NULL);
+ monitor->state |= ISP_CIF_RESET;
+ continue;
+ } else {
+ ret = rkisp_reset_handle(isp);
+ if (ret) {
+ monitor->is_en = false;
+ break;
+ }
}
for (i = 0; i < hw->dev_num; i++) {
@@ -1329,9 +1333,6 @@
struct rkisp_monitor *monitor = &dev->hw_dev->monitor;
monitor->dev = dev->hw_dev;
- monitor->reset_handle = NULL;
- if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21)
- monitor->reset_handle = rkisp_reset_handle_v2x;
init_completion(&monitor->cmpl);
INIT_WORK(&monitor->work, rkisp_restart_monitor);
@@ -1389,20 +1390,18 @@
for (i = 0; i < 9; i++)
rkisp_unite_write(dev, CIF_ISP_CC_COEFF_0 + i * 4,
- *(coeff + i), false, dev->hw_dev->is_unite);
+ *(coeff + i), false);
val = rkisp_read_reg_cache(dev, CIF_ISP_CTRL);
if (dev->isp_sdev.quantization == V4L2_QUANTIZATION_FULL_RANGE)
rkisp_unite_write(dev, CIF_ISP_CTRL, val |
CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
- CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA,
- false, dev->hw_dev->is_unite);
+ CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, false);
else
rkisp_unite_write(dev, CIF_ISP_CTRL, val &
~(CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
- CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA),
- false, dev->hw_dev->is_unite);
+ CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA), false);
}
static void rkisp_config_cmsk_single(struct rkisp_device *dev,
@@ -1498,6 +1497,7 @@
left.win[0].win_en &= ~BIT(i);
left.win[1].win_en &= ~BIT(i);
left.win[2].win_en &= ~BIT(i);
+ right.win[i].h_offs = h_offs - w + RKMOUDLE_UNITE_EXTEND_PIXEL;
} else {
/* cmsk window at dual isp */
left.win[i].h_size = ALIGN(w - h_offs, 8);
@@ -1601,7 +1601,7 @@
cfg = dev->cmsk_cfg;
spin_unlock_irqrestore(&dev->cmsk_lock, lock_flags);
- if (!dev->hw_dev->is_unite)
+ if (!dev->hw_dev->unite)
rkisp_config_cmsk_single(dev, &cfg);
else
rkisp_config_cmsk_dual(dev, &cfg);
@@ -1616,7 +1616,7 @@
struct ispsd_out_fmt *out_fmt;
struct v4l2_rect *in_crop;
struct rkisp_sensor_info *sensor;
- bool is_unite = dev->hw_dev->is_unite;
+ bool is_unite = !!dev->hw_dev->unite;
u32 isp_ctrl = 0;
u32 irq_mask = 0;
u32 signal = 0;
@@ -1646,22 +1646,20 @@
in_fmt->mbus_code == MEDIA_BUS_FMT_Y10_1X10 ||
in_fmt->mbus_code == MEDIA_BUS_FMT_Y12_1X12) {
if (dev->isp_ver >= ISP_V20)
- rkisp_unite_write(dev, ISP_DEBAYER_CONTROL,
- 0, false, is_unite);
+ rkisp_unite_write(dev, ISP_DEBAYER_CONTROL, 0, false);
else
rkisp_write(dev, CIF_ISP_DEMOSAIC,
- CIF_ISP_DEMOSAIC_BYPASS |
- CIF_ISP_DEMOSAIC_TH(0xc), false);
+ CIF_ISP_DEMOSAIC_BYPASS |
+ CIF_ISP_DEMOSAIC_TH(0xc), false);
} else {
if (dev->isp_ver >= ISP_V20)
rkisp_unite_write(dev, ISP_DEBAYER_CONTROL,
SW_DEBAYER_EN |
SW_DEBAYER_FILTER_G_EN |
- SW_DEBAYER_FILTER_C_EN,
- false, is_unite);
+ SW_DEBAYER_FILTER_C_EN, false);
else
rkisp_write(dev, CIF_ISP_DEMOSAIC,
- CIF_ISP_DEMOSAIC_TH(0xc), false);
+ CIF_ISP_DEMOSAIC_TH(0xc), false);
}
if (sensor && sensor->mbus.type == V4L2_MBUS_BT656)
@@ -1714,38 +1712,31 @@
if (rkisp_read_reg_cache(dev, CIF_ISP_CTRL) & ISP32_MIR_ENABLE)
isp_ctrl |= ISP32_MIR_ENABLE;
- rkisp_unite_write(dev, CIF_ISP_CTRL, isp_ctrl, false, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_CTRL, isp_ctrl, false);
acq_prop |= signal | in_fmt->yuv_seq |
CIF_ISP_ACQ_PROP_BAYER_PAT(in_fmt->bayer_pat) |
CIF_ISP_ACQ_PROP_FIELD_SEL_ALL;
- rkisp_unite_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false);
+ rkisp_unite_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true);
if (is_unite)
width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
/* Acquisition Size */
- rkisp_unite_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left,
- false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top,
- false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_ACQ_H_SIZE, acq_mult * width,
- false, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left, false);
+ rkisp_unite_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top, false);
+ rkisp_unite_write(dev, CIF_ISP_ACQ_H_SIZE, acq_mult * width, false);
/* ISP Out Area differ with ACQ is only FIFO, so don't crop in this */
- rkisp_unite_write(dev, CIF_ISP_OUT_H_OFFS, 0, true, is_unite);
- rkisp_unite_write(dev, CIF_ISP_OUT_V_OFFS, 0, true, is_unite);
- rkisp_unite_write(dev, CIF_ISP_OUT_H_SIZE, width, false, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_OUT_H_OFFS, 0, true);
+ rkisp_unite_write(dev, CIF_ISP_OUT_V_OFFS, 0, true);
+ rkisp_unite_write(dev, CIF_ISP_OUT_H_SIZE, width, false);
if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) {
- rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2,
- false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2,
- false, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2, false);
+ rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2, false);
} else {
- rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line,
- false, is_unite);
- rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line,
- false, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line, false);
+ rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line, false);
}
/* interrupt mask */
@@ -1754,7 +1745,7 @@
irq_mask |= ISP2X_LSC_LUT_ERR;
if (dev->is_pre_on)
irq_mask |= CIF_ISP_FRAME_IN;
- rkisp_unite_write(dev, CIF_ISP_IMSC, irq_mask, true, is_unite);
+ rkisp_unite_write(dev, CIF_ISP_IMSC, irq_mask, true);
if ((dev->isp_ver == ISP_V20 ||
dev->isp_ver == ISP_V21) &&
@@ -1909,8 +1900,7 @@
if (dev->isp_ver == ISP_V32)
dpcl |= BIT(0);
- rkisp_unite_set_bits(dev, CIF_VI_DPCL, 0, dpcl, true,
- dev->hw_dev->is_unite);
+ rkisp_unite_set_bits(dev, CIF_VI_DPCL, 0, dpcl, true);
return ret;
}
@@ -2007,9 +1997,9 @@
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
"%s refcnt:%d\n", __func__,
- atomic_read(&dev->hw_dev->refcnt));
+ atomic_read(&hw->refcnt));
- if (atomic_read(&dev->hw_dev->refcnt) > 1)
+ if (atomic_read(&hw->refcnt) > 1)
goto end;
/*
* ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->
@@ -2065,7 +2055,7 @@
val = readl(base + CIF_ISP_CTRL);
writel(val | CIF_ISP_CTRL_ISP_CFG_UPD, base + CIF_ISP_CTRL);
- if (hw->is_unite)
+ if (hw->unite == ISP_UNITE_TWO)
rkisp_next_write(dev, CIF_ISP_CTRL,
val | CIF_ISP_CTRL_ISP_CFG_UPD, true);
@@ -2082,11 +2072,11 @@
safe_rate = hw->clk_rate_tbl[0].clk_rate * 1000000UL;
if (old_rate > safe_rate) {
rkisp_set_clk_rate(hw->clks[0], safe_rate);
- if (hw->is_unite)
+ if (hw->unite == ISP_UNITE_TWO)
rkisp_set_clk_rate(hw->clks[5], safe_rate);
udelay(100);
}
- rkisp_soft_reset(dev->hw_dev, false);
+ rkisp_soft_reset(hw, false);
}
if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) {
@@ -2097,18 +2087,20 @@
writel(0, base + CIF_ISP_CSI0_MASK3);
} else if (dev->isp_ver >= ISP_V20) {
writel(0, base + CSI2RX_CSI2_RESETN);
- if (hw->is_unite)
+ if (hw->unite == ISP_UNITE_TWO)
rkisp_next_write(dev, CSI2RX_CSI2_RESETN, 0, true);
}
hw->is_dvfs = false;
hw->is_runing = false;
- dev->hw_dev->is_idle = true;
- dev->hw_dev->is_mi_update = false;
+ hw->is_idle = true;
+ hw->is_mi_update = false;
+ hw->pre_dev_id = -1;
end:
dev->irq_ends_mask = 0;
dev->hdr.op_mode = 0;
dev->sw_rd_cnt = 0;
+ dev->stats_vdev.rdbk_drop = false;
rkisp_set_state(&dev->isp_state, ISP_STOP);
if (dev->isp_ver >= ISP_V20)
@@ -2154,12 +2146,9 @@
val = dev->isp_sdev.out_crop.height / 15;
val = dev->cap_dev.wait_line / val;
val = ISP3X_RAWAF_INELINE0(val) | ISP3X_RAWAF_INTLINE0_EN;
- rkisp_unite_write(dev, ISP3X_RAWAF_INT_LINE,
- val, false, dev->hw_dev->is_unite);
- rkisp_unite_set_bits(dev, ISP_ISP3A_IMSC, 0,
- ISP2X_3A_RAWAF, false, dev->hw_dev->is_unite);
- rkisp_unite_clear_bits(dev, CIF_ISP_IMSC,
- ISP2X_LSC_LUT_ERR, false, dev->hw_dev->is_unite);
+ rkisp_unite_write(dev, ISP3X_RAWAF_INT_LINE, val, false);
+ rkisp_unite_set_bits(dev, ISP_ISP3A_IMSC, 0, ISP2X_3A_RAWAF, false);
+ rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, ISP2X_LSC_LUT_ERR, false);
dev->rawaf_irq_cnt = 0;
}
}
@@ -2187,12 +2176,11 @@
val |= NOC_HURRY_PRIORITY(2) | NOC_HURRY_W_MODE(2) | NOC_HURRY_R_MODE(1);
if (atomic_read(&dev->hw_dev->refcnt) > 1)
is_direct = false;
- rkisp_unite_write(dev, CIF_ISP_CTRL, val, is_direct, dev->hw_dev->is_unite);
+ rkisp_unite_write(dev, CIF_ISP_CTRL, val, is_direct);
rkisp_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD);
dev->isp_err_cnt = 0;
dev->isp_isr_cnt = 0;
- dev->isp_state = ISP_START | ISP_FRAME_END;
dev->irq_ends_mask |= ISP_FRAME_END;
dev->irq_ends = 0;
@@ -2668,14 +2656,16 @@
max_h = CIF_ISP_INPUT_H_MAX_V21;
break;
case ISP_V30:
- max_w = dev->hw_dev->is_unite ?
+ max_w = dev->hw_dev->unite ?
CIF_ISP_INPUT_W_MAX_V30_UNITE : CIF_ISP_INPUT_W_MAX_V30;
- max_h = dev->hw_dev->is_unite ?
+ max_h = dev->hw_dev->unite ?
CIF_ISP_INPUT_H_MAX_V30_UNITE : CIF_ISP_INPUT_H_MAX_V30;
break;
case ISP_V32:
- max_w = CIF_ISP_INPUT_W_MAX_V32;
- max_h = CIF_ISP_INPUT_H_MAX_V32;
+ max_w = dev->hw_dev->unite ?
+ CIF_ISP_INPUT_W_MAX_V32_UNITE : CIF_ISP_INPUT_W_MAX_V32;
+ max_h = dev->hw_dev->unite ?
+ CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32;
break;
case ISP_V32_L:
max_w = CIF_ISP_INPUT_W_MAX_V32_L;
@@ -2865,6 +2855,7 @@
{
struct rkisp_device *isp_dev = sd_to_isp_dev(sd);
struct rkisp_hw_dev *hw_dev = isp_dev->hw_dev;
+ int ret;
if (!on) {
if (IS_HDR_RDBK(isp_dev->rd_mode)) {
@@ -2877,10 +2868,13 @@
wake_up(&s->done);
}
}
- wait_event_timeout(isp_dev->sync_onoff,
- isp_dev->isp_state & ISP_STOP ||
- !IS_HDR_RDBK(isp_dev->rd_mode),
- msecs_to_jiffies(50));
+ ret = wait_event_timeout(isp_dev->sync_onoff,
+ isp_dev->isp_state & ISP_STOP ||
+ !IS_HDR_RDBK(isp_dev->rd_mode),
+ msecs_to_jiffies(500));
+ if (!ret)
+ v4l2_warn(&isp_dev->v4l2_dev, "%s wait timeout, mode:%d state:0x%x\n",
+ __func__, isp_dev->rd_mode, isp_dev->isp_state);
rkisp_isp_stop(isp_dev);
atomic_dec(&hw_dev->refcnt);
rkisp_params_stream_stop(&isp_dev->params_vdev);
@@ -2901,6 +2895,7 @@
rkisp_config_cif(isp_dev);
rkisp_isp_start(isp_dev);
rkisp_global_update_mi(isp_dev);
+ isp_dev->isp_state = ISP_START | ISP_FRAME_END;
rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, NULL);
return 0;
}
@@ -2936,7 +2931,7 @@
u32 val = pool->buf.buff_addr[RKISP_PLANE_Y];
rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false);
- if (dev->hw_dev->is_unite) {
+ if (dev->hw_dev->unite == ISP_UNITE_TWO) {
u32 offs = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL;
if (stream->memory)
@@ -3054,7 +3049,8 @@
pool->dbufs = dbufs;
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
- "%s type:0x%x dbufs[%d]:%p", __func__, dbufs->type, i, dbufs);
+ "%s type:0x%x first:%d dbufs[%d]:%p", __func__,
+ dbufs->type, dbufs->is_first, i, dbufs);
if (dbufs->is_resmem) {
dma = dbufs->dma;
@@ -3412,11 +3408,64 @@
if (dev->is_bigmode)
mode |= RKISP_ISP_BIGMODE;
info->mode = mode;
- if (dev->hw_dev->is_unite)
+ if (dev->hw_dev->unite)
info->act_width = in_crop->width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
else
info->act_width = in_crop->width;
info->act_height = in_crop->height;
+ return 0;
+}
+
+static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev,
+ struct rkisp_vicap_mode *vicap_mode)
+{
+ struct rkisp_hw_dev *hw = isp_dev->hw_dev;
+ int rd_mode = isp_dev->rd_mode;
+
+ isp_dev->is_suspend_one_frame = false;
+ if (vicap_mode->rdbk_mode == RKISP_VICAP_ONLINE) {
+ if (!hw->is_single)
+ return -EINVAL;
+ /* switch to online mode for single sensor */
+ switch (rd_mode) {
+ case HDR_RDBK_FRAME3:
+ isp_dev->rd_mode = HDR_LINEX3_DDR;
+ break;
+ case HDR_RDBK_FRAME2:
+ isp_dev->rd_mode = HDR_LINEX2_DDR;
+ break;
+ default:
+ isp_dev->rd_mode = HDR_NORMAL;
+ }
+ } else if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO ||
+ vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME) {
+ /* switch to readback mode */
+ switch (rd_mode) {
+ case HDR_LINEX3_DDR:
+ isp_dev->rd_mode = HDR_RDBK_FRAME3;
+ break;
+ case HDR_LINEX2_DDR:
+ isp_dev->rd_mode = HDR_RDBK_FRAME2;
+ break;
+ default:
+ isp_dev->rd_mode = HDR_RDBK_FRAME1;
+ }
+ if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME)
+ isp_dev->is_suspend_one_frame = true;
+ } else {
+ return -EINVAL;
+ }
+ isp_dev->hdr.op_mode = isp_dev->rd_mode;
+ if (rd_mode != isp_dev->rd_mode && hw->cur_dev_id == isp_dev->dev_id) {
+ rkisp_unite_write(isp_dev, CSI2RX_CTRL0,
+ SW_IBUF_OP_MODE(isp_dev->rd_mode), true);
+ if (IS_HDR_RDBK(isp_dev->rd_mode))
+ rkisp_unite_set_bits(isp_dev, CTRL_SWS_CFG, 0,
+ SW_MPIP_DROP_FRM_DIS, true);
+ else
+ rkisp_unite_clear_bits(isp_dev, CTRL_SWS_CFG,
+ SW_MPIP_DROP_FRM_DIS, true);
+ }
return 0;
}
@@ -3445,7 +3494,7 @@
rkisp_get_info(isp_dev, arg);
break;
case RKISP_CMD_GET_TB_HEAD_V32:
- if (isp_dev->tb_head.complete != RKISP_TB_OK || !isp_dev->is_pre_on) {
+ if (isp_dev->tb_head.complete != RKISP_TB_OK) {
ret = -EINVAL;
break;
}
@@ -3543,6 +3592,16 @@
isp_dev->hw_dev->is_multi_overflow = false;
rkisp_hw_enum_isp_size(isp_dev->hw_dev);
}
+ break;
+ case RKISP_VICAP_CMD_SET_STREAM:
+ ret = rkisp_reset_handle(isp_dev);
+ if (!ret) {
+ if (isp_dev->hw_dev->monitor.state & ISP_CIF_RESET)
+ isp_dev->hw_dev->monitor.state &= ~ISP_CIF_RESET;
+ }
+ break;
+ case RKISP_VICAP_CMD_MODE:
+ ret = rkisp_set_work_mode_by_vicap(isp_dev, arg);
break;
default:
ret = -ENOIOCTLCMD;
@@ -3646,6 +3705,9 @@
case RKISP_CMD_MULTI_DEV_FORCE_ENUM:
ret = rkisp_ioctl(sd, cmd, NULL);
break;
+ case RKISP_VICAP_CMD_SET_STREAM:
+ ret = rkisp_ioctl(sd, cmd, NULL);
+ break;
default:
ret = -ENOIOCTLCMD;
}
@@ -3699,7 +3761,7 @@
struct ispsd_in_fmt *in_fmt = &isp_sd->in_fmt;
struct ispsd_out_fmt *out_fmt = &isp_sd->out_fmt;
- *in_fmt = rkisp_isp_input_formats[0];
+ *in_fmt = rkisp_isp_input_formats[8];
in_frm->width = RKISP_DEFAULT_WIDTH;
in_frm->height = RKISP_DEFAULT_HEIGHT;
in_frm->code = in_fmt->mbus_code;
@@ -3765,6 +3827,7 @@
atomic_set(&isp_sdev->frm_sync_seq, 0);
rkisp_monitor_init(isp_dev);
INIT_WORK(&isp_dev->rdbk_work, rkisp_rdbk_work);
+ init_completion(&isp_dev->pm_cmpl);
return 0;
err_cleanup_media_entity:
media_entity_cleanup(&sd->entity);
@@ -3804,9 +3867,54 @@
(cond) ? 0 : -ETIMEDOUT; \
})
+void rkisp_save_tb_info(struct rkisp_device *isp_dev)
+{
+ struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev;
+ void *resmem_va = phys_to_virt(isp_dev->resmem_pa);
+ struct rkisp_thunderboot_resmem_head *head = resmem_va;
+ int size = 0, offset = 0;
+ void *param = NULL;
+
+ switch (isp_dev->isp_ver) {
+ case ISP_V32:
+ size = sizeof(struct rkisp32_thunderboot_resmem_head);
+ offset = size * isp_dev->dev_id;
+ break;
+ default:
+ break;
+ }
+
+ if (size && size < isp_dev->resmem_size) {
+ dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset,
+ size, DMA_FROM_DEVICE);
+ if (isp_dev->is_rtt_first)
+ params_vdev->is_first_cfg = true;
+ if (isp_dev->isp_ver == ISP_V32) {
+ struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset;
+
+ param = &tmp->cfg;
+ head = &tmp->head;
+ v4l2_info(&isp_dev->v4l2_dev,
+ "tb param module en:0x%llx upd:0x%llx cfg upd:0x%llx\n",
+ tmp->cfg.module_en_update,
+ tmp->cfg.module_ens,
+ tmp->cfg.module_cfg_update);
+ }
+ if (param && (isp_dev->isp_state & ISP_STOP))
+ 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",
+ isp_dev->resmem_size, size);
+ head->complete = RKISP_TB_NG;
+ }
+ memcpy(&isp_dev->tb_head, head, sizeof(*head));
+}
+
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
void rkisp_chk_tb_over(struct rkisp_device *isp_dev)
{
+ struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev;
struct rkisp_hw_dev *hw = isp_dev->hw_dev;
struct rkisp_thunderboot_resmem_head *head;
enum rkisp_tb_state tb_state;
@@ -3815,19 +3923,20 @@
if (!isp_dev->is_thunderboot)
return;
+ if (isp_dev->isp_ver == ISP_V32 && params_vdev->is_first_cfg)
+ goto end;
+
resmem_va = phys_to_virt(isp_dev->resmem_pa);
head = (struct rkisp_thunderboot_resmem_head *)resmem_va;
dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr,
sizeof(struct rkisp_thunderboot_resmem_head),
DMA_FROM_DEVICE);
- shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 200 * USEC_PER_MSEC);
+ shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 400 * USEC_PER_MSEC);
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, offset = 0, timeout = 50;
+ int i, timeout = 50;
/* wait for all isp dev to register */
if (head->camera_num > 1) {
@@ -3837,48 +3946,23 @@
break;
usleep_range(200, 210);
}
- }
-
- switch (isp_dev->isp_ver) {
- case ISP_V32:
- size = sizeof(struct rkisp32_thunderboot_resmem_head);
- offset = size * isp_dev->dev_id;
- break;
- default:
- break;
- }
-
- if (size && size < isp_dev->resmem_size) {
- dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset,
- size, DMA_FROM_DEVICE);
- params_vdev->is_first_cfg = true;
- if (isp_dev->isp_ver == ISP_V32) {
- struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset;
-
- param = &tmp->cfg;
- head = &tmp->head;
- v4l2_info(&isp_dev->v4l2_dev,
- "tb param module en:0x%llx upd:0x%llx cfg upd:0x%llx\n",
- tmp->cfg.module_en_update,
- tmp->cfg.module_ens,
- tmp->cfg.module_cfg_update);
+ if (head->camera_num > hw->dev_num) {
+ v4l2_err(&isp_dev->v4l2_dev,
+ "thunderboot invalid camera num:%d, dev num:%d\n",
+ head->camera_num, hw->dev_num);
+ goto end;
}
- 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",
- isp_dev->resmem_size, size);
- head->complete = RKISP_TB_NG;
}
+ for (i = 0; i < head->camera_num; i++)
+ rkisp_save_tb_info(hw->isp[i]);
}
- memcpy(&isp_dev->tb_head, head, sizeof(*head));
+end:
+ head = &isp_dev->tb_head;
v4l2_info(&isp_dev->v4l2_dev,
- "thunderboot info: %d, %d, %d, %d, %d, %d | %d %d\n",
+ "tb info en:%d comp:%d cnt:%d w:%d h:%d cam:%d idx:%d\n",
head->enable,
head->complete,
head->frm_total,
- head->hdr_mode,
head->width,
head->height,
head->camera_num,
@@ -4005,7 +4089,7 @@
struct rkisp_device *dev)
{
struct rkisp_hw_dev *hw = dev->hw_dev;
- void __iomem *base = !hw->is_unite ?
+ void __iomem *base = hw->unite != ISP_UNITE_TWO ?
hw->base_addr : hw->base_next_addr;
unsigned int isp_mis_tmp = 0;
unsigned int isp_err = 0;
@@ -4026,7 +4110,7 @@
if (isp3a_mis & ISP2X_3A_RAWAE_BIG && dev->params_vdev.rdbk_times > 0)
writel(BIT(31), base + RAWAE_BIG1_BASE + RAWAE_BIG_CTRL);
- if (hw->is_unite) {
+ if (hw->unite == ISP_UNITE_TWO) {
u32 val = rkisp_read(dev, ISP3X_ISP_RIS, true);
if (val) {
@@ -4057,9 +4141,14 @@
}
if (IS_HDR_RDBK(dev->hdr.op_mode)) {
- /* read 3d lut at isp readback */
- if (!dev->hw_dev->is_single)
- rkisp_write(dev, ISP_3DLUT_UPDATE, 0, true);
+ /* disabled frame end to read 3dlut for multi sensor
+ * 3dlut will update at isp readback
+ */
+ if (!dev->hw_dev->is_single) {
+ writel(0, hw->base_addr + ISP_3DLUT_UPDATE);
+ if (hw->unite == ISP_UNITE_TWO)
+ writel(0, hw->base_next_addr + ISP_3DLUT_UPDATE);
+ }
rkisp_stats_rdbk_enable(&dev->stats_vdev, true);
goto vs_skip;
}
@@ -4087,7 +4176,7 @@
if (isp_mis & CIF_ISP_FRAME)
sof_event_later = true;
if (dev->vs_irq < 0 && !sof_event_later) {
- dev->isp_sdev.frm_timestamp = ktime_get_ns();
+ dev->isp_sdev.frm_timestamp = rkisp_time_get_ns(dev);
rkisp_isp_queue_event_sof(&dev->isp_sdev);
rkisp_stream_frame_start(dev, isp_mis);
}
@@ -4155,7 +4244,7 @@
/* sampled input frame is complete */
if (isp_mis & CIF_ISP_FRAME_IN) {
dev->isp_sdev.dbg.interval =
- ktime_get_ns() - dev->isp_sdev.dbg.timestamp;
+ rkisp_time_get_ns(dev) - dev->isp_sdev.dbg.timestamp;
rkisp_set_state(&dev->isp_state, ISP_FRAME_IN);
writel(CIF_ISP_FRAME_IN, base + CIF_ISP_ICR);
isp_mis_tmp = readl(base + CIF_ISP_MIS);
@@ -4169,7 +4258,7 @@
dev->rawaf_irq_cnt = 0;
if (!dev->is_pre_on || !IS_HDR_RDBK(dev->rd_mode))
dev->isp_sdev.dbg.interval =
- ktime_get_ns() - dev->isp_sdev.dbg.timestamp;
+ rkisp_time_get_ns(dev) - dev->isp_sdev.dbg.timestamp;
/* Clear Frame In (ISP) */
rkisp_set_state(&dev->isp_state, ISP_FRAME_END);
writel(CIF_ISP_FRAME, base + CIF_ISP_ICR);
@@ -4189,7 +4278,7 @@
u64 tmp = dev->isp_sdev.dbg.interval +
dev->isp_sdev.dbg.timestamp;
- dev->isp_sdev.dbg.timestamp = ktime_get_ns();
+ dev->isp_sdev.dbg.timestamp = rkisp_time_get_ns(dev);
/* v-blank: frame(N)start - frame(N-1)end */
dev->isp_sdev.dbg.delay = dev->isp_sdev.dbg.timestamp - tmp;
}
@@ -4241,7 +4330,7 @@
/* cur frame end and next frame start irq togeter */
if (dev->vs_irq < 0 && sof_event_later) {
- dev->isp_sdev.frm_timestamp = ktime_get_ns();
+ dev->isp_sdev.frm_timestamp = rkisp_time_get_ns(dev);
rkisp_isp_queue_event_sof(&dev->isp_sdev);
rkisp_stream_frame_start(dev, isp_mis);
}
--
Gitblit v1.6.2