Blob Blame History Raw
From c7c345c28068ea7b0d232f598dbb4cfefc3d1925 Mon Sep 17 00:00:00 2001
From: hersen wu <hersenxs.wu@amd.com>
Date: Mon, 6 Jul 2020 09:18:25 -0400
Subject: drm/amd/display: p-state warning occurs while changing resolution
Git-commit: 1f9ce3cf18ed441a0df8f2447c6f9d6556780415
Patch-mainline: v5.9-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322
 from 120hz to 60hz

[Why]
new calculated dispclk, dppclk are stored in
context->bw_ctx.bw.dcn.clk.dispclk_khz, dppclk_khz. Current dispclk,
dppclk are from dc->clk_mgr->clks.dispclk_khz. dcn_validate_bandwidth
compute new dispclk, dppclk. dispclk will put in use after
optimize_bandwidth when ramp_up_dispclk_with_dpp is called. There are
two places for dppclk be put in use. One location is the same as the
location as dispclk. Another is within update_dchubp_dpp which happens
between pre_bandwidth and optimize_bandwidth. dppclk updated within
update_dchubp_dpp will cause new clock values of dispclk and dppclk not
be in use at the same time. when clocks are decreased, this may cause
dppclk is lower than current configuration and let pipe stuck. for
example, eDP + external dp, change resolution of DP from 1920x1080x144hz
to 1280x960x60hz.

before change: dispclk = 337889 dppclk = 337889
change mode, dcn_validate_bandwidth calculate
             dispclk = 143122 dppclk = 143122
update_dchubp_dpp be executed before dispclk be updated,
dispclk = 337889, but dppclk use new value dispclk /2 =
168944. this will cause pipe pstate warning issue.

[How]
between pre_bandwidth and optimize_bandwidth, while dispclk is going to
be decreased, keep dppclk = dispclk

Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 36 +++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 9cdc3d2919f4..da0897fe3b54 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -2459,14 +2459,46 @@ static void dcn10_update_dchubp_dpp(
 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 	struct plane_size size = plane_state->plane_size;
 	unsigned int compat_level = 0;
+	bool should_divided_by_2 = false;
 
 	/* depends on DML calculation, DPP clock value may change dynamically */
 	/* If request max dpp clk is lower than current dispclk, no need to
 	 * divided by 2
 	 */
 	if (plane_state->update_flags.bits.full_update) {
-		bool should_divided_by_2 = context->bw_ctx.bw.dcn.clk.dppclk_khz <=
-				dc->clk_mgr->clks.dispclk_khz / 2;
+
+		/* new calculated dispclk, dppclk are stored in
+		 * context->bw_ctx.bw.dcn.clk.dispclk_khz / dppclk_khz. current
+		 * dispclk, dppclk are from dc->clk_mgr->clks.dispclk_khz.
+		 * dcn_validate_bandwidth compute new dispclk, dppclk.
+		 * dispclk will put in use after optimize_bandwidth when
+		 * ramp_up_dispclk_with_dpp is called.
+		 * there are two places for dppclk be put in use. One location
+		 * is the same as the location as dispclk. Another is within
+		 * update_dchubp_dpp which happens between pre_bandwidth and
+		 * optimize_bandwidth.
+		 * dppclk updated within update_dchubp_dpp will cause new
+		 * clock values of dispclk and dppclk not be in use at the same
+		 * time. when clocks are decreased, this may cause dppclk is
+		 * lower than previous configuration and let pipe stuck.
+		 * for example, eDP + external dp,  change resolution of DP from
+		 * 1920x1080x144hz to 1280x960x60hz.
+		 * before change: dispclk = 337889 dppclk = 337889
+		 * change mode, dcn_validate_bandwidth calculate
+		 *                dispclk = 143122 dppclk = 143122
+		 * update_dchubp_dpp be executed before dispclk be updated,
+		 * dispclk = 337889, but dppclk use new value dispclk /2 =
+		 * 168944. this will cause pipe pstate warning issue.
+		 * solution: between pre_bandwidth and optimize_bandwidth, while
+		 * dispclk is going to be decreased, keep dppclk = dispclk
+		 **/
+		if (context->bw_ctx.bw.dcn.clk.dispclk_khz <
+				dc->clk_mgr->clks.dispclk_khz)
+			should_divided_by_2 = false;
+		else
+			should_divided_by_2 =
+					context->bw_ctx.bw.dcn.clk.dppclk_khz <=
+					dc->clk_mgr->clks.dispclk_khz / 2;
 
 		dpp->funcs->dpp_dppclk_control(
 				dpp,
-- 
2.29.2