All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/28] DC Patches Sep 8, 2023
@ 2023-09-06 12:28 Stylon Wang
  2023-09-06 12:28 ` [PATCH 01/28] drm/amd/display: Blank phantom OTG before enabling Stylon Wang
                   ` (27 more replies)
  0 siblings, 28 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, solomon.chiu, Daniel Wheeler,
	Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

This DC patchset brings improvements in multiple areas. In summary, we have:
- Fix MST bugs
- Fix ODM combine debugfs
- Fix DML calculations
- Fix 2nd DPIA encoder issue
- Fix AUX-based backlight control
- Fix on MPO+ODM use case
- Fix DCCG clock programming
- Improvements on replay
- Improvements on logging and reporting
- Improvements on pipe and OTG handling
- Improvements and bug fixes on power optimization
- Improvements on VRR
- Code clean up and fix un-initialized values

Cc: Daniel Wheeler <daniel.wheeler@amd.com>

Alvin Lee (2):
  drm/amd/display: Blank phantom OTG before enabling
  drm/amd/display: Don't lock phantom pipe on disabling

Anthony Koo (1):
  drm/amd/display: [FW Promotion] Release 0.0.181.0

Aric Cyr (1):
  drm/amd/display: 3.2.250

Aurabindo Pillai (2):
  drm/amd/display: set default return value for ODM Combine debugfs
  drm/amd/display: Add DCHUBBUB callback to report MALL status

Austin Zheng (1):
  drm/amd/display: Add check for vrr_active_fixed

Bhawanpreet Lakha (1):
  drm/amd/display: Add dirty rect support for Replay

Charlene Liu (1):
  drm/amd/display: fix some non-initialized register mask and setting

Dillon Varone (1):
  drm/amd/display: add dp dto programming function to dccg

Ethan Bitnun (1):
  drm/amd/display: Add new logs for AutoDPMTest

Ian Chen (1):
  drm/amd/display: add skip_implict_edp_power_control flag for dcn32

Muhammad Ahmed (1):
  drm/amd/display: Fix MST recognizes connected displays as one

Mustapha Ghaddar (1):
  drm/amd/display: Fix 2nd DPIA encoder Assignment

Nicholas Susanto (1):
  drm/amd/display: Fix DML calculation errors

Paul Hsieh (1):
  drm/amd/display: support main link off before specific vertical line

Qingqing Zhuo (1):
  drm/amd/display: Drop unused registers

Sridevi Arvindekar (1):
  drm/amd/display: dc cleanup for tests

Swapnil Patel (1):
  drm/amd/display: Don't check registers, if using AUX BL control

Wayne Lin (1):
  drm/amd/display: Adjust the MST resume flow

Wenjing Liu (8):
  drm/amd/display: do not block ODM + OPM on one side of the screen
  drm/amd/display: remove a function that does complex calculation in
    every frame but not used
  drm/amd/display: do not attempt ODM power optimization if minimal
    transition doesn't exist
  drm/amd/display: only allow ODM power optimization if surface is
    within guaranteed viewport size
  drm/amd/display: do not skip ODM minimal transition based on new state
  drm/amd/display: minior logging improvements
  drm/amd/display: add seamless pipe topology transition check
  drm/amd/display: move odm power optimization decision after subvp
    optimization

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  96 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |  15 +-
 .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c  |  64 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 107 ++--
 .../drm/amd/display/dc/core/dc_link_enc_cfg.c |   4 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |   7 -
 drivers/gpu/drm/amd/display/dc/dc.h           |   3 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   4 +-
 .../drm/amd/display/dc/dce/dce_clock_source.c |   1 +
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c |  10 +-
 .../display/dc/dce110/dce110_hw_sequencer.c   |  34 +-
 .../drm/amd/display/dc/dcn10/dcn10_hubbub.h   |   5 +-
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |   3 +-
 .../display/dc/dcn10/dcn10_stream_encoder.h   |   5 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |  20 +-
 .../drm/amd/display/dc/dcn32/dcn32_hubbub.c   |  14 +-
 .../drm/amd/display/dc/dcn32/dcn32_hubbub.h   |   6 +-
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.c    | 104 ++-
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.h    |   9 +
 .../gpu/drm/amd/display/dc/dcn32/dcn32_init.c |   2 +
 .../gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c  |   2 +-
 .../drm/amd/display/dc/dcn32/dcn32_resource.c |  79 +--
 .../drm/amd/display/dc/dcn32/dcn32_resource.h |   1 +
 .../display/dc/dcn32/dcn32_resource_helpers.c |   4 +-
 .../drm/amd/display/dc/dcn35/dcn35_hubbub.h   |   2 -
 .../dc/dml/dcn314/display_mode_vba_314.c      |   2 +
 .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c  | 601 ++++++++++--------
 .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.h  |   3 -
 .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h   |   6 +-
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  |  16 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |  10 +
 .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h  |   1 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |   8 +
 .../gpu/drm/amd/display/dc/link/link_dpms.c   |  10 +-
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |   6 +-
 .../amd/display/include/ddc_service_types.h   |   1 +
 .../drm/amd/display/include/logger_types.h    |   5 +-
 37 files changed, 793 insertions(+), 477 deletions(-)

-- 
2.42.0


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/28] drm/amd/display: Blank phantom OTG before enabling
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 02/28] drm/amd/display: Don't lock phantom pipe on disabling Stylon Wang
                   ` (26 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, Samson Tam, solomon.chiu,
	Aurabindo.Pillai, Alvin Lee, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Alvin Lee <Alvin.Lee2@amd.com>

[Description]
Before enabling the phantom OTG for an update we
must enable DPG to avoid underflow.

Reviewed-by: Samson Tam <samson.tam@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 50 +------------------
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 10 +++-
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.c    | 46 +++++++++++++++++
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.h    |  5 ++
 .../gpu/drm/amd/display/dc/dcn32/dcn32_init.c |  1 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  5 ++
 6 files changed, 68 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 20a3b4c81d4b..dcedda85dcdb 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1070,53 +1070,6 @@ static void apply_ctx_interdependent_lock(struct dc *dc,
 	}
 }
 
-static void phantom_pipe_blank(
-		struct dc *dc,
-		struct timing_generator *tg,
-		int width,
-		int height)
-{
-	struct dce_hwseq *hws = dc->hwseq;
-	enum dc_color_space color_space;
-	struct tg_color black_color = {0};
-	struct output_pixel_processor *opp = NULL;
-	uint32_t num_opps, opp_id_src0, opp_id_src1;
-	uint32_t otg_active_width, otg_active_height;
-	uint32_t i;
-
-	/* program opp dpg blank color */
-	color_space = COLOR_SPACE_SRGB;
-	color_space_to_black_color(dc, color_space, &black_color);
-
-	otg_active_width = width;
-	otg_active_height = height;
-
-	/* get the OPTC source */
-	tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
-	ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
-
-	for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
-		if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) {
-			opp = dc->res_pool->opps[i];
-			break;
-		}
-	}
-
-	if (opp && opp->funcs->opp_set_disp_pattern_generator)
-		opp->funcs->opp_set_disp_pattern_generator(
-				opp,
-				CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
-				CONTROLLER_DP_COLOR_SPACE_UDEFINED,
-				COLOR_DEPTH_UNDEFINED,
-				&black_color,
-				otg_active_width,
-				otg_active_height,
-				0);
-
-	if (tg->funcs->is_tg_enabled(tg))
-		hws->funcs.wait_for_blank_complete(opp);
-}
-
 static void dc_update_viusal_confirm_color(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
 {
 	if (dc->ctx->dce_version >= DCN_VERSION_1_0) {
@@ -1207,7 +1160,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
 
 					main_pipe_width = old_stream->mall_stream_config.paired_stream->dst.width;
 					main_pipe_height = old_stream->mall_stream_config.paired_stream->dst.height;
-					phantom_pipe_blank(dc, tg, main_pipe_width, main_pipe_height);
+					if (dc->hwss.blank_phantom)
+						dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height);
 					tg->funcs->enable_crtc(tg);
 				}
 			}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index ad82f19fe36a..5ac85df158b9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1840,8 +1840,16 @@ void dcn20_program_front_end_for_ctx(
 			dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
 			struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg;
 
-			if (tg->funcs->enable_crtc)
+			if (tg->funcs->enable_crtc) {
+				if (dc->hwss.blank_phantom) {
+					int main_pipe_width, main_pipe_height;
+
+					main_pipe_width = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.width;
+					main_pipe_height = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.height;
+					dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height);
+				}
 				tg->funcs->enable_crtc(tg);
+			}
 		}
 	}
 	/* OTG blank before disabling all front ends */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
index 680e7fa8d18a..cae5e1e68c86 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
@@ -1573,3 +1573,49 @@ void dcn32_init_blank(
 	if (opp)
 		hws->funcs.wait_for_blank_complete(opp);
 }
+
+void dcn32_blank_phantom(struct dc *dc,
+		struct timing_generator *tg,
+		int width,
+		int height)
+{
+	struct dce_hwseq *hws = dc->hwseq;
+	enum dc_color_space color_space;
+	struct tg_color black_color = {0};
+	struct output_pixel_processor *opp = NULL;
+	uint32_t num_opps, opp_id_src0, opp_id_src1;
+	uint32_t otg_active_width, otg_active_height;
+	uint32_t i;
+
+	/* program opp dpg blank color */
+	color_space = COLOR_SPACE_SRGB;
+	color_space_to_black_color(dc, color_space, &black_color);
+
+	otg_active_width = width;
+	otg_active_height = height;
+
+	/* get the OPTC source */
+	tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
+	ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
+
+	for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
+		if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) {
+			opp = dc->res_pool->opps[i];
+			break;
+		}
+	}
+
+	if (opp && opp->funcs->opp_set_disp_pattern_generator)
+		opp->funcs->opp_set_disp_pattern_generator(
+				opp,
+				CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
+				CONTROLLER_DP_COLOR_SPACE_UDEFINED,
+				COLOR_DEPTH_UNDEFINED,
+				&black_color,
+				otg_active_width,
+				otg_active_height,
+				0);
+
+	if (tg->funcs->is_tg_enabled(tg))
+		hws->funcs.wait_for_blank_complete(opp);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
index 2d2628f31bed..616d5219119e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
@@ -115,4 +115,9 @@ void dcn32_init_blank(
 		struct dc *dc,
 		struct timing_generator *tg);
 
+void dcn32_blank_phantom(struct dc *dc,
+		struct timing_generator *tg,
+		int width,
+		int height);
+
 #endif /* __DC_HWSS_DCN32_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
index c7417147dff1..eb4227926006 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
@@ -115,6 +115,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
 	.update_phantom_vp_position = dcn32_update_phantom_vp_position,
 	.update_dsc_pg = dcn32_update_dsc_pg,
 	.apply_update_flags_for_phantom = dcn32_apply_update_flags_for_phantom,
+	.blank_phantom = dcn32_blank_phantom,
 };
 
 static const struct hwseq_private_funcs dcn32_private_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index fbfcd29b1d73..1ccdb7359894 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -397,6 +397,11 @@ struct hw_sequencer_funcs {
 	void (*z10_restore)(const struct dc *dc);
 	void (*z10_save_init)(struct dc *dc);
 
+	void (*blank_phantom)(struct dc *dc,
+			struct timing_generator *tg,
+			int width,
+			int height);
+
 	void (*update_visual_confirm_color)(struct dc *dc,
 			struct pipe_ctx *pipe_ctx,
 			int mpcc_id);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/28] drm/amd/display: Don't lock phantom pipe on disabling
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
  2023-09-06 12:28 ` [PATCH 01/28] drm/amd/display: Blank phantom OTG before enabling Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 03/28] drm/amd/display: set default return value for ODM Combine debugfs Stylon Wang
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, Samson Tam, solomon.chiu,
	Aurabindo.Pillai, Alvin Lee, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Alvin Lee <alvin.lee2@amd.com>

[Description]
- When disabling a phantom pipe, we first enable the phantom
  OTG so the double buffer update can successfully take place
- However, want to avoid locking the phantom otherwise setting
  DPG_EN=1 for the phantom pipe is blocked (without this we could
  hit underflow due to phantom HUBP being blanked by default)

Reviewed-by: Samson Tam <samson.tam@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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 9834b75f1837..79befa17bb03 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
@@ -111,7 +111,8 @@ void dcn10_lock_all_pipes(struct dc *dc,
 		if (pipe_ctx->top_pipe ||
 		    !pipe_ctx->stream ||
 		    (!pipe_ctx->plane_state && !old_pipe_ctx->plane_state) ||
-		    !tg->funcs->is_tg_enabled(tg))
+		    !tg->funcs->is_tg_enabled(tg) ||
+			pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM)
 			continue;
 
 		if (lock)
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/28] drm/amd/display: set default return value for ODM Combine debugfs
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
  2023-09-06 12:28 ` [PATCH 01/28] drm/amd/display: Blank phantom OTG before enabling Stylon Wang
  2023-09-06 12:28 ` [PATCH 02/28] drm/amd/display: Don't lock phantom pipe on disabling Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 04/28] drm/amd/display: Add dirty rect support for Replay Stylon Wang
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo Siqueira, roman.li, solomon.chiu, Aurabindo Pillai,
	wayne.lin, Bhawanpreet.Lakha, agustin.gutierrez, pavle.kotarac

From: Aurabindo Pillai <aurabindo.pillai@amd.com>

[Why&How]
Set a default return value of -ENOTSUPP to indicate that the hardware
does not support querying ODM Combine mode.

Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 17d1990ea832..05c1ad98a1f6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -1211,7 +1211,7 @@ static int odm_combine_segments_show(struct seq_file *m, void *unused)
 	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 	struct dc_link *link = aconnector->dc_link;
 	struct pipe_ctx *pipe_ctx = NULL;
-	int i, segments = 0;
+	int i, segments = -EOPNOTSUPP;
 
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/28] drm/amd/display: Add dirty rect support for Replay
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (2 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 03/28] drm/amd/display: set default return value for ODM Combine debugfs Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 05/28] drm/amd/display: Don't check registers, if using AUX BL control Stylon Wang
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sun peng Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, solomon.chiu, Aurabindo.Pillai,
	wayne.lin, Bhawanpreet Lakha, agustin.gutierrez, pavle.kotarac

From: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>

Dirty rect can be used with replay, so enable them to allow for more
powersaving.

Reviewed-by: Sun peng Li <sunpeng.li@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1bb1a394f55f..93f8ec2acb4a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8103,7 +8103,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 		bundle->surface_updates[planes_count].plane_info =
 			&bundle->plane_infos[planes_count];
 
