diff --git a/drivers/media/platform/rockchip/isp/bridge.c b/drivers/media/platform/rockchip/isp/bridge.c index 055790c42456..dbb081327706 100644 --- a/drivers/media/platform/rockchip/isp/bridge.c +++ b/drivers/media/platform/rockchip/isp/bridge.c @@ -48,14 +48,396 @@ static void update_mi(struct rkisp_bridge_device *dev) rkisp_read(dev->ispdev, dev->cfg->reg.g0_base, true)); } +static void dump_dbg_reg(struct rkisp_bridge_device *dev, struct rkisp_ispp_reg *reg_buf) +{ + struct rkisp_isp2x_stat_buffer *tmp_statsbuf; + struct rkisp_hw_dev *hw = dev->ispdev->hw_dev; + u32 offset = 0, size; + + tmp_statsbuf = (struct rkisp_isp2x_stat_buffer *)dev->ispdev->stats_vdev.tmp_statsbuf.vaddr; + memset(reg_buf->isp_offset, -1, sizeof(reg_buf->isp_offset)); + memset(reg_buf->ispp_offset, -1, sizeof(reg_buf->ispp_offset)); + memset(reg_buf->isp_size, 0, sizeof(reg_buf->isp_offset)); + memset(reg_buf->isp_stats_size, 0, sizeof(reg_buf->isp_offset)); + memset(reg_buf->ispp_size, 0, sizeof(reg_buf->ispp_offset)); + if (rkisp_debug_reg & ISP2X_MODULE_DPCC) { + size = 4 + ISP_DPCC0_PDAF_FORWARD_MED - ISP_DPCC0_MODE; + reg_buf->isp_size[ISP2X_ID_DPCC] = size; + reg_buf->isp_offset[ISP2X_ID_DPCC] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_DPCC0_MODE, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_BLS) { + size = 4 + ISP_BLS_D_MEASURED - ISP_BLS_CTRL; + reg_buf->isp_size[ISP2X_ID_BLS] = size; + reg_buf->isp_offset[ISP2X_ID_BLS] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_BLS_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_SDG) { + size = 4 + ISP_GAMMA_B_Y_16 - ISP_GAMMA_DX_LO; + reg_buf->isp_size[ISP2X_ID_SDG] = size; + reg_buf->isp_offset[ISP2X_ID_SDG] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_GAMMA_DX_LO, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_SIHST) { + size = 4 + ISP_HIST_HIST3_DBG2 - ISP_HIST_HIST_CTRL; + reg_buf->isp_size[ISP2X_ID_SIHST] = size; + reg_buf->isp_offset[ISP2X_ID_SIHST] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_HIST_HIST_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_LSC) { + size = 4 + ISP_LSC_STATUS - ISP_LSC_CTRL; + reg_buf->isp_size[ISP2X_ID_LSC] = size; + reg_buf->isp_offset[ISP2X_ID_LSC] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_LSC_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_AWB_GAIN) { + size = 4 + CIF_ISP_AWB_GAIN_RB_V12 - CIF_ISP_AWB_GAIN_G_V12; + reg_buf->isp_size[ISP2X_ID_AWB_GAIN] = size; + reg_buf->isp_offset[ISP2X_ID_AWB_GAIN] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + CIF_ISP_AWB_GAIN_G_V12, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_CCM) { + size = 4 + ISP_CCM_BOUND_BIT - ISP_CCM_CTRL; + reg_buf->isp_size[ISP2X_ID_CCM] = size; + reg_buf->isp_offset[ISP2X_ID_CCM] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_CCM_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_GOC) { + size = 4 + ISP_GAMMA_OUT_Y40 - ISP_GAMMA_OUT_CTRL; + reg_buf->isp_size[ISP2X_ID_GOC] = size; + reg_buf->isp_offset[ISP2X_ID_GOC] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_GAMMA_OUT_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_CPROC) { + size = 4 + CPROC_HUE - CPROC_CTRL; + reg_buf->isp_size[ISP2X_ID_CPROC] = size; + reg_buf->isp_offset[ISP2X_ID_CPROC] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + CPROC_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_SIAF) { + size = 4 + ISP_AFM_LUM_C - ISP_AFM_CTRL; + reg_buf->isp_size[ISP2X_ID_SIAF] = size; + reg_buf->isp_offset[ISP2X_ID_SIAF] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_AFM_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_SIAWB) { + size = 4 + CIF_ISP_AWB_MEAN_V10 - CIF_ISP_AWB_PROP_V10; + reg_buf->isp_size[ISP2X_ID_SIAWB] = size; + reg_buf->isp_offset[ISP2X_ID_SIAWB] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + CIF_ISP_AWB_PROP_V10, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_IE) { + size = 4 + CIF_IMG_EFF_SHARPEN - CIF_IMG_EFF_CTRL; + reg_buf->isp_size[ISP2X_ID_IE] = size; + reg_buf->isp_offset[ISP2X_ID_IE] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + CIF_IMG_EFF_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_YUVAE) { + size = 4 + ISP_YUVAE_RO_DBG3 - ISP_YUVAE_CTRL; + reg_buf->isp_size[ISP2X_ID_YUVAE] = size; + reg_buf->isp_offset[ISP2X_ID_YUVAE] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_YUVAE_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_WDR) { + size = 4 + ISP_WDR_BLKMEAN8_ROW9_4TO7 - ISP_WDR_CTRL; + reg_buf->isp_size[ISP2X_ID_WDR] = size; + reg_buf->isp_offset[ISP2X_ID_WDR] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_WDR_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RK_IESHARP) { + size = 4 + CIF_RKSHARP_UV_GAUSS_OTHER_COE33_COE35 - CIF_RKSHARP_CTRL; + reg_buf->isp_size[ISP2X_ID_RK_IESHARP] = size; + reg_buf->isp_offset[ISP2X_ID_RK_IESHARP] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + CIF_RKSHARP_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWAF) { + size = 4 + ISP_RAWAF_INT_STATE - ISP_RAWAF_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWAF] = size; + reg_buf->isp_offset[ISP2X_ID_RAWAF] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_RAWAF_CTRL, size); + offset += size; + + size = ISP2X_RAWAF_SUMDATA_NUM * sizeof(tmp_statsbuf->params.rawaf.ramdata[0]); + reg_buf->isp_size[ISP2X_ID_RAWAF] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWAF] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawaf.ramdata[0], size); + else + memset(®_buf->reg[offset], 0, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWAE0) { + size = 4 + ISP_RAWAE_LITE_RO_DBG2 - ISP_RAWAE_LITE_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWAE0] = size; + reg_buf->isp_offset[ISP2X_ID_RAWAE0] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_RAWAE_LITE_CTRL, size); + offset += size; + + size = ISP2X_RAWAELITE_MEAN_NUM * sizeof(tmp_statsbuf->params.rawae0.data[0]); + reg_buf->isp_size[ISP2X_ID_RAWAE0] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWAE0] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) { + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawae0.data[0], size); + } else { + memset(®_buf->reg[offset], 0, size); + } + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWAE1) { + size = 4 + RAWAE_BIG_RO_DBG3 - RAWAE_BIG_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWAE1] = size; + reg_buf->isp_offset[ISP2X_ID_RAWAE1] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + RAWAE_BIG1_BASE, size); + offset += size; + + size = ISP2X_RAWAEBIG_MEAN_NUM * sizeof(tmp_statsbuf->params.rawae1.data[0]); + reg_buf->isp_size[ISP2X_ID_RAWAE1] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWAE1] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) { + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawae1.data[0], size); + } else { + memset(®_buf->reg[offset], 0, size); + } + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWAE2) { + size = 4 + RAWAE_BIG_RO_DBG3 - RAWAE_BIG_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWAE2] = size; + reg_buf->isp_offset[ISP2X_ID_RAWAE2] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + RAWAE_BIG2_BASE, size); + offset += size; + + size = ISP2X_RAWAEBIG_MEAN_NUM * sizeof(tmp_statsbuf->params.rawae2.data[0]); + reg_buf->isp_size[ISP2X_ID_RAWAE2] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWAE2] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) { + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawae2.data[0], size); + } else { + memset(®_buf->reg[offset], 0, size); + } + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWAE3) { + size = 4 + RAWAE_BIG_RO_DBG3 - RAWAE_BIG_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWAE3] = size; + reg_buf->isp_offset[ISP2X_ID_RAWAE3] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + RAWAE_BIG3_BASE, size); + offset += size; + + size = ISP2X_RAWAEBIG_MEAN_NUM * sizeof(tmp_statsbuf->params.rawae3.data[0]); + reg_buf->isp_size[ISP2X_ID_RAWAE3] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWAE3] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) { + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawae3.data[0], size); + } else { + memset(®_buf->reg[offset], 0, size); + } + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWAWB) { + size = 4 + ISP_RAWAWB_RAM_CTRL - ISP_RAWAWB_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWAWB] = size; + reg_buf->isp_offset[ISP2X_ID_RAWAWB] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_RAWAWB_CTRL, size); + offset += size; + + size = ISP2X_RAWAWB_RAMDATA_NUM * sizeof(tmp_statsbuf->params.rawawb.ramdata[0]); + reg_buf->isp_size[ISP2X_ID_RAWAWB] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWAWB] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawawb.ramdata[0], size); + else + memset(®_buf->reg[offset], 0, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWHIST0) { + size = 4 + ISP_RAWHIST_LITE_WEIGHT - ISP_RAWHIST_LITE_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWHIST0] = size; + reg_buf->isp_offset[ISP2X_ID_RAWHIST0] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_RAWHIST_LITE_CTRL, size); + offset += size; + + size = ISP2X_HIST_BIN_N_MAX * sizeof(tmp_statsbuf->params.rawhist0.hist_bin[0]); + reg_buf->isp_size[ISP2X_ID_RAWHIST0] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWHIST0] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawhist0.hist_bin[0], size); + else + memset(®_buf->reg[offset], 0, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWHIST1) { + size = 4 + ISP_RAWHIST_BIG_WEIGHT_BASE - ISP_RAWHIST_BIG_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWHIST1] = size; + reg_buf->isp_offset[ISP2X_ID_RAWHIST1] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_RAWHIST_BIG1_BASE, size); + offset += size; + + size = ISP2X_HIST_BIN_N_MAX * sizeof(tmp_statsbuf->params.rawhist1.hist_bin[0]); + reg_buf->isp_size[ISP2X_ID_RAWHIST1] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWHIST1] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawhist1.hist_bin[0], size); + else + memset(®_buf->reg[offset], 0, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWHIST2) { + size = 4 + ISP_RAWHIST_BIG_WEIGHT_BASE - ISP_RAWHIST_BIG_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWHIST2] = size; + reg_buf->isp_offset[ISP2X_ID_RAWHIST2] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_RAWHIST_BIG2_BASE, size); + offset += size; + + size = ISP2X_HIST_BIN_N_MAX * sizeof(tmp_statsbuf->params.rawhist2.hist_bin[0]); + reg_buf->isp_size[ISP2X_ID_RAWHIST2] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWHIST2] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawhist2.hist_bin[0], size); + else + memset(®_buf->reg[offset], 0, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWHIST3) { + size = 4 + ISP_RAWHIST_BIG_WEIGHT_BASE - ISP_RAWHIST_BIG_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWHIST3] = size; + reg_buf->isp_offset[ISP2X_ID_RAWHIST3] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_RAWHIST_BIG3_BASE, size); + offset += size; + + size = ISP2X_HIST_BIN_N_MAX * sizeof(tmp_statsbuf->params.rawhist3.hist_bin[0]); + reg_buf->isp_size[ISP2X_ID_RAWHIST3] += size; + reg_buf->isp_stats_size[ISP2X_ID_RAWHIST3] = size; + if (tmp_statsbuf->frame_id == reg_buf->frame_id) + memcpy(®_buf->reg[offset], &tmp_statsbuf->params.rawhist3.hist_bin[0], size); + else + memset(®_buf->reg[offset], 0, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_HDRMGE) { + size = 4 + ISP_HDRMGE_OVER_Y16 - ISP_HDRMGE_CTRL; + reg_buf->isp_size[ISP2X_ID_HDRMGE] = size; + reg_buf->isp_offset[ISP2X_ID_HDRMGE] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_HDRMGE_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_RAWNR) { + size = 4 + ISP_RAWNR_RGBAIN_FLIP - ISP_RAWNR_CTRL; + reg_buf->isp_size[ISP2X_ID_RAWNR] = size; + reg_buf->isp_offset[ISP2X_ID_RAWNR] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_RAWNR_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_HDRTMO) { + size = 4 + ISP_HDRTMO_HIST_RO31 - ISP_HDRTMO_CTRL; + reg_buf->isp_size[ISP2X_ID_HDRTMO] = size; + reg_buf->isp_offset[ISP2X_ID_HDRTMO] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_HDRTMO_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_GIC) { + size = 4 + ISP_GIC_NOISE_CTRL1 - ISP_GIC_CONTROL; + reg_buf->isp_size[ISP2X_ID_GIC] = size; + reg_buf->isp_offset[ISP2X_ID_GIC] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_GIC_CONTROL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_DHAZ) { + size = 4 + ISP_DHAZ_HIST_REG95 - ISP_DHAZ_CTRL; + reg_buf->isp_size[ISP2X_ID_DHAZ] = size; + reg_buf->isp_offset[ISP2X_ID_DHAZ] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_DHAZ_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_3DLUT) { + size = 4 + ISP_3DLUT_UPDATE - ISP_3DLUT_CTRL; + reg_buf->isp_size[ISP2X_ID_3DLUT] = size; + reg_buf->isp_offset[ISP2X_ID_3DLUT] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_3DLUT_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_LDCH) { + size = 4 + ISP_LDCH_STS - ISP_LDCH_STS; + reg_buf->isp_size[ISP2X_ID_LDCH] = size; + reg_buf->isp_offset[ISP2X_ID_LDCH] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_LDCH_STS, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_GAIN) { + size = 4 + ISP_GAIN_LUT8 - ISP_GAIN_CTRL; + reg_buf->isp_size[ISP2X_ID_GAIN] = size; + reg_buf->isp_offset[ISP2X_ID_GAIN] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_GAIN_CTRL, size); + offset += size; + } + + if (rkisp_debug_reg & ISP2X_MODULE_DEBAYER) { + size = 4 + ISP_DEBAYER_C_FILTER - ISP_DEBAYER_CONTROL; + reg_buf->isp_size[ISP2X_ID_DEBAYER] = size; + reg_buf->isp_offset[ISP2X_ID_DEBAYER] = offset; + memcpy_fromio(®_buf->reg[offset], hw->base_addr + ISP_DEBAYER_CONTROL, size); + offset += size; + } + + reg_buf->reg_size = offset; +} + static int frame_end(struct rkisp_bridge_device *dev, bool en) { struct rkisp_hw_dev *hw = dev->ispdev->hw_dev; struct v4l2_subdev *sd = v4l2_get_subdev_hostdata(&dev->sd); + struct rkisp_ispp_reg *reg_buf; unsigned long lock_flags = 0; u64 ns = ktime_get_ns(); - rkisp_dmarx_get_frame(dev->ispdev, &dev->dbg.id, NULL, true); + rkisp_dmarx_get_frame(dev->ispdev, &dev->dbg.id, NULL, NULL, true); dev->dbg.interval = ns - dev->dbg.timestamp; dev->dbg.timestamp = ns; if (hw->cur_buf && hw->nxt_buf) { @@ -69,14 +451,27 @@ static int frame_end(struct rkisp_bridge_device *dev, bool en) list_add_tail(&hw->cur_buf->list, &hw->list); spin_unlock_irqrestore(&hw->buf_lock, lock_flags); } else { + u64 sof_ns = 0; + ns = 0; rkisp_dmarx_get_frame(dev->ispdev, - &hw->cur_buf->frame_id, &ns, true); - hw->cur_buf->frame_id++; + &hw->cur_buf->frame_id, &sof_ns, &ns, true); + if (!sof_ns) + sof_ns = 0; if (!ns) ns = ktime_get_ns(); hw->cur_buf->frame_timestamp = ns; hw->cur_buf->index = dev->ispdev->dev_id; + rkispp_request_regbuf(sd, ®_buf); + if (reg_buf) { + reg_buf->stat = ISP_ISPP_INUSE; + reg_buf->dev_id = hw->cur_buf->index; + reg_buf->frame_id = hw->cur_buf->frame_id; + reg_buf->sof_timestamp = sof_ns; + reg_buf->frame_timestamp = hw->cur_buf->frame_timestamp; + reg_buf->exposure = dev->ispdev->params_vdev.exposure; + dump_dbg_reg(dev, reg_buf); + } v4l2_subdev_call(sd, video, s_rx_buffer, hw->cur_buf, NULL); } hw->cur_buf = NULL; @@ -464,6 +859,7 @@ static int bridge_start(struct rkisp_bridge_device *dev) update_mi(dev); } dev->ispdev->skip_frame = 0; + rkisp_stats_first_ddr_config(&dev->ispdev->stats_vdev); dev->en = true; return 0; } diff --git a/drivers/media/platform/rockchip/isp/capture_v20.c b/drivers/media/platform/rockchip/isp/capture_v20.c index 3909c6134242..6be8ad74cf95 100644 --- a/drivers/media/platform/rockchip/isp/capture_v20.c +++ b/drivers/media/platform/rockchip/isp/capture_v20.c @@ -1310,7 +1310,7 @@ static int mi_frame_end(struct rkisp_stream *stream) stream->id == RKISP_STREAM_SP) rkisp_dmarx_get_frame(dev, &stream->curr_buf->vb.sequence, - &ns, false); + NULL, &ns, false); else stream->curr_buf->vb.sequence = atomic_read(&stream->sequence) - 1; diff --git a/drivers/media/platform/rockchip/isp/capture_v21.c b/drivers/media/platform/rockchip/isp/capture_v21.c index 405aeaac57ff..87cf213c7ba3 100644 --- a/drivers/media/platform/rockchip/isp/capture_v21.c +++ b/drivers/media/platform/rockchip/isp/capture_v21.c @@ -729,7 +729,7 @@ static int mi_frame_end(struct rkisp_stream *stream) } if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) { - rkisp_dmarx_get_frame(dev, &i, &ns, true); + rkisp_dmarx_get_frame(dev, &i, NULL, &ns, true); atomic_set(&stream->sequence, i); stream->curr_buf->vb.sequence = i; } else { diff --git a/drivers/media/platform/rockchip/isp/common.c b/drivers/media/platform/rockchip/isp/common.c index bed788573cd6..bc53ac0f7c73 100644 --- a/drivers/media/platform/rockchip/isp/common.c +++ b/drivers/media/platform/rockchip/isp/common.c @@ -12,7 +12,7 @@ static const struct vb2_mem_ops *g_ops = &vb2_dma_contig_memops; void rkisp_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) { u32 *mem = dev->sw_base_addr + reg; - u32 *flag = dev->sw_base_addr + reg + ISP_SW_REG_SIZE; + u32 *flag = dev->sw_base_addr + reg + RKISP_ISP_SW_REG_SIZE; *mem = val; *flag = SW_REG_CACHE; @@ -52,13 +52,13 @@ void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end) void __iomem *base = dev->hw_dev->base_addr; u32 i; - if (end > ISP_SW_REG_SIZE - 4) { + if (end > RKISP_ISP_SW_REG_SIZE - 4) { dev_err(dev->dev, "%s out of range\n", __func__); return; } for (i = start; i <= end; i += 4) { u32 *val = dev->sw_base_addr + i; - u32 *flag = dev->sw_base_addr + i + ISP_SW_REG_SIZE; + u32 *flag = dev->sw_base_addr + i + RKISP_ISP_SW_REG_SIZE; if (*flag == SW_REG_CACHE) writel(*val, base + i); diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index 1d793bc30b43..d7eabf9ab247 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -131,6 +131,7 @@ struct rkisp_dummy_buffer { }; extern int rkisp_debug; +extern u64 rkisp_debug_reg; extern struct platform_driver rkisp_plat_drv; static inline diff --git a/drivers/media/platform/rockchip/isp/csi.c b/drivers/media/platform/rockchip/isp/csi.c index 4805b555b17c..aad9b7bbc095 100644 --- a/drivers/media/platform/rockchip/isp/csi.c +++ b/drivers/media/platform/rockchip/isp/csi.c @@ -530,7 +530,7 @@ void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm, u32 mode) bool is_upd = false; hw->cur_dev_id = dev->dev_id; - rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, true); + rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true); if (dma2frm > 2) dma2frm = 2; if (dma2frm == 2) @@ -630,6 +630,7 @@ static void rkisp_dev_trigger_handle(struct rkisp_device *dev, u32 cmd) rkisp_csi_trigger_event(isp, T_CMD_DEQUEUE, &t); isp->dmarx_dev.pre_frame = isp->dmarx_dev.cur_frame; isp->dmarx_dev.cur_frame.id = t.frame_id; + isp->dmarx_dev.cur_frame.sof_timestamp = t.sof_timestamp; isp->dmarx_dev.cur_frame.timestamp = t.frame_timestamp; mode = t.mode; times = t.times; diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 3b12d5e50fd4..5a87193eaf1b 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -67,6 +67,10 @@ static char rkisp_version[RKISP_VERNO_LEN]; module_param_string(version, rkisp_version, RKISP_VERNO_LEN, 0444); MODULE_PARM_DESC(version, "version number"); +u64 rkisp_debug_reg = 0xFFFFFFFFFLL; +module_param_named(debug_reg, rkisp_debug_reg, ullong, 0644); +MODULE_PARM_DESC(debug_reg, "rkisp debug register"); + static DEFINE_MUTEX(rkisp_dev_mutex); static LIST_HEAD(rkisp_device_list); @@ -691,7 +695,7 @@ static int rkisp_plat_probe(struct platform_device *pdev) isp_dev = devm_kzalloc(dev, sizeof(*isp_dev), GFP_KERNEL); if (!isp_dev) return -ENOMEM; - isp_dev->sw_base_addr = devm_kzalloc(dev, ISP_SW_MAX_SIZE, GFP_KERNEL); + isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE, GFP_KERNEL); if (!isp_dev->sw_base_addr) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index 1c91daf4dbb2..8d42f22a7b22 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -949,11 +949,12 @@ static int dmarx_init(struct rkisp_device *dev, u32 id) RKISP_ISP_PAD_SINK, stream->linked); } -void rkisp_dmarx_get_frame(struct rkisp_device *dev, - u32 *id, u64 *timestamp, bool sync) +void rkisp_dmarx_get_frame(struct rkisp_device *dev, u32 *id, + u64 *sof_timestamp, u64 *timestamp, + bool sync) { unsigned long flag = 0; - u64 frame_timestamp = 0; + u64 sof_time = 0, frame_timestamp = 0; u32 frame_id = 0; if (!dev->dmarx_dev.trigger && id) { @@ -964,14 +965,18 @@ void rkisp_dmarx_get_frame(struct rkisp_device *dev, spin_lock_irqsave(&dev->csi_dev.rdbk_lock, flag); if (sync) { frame_id = dev->dmarx_dev.cur_frame.id; + sof_time = dev->dmarx_dev.cur_frame.sof_timestamp; frame_timestamp = dev->dmarx_dev.cur_frame.timestamp; } else { frame_id = dev->dmarx_dev.pre_frame.id; + sof_time = dev->dmarx_dev.pre_frame.sof_timestamp; frame_timestamp = dev->dmarx_dev.pre_frame.timestamp; } spin_unlock_irqrestore(&dev->csi_dev.rdbk_lock, flag); if (id) *id = frame_id; + if (sof_timestamp) + *sof_timestamp = sof_time; if (timestamp) *timestamp = frame_timestamp; } diff --git a/drivers/media/platform/rockchip/isp/dmarx.h b/drivers/media/platform/rockchip/isp/dmarx.h index ba45e2cb9142..4ed00383fd24 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.h +++ b/drivers/media/platform/rockchip/isp/dmarx.h @@ -27,6 +27,7 @@ enum rkisp_dmarx_trigger { }; struct rkisp_dmarx_frame { + u64 sof_timestamp; u64 timestamp; u32 id; }; @@ -47,8 +48,9 @@ struct rkisp_dmarx_device { void rkisp_dmarx_isr(u32 mis_val, struct rkisp_device *dev); void rkisp2_rawrd_isr(u32 mis_val, struct rkisp_device *dev); -void rkisp_dmarx_get_frame(struct rkisp_device *dev, - u32 *id, u64 *timestamp, bool sync); +void rkisp_dmarx_get_frame(struct rkisp_device *dev, u32 *id, + u64 *sof_timestamp, u64 *timestamp, + bool sync); void rkisp_unregister_dmarx_vdev(struct rkisp_device *dev); int rkisp_register_dmarx_vdev(struct rkisp_device *dev); #endif /* _RKISP_DMARX_H */ diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 8ae99358ac62..a86b456e8c6b 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -82,7 +82,7 @@ static void default_sw_reg_flag(struct rkisp_device *dev) u32 i, *flag; for (i = 0; i < ARRAY_SIZE(reg); i++) { - flag = dev->sw_base_addr + reg[i] + ISP_SW_REG_SIZE; + flag = dev->sw_base_addr + reg[i] + RKISP_ISP_SW_REG_SIZE; *flag = SW_REG_CACHE; } } @@ -743,8 +743,8 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev) for (i = 0; i < hw_dev->dev_num; i++) { void *buf = hw_dev->isp[i]->sw_base_addr; - memset(buf, 0, ISP_SW_MAX_SIZE); - memcpy_fromio(buf, base, ISP_SW_REG_SIZE); + memset(buf, 0, RKISP_ISP_SW_MAX_SIZE); + memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); default_sw_reg_flag(hw_dev->isp[i]); } return 0; diff --git a/drivers/media/platform/rockchip/isp/isp_ispp.h b/drivers/media/platform/rockchip/isp/isp_ispp.h index d8365336689b..ce254596307f 100644 --- a/drivers/media/platform/rockchip/isp/isp_ispp.h +++ b/drivers/media/platform/rockchip/isp/isp_ispp.h @@ -6,10 +6,18 @@ #include #include +#include +#include #define RKISPP_BUF_MAX 5 #define RKISP_ISPP_BUF_MAX (RKISPP_BUF_MAX + (2 * (DEV_MAX - 1))) +#define RKISP_ISPP_REGBUF_NUM RKISPP_BUF_POOL_MAX +#define RKISP_ISP_SW_REG_SIZE 0x6000 +#define RKISP_ISP_SW_MAX_SIZE (RKISP_ISP_SW_REG_SIZE * 2) +#define RKISP_ISPP_SW_REG_SIZE 0x0d00 +#define RKISP_ISPP_SW_MAX_SIZE (RKISP_ISPP_SW_REG_SIZE * 2) + #define RKISP_ISPP_CMD_SET_MODE \ _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct rkisp_ispp_mode) #define RKISP_ISPP_CMD_SET_FMT \ @@ -41,6 +49,11 @@ enum rkisp_ispp_work_mode { ISP_ISPP_INIT_FAIL = BIT(7), }; +enum rkisp_ispp_reg_stat { + ISP_ISPP_FREE = 0, + ISP_ISPP_INUSE, +}; + struct frame_debug_info { u64 timestamp; u32 interval; @@ -59,6 +72,22 @@ struct rkisp_ispp_mode { u8 buf_num; }; +struct rkisp_ispp_reg { + enum rkisp_ispp_reg_stat stat; + u32 dev_id; + u32 frame_id; + u32 reg_size; + s32 isp_offset[ISP2X_ID_MAX]; + s32 ispp_offset[ISPP_ID_MAX]; + u32 isp_size[ISP2X_ID_MAX]; + u32 isp_stats_size[ISP2X_ID_MAX]; + u32 ispp_size[ISPP_ID_MAX]; + u64 sof_timestamp; + u64 frame_timestamp; + struct sensor_exposure_cfg exposure; + u8 reg[RKISP_ISP_SW_REG_SIZE + RKISP_ISPP_SW_REG_SIZE]; +}; + struct rkisp_ispp_buf { struct list_head list; struct dma_buf *dbuf[GROUP_BUF_MAX]; @@ -84,4 +113,20 @@ static inline void rkisp_get_bridge_sd(struct platform_device *dev, } #endif +#if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISPP) +void rkispp_request_regbuf(struct v4l2_subdev *sd, struct rkisp_ispp_reg **free_buf); +bool rkispp_get_reg_withstream(void); +#else +static inline void rkispp_request_regbuf(struct v4l2_subdev *sd, + struct rkisp_ispp_reg **free_buf) +{ + *free_buf = NULL; +} + +static inline bool rkispp_get_reg_withstream(void) +{ + return false; +} +#endif + #endif diff --git a/drivers/media/platform/rockchip/isp/isp_params.h b/drivers/media/platform/rockchip/isp/isp_params.h index afb5803fe1f8..9f45d540c048 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.h +++ b/drivers/media/platform/rockchip/isp/isp_params.h @@ -76,6 +76,7 @@ struct rkisp_isp_params_vdev { struct isp2x_hdrmge_cfg cur_hdrmge; struct isp21_drc_cfg cur_hdrdrc; struct isp2x_lsc_cfg cur_lsccfg; + struct sensor_exposure_cfg exposure; }; /* config params before ISP streaming */ diff --git a/drivers/media/platform/rockchip/isp/isp_params_v21.c b/drivers/media/platform/rockchip/isp/isp_params_v21.c index cbd360d9120d..4fd4908022df 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v21.c @@ -4165,7 +4165,7 @@ rkisp_params_isr_v2x(struct rkisp_isp_params_vdev *params_vdev, struct rkisp_device *dev = params_vdev->dev; u32 cur_frame_id; - rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, true); + rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true); if (isp_mis & CIF_ISP_V_START) { if (!params_vdev->cur_buf) return; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v2x.c b/drivers/media/platform/rockchip/isp/isp_params_v2x.c index 4350992cd023..f397429bd1d7 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v2x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v2x.c @@ -4431,6 +4431,7 @@ rkisp_params_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev, params_vdev->rdbk_times = rdbk_times; } + params_vdev->exposure = new_params->exposure; unlock: params_vdev->cur_buf = cur_buf; spin_unlock(¶ms_vdev->config_lock); @@ -4443,7 +4444,7 @@ rkisp_params_isr_v2x(struct rkisp_isp_params_vdev *params_vdev, struct rkisp_device *dev = params_vdev->dev; u32 cur_frame_id; - rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, true); + rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true); if (isp_mis & CIF_ISP_V_START) { if (!params_vdev->cur_buf) return; diff --git a/drivers/media/platform/rockchip/isp/isp_stats.h b/drivers/media/platform/rockchip/isp/isp_stats.h index 2b5e2c645a3d..c3421cc89830 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.h +++ b/drivers/media/platform/rockchip/isp/isp_stats.h @@ -68,6 +68,8 @@ struct rkisp_isp_stats_vdev { bool rdbk_mode; u32 isp_rdbk; u32 isp3a_rdbk; + + struct rkisp_dummy_buffer tmp_statsbuf; }; void rkisp_stats_rdbk_enable(struct rkisp_isp_stats_vdev *stats_vdev, bool en); diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v21.c b/drivers/media/platform/rockchip/isp/isp_stats_v21.c index 349fe41f4846..75e776611113 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v21.c @@ -915,7 +915,7 @@ rkisp_stats_isr_v2x(struct rkisp_isp_stats_vdev *stats_vdev, u32 wr_buf_idx; u32 temp_isp_ris, temp_isp3a_ris; - rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, true); + rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, NULL, true); #ifdef LOG_ISR_EXE_TIME ktime_t in_t = ktime_get(); #endif diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v2x.c b/drivers/media/platform/rockchip/isp/isp_stats_v2x.c index d77d5eca792d..7d65902d32e0 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v2x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v2x.c @@ -1261,6 +1261,13 @@ rkisp_stats_send_meas_v2x(struct rkisp_isp_stats_vdev *stats_vdev, sizeof(struct rkisp_isp2x_stat_buffer)); cur_buf->vb.sequence = cur_frame_id; cur_buf->vb.vb2_buf.timestamp = meas_work->timestamp; + if (rkispp_get_reg_withstream()) { + struct rkisp_isp2x_stat_buffer *tmp_statsbuf; + + tmp_statsbuf = (struct rkisp_isp2x_stat_buffer *)stats_vdev->tmp_statsbuf.vaddr; + if (tmp_statsbuf) + memcpy(tmp_statsbuf, cur_stat_buf, sizeof(*cur_stat_buf)); + } vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } } @@ -1330,7 +1337,7 @@ rkisp_stats_isr_v2x(struct rkisp_isp_stats_vdev *stats_vdev, u32 wr_buf_idx; u32 temp_isp_ris, temp_isp3a_ris; - rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, true); + rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, NULL, true); #ifdef LOG_ISR_EXE_TIME ktime_t in_t = ktime_get(); #endif @@ -1466,6 +1473,12 @@ void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) rkisp_set_bits(stats_vdev->dev, CTRL_SWS_CFG, SW_3A_DDR_WRITE_EN, SW_3A_DDR_WRITE_EN, false); } + + if (rkispp_get_reg_withstream()) { + stats_vdev->tmp_statsbuf.is_need_vaddr = true; + stats_vdev->tmp_statsbuf.size = sizeof(struct rkisp_isp2x_stat_buffer); + rkisp_alloc_buffer(stats_vdev->dev, &stats_vdev->tmp_statsbuf); + } } void rkisp_init_stats_vdev_v2x(struct rkisp_isp_stats_vdev *stats_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v2x.h b/drivers/media/platform/rockchip/isp/isp_stats_v2x.h index 7efe9d15fc0a..40850f1c14bb 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v2x.h +++ b/drivers/media/platform/rockchip/isp/isp_stats_v2x.h @@ -9,7 +9,7 @@ #include #include "common.h" -//#define RKISP_RD_STATS_FROM_DDR +// #define RKISP_RD_STATS_FROM_DDR #define RKISP_RD_STATS_BUF_SIZE 0x35000 struct rkisp_isp_stats_vdev; diff --git a/drivers/media/platform/rockchip/isp/regs_v2x.h b/drivers/media/platform/rockchip/isp/regs_v2x.h index bd5e28cbcdbb..a3c38fecd802 100644 --- a/drivers/media/platform/rockchip/isp/regs_v2x.h +++ b/drivers/media/platform/rockchip/isp/regs_v2x.h @@ -6,9 +6,6 @@ #ifndef _RKISP_REGS_V2X_H #define _RKISP_REGS_V2X_H -#define ISP_SW_REG_SIZE 0x6000 -#define ISP_SW_MAX_SIZE (ISP_SW_REG_SIZE * 2) - #define CTRL_BASE 0x00000000 #define CTRL_VI_ISP_EN (CTRL_BASE + 0x00000) #define CTRL_VI_ISP_PATH (CTRL_BASE + 0x00004) diff --git a/drivers/media/platform/rockchip/ispp/common.c b/drivers/media/platform/rockchip/ispp/common.c index 37b7a5586123..7fd815de5f34 100644 --- a/drivers/media/platform/rockchip/ispp/common.c +++ b/drivers/media/platform/rockchip/ispp/common.c @@ -13,7 +13,7 @@ static const struct vb2_mem_ops *g_ops = &vb2_dma_contig_memops; void rkispp_write(struct rkispp_device *dev, u32 reg, u32 val) { u32 *mem = dev->sw_base_addr + reg; - u32 *flag = dev->sw_base_addr + reg + ISPP_SW_REG_SIZE; + u32 *flag = dev->sw_base_addr + reg + RKISP_ISPP_SW_REG_SIZE; *mem = val; *flag = SW_REG_CACHE; @@ -51,13 +51,13 @@ void rkispp_update_regs(struct rkispp_device *dev, u32 start, u32 end) void __iomem *base = dev->hw_dev->base_addr; u32 i; - if (end > ISPP_SW_REG_SIZE - 4) { + if (end > RKISP_ISPP_SW_REG_SIZE - 4) { dev_err(dev->dev, "%s out of range\n", __func__); return; } for (i = start; i <= end; i += 4) { u32 *val = dev->sw_base_addr + i; - u32 *flag = dev->sw_base_addr + i + ISPP_SW_REG_SIZE; + u32 *flag = dev->sw_base_addr + i + RKISP_ISPP_SW_REG_SIZE; if (*flag == SW_REG_CACHE) writel(*val, base + i); @@ -164,6 +164,66 @@ int rkispp_attach_hw(struct rkispp_device *ispp) return 0; } +static int rkispp_init_regbuf(struct rkispp_hw_dev *hw) +{ + struct rkisp_ispp_reg *reg_buf; + u32 i, buf_size; + + if (!rkispp_reg_withstream) { + hw->reg_buf = NULL; + return 0; + } + + buf_size = RKISP_ISPP_REGBUF_NUM * sizeof(struct rkisp_ispp_reg); + hw->reg_buf = vmalloc(buf_size); + if (!hw->reg_buf) + return -ENOMEM; + + reg_buf = hw->reg_buf; + for (i = 0; i < RKISP_ISPP_REGBUF_NUM; i++) { + reg_buf[i].stat = ISP_ISPP_FREE; + reg_buf[i].dev_id = 0xFF; + reg_buf[i].frame_id = 0; + reg_buf[i].reg_size = 0; + reg_buf[i].sof_timestamp = 0LL; + reg_buf[i].frame_timestamp = 0LL; + } + + return 0; +} + +static void rkispp_free_regbuf(struct rkispp_hw_dev *hw) +{ + if (hw->reg_buf) { + vfree(hw->reg_buf); + hw->reg_buf = NULL; + } +} + +static int rkispp_find_regbuf_by_stat(struct rkispp_hw_dev *hw, struct rkisp_ispp_reg **free_buf, + enum rkisp_ispp_reg_stat stat) +{ + struct rkisp_ispp_reg *reg_buf = hw->reg_buf; + int i = 0, ret; + + *free_buf = NULL; + if (!hw->reg_buf || !rkispp_reg_withstream) + return -EINVAL; + + for (i = 0; i < RKISP_ISPP_REGBUF_NUM; i++) { + if (reg_buf[i].stat == stat) + break; + } + + ret = -ENODATA; + if (i < RKISP_ISPP_REGBUF_NUM) { + ret = 0; + *free_buf = ®_buf[i]; + } + + return ret; +} + static void rkispp_free_pool(struct rkispp_hw_dev *hw) { struct rkispp_isp_buf_pool *buf; @@ -188,6 +248,8 @@ static void rkispp_free_pool(struct rkispp_hw_dev *hw) } buf->dbufs = NULL; } + + rkispp_free_regbuf(hw); } static int rkispp_init_pool(struct rkispp_hw_dev *hw, struct rkisp_ispp_buf *dbufs) @@ -224,6 +286,7 @@ static int rkispp_init_pool(struct rkispp_hw_dev *hw, struct rkisp_ispp_buf *dbu dev_info(hw->dev, "%s dma[%d]:0x%x\n", __func__, i, (u32)pool->dma[i]); } + rkispp_init_regbuf(hw); return ret; err: rkispp_free_pool(hw); @@ -347,3 +410,75 @@ void rkispp_free_common_dummy_buf(struct rkispp_device *dev) return; rkispp_free_buffer(dev, &dev->hw_dev->dummy_buf); } + +int rkispp_find_regbuf_by_id(struct rkispp_device *ispp, struct rkisp_ispp_reg **free_buf, + u32 dev_id, u32 frame_id) +{ + struct rkispp_hw_dev *hw = ispp->hw_dev; + struct rkisp_ispp_reg *reg_buf = hw->reg_buf; + int i = 0, ret; + + *free_buf = NULL; + if (!hw->reg_buf) + return -EINVAL; + + for (i = 0; i < RKISP_ISPP_REGBUF_NUM; i++) { + if (reg_buf[i].dev_id == dev_id && reg_buf[i].frame_id == frame_id) + break; + } + + ret = -ENODATA; + if (i < RKISP_ISPP_REGBUF_NUM) { + ret = 0; + *free_buf = ®_buf[i]; + } + + return ret; +} + +void rkispp_release_regbuf(struct rkispp_device *ispp, struct rkisp_ispp_reg *freebuf) +{ + struct rkispp_hw_dev *hw = ispp->hw_dev; + struct rkisp_ispp_reg *reg_buf = hw->reg_buf; + int i; + + if (!hw->reg_buf) + return; + + for (i = 0; i < RKISP_ISPP_REGBUF_NUM; i++) { + if (reg_buf[i].dev_id == freebuf->dev_id && + reg_buf[i].frame_timestamp < freebuf->frame_timestamp) { + reg_buf[i].frame_id = 0; + reg_buf[i].stat = ISP_ISPP_FREE; + } + } + + freebuf->frame_id = 0; + freebuf->stat = ISP_ISPP_FREE; +} + +void rkispp_request_regbuf(struct v4l2_subdev *sd, struct rkisp_ispp_reg **free_buf) +{ + struct rkispp_subdev *ispp_sdev = v4l2_get_subdevdata(sd); + struct rkispp_device *dev = ispp_sdev->dev; + struct rkispp_hw_dev *hw = dev->hw_dev; + int ret; + + if (!hw->reg_buf) { + *free_buf = NULL; + return; + } + + ret = rkispp_find_regbuf_by_stat(hw, free_buf, ISP_ISPP_FREE); + if (!ret) { + (*free_buf)->stat = ISP_ISPP_INUSE; + } +} +EXPORT_SYMBOL(rkispp_request_regbuf); + +bool rkispp_get_reg_withstream(void) +{ + return rkispp_reg_withstream; +} +EXPORT_SYMBOL(rkispp_get_reg_withstream); + diff --git a/drivers/media/platform/rockchip/ispp/common.h b/drivers/media/platform/rockchip/ispp/common.h index cec14cd77bf6..c43be6c04811 100644 --- a/drivers/media/platform/rockchip/ispp/common.h +++ b/drivers/media/platform/rockchip/ispp/common.h @@ -99,6 +99,8 @@ static inline struct vb2_queue *to_vb2_queue(struct file *file) extern int rkispp_debug; extern bool rkispp_clk_dbg; extern bool rkispp_monitor; +extern bool rkispp_reg_withstream; +extern unsigned int rkispp_debug_reg; extern struct platform_driver rkispp_plat_drv; void rkispp_write(struct rkispp_device *dev, u32 reg, u32 val); @@ -116,4 +118,7 @@ int rkispp_event_handle(struct rkispp_device *ispp, u32 cmd, void *arg); void rkispp_soft_reset(struct rkispp_device *ispp); int rkispp_alloc_common_dummy_buf(struct rkispp_device *dev); void rkispp_free_common_dummy_buf(struct rkispp_device *dev); +int rkispp_find_regbuf_by_id(struct rkispp_device *ispp, struct rkisp_ispp_reg **free_buf, + u32 dev_id, u32 frame_id); +void rkispp_release_regbuf(struct rkispp_device *ispp, struct rkisp_ispp_reg *freebuf); #endif diff --git a/drivers/media/platform/rockchip/ispp/dev.c b/drivers/media/platform/rockchip/ispp/dev.c index 1e7c2a68296f..4b5d5caf42cd 100644 --- a/drivers/media/platform/rockchip/ispp/dev.c +++ b/drivers/media/platform/rockchip/ispp/dev.c @@ -47,6 +47,14 @@ static char rkispp_version[RKISPP_VERNO_LEN]; module_param_string(version, rkispp_version, RKISPP_VERNO_LEN, 0444); MODULE_PARM_DESC(version, "version number"); +bool rkispp_reg_withstream; +module_param_named(sendreg_withstream, rkispp_reg_withstream, bool, 0644); +MODULE_PARM_DESC(sendreg_withstream, "rkispp send reg out with stream"); + +unsigned int rkispp_debug_reg = 0x1F; +module_param_named(debug_reg, rkispp_debug_reg, uint, 0644); +MODULE_PARM_DESC(debug_reg, "rkispp debug register"); + static void get_remote_node_dev(struct rkispp_device *ispp_dev) { struct device *dev = ispp_dev->dev; @@ -225,7 +233,7 @@ static int rkispp_plat_probe(struct platform_device *pdev) ispp_dev = devm_kzalloc(dev, sizeof(*ispp_dev), GFP_KERNEL); if (!ispp_dev) return -ENOMEM; - ispp_dev->sw_base_addr = devm_kzalloc(dev, ISPP_SW_MAX_SIZE, GFP_KERNEL); + ispp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISPP_SW_MAX_SIZE, GFP_KERNEL); if (!ispp_dev->sw_base_addr) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/ispp/hw.c b/drivers/media/platform/rockchip/ispp/hw.c index 13a844759bf5..378698111947 100644 --- a/drivers/media/platform/rockchip/ispp/hw.c +++ b/drivers/media/platform/rockchip/ispp/hw.c @@ -54,7 +54,7 @@ static void default_sw_reg_flag(struct rkispp_device *dev) u32 i, *flag; for (i = 0; i < ARRAY_SIZE(reg); i++) { - flag = dev->sw_base_addr + reg[i] + ISPP_SW_REG_SIZE; + flag = dev->sw_base_addr + reg[i] + RKISP_ISPP_SW_REG_SIZE; *flag = 0xffffffff; } } @@ -338,8 +338,8 @@ static int __maybe_unused rkispp_runtime_resume(struct device *dev) for (i = 0; i < hw_dev->dev_num; i++) { void *buf = hw_dev->ispp[i]->sw_base_addr; - memset(buf, 0, ISPP_SW_MAX_SIZE); - memcpy_fromio(buf, base, ISPP_SW_REG_SIZE); + memset(buf, 0, RKISP_ISPP_SW_MAX_SIZE); + memcpy_fromio(buf, base, RKISP_ISPP_SW_REG_SIZE); default_sw_reg_flag(hw_dev->ispp[i]); } hw_dev->is_idle = true; diff --git a/drivers/media/platform/rockchip/ispp/hw.h b/drivers/media/platform/rockchip/ispp/hw.h index a7a236747e25..cc14eeeb98ed 100644 --- a/drivers/media/platform/rockchip/ispp/hw.h +++ b/drivers/media/platform/rockchip/ispp/hw.h @@ -51,5 +51,6 @@ struct rkispp_hw_dev { bool is_idle; bool is_single; bool is_fec_ext; + struct rkisp_ispp_reg *reg_buf; }; #endif diff --git a/drivers/media/platform/rockchip/ispp/regs.h b/drivers/media/platform/rockchip/ispp/regs.h index c48cf2966b03..fce1b09b1f15 100644 --- a/drivers/media/platform/rockchip/ispp/regs.h +++ b/drivers/media/platform/rockchip/ispp/regs.h @@ -4,9 +4,6 @@ #ifndef _RKISPP_REGS_H #define _RKISPP_REGS_H -#define ISPP_SW_REG_SIZE 0x0d00 -#define ISPP_SW_MAX_SIZE (ISPP_SW_REG_SIZE * 2) - /* registers */ #define RKISPP_CTRL 0x0000 #define RKISPP_CTRL_STRT (RKISPP_CTRL + 0x0000) diff --git a/drivers/media/platform/rockchip/ispp/stream.c b/drivers/media/platform/rockchip/ispp/stream.c index 3ec95b1acf03..347bae7b1268 100644 --- a/drivers/media/platform/rockchip/ispp/stream.c +++ b/drivers/media/platform/rockchip/ispp/stream.c @@ -325,6 +325,7 @@ static int rkispp_frame_end(struct rkispp_stream *stream) { struct rkispp_device *dev = stream->isppdev; struct capture_fmt *fmt = &stream->out_cap_fmt; + struct rkisp_ispp_reg *reg_buf; unsigned long lock_flags = 0; int i = 0; @@ -343,8 +344,29 @@ static int rkispp_frame_end(struct rkispp_stream *stream) payload_size); } stream->curr_buf->vb.sequence = - atomic_read(&dev->ispp_sdev.frm_sync_seq) - 1; + atomic_read(&dev->ispp_sdev.frm_sync_seq); stream->curr_buf->vb.vb2_buf.timestamp = ns; + + if (rkispp_reg_withstream && (fmt->wr_fmt & FMT_FBC)) { + void *addr = vb2_plane_vaddr(&stream->curr_buf->vb.vb2_buf, i); + + rkispp_find_regbuf_by_id(dev, ®_buf, dev->dev_id, + stream->curr_buf->vb.sequence); + if (reg_buf) { + u32 cpy_size = offsetof(struct rkisp_ispp_reg, reg); + + cpy_size += reg_buf->reg_size; + memcpy(addr, reg_buf, cpy_size); + + rkispp_release_regbuf(dev, reg_buf); + vb2_set_plane_payload(&stream->curr_buf->vb.vb2_buf, 1, cpy_size); + } else { + v4l2_err(&dev->v4l2_dev, + "%s can not find reg buf: dev_id %d, sequence %d\n", + __func__, dev->dev_id, stream->curr_buf->vb.sequence); + } + } + vb2_buffer_done(&stream->curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); @@ -355,6 +377,17 @@ static int rkispp_frame_end(struct rkispp_stream *stream) stream->dbg.id = stream->curr_buf->vb.sequence; stream->curr_buf = NULL; + } else if (rkispp_reg_withstream && (fmt->wr_fmt & FMT_FBC)) { + u32 frame_id; + + frame_id = atomic_read(&dev->ispp_sdev.frm_sync_seq); + rkispp_find_regbuf_by_id(dev, ®_buf, dev->dev_id, frame_id); + if (reg_buf) { + rkispp_release_regbuf(dev, reg_buf); + v4l2_info(&dev->v4l2_dev, + "%s: current frame use dummy buffer(dev_id %d, sequence %d)\n", + __func__, dev->dev_id, frame_id); + } } spin_lock_irqsave(&stream->vbq_lock, lock_flags); @@ -1308,6 +1341,11 @@ static int rkispp_queue_setup(struct vb2_queue *queue, plane_fmt->sizeimage; } + if (rkispp_reg_withstream && (cap_fmt->wr_fmt & FMT_FBC)) { + (*num_planes)++; + sizes[1] = sizeof(struct rkisp_ispp_reg); + } + v4l2_dbg(1, rkispp_debug, &dev->v4l2_dev, "%s stream:%d count %d, size %d\n", v4l2_type_names[queue->type], @@ -1696,6 +1734,9 @@ static int rkispp_set_fmt(struct rkispp_stream *stream, if (fmt->mplanes == 1) pixm->plane_fmt[0].sizeimage = imagsize; + if ((fmt->wr_fmt & FMT_FBC) && rkispp_reg_withstream) + pixm->num_planes++; + if (!try) { stream->out_cap_fmt = *fmt; stream->out_fmt = *pixm; @@ -2063,6 +2104,7 @@ static void fec_work_event(struct rkispp_device *dev, struct rkispp_dummy_buffer *dummy; unsigned long lock_flags = 0, lock_flags1 = 0; bool is_start = false, is_quick = false; + struct rkisp_ispp_reg *reg_buf; u32 val; if (!(vdev->module_ens & ISPP_MODULE_FEC)) @@ -2154,6 +2196,20 @@ static void fec_work_event(struct rkispp_device *dev, if (!completion_done(&monitor->fec.cmpl)) complete(&monitor->fec.cmpl); } + + rkispp_find_regbuf_by_id(dev, ®_buf, dev->dev_id, seq); + if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_FEC)) { + u32 offset, size; + + offset = reg_buf->reg_size; + size = 4 + RKISPP_FEC_CROP - RKISPP_FEC_CTRL; + reg_buf->ispp_size[ISPP_ID_FEC] = size; + reg_buf->ispp_offset[ISPP_ID_FEC] = offset; + memcpy_fromio(®_buf->reg[offset], base + RKISPP_FEC_CTRL, size); + + offset += size; + reg_buf->reg_size = offset; + } writel(FEC_ST, base + RKISPP_CTRL_STRT); vdev->fec.is_end = false; } @@ -2180,6 +2236,7 @@ static void nr_work_event(struct rkispp_device *dev, bool is_start = false, is_quick = false; bool is_tnr_en = vdev->module_ens & ISPP_MODULE_TNR; bool is_fec_en = (vdev->module_ens & ISPP_MODULE_FEC); + struct rkisp_ispp_reg *reg_buf; u32 val; if (!(vdev->module_ens & (ISPP_MODULE_NR | ISPP_MODULE_SHP))) @@ -2353,6 +2410,44 @@ static void nr_work_event(struct rkispp_device *dev, if (!completion_done(&monitor->nr.cmpl)) complete(&monitor->nr.cmpl); } + + rkispp_find_regbuf_by_id(dev, ®_buf, dev->dev_id, seq); + if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_NR)) { + u32 offset, size; + + offset = reg_buf->reg_size; + size = 4 + RKISPP_NR_BUFFER_READY - RKISPP_NR_CTRL; + reg_buf->ispp_size[ISPP_ID_NR] = size; + reg_buf->ispp_offset[ISPP_ID_NR] = offset; + memcpy_fromio(®_buf->reg[offset], base + RKISPP_NR_CTRL, size); + + offset += size; + reg_buf->reg_size = offset; + } + if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_SHP)) { + u32 offset, size; + + offset = reg_buf->reg_size; + size = 4 + RKISPP_SHARP_GRAD_RATIO - RKISPP_SHARP_CTRL; + reg_buf->ispp_size[ISPP_ID_SHP] = size; + reg_buf->ispp_offset[ISPP_ID_SHP] = offset; + memcpy_fromio(®_buf->reg[offset], base + RKISPP_SHARP_CTRL, size); + + offset += size; + reg_buf->reg_size = offset; + } + if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_ORB)) { + u32 offset, size; + + offset = reg_buf->reg_size; + size = 4 + RKISPP_ORB_MAX_FEATURE - RKISPP_ORB_WR_BASE; + reg_buf->ispp_size[ISPP_ID_ORB] = size; + reg_buf->ispp_offset[ISPP_ID_ORB] = offset; + memcpy_fromio(®_buf->reg[offset], base + RKISPP_ORB_WR_BASE, size); + + offset += size; + reg_buf->reg_size = offset; + } if (!is_quick) writel(NR_SHP_ST, base + RKISPP_CTRL_STRT); vdev->nr.is_end = false; @@ -2387,6 +2482,7 @@ static void tnr_work_event(struct rkispp_device *dev, u32 val, size = sizeof(vdev->tnr.buf) / sizeof(*dummy); bool is_3to1 = vdev->tnr.is_3to1, is_start = false, is_skip = false; bool is_en = rkispp_read(dev, RKISPP_TNR_CORE_CTRL) & SW_TNR_EN; + struct rkisp_ispp_reg *reg_buf; if (!(vdev->module_ens & ISPP_MODULE_TNR) || (dev->inp == INP_ISP && dev->isp_mode & ISP_ISPP_QUICK)) @@ -2574,6 +2670,19 @@ static void tnr_work_event(struct rkispp_device *dev, if (!completion_done(&monitor->tnr.cmpl)) complete(&monitor->tnr.cmpl); } + rkispp_find_regbuf_by_id(dev, ®_buf, dev->dev_id, seq); + if (reg_buf && (rkispp_debug_reg & ISPP_MODULE_TNR)) { + u32 offset, size; + + offset = reg_buf->reg_size; + size = 4 + RKISPP_TNR_STATE - RKISPP_TNR_CTRL; + reg_buf->ispp_size[ISPP_ID_TNR] = size; + reg_buf->ispp_offset[ISPP_ID_TNR] = offset; + memcpy_fromio(®_buf->reg[offset], base + RKISPP_TNR_CTRL, size); + + offset += size; + reg_buf->reg_size = offset; + } writel(TNR_ST, base + RKISPP_CTRL_STRT); vdev->tnr.is_end = false; } diff --git a/drivers/media/platform/rockchip/ispp/stream.h b/drivers/media/platform/rockchip/ispp/stream.h index 7c764bc713b5..5d28c0f14e4d 100644 --- a/drivers/media/platform/rockchip/ispp/stream.h +++ b/drivers/media/platform/rockchip/ispp/stream.h @@ -94,6 +94,7 @@ struct tnr_module { struct rkisp_ispp_buf *cur_rd; struct rkisp_ispp_buf *nxt_rd; struct rkisp_ispp_buf *cur_wr; + struct rkisp_ispp_reg *reg_buf; struct frame_debug_info dbg; u32 uv_offset; bool is_end; @@ -107,6 +108,7 @@ struct nr_module { spinlock_t buf_lock; struct rkisp_ispp_buf *cur_rd; struct rkispp_dummy_buffer *cur_wr; + struct rkisp_ispp_reg *reg_buf; struct frame_debug_info dbg; u32 uv_offset; bool is_end; @@ -115,6 +117,7 @@ struct nr_module { struct fec_module { struct list_head list_rd; struct rkispp_dummy_buffer *cur_rd; + struct rkisp_ispp_reg *reg_buf; struct frame_debug_info dbg; spinlock_t buf_lock; u32 uv_offset; diff --git a/include/uapi/linux/rkisp2-config.h b/include/uapi/linux/rkisp2-config.h index 07dcb432cad4..23ed615038b5 100644 --- a/include/uapi/linux/rkisp2-config.h +++ b/include/uapi/linux/rkisp2-config.h @@ -30,41 +30,78 @@ #define RKISP_CMD_SET_LDCHBUF_SIZE \ _IOW('V', BASE_VIDIOC_PRIVATE + 5, struct rkisp_ldchbuf_size) -#define ISP2X_MODULE_DPCC BIT_ULL(0) -#define ISP2X_MODULE_BLS BIT_ULL(1) -#define ISP2X_MODULE_SDG BIT_ULL(2) -#define ISP2X_MODULE_SIHST BIT_ULL(3) -#define ISP2X_MODULE_LSC BIT_ULL(4) -#define ISP2X_MODULE_AWB_GAIN BIT_ULL(5) -#define ISP2X_MODULE_BDM BIT_ULL(7) -#define ISP2X_MODULE_CCM BIT_ULL(8) -#define ISP2X_MODULE_GOC BIT_ULL(9) -#define ISP2X_MODULE_CPROC BIT_ULL(10) -#define ISP2X_MODULE_SIAF BIT_ULL(11) -#define ISP2X_MODULE_SIAWB BIT_ULL(12) -#define ISP2X_MODULE_IE BIT_ULL(13) -#define ISP2X_MODULE_YUVAE BIT_ULL(14) -#define ISP2X_MODULE_WDR BIT_ULL(15) -#define ISP2X_MODULE_RK_IESHARP BIT_ULL(16) -#define ISP2X_MODULE_RAWAF BIT_ULL(17) -#define ISP2X_MODULE_RAWAE0 BIT_ULL(18) -#define ISP2X_MODULE_RAWAE1 BIT_ULL(19) -#define ISP2X_MODULE_RAWAE2 BIT_ULL(20) -#define ISP2X_MODULE_RAWAE3 BIT_ULL(21) -#define ISP2X_MODULE_RAWAWB BIT_ULL(22) -#define ISP2X_MODULE_RAWHIST0 BIT_ULL(23) -#define ISP2X_MODULE_RAWHIST1 BIT_ULL(24) -#define ISP2X_MODULE_RAWHIST2 BIT_ULL(25) -#define ISP2X_MODULE_RAWHIST3 BIT_ULL(26) -#define ISP2X_MODULE_HDRMGE BIT_ULL(27) -#define ISP2X_MODULE_RAWNR BIT_ULL(28) -#define ISP2X_MODULE_HDRTMO BIT_ULL(29) -#define ISP2X_MODULE_GIC BIT_ULL(30) -#define ISP2X_MODULE_DHAZ BIT_ULL(31) -#define ISP2X_MODULE_3DLUT BIT_ULL(32) -#define ISP2X_MODULE_LDCH BIT_ULL(33) -#define ISP2X_MODULE_GAIN BIT_ULL(34) -#define ISP2X_MODULE_DEBAYER BIT_ULL(35) +#define ISP2X_ID_DPCC (0) +#define ISP2X_ID_BLS (1) +#define ISP2X_ID_SDG (2) +#define ISP2X_ID_SIHST (3) +#define ISP2X_ID_LSC (4) +#define ISP2X_ID_AWB_GAIN (5) +#define ISP2X_ID_BDM (7) +#define ISP2X_ID_CCM (8) +#define ISP2X_ID_GOC (9) +#define ISP2X_ID_CPROC (10) +#define ISP2X_ID_SIAF (11) +#define ISP2X_ID_SIAWB (12) +#define ISP2X_ID_IE (13) +#define ISP2X_ID_YUVAE (14) +#define ISP2X_ID_WDR (15) +#define ISP2X_ID_RK_IESHARP (16) +#define ISP2X_ID_RAWAF (17) +#define ISP2X_ID_RAWAE0 (18) +#define ISP2X_ID_RAWAE1 (19) +#define ISP2X_ID_RAWAE2 (20) +#define ISP2X_ID_RAWAE3 (21) +#define ISP2X_ID_RAWAWB (22) +#define ISP2X_ID_RAWHIST0 (23) +#define ISP2X_ID_RAWHIST1 (24) +#define ISP2X_ID_RAWHIST2 (25) +#define ISP2X_ID_RAWHIST3 (26) +#define ISP2X_ID_HDRMGE (27) +#define ISP2X_ID_RAWNR (28) +#define ISP2X_ID_HDRTMO (29) +#define ISP2X_ID_GIC (30) +#define ISP2X_ID_DHAZ (31) +#define ISP2X_ID_3DLUT (32) +#define ISP2X_ID_LDCH (33) +#define ISP2X_ID_GAIN (34) +#define ISP2X_ID_DEBAYER (35) +#define ISP2X_ID_MAX (36) + +#define ISP2X_MODULE_DPCC BIT_ULL(ISP2X_ID_DPCC) +#define ISP2X_MODULE_BLS BIT_ULL(ISP2X_ID_BLS) +#define ISP2X_MODULE_SDG BIT_ULL(ISP2X_ID_SDG) +#define ISP2X_MODULE_SIHST BIT_ULL(ISP2X_ID_SIHST) +#define ISP2X_MODULE_LSC BIT_ULL(ISP2X_ID_LSC) +#define ISP2X_MODULE_AWB_GAIN BIT_ULL(ISP2X_ID_AWB_GAIN) +#define ISP2X_MODULE_BDM BIT_ULL(ISP2X_ID_BDM) +#define ISP2X_MODULE_CCM BIT_ULL(ISP2X_ID_CCM) +#define ISP2X_MODULE_GOC BIT_ULL(ISP2X_ID_GOC) +#define ISP2X_MODULE_CPROC BIT_ULL(ISP2X_ID_CPROC) +#define ISP2X_MODULE_SIAF BIT_ULL(ISP2X_ID_SIAF) +#define ISP2X_MODULE_SIAWB BIT_ULL(ISP2X_ID_SIAWB) +#define ISP2X_MODULE_IE BIT_ULL(ISP2X_ID_IE) +#define ISP2X_MODULE_YUVAE BIT_ULL(ISP2X_ID_YUVAE) +#define ISP2X_MODULE_WDR BIT_ULL(ISP2X_ID_WDR) +#define ISP2X_MODULE_RK_IESHARP BIT_ULL(ISP2X_ID_RK_IESHARP) +#define ISP2X_MODULE_RAWAF BIT_ULL(ISP2X_ID_RAWAF) +#define ISP2X_MODULE_RAWAE0 BIT_ULL(ISP2X_ID_RAWAE0) +#define ISP2X_MODULE_RAWAE1 BIT_ULL(ISP2X_ID_RAWAE1) +#define ISP2X_MODULE_RAWAE2 BIT_ULL(ISP2X_ID_RAWAE2) +#define ISP2X_MODULE_RAWAE3 BIT_ULL(ISP2X_ID_RAWAE3) +#define ISP2X_MODULE_RAWAWB BIT_ULL(ISP2X_ID_RAWAWB) +#define ISP2X_MODULE_RAWHIST0 BIT_ULL(ISP2X_ID_RAWHIST0) +#define ISP2X_MODULE_RAWHIST1 BIT_ULL(ISP2X_ID_RAWHIST1) +#define ISP2X_MODULE_RAWHIST2 BIT_ULL(ISP2X_ID_RAWHIST2) +#define ISP2X_MODULE_RAWHIST3 BIT_ULL(ISP2X_ID_RAWHIST3) +#define ISP2X_MODULE_HDRMGE BIT_ULL(ISP2X_ID_HDRMGE) +#define ISP2X_MODULE_RAWNR BIT_ULL(ISP2X_ID_RAWNR) +#define ISP2X_MODULE_HDRTMO BIT_ULL(ISP2X_ID_HDRTMO) +#define ISP2X_MODULE_GIC BIT_ULL(ISP2X_ID_GIC) +#define ISP2X_MODULE_DHAZ BIT_ULL(ISP2X_ID_DHAZ) +#define ISP2X_MODULE_3DLUT BIT_ULL(ISP2X_ID_3DLUT) +#define ISP2X_MODULE_LDCH BIT_ULL(ISP2X_ID_LDCH) +#define ISP2X_MODULE_GAIN BIT_ULL(ISP2X_ID_GAIN) +#define ISP2X_MODULE_DEBAYER BIT_ULL(ISP2X_ID_DEBAYER) /* * Measurement types @@ -179,6 +216,7 @@ enum isp2x_trigger_mode { struct isp2x_csi_trigger { /* timestamp in ns */ + u64 sof_timestamp; u64 frame_timestamp; u32 frame_id; int times; @@ -1439,6 +1477,19 @@ struct isp2x_isp_meas_cfg { struct isp2x_sihst_cfg sihst; } __attribute__ ((packed)); +struct sensor_exposure_s { + u32 fine_integration_time; + u32 coarse_integration_time; + u32 analog_gain_code_global; + u32 digital_gain_global; + u32 isp_digital_gain; +} __attribute__ ((packed)); + +struct sensor_exposure_cfg { + struct sensor_exposure_s linear_exp; + struct sensor_exposure_s hdr_exp[3]; +} __attribute__ ((packed)); + struct isp2x_isp_params_cfg { u64 module_en_update; u64 module_ens; @@ -1446,7 +1497,8 @@ struct isp2x_isp_params_cfg { u32 frame_id; struct isp2x_isp_meas_cfg meas; - struct isp2x_isp_other_cfg others; // must be last item + struct isp2x_isp_other_cfg others; + struct sensor_exposure_cfg exposure; } __attribute__ ((packed)); struct isp2x_siawb_meas { diff --git a/include/uapi/linux/rkispp-config.h b/include/uapi/linux/rkispp-config.h index e4b4c6f3cf3a..7f5f740f59e0 100644 --- a/include/uapi/linux/rkispp-config.h +++ b/include/uapi/linux/rkispp-config.h @@ -11,11 +11,19 @@ #define ISPP_API_VERSION KERNEL_VERSION(1, 2, 1) -#define ISPP_MODULE_TNR BIT(0)//2TO1 -#define ISPP_MODULE_NR BIT(1) -#define ISPP_MODULE_SHP BIT(2) -#define ISPP_MODULE_FEC BIT(3)//CALIBRATION -#define ISPP_MODULE_ORB BIT(4) + +#define ISPP_ID_TNR (0) +#define ISPP_ID_NR (1) +#define ISPP_ID_SHP (2) +#define ISPP_ID_FEC (3) +#define ISPP_ID_ORB (4) +#define ISPP_ID_MAX (5) + +#define ISPP_MODULE_TNR BIT(ISPP_ID_TNR)//2TO1 +#define ISPP_MODULE_NR BIT(ISPP_ID_NR) +#define ISPP_MODULE_SHP BIT(ISPP_ID_SHP) +#define ISPP_MODULE_FEC BIT(ISPP_ID_FEC)//CALIBRATION +#define ISPP_MODULE_ORB BIT(ISPP_ID_ORB) //extra function #define ISPP_MODULE_TNR_3TO1 (BIT(16) | ISPP_MODULE_TNR) #define ISPP_MODULE_FEC_ST (BIT(17) | ISPP_MODULE_FEC)//STABILIZATION