From 0426bfc39b1d6a343fa13bbd9081ddbad92ba3b6 Mon Sep 17 00:00:00 2001 From: Mingwei Yan Date: Wed, 19 Jun 2024 18:46:38 +0800 Subject: [PATCH] media: rockchip: vpss: fix switch scl params irq wrong Signed-off-by: Mingwei Yan Change-Id: I68bdd03f6bff412a131099eaba8d160e89a0b6fa --- drivers/media/platform/rockchip/vpss/stream.c | 28 ++++++++++++++++++- .../platform/rockchip/vpss/vpss_offline.c | 15 +++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rockchip/vpss/stream.c b/drivers/media/platform/rockchip/vpss/stream.c index 5b650357399c..97ccd297fa5b 100644 --- a/drivers/media/platform/rockchip/vpss/stream.c +++ b/drivers/media/platform/rockchip/vpss/stream.c @@ -1050,6 +1050,13 @@ static void poly_phase_scale(struct rkvpss_stream *stream, bool on, bool sync) return; } + /*config scl clk gate*/ + if (in_w == out_w && in_h == out_h) + rkvpss_unite_clear_bits(dev, RKVPSS_VPSS_CLK_GATE, RKVPSS_SCL0_CKG_DIS); + else + rkvpss_unite_set_bits(dev, RKVPSS_VPSS_CLK_GATE, RKVPSS_SCL0_CKG_DIS, + RKVPSS_SCL0_CKG_DIS); + /* TODO diff for input and output format */ if (yuv420_in) { in_div = 2; @@ -1275,7 +1282,7 @@ static void bilinear_scale(struct rkvpss_stream *stream, bool on, bool sync) u32 in_w = stream->crop.width; u32 in_h = stream->crop.height; u32 in_div, out_div; - u32 reg, val, ctrl = 0; + u32 reg, val, ctrl = 0, clk_mask = 0; bool yuv420_in = false, yuv422_to_420 = false; if (!on) { @@ -1284,6 +1291,25 @@ static void bilinear_scale(struct rkvpss_stream *stream, bool on, bool sync) return; } + /*config scl clk gate*/ + switch (stream->id) { + case RKVPSS_OUTPUT_CH1: + clk_mask = RKVPSS_SCL1_CKG_DIS; + break; + case RKVPSS_OUTPUT_CH2: + clk_mask = RKVPSS_SCL2_CKG_DIS; + break; + case RKVPSS_OUTPUT_CH3: + clk_mask = RKVPSS_SCL3_CKG_DIS; + break; + default: + return; + } + if (in_w == out_w && in_h == out_h) + rkvpss_unite_clear_bits(dev, RKVPSS_SCL0_CKG_DIS, clk_mask); + else + rkvpss_unite_set_bits(dev, RKVPSS_SCL0_CKG_DIS, clk_mask, clk_mask); + if (!dev->unite_mode) { /* TODO diff for input and output format */ if (yuv420_in) { diff --git a/drivers/media/platform/rockchip/vpss/vpss_offline.c b/drivers/media/platform/rockchip/vpss/vpss_offline.c index 0f77c29744f6..f19e8e20e50b 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_offline.c +++ b/drivers/media/platform/rockchip/vpss/vpss_offline.c @@ -268,7 +268,11 @@ static void poly_phase_scale(struct rkvpss_frame_cfg *frame_cfg, if (in_w == out_w && in_h == out_w) { rkvpss_hw_write(hw, RKVPSS_ZME_Y_SCL_CTRL, 0); rkvpss_hw_write(hw, RKVPSS_ZME_UV_SCL_CTRL, 0); + rkvpss_hw_clear_bits(hw, RKVPSS_VPSS_CLK_GATE, RKVPSS_SCL0_CKG_DIS); goto end; + } else { + rkvpss_hw_set_bits(hw, RKVPSS_VPSS_CLK_GATE, RKVPSS_SCL0_CKG_DIS, + RKVPSS_SCL0_CKG_DIS); } /* TODO diff for input and output format */ @@ -422,23 +426,32 @@ static void bilinear_scale(struct rkvpss_frame_cfg *frame_cfg, struct rkvpss_hw_dev *hw = ofl->hw; u32 in_w = cfg->crop_width, in_h = cfg->crop_height; u32 out_w = cfg->scl_width, out_h = cfg->scl_height; - u32 reg_base, in_div, out_div, val, ctrl = 0; + u32 reg_base, in_div, out_div, val, ctrl = 0, clk_mask = 0; bool yuv420_in = false, yuv422_to_420 = false; switch (idx) { case RKVPSS_OUTPUT_CH1: reg_base = RKVPSS_SCALE1_BASE; + clk_mask = RKVPSS_SCL1_CKG_DIS; break; case RKVPSS_OUTPUT_CH2: reg_base = RKVPSS_SCALE2_BASE; + clk_mask = RKVPSS_SCL2_CKG_DIS; break; case RKVPSS_OUTPUT_CH3: reg_base = RKVPSS_SCALE3_BASE; + clk_mask = RKVPSS_SCL3_CKG_DIS; break; default: return; } + /*config scl clk gate*/ + if (in_w == out_w && in_h == out_h) + rkvpss_hw_clear_bits(hw, RKVPSS_VPSS_CLK_GATE, clk_mask); + else + rkvpss_hw_set_bits(hw, RKVPSS_VPSS_CLK_GATE, clk_mask, clk_mask); + if (!unite) { if (in_w == out_w && in_h == out_w) goto end;