-		if (acrtc_state->stream->link->psr_settings.psr_feature_enabled) {
+		if (acrtc_state->stream->link->psr_settings.psr_feature_enabled ||
+		    acrtc_state->stream->link->replay_settings.replay_feature_enabled) {
 			fill_dc_dirty_rects(plane, old_plane_state,
 					    new_plane_state, new_crtc_state,
 					    &bundle->flip_addrs[planes_count],
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/28] drm/amd/display: Don't check registers, if using AUX BL control
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (3 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 04/28] drm/amd/display: Add dirty rect support for Replay Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 06/28] drm/amd/display: [FW Promotion] Release 0.0.181.0 Stylon Wang
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Swapnil Patel, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Swapnil Patel <swapnil.patel@amd.com>

[Why]
Currently the driver looks DCN registers to access if BL is on or not.
This check is not valid if we are using AUX based brightness control.
This causes driver to not send out "backlight off" command during power off
sequence as it already thinks it is off.

[How]
Only check DCN registers if we aren't using AUX based brightness control.

Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Swapnil Patel <swapnil.patel@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 602fb149dc10..31454db00ed5 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -964,7 +964,9 @@ void dce110_edp_backlight_control(
 		return;
 	}
 
-	if (link->panel_cntl) {
+	if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled ||
+		link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
+		link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) {
 		bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl);
 
 		if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/28] drm/amd/display: [FW Promotion] Release 0.0.181.0
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (4 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 05/28] drm/amd/display: Don't check registers, if using AUX BL control Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 07/28] drm/amd/display: Fix DML calculation errors Stylon Wang
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Anthony Koo, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, solomon.chiu,
	Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Anthony Koo <anthony.koo@amd.com>

 - Add new params to dmub_feature_caps for checking replay
   support in FW

Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Anthony Koo <anthony.koo@amd.com>
---
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index e2aebba29f68..0367d0850495 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -450,6 +450,8 @@ struct dmub_feature_caps {
 	uint8_t reserved[4];
 	uint8_t subvp_psr_support;
 	uint8_t gecc_enable;
+	uint8_t replay_supported;
+	uint8_t replay_reserved[3];
 };
 
 struct dmub_visual_confirm_color {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/28] drm/amd/display: Fix DML calculation errors
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (5 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 06/28] drm/amd/display: [FW Promotion] Release 0.0.181.0 Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 08/28] drm/amd/display: do not block ODM + OPM on one side of the screen Stylon Wang
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Nicholas Susanto, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, solomon.chiu,
	Aurabindo.Pillai, wayne.lin, Jun Lei, Bhawanpreet.Lakha,
	Nicholas Kazlauskas, agustin.gutierrez, pavle.kotarac

From: Nicholas Susanto <nicholas.susanto@amd.com>

[Why]
DML calculations differ with DCN3.1 spreadsheet values due to
translations errors from the visual basic code

[How]
Add missing calculations that set the value for DSCDelay

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Jun Lei <jun.lei@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Nicholas Susanto <nicholas.susanto@amd.com>
---
 .../gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c    | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
index a94aa0f21a7f..88e56889a68c 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
@@ -2311,6 +2311,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
 								v->OutputFormat[k],
 								v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
 			}
+			v->DSCDelay[k] = v->DSCDelay[k] + (v->HTotal[k] - v->HActive[k]) * dml_ceil((double) v->DSCDelay[k] / v->HActive[k], 1);
 			v->DSCDelay[k] = v->DSCDelay[k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
 		} else {
 			v->DSCDelay[k] = 0;
@@ -4719,6 +4720,7 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
 									v->OutputFormat[k],
 									v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
 				}
+				v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][k] + (v->HTotal[k] - v->HActive[k]) * dml_ceil((double) v->DSCDelayPerState[i][k] / v->HActive[k], 1.0);
 				v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
 			} else {
 				v->DSCDelayPerState[i][k] = 0.0;
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/28] drm/amd/display: do not block ODM + OPM on one side of the screen
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (6 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 07/28] drm/amd/display: Fix DML calculation errors Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28   ` Stylon Wang
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
build scaling param is overriding validation policy regarding small viewport
support. Even if ODM + windowed MPO is not supported. The decision has
to be made at the time of validation. When building scaling params, we might
be building an initial dc state as an input to DML validation. The initial state
is not supposed to be always valid and we rely on DML to modify the initial
dc state and determine the final validation result. This check is pre judging
validation result when building the initial dc state.

This causes an issue where we are transitioning from desktop only ODM
combine 2:1 to ODM bypass with 2 planes. In this case we are building
an initial state with with ODM 2:1 combine + 2 planes. This is indeed not
supported but DML is about to modify the state so it no longer uses ODM
combine. Before it reaches DML, dc resource already fails validation because
it checks that the initial state is not supported by our policy. This overrides
the ODM decision to validate this state with ODM combine disabled. Therefore
causes an unexpected validation failure when the secondary plane is added
on one side of the screen.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index c929003825f4..494efbede0b2 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1371,13 +1371,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 	/* depends on scaling ratios and recout, does not calculate offset yet */
 	calculate_viewport_size(pipe_ctx);
 
-	if (!pipe_ctx->stream->ctx->dc->config.enable_windowed_mpo_odm) {
-		/* Stopgap for validation of ODM + MPO on one side of screen case */
-		if (pipe_ctx->plane_res.scl_data.viewport.height < 1 ||
-				pipe_ctx->plane_res.scl_data.viewport.width < 1)
-			return false;
-	}
-
 	/*
 	 * LB calculations depend on vp size, h/v_active and scaling ratios
 	 * Setting line buffer pixel depth to 24bpp yields banding
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/28] drm/amd/display: Fix 2nd DPIA encoder Assignment
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
@ 2023-09-06 12:28   ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 02/28] drm/amd/display: Don't lock phantom pipe on disabling Stylon Wang
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, roman.li, wayne.lin,
	stylon.wang, solomon.chiu, pavle.kotarac, agustin.gutierrez,
	Mustapha Ghaddar, Cruise Hung, Meenakshikumar Somasundaram,
	Mario Limonciello, Alex Deucher, stable

From: Mustapha Ghaddar <mghaddar@amd.com>

[HOW & Why]
There seems to be an issue with 2nd DPIA acquiring link encoder for tiled displays.
Solution is to remove check for eng_id before we get first dynamic encoder for it

Reviewed-by: Cruise Hung <cruise.hung@amd.com>
Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Mustapha Ghaddar <mghaddar@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
index b66eeac4d3d2..be5a6d008b29 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
@@ -395,8 +395,7 @@ void link_enc_cfg_link_encs_assign(
 					stream->link->dpia_preferred_eng_id != ENGINE_ID_UNKNOWN)
 				eng_id_req = stream->link->dpia_preferred_eng_id;
 
-			if (eng_id == ENGINE_ID_UNKNOWN)
-				eng_id = find_first_avail_link_enc(stream->ctx, state, eng_id_req);
+			eng_id = find_first_avail_link_enc(stream->ctx, state, eng_id_req);
 		}
 		else
 			eng_id =  link_enc->preferred_engine;
@@ -501,7 +500,6 @@ struct dc_link *link_enc_cfg_get_link_using_link_enc(
 	if (stream)
 		link = stream->link;
 
-	// dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id);
 	return link;
 }
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/28] drm/amd/display: Fix 2nd DPIA encoder Assignment
@ 2023-09-06 12:28   ` Stylon Wang
  0 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, stable, Meenakshikumar Somasundaram,
	solomon.chiu, Aurabindo.Pillai, Mario Limonciello, wayne.lin,
	Alex Deucher, Mustapha Ghaddar, Bhawanpreet.Lakha, Cruise Hung,
	agustin.gutierrez, pavle.kotarac

From: Mustapha Ghaddar <mghaddar@amd.com>

[HOW & Why]
There seems to be an issue with 2nd DPIA acquiring link encoder for tiled displays.
Solution is to remove check for eng_id before we get first dynamic encoder for it

Reviewed-by: Cruise Hung <cruise.hung@amd.com>
Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Mustapha Ghaddar <mghaddar@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
index b66eeac4d3d2..be5a6d008b29 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
@@ -395,8 +395,7 @@ void link_enc_cfg_link_encs_assign(
 					stream->link->dpia_preferred_eng_id != ENGINE_ID_UNKNOWN)
 				eng_id_req = stream->link->dpia_preferred_eng_id;
 
-			if (eng_id == ENGINE_ID_UNKNOWN)
-				eng_id = find_first_avail_link_enc(stream->ctx, state, eng_id_req);
+			eng_id = find_first_avail_link_enc(stream->ctx, state, eng_id_req);
 		}
 		else
 			eng_id =  link_enc->preferred_engine;
@@ -501,7 +500,6 @@ struct dc_link *link_enc_cfg_get_link_using_link_enc(
 	if (stream)
 		link = stream->link;
 
-	// dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id);
 	return link;
 }
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/28] drm/amd/display: Adjust the MST resume flow
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
@ 2023-09-06 12:28   ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 02/28] drm/amd/display: Don't lock phantom pipe on disabling Stylon Wang
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, roman.li, wayne.lin,
	stylon.wang, solomon.chiu, pavle.kotarac, agustin.gutierrez,
	Mario Limonciello, Alex Deucher, stable

From: Wayne Lin <wayne.lin@amd.com>

[Why]
In drm_dp_mst_topology_mgr_resume() today, it will resume the
mst branch to be ready handling mst mode and also consecutively do
the mst topology probing. Which will cause the dirver have chance
to fire hotplug event before restoring the old state. Then Userspace
will react to the hotplug event based on a wrong state.

[How]
Adjust the mst resume flow as:
1. set dpcd to resume mst branch status
2. restore source old state
3. Do mst resume topology probing

For drm_dp_mst_topology_mgr_resume(), it's better to adjust it to
pull out topology probing work into a 2nd part procedure of the mst
resume. Will have a follow up patch in drm.

Reviewed-by: Chao-kai Wang <stylon.wang@amd.com>
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 93 ++++++++++++++++---
 1 file changed, 80 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 93f8ec2acb4a..15bd87200f6d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2350,14 +2350,62 @@ static int dm_late_init(void *handle)
 	return detect_mst_link_for_all_connectors(adev_to_drm(adev));
 }
 
+static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr)
+{
+	int ret;
+	u8 guid[16];
+	u64 tmp64;
+
+	mutex_lock(&mgr->lock);
+	if (!mgr->mst_primary)
+		goto out_fail;
+
+	if (drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd) < 0) {
+		drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n");
+		goto out_fail;
+	}
+
+	ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
+				 DP_MST_EN |
+				 DP_UP_REQ_EN |
+				 DP_UPSTREAM_IS_SRC);
+	if (ret < 0) {
+		drm_dbg_kms(mgr->dev, "mst write failed - undocked during suspend?\n");
+		goto out_fail;
+	}
+
+	/* Some hubs forget their guids after they resume */
+	ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
+	if (ret != 16) {
+		drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n");
+		goto out_fail;
+	}
+
+	if (memchr_inv(guid, 0, 16) == NULL) {
+		tmp64 = get_jiffies_64();
+		memcpy(&guid[0], &tmp64, sizeof(u64));
+		memcpy(&guid[8], &tmp64, sizeof(u64));
+
+		ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, guid, 16);
+
+		if (ret != 16) {
+			drm_dbg_kms(mgr->dev, "check mstb guid failed - undocked during suspend?\n");
+			goto out_fail;
+		}
+	}
+
+	memcpy(mgr->mst_primary->guid, guid, 16);
+
+out_fail:
+	mutex_unlock(&mgr->lock);
+}
+
 static void s3_handle_mst(struct drm_device *dev, bool suspend)
 {
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_connector *connector;
 	struct drm_connector_list_iter iter;
 	struct drm_dp_mst_topology_mgr *mgr;
-	int ret;
-	bool need_hotplug = false;
 
 	drm_connector_list_iter_begin(dev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
@@ -2379,18 +2427,15 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
 			if (!dp_is_lttpr_present(aconnector->dc_link))
 				try_to_configure_aux_timeout(aconnector->dc_link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
 
-			ret = drm_dp_mst_topology_mgr_resume(mgr, true);
-			if (ret < 0) {
-				dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx,
-					aconnector->dc_link);
-				need_hotplug = true;
-			}
+			/* TODO: move resume_mst_branch_status() into drm mst resume again
+			 * once topology probing work is pulled out from mst resume into mst
+			 * resume 2nd step. mst resume 2nd step should be called after old
+			 * state getting restored (i.e. drm_atomic_helper_resume()).
+			 */
+			resume_mst_branch_status(mgr);
 		}
 	}
 	drm_connector_list_iter_end(&iter);
-
-	if (need_hotplug)
-		drm_kms_helper_hotplug_event(dev);
 }
 
 static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
@@ -2784,7 +2829,8 @@ static int dm_resume(void *handle)
 	struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state);
 	enum dc_connection_type new_connection_type = dc_connection_none;
 	struct dc_state *dc_state;
-	int i, r, j;
+	int i, r, j, ret;
+	bool need_hotplug = false;
 
 	if (dm->dc->caps.ips_support) {
 		dc_dmub_srv_exit_low_power_state(dm->dc);
@@ -2886,7 +2932,7 @@ static int dm_resume(void *handle)
 			continue;
 
 		/*
-		 * this is the case when traversing through already created
+		 * this is the case when traversing through already created end sink
 		 * MST connectors, should be skipped
 		 */
 		if (aconnector && aconnector->mst_root)
@@ -2946,6 +2992,27 @@ static int dm_resume(void *handle)
 
 	dm->cached_state = NULL;
 
+	/* Do mst topology probing after resuming cached state*/
+	drm_connector_list_iter_begin(ddev, &iter);
+	drm_for_each_connector_iter(connector, &iter) {
+		aconnector = to_amdgpu_dm_connector(connector);
+		if (aconnector->dc_link->type != dc_connection_mst_branch ||
+		    aconnector->mst_root)
+			continue;
+
+		ret = drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr, true);
+
+		if (ret < 0) {
+			dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx,
+					aconnector->dc_link);
+			need_hotplug = true;
+		}
+	}
+	drm_connector_list_iter_end(&iter);
+
+	if (need_hotplug)
+		drm_kms_helper_hotplug_event(ddev);
+
 	amdgpu_dm_irq_resume_late(adev);
 
 	amdgpu_dm_smu_write_watermarks_table(adev);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/28] drm/amd/display: Adjust the MST resume flow
