From a1a35216e249199a35c02de6b04dc4416aba5e5d Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Fri, 22 Apr 2022 10:02:29 +0800 Subject: [PATCH] media: rockchip: isp: isp32 fix ae no working with af should not to clean meas done during working for af ae mode, if not ae will abnormal. Change-Id: Id7353409cc8b79b3b3a59fe39df905344afacf7b Signed-off-by: Cai YiWei --- .../media/platform/rockchip/isp/isp_stats.c | 3 + .../media/platform/rockchip/isp/isp_stats.h | 3 + .../platform/rockchip/isp/isp_stats_v32.c | 133 +++++++----------- .../media/platform/rockchip/isp/regs_v3x.h | 1 + 4 files changed, 57 insertions(+), 83 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/isp_stats.c b/drivers/media/platform/rockchip/isp/isp_stats.c index a69860c4774c..0f2c48c43f1e 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.c +++ b/drivers/media/platform/rockchip/isp/isp_stats.c @@ -192,6 +192,9 @@ static void rkisp_stats_vb2_stop_streaming(struct vb2_queue *vq) stats_vdev->nxt_buf = NULL; } spin_unlock_irqrestore(&stats_vdev->rd_lock, flags); + + stats_vdev->ae_meas_done_next = false; + stats_vdev->af_meas_done_next = false; } static int diff --git a/drivers/media/platform/rockchip/isp/isp_stats.h b/drivers/media/platform/rockchip/isp/isp_stats.h index d3b1e33eb66c..6797084a5dac 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.h +++ b/drivers/media/platform/rockchip/isp/isp_stats.h @@ -72,6 +72,9 @@ struct rkisp_isp_stats_vdev { struct rkisp_dummy_buffer tmp_statsbuf; struct rkisp_buffer *cur_buf; struct rkisp_buffer *nxt_buf; + + bool af_meas_done_next; + bool ae_meas_done_next; }; void rkisp_stats_rdbk_enable(struct rkisp_isp_stats_vdev *stats_vdev, bool en); diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v32.c b/drivers/media/platform/rockchip/isp/isp_stats_v32.c index f093c4acdeb5..4ace7bff0161 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v32.c @@ -175,7 +175,7 @@ rkisp_stats_get_rawaf_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, return -ENODATA; } - if (!pbuf) + if (!pbuf || stats_vdev->af_meas_done_next) goto out; af = &pbuf->params.rawaf; @@ -187,25 +187,42 @@ rkisp_stats_get_rawaf_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, af->highlit_cnt_winb = isp3_stats_read(stats_vdev, ISP3X_RAWAF_HIGHLIT_CNT_WINB); out: - isp3_module_done(stats_vdev, ISP3X_RAWAF_CTRL, ctrl); + /* af should not clean mease done during isp working for af_ae_mode */ + stats_vdev->af_meas_done_next = false; + if ((ctrl & ISP3X_RAWAF_AE_MODE) && + (isp3_stats_read(stats_vdev, ISP3X_DPCC0_BASE) & ISP3X_DPCC_WORKING)) + stats_vdev->af_meas_done_next = true; + else + isp3_module_done(stats_vdev, ISP3X_RAWAF_CTRL, ctrl); return 0; } static int rkisp_stats_get_rawaebig_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, - struct isp32_rawaebig_stat1 *ae, u32 blk_no) + struct rkisp32_isp_stat_buffer *pbuf, + u32 blk_no) { - u32 i, base, addr, ctrl; + struct isp32_rawaebig_stat1 *ae = NULL; + u32 i, base, addr, ctrl, meas_type; switch (blk_no) { case 1: base = RAWAE_BIG2_BASE; + meas_type = ISP32_STAT_RAWAE1; + if (pbuf) + ae = &pbuf->params.rawae1_1; break; case 2: base = RAWAE_BIG3_BASE; + meas_type = ISP32_STAT_RAWAE2; + if (pbuf) + ae = &pbuf->params.rawae2_1; break; default: base = RAWAE_BIG1_BASE; + meas_type = ISP32_STAT_RAWAE3; + if (pbuf) + ae = &pbuf->params.rawae3_1; break; } @@ -217,7 +234,7 @@ rkisp_stats_get_rawaebig_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, return -ENODATA; } - if (!ae) + if (!ae || stats_vdev->ae_meas_done_next) goto out; for (i = 0; i < ISP32_RAWAEBIG_SUBWIN_NUM; i++) { @@ -229,27 +246,40 @@ rkisp_stats_get_rawaebig_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, ae->sumb[i] = isp3_stats_read(stats_vdev, addr); } + pbuf->meas_type |= meas_type; + out: - isp3_module_done(stats_vdev, base + ISP3X_RAWAE_BIG_CTRL, ctrl); + /* ae should not clean mease done during isp working for af_ae_mode */ + if (blk_no == 0 && stats_vdev->af_meas_done_next) { + stats_vdev->ae_meas_done_next = true; + } else { + isp3_module_done(stats_vdev, base + ISP3X_RAWAE_BIG_CTRL, ctrl); + if (blk_no == 0) + stats_vdev->ae_meas_done_next = false; + } return 0; } static int rkisp_stats_get_rawhstbig_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, - struct isp2x_rawhistbig_stat *hst, u32 blk_no) + struct rkisp32_isp_stat_buffer *pbuf, + u32 blk_no) { - u32 addr, ctrl; + u32 addr, ctrl, meas_type; switch (blk_no) { case 1: addr = ISP3X_RAWHIST_BIG2_BASE; + meas_type = ISP32_STAT_RAWHST1; break; case 2: addr = ISP3X_RAWHIST_BIG3_BASE; + meas_type = ISP32_STAT_RAWHST2; break; case 0: default: addr = ISP3X_RAWHIST_BIG1_BASE; + meas_type = ISP32_STAT_RAWHST3; break; } @@ -261,9 +291,10 @@ rkisp_stats_get_rawhstbig_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, return -ENODATA; } - if (!hst) + if (!pbuf) goto out; + pbuf->meas_type |= meas_type; out: isp3_module_done(stats_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, ctrl); return 0; @@ -273,108 +304,42 @@ static int rkisp_stats_get_rawae1_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp32_isp_stat_buffer *pbuf) { - int ret = 0; - - if (!pbuf) { - rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, NULL, 1); - } else { - ret = rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, - &pbuf->params.rawae1_1, 1); - if (!ret) - pbuf->meas_type |= ISP32_STAT_RAWAE1; - } - - return ret; + return rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, pbuf, 1); } static int rkisp_stats_get_rawhst1_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp32_isp_stat_buffer *pbuf) { - int ret = 0; - - if (!pbuf) { - rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, NULL, 1); - } else { - ret = rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, - &pbuf->params.rawhist1, 1); - if (!ret) - pbuf->meas_type |= ISP32_STAT_RAWHST1; - } - - return ret; + return rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, pbuf, 1); } static int rkisp_stats_get_rawae2_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp32_isp_stat_buffer *pbuf) { - int ret = 0; - - if (!pbuf) { - rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, NULL, 2); - } else { - ret = rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, - &pbuf->params.rawae2_1, 2); - if (!ret) - pbuf->meas_type |= ISP32_STAT_RAWAE2; - } - - return ret; + return rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, pbuf, 2); } static int rkisp_stats_get_rawhst2_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp32_isp_stat_buffer *pbuf) { - int ret = 0; - - if (!pbuf) { - rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, NULL, 2); - } else { - ret = rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, - &pbuf->params.rawhist2, 2); - if (!ret) - pbuf->meas_type |= ISP32_STAT_RAWHST2; - } - - return ret; + return rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, pbuf, 2); } static int rkisp_stats_get_rawae3_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp32_isp_stat_buffer *pbuf) { - int ret = 0; - - if (!pbuf) { - rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, NULL, 0); - } else { - ret = rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, - &pbuf->params.rawae3_1, 0); - if (!ret) - pbuf->meas_type |= ISP32_STAT_RAWAE3; - } - - return ret; + return rkisp_stats_get_rawaebig_meas_ddr(stats_vdev, pbuf, 0); } static int rkisp_stats_get_rawhst3_meas_ddr(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp32_isp_stat_buffer *pbuf) { - int ret = 0; - - if (!pbuf) { - rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, NULL, 0); - } else { - ret = rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, - &pbuf->params.rawhist3, 0); - if (!ret) - pbuf->meas_type |= ISP32_STAT_RAWHST3; - } - - return ret; + return rkisp_stats_get_rawhstbig_meas_ddr(stats_vdev, pbuf, 0); } static int @@ -580,10 +545,12 @@ rkisp_stats_send_meas_v32(struct rkisp_isp_stats_vdev *stats_vdev, if (meas_work->isp3a_ris & ISP3X_3A_RAWAWB) ret |= ops->get_rawawb_meas(stats_vdev, cur_stat_buf); - if (meas_work->isp3a_ris & ISP3X_3A_RAWAF) + if (meas_work->isp3a_ris & ISP3X_3A_RAWAF || + stats_vdev->af_meas_done_next) ret |= ops->get_rawaf_meas(stats_vdev, cur_stat_buf); - if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_BIG) + if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_BIG || + stats_vdev->ae_meas_done_next) ret |= ops->get_rawae3_meas(stats_vdev, cur_stat_buf); if (meas_work->isp3a_ris & ISP3X_3A_RAWHIST_BIG) diff --git a/drivers/media/platform/rockchip/isp/regs_v3x.h b/drivers/media/platform/rockchip/isp/regs_v3x.h index 2584deb0e1b6..4f43858b2167 100644 --- a/drivers/media/platform/rockchip/isp/regs_v3x.h +++ b/drivers/media/platform/rockchip/isp/regs_v3x.h @@ -2116,6 +2116,7 @@ #define ISP3X_GAIN_2DDR_mode(a) (((a) & 0x3) << 25) /* DPCC */ +#define ISP3X_DPCC_WORKING BIT(30) /* CCM */ #define ISP3X_CCM_HIGHY_ADJ_DIS BIT(1)