From 3f4adbc02c19b61abe1d5ad0428ae88830e6bde6 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Wed, 30 Jul 2025 17:36:20 +0800 Subject: [PATCH] media: rockchip: vicap fixes stream loss when use switch with online mode Change-Id: I4abab7f8d7ae9c446615feb2dd5bbe262b8d442e Signed-off-by: Zefa Chen --- drivers/media/platform/rockchip/cif/capture.c | 42 +++++++++++++------ .../media/platform/rockchip/cif/subdev-itf.c | 2 +- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index d2554afaaa43..7173e9175aba 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -13742,6 +13742,12 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, struct v4l2_subdev *sd = NULL; struct rkisp_vicap_sof sof = {0}; + v4l2_dbg(5, rkcif_debug, &priv->cif_dev->v4l2_dev, + "toisp_off %d\n", priv->is_toisp_off); + + if (priv->is_toisp_off) + return; + for (i = 0; i < TOISP_CH_MAX; i++) { if (priv->cif_dev->chip_id < CHIP_RK3576_CIF) ch = rkcif_g_toisp_ch(intstat_glb, index); @@ -13772,13 +13778,16 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, spin_lock_irqsave(&stream->cifdev->stream_spinlock, flags); if (stream->is_wait_stop_complete) { - if (stream->cifdev->hdr.hdr_mode == NO_HDR || - (stream->cifdev->hdr.hdr_mode == HDR_X2 && stream->id == 1) || - (stream->cifdev->hdr.hdr_mode == HDR_X3 && stream->id == 2)) { - rkcif_disable_capture(stream); - } else { - stream->to_stop_dma = RKCIF_DMAEN_BY_ISP; - rkcif_stop_dma_capture(stream); + if (!stream->cifdev->switch_info.is_use_switch || + atomic_dec_if_positive(&stream->cifdev->hw_dev->switch_stream_cnt[stream->cifdev->switch_info.host_idx]) == 0) { + if (stream->cifdev->hdr.hdr_mode == NO_HDR || + (stream->cifdev->hdr.hdr_mode == HDR_X2 && stream->id == 1) || + (stream->cifdev->hdr.hdr_mode == HDR_X3 && stream->id == 2)) { + rkcif_disable_capture(stream); + } else { + stream->to_stop_dma = RKCIF_DMAEN_BY_ISP; + rkcif_stop_dma_capture(stream); + } } stream->is_wait_stop_complete = false; stream->is_pause_stream = true; @@ -13790,7 +13799,9 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, (stream->cifdev->hdr.hdr_mode == HDR_X3 && stream->id == 2))) { stream->cifdev->sensor_state_change = false; spin_unlock_irqrestore(&stream->cifdev->stream_spinlock, flags); - rkcif_dphy_quick_stream(stream->cifdev, on); + if (!stream->cifdev->switch_info.is_use_switch || + atomic_read(&stream->cifdev->hw_dev->switch_stream_cnt[stream->cifdev->switch_info.host_idx]) == 0) + rkcif_dphy_quick_stream(stream->cifdev, on); atomic_inc(&stream->cifdev->sensor_off); stream->cifdev->sensor_work.on = stream->cifdev->sensor_state; schedule_work(&stream->cifdev->sensor_work.work); @@ -13806,7 +13817,9 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, if (!stream->is_wait_single_cap) { stream->is_single_cap = false; spin_unlock_irqrestore(&stream->cifdev->stream_spinlock, flags); - rkcif_dphy_quick_stream(stream->cifdev, on); + if (!stream->cifdev->switch_info.is_use_switch || + atomic_read(&stream->cifdev->hw_dev->switch_stream_cnt[stream->cifdev->switch_info.host_idx]) == 0) + rkcif_dphy_quick_stream(stream->cifdev, on); stream->cifdev->sensor_work.on = 0; atomic_inc(&stream->cifdev->sensor_off); schedule_work(&stream->cifdev->sensor_work.work); @@ -13833,7 +13846,9 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, "stream[%d] toisp fe %d\n", stream->id, stream->frame_idx - 1); - + if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE_UNITE || + priv->mode.rdbk_mode == RKISP_VICAP_ONLINE_MULTI) + priv->is_toisp_off = true; switch (ch) { case RKCIF_TOISP_CH0: if (priv->cif_dev->chip_id < CHIP_RK3576_CIF) @@ -13860,13 +13875,11 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, break; } } - if (priv->is_toisp_off) - continue; if (priv->cif_dev->chip_id < CHIP_RK3576_CIF) ch = rkcif_g_toisp_fs(intstat_glb, index); else ch = rkcif_g_toisp_fs_rk3576(intstat_glb, index); - if (ch >= 0 && (!priv->is_toisp_off)) { + if (ch >= 0) { src_id = priv->toisp_inf.ch_info[ch].id; if (src_id != rkcif_toisp_get_src_id(priv, index, ch)) continue; @@ -14520,6 +14533,9 @@ int rkcif_stream_suspend(struct rkcif_device *cif_dev, int mode) } } + if (priv && priv->mode.rdbk_mode < RKISP_VICAP_RDBK_AIQ) + priv->is_toisp_off = true; + if (suspend_cnt == 0) goto out_suspend; diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index 73f8b4376bc9..5c0633c4f341 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -1172,7 +1172,6 @@ void sditf_disable_immediately(struct sditf_priv *priv) sditf_channel_disable(priv, 1); } } - priv->is_toisp_off = true; if (priv->cif_dev->switch_info.is_use_switch) priv->cif_dev->switch_info.is_active = false; } @@ -1274,6 +1273,7 @@ static int sditf_stop_stream(struct sditf_priv *priv) priv->toisp_inf.ch_info[0].is_valid = false; priv->toisp_inf.ch_info[1].is_valid = false; priv->toisp_inf.ch_info[2].is_valid = false; + priv->is_toisp_off = true; return 0; }