@ 2023-09-06 12:28   ` Stylon Wang
  0 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, stable, solomon.chiu,
	Aurabindo.Pillai, Mario Limonciello, wayne.lin, Alex Deucher,
	Bhawanpreet.Lakha, agustin.gutierrez, pavle.kotarac

From: Wayne Lin <wayne.lin@amd.com>

[Why]
In drm_dp_mst_topology_mgr_resume() today, it will resume the
mst branch to be ready handling mst mode and also consecutively do
the mst topology probing. Which will cause the dirver have chance
to fire hotplug event before restoring the old state. Then Userspace
will react to the hotplug event based on a wrong state.

[How]
Adjust the mst resume flow as:
1. set dpcd to resume mst branch status
2. restore source old state
3. Do mst resume topology probing

For drm_dp_mst_topology_mgr_resume(), it's better to adjust it to
pull out topology probing work into a 2nd part procedure of the mst
resume. Will have a follow up patch in drm.

Reviewed-by: Chao-kai Wang <stylon.wang@amd.com>
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 93 ++++++++++++++++---
 1 file changed, 80 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 93f8ec2acb4a..15bd87200f6d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2350,14 +2350,62 @@ static int dm_late_init(void *handle)
 	return detect_mst_link_for_all_connectors(adev_to_drm(adev));
 }
 
+static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr)
+{
+	int ret;
+	u8 guid[16];
+	u64 tmp64;
+
+	mutex_lock(&mgr->lock);
+	if (!mgr->mst_primary)
+		goto out_fail;
+
+	if (drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd) < 0) {
+		drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n");
+		goto out_fail;
+	}
+
+	ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
+				 DP_MST_EN |
+				 DP_UP_REQ_EN |
+				 DP_UPSTREAM_IS_SRC);
+	if (ret < 0) {
+		drm_dbg_kms(mgr->dev, "mst write failed - undocked during suspend?\n");
+		goto out_fail;
+	}
+
+	/* Some hubs forget their guids after they resume */
+	ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
+	if (ret != 16) {
+		drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n");
+		goto out_fail;
+	}
+
+	if (memchr_inv(guid, 0, 16) == NULL) {
+		tmp64 = get_jiffies_64();
+		memcpy(&guid[0], &tmp64, sizeof(u64));
+		memcpy(&guid[8], &tmp64, sizeof(u64));
+
+		ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, guid, 16);
+
+		if (ret != 16) {
+			drm_dbg_kms(mgr->dev, "check mstb guid failed - undocked during suspend?\n");
+			goto out_fail;
+		}
+	}
+
+	memcpy(mgr->mst_primary->guid, guid, 16);
+
+out_fail:
+	mutex_unlock(&mgr->lock);
+}
+
 static void s3_handle_mst(struct drm_device *dev, bool suspend)
 {
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_connector *connector;
 	struct drm_connector_list_iter iter;
 	struct drm_dp_mst_topology_mgr *mgr;
-	int ret;
-	bool need_hotplug = false;
 
 	drm_connector_list_iter_begin(dev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
@@ -2379,18 +2427,15 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
 			if (!dp_is_lttpr_present(aconnector->dc_link))
 				try_to_configure_aux_timeout(aconnector->dc_link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
 
-			ret = drm_dp_mst_topology_mgr_resume(mgr, true);
-			if (ret < 0) {
-				dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx,
-					aconnector->dc_link);
-				need_hotplug = true;
-			}
+			/* TODO: move resume_mst_branch_status() into drm mst resume again
+			 * once topology probing work is pulled out from mst resume into mst
+			 * resume 2nd step. mst resume 2nd step should be called after old
+			 * state getting restored (i.e. drm_atomic_helper_resume()).
+			 */
+			resume_mst_branch_status(mgr);
 		}
 	}
 	drm_connector_list_iter_end(&iter);
-
-	if (need_hotplug)
-		drm_kms_helper_hotplug_event(dev);
 }
 
 static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
@@ -2784,7 +2829,8 @@ static int dm_resume(void *handle)
 	struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state);
 	enum dc_connection_type new_connection_type = dc_connection_none;
 	struct dc_state *dc_state;
-	int i, r, j;
+	int i, r, j, ret;
+	bool need_hotplug = false;
 
 	if (dm->dc->caps.ips_support) {
 		dc_dmub_srv_exit_low_power_state(dm->dc);
@@ -2886,7 +2932,7 @@ static int dm_resume(void *handle)
 			continue;
 
 		/*
-		 * this is the case when traversing through already created
+		 * this is the case when traversing through already created end sink
 		 * MST connectors, should be skipped
 		 */
 		if (aconnector && aconnector->mst_root)
@@ -2946,6 +2992,27 @@ static int dm_resume(void *handle)
 
 	dm->cached_state = NULL;
 
+	/* Do mst topology probing after resuming cached state*/
+	drm_connector_list_iter_begin(ddev, &iter);
+	drm_for_each_connector_iter(connector, &iter) {
+		aconnector = to_amdgpu_dm_connector(connector);
+		if (aconnector->dc_link->type != dc_connection_mst_branch ||
+		    aconnector->mst_root)
+			continue;
+
+		ret = drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr, true);
+
+		if (ret < 0) {
+			dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx,
+					aconnector->dc_link);
+			need_hotplug = true;
+		}
+	}
+	drm_connector_list_iter_end(&iter);
+
+	if (need_hotplug)
+		drm_kms_helper_hotplug_event(ddev);
+
 	amdgpu_dm_irq_resume_late(adev);
 
 	amdgpu_dm_smu_write_watermarks_table(adev);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 11/28] drm/amd/display: support main link off before specific vertical line
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (9 preceding siblings ...)
  2023-09-06 12:28   ` Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 12/28] drm/amd/display: Add new logs for AutoDPMTest Stylon Wang
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, solomon.chiu, Aurabindo.Pillai,
	wayne.lin, Paul Hsieh, Robin Chen, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Paul Hsieh <paul.hsieh@amd.com>

[Why]
Some panels request main link off before specific vertical line.
If source turn off main link after specific vertical line then
panel defect will be exposed.

[How]
Add interface to support turn off main link before specific
vertical line

Reviewed-by: Robin Chen <robin.chen@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Paul Hsieh <paul.hsieh@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c          | 10 +++++++++-
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h        |  4 ++--
 .../gpu/drm/amd/display/include/ddc_service_types.h    |  1 +
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
index 0f24b6fbd220..f27cc8f9d0aa 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -35,6 +35,7 @@
 
 static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3};
 static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5};
+static const uint8_t DP_SINK_DEVICE_STR_ID_3[] = {0x42, 0x61, 0x6c, 0x73, 0x61};
 
 /*
  * Convert dmcub psr state to dmcu psr state.
@@ -295,7 +296,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
 		struct psr_context *psr_context,
 		uint8_t panel_inst)
 {
-	union dmub_rb_cmd cmd;
+	union dmub_rb_cmd cmd = { 0 };
 	struct dc_context *dc = dmub->ctx;
 	struct dmub_cmd_psr_copy_settings_data *copy_settings_data
 		= &cmd.psr_copy_settings.psr_copy_settings_data;
@@ -408,6 +409,13 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
 	else
 		copy_settings_data->debug.bitfields.force_wakeup_by_tps3 = 0;
 
+	if (link->psr_settings.psr_version == DC_PSR_VERSION_1 &&
+		link->dpcd_caps.sink_dev_id == DP_DEVICE_ID_0022B9 &&
+		!memcmp(link->dpcd_caps.sink_dev_id_str, DP_SINK_DEVICE_STR_ID_3,
+			sizeof(DP_SINK_DEVICE_STR_ID_3))) {
+		copy_settings_data->poweroff_before_vertical_line = 16;
+	}
+
 	//WA for PSR1 on specific TCON, require frame delay for frame re-lock
 	copy_settings_data->relock_delay_frame_cnt = 0;
 	if (link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8)
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 0367d0850495..6e705b219872 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -2283,9 +2283,9 @@ struct dmub_cmd_psr_copy_settings_data {
 	 */
 	uint16_t dsc_slice_height;
 	/**
-	 * Explicit padding to 4 byte boundary.
+	 * Some panels request main link off before xth vertical line
 	 */
-	uint16_t pad;
+	uint16_t poweroff_before_vertical_line;
 };
 
 /**
diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
index 68dfc7968017..1c603b12957f 100644
--- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
@@ -39,6 +39,7 @@
 #define DP_BRANCH_HW_REV_10 0x10
 #define DP_BRANCH_HW_REV_20 0x20
 
+#define DP_DEVICE_ID_0022B9 0x0022B9
 #define DP_DEVICE_ID_38EC11 0x38EC11
 #define DP_DEVICE_ID_BA4159 0xBA4159
 #define DP_FORCE_PSRSU_CAPABILITY 0x40F
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 12/28] drm/amd/display: Add new logs for AutoDPMTest
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (10 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 11/28] drm/amd/display: support main link off before specific vertical line Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 13/28] drm/amd/display: Add DCHUBBUB callback to report MALL status Stylon Wang
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Ethan Bitnun, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, solomon.chiu,
	Aurabindo.Pillai, Alvin Lee, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Ethan Bitnun <etbitnun@amd.com>

[Description]
 - Add new logs to be used by the AutoDPMTest
 - Enclose AutoDPMTest logs in settings
 - Add logging definition

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Ethan Bitnun <etbitnun@amd.com>
---
 .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c  | 36 +++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/dc.h           |  1 +
 .../drm/amd/display/include/logger_types.h    |  5 ++-
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
index 984b52923534..4fd25bb1ab92 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
@@ -450,6 +450,38 @@ static int dcn32_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base)
 	return 0;
 }
 
+static void dcn32_auto_dpm_test_log(struct dc_clocks *new_clocks, struct clk_mgr_internal *clk_mgr)
+{
+	////////////////////////////////////////////////////////////////////////////
+	//	IMPORTANT: 	When adding more clocks to these logs, do NOT put a newline
+	//	 			anywhere other than at the very end of the string.
+	//
+	//	Formatting example (make sure to have " - " between each entry):
+	//
+	//				AutoDPMTest: clk1:%d - clk2:%d - clk3:%d - clk4:%d\n"
+	////////////////////////////////////////////////////////////////////////////
+	if (new_clocks &&
+		new_clocks->dramclk_khz > 0 &&
+		new_clocks->fclk_khz > 0 &&
+		new_clocks->dcfclk_khz > 0 &&
+		new_clocks->dppclk_khz > 0) {
+
+		if (new_clocks->p_state_change_support) {
+			DC_LOG_AUTO_DPM_TEST("AutoDPMTest: dramclk_khz:%d - fclk_khz:%d - "
+						 "dcfclk_khz:%d - dppclk_khz:%d\n",
+						 new_clocks->dramclk_khz,
+						 new_clocks->fclk_khz,
+						 new_clocks->dcfclk_khz,
+						 new_clocks->dppclk_khz);
+		} else {
+			DC_LOG_AUTO_DPM_TEST("AutoDPMTest: dramclk_khz:1249000 - fclk_khz:%d - "
+						 "dcfclk_khz:%d - dppclk_khz:%d\n",
+						 new_clocks->fclk_khz,
+						 new_clocks->dcfclk_khz,
+						 new_clocks->dppclk_khz);
+		}
+	}
+}
 
 static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
 			struct dc_state *context,
@@ -646,6 +678,10 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
 		/*update dmcu for wait_loop count*/
 		dmcu->funcs->set_psr_wait_loop(dmcu,
 				clk_mgr_base->clks.dispclk_khz / 1000 / 7);
