diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi index 6556e3c6f5f9..6deb34670219 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi @@ -1080,6 +1080,10 @@ status = "okay"; }; +&rkvtunnel { + status = "okay"; +}; + &rockchip_suspend { status = "okay"; rockchip,sleep-debug-en = <1>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi index 5855d0e0a37d..14ab6a7eb403 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi @@ -2164,6 +2164,11 @@ status = "disabled"; }; + rkvtunnel: rkvtunnel { + compatible = "rockchip,video-tunnel"; + status = "disabled"; + }; + rockchip_suspend: rockchip-suspend { compatible = "rockchip,pm-rk3588"; status = "disabled"; diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index 73cd32aa4b4c..af740c2a93db 100644 --- a/arch/arm64/configs/rockchip_defconfig +++ b/arch/arm64/configs/rockchip_defconfig @@ -686,6 +686,7 @@ CONFIG_ROCKCHIP_MPP_IEP2=y CONFIG_ROCKCHIP_MPP_JPGDEC=y CONFIG_ROCKCHIP_MPP_AV1DEC=y CONFIG_ROCKCHIP_MPP_VDPP=y +CONFIG_ROCKCHIP_VIDEO_TUNNEL=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 467e7da5a53c..bb67d4726b83 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -1058,11 +1058,6 @@ static int rkisp_pm_prepare(struct device *dev) if (!hw->is_idle && hw->cur_dev_id == isp_dev->dev_id) isp_dev->suspend_sync = true; spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags); - } else { - /* wait one frame for online */ - isp_dev->suspend_sync = true; - if (hw->isp_size[isp_dev->dev_id].fps) - time = 1000 / hw->isp_size[isp_dev->dev_id].fps; } if (isp_dev->suspend_sync) { @@ -1084,6 +1079,7 @@ static void rkisp_pm_complete(struct device *dev) struct rkisp_pipeline *p = &isp_dev->pipe; struct rkisp_stream *stream; int i, on = 1, rd_mode = isp_dev->rd_mode; + u32 val; if (isp_dev->isp_state & ISP_STOP) { if (pm_runtime_active(dev) && @@ -1156,10 +1152,20 @@ static void rkisp_pm_complete(struct device *dev) isp_dev->is_suspend = false; isp_dev->isp_state = ISP_START | ISP_FRAME_END; + if (isp_dev->is_suspend_one_frame) + isp_dev->is_first_double = true; + if (hw->isp_ver > ISP_V20) { + val = ISP3X_YNR_FST_FRAME | ISP3X_CNR_FST_FRAME | + ISP3X_DHAZ_FST_FRAME | ISP3X_ADRC_FST_FRAME; + if (hw->isp_ver == ISP_V32) + val |= ISP32_SHP_FST_FRAME; + rkisp_unite_set_bits(isp_dev, ISP3X_ISP_CTRL1, 0, val, false); + } for (i = 0; i < RKISP_MAX_STREAM; i++) { stream = &isp_dev->cap_dev.stream[i]; if (i == RKISP_STREAM_VIR || !stream->streaming || !stream->curr_buf) continue; + /* skip first frame due to hw no reference frame information */ stream->skip_frame = 1; } if (hw->cur_dev_id == isp_dev->dev_id) diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index fcdfa895a26a..1c726a63cad3 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -278,6 +278,7 @@ struct rkisp_device { bool is_frame_double; bool is_suspend; bool suspend_sync; + bool is_suspend_one_frame; struct rkisp_vicap_input vicap_in; diff --git a/drivers/media/platform/rockchip/isp/isp_external.h b/drivers/media/platform/rockchip/isp/isp_external.h index 5de005fe8d0b..6d4907483830 100644 --- a/drivers/media/platform/rockchip/isp/isp_external.h +++ b/drivers/media/platform/rockchip/isp/isp_external.h @@ -35,6 +35,7 @@ enum rkisp_vicap_link { RKISP_VICAP_ONLINE, RKISP_VICAP_RDBK_AIQ, RKISP_VICAP_RDBK_AUTO, + RKISP_VICAP_RDBK_AUTO_ONE_FRAME, }; struct rkisp_vicap_mode { diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 21025c0e903a..095897a1fe6a 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -3394,6 +3394,7 @@ static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev, struct rkisp_hw_dev *hw = isp_dev->hw_dev; int rd_mode = isp_dev->rd_mode; + isp_dev->is_suspend_one_frame = false; if (vicap_mode->rdbk_mode == RKISP_VICAP_ONLINE) { if (!hw->is_single) return -EINVAL; @@ -3408,7 +3409,8 @@ static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev, default: isp_dev->rd_mode = HDR_NORMAL; } - } else if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO) { + } else if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO || + vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME) { /* switch to readback mode */ switch (rd_mode) { case HDR_LINEX3_DDR: @@ -3420,6 +3422,8 @@ static int rkisp_set_work_mode_by_vicap(struct rkisp_device *isp_dev, default: isp_dev->rd_mode = HDR_RDBK_FRAME1; } + if (vicap_mode->rdbk_mode == RKISP_VICAP_RDBK_AUTO_ONE_FRAME) + isp_dev->is_suspend_one_frame = true; } else { return -EINVAL; }