All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/18] DC Patches September 17, 2021
@ 2021-09-17 19:25 Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 01/18] drm/amd/display: Extend w/a for hard hang on HPD to dcn20 Rodrigo Siqueira
                   ` (17 more replies)
  0 siblings, 18 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu,
	Daniel Wheeler, Mark Broadworth

This DC patchset brings improvements in multiple areas. In summary, we
highlight:

- New firmware version
- Fix HPD problems on DCN2
- Fix generic encoder problems and null deferences
- Adjust DCN301 watermark
- Rework dynamic bpp for DCN3x
- Improve link training fallback logic

Best Regards
Siqueira

Cc: Daniel Wheeler <daniel.wheeler@amd.com>
Cc: Mark Broadworth <mark.broadworth@amd.com>

Anthony Koo (2):
  drm/amd/display: [FW Promotion] Release 0.0.83
  drm/amd/display: [FW Promotion] Release 0.0.84

Aric Cyr (2):
  drm/amd/display: 3.2.153
  drm/amd/display: 3.2.154

Guo, Bing (1):
  drm/amd/display: Fix issue with dynamic bpp change for DCN3x

Hayden Goodfellow (1):
  drm/amd/display: Fix wrong format specifier in amdgpu_dm.c

Jimmy Kizito (4):
  drm/amd/display: Fix link training fallback logic
  drm/amd/display: Fix concurrent dynamic encoder assignment
  drm/amd/display: Fix dynamic encoder reassignment
  drm/amd/display: Fix null pointer dereference for encoders

Lai, Derek (1):
  drm/amd/display: Added power down on boot for DCN3

Liu, Zhan (3):
  drm/amd/display: Fix DCN3 B0 DP Alt Mapping
  drm/amd/display: Fix B0 USB-C DP Alt mode
  drm/amd/display: DIG mapping change is causing a blocker

Meenakshikumar Somasundaram (1):
  drm/amd/display: Creating a fw boot options bit for an upcoming
    feature

Michael Strauss (1):
  drm/amd/display: Disable mem low power for CM HW block on DCN3.1

Nikola Cornij (1):
  drm/amd/display: Use adjusted DCN301 watermarks

Qingqing Zhuo (1):
  drm/amd/display: Extend w/a for hard hang on HPD to dcn20

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   2 +-
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  |  12 +-
 .../display/dc/clk_mgr/dcn301/vg_clk_mgr.c    |   4 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  17 +-
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  39 +-
 .../drm/amd/display/dc/core/dc_link_enc_cfg.c | 461 ++++++++++++++----
 .../drm/amd/display/dc/core/dc_link_hwss.c    |  35 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  17 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |   2 +-
 .../display/dc/dce110/dce110_hw_sequencer.c   |   2 +-
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |   2 +-
 .../amd/display/dc/dcn10/dcn10_link_encoder.h |   1 +
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   4 +-
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |   5 +-
 .../display/dc/dcn20/dcn20_stream_encoder.c   |   3 +-
 .../dc/dcn30/dcn30_dio_stream_encoder.c       |  18 +-
 .../gpu/drm/amd/display/dc/dcn30/dcn30_optc.c |  17 +-
 .../gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c  | 198 +++++---
 .../gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h  |   6 +-
 .../amd/display/dc/dcn301/dcn301_resource.c   |  96 +++-
 .../display/dc/dcn31/dcn31_dio_link_encoder.c |  39 +-
 .../display/dc/dcn31/dcn31_dio_link_encoder.h |  11 +-
 .../dc/dcn31/dcn31_hpo_dp_stream_encoder.c    |  15 +-
 .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   4 +
 .../gpu/drm/amd/display/dc/dcn31/dcn31_init.c |   2 +
 .../drm/amd/display/dc/dcn31/dcn31_resource.c |   2 +-
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  18 +-
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |   2 +-
 .../drm/amd/display/dc/inc/hw/link_encoder.h  |   6 +
 .../amd/display/dc/inc/hw/stream_encoder.h    |   6 +-
 .../gpu/drm/amd/display/dc/inc/link_enc_cfg.h |  23 +-
 .../display/dc/irq/dcn20/irq_service_dcn20.c  |  25 +
 .../display/dc/irq/dcn20/irq_service_dcn20.h  |   2 +
 .../dc/virtual/virtual_stream_encoder.c       |   3 +-
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |   7 +-
 .../include/asic_reg/dpcs/dpcs_4_2_0_offset.h |  27 +
 36 files changed, 878 insertions(+), 255 deletions(-)

-- 
2.25.1


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

* [PATCH 01/18] drm/amd/display: Extend w/a for hard hang on HPD to dcn20
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 02/18] drm/amd/display: [FW Promotion] Release 0.0.83 Rodrigo Siqueira
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Hersen Wu

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

[Why]
HPD disable and enable sequences are not mutually exclusive on Linux.
For HPDs that spans under 1s (i.e. HPD low = 1s), part of the disable
sequence (specifically, a request to SMU to lower refclk) could come
right before the call to PHY enablement, causing DMUB to access an
irresponsive PHY and thus a hard hang on the system.

[How]
Disable 48mhz refclk off when there is any HPD status in connected state
for dcn20.

Reviewed-by: Hersen Wu <hersenxs.wu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
---
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  | 12 ++++++++-
 .../display/dc/irq/dcn20/irq_service_dcn20.c  | 25 +++++++++++++++++++
 .../display/dc/irq/dcn20/irq_service_dcn20.h  |  2 ++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index 0d01aa9f15a6..315466f5aade 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -38,6 +38,8 @@
 #include "clk/clk_11_0_0_offset.h"
 #include "clk/clk_11_0_0_sh_mask.h"
 
+#include "irq/dcn20/irq_service_dcn20.h"
+
 #undef FN
 #define FN(reg_name, field_name) \
 	clk_mgr->clk_mgr_shift->field_name, clk_mgr->clk_mgr_mask->field_name
@@ -221,6 +223,8 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
 	bool force_reset = false;
 	bool p_state_change_support;
 	int total_plane_count;
+	int irq_src;
+	uint32_t hpd_state;
 
 	if (dc->work_arounds.skip_clock_update)
 		return;
@@ -238,7 +242,13 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
 	if (dc->res_pool->pp_smu)
 		pp_smu = &dc->res_pool->pp_smu->nv_funcs;
 
-	if (display_count == 0)
+	for (irq_src = DC_IRQ_SOURCE_HPD1; irq_src <= DC_IRQ_SOURCE_HPD6; irq_src++) {
+		hpd_state = dal_get_hpd_state_dcn20(dc->res_pool->irqs, irq_src);
+		if (hpd_state)
+			break;
+	}
+
+	if (display_count == 0 && !hpd_state)
 		enter_display_off = true;
 
 	if (enter_display_off == safe_to_lower) {
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
index c4b067d01895..49d87fe5c167 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
@@ -132,6 +132,31 @@ enum dc_irq_source to_dal_irq_source_dcn20(
 	}
 }
 
+uint32_t dal_get_hpd_state_dcn20(struct irq_service *irq_service, enum dc_irq_source source)
+{
+	const struct irq_source_info *info;
+	uint32_t addr;
+	uint32_t value;
+	uint32_t current_status;
+
+	info = find_irq_source_info(irq_service, source);
+	if (!info)
+		return 0;
+
+	addr = info->status_reg;
+	if (!addr)
+		return 0;
+
+	value = dm_read_reg(irq_service->ctx, addr);
+	current_status =
+		get_reg_field_value(
+			value,
+			HPD0_DC_HPD_INT_STATUS,
+			DC_HPD_SENSE);
+
+	return current_status;
+}
+
 static bool hpd_ack(
 	struct irq_service *irq_service,
 	const struct irq_source_info *info)
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h
index aee4b37999f1..f60a203e7188 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h
@@ -31,4 +31,6 @@
 struct irq_service *dal_irq_service_dcn20_create(
 	struct irq_service_init_data *init_data);
 
+uint32_t dal_get_hpd_state_dcn20(struct irq_service *irq_service, enum dc_irq_source source);
+
 #endif
-- 
2.25.1


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

* [PATCH 02/18] drm/amd/display: [FW Promotion] Release 0.0.83
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 01/18] drm/amd/display: Extend w/a for hard hang on HPD to dcn20 Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 03/18] drm/amd/display: 3.2.153 Rodrigo Siqueira
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Anthony Koo

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

Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
---
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 2c4ec3cac70e..1edc5bb4d668 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -47,10 +47,10 @@
 
 /* Firmware versioning. */
 #ifdef DMUB_EXPOSE_VERSION
-#define DMUB_FW_VERSION_GIT_HASH 0x3f002dea8
+#define DMUB_FW_VERSION_GIT_HASH 0xb24cbe3d
 #define DMUB_FW_VERSION_MAJOR 0
 #define DMUB_FW_VERSION_MINOR 0
-#define DMUB_FW_VERSION_REVISION 82
+#define DMUB_FW_VERSION_REVISION 83
 #define DMUB_FW_VERSION_TEST 0
 #define DMUB_FW_VERSION_VBIOS 0
 #define DMUB_FW_VERSION_HOTFIX 0
-- 
2.25.1


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

* [PATCH 03/18] drm/amd/display: 3.2.153
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 01/18] drm/amd/display: Extend w/a for hard hang on HPD to dcn20 Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 02/18] drm/amd/display: [FW Promotion] Release 0.0.83 Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 04/18] drm/amd/display: Fix DCN3 B0 DP Alt Mapping Rodrigo Siqueira
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Aric Cyr

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

Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@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 8897750bdaea..1306dedc1a98 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -45,7 +45,7 @@
 /* forward declaration */
 struct aux_payload;
 
-#define DC_VER "3.2.152"
+#define DC_VER "3.2.153"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.25.1


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

* [PATCH 04/18] drm/amd/display: Fix DCN3 B0 DP Alt Mapping
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (2 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 03/18] drm/amd/display: 3.2.153 Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 05/18] drm/amd/display: Fix link training fallback logic Rodrigo Siqueira
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Liu, Zhan,
	Charlene Liu

From: "Liu, Zhan" <Zhan.Liu@amd.com>

[Why]
DCN3 B0 has a mux, which redirects PHYC and PHYD to PHYF and PHYG.

[How]
Fix DIG mapping.

Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Zhan Liu <Zhan.Liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 613d34bde7dd..a823a64d02a5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -1383,6 +1383,12 @@ static struct stream_encoder *dcn31_stream_encoder_create(
 		return NULL;
 	}
 
+	if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
+			ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
+		if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD))
+			eng_id = eng_id + 3; // For B0 only. C->F, D->G.
+	}
+
 	dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
 					eng_id, vpg, afmt,
 					&stream_enc_regs[eng_id],
-- 
2.25.1


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

* [PATCH 05/18] drm/amd/display: Fix link training fallback logic
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (3 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 04/18] drm/amd/display: Fix DCN3 B0 DP Alt Mapping Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 06/18] drm/amd/display: Fix concurrent dynamic encoder assignment Rodrigo Siqueira
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Jimmy Kizito,
	Meenakshikumar Somasundaram, Jun Lei

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Link training should fail if stream bandwidth exceeds link bandwidth.

[How]
Correct fallback logic and use named variables to make intention clear.

Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index ac4896ff912c..c96a8694236e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2441,12 +2441,16 @@ bool perform_link_training_with_retries(
 			if (type == dc_connection_none)
 				break;
 		} else if (do_fallback) {
+			uint32_t req_bw;
+			uint32_t link_bw;
+
 			decide_fallback_link_setting(*link_setting, &current_setting, status);
 			/* Fail link training if reduced link bandwidth no longer meets
 			 * stream requirements.
 			 */
-			if (dc_bandwidth_in_kbps_from_timing(&stream->timing) <
-					dc_link_bandwidth_kbps(link, &current_setting))
+			req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
+			link_bw = dc_link_bandwidth_kbps(link, &current_setting);
+			if (req_bw > link_bw)
 				break;
 		}
 
-- 
2.25.1


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

* [PATCH 06/18] drm/amd/display: Fix concurrent dynamic encoder assignment
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (4 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 05/18] drm/amd/display: Fix link training fallback logic Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 07/18] drm/amd/display: Fix dynamic encoder reassignment Rodrigo Siqueira
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Jimmy Kizito,
	Jun Lei

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Trying to enable multiple displays simultaneously exposed shortcomings
with the algorithm for dynamic link encoder assignment.

The main problems were:
- Assuming stream order remained constant across states would sometimes
lead to invalid DIG encoder assignment.
- Incorrect logic for deciding whether or not a DIG could support a
stream would also sometimes lead to invalid DIG encoder assignment.
- Changes in encoder assignment were wholesale while updating of the
pipe backend is incremental. This would lead to the hardware state not
matching the software state even with valid encoder assignments.

[How]

The following changes fix the identified problems.
- Use stream pointer rather than stream index to track streams across
states.
- Fix DIG compatibility check by examining the link signal type rather
than the stream signal type.
- Modify assignment algorithm to make incremental updates so software
and hardware states remain coherent.

Additionally:
- Add assertions and an encoder assignment validation function
link_enc_cfg_validate() to detect potential problems with encoder
assignment closer to their root cause.
- Reduce the frequency with which the assignment algorithm is executed.
It should not be necessary for fast state validation.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |   2 +-
 .../drm/amd/display/dc/core/dc_link_enc_cfg.c | 329 ++++++++++++++----
 .../gpu/drm/amd/display/dc/core/dc_resource.c |   2 +-
 .../drm/amd/display/dc/inc/hw/link_encoder.h  |   1 +
 .../gpu/drm/amd/display/dc/inc/link_enc_cfg.h |   3 +
 5 files changed, 260 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index c96a8694236e..920ae2b0b165 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2362,7 +2362,7 @@ bool perform_link_training_with_retries(
 	/* Dynamically assigned link encoders associated with stream rather than
 	 * link.
 	 */
-	if (link->dc->res_pool->funcs->link_encs_assign)
+	if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign)
 		link_enc = stream->link_enc;
 	else
 		link_enc = link->link_enc;
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 49b17bbea8d1..5536184fff46 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
@@ -35,78 +35,116 @@ static bool is_dig_link_enc_stream(struct dc_stream_state *stream)
 	int i;
 
 	/* Loop over created link encoder objects. */
-	for (i = 0; i < stream->ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) {
-		link_enc = stream->ctx->dc->res_pool->link_encoders[i];
-
-		if (link_enc &&
-				((uint32_t)stream->signal & link_enc->output_signals)) {
-			if (dc_is_dp_signal(stream->signal)) {
-				/* DIGs do not support DP2.0 streams with 128b/132b encoding. */
-				struct dc_link_settings link_settings = {0};
-
-				decide_link_settings(stream, &link_settings);
-				if ((link_settings.link_rate >= LINK_RATE_LOW) &&
-						link_settings.link_rate <= LINK_RATE_HIGH3) {
+	if (stream) {
+		for (i = 0; i < stream->ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) {
+			link_enc = stream->ctx->dc->res_pool->link_encoders[i];
+
+			/* Need to check link signal type rather than stream signal type which may not
+			 * yet match.
+			 */
+			if (link_enc && ((uint32_t)stream->link->connector_signal & link_enc->output_signals)) {
+				if (dc_is_dp_signal(stream->signal)) {
+					/* DIGs do not support DP2.0 streams with 128b/132b encoding. */
+					struct dc_link_settings link_settings = {0};
+
+					decide_link_settings(stream, &link_settings);
+					if ((link_settings.link_rate >= LINK_RATE_LOW) &&
+							link_settings.link_rate <= LINK_RATE_HIGH3) {
+						is_dig_stream = true;
+						break;
+					}
+				} else {
 					is_dig_stream = true;
 					break;
 				}
-			} else {
-				is_dig_stream = true;
-				break;
 			}
 		}
 	}
-
 	return is_dig_stream;
 }
 
-/* Update DIG link encoder resource tracking variables in dc_state. */
-static void update_link_enc_assignment(
+/* Return stream using DIG link encoder resource. NULL if unused. */
+static struct dc_stream_state *get_stream_using_link_enc(
+		struct dc_state *state,
+		enum engine_id eng_id)
+{
+	struct dc_stream_state *stream = NULL;
+	int i;
+
+	for (i = 0; i < state->stream_count; i++) {
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+
+		if ((assignment.valid == true) && (assignment.eng_id == eng_id)) {
+			stream = state->streams[i];
+			break;
+		}
+	}
+
+	return stream;
+}
+
+static void remove_link_enc_assignment(
 		struct dc_state *state,
 		struct dc_stream_state *stream,
-		enum engine_id eng_id,
-		bool add_enc)
+		enum engine_id eng_id)
 {
 	int eng_idx;
-	int stream_idx;
 	int i;
 
 	if (eng_id != ENGINE_ID_UNKNOWN) {
 		eng_idx = eng_id - ENGINE_ID_DIGA;
-		stream_idx = -1;
 
-		/* Index of stream in dc_state used to update correct entry in
+		/* stream ptr of stream in dc_state used to update correct entry in
 		 * link_enc_assignments table.
 		 */
-		for (i = 0; i < state->stream_count; i++) {
-			if (stream == state->streams[i]) {
-				stream_idx = i;
+		for (i = 0; i < MAX_PIPES; i++) {
+			struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+
+			if (assignment.valid && assignment.stream == stream) {
+				state->res_ctx.link_enc_assignments[i].valid = false;
+				/* Only add link encoder back to availability pool if not being
+				 * used by any other stream (i.e. removing SST stream or last MST stream).
+				 */
+				if (get_stream_using_link_enc(state, eng_id) == NULL)
+					state->res_ctx.link_enc_avail[eng_idx] = eng_id;
+				stream->link_enc = NULL;
 				break;
 			}
 		}
+	}
+}
+
+static void add_link_enc_assignment(
+		struct dc_state *state,
+		struct dc_stream_state *stream,
+		enum engine_id eng_id)
+{
+	int eng_idx;
+	int i;
+
+	if (eng_id != ENGINE_ID_UNKNOWN) {
+		eng_idx = eng_id - ENGINE_ID_DIGA;
 
-		/* Update link encoder assignments table, link encoder availability
-		 * pool and link encoder assigned to stream in state.
-		 * Add/remove encoder resource to/from stream.
+		/* stream ptr of stream in dc_state used to update correct entry in
+		 * link_enc_assignments table.
 		 */
-		if (stream_idx != -1) {
-			if (add_enc) {
-				state->res_ctx.link_enc_assignments[stream_idx] = (struct link_enc_assignment){
+		for (i = 0; i < state->stream_count; i++) {
+			if (stream == state->streams[i]) {
+				state->res_ctx.link_enc_assignments[i] = (struct link_enc_assignment){
 					.valid = true,
 					.ep_id = (struct display_endpoint_id) {
 						.link_id = stream->link->link_id,
 						.ep_type = stream->link->ep_type},
-					.eng_id = eng_id};
+					.eng_id = eng_id,
+					.stream = stream};
 				state->res_ctx.link_enc_avail[eng_idx] = ENGINE_ID_UNKNOWN;
 				stream->link_enc = stream->ctx->dc->res_pool->link_encoders[eng_idx];
-			} else {
-				state->res_ctx.link_enc_assignments[stream_idx].valid = false;
-				state->res_ctx.link_enc_avail[eng_idx] = eng_id;
-				stream->link_enc = NULL;
+				break;
 			}
-		} else {
-			dm_output_to_console("%s: Stream not found in dc_state.\n", __func__);
 		}
+
+		/* Attempted to add an encoder assignment for a stream not in dc_state. */
+		ASSERT(i != state->stream_count);
 	}
 }
 
@@ -127,30 +165,29 @@ static enum engine_id find_first_avail_link_enc(
 	return eng_id;
 }
 
-/* Return stream using DIG link encoder resource. NULL if unused. */
-static struct dc_stream_state *get_stream_using_link_enc(
-		struct dc_state *state,
-		enum engine_id eng_id)
+static bool is_avail_link_enc(struct dc_state *state, enum engine_id eng_id)
 {
-	struct dc_stream_state *stream = NULL;
-	int stream_idx = -1;
-	int i;
+	bool is_avail = false;
+	int eng_idx = eng_id - ENGINE_ID_DIGA;
 
-	for (i = 0; i < state->stream_count; i++) {
-		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+	if (eng_id != ENGINE_ID_UNKNOWN && state->res_ctx.link_enc_avail[eng_idx] != ENGINE_ID_UNKNOWN)
+		is_avail = true;
 
-		if ((assignment.valid == true) && (assignment.eng_id == eng_id)) {
-			stream_idx = i;
-			break;
-		}
-	}
+	return is_avail;
+}
 
-	if (stream_idx != -1)
-		stream = state->streams[stream_idx];
-	else
-		dm_output_to_console("%s: No stream using DIG(%d).\n", __func__, eng_id);
+/* Test for display_endpoint_id equality. */
+static bool are_ep_ids_equal(struct display_endpoint_id *lhs, struct display_endpoint_id *rhs)
+{
+	bool are_equal = false;
 
-	return stream;
+	if (lhs->link_id.id == rhs->link_id.id &&
+			lhs->link_id.enum_id == rhs->link_id.enum_id &&
+			lhs->link_id.type == rhs->link_id.type &&
+			lhs->ep_type == rhs->ep_type)
+		are_equal = true;
+
+	return are_equal;
 }
 
 void link_enc_cfg_init(
@@ -175,11 +212,17 @@ void link_enc_cfg_link_encs_assign(
 {
 	enum engine_id eng_id = ENGINE_ID_UNKNOWN;
 	int i;
+	int j;
+
+	ASSERT(state->stream_count == stream_count);
 
 	/* Release DIG link encoder resources before running assignment algorithm. */
 	for (i = 0; i < stream_count; i++)
 		dc->res_pool->funcs->link_enc_unassign(state, streams[i]);
 
+	for (i = 0; i < MAX_PIPES; i++)
+		ASSERT(state->res_ctx.link_enc_assignments[i].valid == false);
+
 	/* (a) Assign DIG link encoders to physical (unmappable) endpoints first. */
 	for (i = 0; i < stream_count; i++) {
 		struct dc_stream_state *stream = streams[i];
@@ -191,26 +234,73 @@ void link_enc_cfg_link_encs_assign(
 		/* Physical endpoints have a fixed mapping to DIG link encoders. */
 		if (!stream->link->is_dig_mapping_flexible) {
 			eng_id = stream->link->eng_id;
-			update_link_enc_assignment(state, stream, eng_id, true);
+			add_link_enc_assignment(state, stream, eng_id);
+		}
+	}
+
+	/* (b) Retain previous assignments for mappable endpoints if encoders still available. */
+	eng_id = ENGINE_ID_UNKNOWN;
+
+	if (state != dc->current_state) {
+		struct dc_state *prev_state = dc->current_state;
+
+		for (i = 0; i < stream_count; i++) {
+			struct dc_stream_state *stream = state->streams[i];
+
+			/* Skip stream if not supported by DIG link encoder. */
+			if (!is_dig_link_enc_stream(stream))
+				continue;
+
+			if (!stream->link->is_dig_mapping_flexible)
+				continue;
+
+			for (j = 0; j < prev_state->stream_count; j++) {
+				struct dc_stream_state *prev_stream = prev_state->streams[j];
+
+				if (stream == prev_stream && stream->link == prev_stream->link &&
+						prev_state->res_ctx.link_enc_assignments[j].valid) {
+					eng_id = prev_state->res_ctx.link_enc_assignments[j].eng_id;
+					if (is_avail_link_enc(state, eng_id))
+						add_link_enc_assignment(state, stream, eng_id);
+				}
+			}
 		}
 	}
 
-	/* (b) Then assign encoders to mappable endpoints. */
+	/* (c) Then assign encoders to remaining mappable endpoints. */
 	eng_id = ENGINE_ID_UNKNOWN;
 
 	for (i = 0; i < stream_count; i++) {
 		struct dc_stream_state *stream = streams[i];
 
 		/* Skip stream if not supported by DIG link encoder. */
-		if (!is_dig_link_enc_stream(stream))
+		if (!is_dig_link_enc_stream(stream)) {
+			ASSERT(stream->link->is_dig_mapping_flexible != true);
 			continue;
+		}
 
 		/* Mappable endpoints have a flexible mapping to DIG link encoders. */
 		if (stream->link->is_dig_mapping_flexible) {
-			eng_id = find_first_avail_link_enc(stream->ctx, state);
-			update_link_enc_assignment(state, stream, eng_id, true);
+			struct link_encoder *link_enc = NULL;
+
+			/* Skip if encoder assignment retained in step (b) above. */
+			if (stream->link_enc)
+				continue;
+
+			/* For MST, multiple streams will share the same link / display
+			 * endpoint. These streams should use the same link encoder
+			 * assigned to that endpoint.
+			 */
+			link_enc = link_enc_cfg_get_link_enc_used_by_link(state, stream->link);
+			if (link_enc == NULL)
+				eng_id = find_first_avail_link_enc(stream->ctx, state);
+			else
+				eng_id =  link_enc->preferred_engine;
+			add_link_enc_assignment(state, stream, eng_id);
 		}
 	}
+
+	link_enc_cfg_validate(dc, state);
 }
 
 void link_enc_cfg_link_enc_unassign(
@@ -226,7 +316,7 @@ void link_enc_cfg_link_enc_unassign(
 	if (stream->link_enc)
 		eng_id = stream->link_enc->preferred_engine;
 
-	update_link_enc_assignment(state, stream, eng_id, false);
+	remove_link_enc_assignment(state, stream, eng_id);
 }
 
 bool link_enc_cfg_is_transmitter_mappable(
@@ -248,21 +338,18 @@ struct dc_link *link_enc_cfg_get_link_using_link_enc(
 		enum engine_id eng_id)
 {
 	struct dc_link *link = NULL;
-	int stream_idx = -1;
 	int i;
 
 	for (i = 0; i < state->stream_count; i++) {
 		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
 
 		if ((assignment.valid == true) && (assignment.eng_id == eng_id)) {
-			stream_idx = i;
+			link = state->streams[i]->link;
 			break;
 		}
 	}
 
-	if (stream_idx != -1)
-		link = state->streams[stream_idx]->link;
-	else
+	if (link == NULL)
 		dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id);
 
 	return link;
@@ -282,13 +369,9 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
 
 	for (i = 0; i < state->stream_count; i++) {
 		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
-		if (assignment.valid == true &&
-				assignment.ep_id.link_id.id == ep_id.link_id.id &&
-				assignment.ep_id.link_id.enum_id == ep_id.link_id.enum_id &&
-				assignment.ep_id.link_id.type == ep_id.link_id.type &&
-				assignment.ep_id.ep_type == ep_id.ep_type) {
+
+		if (assignment.valid == true && are_ep_ids_equal(&assignment.ep_id, &ep_id))
 			link_enc = link->dc->res_pool->link_encoders[assignment.eng_id - ENGINE_ID_DIGA];
-		}
 	}
 
 	return link_enc;
@@ -318,3 +401,99 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
 
 	return link_enc;
 }
+
+bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state)
+{
+	bool is_valid = false;
+	bool valid_entries = true;
+	bool valid_stream_ptrs = true;
+	bool valid_uniqueness = true;
+	bool valid_avail = true;
+	bool valid_streams = true;
+	int i, j;
+	uint8_t valid_count = 0;
+	uint8_t dig_stream_count = 0;
+	int matching_stream_ptrs = 0;
+	int eng_ids_per_ep_id[MAX_PIPES] = {0};
+
+	/* (1) No. valid entries same as stream count. */
+	for (i = 0; i < MAX_PIPES; i++) {
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+
+		if (assignment.valid)
+			valid_count++;
+
+		if (is_dig_link_enc_stream(state->streams[i]))
+			dig_stream_count++;
+	}
+	if (valid_count != dig_stream_count)
+		valid_entries = false;
+
+	/* (2) Matching stream ptrs. */
+	for (i = 0; i < MAX_PIPES; i++) {
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+
+		if (assignment.valid) {
+			if (assignment.stream == state->streams[i])
+				matching_stream_ptrs++;
+			else
+				valid_stream_ptrs = false;
+		}
+	}
+
+	/* (3) Each endpoint assigned unique encoder. */
+	for (i = 0; i < MAX_PIPES; i++) {
+		struct link_enc_assignment assignment_i = state->res_ctx.link_enc_assignments[i];
+
+		if (assignment_i.valid) {
+			struct display_endpoint_id ep_id_i = assignment_i.ep_id;
+
+			eng_ids_per_ep_id[i]++;
+			for (j = 0; j < MAX_PIPES; j++) {
+				struct link_enc_assignment assignment_j = state->res_ctx.link_enc_assignments[j];
+
+				if (j == i)
+					continue;
+
+				if (assignment_j.valid) {
+					struct display_endpoint_id ep_id_j = assignment_j.ep_id;
+
+					if (are_ep_ids_equal(&ep_id_i, &ep_id_j) &&
+							assignment_i.eng_id != assignment_j.eng_id) {
+						valid_uniqueness = false;
+						eng_ids_per_ep_id[i]++;
+					}
+				}
+			}
+		}
+	}
+
+	/* (4) Assigned encoders not in available pool. */
+	for (i = 0; i < MAX_PIPES; i++) {
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+
+		if (assignment.valid) {
+			for (j = 0; j < dc->res_pool->res_cap->num_dig_link_enc; j++) {
+				if (state->res_ctx.link_enc_avail[j] == assignment.eng_id) {
+					valid_avail = false;
+					break;
+				}
+			}
+		}
+	}
+
+	/* (5) All streams have valid link encoders. */
+	for (i = 0; i < state->stream_count; i++) {
+		struct dc_stream_state *stream = state->streams[i];
+
+		if (is_dig_link_enc_stream(stream) && stream->link_enc == NULL) {
+			valid_streams = false;
+			break;
+		}
+	}
+
+	is_valid = valid_entries && valid_stream_ptrs && valid_uniqueness && valid_avail && valid_streams;
+	ASSERT(is_valid);
+
+	return is_valid;
+}
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 8766b124d4b0..b4e986f736ad 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -2241,7 +2241,7 @@ enum dc_status dc_validate_global_state(
 	 * Update link encoder to stream assignment.
 	 * TODO: Split out reason allocation from validation.
 	 */
-	if (dc->res_pool->funcs->link_encs_assign)
+	if (dc->res_pool->funcs->link_encs_assign && fast_validate == false)
 		dc->res_pool->funcs->link_encs_assign(
 			dc, new_ctx, new_ctx->streams, new_ctx->stream_count);
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 5084289810e2..23af9640c544 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -212,6 +212,7 @@ struct link_enc_assignment {
 	bool valid;
 	struct display_endpoint_id ep_id;
 	enum engine_id eng_id;
+	struct dc_stream_state *stream;
 };
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
index 2472c9aed095..09f7c868feed 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
@@ -93,4 +93,7 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
 		struct dc_state *state,
 		const struct dc_stream_state *stream);
 
+/* Returns true if encoder assignments in supplied state pass validity checks. */
+bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state);
+
 #endif /* DC_INC_LINK_ENC_CFG_H_ */
-- 
2.25.1


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

* [PATCH 07/18] drm/amd/display: Fix dynamic encoder reassignment
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (5 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 06/18] drm/amd/display: Fix concurrent dynamic encoder assignment Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 08/18] drm/amd/display: Added power down on boot for DCN3 Rodrigo Siqueira
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Jimmy Kizito,
	Jun Lei

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Incorrect encoder assignments were being used while applying a new state
to hardware.

(1) When committing a new state to hardware requires resetting the
back-end, the encoder assignments of the current or old state should be
used when disabling the back-end; and the encoder assignments for the
next or new state should be used when re-enabling the back-end.

(2) Link training on hot plug could take over an encoder already in use
by another stream without first disabling it.

[How]

(1) Introduce a resource context 'link_enc_cfg_context' which includes:
- a mode to indicate when transitioning from current to next state.
- transient encoder assignments to use during this state transition.

Update the encoder configuration interface to respond to queries about
encoder assignment based on the mode of operation.

(2) Check if an encoder is already in use before attempting to perform
link training on hot plug.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  13 +-
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  27 +--
 .../drm/amd/display/dc/core/dc_link_enc_cfg.c | 178 +++++++++++++-----
 .../drm/amd/display/dc/core/dc_link_hwss.c    |   6 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  15 +-
 .../display/dc/dce110/dce110_hw_sequencer.c   |   2 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   4 +-
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |   5 +-
 .../display/dc/dcn31/dcn31_dio_link_encoder.c |   6 +-
 .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   4 +
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  18 +-
 .../drm/amd/display/dc/inc/hw/link_encoder.h  |   5 +
 .../gpu/drm/amd/display/dc/inc/link_enc_cfg.h |  20 +-
 13 files changed, 215 insertions(+), 88 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 222509557672..4ec3de34bd67 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3490,11 +3490,8 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 			link_enc = pipe_ctx->stream->link->link_enc;
 			config.phy_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
 		} else if (pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign) {
-			/* Use link encoder assignment from current DC state - which may differ from the DC state to be
-			 * committed - when updating PSP config.
-			 */
 			link_enc = link_enc_cfg_get_link_enc_used_by_stream(
-					pipe_ctx->stream->link->dc->current_state,
+					pipe_ctx->stream->ctx->dc,
 					pipe_ctx->stream);
 			config.phy_idx = 0; /* Clear phy_idx for non-physical display endpoints. */
 		}
@@ -3619,7 +3616,7 @@ void core_link_enable_stream(
 		return;
 
 	if (dc->res_pool->funcs->link_encs_assign && stream->link->ep_type != DISPLAY_ENDPOINT_PHY)
-		link_enc = stream->link_enc;
+		link_enc = link_enc_cfg_get_link_enc_used_by_stream(dc, stream);
 	else
 		link_enc = stream->link->link_enc;
 	ASSERT(link_enc);
@@ -4216,14 +4213,14 @@ bool dc_link_is_fec_supported(const struct dc_link *link)
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign) {
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 		if (link_enc == NULL)
-			link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
+			link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
 	} else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
 
-	return (dc_is_dp_signal(link->connector_signal) &&
+	return (dc_is_dp_signal(link->connector_signal) && link_enc &&
 			link_enc->features.fec_supported &&
 			link->dpcd_caps.fec_cap.bits.FEC_CAPABLE &&
 			!IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment));
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 920ae2b0b165..938bfd8761d1 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -282,7 +282,7 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 	else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
@@ -317,7 +317,7 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 	else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
@@ -2363,7 +2363,7 @@ bool perform_link_training_with_retries(
 	 * link.
 	 */
 	if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign)
-		link_enc = stream->link_enc;
+		link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
 	else
 		link_enc = link->link_enc;
 
@@ -2645,9 +2645,9 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign) {
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 		if (link_enc == NULL)
-			link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
+			link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
 	} else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
@@ -2676,9 +2676,9 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign) {
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 		if (link_enc == NULL)
-			link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state);
+			link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
 	} else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
@@ -2860,7 +2860,13 @@ bool dp_verify_link_cap(
 	enum link_training_result status;
 	union hpd_irq_data irq_data;
 
-	if (link->dc->debug.skip_detection_link_training) {
+	/* Accept reported capabilities if link supports flexible encoder mapping or encoder already in use. */
+	if (link->dc->debug.skip_detection_link_training ||
+			link->is_dig_mapping_flexible) {
+		link->verified_link_cap = *known_limit_link_setting;
+		return true;
+	} else if (link->link_enc && link->dc->res_pool->funcs->link_encs_assign &&
+			!link_enc_cfg_is_link_enc_avail(link->ctx->dc, link->link_enc->preferred_engine)) {
 		link->verified_link_cap = *known_limit_link_setting;
 		return true;
 	}
@@ -5658,7 +5664,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready)
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 	else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
@@ -5705,8 +5711,7 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(
-				link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 	else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
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 5536184fff46..4dce25c39b75 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
@@ -63,6 +63,18 @@ static bool is_dig_link_enc_stream(struct dc_stream_state *stream)
 	return is_dig_stream;
 }
 
+static struct link_enc_assignment get_assignment(struct dc *dc, int i)
+{
+	struct link_enc_assignment assignment;
+
+	if (dc->current_state->res_ctx.link_enc_cfg_ctx.mode == LINK_ENC_CFG_TRANSIENT)
+		assignment = dc->current_state->res_ctx.link_enc_cfg_ctx.transient_assignments[i];
+	else /* LINK_ENC_CFG_STEADY */
+		assignment = dc->current_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
+
+	return assignment;
+}
+
 /* Return stream using DIG link encoder resource. NULL if unused. */
 static struct dc_stream_state *get_stream_using_link_enc(
 		struct dc_state *state,
@@ -72,7 +84,7 @@ static struct dc_stream_state *get_stream_using_link_enc(
 	int i;
 
 	for (i = 0; i < state->stream_count; i++) {
-		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
 
 		if ((assignment.valid == true) && (assignment.eng_id == eng_id)) {
 			stream = state->streams[i];
@@ -98,15 +110,15 @@ static void remove_link_enc_assignment(
 		 * link_enc_assignments table.
 		 */
 		for (i = 0; i < MAX_PIPES; i++) {
-			struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+			struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
 
 			if (assignment.valid && assignment.stream == stream) {
-				state->res_ctx.link_enc_assignments[i].valid = false;
+				state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid = false;
 				/* Only add link encoder back to availability pool if not being
 				 * used by any other stream (i.e. removing SST stream or last MST stream).
 				 */
 				if (get_stream_using_link_enc(state, eng_id) == NULL)
-					state->res_ctx.link_enc_avail[eng_idx] = eng_id;
+					state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] = eng_id;
 				stream->link_enc = NULL;
 				break;
 			}
@@ -130,14 +142,14 @@ static void add_link_enc_assignment(
 		 */
 		for (i = 0; i < state->stream_count; i++) {
 			if (stream == state->streams[i]) {
-				state->res_ctx.link_enc_assignments[i] = (struct link_enc_assignment){
+				state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i] = (struct link_enc_assignment){
 					.valid = true,
 					.ep_id = (struct display_endpoint_id) {
 						.link_id = stream->link->link_id,
 						.ep_type = stream->link->ep_type},
 					.eng_id = eng_id,
 					.stream = stream};
-				state->res_ctx.link_enc_avail[eng_idx] = ENGINE_ID_UNKNOWN;
+				state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] = ENGINE_ID_UNKNOWN;
 				stream->link_enc = stream->ctx->dc->res_pool->link_encoders[eng_idx];
 				break;
 			}
@@ -157,7 +169,7 @@ static enum engine_id find_first_avail_link_enc(
 	int i;
 
 	for (i = 0; i < ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) {
-		eng_id = state->res_ctx.link_enc_avail[i];
+		eng_id = state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i];
 		if (eng_id != ENGINE_ID_UNKNOWN)
 			break;
 	}
@@ -170,7 +182,7 @@ static bool is_avail_link_enc(struct dc_state *state, enum engine_id eng_id)
 	bool is_avail = false;
 	int eng_idx = eng_id - ENGINE_ID_DIGA;
 
-	if (eng_id != ENGINE_ID_UNKNOWN && state->res_ctx.link_enc_avail[eng_idx] != ENGINE_ID_UNKNOWN)
+	if (eng_id != ENGINE_ID_UNKNOWN && state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] != ENGINE_ID_UNKNOWN)
 		is_avail = true;
 
 	return is_avail;
@@ -190,6 +202,28 @@ static bool are_ep_ids_equal(struct display_endpoint_id *lhs, struct display_end
 	return are_equal;
 }
 
+static struct link_encoder *get_link_enc_used_by_link(
+		struct dc_state *state,
+		const struct dc_link *link)
+{
+	struct link_encoder *link_enc = NULL;
+	struct display_endpoint_id ep_id;
+	int i;
+
+	ep_id = (struct display_endpoint_id) {
+		.link_id = link->link_id,
+		.ep_type = link->ep_type};
+
+	for (i = 0; i < state->stream_count; i++) {
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
+
+		if (assignment.valid == true && are_ep_ids_equal(&assignment.ep_id, &ep_id))
+			link_enc = link->dc->res_pool->link_encoders[assignment.eng_id - ENGINE_ID_DIGA];
+	}
+
+	return link_enc;
+}
+
 void link_enc_cfg_init(
 		struct dc *dc,
 		struct dc_state *state)
@@ -198,10 +232,12 @@ void link_enc_cfg_init(
 
 	for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) {
 		if (dc->res_pool->link_encoders[i])
-			state->res_ctx.link_enc_avail[i] = (enum engine_id) i;
+			state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i] = (enum engine_id) i;
 		else
-			state->res_ctx.link_enc_avail[i] = ENGINE_ID_UNKNOWN;
+			state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i] = ENGINE_ID_UNKNOWN;
 	}
+
+	state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY;
 }
 
 void link_enc_cfg_link_encs_assign(
@@ -221,7 +257,7 @@ void link_enc_cfg_link_encs_assign(
 		dc->res_pool->funcs->link_enc_unassign(state, streams[i]);
 
 	for (i = 0; i < MAX_PIPES; i++)
-		ASSERT(state->res_ctx.link_enc_assignments[i].valid == false);
+		ASSERT(state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid == false);
 
 	/* (a) Assign DIG link encoders to physical (unmappable) endpoints first. */
 	for (i = 0; i < stream_count; i++) {
@@ -258,8 +294,8 @@ void link_enc_cfg_link_encs_assign(
 				struct dc_stream_state *prev_stream = prev_state->streams[j];
 
 				if (stream == prev_stream && stream->link == prev_stream->link &&
-						prev_state->res_ctx.link_enc_assignments[j].valid) {
-					eng_id = prev_state->res_ctx.link_enc_assignments[j].eng_id;
+						prev_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[j].valid) {
+					eng_id = prev_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[j].eng_id;
 					if (is_avail_link_enc(state, eng_id))
 						add_link_enc_assignment(state, stream, eng_id);
 				}
@@ -291,7 +327,7 @@ void link_enc_cfg_link_encs_assign(
 			 * endpoint. These streams should use the same link encoder
 			 * assigned to that endpoint.
 			 */
-			link_enc = link_enc_cfg_get_link_enc_used_by_link(state, stream->link);
+			link_enc = get_link_enc_used_by_link(state, stream->link);
 			if (link_enc == NULL)
 				eng_id = find_first_avail_link_enc(stream->ctx, state);
 			else
@@ -301,6 +337,15 @@ void link_enc_cfg_link_encs_assign(
 	}
 
 	link_enc_cfg_validate(dc, state);
+
+	/* Update transient assignments. */
+	for (i = 0; i < MAX_PIPES; i++) {
+		dc->current_state->res_ctx.link_enc_cfg_ctx.transient_assignments[i] =
+			state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
+	}
+
+	/* Current state mode will be set to steady once this state committed. */
+	state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY;
 }
 
 void link_enc_cfg_link_enc_unassign(
@@ -320,12 +365,12 @@ void link_enc_cfg_link_enc_unassign(
 }
 
 bool link_enc_cfg_is_transmitter_mappable(
-		struct dc_state *state,
+		struct dc *dc,
 		struct link_encoder *link_enc)
 {
 	bool is_mappable = false;
 	enum engine_id eng_id = link_enc->preferred_engine;
-	struct dc_stream_state *stream = get_stream_using_link_enc(state, eng_id);
+	struct dc_stream_state *stream = link_enc_cfg_get_stream_using_link_enc(dc, eng_id);
 
 	if (stream)
 		is_mappable = stream->link->is_dig_mapping_flexible;
@@ -333,30 +378,43 @@ bool link_enc_cfg_is_transmitter_mappable(
 	return is_mappable;
 }
 
-struct dc_link *link_enc_cfg_get_link_using_link_enc(
-		struct dc_state *state,
+struct dc_stream_state *link_enc_cfg_get_stream_using_link_enc(
+		struct dc *dc,
 		enum engine_id eng_id)
 {
-	struct dc_link *link = NULL;
+	struct dc_stream_state *stream = NULL;
 	int i;
 
-	for (i = 0; i < state->stream_count; i++) {
-		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+	for (i = 0; i < MAX_PIPES; i++) {
+		struct link_enc_assignment assignment = get_assignment(dc, i);
 
 		if ((assignment.valid == true) && (assignment.eng_id == eng_id)) {
-			link = state->streams[i]->link;
+			stream = assignment.stream;
 			break;
 		}
 	}
 
-	if (link == NULL)
-		dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id);
+	return stream;
+}
 
+struct dc_link *link_enc_cfg_get_link_using_link_enc(
+		struct dc *dc,
+		enum engine_id eng_id)
+{
+	struct dc_link *link = NULL;
+	struct dc_stream_state *stream = NULL;
+
+	stream = link_enc_cfg_get_stream_using_link_enc(dc, eng_id);
+
+	if (stream)
+		link = stream->link;
+
+	// dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id);
 	return link;
 }
 
 struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
-		struct dc_state *state,
+		struct dc *dc,
 		const struct dc_link *link)
 {
 	struct link_encoder *link_enc = NULL;
@@ -367,41 +425,74 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
 		.link_id = link->link_id,
 		.ep_type = link->ep_type};
 
-	for (i = 0; i < state->stream_count; i++) {
-		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+	for (i = 0; i < MAX_PIPES; i++) {
+		struct link_enc_assignment assignment = get_assignment(dc, i);
 
-		if (assignment.valid == true && are_ep_ids_equal(&assignment.ep_id, &ep_id))
+		if (assignment.valid == true && are_ep_ids_equal(&assignment.ep_id, &ep_id)) {
 			link_enc = link->dc->res_pool->link_encoders[assignment.eng_id - ENGINE_ID_DIGA];
+			break;
+		}
 	}
 
 	return link_enc;
 }
 
-struct link_encoder *link_enc_cfg_get_next_avail_link_enc(
-	const struct dc *dc,
-	const struct dc_state *state)
+struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc)
 {
 	struct link_encoder *link_enc = NULL;
-	enum engine_id eng_id;
+	enum engine_id encs_assigned[MAX_DIG_LINK_ENCODERS];
+	int i;
+
+	for (i = 0; i < MAX_DIG_LINK_ENCODERS; i++)
+		encs_assigned[i] = ENGINE_ID_UNKNOWN;
 
-	eng_id = find_first_avail_link_enc(dc->ctx, state);
-	if (eng_id != ENGINE_ID_UNKNOWN)
-		link_enc = dc->res_pool->link_encoders[eng_id - ENGINE_ID_DIGA];
+	/* Add assigned encoders to list. */
+	for (i = 0; i < MAX_PIPES; i++) {
+		struct link_enc_assignment assignment = get_assignment(dc, i);
+
+		if (assignment.valid)
+			encs_assigned[assignment.eng_id - ENGINE_ID_DIGA] = assignment.eng_id;
+	}
+
+	for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) {
+		if (encs_assigned[i] == ENGINE_ID_UNKNOWN) {
+			link_enc = dc->res_pool->link_encoders[i];
+			break;
+		}
+	}
 
 	return link_enc;
 }
 
 struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
-		struct dc_state *state,
+		struct dc *dc,
 		const struct dc_stream_state *stream)
 {
 	struct link_encoder *link_enc;
 
-	link_enc = link_enc_cfg_get_link_enc_used_by_link(state, stream->link);
+	link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, stream->link);
 
 	return link_enc;
 }
 
+bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id)
+{
+	bool is_avail = true;
+	int i;
+
+	/* Add assigned encoders to list. */
+	for (i = 0; i < MAX_PIPES; i++) {
+		struct link_enc_assignment assignment = get_assignment(dc, i);
+
+		if (assignment.valid && assignment.eng_id == eng_id) {
+			is_avail = false;
+			break;
+		}
+	}
+
+	return is_avail;
+}
+
 bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state)
 {
 	bool is_valid = false;
@@ -418,7 +509,7 @@ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state)
 
 	/* (1) No. valid entries same as stream count. */
 	for (i = 0; i < MAX_PIPES; i++) {
-		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
 
 		if (assignment.valid)
 			valid_count++;
@@ -431,7 +522,7 @@ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state)
 
 	/* (2) Matching stream ptrs. */
 	for (i = 0; i < MAX_PIPES; i++) {
-		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
 
 		if (assignment.valid) {
 			if (assignment.stream == state->streams[i])
@@ -443,14 +534,15 @@ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state)
 
 	/* (3) Each endpoint assigned unique encoder. */
 	for (i = 0; i < MAX_PIPES; i++) {
-		struct link_enc_assignment assignment_i = state->res_ctx.link_enc_assignments[i];
+		struct link_enc_assignment assignment_i = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
 
 		if (assignment_i.valid) {
 			struct display_endpoint_id ep_id_i = assignment_i.ep_id;
 
 			eng_ids_per_ep_id[i]++;
 			for (j = 0; j < MAX_PIPES; j++) {
-				struct link_enc_assignment assignment_j = state->res_ctx.link_enc_assignments[j];
+				struct link_enc_assignment assignment_j =
+					state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[j];
 
 				if (j == i)
 					continue;
@@ -470,11 +562,11 @@ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state)
 
 	/* (4) Assigned encoders not in available pool. */
 	for (i = 0; i < MAX_PIPES; i++) {
-		struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i];
+		struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
 
 		if (assignment.valid) {
 			for (j = 0; j < dc->res_pool->res_cap->num_dig_link_enc; j++) {
-				if (state->res_ctx.link_enc_avail[j] == assignment.eng_id) {
+				if (state->res_ctx.link_enc_cfg_ctx.link_enc_avail[j] == assignment.eng_id) {
 					valid_avail = false;
 					break;
 				}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index dae0ab761b61..64f76f57c85d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -87,7 +87,7 @@ void dp_enable_link_phy(
 
 	/* Link should always be assigned encoder when en-/disabling. */
 	if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, link);
 	else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
@@ -247,7 +247,7 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
 
 	/* Link should always be assigned encoder when en-/disabling. */
 	if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, link);
 	else
 		link_enc = link->link_enc;
 	ASSERT(link_enc);
@@ -391,7 +391,7 @@ void dp_set_hw_test_pattern(
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign)
-		encoder = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		encoder = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 	else
 		encoder = link->link_enc;
 
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 b4e986f736ad..adc656fc4848 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -41,6 +41,7 @@
 #include "set_mode_types.h"
 #include "virtual/virtual_stream_encoder.h"
 #include "dpcd_defs.h"
+#include "link_enc_cfg.h"
 #include "dc_link_dp.h"
 
 #if defined(CONFIG_DRM_AMD_DC_SI)
@@ -2826,8 +2827,18 @@ bool pipe_need_reprogram(
 #endif
 
 	/* DIG link encoder resource assignment for stream changed. */
-	if (pipe_ctx_old->stream->link_enc != pipe_ctx->stream->link_enc)
-		return true;
+	if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) {
+		bool need_reprogram = false;
+		struct dc *dc = pipe_ctx_old->stream->ctx->dc;
+		enum link_enc_cfg_mode mode = dc->current_state->res_ctx.link_enc_cfg_ctx.mode;
+
+		dc->current_state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY;
+		if (link_enc_cfg_get_link_enc_used_by_stream(dc, pipe_ctx_old->stream) != pipe_ctx->stream->link_enc)
+			need_reprogram = true;
+		dc->current_state->res_ctx.link_enc_cfg_ctx.mode = mode;
+
+		return need_reprogram;
+	}
 
 	return false;
 }
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 102f76462752..af3e68d3e747 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
@@ -1219,7 +1219,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 	if (link->ep_type == DISPLAY_ENDPOINT_PHY)
 		link_enc = link->link_enc;
 	else if (dc->res_pool->funcs->link_encs_assign)
-		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
+		link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
 	ASSERT(link_enc);
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
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 c0aed7d07eeb..fc83744149d9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -54,6 +54,7 @@
 #include "hw_sequencer.h"
 #include "inc/link_dpcd.h"
 #include "dpcd_defs.h"
+#include "inc/link_enc_cfg.h"
 
 #define DC_LOGGER_INIT(logger)
 
@@ -2385,9 +2386,10 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
 
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign)
-		link_enc = pipe_ctx->stream->link_enc;
+		link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
 	else
 		link_enc = link->link_enc;
+	ASSERT(link_enc);
 
 	/* For MST, there are multiply stream go to only one link.
 	 * connect DIG back_end to front_end while enable_stream and
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index e69f553d680f..cb49375d83c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -1610,10 +1610,9 @@ static void get_pixel_clock_parameters(
 	 */
 	if (link->is_dig_mapping_flexible &&
 			link->dc->res_pool->funcs->link_encs_assign) {
-		link_enc = link_enc_cfg_get_link_enc_used_by_stream(stream->link->dc->current_state, stream);
+		link_enc = link_enc_cfg_get_link_enc_used_by_stream(stream->ctx->dc, stream);
 		if (link_enc == NULL)
-			link_enc = link_enc_cfg_get_next_avail_link_enc(stream->link->dc,
-				stream->link->dc->current_state);
+			link_enc = link_enc_cfg_get_next_avail_link_enc(stream->ctx->dc);
 	} else
 		link_enc = stream->link->link_enc;
 	ASSERT(link_enc);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
index 77b81f6c24b9..03f0290d41f2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
@@ -367,7 +367,7 @@ void dcn31_link_encoder_enable_dp_output(
 	enum clock_source_id clock_source)
 {
 	/* Enable transmitter and encoder. */
-	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc->current_state, enc)) {
+	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
 
 		dcn20_link_encoder_enable_dp_output(enc, link_settings, clock_source);
 
@@ -383,7 +383,7 @@ void dcn31_link_encoder_enable_dp_mst_output(
 	enum clock_source_id clock_source)
 {
 	/* Enable transmitter and encoder. */
-	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc->current_state, enc)) {
+	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
 
 		dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source);
 
@@ -398,7 +398,7 @@ void dcn31_link_encoder_disable_output(
 	enum signal_type signal)
 {
 	/* Disable transmitter and encoder. */
-	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc->current_state, enc)) {
+	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
 
 		dcn10_link_encoder_disable_output(enc, signal);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
index d3598ce1f5de..0713910a3aa9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
@@ -48,6 +48,7 @@
 #include "dc_link_dp.h"
 #include "inc/link_dpcd.h"
 #include "dcn10/dcn10_hw_sequencer.h"
+#include "inc/link_enc_cfg.h"
 
 #define DC_LOGGER_INIT(logger)
 
@@ -599,4 +600,7 @@ void dcn31_reset_hw_ctx_wrap(
 				old_clk->funcs->cs_power_down(old_clk);
 		}
 	}
+
+	/* New dc_state in the process of being applied to hardware. */
+	dc->current_state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_TRANSIENT;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index ed254c2771f0..8cff054db29f 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -384,6 +384,17 @@ struct pipe_ctx {
 	bool vtp_locked;
 };
 
+/* Data used for dynamic link encoder assignment.
+ * Tracks current and future assignments; available link encoders;
+ * and mode of operation (whether to use current or future assignments).
+ */
+struct link_enc_cfg_context {
+	enum link_enc_cfg_mode mode;
+	struct link_enc_assignment link_enc_assignments[MAX_PIPES];
+	enum engine_id link_enc_avail[MAX_DIG_LINK_ENCODERS];
+	struct link_enc_assignment transient_assignments[MAX_PIPES];
+};
+
 struct resource_context {
 	struct pipe_ctx pipe_ctx[MAX_PIPES];
 	bool is_stream_enc_acquired[MAX_PIPES * 2];
@@ -391,12 +402,7 @@ struct resource_context {
 	uint8_t clock_source_ref_count[MAX_CLOCK_SOURCES];
 	uint8_t dp_clock_source_ref_count;
 	bool is_dsc_acquired[MAX_PIPES];
-	/* A table/array of encoder-to-link assignments. One entry per stream.
-	 * Indexed by stream index in dc_state.
-	 */
-	struct link_enc_assignment link_enc_assignments[MAX_PIPES];
-	/* List of available link encoders. Uses engine ID as encoder identifier. */
-	enum engine_id link_enc_avail[MAX_DIG_LINK_ENCODERS];
+	struct link_enc_cfg_context link_enc_cfg_ctx;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS];
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 23af9640c544..bb0e91756ddd 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -215,6 +215,11 @@ struct link_enc_assignment {
 	struct dc_stream_state *stream;
 };
 
+enum link_enc_cfg_mode {
+	LINK_ENC_CFG_STEADY, /* Normal operation - use current_state. */
+	LINK_ENC_CFG_TRANSIENT /* During commit state - use state to be committed. */
+};
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 enum dp2_link_mode {
 	DP2_LINK_TRAINING_TPS1,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
index 09f7c868feed..83b2199b2c83 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
@@ -70,29 +70,35 @@ void link_enc_cfg_link_enc_unassign(
  * endpoint.
  */
 bool link_enc_cfg_is_transmitter_mappable(
-		struct dc_state *state,
+		struct dc *dc,
 		struct link_encoder *link_enc);
 
+/* Return stream using DIG link encoder resource. NULL if unused. */
+struct dc_stream_state *link_enc_cfg_get_stream_using_link_enc(
+		struct dc *dc,
+		enum engine_id eng_id);
+
 /* Return link using DIG link encoder resource. NULL if unused. */
 struct dc_link *link_enc_cfg_get_link_using_link_enc(
-		struct dc_state *state,
+		struct dc *dc,
 		enum engine_id eng_id);
 
 /* Return DIG link encoder used by link. NULL if unused. */
 struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
-		struct dc_state *state,
+		struct dc *dc,
 		const struct dc_link *link);
 
 /* Return next available DIG link encoder. NULL if none available. */
-struct link_encoder *link_enc_cfg_get_next_avail_link_enc(
-	const struct dc *dc,
-	const struct dc_state *state);
+struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc);
 
 /* Return DIG link encoder used by stream. NULL if unused. */
 struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
-		struct dc_state *state,
+		struct dc *dc,
 		const struct dc_stream_state *stream);
 
+/* Return true if encoder available to use. */
+bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id);
+
 /* Returns true if encoder assignments in supplied state pass validity checks. */
 bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state);
 
-- 
2.25.1


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

* [PATCH 08/18] drm/amd/display: Added power down on boot for DCN3
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (6 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 07/18] drm/amd/display: Fix dynamic encoder reassignment Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 09/18] drm/amd/display: Use adjusted DCN301 watermarks Rodrigo Siqueira
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Lai, Derek,
	Anthony Koo

From: "Lai, Derek" <Derek.Lai@amd.com>

[Why]
The change of setting a timer callback on boot for 10 seconds is still
working, just lost power down on boot and power down for DCN3.

[How]
Added power down on boot and power down for DCN3.

Reviewed-by: Anthony Koo <anthony.koo@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Derek Lai <Derek.Lai@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c
index 10c83f4083b5..c6a737781ad1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c
@@ -34,6 +34,7 @@
 static const struct hw_sequencer_funcs dcn31_funcs = {
 	.program_gamut_remap = dcn10_program_gamut_remap,
 	.init_hw = dcn31_init_hw,
+	.power_down_on_boot = dcn10_power_down_on_boot,
 	.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
 	.apply_ctx_for_surface = NULL,
 	.program_front_end_for_ctx = dcn20_program_front_end_for_ctx,
@@ -93,6 +94,7 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
 	.set_flip_control_gsl = dcn20_set_flip_control_gsl,
 	.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
 	.calc_vupdate_position = dcn10_calc_vupdate_position,
+	.power_down = dce110_power_down,
 	.set_backlight_level = dcn21_set_backlight_level,
 	.set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
 	.set_pipe = dcn21_set_pipe,
-- 
2.25.1


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

* [PATCH 09/18] drm/amd/display: Use adjusted DCN301 watermarks
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (7 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 08/18] drm/amd/display: Added power down on boot for DCN3 Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 10/18] drm/amd/display: Fix issue with dynamic bpp change for DCN3x Rodrigo Siqueira
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Nikola Cornij,
	Zhan Liu

From: Nikola Cornij <nikola.cornij@amd.com>

[why]
If DCN30 watermark calc is used for DCN301, the calculated values are
wrong due to the data structure mismatch between DCN30 and DCN301.
However, using the original DCN301 watermark values causes underflow.

[how]
- Add DCN21-style watermark calculations
- Adjust DCN301 watermark values to remove the underflow

Reviewed-by: Zhan Liu <zhan.liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
---
 .../display/dc/clk_mgr/dcn301/vg_clk_mgr.c    |  4 +-
 .../amd/display/dc/dcn301/dcn301_resource.c   | 96 ++++++++++++++++++-
 2 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
index 7046da14bb2a..3eee32faa208 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
@@ -582,8 +582,8 @@ static struct wm_table lpddr5_wm_table = {
 			.wm_inst = WM_A,
 			.wm_type = WM_TYPE_PSTATE_CHG,
 			.pstate_latency_us = 11.65333,
-			.sr_exit_time_us = 5.32,
-			.sr_enter_plus_exit_time_us = 6.38,
+			.sr_exit_time_us = 7.95,
+			.sr_enter_plus_exit_time_us = 9,
 			.valid = true,
 		},
 		{
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index 73b8fcb3c5c9..5350c93d7772 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -1626,12 +1626,106 @@ static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *b
 	dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30);
 }
 
+static void calculate_wm_set_for_vlevel(
+		int vlevel,
+		struct wm_range_table_entry *table_entry,
+		struct dcn_watermarks *wm_set,
+		struct display_mode_lib *dml,
+		display_e2e_pipe_params_st *pipes,
+		int pipe_cnt)
+{
+	double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
+
+	ASSERT(vlevel < dml->soc.num_states);
+	/* only pipe 0 is read for voltage and dcf/soc clocks */
+	pipes[0].clks_cfg.voltage = vlevel;
+	pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
+	pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
+
+	dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
+	dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
+	dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
+
+	wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
+	wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
+	wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
+	wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
+	wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
+	wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
+	wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
+	wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
+	dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
+
+}
+
+static void dcn301_calculate_wm_and_dlg(
+		struct dc *dc, struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int pipe_cnt,
+		int vlevel_req)
+{
+	int i, pipe_idx;
+	int vlevel, vlevel_max;
+	struct wm_range_table_entry *table_entry;
+	struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
+
+	ASSERT(bw_params);
+
+	vlevel_max = bw_params->clk_table.num_entries - 1;
+
+	/* WM Set D */
+	table_entry = &bw_params->wm_table.entries[WM_D];
+	if (table_entry->wm_type == WM_TYPE_RETRAINING)
+		vlevel = 0;
+	else
+		vlevel = vlevel_max;
+	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
+						&context->bw_ctx.dml, pipes, pipe_cnt);
+	/* WM Set C */
+	table_entry = &bw_params->wm_table.entries[WM_C];
+	vlevel = min(max(vlevel_req, 2), vlevel_max);
+	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
+						&context->bw_ctx.dml, pipes, pipe_cnt);
+	/* WM Set B */
+	table_entry = &bw_params->wm_table.entries[WM_B];
+	vlevel = min(max(vlevel_req, 1), vlevel_max);
+	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
+						&context->bw_ctx.dml, pipes, pipe_cnt);
+
+	/* WM Set A */
+	table_entry = &bw_params->wm_table.entries[WM_A];
+	vlevel = min(vlevel_req, vlevel_max);
+	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
+						&context->bw_ctx.dml, pipes, pipe_cnt);
+
+	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+		if (!context->res_ctx.pipe_ctx[i].stream)
+			continue;
+
+		pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
+		pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+
+		if (dc->config.forced_clocks) {
+			pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
+			pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
+		}
+		if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
+			pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
+		if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
+			pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
+
+		pipe_idx++;
+	}
+
+	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+}
+
 static struct resource_funcs dcn301_res_pool_funcs = {
 	.destroy = dcn301_destroy_resource_pool,
 	.link_enc_create = dcn301_link_encoder_create,
 	.panel_cntl_create = dcn301_panel_cntl_create,
 	.validate_bandwidth = dcn30_validate_bandwidth,
-	.calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
+	.calculate_wm_and_dlg = dcn301_calculate_wm_and_dlg,
 	.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
 	.populate_dml_pipes = dcn30_populate_dml_pipes_from_context,
 	.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
-- 
2.25.1


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

* [PATCH 10/18] drm/amd/display: Fix issue with dynamic bpp change for DCN3x
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (8 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 09/18] drm/amd/display: Use adjusted DCN301 watermarks Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 11/18] drm/amd/display: Disable mem low power for CM HW block on DCN3.1 Rodrigo Siqueira
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Guo, Bing,
	Wenjing Liu

From: "Guo, Bing" <Bing.Guo@amd.com>

Why:
Screen sometimes would have artifacts or blink once at the time when bpp
is dynamically changed.

How:
1. Changed to update PPS infopacket in frame mode instead of immediate mode
   since other updates for bpp change are double-buffered.
2. Changed double-buffering enablement programming for DCN30 as advised by
ASIC team

Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Bing Guo <Bing.Guo@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |   4 +-
 .../drm/amd/display/dc/core/dc_link_hwss.c    |  29 ++-
 .../display/dc/dcn20/dcn20_stream_encoder.c   |   3 +-
 .../dc/dcn30/dcn30_dio_stream_encoder.c       |  18 +-
 .../gpu/drm/amd/display/dc/dcn30/dcn30_optc.c |  17 +-
 .../gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c  | 198 ++++++++++++------
 .../gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h  |   6 +-
 .../dc/dcn31/dcn31_hpo_dp_stream_encoder.c    |  15 +-
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |   2 +-
 .../amd/display/dc/inc/hw/stream_encoder.h    |   6 +-
 .../dc/virtual/virtual_stream_encoder.c       |   3 +-
 11 files changed, 204 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 4ec3de34bd67..2bd38d19a447 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3554,7 +3554,7 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
 
 	/* Set DPS PPS SDP (AKA "info frames") */
 	if (pipe_ctx->stream->timing.flags.DSC) {
-		dp_set_dsc_pps_sdp(pipe_ctx, true);
+		dp_set_dsc_pps_sdp(pipe_ctx, true, true);
 	}
 
 	/* Allocate Payload */
@@ -3803,7 +3803,7 @@ void core_link_enable_stream(
 			if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
 					dc_is_virtual_signal(pipe_ctx->stream->signal)) {
 				dp_set_dsc_on_rx(pipe_ctx, true);
-				dp_set_dsc_pps_sdp(pipe_ctx, true);
+				dp_set_dsc_pps_sdp(pipe_ctx, true, true);
 			}
 		}
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index 64f76f57c85d..cc4b28e94727 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -607,7 +607,8 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
 										pipe_ctx->stream_res.hpo_dp_stream_enc,
 										false,
-										NULL);
+										NULL,
+										true);
 			else
 #endif
 				if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
@@ -615,7 +616,7 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 							pipe_ctx->stream_res.stream_enc,
 							OPTC_DSC_DISABLED, 0, 0);
 					pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
-								pipe_ctx->stream_res.stream_enc, false, NULL);
+								pipe_ctx->stream_res.stream_enc, false, NULL, true);
 				}
 		}
 
@@ -650,7 +651,16 @@ bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
 	return result;
 }
 
-bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
+/*
+ * For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
+ * hence PPS info packet update need to use frame update instead of immediate update.
+ * Added parameter immediate_update for this purpose.
+ * The decision to use frame update is hard-coded in function dp_update_dsc_config(),
+ * which is the only place where a "false" would be passed in for param immediate_update.
+ *
+ * immediate_update is only applicable when DSC is enabled.
+ */
+bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
 {
 	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 	struct dc_stream_state *stream = pipe_ctx->stream;
@@ -682,13 +692,15 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
 				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
 										pipe_ctx->stream_res.hpo_dp_stream_enc,
 										true,
-										&dsc_packed_pps[0]);
+										&dsc_packed_pps[0],
+										immediate_update);
 			else
 #endif
 				pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
 										pipe_ctx->stream_res.stream_enc,
 										true,
-										&dsc_packed_pps[0]);
+										&dsc_packed_pps[0],
+										immediate_update);
 		}
 	} else {
 		/* disable DSC PPS in stream encoder */
@@ -698,11 +710,12 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
 				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
 										pipe_ctx->stream_res.hpo_dp_stream_enc,
 										false,
-										NULL);
+										NULL,
+										true);
 			else
 #endif
 				pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
-							pipe_ctx->stream_res.stream_enc, false, NULL);
+							pipe_ctx->stream_res.stream_enc, false, NULL, true);
 		}
 	}
 
@@ -720,7 +733,7 @@ bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
 		return false;
 
 	dp_set_dsc_on_stream(pipe_ctx, true);
-	dp_set_dsc_pps_sdp(pipe_ctx, true);
+	dp_set_dsc_pps_sdp(pipe_ctx, true, false);
 	return true;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
index 44f31b7b9ac9..11c50b508754 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
@@ -292,7 +292,8 @@ static void enc2_dp_set_dsc_config(struct stream_encoder *enc,
 
 static void enc2_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
 					bool enable,
-					uint8_t *dsc_packed_pps)
+					uint8_t *dsc_packed_pps,
+					bool immediate_update)
 {
 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c
index b73dfd2661b9..3ea6dacec80c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c
@@ -77,7 +77,8 @@ static void enc3_update_hdmi_info_packet(
 		enc1->base.vpg->funcs->update_generic_info_packet(
 				enc1->base.vpg,
 				packet_index,
-				info_packet);
+				info_packet,
+				true);
 
 		/* enable transmission of packet(s) -
 		 * packet transmission begins on the next frame */
@@ -335,7 +336,8 @@ static void enc3_dp_set_dsc_config(struct stream_encoder *enc,
 
 static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
 					bool enable,
-					uint8_t *dsc_packed_pps)
+					uint8_t *dsc_packed_pps,
+					bool immediate_update)
 {
 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 
@@ -365,7 +367,8 @@ static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
 			enc1->base.vpg->funcs->update_generic_info_packet(
 							enc1->base.vpg,
 							11 + i,
-							&pps_sdp);
+							&pps_sdp,
+							immediate_update);
 		}
 
 		/* SW should make sure VBID[6] update line number is bigger
@@ -429,19 +432,22 @@ static void enc3_stream_encoder_update_dp_info_packets(
 		enc->vpg->funcs->update_generic_info_packet(
 				enc->vpg,
 				0,  /* packetIndex */
-				&info_frame->vsc);
+				&info_frame->vsc,
+				true);
 	}
 	if (info_frame->spd.valid) {
 		enc->vpg->funcs->update_generic_info_packet(
 				enc->vpg,
 				2,  /* packetIndex */
-				&info_frame->spd);
+				&info_frame->spd,
+				true);
 	}
 	if (info_frame->hdrsmd.valid) {
 		enc->vpg->funcs->update_generic_info_packet(
 				enc->vpg,
 				3,  /* packetIndex */
-				&info_frame->hdrsmd);
+				&info_frame->hdrsmd,
+				true);
 	}
 	/* packetIndex 4 is used for send immediate sdp message, and please
 	 * use other packetIndex (such as 5,6) for other info packet
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c
index 089be7347591..5d9e6413d67a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c
@@ -73,16 +73,23 @@ void optc3_lock_doublebuffer_enable(struct timing_generator *optc)
 		OTG_H_BLANK_END, &h_blank_end);
 
 	REG_UPDATE_2(OTG_GLOBAL_CONTROL1,
-		MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start,
-		MASTER_UPDATE_LOCK_DB_END_Y, v_blank_end);
+		MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start - 1,
+		MASTER_UPDATE_LOCK_DB_END_Y, v_blank_start);
 	REG_UPDATE_2(OTG_GLOBAL_CONTROL4,
-		DIG_UPDATE_POSITION_X, 20,
-		DIG_UPDATE_POSITION_Y, v_blank_start);
+		DIG_UPDATE_POSITION_X, h_blank_start - 180 - 1,
+		DIG_UPDATE_POSITION_Y, v_blank_start - 1);
+	// there is a DIG_UPDATE_VCOUNT_MODE and it is 0.
+
 	REG_UPDATE_3(OTG_GLOBAL_CONTROL0,
 		MASTER_UPDATE_LOCK_DB_START_X, h_blank_start - 200 - 1,
-		MASTER_UPDATE_LOCK_DB_END_X, h_blank_end,
+		MASTER_UPDATE_LOCK_DB_END_X, h_blank_start - 180,
 		MASTER_UPDATE_LOCK_DB_EN, 1);
 	REG_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 1);
+
+	REG_SET_3(OTG_VUPDATE_KEEPOUT, 0,
+		MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, 0,
+		MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, 100,
+		OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 1);
 }
 
 void optc3_lock_doublebuffer_disable(struct timing_generator *optc)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c
index 9748aaa044f7..14bc44b1f886 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c
@@ -46,7 +46,8 @@
 void vpg3_update_generic_info_packet(
 	struct vpg *vpg,
 	uint32_t packet_index,
-	const struct dc_info_packet *info_packet)
+	const struct dc_info_packet *info_packet,
+	bool immediate_update)
 {
 	struct dcn30_vpg *vpg3 = DCN30_VPG_FROM_VPG(vpg);
 	uint32_t i;
@@ -106,69 +107,138 @@ void vpg3_update_generic_info_packet(
 	/* atomically update double-buffered GENERIC0 registers in immediate mode
 	 * (update at next block_update when block_update_lock == 0).
 	 */
-	switch (packet_index) {
-	case 0:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC0_IMMEDIATE_UPDATE, 1);
-		break;
-	case 1:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC1_IMMEDIATE_UPDATE, 1);
-		break;
-	case 2:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC2_IMMEDIATE_UPDATE, 1);
-		break;
-	case 3:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC3_IMMEDIATE_UPDATE, 1);
-		break;
-	case 4:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC4_IMMEDIATE_UPDATE, 1);
-		break;
-	case 5:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC5_IMMEDIATE_UPDATE, 1);
-		break;
-	case 6:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC6_IMMEDIATE_UPDATE, 1);
-		break;
-	case 7:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC7_IMMEDIATE_UPDATE, 1);
-		break;
-	case 8:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC8_IMMEDIATE_UPDATE, 1);
-		break;
-	case 9:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC9_IMMEDIATE_UPDATE, 1);
-		break;
-	case 10:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC10_IMMEDIATE_UPDATE, 1);
-		break;
-	case 11:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC11_IMMEDIATE_UPDATE, 1);
-		break;
-	case 12:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC12_IMMEDIATE_UPDATE, 1);
-		break;
-	case 13:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC13_IMMEDIATE_UPDATE, 1);
-		break;
-	case 14:
-		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
-				VPG_GENERIC14_IMMEDIATE_UPDATE, 1);
-		break;
-	default:
-		break;
+	if (immediate_update) {
+		switch (packet_index) {
+		case 0:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC0_IMMEDIATE_UPDATE, 1);
+			break;
+		case 1:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC1_IMMEDIATE_UPDATE, 1);
+			break;
+		case 2:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC2_IMMEDIATE_UPDATE, 1);
+			break;
+		case 3:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC3_IMMEDIATE_UPDATE, 1);
+			break;
+		case 4:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC4_IMMEDIATE_UPDATE, 1);
+			break;
+		case 5:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC5_IMMEDIATE_UPDATE, 1);
+			break;
+		case 6:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC6_IMMEDIATE_UPDATE, 1);
+			break;
+		case 7:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC7_IMMEDIATE_UPDATE, 1);
+			break;
+		case 8:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC8_IMMEDIATE_UPDATE, 1);
+			break;
+		case 9:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC9_IMMEDIATE_UPDATE, 1);
+			break;
+		case 10:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC10_IMMEDIATE_UPDATE, 1);
+			break;
+		case 11:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC11_IMMEDIATE_UPDATE, 1);
+			break;
+		case 12:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC12_IMMEDIATE_UPDATE, 1);
+			break;
+		case 13:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC13_IMMEDIATE_UPDATE, 1);
+			break;
+		case 14:
+			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+					VPG_GENERIC14_IMMEDIATE_UPDATE, 1);
+			break;
+		default:
+			break;
+		}
+	} else {
+		switch (packet_index) {
+		case 0:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC0_FRAME_UPDATE, 1);
+			break;
+		case 1:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC1_FRAME_UPDATE, 1);
+			break;
+		case 2:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC2_FRAME_UPDATE, 1);
+			break;
+		case 3:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC3_FRAME_UPDATE, 1);
+			break;
+		case 4:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC4_FRAME_UPDATE, 1);
+			break;
+		case 5:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC5_FRAME_UPDATE, 1);
+			break;
+		case 6:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC6_FRAME_UPDATE, 1);
+			break;
+		case 7:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC7_FRAME_UPDATE, 1);
+			break;
+		case 8:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC8_FRAME_UPDATE, 1);
+			break;
+		case 9:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC9_FRAME_UPDATE, 1);
+			break;
+		case 10:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC10_FRAME_UPDATE, 1);
+			break;
+		case 11:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC11_FRAME_UPDATE, 1);
+			break;
+		case 12:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC12_FRAME_UPDATE, 1);
+			break;
+		case 13:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC13_FRAME_UPDATE, 1);
+			break;
+		case 14:
+			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+					VPG_GENERIC14_FRAME_UPDATE, 1);
+			break;
+
+		default:
+			break;
+		}
+
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h
index 96dccb2f1124..ed9a5549c389 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h
@@ -138,7 +138,8 @@ struct vpg_funcs {
 	void (*update_generic_info_packet)(
 		struct vpg *vpg,
 		uint32_t packet_index,
-		const struct dc_info_packet *info_packet);
+		const struct dc_info_packet *info_packet,
+		bool immediate_update);
 
 	void (*vpg_poweron)(
 		struct vpg *vpg);
@@ -163,7 +164,8 @@ struct dcn30_vpg {
 void vpg3_update_generic_info_packet(
 	struct vpg *vpg,
 	uint32_t packet_index,
-	const struct dc_info_packet *info_packet);
+	const struct dc_info_packet *info_packet,
+	bool immediate_update);
 
 void vpg3_construct(struct dcn30_vpg *vpg3,
 	struct dc_context *ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
index 25e4794eb9ad..565f12dd179a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
@@ -442,21 +442,24 @@ static void dcn31_hpo_dp_stream_enc_update_dp_info_packets(
 		enc->vpg->funcs->update_generic_info_packet(
 				enc->vpg,
 				0,  /* packetIndex */
-				&info_frame->vsc);
+				&info_frame->vsc,
+				true);
 		sdp_stream_enable = true;
 	}
 	if (info_frame->spd.valid) {
 		enc->vpg->funcs->update_generic_info_packet(
 				enc->vpg,
 				2,  /* packetIndex */
-				&info_frame->spd);
+				&info_frame->spd,
+				true);
 		sdp_stream_enable = true;
 	}
 	if (info_frame->hdrsmd.valid) {
 		enc->vpg->funcs->update_generic_info_packet(
 				enc->vpg,
 				3,  /* packetIndex */
-				&info_frame->hdrsmd);
+				&info_frame->hdrsmd,
+				true);
 		sdp_stream_enable = true;
 	}
 	/* enable/disable transmission of packet(s).
@@ -520,7 +523,8 @@ static uint32_t hpo_dp_is_gsp_enabled(
 static void dcn31_hpo_dp_stream_enc_set_dsc_pps_info_packet(
 		struct hpo_dp_stream_encoder *enc,
 		bool enable,
-		uint8_t *dsc_packed_pps)
+		uint8_t *dsc_packed_pps,
+		bool immediate_update)
 {
 	struct dcn31_hpo_dp_stream_encoder *enc3 = DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(enc);
 
@@ -544,7 +548,8 @@ static void dcn31_hpo_dp_stream_enc_set_dsc_pps_info_packet(
 			enc3->base.vpg->funcs->update_generic_info_packet(
 							enc3->base.vpg,
 							11 + i,
-							&pps_sdp);
+							&pps_sdp,
+							immediate_update);
 		}
 
 		/* SW should make sure VBID[6] update line number is bigger
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
index 3cc110e13213..cb8e785a866e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
@@ -166,7 +166,7 @@ uint8_t dc_dp_initialize_scrambling_data_symbols(
 enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready);
 void dp_set_fec_enable(struct dc_link *link, bool enable);
 bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
-bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable);
+bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update);
 void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
 bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx);
 bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index 9f03fda5b965..c88e113b94d1 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -229,7 +229,8 @@ struct stream_encoder_funcs {
 
 	void (*dp_set_dsc_pps_info_packet)(struct stream_encoder *enc,
 				bool enable,
-				uint8_t *dsc_packed_pps);
+				uint8_t *dsc_packed_pps,
+				bool immediate_update);
 
 	void (*set_dynamic_metadata)(struct stream_encoder *enc,
 			bool enable,
@@ -298,7 +299,8 @@ struct hpo_dp_stream_encoder_funcs {
 	void (*dp_set_dsc_pps_info_packet)(
 			struct hpo_dp_stream_encoder *enc,
 			bool enable,
-			uint8_t *dsc_packed_pps);
+			uint8_t *dsc_packed_pps,
+			bool immediate_update);
 
 	void (*map_stream_to_link)(
 			struct hpo_dp_stream_encoder *enc,
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c
index 42a29b712e0e..1e39aae6b1cf 100644
--- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c
@@ -104,7 +104,8 @@ static void virtual_setup_stereo_sync(
 static void virtual_stream_encoder_set_dsc_pps_info_packet(
 		struct stream_encoder *enc,
 		bool enable,
-		uint8_t *dsc_packed_pps)
+		uint8_t *dsc_packed_pps,
+		bool immediate_update)
 {}
 
 static const struct stream_encoder_funcs virtual_str_enc_funcs = {
-- 
2.25.1


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

* [PATCH 11/18] drm/amd/display: Disable mem low power for CM HW block on DCN3.1
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (9 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 10/18] drm/amd/display: Fix issue with dynamic bpp change for DCN3x Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 12/18] drm/amd/display: Fix B0 USB-C DP Alt mode Rodrigo Siqueira
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu,
	Michael Strauss, Haonan Wang

From: Michael Strauss <michael.strauss@amd.com>

[WHY]
Currently causes visible flicker in some scenarios on OLED eDPs

Reviewed-by: Haonan Wang <haonan.wang2@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Michael Strauss <michael.strauss@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index a823a64d02a5..0b60ac676423 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -1013,7 +1013,7 @@ static const struct dc_debug_options debug_defaults_drv = {
 			.i2c = true,
 			.dmcu = false, // This is previously known to cause hang on S3 cycles if enabled
 			.dscl = true,
-			.cm = true,
+			.cm = false, // visible flicker on OLED eDPs
 			.mpc = true,
 			.optc = true,
 			.vpg = true,
-- 
2.25.1


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

* [PATCH 12/18] drm/amd/display: Fix B0 USB-C DP Alt mode
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (10 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 11/18] drm/amd/display: Disable mem low power for CM HW block on DCN3.1 Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 13/18] drm/amd/display: DIG mapping change is causing a blocker Rodrigo Siqueira
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Liu, Zhan,
	Charlene Liu

From: "Liu, Zhan" <Zhan.Liu@amd.com>

[Why]
Starting from B0, along with RDPCSTX, RDPCSPIPE registers are also used.

[How]
Make sure RDPCSPIPE registers are programmed correctly.

Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by:Zhan Liu <Zhan.Liu@amd.com>
---
 .../amd/display/dc/dcn10/dcn10_link_encoder.h |  1 +
 .../display/dc/dcn31/dcn31_dio_link_encoder.c | 33 ++++++++++++++++++-
 .../display/dc/dcn31/dcn31_dio_link_encoder.h | 11 ++++++-
 .../include/asic_reg/dpcs/dpcs_4_2_0_offset.h | 27 +++++++++++++++
 4 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
index d8b22618b79e..c337588231ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
@@ -118,6 +118,7 @@ struct dcn10_link_enc_registers {
 	uint32_t RDPCSTX_PHY_CNTL4;
 	uint32_t RDPCSTX_PHY_CNTL5;
 	uint32_t RDPCSTX_PHY_CNTL6;
+	uint32_t RDPCSPIPE_PHY_CNTL6;
 	uint32_t RDPCSTX_PHY_CNTL7;
 	uint32_t RDPCSTX_PHY_CNTL8;
 	uint32_t RDPCSTX_PHY_CNTL9;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
index 03f0290d41f2..4f0a0803db6c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
@@ -37,6 +37,7 @@
 
 #include "link_enc_cfg.h"
 #include "dc_dmub_srv.h"
+#include "dal_asic_id.h"
 
 #define CTX \
 	enc10->base.ctx
@@ -215,7 +216,7 @@ static const struct link_encoder_funcs dcn31_link_enc_funcs = {
 	.fec_is_active = enc2_fec_is_active,
 	.get_dig_frontend = dcn10_get_dig_frontend,
 	.get_dig_mode = dcn10_get_dig_mode,
-	.is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
+	.is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode,
 	.get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
 	.set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
 };
@@ -408,3 +409,33 @@ void dcn31_link_encoder_disable_output(
 	}
 }
 
+bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc)
+{
+	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+	uint32_t dp_alt_mode_disable;
+	bool is_usb_c_alt_mode = false;
+
+	if (enc->features.flags.bits.DP_IS_USB_C) {
+		if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
+			// [Note] no need to check hw_internal_rev once phy mux selection is ready
+			REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+		} else {
+		/*
+		 * B0 phys use a new set of registers to check whether alt mode is disabled.
+		 * if value == 1 alt mode is disabled, otherwise it is enabled.
+		 */
+			if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
+					|| (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
+					|| (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
+				REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+			} else {
+			// [Note] need to change TRANSMITTER_UNIPHY_C/D to F/G once phy mux selection is ready
+				REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+			}
+		}
+
+		is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
+	}
+
+	return is_usb_c_alt_mode;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h
index 32d146312838..bec50e4402ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h
@@ -69,6 +69,7 @@
 	SRI(RDPCSTX_PHY_CNTL4, RDPCSTX, id), \
 	SRI(RDPCSTX_PHY_CNTL5, RDPCSTX, id), \
 	SRI(RDPCSTX_PHY_CNTL6, RDPCSTX, id), \
+	SRI(RDPCSPIPE_PHY_CNTL6, RDPCSPIPE, id), \
 	SRI(RDPCSTX_PHY_CNTL7, RDPCSTX, id), \
 	SRI(RDPCSTX_PHY_CNTL8, RDPCSTX, id), \
 	SRI(RDPCSTX_PHY_CNTL9, RDPCSTX, id), \
@@ -115,7 +116,9 @@
 	LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_MPLL_EN, mask_sh),\
 	LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_MPLL_EN, mask_sh),\
 	LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
-	LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
+	LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
+	LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
+	LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE_ACK, mask_sh),\
 	LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_QUOT, mask_sh),\
 	LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_DEN, mask_sh),\
 	LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL8, RDPCS_PHY_DP_MPLLB_SSC_PEAK, mask_sh),\
@@ -243,4 +246,10 @@ void dcn31_link_encoder_disable_output(
 	struct link_encoder *enc,
 	enum signal_type signal);
 
+/*
+ * Check whether USB-C DP Alt mode is disabled
+ */
+bool dcn31_link_encoder_is_in_alt_mode(
+	struct link_encoder *enc);
+
 #endif /* __DC_LINK_ENCODER__DCN31_H__ */
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h
index 92caf8441d1e..01a56556cde1 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h
@@ -11932,5 +11932,32 @@
 #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_RX_OVRD_OUT_2                                                0xe0c7
 #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_TX_OVRD_IN_2                                                 0xe0c8
 
+//RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT                                            0x10
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT                                        0x11
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT                                    0x12
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK                                              0x00010000L
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK                                          0x00020000L
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK                                      0x00040000L
+
+//RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT                                            0x10
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT                                        0x11
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT                                    0x12
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK                                              0x00010000L
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK                                          0x00020000L
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK                                      0x00040000L
+
+//[Note] Hack. RDPCSPIPE only has 2 instances.
+#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6                                                              0x2e4b
+#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6                                                              0x2e4b
+#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
 
 #endif
-- 
2.25.1


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

* [PATCH 13/18] drm/amd/display: DIG mapping change is causing a blocker
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (11 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 12/18] drm/amd/display: Fix B0 USB-C DP Alt mode Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 14/18] drm/amd/display: Creating a fw boot options bit for an upcoming feature Rodrigo Siqueira
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Liu, Zhan,
	Jimmy Kizito

From: "Liu, Zhan" <Zhan.Liu@amd.com>

[Why]
DIG mapping change is causing a blocker

[How]
Revert the change for now. We will re-implement it later.

Reviewed-by: Jimmy Kizito <jimmy.kizito@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Zhan Liu <Zhan.Liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 0b60ac676423..6f0c788d1904 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -1383,12 +1383,6 @@ static struct stream_encoder *dcn31_stream_encoder_create(
 		return NULL;
 	}
 
-	if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
-			ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
-		if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD))
-			eng_id = eng_id + 3; // For B0 only. C->F, D->G.
-	}
-
 	dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
 					eng_id, vpg, afmt,
 					&stream_enc_regs[eng_id],
-- 
2.25.1


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

* [PATCH 14/18] drm/amd/display: Creating a fw boot options bit for an upcoming feature
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (12 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 13/18] drm/amd/display: DIG mapping change is causing a blocker Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 15/18] drm/amd/display: Fix null pointer dereference for encoders Rodrigo Siqueira
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu,
	Meenakshikumar Somasundaram, Jimmy Kizito, Jun Lei

From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>

[Why]
Need a bit for x86 driver to enable a FW boot option for an upcoming
feature.

[How]
Added a bit in dmub_fw_boot_options for an upcoming feature.

Reviewed-by: Jimmy Kizito <jimmy.kizito@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
---
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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 1edc5bb4d668..1b377364ace7 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -372,7 +372,8 @@ union dmub_fw_boot_options {
 		uint32_t reserved2: 1; /**< reserved for an unreleased feature */
 		uint32_t reserved_unreleased1: 1; /**< reserved for an unreleased feature */
 		uint32_t invalid_vbios_data: 1; /**< 1 if VBIOS data table is invalid */
-		uint32_t reserved : 23; /**< reserved */
+		uint32_t reserved_unreleased2: 1; /**< reserved for an unreleased feature */
+		uint32_t reserved : 22; /**< reserved */
 	} bits; /**< boot bits */
 	uint32_t all; /**< 32-bit access to bits */
 };
-- 
2.25.1


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

* [PATCH 15/18] drm/amd/display: Fix null pointer dereference for encoders
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (13 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 14/18] drm/amd/display: Creating a fw boot options bit for an upcoming feature Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 16/18] drm/amd/display: [FW Promotion] Release 0.0.84 Rodrigo Siqueira
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Jimmy Kizito,
	Aric Cyr, Meenakshikumar Somasundaram

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Links which are dynamically assigned link encoders have their link
encoder set to NULL.

[How]
Check that a pointer to a link_encoder object is non-NULL before using
it.

Reviewed-by: Aric Cyr <aric.cyr@amd.com>
Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c          | 2 +-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 938bfd8761d1..d6454d80311e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -5684,7 +5684,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready)
 				link_enc->funcs->fec_set_ready(link_enc, true);
 				link->fec_state = dc_link_fec_ready;
 			} else {
-				link_enc->funcs->fec_set_ready(link->link_enc, false);
+				link_enc->funcs->fec_set_ready(link_enc, false);
 				link->fec_state = dc_link_fec_not_ready;
 				dm_error("dpcd write failed to set fec_ready");
 			}
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 e1edbfa761f1..c5e2b4f138fd 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
@@ -1587,7 +1587,7 @@ void dcn10_power_down_on_boot(struct dc *dc)
 		for (i = 0; i < dc->link_count; i++) {
 			struct dc_link *link = dc->links[i];
 
-			if (link->link_enc->funcs->is_dig_enabled &&
+			if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
 					link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
 					dc->hwss.power_down) {
 				dc->hwss.power_down(dc);
-- 
2.25.1


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

* [PATCH 16/18] drm/amd/display: [FW Promotion] Release 0.0.84
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (14 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 15/18] drm/amd/display: Fix null pointer dereference for encoders Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 17/18] drm/amd/display: 3.2.154 Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 18/18] drm/amd/display: Fix wrong format specifier in amdgpu_dm.c Rodrigo Siqueira
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Anthony Koo

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

Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
---
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 1b377364ace7..359f091e37f1 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -47,10 +47,10 @@
 
 /* Firmware versioning. */
 #ifdef DMUB_EXPOSE_VERSION
-#define DMUB_FW_VERSION_GIT_HASH 0xb24cbe3d
+#define DMUB_FW_VERSION_GIT_HASH 0x607c9623
 #define DMUB_FW_VERSION_MAJOR 0
 #define DMUB_FW_VERSION_MINOR 0
-#define DMUB_FW_VERSION_REVISION 83
+#define DMUB_FW_VERSION_REVISION 84
 #define DMUB_FW_VERSION_TEST 0
 #define DMUB_FW_VERSION_VBIOS 0
 #define DMUB_FW_VERSION_HOTFIX 0
-- 
2.25.1


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

* [PATCH 17/18] drm/amd/display: 3.2.154
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (15 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 16/18] drm/amd/display: [FW Promotion] Release 0.0.84 Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  2021-09-17 19:25 ` [PATCH 18/18] drm/amd/display: Fix wrong format specifier in amdgpu_dm.c Rodrigo Siqueira
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, Aric Cyr

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