+
+	if (dc->config.enable_auto_dpm_test_logs) {
+	    dcn32_auto_dpm_test_log(new_clocks, clk_mgr);
+	}
 }
 
 static uint32_t dcn32_get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 7e6f819a9952..05ab24c81041 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -420,6 +420,7 @@ struct dc_config {
 	int sdpif_request_limit_words_per_umc;
 	bool use_old_fixed_vs_sequence;
 	bool dc_mode_clk_limit_support;
+	bool enable_auto_dpm_test_logs;
 };
 
 enum visual_confirm {
diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h
index 3bf08a60c45c..fb657f7408a7 100644
--- a/drivers/gpu/drm/amd/display/include/logger_types.h
+++ b/drivers/gpu/drm/amd/display/include/logger_types.h
@@ -73,6 +73,7 @@
 #define DC_LOG_SMU(...) pr_debug("[SMU_MSG]:"__VA_ARGS__)
 #define DC_LOG_DWB(...) DRM_DEBUG_KMS(__VA_ARGS__)
 #define DC_LOG_DP2(...) DRM_DEBUG_KMS(__VA_ARGS__)
+#define DC_LOG_AUTO_DPM_TEST(...) pr_debug("[AutoDPMTest]: "__VA_ARGS__)
 
 struct dal_logger;
 
@@ -128,6 +129,7 @@ enum dc_log_type {
 	LOG_SAMPLE_1DLUT,
 	LOG_DP2,
 	LOG_DC2RESERVED12,
+	LOG_AUTO_DPM_TEST,
 };
 
 #define DC_MIN_LOG_MASK ((1 << LOG_ERROR) | \
@@ -157,7 +159,8 @@ enum dc_log_type {
 		(1ULL << LOG_IF_TRACE) | \
 		(1ULL << LOG_HDMI_FRL) | \
 		(1ULL << LOG_SCALER) | \
-		(1ULL << LOG_DTN) /* | \
+		(1ULL << LOG_DTN) | \
+		(1ULL << LOG_AUTO_DPM_TEST)/* | \
 		(1ULL << LOG_DEBUG) | \
 		(1ULL << LOG_BIOS) | \
 		(1ULL << LOG_SURFACE) | \
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 13/28] drm/amd/display: Add DCHUBBUB callback to report MALL status
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (11 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 12/28] drm/amd/display: Add new logs for AutoDPMTest Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 14/28] drm/amd/display: remove a function that does complex calculation in every frame but not used Stylon Wang
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, solomon.chiu, Aurabindo Pillai,
	Alvin Lee, wayne.lin, Bhawanpreet.Lakha, agustin.gutierrez,
	pavle.kotarac

From: Aurabindo Pillai <aurabindo.pillai@amd.com>

[Why&How]
For enabling automated testing, add a hook to DCHUBBUB interface so that
mall status can be queried by userspace through debugfs. This removes
dependence on requiring a userspace tool like UMR for querying status
for MALL static screen IGT test.

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c  | 13 ++++++++++---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h    |  5 ++++-
 .../gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c    | 14 +++++++++++++-
 .../gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h    |  6 +++++-
 .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.h  |  1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h   |  1 +
 6 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 05c1ad98a1f6..1259d6351c50 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -37,6 +37,7 @@
 #include "link_hwss.h"
 #include "dc/dc_dmub_srv.h"
 #include "link/protocols/link_dp_capability.h"
+#include "inc/hw/dchubbub.h"
 
 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
 #include "amdgpu_dm_psr.h"
@@ -3642,10 +3643,16 @@ DEFINE_DEBUGFS_ATTRIBUTE(disable_hpd_ops, disable_hpd_get,
 static int capabilities_show(struct seq_file *m, void *unused)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
-	struct dc_caps caps = adev->dm.dc->caps;
-	bool mall_supported = caps.mall_size_total;
+	struct dc *dc = adev->dm.dc;
+	bool mall_supported = dc->caps.mall_size_total;
+	unsigned int mall_in_use = false;
+	struct hubbub *hubbub = dc->res_pool->hubbub;
+
+	if (hubbub->funcs->get_mall_en)
+		hubbub->funcs->get_mall_en(hubbub, &mall_in_use);
 
-	seq_printf(m, "mall: %s\n", mall_supported ? "yes" : "no");
+	seq_printf(m, "mall supported: %s, enabled: %s\n",
+			   mall_supported ? "yes" : "no", mall_in_use ? "yes" : "no");
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
index adc876156d2e..5ddf2b36986e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
@@ -171,6 +171,7 @@ struct dcn_hubbub_registers {
 	uint32_t DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B;
 	uint32_t DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C;
 	uint32_t DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D;
+	uint32_t DCHUBBUB_ARB_MALL_CNTL;
 	uint32_t SDPIF_REQUEST_RATE_LIMIT;
 	uint32_t DCHUBBUB_SDPIF_CFG0;
 	uint32_t DCHUBBUB_SDPIF_CFG1;
@@ -194,7 +195,9 @@ struct dcn_hubbub_registers {
 		type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A;\
 		type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B;\
 		type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C;\
-		type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D
+		type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D;\
+		type MALL_PREFETCH_COMPLETE;\
+		type MALL_IN_USE
 
 #define HUBBUB_REG_FIELD_LIST_DCN35(type) \
 		type DCHUBBUB_FGCG_REP_DIS
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c
index 8bfef6d095b2..88dfc907553d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c
@@ -945,6 +945,17 @@ void hubbub32_force_wm_propagate_to_pipes(struct hubbub *hubbub)
 			DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
 }
 
+void hubbub32_get_mall_en(struct hubbub *hubbub, unsigned int *mall_in_use)
+{
+	struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
+	uint32_t prefetch_complete, mall_en;
+
+	REG_GET_2(DCHUBBUB_ARB_MALL_CNTL, MALL_IN_USE, &mall_en,
+			  MALL_PREFETCH_COMPLETE, &prefetch_complete);
+
+	*mall_in_use = prefetch_complete && mall_en;
+}
+
 void hubbub32_init(struct hubbub *hubbub)
 {
 	struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
@@ -995,7 +1006,8 @@ static const struct hubbub_funcs hubbub32_funcs = {
 	.init_crb = dcn32_init_crb,
 	.hubbub_read_state = hubbub2_read_state,
 	.force_usr_retraining_allow = hubbub32_force_usr_retraining_allow,
-	.set_request_limit = hubbub32_set_request_limit
+	.set_request_limit = hubbub32_set_request_limit,
+	.get_mall_en = hubbub32_get_mall_en,
 };
 
 void hubbub32_construct(struct dcn20_hubbub *hubbub2,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h
index ad33427192c6..f073839a4b6d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.h
@@ -110,7 +110,9 @@
 	HUBBUB_SF(DCHUBBUB_CLOCK_CNTL, DCFCLK_R_DCHUBBUB_GATE_DIS, mask_sh),\
 	HUBBUB_SF(DCHUBBUB_SDPIF_CFG0, SDPIF_PORT_CONTROL, mask_sh),\
 	HUBBUB_SF(DCHUBBUB_SDPIF_CFG1, SDPIF_MAX_NUM_OUTSTANDING, mask_sh),\
-	HUBBUB_SF(DCHUBBUB_MEM_PWR_MODE_CTRL, DET_MEM_PWR_LS_MODE, mask_sh)
+	HUBBUB_SF(DCHUBBUB_MEM_PWR_MODE_CTRL, DET_MEM_PWR_LS_MODE, mask_sh),\
+	HUBBUB_SF(DCHUBBUB_ARB_MALL_CNTL, MALL_PREFETCH_COMPLETE, mask_sh),\
+	HUBBUB_SF(DCHUBBUB_ARB_MALL_CNTL, MALL_IN_USE, mask_sh)
 
 
 
@@ -157,4 +159,6 @@ void hubbub32_construct(struct dcn20_hubbub *hubbub2,
 
 void hubbub32_set_request_limit(struct hubbub *hubbub, int umc_count, int words_per_umc);
 
+void hubbub32_get_mall_en(struct hubbub *hubbub, unsigned int *mall_in_use);
+
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
index c76de61029e0..f075982363be 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
@@ -1283,6 +1283,7 @@ bool dcn32_subvp_vblank_admissable(struct dc *dc, struct dc_state *context, int
       SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B),                         \
       SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C),                         \
       SR(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D),                         \
+      SR(DCHUBBUB_ARB_MALL_CNTL),                                              \
       SR(DCN_VM_FAULT_ADDR_MSB), SR(DCN_VM_FAULT_ADDR_LSB),                    \
       SR(DCN_VM_FAULT_CNTL), SR(DCN_VM_FAULT_STATUS),                          \
       SR(SDPIF_REQUEST_RATE_LIMIT)                                             \
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index f5677dbb4e7d..cea05843990c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -193,6 +193,7 @@ struct hubbub_funcs {
 	void (*force_usr_retraining_allow)(struct hubbub *hubbub, bool allow);
 	void (*set_request_limit)(struct hubbub *hubbub, int memory_channel_count, int words_per_channel);
 	void (*dchubbub_init)(struct hubbub *hubbub);
+	void (*get_mall_en)(struct hubbub *hubbub, unsigned int *mall_in_use);
 };
 
 struct hubbub {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 14/28] drm/amd/display: remove a function that does complex calculation in every frame but not used
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (12 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 13/28] drm/amd/display: Add DCHUBBUB callback to report MALL status Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 15/28] drm/amd/display: do not attempt ODM power optimization if minimal transition doesn't exist Stylon Wang
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
The result of predict_pipe_split calculation is no longer used but the
function is not removed. This will cause unnecessary calculation
of pipe split prediction in every frame update.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 .../drm/amd/display/dc/dcn32/dcn32_resource.c |  3 -
 .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c  | 84 -------------------
 .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.h  |  3 -
 3 files changed, 90 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
index fd12791995a7..8cb6b94e83d2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
@@ -2031,9 +2031,6 @@ int dcn32_populate_dml_pipes_from_context(
 			}
 		}
 
-		DC_FP_START();
-		dcn32_predict_pipe_split(context, &pipes[pipe_cnt]);
-		DC_FP_END();
 
 		pipe_cnt++;
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 0c68cd97a461..496f0f58fa7d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -348,90 +348,6 @@ void dcn32_helper_populate_phantom_dlg_params(struct dc *dc,
 	}
 }
 
-/**
- * dcn32_predict_pipe_split - Predict if pipe split will occur for a given DML pipe
- * @context: [in] New DC state to be programmed
- * @pipe_e2e: [in] DML pipe end to end context
- *
- * This function takes in a DML pipe (pipe_e2e) and predicts if pipe split is required (both
- * ODM and MPC). For pipe split, ODM combine is determined by the ODM mode, and MPC combine is
- * determined by DPPClk requirements
- *
- * This function follows the same policy as DML:
- * - Check for ODM combine requirements / policy first
- * - MPC combine is only chosen if there is no ODM combine requirements / policy in place, and
- *   MPC is required
- *
- * Return: Number of splits expected (1 for 2:1 split, 3 for 4:1 split, 0 for no splits).
- */
-uint8_t dcn32_predict_pipe_split(struct dc_state *context,
-				  display_e2e_pipe_params_st *pipe_e2e)
-{
-	double pscl_throughput;
-	double pscl_throughput_chroma;
-	double dpp_clk_single_dpp, clock;
-	double clk_frequency = 0.0;
-	double vco_speed = context->bw_ctx.dml.soc.dispclk_dppclk_vco_speed_mhz;
-	bool total_available_pipes_support = false;
-	uint32_t number_of_dpp = 0;
-	enum odm_combine_mode odm_mode = dm_odm_combine_mode_disabled;
-	double req_dispclk_per_surface = 0;
-	uint8_t num_splits = 0;
-
-	dc_assert_fp_enabled();
-
-	dml32_CalculateODMMode(context->bw_ctx.dml.ip.maximum_pixels_per_line_per_dsc_unit,
-			pipe_e2e->pipe.dest.hactive,
-			pipe_e2e->dout.output_format,
-			pipe_e2e->dout.output_type,
-			pipe_e2e->pipe.dest.odm_combine_policy,
-			context->bw_ctx.dml.soc.clock_limits[context->bw_ctx.dml.soc.num_states - 1].dispclk_mhz,
-			context->bw_ctx.dml.soc.clock_limits[context->bw_ctx.dml.soc.num_states - 1].dispclk_mhz,
-			pipe_e2e->dout.dsc_enable != 0,
-			0, /* TotalNumberOfActiveDPP can be 0 since we're predicting pipe split requirement */
-			context->bw_ctx.dml.ip.max_num_dpp,
-			pipe_e2e->pipe.dest.pixel_rate_mhz,
-			context->bw_ctx.dml.soc.dcn_downspread_percent,
-			context->bw_ctx.dml.ip.dispclk_ramp_margin_percent,
-			context->bw_ctx.dml.soc.dispclk_dppclk_vco_speed_mhz,
-			pipe_e2e->dout.dsc_slices,
-			/* Output */
-			&total_available_pipes_support,
-			&number_of_dpp,
-			&odm_mode,
-			&req_dispclk_per_surface);
-
-	dml32_CalculateSinglePipeDPPCLKAndSCLThroughput(pipe_e2e->pipe.scale_ratio_depth.hscl_ratio,
-			pipe_e2e->pipe.scale_ratio_depth.hscl_ratio_c,
-			pipe_e2e->pipe.scale_ratio_depth.vscl_ratio,
-			pipe_e2e->pipe.scale_ratio_depth.vscl_ratio_c,
-			context->bw_ctx.dml.ip.max_dchub_pscl_bw_pix_per_clk,
-			context->bw_ctx.dml.ip.max_pscl_lb_bw_pix_per_clk,
-			pipe_e2e->pipe.dest.pixel_rate_mhz,
-			pipe_e2e->pipe.src.source_format,
-			pipe_e2e->pipe.scale_taps.htaps,
-			pipe_e2e->pipe.scale_taps.htaps_c,
-			pipe_e2e->pipe.scale_taps.vtaps,
-			pipe_e2e->pipe.scale_taps.vtaps_c,
-			/* Output */
-			&pscl_throughput, &pscl_throughput_chroma,
-			&dpp_clk_single_dpp);
-
-	clock = dpp_clk_single_dpp * (1 + context->bw_ctx.dml.soc.dcn_downspread_percent / 100);
-
-	if (clock > 0)
-		clk_frequency = vco_speed * 4.0 / ((int)(vco_speed * 4.0) / clock);
-
-	if (odm_mode == dm_odm_combine_mode_2to1)
-		num_splits = 1;
-	else if (odm_mode == dm_odm_combine_mode_4to1)
-		num_splits = 3;
-	else if (clk_frequency > context->bw_ctx.dml.soc.clock_limits[context->bw_ctx.dml.soc.num_states - 1].dppclk_mhz)
-		num_splits = 1;
-
-	return num_splits;
-}
-
 static float calculate_net_bw_in_kbytes_sec(struct _vcs_dpi_voltage_scaling_st *entry)
 {
 	float memory_bw_kbytes_sec;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h
index defbee866be6..d25c3f730a59 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h
@@ -36,9 +36,6 @@ void dcn32_helper_populate_phantom_dlg_params(struct dc *dc,
 					      display_e2e_pipe_params_st *pipes,
 					      int pipe_cnt);
 
-uint8_t dcn32_predict_pipe_split(struct dc_state *context,
-				  display_e2e_pipe_params_st *pipe_e2e);
-
 void dcn32_set_phantom_stream_timing(struct dc *dc,
 				     struct dc_state *context,
 				     struct pipe_ctx *ref_pipe,
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 15/28] drm/amd/display: do not attempt ODM power optimization if minimal transition doesn't exist
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (13 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 14/28] drm/amd/display: remove a function that does complex calculation in every frame but not used Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 16/28] drm/amd/display: only allow ODM power optimization if surface is within guaranteed viewport size Stylon Wang
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
In some cases such as 8k desktop surface with 144Hz timing, we decide to
enable ODM power optimization but this surface doesn't have a minimum
transition state. Therefore we cannot switch off ODM power optimization seamlessly
This creates path depedency on ODM power optimization decision. i.e
whether or not we should switch off ODM power optimization is dependent
on if the transition to switch off ODM power optimization from current state
is seamless. We don't desire a path dependent power optimization policy
as it is too dynamic and difficult to maintain.

[how]
Attempt ODM power optimization only after we can validate new state without
using pipe combine.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 .../drm/amd/display/dc/dcn32/dcn32_resource.c |  76 +--
 .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c  | 487 +++++++++++-------
 2 files changed, 306 insertions(+), 257 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
index 8cb6b94e83d2..a74d4cab5a7d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
@@ -1885,67 +1885,6 @@ bool dcn32_validate_bandwidth(struct dc *dc,
 	return out;
 }
 
-static bool should_allow_odm_power_optimization(struct dc *dc,
-		struct dc_state *context)
-{
-	struct dc_stream_state *stream = context->streams[0];
-
-	/*
-	 * this debug flag allows us to disable ODM power optimization feature
-	 * unconditionally. we force the feature off if this is set to false.
-	 */
-	if (!dc->debug.enable_single_display_2to1_odm_policy)
-		return false;
-
-	/* current design and test coverage is only limited to allow ODM power
-	 * optimization for single stream. Supporting it for multiple streams
-	 * use case would require additional algorithm to decide how to
-	 * optimize power consumption when there are not enough free pipes to
-	 * allocate for all the streams. This level of optimization would
-	 * require multiple attempts of revalidation to make an optimized
-	 * decision. Unfortunately We do not support revalidation flow in
-	 * current version of DML.
-	 */
-	if (context->stream_count != 1)
-		return false;
-
-	/*
-	 * Our hardware doesn't support ODM for HDMI TMDS
-	 */
-	if (dc_is_hdmi_signal(stream->signal))
-		return false;
-
-	/*
-	 * ODM Combine 2:1 requires horizontal timing divisible by 2 so each
-	 * ODM segment has the same size.
-	 */
-	if (!is_h_timing_divisible_by_2(stream))
-		return false;
-
-	/*
-	 * No power benefits if the timing's pixel clock is not high enough to
-	 * raise display clock from minimum power state.
-	 */
-	if (stream->timing.pix_clk_100hz * 100 <= DCN3_2_VMIN_DISPCLK_HZ)
-		return false;
-
-	/* the new ODM power optimization feature reduces software design
-	 * limitation and allows ODM power optimization to be supported even
-	 * with presence of overlay planes. The new feature is enabled based on
-	 * enable_windowed_mpo_odm flag. If the flag is not set, we limit our
-	 * feature scope due to previous software design limitation */
-	if (!dc->config.enable_windowed_mpo_odm) {
-		if (context->stream_status[0].plane_count != 1)
-			return false;
-
-		if (stream->src.width >= 5120 &&
-				stream->src.width > stream->dst.width)
-			return false;
-	}
-
-	return true;
-}
-
 int dcn32_populate_dml_pipes_from_context(
 	struct dc *dc, struct dc_state *context,
 	display_e2e_pipe_params_st *pipes,
@@ -1959,20 +1898,6 @@ int dcn32_populate_dml_pipes_from_context(
 
 	dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
 
-	/*
-	 * Apply pipe split policy first so we can predict the pipe split correctly
-	 * (dcn32_predict_pipe_split).
-	 */
-	for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
-		if (!res_ctx->pipe_ctx[i].stream)
-			continue;
-		if (should_allow_odm_power_optimization(dc, context))
-			pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1;
-		else
-			pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
-		pipe_cnt++;
-	}
-
 	for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
 
 		if (!res_ctx->pipe_ctx[i].stream)
@@ -1985,6 +1910,7 @@ int dcn32_populate_dml_pipes_from_context(
 		dcn32_zero_pipe_dcc_fraction(pipes, pipe_cnt);
 		DC_FP_END();
 		pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
+		pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
 		pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet
 		pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
 		pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 496f0f58fa7d..883e90be2257 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -1078,6 +1078,307 @@ static void assign_subvp_index(struct dc *dc, struct dc_state *context)
 	}
 }
 
+struct pipe_slice_table {
+	struct {
+		struct dc_stream_state *stream;
+		int slice_count;
+	} odm_combines[MAX_STREAMS];
+	int odm_combine_count;
+
+	struct {
+		struct dc_plane_state *plane;
+		int slice_count;
+	} mpc_combines[MAX_SURFACES];
+	int mpc_combine_count;
+};
+
+
+static void update_slice_table_for_stream(struct pipe_slice_table *table,
+		struct dc_stream_state *stream, int diff)
+{
+	int i;
+
+	for (i = 0; i < table->odm_combine_count; i++) {
+		if (table->odm_combines[i].stream == stream) {
+			table->odm_combines[i].slice_count += diff;
+			break;
+		}
+	}
+
+	if (i == table->odm_combine_count) {
+		table->odm_combine_count++;
+		table->odm_combines[i].stream = stream;
+		table->odm_combines[i].slice_count = diff;
+	}
+}
+
+static void update_slice_table_for_plane(struct pipe_slice_table *table,
+		struct dc_plane_state *plane, int diff)
+{
+	int i;
+
+	for (i = 0; i < table->mpc_combine_count; i++) {
+		if (table->mpc_combines[i].plane == plane) {
+			table->mpc_combines[i].slice_count += diff;
+			break;
+		}
+	}
+
+	if (i == table->mpc_combine_count) {
+		table->mpc_combine_count++;
+		table->mpc_combines[i].plane = plane;
+		table->mpc_combines[i].slice_count = diff;
+	}
+}
+
+static void init_pipe_slice_table_from_context(
+		struct pipe_slice_table *table,
+		struct dc_state *context)
+{
+	int i, j;
+	struct pipe_ctx *otg_master;
+	struct pipe_ctx *dpp_pipes[MAX_PIPES];
+	struct dc_stream_state *stream;
+	int count;
+
+	memset(table, 0, sizeof(*table));
+
+	for (i = 0; i < context->stream_count; i++) {
+		stream = context->streams[i];
+		otg_master = resource_get_otg_master_for_stream(
+				&context->res_ctx, stream);
+		count = resource_get_odm_slice_count(otg_master);
+		update_slice_table_for_stream(table, stream, count);
+
+		count = resource_get_dpp_pipes_for_opp_head(otg_master,
+				&context->res_ctx, dpp_pipes);
+		for (j = 0; j < count; j++)
+			if (dpp_pipes[j]->plane_state)
+				update_slice_table_for_plane(table,
+						dpp_pipes[j]->plane_state, 1);
+	}
+}
+
+static bool update_pipe_slice_table_with_split_flags(
+		struct pipe_slice_table *table,
+		struct dc *dc,
+		struct dc_state *context,
+		struct vba_vars_st *vba,
+		int split[MAX_PIPES],
+		bool merge[MAX_PIPES])
+{
+	/* NOTE: we are deprecating the support for the concept of pipe splitting
+	 * or pipe merging. Instead we append slices to the end and remove
+	 * slices from the end. The following code converts a pipe split or
+	 * merge to an append or remove operation.
+	 *
+	 * For example:
+	 * When split flags describe the following pipe connection transition
+	 *
+	 * from:
+	 *  pipe 0 (split=2) -> pipe 1 (split=2)
+	 * to: (old behavior)
+	 *  pipe 0 -> pipe 2 -> pipe 1 -> pipe 3
+	 *
+	 * the code below actually does:
+	 *  pipe 0 -> pipe 1 -> pipe 2 -> pipe 3
+	 *
+	 * This is the new intended behavior and for future DCNs we will retire
+	 * the old concept completely.
+	 */
+	struct pipe_ctx *pipe;
+	bool odm;
+	int i;
+	bool updated = false;
+
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		pipe = &context->res_ctx.pipe_ctx[i];
+
+		if (merge[i]) {
+			if (resource_is_pipe_type(pipe, OPP_HEAD))
+				/* merging OPP head means reducing ODM slice
+				 * count by 1
+				 */
+				update_slice_table_for_stream(table, pipe->stream, -1);
+			else if (resource_is_pipe_type(pipe, DPP_PIPE) &&
+					resource_get_odm_slice_index(resource_get_opp_head(pipe)) == 0)
+				/* merging DPP pipe of the first ODM slice means
+				 * reducing MPC slice count by 1
+				 */
+				update_slice_table_for_plane(table, pipe->plane_state, -1);
+			updated = true;
+		}
+
+		if (split[i]) {
+			odm = vba->ODMCombineEnabled[vba->pipe_plane[i]] !=
+					dm_odm_combine_mode_disabled;
+			if (odm && resource_is_pipe_type(pipe, OPP_HEAD))
+				update_slice_table_for_stream(
+						table, pipe->stream, split[i] - 1);
+			else if (!odm && resource_is_pipe_type(pipe, DPP_PIPE))
+				update_slice_table_for_plane(
+						table, pipe->plane_state, split[i] - 1);
+			updated = true;
+		}
+	}
+	return updated;
+}
+
+static void update_pipes_with_slice_table(struct dc *dc, struct dc_state *context,
+		struct pipe_slice_table *table)
+{
+	int i;
+
+	for (i = 0; i < table->odm_combine_count; i++) {
+		resource_update_pipes_for_stream_with_slice_count(context,
+				dc->current_state, dc->res_pool,
+				table->odm_combines[i].stream,
+				table->odm_combines[i].slice_count);
+		/* TODO: move this into the function above */
+		dcn20_build_mapped_resource(dc, context,
+				table->odm_combines[i].stream);
+	}
+
+	for (i = 0; i < table->mpc_combine_count; i++)
+		resource_update_pipes_for_plane_with_slice_count(context,
+				dc->current_state, dc->res_pool,
+				table->mpc_combines[i].plane,
+				table->mpc_combines[i].slice_count);
+}
+
+static bool update_pipes_with_split_flags(struct dc *dc, struct dc_state *context,
+		struct vba_vars_st *vba, int split[MAX_PIPES],
+		bool merge[MAX_PIPES])
+{
+	struct pipe_slice_table slice_table;
+	bool updated;
+
+	init_pipe_slice_table_from_context(&slice_table, context);
+	updated = update_pipe_slice_table_with_split_flags(
+			&slice_table, dc, context, vba,
+			split, merge);
+	update_pipes_with_slice_table(dc, context, &slice_table);
+	return updated;
+}
+
+static bool should_allow_odm_power_optimization(struct dc *dc,
+		struct dc_state *context, struct vba_vars_st *v, int *split,
+		bool *merge)
+{
+	struct dc_stream_state *stream = context->streams[0];
+	struct pipe_slice_table slice_table;
+	int i;
+
+	/*
+	 * this debug flag allows us to disable ODM power optimization feature
+	 * unconditionally. we force the feature off if this is set to false.
+	 */
+	if (!dc->debug.enable_single_display_2to1_odm_policy)
+		return false;
+
+	/* current design and test coverage is only limited to allow ODM power
+	 * optimization for single stream. Supporting it for multiple streams
+	 * use case would require additional algorithm to decide how to
+	 * optimize power consumption when there are not enough free pipes to
+	 * allocate for all the streams. This level of optimization would
+	 * require multiple attempts of revalidation to make an optimized
+	 * decision. Unfortunately We do not support revalidation flow in
+	 * current version of DML.
+	 */
+	if (context->stream_count != 1)
+		return false;
+
+	/*
+	 * Our hardware doesn't support ODM for HDMI TMDS
+	 */
+	if (dc_is_hdmi_signal(stream->signal))
+		return false;
+
+	/*
+	 * ODM Combine 2:1 requires horizontal timing divisible by 2 so each
+	 * ODM segment has the same size.
+	 */
+	if (!is_h_timing_divisible_by_2(stream))
+		return false;
+
+	/*
+	 * No power benefits if the timing's pixel clock is not high enough to
+	 * raise display clock from minimum power state.
+	 */
+	if (stream->timing.pix_clk_100hz * 100 <= DCN3_2_VMIN_DISPCLK_HZ)
+		return false;
+
+	if (dc->config.enable_windowed_mpo_odm) {
+		/*
+		 * ODM power optimization should only be allowed if the feature
+		 * can be seamlessly toggled off within an update. This would
+		 * require that the feature is applied on top of a minimal
+		 * state. A minimal state is defined as a state validated
+		 * without the need of pipe split. Therefore, when transition to
+		 * toggle the feature off, the same stream and plane
+		 * configuration can be supported by the pipe resource in the
+		 * first ODM slice alone without the need to acquire extra
+		 * resources.
+		 */
+		init_pipe_slice_table_from_context(&slice_table, context);
+		update_pipe_slice_table_with_split_flags(
+				&slice_table, dc, context, v,
+				split, merge);
+		for (i = 0; i < slice_table.mpc_combine_count; i++)
+			if (slice_table.mpc_combines[i].slice_count > 1)
+				return false;
+
+		for (i = 0; i < slice_table.odm_combine_count; i++)
+			if (slice_table.odm_combines[i].slice_count > 1)
+				return false;
+	} else {
+		/*
+		 * the new ODM power optimization feature reduces software
+		 * design limitation and allows ODM power optimization to be
+		 * supported even with presence of overlay planes. The new
+		 * feature is enabled based on enable_windowed_mpo_odm flag. If
+		 * the flag is not set, we limit our feature scope due to
+		 * previous software design limitation
+		 */
+		if (context->stream_status[0].plane_count != 1)
+			return false;
+
+		if (memcmp(&context->stream_status[0].plane_states[0]->clip_rect,
+				&stream->src, sizeof(struct rect)) != 0)
+			return false;
+
+		if (stream->src.width >= 5120 &&
+				stream->src.width > stream->dst.width)
+			return false;
+	}
+	return true;
+}
+
+static void try_odm_power_optimization_and_revalidate(
+		struct dc *dc,
+		struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int *split,
+		bool *merge,
+		unsigned int *vlevel,
+		int pipe_cnt)
+{
+	int i;
+	unsigned int new_vlevel;
+
+	for (i = 0; i < pipe_cnt; i++)
+		pipes[i].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1;
+
+	new_vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
+
+	if (new_vlevel < context->bw_ctx.dml.soc.num_states) {
+		memset(split, 0, MAX_PIPES * sizeof(int));
+		memset(merge, 0, MAX_PIPES * sizeof(bool));
+		*vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, new_vlevel, split, merge);
+		context->bw_ctx.dml.vba.VoltageLevel = *vlevel;
+	}
+}
+
 static void dcn32_full_validate_bw_helper(struct dc *dc,
 				   struct dc_state *context,
 				   display_e2e_pipe_params_st *pipes,
@@ -1113,6 +1414,10 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
 		vba->VoltageLevel = *vlevel;
 	}
 
