From 6778948f9de86c3cfaf36725a7c87dcff9ba247f Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 08:20:59 +0000 Subject: [PATCH] kernel_5.10 no rt --- kernel/drivers/media/platform/rockchip/isp/rkisp.c | 449 +++++++++++++++++++++++++++++++++---------------------- 1 files changed, 269 insertions(+), 180 deletions(-) diff --git a/kernel/drivers/media/platform/rockchip/isp/rkisp.c b/kernel/drivers/media/platform/rockchip/isp/rkisp.c index 1d69fab..6bab4e5 100644 --- a/kernel/drivers/media/platform/rockchip/isp/rkisp.c +++ b/kernel/drivers/media/platform/rockchip/isp/rkisp.c @@ -213,17 +213,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 +517,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 +529,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 +542,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 +594,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 +625,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 +651,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 +695,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 +706,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 +726,88 @@ 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); + 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); + } 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 +818,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 +854,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) @@ -865,6 +914,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; @@ -914,17 +969,40 @@ 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; } + /* 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_pre_on && 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); } + isp->params_vdev.rdbk_times = isp->sw_rd_cnt + 1; } end: spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags); @@ -982,12 +1060,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", @@ -1001,6 +1073,9 @@ if ((dev->irq_ends & dev->irq_ends_mask) != dev->irq_ends_mask || !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); @@ -1068,26 +1143,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; @@ -1389,20 +1463,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, @@ -1601,7 +1673,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 +1688,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 +1718,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 +1784,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 +1817,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 +1972,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 +2069,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 +2127,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 +2144,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 +2159,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 +2218,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 +2248,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 +2728,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; @@ -2901,6 +2963,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 +2999,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) @@ -3412,7 +3475,7 @@ 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; @@ -3699,7 +3762,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; @@ -3805,8 +3868,52 @@ }) #ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP +static 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); + 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) + 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)); +} + 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 +3922,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,42 +3945,18 @@ 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", head->enable, @@ -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; } -- Gitblit v1.6.2