This new DC version brings improvements in the following areas:
- New firmware version
- Fix HPD problems on DCN2
- Fix generic encoder problems and null deferences
- Adjust DCN301 watermark
- Rework dynamic bpp for DCN3x
- Improve link training fallback logic

Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@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 1306dedc1a98..e5dcbee6e672 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -45,7 +45,7 @@
 /* forward declaration */
 struct aux_payload;
 
-#define DC_VER "3.2.153"
+#define DC_VER "3.2.154"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.25.1


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

* [PATCH 18/18] drm/amd/display: Fix wrong format specifier in amdgpu_dm.c
  2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
                   ` (16 preceding siblings ...)
  2021-09-17 19:25 ` [PATCH 17/18] drm/amd/display: 3.2.154 Rodrigo Siqueira
@ 2021-09-17 19:25 ` Rodrigo Siqueira
  17 siblings, 0 replies; 19+ messages in thread
From: Rodrigo Siqueira @ 2021-09-17 19:25 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu,
	Hayden Goodfellow

From: Hayden Goodfellow <Hayden.Goodfellow@amd.com>

[Why]
Currently, the 32bit kernel build fails due to an incorrect string
format specifier. ARRAY_SIZE() returns size_t type as it uses sizeof().
However, we specify it in a string as %ld. This causes a compiler error
and causes the 32bit build to fail.

[How]
Change the %ld to %zu as size_t (which sizeof() returns) is an unsigned
integer data type. We use 'z' to ensure it also works with 64bit build.

Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Hayden Goodfellow <Hayden.Goodfellow@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 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 85d1304b8236..9da46fe12498 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -760,7 +760,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
 			do {
 				dc_stat_get_dmub_notification(adev->dm.dc, &notify);
 				if (notify.type > ARRAY_SIZE(dm->dmub_thread_offload)) {
-					DRM_ERROR("DM: notify type %d larger than the array size %ld !", notify.type,
+					DRM_ERROR("DM: notify type %d larger than the array size %zu!", notify.type,
 					ARRAY_SIZE(dm->dmub_thread_offload));
 					continue;
 				}
-- 
2.25.1


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

end of thread, other threads:[~2021-09-17 19:26 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-17 19:25 [PATCH 00/18] DC Patches September 17, 2021 Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 01/18] drm/amd/display: Extend w/a for hard hang on HPD to dcn20 Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 02/18] drm/amd/display: [FW Promotion] Release 0.0.83 Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 03/18] drm/amd/display: 3.2.153 Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 04/18] drm/amd/display: Fix DCN3 B0 DP Alt Mapping Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 05/18] drm/amd/display: Fix link training fallback logic Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 06/18] drm/amd/display: Fix concurrent dynamic encoder assignment Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 07/18] drm/amd/display: Fix dynamic encoder reassignment Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 08/18] drm/amd/display: Added power down on boot for DCN3 Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 09/18] drm/amd/display: Use adjusted DCN301 watermarks Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 10/18] drm/amd/display: Fix issue with dynamic bpp change for DCN3x Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 11/18] drm/amd/display: Disable mem low power for CM HW block on DCN3.1 Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 12/18] drm/amd/display: Fix B0 USB-C DP Alt mode Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 13/18] drm/amd/display: DIG mapping change is causing a blocker Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 14/18] drm/amd/display: Creating a fw boot options bit for an upcoming feature Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 15/18] drm/amd/display: Fix null pointer dereference for encoders Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 16/18] drm/amd/display: [FW Promotion] Release 0.0.84 Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 17/18] drm/amd/display: 3.2.154 Rodrigo Siqueira
2021-09-17 19:25 ` [PATCH 18/18] drm/amd/display: Fix wrong format specifier in amdgpu_dm.c Rodrigo Siqueira

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.