+	if (should_allow_odm_power_optimization(dc, context, vba, split, merge))
+		try_odm_power_optimization_and_revalidate(
+				dc, context, pipes, split, merge, vlevel, *pipe_cnt);
+
 	/* Conditions for setting up phantom pipes for SubVP:
 	 * 1. Not force disable SubVP
 	 * 2. Full update (i.e. !fast_validate)
@@ -1570,188 +1875,6 @@ static bool dcn32_split_stream_for_mpc_or_odm(
 	return true;
 }
 
-struct pipe_slice_table {
-	struct {
-		struct dc_stream_state *stream;
-		int slice_count;
-	} odm_combines[MAX_STREAMS];
-	int odm_combine_count;
-
-	struct {
-		struct dc_plane_state *plane;
-		int slice_count;
-	} mpc_combines[MAX_SURFACES];
-	int mpc_combine_count;
-};
-
-static void update_slice_table_for_stream(struct pipe_slice_table *table,
-		struct dc_stream_state *stream, int diff)
-{
-	int i;
-
-	for (i = 0; i < table->odm_combine_count; i++) {
-		if (table->odm_combines[i].stream == stream) {
-			table->odm_combines[i].slice_count += diff;
-			break;
-		}
-	}
-
-	if (i == table->odm_combine_count) {
-		table->odm_combine_count++;
-		table->odm_combines[i].stream = stream;
-		table->odm_combines[i].slice_count = diff;
-	}
-}
-
-static void update_slice_table_for_plane(struct pipe_slice_table *table,
-		struct dc_plane_state *plane, int diff)
-{
-	int i;
-
-	for (i = 0; i < table->mpc_combine_count; i++) {
-		if (table->mpc_combines[i].plane == plane) {
-			table->mpc_combines[i].slice_count += diff;
-			break;
-		}
-	}
-
-	if (i == table->mpc_combine_count) {
-		table->mpc_combine_count++;
-		table->mpc_combines[i].plane = plane;
-		table->mpc_combines[i].slice_count = diff;
-	}
-}
-
-static void init_pipe_slice_table_from_context(
-		struct pipe_slice_table *table,
-		struct dc_state *context)
-{
-	int i, j;
-	struct pipe_ctx *otg_master;
-	struct pipe_ctx *dpp_pipes[MAX_PIPES];
-	struct dc_stream_state *stream;
-	int count;
-
-	memset(table, 0, sizeof(*table));
-
-	for (i = 0; i < context->stream_count; i++) {
-		stream = context->streams[i];
-		otg_master = resource_get_otg_master_for_stream(
-				&context->res_ctx, stream);
-		count = resource_get_odm_slice_count(otg_master);
-		update_slice_table_for_stream(table, stream, count);
-
-		count = resource_get_dpp_pipes_for_opp_head(otg_master,
-				&context->res_ctx, dpp_pipes);
-		for (j = 0; j < count; j++)
-			if (dpp_pipes[j]->plane_state)
-				update_slice_table_for_plane(table,
-						dpp_pipes[j]->plane_state, 1);
-	}
-}
-
-static bool update_pipe_slice_table_with_split_flags(
-		struct pipe_slice_table *table,
-		struct dc *dc,
-		struct dc_state *context,
-		struct vba_vars_st *vba,
-		int split[MAX_PIPES],
-		bool merge[MAX_PIPES])
-{
-	/* NOTE: we are deprecating the support for the concept of pipe splitting
-	 * or pipe merging. Instead we append slices to the end and remove
-	 * slices from the end. The following code converts a pipe split or
-	 * merge to an append or remove operation.
-	 *
-	 * For example:
-	 * When split flags describe the following pipe connection transition
-	 *
-	 * from:
-	 *  pipe 0 (split=2) -> pipe 1 (split=2)
-	 * to: (old behavior)
-	 *  pipe 0 -> pipe 2 -> pipe 1 -> pipe 3
-	 *
-	 * the code below actually does:
-	 *  pipe 0 -> pipe 1 -> pipe 2 -> pipe 3
-	 *
-	 * This is the new intended behavior and for future DCNs we will retire
-	 * the old concept completely.
-	 */
-	struct pipe_ctx *pipe;
-	bool odm;
-	int i;
-	bool updated = false;
-
-	for (i = 0; i < dc->res_pool->pipe_count; i++) {
-		pipe = &context->res_ctx.pipe_ctx[i];
-
-		if (merge[i]) {
-			if (resource_is_pipe_type(pipe, OPP_HEAD))
-				/* merging OPP head means reducing ODM slice
-				 * count by 1
-				 */
-				update_slice_table_for_stream(table, pipe->stream, -1);
-			else if (resource_is_pipe_type(pipe, DPP_PIPE) &&
-					resource_get_odm_slice_index(resource_get_opp_head(pipe)) == 0)
-				/* merging DPP pipe of the first ODM slice means
-				 * reducing MPC slice count by 1
-				 */
-				update_slice_table_for_plane(table, pipe->plane_state, -1);
-			updated = true;
-		}
-
-		if (split[i]) {
-			odm = vba->ODMCombineEnabled[vba->pipe_plane[i]] !=
-					dm_odm_combine_mode_disabled;
-			if (odm && resource_is_pipe_type(pipe, OPP_HEAD))
-				update_slice_table_for_stream(
-						table, pipe->stream, split[i] - 1);
-			else if (!odm && resource_is_pipe_type(pipe, DPP_PIPE))
-				update_slice_table_for_plane(
-						table, pipe->plane_state, split[i] - 1);
-			updated = true;
-		}
-	}
-	return updated;
-}
-
-static void update_pipes_with_slice_table(struct dc *dc, struct dc_state *context,
-		struct pipe_slice_table *table)
-{
-	int i;
-
-	for (i = 0; i < table->odm_combine_count; i++) {
-		resource_update_pipes_for_stream_with_slice_count(context,
-				dc->current_state, dc->res_pool,
-				table->odm_combines[i].stream,
-				table->odm_combines[i].slice_count);
-		/* TODO: move this into the function above */
-		dcn20_build_mapped_resource(dc, context,
-				table->odm_combines[i].stream);
-	}
-
-	for (i = 0; i < table->mpc_combine_count; i++)
-		resource_update_pipes_for_plane_with_slice_count(context,
-				dc->current_state, dc->res_pool,
-				table->mpc_combines[i].plane,
-				table->mpc_combines[i].slice_count);
-}
-
-static bool update_pipes_with_split_flags(struct dc *dc, struct dc_state *context,
-		struct vba_vars_st *vba, int split[MAX_PIPES],
-		bool merge[MAX_PIPES])
-{
-	struct pipe_slice_table slice_table;
-	bool updated;
-
-	init_pipe_slice_table_from_context(&slice_table, context);
-	updated = update_pipe_slice_table_with_split_flags(
-			&slice_table, dc, context, vba,
-			split, merge);
-	update_pipes_with_slice_table(dc, context, &slice_table);
-	return updated;
-}
-
 bool dcn32_internal_validate_bw(struct dc *dc,
 				struct dc_state *context,
 				display_e2e_pipe_params_st *pipes,
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 16/28] drm/amd/display: only allow ODM power optimization if surface is within guaranteed viewport size
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (14 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 15/28] drm/amd/display: do not attempt ODM power optimization if minimal transition doesn't exist Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 17/28] drm/amd/display: add dp dto programming function to dccg Stylon Wang
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
Current dc update design has limitation to support transition from
ODM combine to minimum transition to MPC combine state seamlessly
at the capability boundary when MPO plane is resizing. This will
require dc update high level refactor in order to remove the design
limitation. The decision is to block such use case for existing products
by limiting ODM power optimization support for only those surfaces
within guaranteed viewport size. This will prevent us from transitioning
to MPC combine state when ODM power optimization is enabled.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 36 +++++++++++++++++++
 .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c  | 27 ++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index dcedda85dcdb..0320bc49458c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3881,6 +3881,7 @@ static void commit_planes_for_stream(struct dc *dc,
  */
 static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
 		struct dc_stream_state *stream,
+		struct dc_surface_update *srf_updates,
 		int surface_count,
 		bool *is_plane_addition)
 {
@@ -3918,6 +3919,40 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
 				*is_plane_addition = true;
 			}
 		}
+		if (dc->config.enable_windowed_mpo_odm) {
+			const struct rect *guaranteed_viewport = &stream->src;
+			const struct rect *surface_src, *surface_dst;
+			bool are_cur_planes_guaranteed = true;
+			bool are_new_planes_guaranteed = true;
+
+			for (i = 0; i < cur_stream_status->plane_count; i++) {
+				surface_src = &cur_stream_status->plane_states[i]->src_rect;
+				surface_dst = &cur_stream_status->plane_states[i]->dst_rect;
+				if ((surface_src->height > surface_dst->height && surface_src->height > guaranteed_viewport->height) ||
+						(surface_src->width > surface_dst->width && surface_src->width > guaranteed_viewport->width))
+					are_cur_planes_guaranteed = false;
+			}
+
+			for (i = 0; i < surface_count; i++) {
+				if (srf_updates[i].scaling_info) {
+					surface_src = &srf_updates[i].scaling_info->src_rect;
+					surface_dst = &srf_updates[i].scaling_info->dst_rect;
+				} else {
+					surface_src = &srf_updates[i].surface->src_rect;
+					surface_dst = &srf_updates[i].surface->dst_rect;
+				}
+				if ((surface_src->height > surface_dst->height && surface_src->height > guaranteed_viewport->height) ||
+						(surface_src->width > surface_dst->width && surface_src->width > guaranteed_viewport->width))
+					are_new_planes_guaranteed = false;
+			}
+
+			if (are_cur_planes_guaranteed && !are_new_planes_guaranteed) {
+				force_minimal_pipe_splitting = true;
+				*is_plane_addition = true;
+			} else if (!are_cur_planes_guaranteed && are_new_planes_guaranteed) {
+				force_minimal_pipe_splitting = true;
+			}
+		}
 	}
 
 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -4270,6 +4305,7 @@ bool dc_update_planes_and_stream(struct dc *dc,
 	force_minimal_pipe_splitting = could_mpcc_tree_change_for_active_pipes(
 			dc,
 			stream,
+			srf_updates,
 			surface_count,
 			&is_plane_addition);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 883e90be2257..2358c9100cff 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -1267,6 +1267,8 @@ static bool should_allow_odm_power_optimization(struct dc *dc,
 {
 	struct dc_stream_state *stream = context->streams[0];
 	struct pipe_slice_table slice_table;
+	struct dc_plane_state *plane;
+	struct rect guaranteed_viewport;
 	int i;
 
 	/*
@@ -1331,6 +1333,31 @@ static bool should_allow_odm_power_optimization(struct dc *dc,
 		for (i = 0; i < slice_table.odm_combine_count; i++)
 			if (slice_table.odm_combines[i].slice_count > 1)
 				return false;
+
+		/* up to here we know that a plane with viewport equal to stream
+		 * src can be validated with single DPP pipe. Therefore any
+		 * planes with smaller or equal viewport is guaranteed to work
+		 * regardless of its position and scaling ratio. Also we know
+		 * any plane without downscale ratio greater than 1 should also
+		 * work. Up until DCN3x we still have software limitation that
+		 * doesn't implement a smooth transition between ODM combine and
+		 * MPC combine during plane resizing when we are crossing ODM
+		 * capability boundary. So we are adding this guaranteed
+		 * viewport condition to limit ODM power optimization support
+		 * for only the planes within the guaranteed viewport size. Such
+		 * planes can be supported with ODM power optimization without
+		 * ever the need to transition to MPC combine in any scaling
+		 * ratios and positions. Therefore we cover the software
+		 * limitation of this transition sequence.
+		 */
+		guaranteed_viewport = stream->src;
+		for (i = 0; i < context->stream_status[0].plane_count; i++) {
+			plane = context->stream_status[0].plane_states[i];
+
+			if ((plane->src_rect.height > plane->dst_rect.height && plane->src_rect.height > guaranteed_viewport.height) ||
+					(plane->src_rect.width > plane->dst_rect.width && plane->src_rect.width > guaranteed_viewport.width))
+				return false;
+		}
 	} else {
 		/*
 		 * the new ODM power optimization feature reduces software
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 17/28] drm/amd/display: add dp dto programming function to dccg
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (15 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 16/28] drm/amd/display: only allow ODM power optimization if surface is within guaranteed viewport size Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 18/28] drm/amd/display: Drop unused registers Stylon Wang
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, solomon.chiu,
	Aurabindo.Pillai, wayne.lin, Jun Lei, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Dillon Varone <dillon.varone@amd.com>

[WHY&HOW]
Add support for programming dp dto via dccg.

Reviewed-by: Jun Lei <jun.lei@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Dillon Varone <dillon.varone@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c |  1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h          | 10 ++++++++++
 2 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
index ed8936405dfa..75cf4ab8ae3c 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
@@ -34,6 +34,7 @@
 
 #include "dce_clock_source.h"
 #include "clk_mgr.h"
+#include "dccg.h"
 
 #include "reg_helper.h"
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
index 3e2f0f64c98c..65bb7cd05385 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
@@ -56,6 +56,13 @@ enum dentist_dispclk_change_mode {
 	DISPCLK_CHANGE_MODE_RAMPING,
 };
 
+struct dp_dto_params {
+	int otg_inst;
+	enum signal_type signal;
+	long long pixclk_hz;
+	long long refclk_hz;
+};
+
 enum pixel_rate_div {
    PIXEL_RATE_DIV_BY_1 = 0,
    PIXEL_RATE_DIV_BY_2 = 1,
@@ -182,6 +189,9 @@ struct dccg_funcs {
 			struct dccg *dccg,
 			uint32_t stream_enc_inst,
 			uint32_t link_enc_inst);
+	void (*set_dp_dto)(
+			struct dccg *dccg,
+			const struct dp_dto_params *params);
 };
 
 #endif //__DAL_DCCG_H__
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 18/28] drm/amd/display: Drop unused registers
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (16 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 17/28] drm/amd/display: add dp dto programming function to dccg Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 19/28] drm/amd/display: dc cleanup for tests Stylon Wang
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, solomon.chiu, Aurabindo.Pillai,
	wayne.lin, Bhawanpreet.Lakha, agustin.gutierrez, pavle.kotarac

From: Qingqing Zhuo <qingqing.zhuo@amd.com>

[Why & How]
Some registers are never used in the driver
but defined. Remove them.

Reviewed-by: Roman Li <roman.li@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h
index 013029f2e257..dc7331dc3b65 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h
@@ -37,8 +37,6 @@
 	SR(DCHUBBUB_ARB_SAT_LEVEL),\
 	SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND),\
 	SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
-	SR(DCHUBBUB_TEST_DEBUG_INDEX), \
-	SR(DCHUBBUB_TEST_DEBUG_DATA),\
 	SR(DCHUBBUB_SOFT_RESET),\
 	SR(DCHUBBUB_CRC_CTRL), \
 	SR(DCN_VM_FB_LOCATION_BASE),\
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 19/28] drm/amd/display: dc cleanup for tests
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (17 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 18/28] drm/amd/display: Drop unused registers Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 20/28] drm/amd/display: Add check for vrr_active_fixed Stylon Wang
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, solomon.chiu,
	Aurabindo.Pillai, wayne.lin, Sridevi Arvindekar,
	Bhawanpreet.Lakha, agustin.gutierrez, pavle.kotarac

From: Sridevi Arvindekar <Sridevi.Arvindekar@amd.com>

[WHY&HOW]
Code cleanup found in internal tests

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Sridevi Arvindekar <Sridevi.Arvindekar@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 5ac85df158b9..37cab11d1b31 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2855,7 +2855,7 @@ void dcn20_fpga_init_hw(struct dc *dc)
 	res_pool->mpc->funcs->mpc_init(res_pool->mpc);
 
 	/* initialize OPP mpc_tree parameter */
-	for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
 		res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
 		res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
 		for (j = 0; j < MAX_PIPES; j++)
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 20/28] drm/amd/display: Add check for vrr_active_fixed
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (18 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 19/28] drm/amd/display: dc cleanup for tests Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 21/28] drm/amd/display: fix some non-initialized register mask and setting Stylon Wang
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Austin Zheng, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, solomon.chiu,
	Aurabindo.Pillai, Alvin Lee, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Austin Zheng <austin.zheng@amd.com>

Why:
vrr_active_fixed should also be checked when
determining if DRR is in use

How:
Add check for vrr_active_fixed when allow_freesync
and vrr_active_variable are also checked

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Austin Zheng <austin.zheng@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c                  | 4 ++--
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c | 4 ++--
 drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c          | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index 979f52ee5604..2f98dfa06dad 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -554,7 +554,7 @@ static void populate_subvp_cmd_vblank_pipe_info(struct dc *dc,
 			vblank_pipe->stream->timing.v_total - vblank_pipe->stream->timing.v_front_porch - vblank_pipe->stream->timing.v_addressable;
 
 	if (vblank_pipe->stream->ignore_msa_timing_param &&
-		(vblank_pipe->stream->allow_freesync || vblank_pipe->stream->vrr_active_variable))
+		(vblank_pipe->stream->allow_freesync || vblank_pipe->stream->vrr_active_variable || vblank_pipe->stream->vrr_active_fixed))
 		populate_subvp_cmd_drr_info(dc, pipe, vblank_pipe, pipe_data);
 }
 
@@ -648,7 +648,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
 	pipe_data->pipe_config.subvp_data.mall_region_lines = phantom_timing->v_addressable;
 	pipe_data->pipe_config.subvp_data.main_pipe_index = subvp_pipe->stream_res.tg->inst;
 	pipe_data->pipe_config.subvp_data.is_drr = subvp_pipe->stream->ignore_msa_timing_param &&
-		(subvp_pipe->stream->allow_freesync || subvp_pipe->stream->vrr_active_variable);
+		(subvp_pipe->stream->allow_freesync || subvp_pipe->stream->vrr_active_variable || subvp_pipe->stream->vrr_active_fixed);
 
 	/* Calculate the scaling factor from the src and dst height.
 	 * e.g. If 3840x2160 being downscaled to 1920x1080, the scaling factor is 1/2.
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
index f5705b3e6e42..bc5f0db23d0c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
@@ -706,7 +706,7 @@ bool dcn32_subvp_drr_admissable(struct dc *dc, struct dc_state *context)
 				non_subvp_pipes++;
 				drr_psr_capable = (drr_psr_capable || dcn32_is_psr_capable(pipe));
 				if (pipe->stream->ignore_msa_timing_param &&
-						(pipe->stream->allow_freesync || pipe->stream->vrr_active_variable)) {
+						(pipe->stream->allow_freesync || pipe->stream->vrr_active_variable || pipe->stream->vrr_active_fixed)) {
 					drr_pipe_found = true;
 				}
 			}
@@ -764,7 +764,7 @@ bool dcn32_subvp_vblank_admissable(struct dc *dc, struct dc_state *context, int
 				non_subvp_pipes++;
 				vblank_psr_capable = (vblank_psr_capable || dcn32_is_psr_capable(pipe));
 				if (pipe->stream->ignore_msa_timing_param &&
-						(pipe->stream->allow_freesync || pipe->stream->vrr_active_variable)) {
+						(pipe->stream->allow_freesync || pipe->stream->vrr_active_variable || pipe->stream->vrr_active_fixed)) {
 					drr_pipe_found = true;
 				}
 			}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 2358c9100cff..92e2d1df5b32 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -822,7 +822,7 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context)
 			continue;
 
 		if (drr_pipe->stream->mall_stream_config.type == SUBVP_NONE && drr_pipe->stream->ignore_msa_timing_param &&
-				(drr_pipe->stream->allow_freesync || drr_pipe->stream->vrr_active_variable))
+				(drr_pipe->stream->allow_freesync || drr_pipe->stream->vrr_active_variable || drr_pipe->stream->vrr_active_fixed))
 			break;
 	}
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 21/28] drm/amd/display: fix some non-initialized register mask and setting
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (19 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 20/28] drm/amd/display: Add check for vrr_active_fixed Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 22/28] drm/amd/display: Fix MST recognizes connected displays as one Stylon Wang
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Charlene Liu, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Duncan Ma,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Charlene Liu <charlene.liu@amd.com>

[why]
fix some non-initialized register mask and update golden setting

Reviewed-by: Duncan Ma <duncan.ma@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Charlene Liu <charlene.liu@amd.com>
---
 .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c  | 56 ++++++++++++++-----
 .../display/dc/dcn10/dcn10_stream_encoder.h   |  5 +-
 .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h   |  6 +-
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  | 16 +++++-
 4 files changed, 65 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
index 4fd25bb1ab92..37ffa0050e60 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
@@ -53,6 +53,14 @@
 #define mmCLK1_CLK3_DFS_CNTL                            0x16E72
 #define mmCLK1_CLK4_DFS_CNTL                            0x16E75
 
+#define mmCLK1_CLK0_CURRENT_CNT                         0x16EE7
+#define mmCLK1_CLK1_CURRENT_CNT                         0x16EE8
+#define mmCLK1_CLK2_CURRENT_CNT                         0x16EE9
+#define mmCLK1_CLK3_CURRENT_CNT                         0x16EEA
+#define mmCLK1_CLK4_CURRENT_CNT                         0x16EEB
+
+#define mmCLK4_CLK0_CURRENT_CNT                         0x1B0C9
+
 #define CLK1_CLK_PLL_REQ__FbMult_int_MASK               0x000001ffUL
 #define CLK1_CLK_PLL_REQ__PllSpineDiv_MASK              0x0000f000UL
 #define CLK1_CLK_PLL_REQ__FbMult_frac_MASK              0xffff0000UL
@@ -452,6 +460,26 @@ static int dcn32_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base)
 
 static void dcn32_auto_dpm_test_log(struct dc_clocks *new_clocks, struct clk_mgr_internal *clk_mgr)
 {
+    unsigned int dispclk_khz_reg    = REG_READ(CLK1_CLK0_CURRENT_CNT); // DISPCLK
+    unsigned int dppclk_khz_reg     = REG_READ(CLK1_CLK1_CURRENT_CNT); // DPPCLK
+    unsigned int dprefclk_khz_reg   = REG_READ(CLK1_CLK2_CURRENT_CNT); // DPREFCLK
+    unsigned int dcfclk_khz_reg     = REG_READ(CLK1_CLK3_CURRENT_CNT); // DCFCLK
+    unsigned int dtbclk_khz_reg     = REG_READ(CLK1_CLK4_CURRENT_CNT); // DTBCLK
+    unsigned int fclk_khz_reg       = REG_READ(CLK4_CLK0_CURRENT_CNT); // FCLK
+
+    // Overrides for these clocks in case there is no p_state change support
+    int dramclk_khz_override = new_clocks->dramclk_khz;
+    int fclk_khz_override = new_clocks->fclk_khz;
+
+    int num_fclk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_fclk_levels - 1;
+
+    if (!new_clocks->p_state_change_support) {
+	    dramclk_khz_override = clk_mgr->base.bw_params->max_memclk_mhz * 1000;
+    }
+    if (!new_clocks->fclk_p_state_change_support) {
+	    fclk_khz_override = clk_mgr->base.bw_params->clk_table.entries[num_fclk_levels].fclk_mhz * 1000;
+    }
+
 	////////////////////////////////////////////////////////////////////////////
 	//	IMPORTANT: 	When adding more clocks to these logs, do NOT put a newline
 	//	 			anywhere other than at the very end of the string.
@@ -466,20 +494,20 @@ static void dcn32_auto_dpm_test_log(struct dc_clocks *new_clocks, struct clk_mgr
 		new_clocks->dcfclk_khz > 0 &&
 		new_clocks->dppclk_khz > 0) {
 
-		if (new_clocks->p_state_change_support) {
-			DC_LOG_AUTO_DPM_TEST("AutoDPMTest: dramclk_khz:%d - fclk_khz:%d - "
-						 "dcfclk_khz:%d - dppclk_khz:%d\n",
-						 new_clocks->dramclk_khz,
-						 new_clocks->fclk_khz,
-						 new_clocks->dcfclk_khz,
-						 new_clocks->dppclk_khz);
-		} else {
-			DC_LOG_AUTO_DPM_TEST("AutoDPMTest: dramclk_khz:1249000 - fclk_khz:%d - "
-						 "dcfclk_khz:%d - dppclk_khz:%d\n",
-						 new_clocks->fclk_khz,
-						 new_clocks->dcfclk_khz,
-						 new_clocks->dppclk_khz);
-		}
+		DC_LOG_AUTO_DPM_TEST("AutoDPMTest: dramclk:%d - fclk:%d - "
+			"dcfclk:%d - dppclk:%d - dispclk_hw:%d - "
+			"dppclk_hw:%d - dprefclk_hw:%d - dcfclk_hw:%d - "
+			"dtbclk_hw:%d - fclk_hw:%d\n",
+			dramclk_khz_override,
+			fclk_khz_override,
+			new_clocks->dcfclk_khz,
+			new_clocks->dppclk_khz,
+			dispclk_khz_reg,
+			dppclk_khz_reg,
+			dprefclk_khz_reg,
+			dcfclk_khz_reg,
+			dtbclk_khz_reg,
+			fclk_khz_reg);
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
index 085b269c654f..c429590f1298 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
@@ -577,7 +577,10 @@ struct dcn10_stream_enc_registers {
 	type DIG_FIFO_READ_START_LEVEL;\
 	type DIG_FIFO_ENABLE;\
 	type DIG_FIFO_RESET;\
-	type DIG_FIFO_RESET_DONE
+	type DIG_FIFO_RESET_DONE;\
+	type PIXEL_ENCODING_TYPE;\
+	type UNCOMPRESSED_PIXEL_FORMAT;\
+	type UNCOMPRESSED_COMPONENT_DEPTH
 
 #define SE_REG_FIELD_LIST_DCN3_5_COMMON(type) \
 	type DIG_FE_CLK_EN;\
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
index 580fea4fde52..46312a7b8c2b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
@@ -45,11 +45,12 @@
 
 struct dcn3_clk_internal {
 	int dummy;
-	/*TODO:
+//	TODO:
 	uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk
 	uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk
 	uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk
 	uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk
+	uint32_t CLK1_CLK4_CURRENT_CNT;
 	uint32_t CLK1_CLK3_DS_CNTL;	//dcf_deep_sleep_divider
 	uint32_t CLK1_CLK3_ALLOW_DS;	//dcf_deep_sleep_allow
 
@@ -57,7 +58,8 @@ struct dcn3_clk_internal {
 	uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass
 	uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass
 	uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass
-	*/
+
+	uint32_t CLK4_CLK0_CURRENT_CNT; //fclk
 };
 
 struct dcn301_clk_internal {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
index cff5fd55a0ad..9a595246824d 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
@@ -163,7 +163,13 @@ enum dentist_divider_range {
 	CLK_SR_DCN32(CLK1_CLK1_DFS_CNTL), \
 	CLK_SR_DCN32(CLK1_CLK2_DFS_CNTL), \
 	CLK_SR_DCN32(CLK1_CLK3_DFS_CNTL), \
-	CLK_SR_DCN32(CLK1_CLK4_DFS_CNTL)
+	CLK_SR_DCN32(CLK1_CLK4_DFS_CNTL), \
+    CLK_SR_DCN32(CLK1_CLK0_CURRENT_CNT), \
+    CLK_SR_DCN32(CLK1_CLK1_CURRENT_CNT), \
+    CLK_SR_DCN32(CLK1_CLK2_CURRENT_CNT), \
+    CLK_SR_DCN32(CLK1_CLK3_CURRENT_CNT), \
+    CLK_SR_DCN32(CLK1_CLK4_CURRENT_CNT), \
+    CLK_SR_DCN32(CLK4_CLK0_CURRENT_CNT)
 
 #define CLK_COMMON_MASK_SH_LIST_DCN32(mask_sh) \
 	CLK_COMMON_MASK_SH_LIST_DCN20_BASE(mask_sh),\
@@ -222,6 +228,8 @@ struct clk_mgr_registers {
 	uint32_t CLK4_CLK2_CURRENT_CNT;
 	uint32_t CLK4_CLK_PLL_REQ;
 
+	uint32_t CLK4_CLK0_CURRENT_CNT;
+
 	uint32_t CLK3_CLK2_DFS_CNTL;
 	uint32_t CLK3_CLK_PLL_REQ;
 
@@ -235,6 +243,12 @@ struct clk_mgr_registers {
 	uint32_t CLK1_CLK3_DFS_CNTL;
 	uint32_t CLK1_CLK4_DFS_CNTL;
 
+	uint32_t CLK1_CLK0_CURRENT_CNT;
+    uint32_t CLK1_CLK1_CURRENT_CNT;
+    uint32_t CLK1_CLK2_CURRENT_CNT;
+    uint32_t CLK1_CLK3_CURRENT_CNT;
+    uint32_t CLK1_CLK4_CURRENT_CNT;
+
 	uint32_t CLK0_CLK0_DFS_CNTL;
 	uint32_t CLK0_CLK1_DFS_CNTL;
 	uint32_t CLK0_CLK3_DFS_CNTL;
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 22/28] drm/amd/display: Fix MST recognizes connected displays as one
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (20 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 21/28] drm/amd/display: fix some non-initialized register mask and setting Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 23/28] drm/amd/display: 3.2.250 Stylon Wang
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Charlene Liu, Muhammad Ahmed, Sunpeng.Li,
	Harry.Wentland, qingqing.zhuo, Rodrigo.Siqueira, roman.li,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Muhammad Ahmed <ahmed.ahmed@amd.com>

[What]
MST now recognizes both connected displays

Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Muhammad Ahmed <ahmed.ahmed@amd.com>
---
 .../display/dc/dce110/dce110_hw_sequencer.c   | 30 +++++++++++--------
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |  8 ++---
 .../gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c  |  2 +-
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 31454db00ed5..2701620350af 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -1178,12 +1178,15 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 		dto_params.otg_inst = tg->inst;
 		dto_params.timing = &pipe_ctx->stream->timing;
 		dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
-		dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
-		dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
-		dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst);
-	} else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST && dccg->funcs->disable_symclk_se)
+		if (dccg) {
+			dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
+			dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
+			dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst);
+		}
+	} else if (dccg && dccg->funcs->disable_symclk_se) {
 		dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
 				link_enc->transmitter - TRANSMITTER_UNIPHY_A);
+	}
 
 	if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
 		/* TODO: This looks like a bug to me as we are disabling HPO IO when
@@ -2655,11 +2658,11 @@ void dce110_prepare_bandwidth(
 	struct clk_mgr *dccg = dc->clk_mgr;
 
 	dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
-
-	dccg->funcs->update_clocks(
-			dccg,
-			context,
-			false);
+	if (dccg)
+		dccg->funcs->update_clocks(
+				dccg,
+				context,
+				false);
 }
 
 void dce110_optimize_bandwidth(
@@ -2670,10 +2673,11 @@ void dce110_optimize_bandwidth(
 
 	dce110_set_displaymarks(dc, context);
 
-	dccg->funcs->update_clocks(
-			dccg,
-			context,
-			true);
+	if (dccg)
+		dccg->funcs->update_clocks(
+				dccg,
+				context,
+				true);
 }
 
 static void dce110_program_front_end_for_pipe(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 37cab11d1b31..19ab08f5122e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2710,8 +2710,6 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
 	struct dce_hwseq *hws = dc->hwseq;
 	unsigned int k1_div = PIXEL_RATE_DIV_NA;
 	unsigned int k2_div = PIXEL_RATE_DIV_NA;
-	struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
-	struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
 
 	if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
 		if (dc->hwseq->funcs.setup_hpo_hw_control)
@@ -2731,10 +2729,8 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
 		dto_params.timing = &pipe_ctx->stream->timing;
 		dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
 		dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
-	} else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST && dccg->funcs->enable_symclk_se)
-		dccg->funcs->enable_symclk_se(dccg,
-			stream_enc->stream_enc_inst, link_enc->transmitter - TRANSMITTER_UNIPHY_A);
-
+	} else {
+		}
 	if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) {
 		hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
index 3082da04a63d..1d052f08aff5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
@@ -75,7 +75,7 @@ void mpc32_power_on_blnd_lut(
 		if (power_on) {
 			REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_FORCE, 0);
 			REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_STATE, 0, 1, 5);
-		} else {
+		} else if (!mpc->ctx->dc->debug.disable_mem_low_power) {
 			ASSERT(false);
 			/* TODO: change to mpc
 			 *  dpp_base->ctx->dc->optimized_required = true;
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 23/28] drm/amd/display: 3.2.250
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (21 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 22/28] drm/amd/display: Fix MST recognizes connected displays as one Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 24/28] drm/amd/display: do not skip ODM minimal transition based on new state Stylon Wang
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Aric Cyr, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, solomon.chiu, Aurabindo.Pillai,
	wayne.lin, Bhawanpreet.Lakha, agustin.gutierrez, pavle.kotarac

From: Aric Cyr <aric.cyr@amd.com>

Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Aric Cyr <aric.cyr@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 05ab24c81041..bece61d2508b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -47,7 +47,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.249"
+#define DC_VER "3.2.250"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 24/28] drm/amd/display: do not skip ODM minimal transition based on new state
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (22 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 23/28] drm/amd/display: 3.2.250 Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 25/28] drm/amd/display: minior logging improvements Stylon Wang
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
During 8k video plane resizing we could transition from MPC combine mode
back to ODM combine 2:1 + 8k video plane. In this transition minimal
transition state is based on new state with ODM combine enabled.
We are skipping this and it causes corruption because we have to reassign
a current DPP pipe to a different MPC blending tree which is not supported
seamlessly.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 0320bc49458c..8e8362026825 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4048,10 +4048,10 @@ static bool commit_minimal_transition_state(struct dc *dc,
 	 * pipe, we must use the minimal transition.
 	 */
 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
-		struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+		struct pipe_ctx *pipe = &transition_base_context->res_ctx.pipe_ctx[i];
 
-		if (pipe->stream && pipe->next_odm_pipe) {
-			odm_in_use = true;
+		if (resource_is_pipe_type(pipe, OTG_MASTER)) {
+			odm_in_use = resource_get_odm_slice_count(pipe) > 1;
 			break;
 		}
 	}
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 25/28] drm/amd/display: minior logging improvements
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (23 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 24/28] drm/amd/display: do not skip ODM minimal transition based on new state Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 26/28] drm/amd/display: add seamless pipe topology transition check Stylon Wang
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Wenjing Liu <wenjing.liu@amd.com>

[how]
- Add minimial transition log with reason and base state.
- Do not log set dpms interfaces for virtual signal in stream.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c        |  7 +++++++
 drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 10 ++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8e8362026825..a857de5ebe85 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4069,6 +4069,13 @@ static bool commit_minimal_transition_state(struct dc *dc,
 		return true;
 	}
 
+	DC_LOG_DC("%s base = %s state, reason = %s\n", __func__,
+			dc->current_state == transition_base_context ? "current" : "new",
+			subvp_in_use ? "Subvp In Use" :
+			odm_in_use ? "ODM in Use" :
+			dc->debug.pipe_split_policy != MPC_SPLIT_AVOID ? "MPC in Use" :
+			"Unknown");
+
 	if (!dc->config.is_vmin_only_asic) {
 		tmp_mpc_policy = dc->debug.pipe_split_policy;
 		dc->debug.pipe_split_policy = MPC_SPLIT_AVOID;
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
index cd9dd270b05f..d8327911c467 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
@@ -2269,6 +2269,8 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
 
 	if (dp_is_128b_132b_signal(pipe_ctx))
 		vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
+	if (dc_is_virtual_signal(pipe_ctx->stream->signal))
+		return;
 
 	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
 
@@ -2281,9 +2283,6 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
 		}
 	}
 
-	if (dc_is_virtual_signal(pipe_ctx->stream->signal))
-		return;
-
 	if (!pipe_ctx->stream->sink->edid_caps.panel_patch.skip_avmute) {
 		if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
 			set_avmute(pipe_ctx, true);
@@ -2382,6 +2381,8 @@ void link_set_dpms_on(
 
 	if (dp_is_128b_132b_signal(pipe_ctx))
 		vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
+	if (dc_is_virtual_signal(pipe_ctx->stream->signal))
+		return;
 
 	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
 
@@ -2394,9 +2395,6 @@ void link_set_dpms_on(
 		}
 	}
 
-	if (dc_is_virtual_signal(pipe_ctx->stream->signal))
-		return;
-
 	link_enc = link_enc_cfg_get_link_enc(link);
 	ASSERT(link_enc);
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 26/28] drm/amd/display: add seamless pipe topology transition check
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (24 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 25/28] drm/amd/display: minior logging improvements Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 27/28] drm/amd/display: move odm power optimization decision after subvp optimization Stylon Wang
  2023-09-06 12:28 ` [PATCH 28/28] drm/amd/display: add skip_implict_edp_power_control flag for dcn32 Stylon Wang
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
We have a few cases where we need to perform update topology update
in dc update interface. However some of the updates are not seamless
This could cause user noticible glitches. To enforce seamless transition
we are adding a checking condition and error logging so the corruption
as result of non seamless transition can be easily spotted.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  8 +++
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.c    | 52 +++++++++++++++++++
 .../drm/amd/display/dc/dcn32/dcn32_hwseq.h    |  4 ++
 .../gpu/drm/amd/display/dc/dcn32/dcn32_init.c |  1 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  3 ++
 5 files changed, 68 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index a857de5ebe85..f91d0f6b0d7d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4370,6 +4370,14 @@ bool dc_update_planes_and_stream(struct dc *dc,
 				update_type,
 				context);
 	} else {
+		if (!stream_update &&
+				dc->hwss.is_pipe_topology_transition_seamless &&
+				!dc->hwss.is_pipe_topology_transition_seamless(
+						dc, dc->current_state, context)) {
+
+			DC_LOG_ERROR("performing non-seamless pipe topology transition with surface only update!\n");
+			BREAK_TO_DEBUGGER();
+		}
 		commit_planes_for_stream(
 				dc,
 				srf_updates,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
index cae5e1e68c86..018376146d97 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
@@ -1619,3 +1619,55 @@ void dcn32_blank_phantom(struct dc *dc,
 	if (tg->funcs->is_tg_enabled(tg))
 		hws->funcs.wait_for_blank_complete(opp);
 }
+
+bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
+		const struct dc_state *cur_ctx,
+		const struct dc_state *new_ctx)
+{
+	int i;
+	const struct pipe_ctx *cur_pipe, *new_pipe;
+	bool is_seamless = true;
+
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		cur_pipe = &cur_ctx->res_ctx.pipe_ctx[i];
+		new_pipe = &new_ctx->res_ctx.pipe_ctx[i];
+
+		if (resource_is_pipe_type(cur_pipe, FREE_PIPE) ||
+				resource_is_pipe_type(new_pipe, FREE_PIPE))
+			/* adding or removing free pipes is always seamless */
+			continue;
+		else if (resource_is_pipe_type(cur_pipe, OTG_MASTER)) {
+			if (resource_is_pipe_type(new_pipe, OTG_MASTER))
+				if (cur_pipe->stream->stream_id == new_pipe->stream->stream_id)
+				/* OTG master with the same stream is seamless */
+					continue;
+		} else if (resource_is_pipe_type(cur_pipe, OPP_HEAD)) {
+			if (resource_is_pipe_type(new_pipe, OPP_HEAD)) {
+				if (cur_pipe->stream_res.tg == new_pipe->stream_res.tg)
+					/*
+					 * OPP heads sharing the same timing
+					 * generator is seamless
+					 */
+					continue;
+			}
+		} else if (resource_is_pipe_type(cur_pipe, DPP_PIPE)) {
+			if (resource_is_pipe_type(new_pipe, DPP_PIPE)) {
+				if (cur_pipe->stream_res.opp == new_pipe->stream_res.opp)
+					/*
+					 * DPP pipes sharing the same OPP head is
+					 * seamless
+					 */
+					continue;
+			}
+		}
+
+		/*
+		 * This pipe's transition doesn't fall under any seamless
+		 * conditions
+		 */
+		is_seamless = false;
+		break;
+	}
+
+	return is_seamless;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
index 616d5219119e..9992e40acd21 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
@@ -120,4 +120,8 @@ void dcn32_blank_phantom(struct dc *dc,
 		int width,
 		int height);
 
+bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
+		const struct dc_state *cur_ctx,
+		const struct dc_state *new_ctx);
+
 #endif /* __DC_HWSS_DCN32_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
index eb4227926006..1edadff39a5e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
@@ -116,6 +116,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
 	.update_dsc_pg = dcn32_update_dsc_pg,
 	.apply_update_flags_for_phantom = dcn32_apply_update_flags_for_phantom,
 	.blank_phantom = dcn32_blank_phantom,
+	.is_pipe_topology_transition_seamless = dcn32_is_pipe_topology_transition_seamless,
 };
 
 static const struct hwseq_private_funcs dcn32_private_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index 1ccdb7359894..e0dd56182841 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -410,6 +410,9 @@ struct hw_sequencer_funcs {
 			struct dc_state *context,
 			struct pipe_ctx *phantom_pipe);
 	void (*apply_update_flags_for_phantom)(struct pipe_ctx *phantom_pipe);
+	bool (*is_pipe_topology_transition_seamless)(struct dc *dc,
+			const struct dc_state *cur_ctx,
+			const struct dc_state *new_ctx);
 
 	void (*calc_blocks_to_gate)(struct dc *dc, struct dc_state *context,
 		struct pg_block_update *update_state);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 27/28] drm/amd/display: move odm power optimization decision after subvp optimization
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (25 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 26/28] drm/amd/display: add seamless pipe topology transition check Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  2023-09-06 12:28 ` [PATCH 28/28] drm/amd/display: add skip_implict_edp_power_control flag for dcn32 Stylon Wang
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Dillon Varone, Sunpeng.Li, Harry.Wentland,
	qingqing.zhuo, Rodrigo.Siqueira, roman.li, Wenjing Liu,
	solomon.chiu, Aurabindo.Pillai, wayne.lin, Bhawanpreet.Lakha,
	agustin.gutierrez, pavle.kotarac

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
ODM power optimization excludes subvp power optimization but subvp
optimization can override ODM power optimization even if subvp optimization
configuration is not found. This happens with 4k144hz + 1 5k desktop plane.
We could have applied ODM power optimization however this is overridden by
subvp but subvp ends up deciding not apply its optimization.

[how]
Move ODM power optimization decision after subvp so it will try ODM power
optimization after subvp optimization is not possible.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 92e2d1df5b32..1f53883d8f56 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -1441,10 +1441,6 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
 		vba->VoltageLevel = *vlevel;
 	}
 
-	if (should_allow_odm_power_optimization(dc, context, vba, split, merge))
-		try_odm_power_optimization_and_revalidate(
-				dc, context, pipes, split, merge, vlevel, *pipe_cnt);
-
 	/* Conditions for setting up phantom pipes for SubVP:
 	 * 1. Not force disable SubVP
 	 * 2. Full update (i.e. !fast_validate)
@@ -1563,6 +1559,11 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
 			assign_subvp_index(dc, context);
 		}
 	}
+
+	if (should_allow_odm_power_optimization(dc, context, vba, split, merge))
+		try_odm_power_optimization_and_revalidate(
+				dc, context, pipes, split, merge, vlevel, *pipe_cnt);
+
 }
 
 static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 28/28] drm/amd/display: add skip_implict_edp_power_control flag for dcn32
  2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
                   ` (26 preceding siblings ...)
  2023-09-06 12:28 ` [PATCH 27/28] drm/amd/display: move odm power optimization decision after subvp optimization Stylon Wang
@ 2023-09-06 12:28 ` Stylon Wang
  27 siblings, 0 replies; 31+ messages in thread
From: Stylon Wang @ 2023-09-06 12:28 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, Ian Chen, Sunpeng.Li, Harry.Wentland, qingqing.zhuo,
	Rodrigo.Siqueira, roman.li, solomon.chiu, Aurabindo.Pillai,
	wayne.lin, Robin Chen, Bhawanpreet.Lakha, agustin.gutierrez,
	pavle.kotarac

From: Ian Chen <ian.chen@amd.com>

Add flag skip_implict_edp_power_control check in function
dcn32_disable_link_output to fix DCN35 issue.

Reviewed-by: Robin Chen <robin.chen@amd.com>
Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Ian Chen <ian.chen@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
index 018376146d97..e8a989a50afa 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
@@ -1322,7 +1322,8 @@ void dcn32_disable_link_output(struct dc_link *link,
 	struct dmcu *dmcu = dc->res_pool->dmcu;
 
 	if (signal == SIGNAL_TYPE_EDP &&
-			link->dc->hwss.edp_backlight_control)
+			link->dc->hwss.edp_backlight_control &&
+			!link->skip_implict_edp_power_control)
 		link->dc->hwss.edp_backlight_control(link, false);
 	else if (dmcu != NULL && dmcu->funcs->lock_phy)
 		dmcu->funcs->lock_phy(dmcu);
@@ -1331,7 +1332,8 @@ void dcn32_disable_link_output(struct dc_link *link,
 	link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
 
 	if (signal == SIGNAL_TYPE_EDP &&
-			link->dc->hwss.edp_backlight_control)
+			link->dc->hwss.edp_backlight_control &&
+			!link->skip_implict_edp_power_control)
 		link->dc->hwss.edp_power_control(link, false);
 	else if (dmcu != NULL && dmcu->funcs->lock_phy)
 		dmcu->funcs->unlock_phy(dmcu);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2023-09-06 12:52 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-06 12:28 [PATCH 00/28] DC Patches Sep 8, 2023 Stylon Wang
2023-09-06 12:28 ` [PATCH 01/28] drm/amd/display: Blank phantom OTG before enabling Stylon Wang
2023-09-06 12:28 ` [PATCH 02/28] drm/amd/display: Don't lock phantom pipe on disabling Stylon Wang
2023-09-06 12:28 ` [PATCH 03/28] drm/amd/display: set default return value for ODM Combine debugfs Stylon Wang
2023-09-06 12:28 ` [PATCH 04/28] drm/amd/display: Add dirty rect support for Replay Stylon Wang
2023-09-06 12:28 ` [PATCH 05/28] drm/amd/display: Don't check registers, if using AUX BL control Stylon Wang
2023-09-06 12:28 ` [PATCH 06/28] drm/amd/display: [FW Promotion] Release 0.0.181.0 Stylon Wang
2023-09-06 12:28 ` [PATCH 07/28] drm/amd/display: Fix DML calculation errors Stylon Wang
2023-09-06 12:28 ` [PATCH 08/28] drm/amd/display: do not block ODM + OPM on one side of the screen Stylon Wang
2023-09-06 12:28 ` [PATCH 09/28] drm/amd/display: Fix 2nd DPIA encoder Assignment Stylon Wang
2023-09-06 12:28   ` Stylon Wang
2023-09-06 12:28 ` [PATCH 10/28] drm/amd/display: Adjust the MST resume flow Stylon Wang
2023-09-06 12:28   ` Stylon Wang
2023-09-06 12:28 ` [PATCH 11/28] drm/amd/display: support main link off before specific vertical line Stylon Wang
2023-09-06 12:28 ` [PATCH 12/28] drm/amd/display: Add new logs for AutoDPMTest Stylon Wang
2023-09-06 12:28 ` [PATCH 13/28] drm/amd/display: Add DCHUBBUB callback to report MALL status Stylon Wang
2023-09-06 12:28 ` [PATCH 14/28] drm/amd/display: remove a function that does complex calculation in every frame but not used Stylon Wang
2023-09-06 12:28 ` [PATCH 15/28] drm/amd/display: do not attempt ODM power optimization if minimal transition doesn't exist Stylon Wang
2023-09-06 12:28 ` [PATCH 16/28] drm/amd/display: only allow ODM power optimization if surface is within guaranteed viewport size Stylon Wang
2023-09-06 12:28 ` [PATCH 17/28] drm/amd/display: add dp dto programming function to dccg Stylon Wang
2023-09-06 12:28 ` [PATCH 18/28] drm/amd/display: Drop unused registers Stylon Wang
2023-09-06 12:28 ` [PATCH 19/28] drm/amd/display: dc cleanup for tests Stylon Wang
2023-09-06 12:28 ` [PATCH 20/28] drm/amd/display: Add check for vrr_active_fixed Stylon Wang
2023-09-06 12:28 ` [PATCH 21/28] drm/amd/display: fix some non-initialized register mask and setting Stylon Wang
2023-09-06 12:28 ` [PATCH 22/28] drm/amd/display: Fix MST recognizes connected displays as one Stylon Wang
2023-09-06 12:28 ` [PATCH 23/28] drm/amd/display: 3.2.250 Stylon Wang
2023-09-06 12:28 ` [PATCH 24/28] drm/amd/display: do not skip ODM minimal transition based on new state Stylon Wang
2023-09-06 12:28 ` [PATCH 25/28] drm/amd/display: minior logging improvements Stylon Wang
2023-09-06 12:28 ` [PATCH 26/28] drm/amd/display: add seamless pipe topology transition check Stylon Wang
2023-09-06 12:28 ` [PATCH 27/28] drm/amd/display: move odm power optimization decision after subvp optimization Stylon Wang
2023-09-06 12:28 ` [PATCH 28/28] drm/amd/display: add skip_implict_edp_power_control flag for dcn32 Stylon Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.