]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.3
authorSasha Levin <sashal@kernel.org>
Mon, 15 May 2023 01:42:06 +0000 (21:42 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 15 May 2023 01:42:06 +0000 (21:42 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.3/drm-amd-display-add-minimum-z8-residency-debug-optio.patch [new file with mode: 0644]
queue-6.3/drm-amd-display-hpd-rx-irq-not-working-with-edp-inte.patch [new file with mode: 0644]
queue-6.3/drm-amd-display-lowering-min-z8-residency-time.patch [new file with mode: 0644]
queue-6.3/drm-amd-display-merge-dc_link.h-into-dc.h-and-dc_typ.patch [new file with mode: 0644]
queue-6.3/drm-amd-display-update-minimum-stutter-residency-for.patch [new file with mode: 0644]
queue-6.3/drm-i915-add-_pick_even_2ranges.patch [new file with mode: 0644]
queue-6.3/drm-i915-disable-sampler-indirect-state-in-bindless-.patch [new file with mode: 0644]
queue-6.3/drm-i915-mtl-add-wa_14017856879.patch [new file with mode: 0644]
queue-6.3/drm-i915-mtl-add-workarounds-wa_14017066071-and-wa_1.patch [new file with mode: 0644]
queue-6.3/series

diff --git a/queue-6.3/drm-amd-display-add-minimum-z8-residency-debug-optio.patch b/queue-6.3/drm-amd-display-add-minimum-z8-residency-debug-optio.patch
new file mode 100644 (file)
index 0000000..532a09f
--- /dev/null
@@ -0,0 +1,70 @@
+From 7ce03654e704cdd33b8a4c16df43331707aafba6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Feb 2023 11:17:50 -0500
+Subject: drm/amd/display: Add minimum Z8 residency debug option
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 0db13eae41fcc67f408dbb3dfda59633c4fa03fb ]
+
+[Why]
+Allows finer control and tuning for debug and profiling.
+
+[How]
+Add the debug option into DC. The default remains the same as before
+for now.
+
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: d893f39320e1 ("drm/amd/display: Lowering min Z8 residency time")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dc.h                     | 1 +
+ drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 1 +
+ drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c    | 3 ++-
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index 84caf1f6b9e0e..3fb868f2f6f5b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -795,6 +795,7 @@ struct dc_debug_options {
+       unsigned int force_odm_combine; //bit vector based on otg inst
+       unsigned int seamless_boot_odm_combine;
+       unsigned int force_odm_combine_4to1; //bit vector based on otg inst
++      int minimum_z8_residency_time;
+       bool disable_z9_mpc;
+       unsigned int force_fclk_khz;
+       bool enable_tri_buf;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+index 9ffba4c6fe550..5c23c934c9751 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -887,6 +887,7 @@ static const struct dc_plane_cap plane_cap = {
+ static const struct dc_debug_options debug_defaults_drv = {
+       .disable_z10 = false,
+       .enable_z9_disable_interface = true,
++      .minimum_z8_residency_time = 1000,
+       .psr_skip_crtc_disable = true,
+       .disable_dmcu = true,
+       .force_abm_enable = false,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+index d3ba65efe1d2e..f3cfc144e3587 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+@@ -973,7 +973,8 @@ static enum dcn_zstate_support_state  decide_zstate_support(struct dc *dc, struc
+       else if (context->stream_count == 1 &&  context->streams[0]->signal == SIGNAL_TYPE_EDP) {
+               struct dc_link *link = context->streams[0]->sink->link;
+               struct dc_stream_status *stream_status = &context->stream_status[0];
+-              bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > 1000.0;
++              int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000;
++              bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency;
+               bool is_pwrseq0 = link->link_index == 0;
+               if (dc_extended_blank_supported(dc)) {
+-- 
+2.39.2
+
diff --git a/queue-6.3/drm-amd-display-hpd-rx-irq-not-working-with-edp-inte.patch b/queue-6.3/drm-amd-display-hpd-rx-irq-not-working-with-edp-inte.patch
new file mode 100644 (file)
index 0000000..675a9c4
--- /dev/null
@@ -0,0 +1,83 @@
+From 664f303c2e9f234a8715a31a13da2b55132f4ac0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Feb 2023 20:47:57 +0800
+Subject: drm/amd/display: hpd rx irq not working with eDP interface
+
+From: Robin Chen <robin.chen@amd.com>
+
+[ Upstream commit eeefe7c4820b6baa0462a8b723ea0a3b5846ccae ]
+
+[Why]
+This is the fix for the defect of commit ab144f0b4ad6
+("drm/amd/display: Allow individual control of eDP hotplug support").
+
+[How]
+To revise the default eDP hotplug setting and use the enum to git rid
+of the magic number for different options.
+
+Fixes: ab144f0b4ad6 ("drm/amd/display: Allow individual control of eDP hotplug support")
+Cc: stable@vger.kernel.org
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Robin Chen <robin.chen@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dc_types.h          | 7 +++++++
+ drivers/gpu/drm/amd/display/dc/link/link_factory.c | 9 +++++++--
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
+index f28b8597cc1e6..cba65766ef47b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
+@@ -1086,4 +1086,11 @@ struct dc_dpia_bw_alloc {
+ };
+ #define MAX_SINKS_PER_LINK 4
++
++enum dc_hpd_enable_select {
++      HPD_EN_FOR_ALL_EDP = 0,
++      HPD_EN_FOR_PRIMARY_EDP_ONLY,
++      HPD_EN_FOR_SECONDARY_EDP_ONLY,
++};
++
+ #endif /* DC_TYPES_H_ */
+diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+index aeb26a4d539e9..8aaf14afa4271 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
++++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+@@ -274,14 +274,18 @@ static bool dc_link_construct_phy(struct dc_link *link,
+                               link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
+                       switch (link->dc->config.allow_edp_hotplug_detection) {
+-                      case 1: // only the 1st eDP handles hotplug
++                      case HPD_EN_FOR_ALL_EDP:
++                              link->irq_source_hpd_rx =
++                                              dal_irq_get_rx_source(link->hpd_gpio);
++                              break;
++                      case HPD_EN_FOR_PRIMARY_EDP_ONLY:
+                               if (link->link_index == 0)
+                                       link->irq_source_hpd_rx =
+                                               dal_irq_get_rx_source(link->hpd_gpio);
+                               else
+                                       link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
+                               break;
+-                      case 2: // only the 2nd eDP handles hotplug
++                      case HPD_EN_FOR_SECONDARY_EDP_ONLY:
+                               if (link->link_index == 1)
+                                       link->irq_source_hpd_rx =
+                                               dal_irq_get_rx_source(link->hpd_gpio);
+@@ -289,6 +293,7 @@ static bool dc_link_construct_phy(struct dc_link *link,
+                                       link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
+                               break;
+                       default:
++                              link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
+                               break;
+                       }
+               }
+-- 
+2.39.2
+
diff --git a/queue-6.3/drm-amd-display-lowering-min-z8-residency-time.patch b/queue-6.3/drm-amd-display-lowering-min-z8-residency-time.patch
new file mode 100644 (file)
index 0000000..6a56bbf
--- /dev/null
@@ -0,0 +1,41 @@
+From 5b16d9935c404461d324662b51b3647e2e417e57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Apr 2023 10:49:38 -0400
+Subject: drm/amd/display: Lowering min Z8 residency time
+
+From: Leo Chen <sancchen@amd.com>
+
+[ Upstream commit d893f39320e1248d1c97fde0d6e51e5ea008a76b ]
+
+[Why & How]
+Per HW team request, we're lowering the minimum Z8
+residency time to 2000us. This enables Z8 support for additional
+modes we were previously blocking like 2k>60hz
+
+Cc: stable@vger.kernel.org
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Leo Chen <sancchen@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+index 33d8188d076ab..30129fb9c27a9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -887,7 +887,7 @@ static const struct dc_plane_cap plane_cap = {
+ static const struct dc_debug_options debug_defaults_drv = {
+       .disable_z10 = false,
+       .enable_z9_disable_interface = true,
+-      .minimum_z8_residency_time = 3080,
++      .minimum_z8_residency_time = 2000,
+       .psr_skip_crtc_disable = true,
+       .disable_dmcu = true,
+       .force_abm_enable = false,
+-- 
+2.39.2
+
diff --git a/queue-6.3/drm-amd-display-merge-dc_link.h-into-dc.h-and-dc_typ.patch b/queue-6.3/drm-amd-display-merge-dc_link.h-into-dc.h-and-dc_typ.patch
new file mode 100644 (file)
index 0000000..11a552a
--- /dev/null
@@ -0,0 +1,1757 @@
+From 1632799554eb11bc9cfbde13ca9d6727a97552d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 17:58:52 -0500
+Subject: drm/amd/display: merge dc_link.h into dc.h and dc_types.h
+
+From: Wenjing Liu <wenjing.liu@amd.com>
+
+[ Upstream commit 7ae1dbe6547c39410d82156c96eaa9c8cf55e87a ]
+
+[why]
+Remove the need to include dc_link.h separately. dc.h should contain
+everything needed on DM side.
+
+[How]
+Merge dc_link.h into dc.h and dc_types.h so DM only needs to include
+dc.h to use all link public functions.
+
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: eeefe7c4820b ("drm/amd/display: hpd rx irq not working with eDP interface")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   2 +-
+ .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |   2 +-
+ .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c  |   4 +-
+ drivers/gpu/drm/amd/display/dc/core/dc.c      | 156 +----
+ .../drm/amd/display/dc/core/dc_link_exports.c |  87 +++
+ drivers/gpu/drm/amd/display/dc/dc.h           | 553 +++++++++++++++++-
+ drivers/gpu/drm/amd/display/dc/dc_dp_types.h  | 107 ++++
+ drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |  14 +
+ drivers/gpu/drm/amd/display/dc/dc_types.h     | 104 ++++
+ drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c |   2 +-
+ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h |   5 +-
+ .../display/dc/dce110/dce110_hw_sequencer.c   |   2 +-
+ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |   2 +-
+ .../dc/dcn30/dcn30_dio_stream_encoder.c       |   1 +
+ .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   2 +-
+ .../dc/dcn31/dcn31_hpo_dp_link_encoder.c      |   1 -
+ .../dc/dcn31/dcn31_hpo_dp_stream_encoder.c    |   2 +-
+ .../dc/dcn32/dcn32_hpo_dp_link_encoder.c      |   1 -
+ .../drm/amd/display/dc/dcn32/dcn32_hwseq.c    |   2 +-
+ .../dc/dml/dcn30/display_mode_vba_30.c        |   1 -
+ .../dc/dml/dcn31/display_mode_vba_31.c        |   1 -
+ .../dc/dml/dcn314/display_mode_vba_314.c      |   1 -
+ .../dc/dml/dcn32/display_mode_vba_32.c        |   1 -
+ .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h |  14 -
+ .../drm/amd/display/dc/inc/hw/link_encoder.h  |  52 --
+ .../amd/display/dc/inc/hw/stream_encoder.h    |   1 -
+ drivers/gpu/drm/amd/display/dc/inc/link.h     |   1 -
+ .../display/dc/link/accessories/link_dp_cts.c |  17 -
+ .../drm/amd/display/dc/link/link_detection.c  |  99 ++++
+ .../display/dc/link/protocols/link_dp_dpia.c  |   1 -
+ .../dc/link/protocols/link_dp_dpia_bw.c       |   1 -
+ .../dc/link/protocols/link_dp_training_dpia.c |   1 -
+ .../amd/display/include/link_service_types.h  |  26 -
+ 33 files changed, 978 insertions(+), 288 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 9ed2854141621..cf5f7ec361b0e 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2274,7 +2274,7 @@ static int dm_late_init(void *handle)
+               struct dc_link *edp_links[MAX_NUM_EDP];
+               int edp_num;
+-              get_edp_links(adev->dm.dc, edp_links, &edp_num);
++              dc_get_edp_links(adev->dm.dc, edp_links, &edp_num);
+               for (i = 0; i < edp_num; i++) {
+                       if (!dmub_init_abm_config(adev->dm.dc->res_pool, params, i))
+                               return -EINVAL;
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+index 09a3efa517da9..4a5dae578d970 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+@@ -724,7 +724,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us
+       for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++)
+               link_training_settings.hw_lane_settings[i] = link->cur_lane_setting[i];
+-      dc_link_set_test_pattern(
++      dc_link_dp_set_test_pattern(
+               link,
+               test_pattern,
+               DP_TEST_PATTERN_COLOR_SPACE_RGB,
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+index 69691daf4dbbd..73a45ec27f90d 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+@@ -104,7 +104,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
+       int edp_num;
+       unsigned int panel_inst;
+-      get_edp_links(dc, edp_links, &edp_num);
++      dc_get_edp_links(dc, edp_links, &edp_num);
+       if (dc->hwss.exit_optimized_pwr_state)
+               dc->hwss.exit_optimized_pwr_state(dc, dc->current_state);
+@@ -129,7 +129,7 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
+       int edp_num;
+       unsigned int panel_inst;
+-      get_edp_links(dc, edp_links, &edp_num);
++      dc_get_edp_links(dc, edp_links, &edp_num);
+       if (edp_num) {
+               for (panel_inst = 0; panel_inst < edp_num; panel_inst++) {
+                       edp_link = edp_links[panel_inst];
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 1c218c5266509..d406d7b74c6c3 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -53,7 +53,6 @@
+ #include "link_encoder.h"
+ #include "link_enc_cfg.h"
+-#include "dc_link.h"
+ #include "link.h"
+ #include "dm_helpers.h"
+ #include "mem_input.h"
+@@ -1298,7 +1297,7 @@ static void detect_edp_presence(struct dc *dc)
+       int i;
+       int edp_num;
+-      get_edp_links(dc, edp_links, &edp_num);
++      dc_get_edp_links(dc, edp_links, &edp_num);
+       if (!edp_num)
+               return;
+@@ -4317,157 +4316,6 @@ bool dc_is_dmcu_initialized(struct dc *dc)
+       return false;
+ }
+-bool dc_is_oem_i2c_device_present(
+-      struct dc *dc,
+-      size_t slave_address)
+-{
+-      if (dc->res_pool->oem_device)
+-              return dce_i2c_oem_device_present(
+-                      dc->res_pool,
+-                      dc->res_pool->oem_device,
+-                      slave_address);
+-
+-      return false;
+-}
+-
+-bool dc_submit_i2c(
+-              struct dc *dc,
+-              uint32_t link_index,
+-              struct i2c_command *cmd)
+-{
+-
+-      struct dc_link *link = dc->links[link_index];
+-      struct ddc_service *ddc = link->ddc;
+-      return dce_i2c_submit_command(
+-              dc->res_pool,
+-              ddc->ddc_pin,
+-              cmd);
+-}
+-
+-bool dc_submit_i2c_oem(
+-              struct dc *dc,
+-              struct i2c_command *cmd)
+-{
+-      struct ddc_service *ddc = dc->res_pool->oem_device;
+-      if (ddc)
+-              return dce_i2c_submit_command(
+-                      dc->res_pool,
+-                      ddc->ddc_pin,
+-                      cmd);
+-
+-      return false;
+-}
+-
+-static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
+-{
+-      if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
+-              BREAK_TO_DEBUGGER();
+-              return false;
+-      }
+-
+-      dc_sink_retain(sink);
+-
+-      dc_link->remote_sinks[dc_link->sink_count] = sink;
+-      dc_link->sink_count++;
+-
+-      return true;
+-}
+-
+-/*
+- * dc_link_add_remote_sink() - Create a sink and attach it to an existing link
+- *
+- * EDID length is in bytes
+- */
+-struct dc_sink *dc_link_add_remote_sink(
+-              struct dc_link *link,
+-              const uint8_t *edid,
+-              int len,
+-              struct dc_sink_init_data *init_data)
+-{
+-      struct dc_sink *dc_sink;
+-      enum dc_edid_status edid_status;
+-
+-      if (len > DC_MAX_EDID_BUFFER_SIZE) {
+-              dm_error("Max EDID buffer size breached!\n");
+-              return NULL;
+-      }
+-
+-      if (!init_data) {
+-              BREAK_TO_DEBUGGER();
+-              return NULL;
+-      }
+-
+-      if (!init_data->link) {
+-              BREAK_TO_DEBUGGER();
+-              return NULL;
+-      }
+-
+-      dc_sink = dc_sink_create(init_data);
+-
+-      if (!dc_sink)
+-              return NULL;
+-
+-      memmove(dc_sink->dc_edid.raw_edid, edid, len);
+-      dc_sink->dc_edid.length = len;
+-
+-      if (!link_add_remote_sink_helper(
+-                      link,
+-                      dc_sink))
+-              goto fail_add_sink;
+-
+-      edid_status = dm_helpers_parse_edid_caps(
+-                      link,
+-                      &dc_sink->dc_edid,
+-                      &dc_sink->edid_caps);
+-
+-      /*
+-       * Treat device as no EDID device if EDID
+-       * parsing fails
+-       */
+-      if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) {
+-              dc_sink->dc_edid.length = 0;
+-              dm_error("Bad EDID, status%d!\n", edid_status);
+-      }
+-
+-      return dc_sink;
+-
+-fail_add_sink:
+-      dc_sink_release(dc_sink);
+-      return NULL;
+-}
+-
+-/*
+- * dc_link_remove_remote_sink() - Remove a remote sink from a dc_link
+- *
+- * Note that this just removes the struct dc_sink - it doesn't
+- * program hardware or alter other members of dc_link
+- */
+-void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
+-{
+-      int i;
+-
+-      if (!link->sink_count) {
+-              BREAK_TO_DEBUGGER();
+-              return;
+-      }
+-
+-      for (i = 0; i < link->sink_count; i++) {
+-              if (link->remote_sinks[i] == sink) {
+-                      dc_sink_release(sink);
+-                      link->remote_sinks[i] = NULL;
+-
+-                      /* shrink array to remove empty place */
+-                      while (i < link->sink_count - 1) {
+-                              link->remote_sinks[i] = link->remote_sinks[i+1];
+-                              i++;
+-                      }
+-                      link->remote_sinks[i] = NULL;
+-                      link->sink_count--;
+-                      return;
+-              }
+-      }
+-}
+-
+ void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info)
+ {
+       info->displayClock                              = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz;
+@@ -4990,7 +4838,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo
+               return;
+       }
+-      get_edp_links(dc, edp_links, &edp_num);
++      dc_get_edp_links(dc, edp_links, &edp_num);
+       /* Determine panel inst */
+       for (i = 0; i < edp_num; i++) {
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
+index a951e10416ee6..862cb0f93b7d9 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
+@@ -34,6 +34,49 @@
+  * in this file which calls link functions.
+  */
+ #include "link.h"
++#include "dce/dce_i2c.h"
++struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index)
++{
++      return dc->links[link_index];
++}
++
++void dc_get_edp_links(const struct dc *dc,
++              struct dc_link **edp_links,
++              int *edp_num)
++{
++      int i;
++
++      *edp_num = 0;
++      for (i = 0; i < dc->link_count; i++) {
++              // report any eDP links, even unconnected DDI's
++              if (!dc->links[i])
++                      continue;
++              if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) {
++                      edp_links[*edp_num] = dc->links[i];
++                      if (++(*edp_num) == MAX_NUM_EDP)
++                              return;
++              }
++      }
++}
++
++bool dc_get_edp_link_panel_inst(const struct dc *dc,
++              const struct dc_link *link,
++              unsigned int *inst_out)
++{
++      struct dc_link *edp_links[MAX_NUM_EDP];
++      int edp_num, i;
++
++      *inst_out = 0;
++      if (link->connector_signal != SIGNAL_TYPE_EDP)
++              return false;
++      dc_get_edp_links(dc, edp_links, &edp_num);
++      for (i = 0; i < edp_num; i++) {
++              if (link == edp_links[i])
++                      break;
++              (*inst_out)++;
++      }
++      return true;
++}
+ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
+ {
+@@ -101,3 +144,47 @@ bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx)
+ {
+       return link_update_dsc_config(pipe_ctx);
+ }
++
++bool dc_is_oem_i2c_device_present(
++      struct dc *dc,
++      size_t slave_address)
++{
++      if (dc->res_pool->oem_device)
++              return dce_i2c_oem_device_present(
++                      dc->res_pool,
++                      dc->res_pool->oem_device,
++                      slave_address);
++
++      return false;
++}
++
++bool dc_submit_i2c(
++              struct dc *dc,
++              uint32_t link_index,
++              struct i2c_command *cmd)
++{
++
++      struct dc_link *link = dc->links[link_index];
++      struct ddc_service *ddc = link->ddc;
++
++      return dce_i2c_submit_command(
++              dc->res_pool,
++              ddc->ddc_pin,
++              cmd);
++}
++
++bool dc_submit_i2c_oem(
++              struct dc *dc,
++              struct i2c_command *cmd)
++{
++      struct ddc_service *ddc = dc->res_pool->oem_device;
++
++      if (ddc)
++              return dce_i2c_submit_command(
++                      dc->res_pool,
++                      ddc->ddc_pin,
++                      cmd);
++
++      return false;
++}
++
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index 1fde433786894..84caf1f6b9e0e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -1379,8 +1379,159 @@ struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc,
+ uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
+ /* Link Interfaces */
+-/* TODO: remove this after resolving external dependencies */
+-#include "dc_link.h"
++/*
++ * A link contains one or more sinks and their connected status.
++ * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
++ */
++struct dc_link {
++      struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK];
++      unsigned int sink_count;
++      struct dc_sink *local_sink;
++      unsigned int link_index;
++      enum dc_connection_type type;
++      enum signal_type connector_signal;
++      enum dc_irq_source irq_source_hpd;
++      enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse  */
++
++      bool is_hpd_filter_disabled;
++      bool dp_ss_off;
++
++      /**
++       * @link_state_valid:
++       *
++       * If there is no link and local sink, this variable should be set to
++       * false. Otherwise, it should be set to true; usually, the function
++       * core_link_enable_stream sets this field to true.
++       */
++      bool link_state_valid;
++      bool aux_access_disabled;
++      bool sync_lt_in_progress;
++      bool skip_stream_reenable;
++      bool is_internal_display;
++      /** @todo Rename. Flag an endpoint as having a programmable mapping to a DIG encoder. */
++      bool is_dig_mapping_flexible;
++      bool hpd_status; /* HPD status of link without physical HPD pin. */
++      bool is_hpd_pending; /* Indicates a new received hpd */
++      bool is_automated; /* Indicates automated testing */
++
++      bool edp_sink_present;
++
++      struct dp_trace dp_trace;
++
++      /* caps is the same as reported_link_cap. link_traing use
++       * reported_link_cap. Will clean up.  TODO
++       */
++      struct dc_link_settings reported_link_cap;
++      struct dc_link_settings verified_link_cap;
++      struct dc_link_settings cur_link_settings;
++      struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX];
++      struct dc_link_settings preferred_link_setting;
++      /* preferred_training_settings are override values that
++       * come from DM. DM is responsible for the memory
++       * management of the override pointers.
++       */
++      struct dc_link_training_overrides preferred_training_settings;
++      struct dp_audio_test_data audio_test_data;
++
++      uint8_t ddc_hw_inst;
++
++      uint8_t hpd_src;
++
++      uint8_t link_enc_hw_inst;
++      /* DIG link encoder ID. Used as index in link encoder resource pool.
++       * For links with fixed mapping to DIG, this is not changed after dc_link
++       * object creation.
++       */
++      enum engine_id eng_id;
++
++      bool test_pattern_enabled;
++      union compliance_test_state compliance_test_state;
++
++      void *priv;
++
++      struct ddc_service *ddc;
++
++      bool aux_mode;
++
++      /* Private to DC core */
++
++      const struct dc *dc;
++
++      struct dc_context *ctx;
++
++      struct panel_cntl *panel_cntl;
++      struct link_encoder *link_enc;
++      struct graphics_object_id link_id;
++      /* Endpoint type distinguishes display endpoints which do not have entries
++       * in the BIOS connector table from those that do. Helps when tracking link
++       * encoder to display endpoint assignments.
++       */
++      enum display_endpoint_type ep_type;
++      union ddi_channel_mapping ddi_channel_mapping;
++      struct connector_device_tag_info device_tag;
++      struct dpcd_caps dpcd_caps;
++      uint32_t dongle_max_pix_clk;
++      unsigned short chip_caps;
++      unsigned int dpcd_sink_count;
++#if defined(CONFIG_DRM_AMD_DC_HDCP)
++      struct hdcp_caps hdcp_caps;
++#endif
++      enum edp_revision edp_revision;
++      union dpcd_sink_ext_caps dpcd_sink_ext_caps;
++
++      struct psr_settings psr_settings;
++
++      /* Drive settings read from integrated info table */
++      struct dc_lane_settings bios_forced_drive_settings;
++
++      /* Vendor specific LTTPR workaround variables */
++      uint8_t vendor_specific_lttpr_link_rate_wa;
++      bool apply_vendor_specific_lttpr_link_rate_wa;
++
++      /* MST record stream using this link */
++      struct link_flags {
++              bool dp_keep_receiver_powered;
++              bool dp_skip_DID2;
++              bool dp_skip_reset_segment;
++              bool dp_skip_fs_144hz;
++              bool dp_mot_reset_segment;
++              /* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */
++              bool dpia_mst_dsc_always_on;
++              /* Forced DPIA into TBT3 compatibility mode. */
++              bool dpia_forced_tbt3_mode;
++              bool dongle_mode_timing_override;
++      } wa_flags;
++      struct link_mst_stream_allocation_table mst_stream_alloc_table;
++
++      struct dc_link_status link_status;
++      struct dprx_states dprx_states;
++
++      struct gpio *hpd_gpio;
++      enum dc_link_fec_state fec_state;
++      bool link_powered_externally;   // Used to bypass hardware sequencing delays when panel is powered down forcibly
++
++      struct dc_panel_config panel_config;
++      struct phy_state phy_state;
++      // BW ALLOCATON USB4 ONLY
++      struct dc_dpia_bw_alloc dpia_bw_alloc_config;
++};
++
++/* Return an enumerated dc_link.
++ * dc_link order is constant and determined at
++ * boot time.  They cannot be created or destroyed.
++ * Use dc_get_caps() to get number of links.
++ */
++struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index);
++
++/* Return instance id of the edp link. Inst 0 is primary edp link. */
++bool dc_get_edp_link_panel_inst(const struct dc *dc,
++              const struct dc_link *link,
++              unsigned int *inst_out);
++
++/* Return an array of link pointers to edp links. */
++void dc_get_edp_links(const struct dc *dc,
++              struct dc_link **edp_links,
++              int *edp_num);
+ /* The function initiates detection handshake over the given link. It first
+  * determines if there are display connections over the link. If so it initiates
+@@ -1404,6 +1555,38 @@ uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
+  */
+ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason);
++struct dc_sink_init_data;
++
++/* When link connection type is dc_connection_mst_branch, remote sink can be
++ * added to the link. The interface creates a remote sink and associates it with
++ * current link. The sink will be retained by link until remove remote sink is
++ * called.
++ *
++ * @dc_link - link the remote sink will be added to.
++ * @edid - byte array of EDID raw data.
++ * @len - size of the edid in byte
++ * @init_data -
++ */
++struct dc_sink *dc_link_add_remote_sink(
++              struct dc_link *dc_link,
++              const uint8_t *edid,
++              int len,
++              struct dc_sink_init_data *init_data);
++
++/* Remove remote sink from a link with dc_connection_mst_branch connection type.
++ * @link - link the sink should be removed from
++ * @sink - sink to be removed.
++ */
++void dc_link_remove_remote_sink(
++      struct dc_link *link,
++      struct dc_sink *sink);
++
++/* Enable HPD interrupt handler for a given link */
++void dc_link_enable_hpd(const struct dc_link *link);
++
++/* Disable HPD interrupt handler for a given link */
++void dc_link_disable_hpd(const struct dc_link *link);
++
+ /* determine if there is a sink connected to the link
+  *
+  * @type - dc_connection_single if connected, dc_connection_none otherwise.
+@@ -1417,15 +1600,119 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason);
+ bool dc_link_detect_connection_type(struct dc_link *link,
+               enum dc_connection_type *type);
++/* query current hpd pin value
++ * return - true HPD is asserted (HPD high), false otherwise (HPD low)
++ *
++ */
++bool dc_link_get_hpd_state(struct dc_link *dc_link);
++
+ /* Getter for cached link status from given link */
+ const struct dc_link_status *dc_link_get_status(const struct dc_link *link);
++/* enable/disable hardware HPD filter.
++ *
++ * @link - The link the HPD pin is associated with.
++ * @enable = true - enable hardware HPD filter. HPD event will only queued to irq
++ * handler once after no HPD change has been detected within dc default HPD
++ * filtering interval since last HPD event. i.e if display keeps toggling hpd
++ * pulses within default HPD interval, no HPD event will be received until HPD
++ * toggles have stopped. Then HPD event will be queued to irq handler once after
++ * dc default HPD filtering interval since last HPD event.
++ *
++ * @enable = false - disable hardware HPD filter. HPD event will be queued
++ * immediately to irq handler after no HPD change has been detected within
++ * IRQ_HPD (aka HPD short pulse) interval (i.e 2ms).
++ */
++void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
++
++/* submit i2c read/write payloads through ddc channel
++ * @link_index - index to a link with ddc in i2c mode
++ * @cmd - i2c command structure
++ * return - true if success, false otherwise.
++ */
++bool dc_submit_i2c(
++              struct dc *dc,
++              uint32_t link_index,
++              struct i2c_command *cmd);
++
++/* submit i2c read/write payloads through oem channel
++ * @link_index - index to a link with ddc in i2c mode
++ * @cmd - i2c command structure
++ * return - true if success, false otherwise.
++ */
++bool dc_submit_i2c_oem(
++              struct dc *dc,
++              struct i2c_command *cmd);
++
++enum aux_return_code_type;
++/* Attempt to transfer the given aux payload. This function does not perform
++ * retries or handle error states. The reply is returned in the payload->reply
++ * and the result through operation_result. Returns the number of bytes
++ * transferred,or -1 on a failure.
++ */
++int dc_link_aux_transfer_raw(struct ddc_service *ddc,
++              struct aux_payload *payload,
++              enum aux_return_code_type *operation_result);
++
++bool dc_is_oem_i2c_device_present(
++      struct dc *dc,
++      size_t slave_address
++);
++
+ #ifdef CONFIG_DRM_AMD_DC_HDCP
++
+ /* return true if the connected receiver supports the hdcp version */
+ bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal);
+ bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal);
+ #endif
++/* Notify DC about DP RX Interrupt (aka DP IRQ_HPD).
++ *
++ * TODO - When defer_handling is true the function will have a different purpose.
++ * It no longer does complete hpd rx irq handling. We should create a separate
++ * interface specifically for this case.
++ *
++ * Return:
++ * true - Downstream port status changed. DM should call DC to do the
++ * detection.
++ * false - no change in Downstream port status. No further action required
++ * from DM.
++ */
++bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link,
++              union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss,
++              bool defer_handling, bool *has_left_work);
++/* handle DP specs define test automation sequence*/
++void dc_link_dp_handle_automated_test(struct dc_link *link);
++
++/* handle DP Link loss sequence and try to recover RX link loss with best
++ * effort
++ */
++void dc_link_dp_handle_link_loss(struct dc_link *link);
++
++/* Determine if hpd rx irq should be handled or ignored
++ * return true - hpd rx irq should be handled.
++ * return false - it is safe to ignore hpd rx irq event
++ */
++bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link);
++
++/* Determine if link loss is indicated with a given hpd_irq_dpcd_data.
++ * @link - link the hpd irq data associated with
++ * @hpd_irq_dpcd_data - input hpd irq data
++ * return - true if hpd irq data indicates a link lost
++ */
++bool dc_link_check_link_loss_status(struct dc_link *link,
++              union hpd_irq_data *hpd_irq_dpcd_data);
++
++/* Read hpd rx irq data from a given link
++ * @link - link where the hpd irq data should be read from
++ * @irq_data - output hpd irq data
++ * return - DC_OK if hpd irq data is read successfully, otherwise hpd irq data
++ * read has failed.
++ */
++enum dc_status dc_link_dp_read_hpd_rx_irq_data(
++      struct dc_link *link,
++      union hpd_irq_data *irq_data);
++
+ /* The function clears recorded DP RX states in the link. DM should call this
+  * function when it is resuming from S3 power state to previously connected links.
+  *
+@@ -1493,6 +1780,268 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);
+  * interface i.e stream_update->dsc_config
+  */
+ bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx);
++
++/* translate a raw link rate data to bandwidth in kbps */
++uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw);
++
++/* determine the optimal bandwidth given link and required bw.
++ * @link - current detected link
++ * @req_bw - requested bandwidth in kbps
++ * @link_settings - returned most optimal link settings that can fit the
++ * requested bandwidth
++ * return - false if link can't support requested bandwidth, true if link
++ * settings is found.
++ */
++bool dc_link_decide_edp_link_settings(struct dc_link *link,
++              struct dc_link_settings *link_settings,
++              uint32_t req_bw);
++
++/* return the max dp link settings can be driven by the link without considering
++ * connected RX device and its capability
++ */
++bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link,
++              struct dc_link_settings *max_link_enc_cap);
++
++/* determine when the link is driving MST mode, what DP link channel coding
++ * format will be used. The decision will remain unchanged until next HPD event.
++ *
++ * @link -  a link with DP RX connection
++ * return - if stream is committed to this link with MST signal type, type of
++ * channel coding format dc will choose.
++ */
++enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(
++              const struct dc_link *link);
++
++/* get max dp link settings the link can enable with all things considered. (i.e
++ * TX/RX/Cable capabilities and dp override policies.
++ *
++ * @link - a link with DP RX connection
++ * return - max dp link settings the link can enable.
++ *
++ */
++const struct dc_link_settings *dc_link_get_link_cap(const struct dc_link *link);
++
++/* Check if a RX (ex. DP sink, MST hub, passive or active dongle) is connected
++ * to a link with dp connector signal type.
++ * @link - a link with dp connector signal type
++ * return - true if connected, false otherwise
++ */
++bool dc_link_is_dp_sink_present(struct dc_link *link);
++
++/* Force DP lane settings update to main-link video signal and notify the change
++ * to DP RX via DPCD. This is a debug interface used for video signal integrity
++ * tuning purpose. The interface assumes link has already been enabled with DP
++ * signal.
++ *
++ * @lt_settings - a container structure with desired hw_lane_settings
++ */
++void dc_link_set_drive_settings(struct dc *dc,
++                              struct link_training_settings *lt_settings,
++                              const struct dc_link *link);
++
++/* Enable a test pattern in Link or PHY layer in an active link for compliance
++ * test or debugging purpose. The test pattern will remain until next un-plug.
++ *
++ * @link - active link with DP signal output enabled.
++ * @test_pattern - desired test pattern to output.
++ * NOTE: set to DP_TEST_PATTERN_VIDEO_MODE to disable previous test pattern.
++ * @test_pattern_color_space - for video test pattern choose a desired color
++ * space.
++ * @p_link_settings - For PHY pattern choose a desired link settings
++ * @p_custom_pattern - some test pattern will require a custom input to
++ * customize some pattern details. Otherwise keep it to NULL.
++ * @cust_pattern_size - size of the custom pattern input.
++ *
++ */
++bool dc_link_dp_set_test_pattern(
++      struct dc_link *link,
++      enum dp_test_pattern test_pattern,
++      enum dp_test_pattern_color_space test_pattern_color_space,
++      const struct link_training_settings *p_link_settings,
++      const unsigned char *p_custom_pattern,
++      unsigned int cust_pattern_size);
++
++/* Force DP link settings to always use a specific value until reboot to a
++ * specific link. If link has already been enabled, the interface will also
++ * switch to desired link settings immediately. This is a debug interface to
++ * generic dp issue trouble shooting.
++ */
++void dc_link_set_preferred_link_settings(struct dc *dc,
++              struct dc_link_settings *link_setting,
++              struct dc_link *link);
++
++/* Force DP link to customize a specific link training behavior by overriding to
++ * standard DP specs defined protocol. This is a debug interface to trouble shoot
++ * display specific link training issues or apply some display specific
++ * workaround in link training.
++ *
++ * @link_settings - if not NULL, force preferred link settings to the link.
++ * @lt_override - a set of override pointers. If any pointer is none NULL, dc
++ * will apply this particular override in future link training. If NULL is
++ * passed in, dc resets previous overrides.
++ * NOTE: DM must keep the memory from override pointers until DM resets preferred
++ * training settings.
++ */
++void dc_link_set_preferred_training_settings(struct dc *dc,
++              struct dc_link_settings *link_setting,
++              struct dc_link_training_overrides *lt_overrides,
++              struct dc_link *link,
++              bool skip_immediate_retrain);
++
++/* return - true if FEC is supported with connected DP RX, false otherwise */
++bool dc_link_is_fec_supported(const struct dc_link *link);
++
++/* query FEC enablement policy to determine if FEC will be enabled by dc during
++ * link enablement.
++ * return - true if FEC should be enabled, false otherwise.
++ */
++bool dc_link_should_enable_fec(const struct dc_link *link);
++
++/* determine lttpr mode the current link should be enabled with a specific link
++ * settings.
++ */
++enum lttpr_mode dc_link_decide_lttpr_mode(struct dc_link *link,
++              struct dc_link_settings *link_setting);
++
++/* Force DP RX to update its power state.
++ * NOTE: this interface doesn't update dp main-link. Calling this function will
++ * cause DP TX main-link and DP RX power states out of sync. DM has to restore
++ * RX power state back upon finish DM specific execution requiring DP RX in a
++ * specific power state.
++ * @on - true to set DP RX in D0 power state, false to set DP RX in D3 power
++ * state.
++ */
++void dc_link_dp_receiver_power_ctrl(struct dc_link *link, bool on);
++
++/* Force link to read base dp receiver caps from dpcd 000h - 00Fh and overwrite
++ * current value read from extended receiver cap from 02200h - 0220Fh.
++ * Some DP RX has problems of providing accurate DP receiver caps from extended
++ * field, this interface is a workaround to revert link back to use base caps.
++ */
++void dc_link_overwrite_extended_receiver_cap(
++              struct dc_link *link);
++
++void dc_link_edp_panel_backlight_power_on(struct dc_link *link,
++              bool wait_for_hpd);
++
++/* Set backlight level of an embedded panel (eDP, LVDS).
++ * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer
++ * and 16 bit fractional, where 1.0 is max backlight value.
++ */
++bool dc_link_set_backlight_level(const struct dc_link *dc_link,
++              uint32_t backlight_pwm_u16_16,
++              uint32_t frame_ramp);
++
++/* Set/get nits-based backlight level of an embedded panel (eDP, LVDS). */
++bool dc_link_set_backlight_level_nits(struct dc_link *link,
++              bool isHDR,
++              uint32_t backlight_millinits,
++              uint32_t transition_time_in_ms);
++
++bool dc_link_get_backlight_level_nits(struct dc_link *link,
++              uint32_t *backlight_millinits,
++              uint32_t *backlight_millinits_peak);
++
++int dc_link_get_backlight_level(const struct dc_link *dc_link);
++
++int dc_link_get_target_backlight_pwm(const struct dc_link *link);
++
++bool dc_link_set_psr_allow_active(struct dc_link *dc_link, const bool *enable,
++              bool wait, bool force_static, const unsigned int *power_opts);
++
++bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state);
++
++bool dc_link_setup_psr(struct dc_link *dc_link,
++              const struct dc_stream_state *stream, struct psr_config *psr_config,
++              struct psr_context *psr_context);
++
++/* On eDP links this function call will stall until T12 has elapsed.
++ * If the panel is not in power off state, this function will return
++ * immediately.
++ */
++bool dc_link_wait_for_t12(struct dc_link *link);
++
++/* Determine if dp trace has been initialized to reflect upto date result *
++ * return - true if trace is initialized and has valid data. False dp trace
++ * doesn't have valid result.
++ */
++bool dc_dp_trace_is_initialized(struct dc_link *link);
++
++/* Query a dp trace flag to indicate if the current dp trace data has been
++ * logged before
++ */
++bool dc_dp_trace_is_logged(struct dc_link *link,
++              bool in_detection);
++
++/* Set dp trace flag to indicate whether DM has already logged the current dp
++ * trace data. DM can set is_logged to true upon logging and check
++ * dc_dp_trace_is_logged before logging to avoid logging the same result twice.
++ */
++void dc_dp_trace_set_is_logged_flag(struct dc_link *link,
++              bool in_detection,
++              bool is_logged);
++
++/* Obtain driver time stamp for last dp link training end. The time stamp is
++ * formatted based on dm_get_timestamp DM function.
++ * @in_detection - true to get link training end time stamp of last link
++ * training in detection sequence. false to get link training end time stamp
++ * of last link training in commit (dpms) sequence
++ */
++unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link,
++              bool in_detection);
++
++/* Get how many link training attempts dc has done with latest sequence.
++ * @in_detection - true to get link training count of last link
++ * training in detection sequence. false to get link training count of last link
++ * training in commit (dpms) sequence
++ */
++struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link,
++              bool in_detection);
++
++/* Get how many link loss has happened since last link training attempts */
++unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link);
++
++/*
++ *  USB4 DPIA BW ALLOCATION PUBLIC FUNCTIONS
++ */
++/*
++ * Send a request from DP-Tx requesting to allocate BW remotely after
++ * allocating it locally. This will get processed by CM and a CB function
++ * will be called.
++ *
++ * @link: pointer to the dc_link struct instance
++ * @req_bw: The requested bw in Kbyte to allocated
++ *
++ * return: none
++ */
++void dc_link_set_usb4_req_bw_req(struct dc_link *link, int req_bw);
++
++/*
++ * Handle function for when the status of the Request above is complete.
++ * We will find out the result of allocating on CM and update structs.
++ *
++ * @link: pointer to the dc_link struct instance
++ * @bw: Allocated or Estimated BW depending on the result
++ * @result: Response type
++ *
++ * return: none
++ */
++void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link,
++              uint8_t bw, uint8_t result);
++
++/*
++ * Handle the USB4 BW Allocation related functionality here:
++ * Plug => Try to allocate max bw from timing parameters supported by the sink
++ * Unplug => de-allocate bw
++ *
++ * @link: pointer to the dc_link struct instance
++ * @peak_bw: Peak bw used by the link/sink
++ *
++ * return: allocated bw else return 0
++ */
++int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(
++              struct dc_link *link, int peak_bw);
++
+ /* Sink Interfaces - A sink corresponds to a display output device */
+ struct dc_container_id {
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+index 809a1851f1965..4bccce94d83bb 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+@@ -1261,4 +1261,111 @@ union dpcd_sink_ext_caps {
+       } bits;
+       uint8_t raw;
+ };
++
++enum dc_link_fec_state {
++      dc_link_fec_not_ready,
++      dc_link_fec_ready,
++      dc_link_fec_enabled
++};
++
++union dpcd_psr_configuration {
++      struct {
++              unsigned char ENABLE                    : 1;
++              unsigned char TRANSMITTER_ACTIVE_IN_PSR : 1;
++              unsigned char CRC_VERIFICATION          : 1;
++              unsigned char FRAME_CAPTURE_INDICATION  : 1;
++              /* For eDP 1.4, PSR v2*/
++              unsigned char LINE_CAPTURE_INDICATION   : 1;
++              /* For eDP 1.4, PSR v2*/
++              unsigned char IRQ_HPD_WITH_CRC_ERROR    : 1;
++              unsigned char ENABLE_PSR2               : 1;
++              unsigned char EARLY_TRANSPORT_ENABLE    : 1;
++      } bits;
++      unsigned char raw;
++};
++
++union dpcd_alpm_configuration {
++      struct {
++              unsigned char ENABLE                    : 1;
++              unsigned char IRQ_HPD_ENABLE            : 1;
++              unsigned char RESERVED                  : 6;
++      } bits;
++      unsigned char raw;
++};
++
++union dpcd_sink_active_vtotal_control_mode {
++      struct {
++              unsigned char ENABLE                    : 1;
++              unsigned char RESERVED                  : 7;
++      } bits;
++      unsigned char raw;
++};
++
++union psr_error_status {
++      struct {
++              unsigned char LINK_CRC_ERROR        :1;
++              unsigned char RFB_STORAGE_ERROR     :1;
++              unsigned char VSC_SDP_ERROR         :1;
++              unsigned char RESERVED              :5;
++      } bits;
++      unsigned char raw;
++};
++
++union psr_sink_psr_status {
++      struct {
++      unsigned char SINK_SELF_REFRESH_STATUS  :3;
++      unsigned char RESERVED                  :5;
++      } bits;
++      unsigned char raw;
++};
++
++struct edp_trace_power_timestamps {
++      uint64_t poweroff;
++      uint64_t poweron;
++};
++
++struct dp_trace_lt_counts {
++      unsigned int total;
++      unsigned int fail;
++};
++
++enum link_training_result {
++      LINK_TRAINING_SUCCESS,
++      LINK_TRAINING_CR_FAIL_LANE0,
++      LINK_TRAINING_CR_FAIL_LANE1,
++      LINK_TRAINING_CR_FAIL_LANE23,
++      /* CR DONE bit is cleared during EQ step */
++      LINK_TRAINING_EQ_FAIL_CR,
++      /* CR DONE bit is cleared but LANE0_CR_DONE is set during EQ step */
++      LINK_TRAINING_EQ_FAIL_CR_PARTIAL,
++      /* other failure during EQ step */
++      LINK_TRAINING_EQ_FAIL_EQ,
++      LINK_TRAINING_LQA_FAIL,
++      /* one of the CR,EQ or symbol lock is dropped */
++      LINK_TRAINING_LINK_LOSS,
++      /* Abort link training (because sink unplugged) */
++      LINK_TRAINING_ABORT,
++      DP_128b_132b_LT_FAILED,
++      DP_128b_132b_MAX_LOOP_COUNT_REACHED,
++      DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT,
++      DP_128b_132b_CDS_DONE_TIMEOUT,
++};
++
++struct dp_trace_lt {
++      struct dp_trace_lt_counts counts;
++      struct dp_trace_timestamps {
++              unsigned long long start;
++              unsigned long long end;
++      } timestamps;
++      enum link_training_result result;
++      bool is_logged;
++};
++
++struct dp_trace {
++      struct dp_trace_lt detect_lt_trace;
++      struct dp_trace_lt commit_lt_trace;
++      unsigned int link_loss_count;
++      bool is_initialized;
++      struct edp_trace_power_timestamps edp_trace_power_timestamps;
++};
+ #endif /* DC_DP_TYPES_H */
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+index cc3d6fb393640..a583a72845fe8 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+@@ -1085,5 +1085,19 @@ struct tg_color {
+       uint16_t color_b_cb;
+ };
++enum symclk_state {
++      SYMCLK_OFF_TX_OFF,
++      SYMCLK_ON_TX_ON,
++      SYMCLK_ON_TX_OFF,
++};
++
++struct phy_state {
++      struct {
++              uint8_t otg             : 1;
++              uint8_t reserved        : 7;
++      } symclk_ref_cnts;
++      enum symclk_state symclk_state;
++};
++
+ #endif /* DC_HW_TYPES_H */
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
+index 27d0242d6cbd4..f28b8597cc1e6 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
+@@ -38,6 +38,7 @@
+ #include "dc_hw_types.h"
+ #include "dal_types.h"
+ #include "grph_object_defs.h"
++#include "grph_object_ctrl_defs.h"
+ #ifdef CONFIG_DRM_AMD_DC_HDCP
+ #include "dm_cp_psp.h"
+@@ -982,4 +983,107 @@ struct hdcp_caps {
+       union hdcp_bcaps bcaps;
+ };
+ #endif
++
++/* DP MST stream allocation (payload bandwidth number) */
++struct link_mst_stream_allocation {
++      /* DIG front */
++      const struct stream_encoder *stream_enc;
++      /* HPO DP Stream Encoder */
++      const struct hpo_dp_stream_encoder *hpo_dp_stream_enc;
++      /* associate DRM payload table with DC stream encoder */
++      uint8_t vcp_id;
++      /* number of slots required for the DP stream in transport packet */
++      uint8_t slot_count;
++};
++
++#define MAX_CONTROLLER_NUM 6
++
++/* DP MST stream allocation table */
++struct link_mst_stream_allocation_table {
++      /* number of DP video streams */
++      int stream_count;
++      /* array of stream allocations */
++      struct link_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM];
++};
++
++/* PSR feature flags */
++struct psr_settings {
++      bool psr_feature_enabled;               // PSR is supported by sink
++      bool psr_allow_active;                  // PSR is currently active
++      enum dc_psr_version psr_version;                // Internal PSR version, determined based on DPCD
++      bool psr_vtotal_control_support;        // Vtotal control is supported by sink
++      unsigned long long psr_dirty_rects_change_timestamp_ns; // for delay of enabling PSR-SU
++
++      /* These parameters are calculated in Driver,
++       * based on display timing and Sink capabilities.
++       * If VBLANK region is too small and Sink takes a long time
++       * to set up RFB, it may take an extra frame to enter PSR state.
++       */
++      bool psr_frame_capture_indication_req;
++      unsigned int psr_sdp_transmit_line_num_deadline;
++      uint8_t force_ffu_mode;
++      unsigned int psr_power_opt;
++};
++
++/* To split out "global" and "per-panel" config settings.
++ * Add a struct dc_panel_config under dc_link
++ */
++struct dc_panel_config {
++      /* extra panel power sequence parameters */
++      struct pps {
++              unsigned int extra_t3_ms;
++              unsigned int extra_t7_ms;
++              unsigned int extra_delay_backlight_off;
++              unsigned int extra_post_t7_ms;
++              unsigned int extra_pre_t11_ms;
++              unsigned int extra_t12_ms;
++              unsigned int extra_post_OUI_ms;
++      } pps;
++      /* nit brightness */
++      struct nits_brightness {
++              unsigned int peak; /* nits */
++              unsigned int max_avg; /* nits */
++              unsigned int min; /* 1/10000 nits */
++              unsigned int max_nonboost_brightness_millinits;
++              unsigned int min_brightness_millinits;
++      } nits_brightness;
++      /* PSR */
++      struct psr {
++              bool disable_psr;
++              bool disallow_psrsu;
++              bool rc_disable;
++              bool rc_allow_static_screen;
++              bool rc_allow_fullscreen_VPB;
++      } psr;
++      /* ABM */
++      struct varib {
++              unsigned int varibright_feature_enable;
++              unsigned int def_varibright_level;
++              unsigned int abm_config_setting;
++      } varib;
++      /* edp DSC */
++      struct dsc {
++              bool disable_dsc_edp;
++              unsigned int force_dsc_edp_policy;
++      } dsc;
++      /* eDP ILR */
++      struct ilr {
++              bool optimize_edp_link_rate; /* eDP ILR */
++      } ilr;
++};
++
++/*
++ *  USB4 DPIA BW ALLOCATION STRUCTS
++ */
++struct dc_dpia_bw_alloc {
++      int sink_verified_bw;  // The Verified BW that sink can allocated and use that has been verified already
++      int sink_allocated_bw; // The Actual Allocated BW that sink currently allocated
++      int sink_max_bw;       // The Max BW that sink can require/support
++      int estimated_bw;      // The estimated available BW for this DPIA
++      int bw_granularity;    // BW Granularity
++      bool bw_alloc_enabled; // The BW Alloc Mode Support is turned ON for all 3:  DP-Tx & Dpia & CM
++      bool response_ready;   // Response ready from the CM side
++};
++
++#define MAX_SINKS_PER_LINK 4
+ #endif /* DC_TYPES_H_ */
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
+index fb0dec4ed3a6c..9fc48208c2e42 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
+@@ -148,7 +148,7 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level)
+       int edp_num;
+       uint8_t panel_mask = 0;
+-      get_edp_links(dc->dc, edp_links, &edp_num);
++      dc_get_edp_links(dc->dc, edp_links, &edp_num);
+       for (i = 0; i < edp_num; i++) {
+               if (edp_links[i]->link_status.link_active)
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
+index 74005b9d352a2..289e42070ece9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
+@@ -26,8 +26,9 @@
+ #ifndef _DMUB_PSR_H_
+ #define _DMUB_PSR_H_
+-#include "os_types.h"
+-#include "dc_link.h"
++#include "dc_types.h"
++struct dc_link;
++struct dmub_psr_funcs;
+ struct dmub_psr {
+       struct dc_context *ctx;
+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 0d4d3d586166d..cb3bb5402c52b 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
+@@ -1739,7 +1739,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
+       get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num);
+-      get_edp_links(dc, edp_links, &edp_num);
++      dc_get_edp_links(dc, edp_links, &edp_num);
+       if (hws->funcs.init_pipes)
+               hws->funcs.init_pipes(dc, context);
+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 26c5c478fa355..e255519cb5ccc 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
+@@ -1646,7 +1646,7 @@ void dcn10_power_down_on_boot(struct dc *dc)
+       int edp_num;
+       int i = 0;
+-      get_edp_links(dc, edp_links, &edp_num);
++      dc_get_edp_links(dc, edp_links, &edp_num);
+       if (edp_num)
+               edp_link = edp_links[0];
+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 5f9079d3943a6..9d08127d209b8 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
+@@ -28,6 +28,7 @@
+ #include "dcn30_dio_stream_encoder.h"
+ #include "reg_helper.h"
+ #include "hw_shared.h"
++#include "dc.h"
+ #include "core_types.h"
+ #include <linux/delay.h>
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index df787fcf8e86e..b4df540c0c61e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -567,7 +567,7 @@ void dcn30_init_hw(struct dc *dc)
+               struct dc_link *edp_links[MAX_NUM_EDP];
+               struct dc_link *edp_link = NULL;
+-              get_edp_links(dc, edp_links, &edp_num);
++              dc_get_edp_links(dc, edp_links, &edp_num);
+               if (edp_num)
+                       edp_link = edp_links[0];
+               if (edp_link && edp_link->link_enc->funcs->is_dig_enabled &&
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c
+index 0b317ed31f918..5b7ad38f85e08 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c
+@@ -26,7 +26,6 @@
+ #include "dc_bios_types.h"
+ #include "dcn31_hpo_dp_link_encoder.h"
+ #include "reg_helper.h"
+-#include "dc_link.h"
+ #include "stream_encoder.h"
+ #define DC_LOGGER \
+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 d76f55a12eb41..0278bae50a9d6 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
+@@ -26,7 +26,7 @@
+ #include "dc_bios_types.h"
+ #include "dcn31_hpo_dp_stream_encoder.h"
+ #include "reg_helper.h"
+-#include "dc_link.h"
++#include "dc.h"
+ #define DC_LOGGER \
+               enc3->base.ctx->logger
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hpo_dp_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hpo_dp_link_encoder.c
+index 4dbad8d4b4fc2..8af01f579690f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hpo_dp_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hpo_dp_link_encoder.c
+@@ -26,7 +26,6 @@
+ #include "dcn31/dcn31_hpo_dp_link_encoder.h"
+ #include "dcn32_hpo_dp_link_encoder.h"
+ #include "reg_helper.h"
+-#include "dc_link.h"
+ #include "stream_encoder.h"
+ #define DC_LOGGER \
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index eb51f5344436c..823f29c292d05 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -828,7 +828,7 @@ void dcn32_init_hw(struct dc *dc)
+               struct dc_link *edp_links[MAX_NUM_EDP];
+               struct dc_link *edp_link;
+-              get_edp_links(dc, edp_links, &edp_num);
++              dc_get_edp_links(dc, edp_links, &edp_num);
+               if (edp_num) {
+                       for (i = 0; i < edp_num; i++) {
+                               edp_link = edp_links[i];
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+index c3d75e56410cc..899105da04335 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+@@ -25,7 +25,6 @@
+ #ifdef CONFIG_DRM_AMD_DC_DCN
+ #include "dc.h"
+-#include "dc_link.h"
+ #include "../display_mode_lib.h"
+ #include "display_mode_vba_30.h"
+ #include "../dml_inline_defs.h"
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+index 27f488405335f..2b57f5b2362a4 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+@@ -24,7 +24,6 @@
+  */
+ #include "dc.h"
+-#include "dc_link.h"
+ #include "../display_mode_lib.h"
+ #include "../dcn30/display_mode_vba_30.h"
+ #include "display_mode_vba_31.h"
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+index c843b394aeb4a..461ab6d2030e2 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+@@ -27,7 +27,6 @@
+ #define UNIT_TEST 0
+ #if !UNIT_TEST
+ #include "dc.h"
+-#include "dc_link.h"
+ #endif
+ #include "../display_mode_lib.h"
+ #include "display_mode_vba_314.h"
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index fead104a31a66..02d99b6bfe5ec 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -24,7 +24,6 @@
+  */
+ #include "dc.h"
+-#include "dc_link.h"
+ #include "../display_mode_lib.h"
+ #include "display_mode_vba_32.h"
+ #include "../dml_inline_defs.h"
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+index a819f0f97c5f3..b95ae9596c3b1 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+@@ -275,20 +275,6 @@ enum dc_lut_mode {
+       LUT_RAM_B
+ };
+-enum symclk_state {
+-      SYMCLK_OFF_TX_OFF,
+-      SYMCLK_ON_TX_ON,
+-      SYMCLK_ON_TX_OFF,
+-};
+-
+-struct phy_state {
+-      struct {
+-              uint8_t otg             : 1;
+-              uint8_t reserved        : 7;
+-      } symclk_ref_cnts;
+-      enum symclk_state symclk_state;
+-};
+-
+ /**
+  * speakersToChannels
+  *
+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 ec572a9e40547..dbe7afa9d3a22 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
+@@ -75,58 +75,6 @@ struct encoder_feature_support {
+       bool fec_supported;
+ };
+-union dpcd_psr_configuration {
+-      struct {
+-              unsigned char ENABLE                    : 1;
+-              unsigned char TRANSMITTER_ACTIVE_IN_PSR : 1;
+-              unsigned char CRC_VERIFICATION          : 1;
+-              unsigned char FRAME_CAPTURE_INDICATION  : 1;
+-              /* For eDP 1.4, PSR v2*/
+-              unsigned char LINE_CAPTURE_INDICATION   : 1;
+-              /* For eDP 1.4, PSR v2*/
+-              unsigned char IRQ_HPD_WITH_CRC_ERROR    : 1;
+-              unsigned char ENABLE_PSR2               : 1;
+-              /* For eDP 1.5, PSR v2 w/ early transport */
+-              unsigned char EARLY_TRANSPORT_ENABLE    : 1;
+-      } bits;
+-      unsigned char raw;
+-};
+-
+-union dpcd_alpm_configuration {
+-      struct {
+-              unsigned char ENABLE                    : 1;
+-              unsigned char IRQ_HPD_ENABLE            : 1;
+-              unsigned char RESERVED                  : 6;
+-      } bits;
+-      unsigned char raw;
+-};
+-
+-union dpcd_sink_active_vtotal_control_mode {
+-      struct {
+-              unsigned char ENABLE                    : 1;
+-              unsigned char RESERVED                  : 7;
+-      } bits;
+-      unsigned char raw;
+-};
+-
+-union psr_error_status {
+-      struct {
+-              unsigned char LINK_CRC_ERROR        :1;
+-              unsigned char RFB_STORAGE_ERROR     :1;
+-              unsigned char VSC_SDP_ERROR         :1;
+-              unsigned char RESERVED              :5;
+-      } bits;
+-      unsigned char raw;
+-};
+-
+-union psr_sink_psr_status {
+-      struct {
+-      unsigned char SINK_SELF_REFRESH_STATUS  :3;
+-      unsigned char RESERVED                  :5;
+-      } bits;
+-      unsigned char raw;
+-};
+-
+ struct link_encoder {
+       const struct link_encoder_funcs *funcs;
+       int32_t aux_channel_offset;
+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 bb5ad70d42662..c4fbbf08ef868 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
+@@ -30,7 +30,6 @@
+ #include "audio_types.h"
+ #include "hw_shared.h"
+-#include "dc_link.h"
+ struct dc_bios;
+ struct dc_context;
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h
+index e70fa00592236..6a346a41f07b2 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/link.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/link.h
+@@ -38,7 +38,6 @@
+  * into this file and prefix it with "link_".
+  */
+ #include "core_types.h"
+-#include "dc_link.h"
+ struct link_init_data {
+       const struct dc *dc;
+diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
+index 942300e0bd929..7f36d733bfcab 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
++++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
+@@ -1027,20 +1027,3 @@ void dc_link_set_preferred_training_settings(struct dc *dc,
+       if (skip_immediate_retrain == false)
+               dc_link_set_preferred_link_settings(dc, &link->preferred_link_setting, link);
+ }
+-
+-void dc_link_set_test_pattern(struct dc_link *link,
+-              enum dp_test_pattern test_pattern,
+-              enum dp_test_pattern_color_space test_pattern_color_space,
+-              const struct link_training_settings *p_link_settings,
+-              const unsigned char *p_custom_pattern,
+-              unsigned int cust_pattern_size)
+-{
+-      if (link != NULL)
+-              dc_link_dp_set_test_pattern(
+-                      link,
+-                      test_pattern,
+-                      test_pattern_color_space,
+-                      p_link_settings,
+-                      p_custom_pattern,
+-                      cust_pattern_size);
+-}
+diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+index f70025ef7b69e..9839ec222875a 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
++++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+@@ -1329,3 +1329,102 @@ const struct dc_link_status *link_get_status(const struct dc_link *link)
+       return &link->link_status;
+ }
++
++static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
++{
++      if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
++              BREAK_TO_DEBUGGER();
++              return false;
++      }
++
++      dc_sink_retain(sink);
++
++      dc_link->remote_sinks[dc_link->sink_count] = sink;
++      dc_link->sink_count++;
++
++      return true;
++}
++
++struct dc_sink *dc_link_add_remote_sink(
++              struct dc_link *link,
++              const uint8_t *edid,
++              int len,
++              struct dc_sink_init_data *init_data)
++{
++      struct dc_sink *dc_sink;
++      enum dc_edid_status edid_status;
++
++      if (len > DC_MAX_EDID_BUFFER_SIZE) {
++              dm_error("Max EDID buffer size breached!\n");
++              return NULL;
++      }
++
++      if (!init_data) {
++              BREAK_TO_DEBUGGER();
++              return NULL;
++      }
++
++      if (!init_data->link) {
++              BREAK_TO_DEBUGGER();
++              return NULL;
++      }
++
++      dc_sink = dc_sink_create(init_data);
++
++      if (!dc_sink)
++              return NULL;
++
++      memmove(dc_sink->dc_edid.raw_edid, edid, len);
++      dc_sink->dc_edid.length = len;
++
++      if (!link_add_remote_sink_helper(
++                      link,
++                      dc_sink))
++              goto fail_add_sink;
++
++      edid_status = dm_helpers_parse_edid_caps(
++                      link,
++                      &dc_sink->dc_edid,
++                      &dc_sink->edid_caps);
++
++      /*
++       * Treat device as no EDID device if EDID
++       * parsing fails
++       */
++      if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) {
++              dc_sink->dc_edid.length = 0;
++              dm_error("Bad EDID, status%d!\n", edid_status);
++      }
++
++      return dc_sink;
++
++fail_add_sink:
++      dc_sink_release(dc_sink);
++      return NULL;
++}
++
++void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
++{
++      int i;
++
++      if (!link->sink_count) {
++              BREAK_TO_DEBUGGER();
++              return;
++      }
++
++      for (i = 0; i < link->sink_count; i++) {
++              if (link->remote_sinks[i] == sink) {
++                      dc_sink_release(sink);
++                      link->remote_sinks[i] = NULL;
++
++                      /* shrink array to remove empty place */
++                      while (i < link->sink_count - 1) {
++                              link->remote_sinks[i] = link->remote_sinks[i+1];
++                              i++;
++                      }
++                      link->remote_sinks[i] = NULL;
++                      link->sink_count--;
++                      return;
++              }
++      }
++}
+diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c
+index 32f48a48e9dde..cbfa9343ffaf9 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c
++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c
+@@ -26,7 +26,6 @@
+ #include "dc.h"
+ #include "inc/core_status.h"
+-#include "dc_link.h"
+ #include "dpcd_defs.h"
+ #include "link_dp_dpia.h"
+diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
+index f69e681b3b5bf..1ecf1d8573592 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
+@@ -27,7 +27,6 @@
+ //                            USB4 DPIA BANDWIDTH ALLOCATION LOGIC
+ /*********************************************************************/
+ #include "dc.h"
+-#include "dc_link.h"
+ #include "link_dp_dpia_bw.h"
+ #include "drm_dp_helper_dc.h"
+ #include "link_dpcd.h"
+diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c
+index e60da0532c539..4ded5f9cdecc6 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c
++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c
+@@ -29,7 +29,6 @@
+ #include "link_dp_training_dpia.h"
+ #include "dc.h"
+ #include "inc/core_status.h"
+-#include "dc_link.h"
+ #include "dpcd_defs.h"
+ #include "link_dp_dpia.h"
+diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h
+index 18b9173d5a962..cd870af5fd250 100644
+--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
++++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
+@@ -34,10 +34,6 @@
+ struct ddc;
+ struct irq_manager;
+-enum {
+-      MAX_CONTROLLER_NUM = 6
+-};
+-
+ enum dp_power_state {
+       DP_POWER_STATE_D0 = 1,
+       DP_POWER_STATE_D3
+@@ -60,28 +56,6 @@ enum {
+       DATA_EFFICIENCY_128b_132b_x10000 = 9646, /* 96.71% data efficiency x 99.75% downspread factor */
+ };
+-enum link_training_result {
+-      LINK_TRAINING_SUCCESS,
+-      LINK_TRAINING_CR_FAIL_LANE0,
+-      LINK_TRAINING_CR_FAIL_LANE1,
+-      LINK_TRAINING_CR_FAIL_LANE23,
+-      /* CR DONE bit is cleared during EQ step */
+-      LINK_TRAINING_EQ_FAIL_CR,
+-      /* CR DONE bit is cleared but LANE0_CR_DONE is set during EQ step */
+-      LINK_TRAINING_EQ_FAIL_CR_PARTIAL,
+-      /* other failure during EQ step */
+-      LINK_TRAINING_EQ_FAIL_EQ,
+-      LINK_TRAINING_LQA_FAIL,
+-      /* one of the CR,EQ or symbol lock is dropped */
+-      LINK_TRAINING_LINK_LOSS,
+-      /* Abort link training (because sink unplugged) */
+-      LINK_TRAINING_ABORT,
+-      DP_128b_132b_LT_FAILED,
+-      DP_128b_132b_MAX_LOOP_COUNT_REACHED,
+-      DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT,
+-      DP_128b_132b_CDS_DONE_TIMEOUT,
+-};
+-
+ enum lttpr_mode {
+       LTTPR_MODE_UNKNOWN,
+       LTTPR_MODE_NON_LTTPR,
+-- 
+2.39.2
+
diff --git a/queue-6.3/drm-amd-display-update-minimum-stutter-residency-for.patch b/queue-6.3/drm-amd-display-update-minimum-stutter-residency-for.patch
new file mode 100644 (file)
index 0000000..cf8fc78
--- /dev/null
@@ -0,0 +1,43 @@
+From 4b234b9f6d239320eb4806a32b75d3e6afeb03eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Feb 2023 10:27:10 -0500
+Subject: drm/amd/display: Update minimum stutter residency for DCN314 Z8
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 0215ce9057edf69aff9c1a32f4254e1ec297db31 ]
+
+[Why]
+Block periods that are too short as they have the potential to
+currently cause hangs in other firmware components on the system.
+
+[How]
+Update the threshold, mostly targeting a block of 4k and downscaling.
+
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: d893f39320e1 ("drm/amd/display: Lowering min Z8 residency time")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+index 5c23c934c9751..33d8188d076ab 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -887,7 +887,7 @@ static const struct dc_plane_cap plane_cap = {
+ static const struct dc_debug_options debug_defaults_drv = {
+       .disable_z10 = false,
+       .enable_z9_disable_interface = true,
+-      .minimum_z8_residency_time = 1000,
++      .minimum_z8_residency_time = 3080,
+       .psr_skip_crtc_disable = true,
+       .disable_dmcu = true,
+       .force_abm_enable = false,
+-- 
+2.39.2
+
diff --git a/queue-6.3/drm-i915-add-_pick_even_2ranges.patch b/queue-6.3/drm-i915-add-_pick_even_2ranges.patch
new file mode 100644 (file)
index 0000000..0a008ea
--- /dev/null
@@ -0,0 +1,83 @@
+From e7db02b4037e04a2186d0f86e7e6b121909b4e9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Jan 2023 10:24:03 -0800
+Subject: drm/i915: Add _PICK_EVEN_2RANGES()
+
+From: Lucas De Marchi <lucas.demarchi@intel.com>
+
+[ Upstream commit 357513233d6456c9f99e34794897efd4ae907e83 ]
+
+It's a constant pattern in the driver to need to use 2 ranges of MMIOs
+based on port, phy, pll, etc. When that happens, instead of using
+_PICK_EVEN(), _PICK() needs to be used.  Using _PICK() is discouraged
+due to some reasons like:
+
+1) It increases the code size since the array is declared
+   in each call site
+2) Developers need to be careful not to incur an
+   out-of-bounds array access
+3) Developers need to be careful that the indexes match the
+   table. For that it may be that the table needs to contain
+   holes, making (1) even worse.
+
+Add a variant of _PICK_EVEN() that works with 2 ranges and selects which
+one to use depending on the index value.
+
+v2: Fix the address expansion in the example (Anusha)
+v3: Also rename macro to _PICK_EVEN_2RANGES() in the documentation
+    and reword it to clarify what ranges are chosen based on the index
+    (Jani)
+
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Reviewed-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
+Acked-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230125182403.7526-1-lucas.demarchi@intel.com
+Stable-dep-of: 214b09db6197 ("drm/msm: fix drm device leak on bind errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/i915_reg_defs.h | 29 ++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h
+index be43580a69793..983c5aa3045b3 100644
+--- a/drivers/gpu/drm/i915/i915_reg_defs.h
++++ b/drivers/gpu/drm/i915/i915_reg_defs.h
+@@ -119,6 +119,35 @@
+  */
+ #define _PICK_EVEN(__index, __a, __b) ((__a) + (__index) * ((__b) - (__a)))
++/*
++ * Like _PICK_EVEN(), but supports 2 ranges of evenly spaced address offsets.
++ * @__c_index corresponds to the index in which the second range starts to be
++ * used. Using math interval notation, the first range is used for indexes [ 0,
++ * @__c_index), while the second range is used for [ @__c_index, ... ). Example:
++ *
++ * #define _FOO_A                     0xf000
++ * #define _FOO_B                     0xf004
++ * #define _FOO_C                     0xf008
++ * #define _SUPER_FOO_A                       0xa000
++ * #define _SUPER_FOO_B                       0xa100
++ * #define FOO(x)                     _MMIO(_PICK_EVEN_2RANGES(x, 3,          \
++ *                                          _FOO_A, _FOO_B,                   \
++ *                                          _SUPER_FOO_A, _SUPER_FOO_B))
++ *
++ * This expands to:
++ *    0: 0xf000,
++ *    1: 0xf004,
++ *    2: 0xf008,
++ *    3: 0xa000,
++ *    4: 0xa100,
++ *    5: 0xa200,
++ *    ...
++ */
++#define _PICK_EVEN_2RANGES(__index, __c_index, __a, __b, __c, __d)            \
++      (BUILD_BUG_ON_ZERO(!__is_constexpr(__c_index)) +                        \
++       ((__index) < (__c_index) ? _PICK_EVEN(__index, __a, __b) :             \
++                                 _PICK_EVEN((__index) - (__c_index), __c, __d)))
++
+ /*
+  * Given the arbitrary numbers in varargs, pick the 0-based __index'th number.
+  *
+-- 
+2.39.2
+
diff --git a/queue-6.3/drm-i915-disable-sampler-indirect-state-in-bindless-.patch b/queue-6.3/drm-i915-disable-sampler-indirect-state-in-bindless-.patch
new file mode 100644 (file)
index 0000000..7ed626e
--- /dev/null
@@ -0,0 +1,81 @@
+From 7d3c1239a3c2d42a74d3f614883f6754c771f11d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Apr 2023 12:32:37 +0300
+Subject: drm/i915: disable sampler indirect state in bindless heap
+
+From: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
+
+[ Upstream commit 81900e3a37750d8c6ad705045310e002f6dd0356 ]
+
+By default the indirect state sampler data (border colors) are stored
+in the same heap as the SAMPLER_STATE structure. For userspace drivers
+that can be 2 different heaps (dynamic state heap & bindless sampler
+state heap). This means that border colors have to copied in 2
+different places so that the same SAMPLER_STATE structure find the
+right data.
+
+This change is forcing the indirect state sampler data to only be in
+the dynamic state pool (more convenient for userspace drivers, they
+only have to have one copy of the border colors). This is reproducing
+the behavior of the Windows drivers.
+
+BSpec: 46052
+
+Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Haridhar Kalvala <haridhar.kalvala@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230407093237.3296286-1-lionel.g.landwerlin@intel.com
+(cherry picked from commit 16fc9c08f0ec7b1c95f1ea4a16097acdb3fc943d)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_gt_regs.h     |  1 +
+ drivers/gpu/drm/i915/gt/intel_workarounds.c | 19 +++++++++++++++++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+index 72275749686aa..e54891b0e2f43 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
++++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+@@ -1146,6 +1146,7 @@
+ #define   SC_DISABLE_POWER_OPTIMIZATION_EBB   REG_BIT(9)
+ #define   GEN11_SAMPLER_ENABLE_HEADLESS_MSG   REG_BIT(5)
+ #define   MTL_DISABLE_SAMPLER_SC_OOO          REG_BIT(3)
++#define   GEN11_INDIRECT_STATE_BASE_ADDR_OVERRIDE     REG_BIT(0)
+ #define GEN9_HALF_SLICE_CHICKEN7              MCR_REG(0xe194)
+ #define   DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA     REG_BIT(15)
+diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+index b7c6c078dcc02..14f92a8082857 100644
+--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
++++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+@@ -3015,6 +3015,25 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li
+       add_render_compute_tuning_settings(i915, wal);
++      if (GRAPHICS_VER(i915) >= 11) {
++              /* This is not a Wa (although referred to as
++               * WaSetInidrectStateOverride in places), this allows
++               * applications that reference sampler states through
++               * the BindlessSamplerStateBaseAddress to have their
++               * border color relative to DynamicStateBaseAddress
++               * rather than BindlessSamplerStateBaseAddress.
++               *
++               * Otherwise SAMPLER_STATE border colors have to be
++               * copied in multiple heaps (DynamicStateBaseAddress &
++               * BindlessSamplerStateBaseAddress)
++               *
++               * BSpec: 46052
++               */
++              wa_mcr_masked_en(wal,
++                               GEN10_SAMPLER_MODE,
++                               GEN11_INDIRECT_STATE_BASE_ADDR_OVERRIDE);
++      }
++
+       if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_B0, STEP_FOREVER) ||
+           IS_MTL_GRAPHICS_STEP(i915, P, STEP_B0, STEP_FOREVER))
+               /* Wa_14017856879 */
+-- 
+2.39.2
+
diff --git a/queue-6.3/drm-i915-mtl-add-wa_14017856879.patch b/queue-6.3/drm-i915-mtl-add-wa_14017856879.patch
new file mode 100644 (file)
index 0000000..34e71fa
--- /dev/null
@@ -0,0 +1,57 @@
+From 01f6748b6c01765907b92d7d63b4c0de534f8b69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Apr 2023 23:02:20 +0530
+Subject: drm/i915/mtl: Add Wa_14017856879
+
+From: Haridhar Kalvala <haridhar.kalvala@intel.com>
+
+[ Upstream commit 4b51210f98c2b89ce37aede5b8dc5105be0572c6 ]
+
+Wa_14017856879 implementation for mtl.
+
+Bspec: 46046
+
+Signed-off-by: Haridhar Kalvala <haridhar.kalvala@intel.com>
+Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230404173220.3175577-1-haridhar.kalvala@intel.com
+Stable-dep-of: 81900e3a3775 ("drm/i915: disable sampler indirect state in bindless heap")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_gt_regs.h     | 2 ++
+ drivers/gpu/drm/i915/gt/intel_workarounds.c | 5 +++++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+index 15b8636853ff0..72275749686aa 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
++++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+@@ -1172,7 +1172,9 @@
+ #define   THREAD_EX_ARB_MODE_RR_AFTER_DEP     REG_FIELD_PREP(THREAD_EX_ARB_MODE, 0x2)
+ #define HSW_ROW_CHICKEN3                      _MMIO(0xe49c)
++#define GEN9_ROW_CHICKEN3                     MCR_REG(0xe49c)
+ #define   HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE  (1 << 6)
++#define   MTL_DISABLE_FIX_FOR_EOT_FLUSH               REG_BIT(9)
+ #define GEN8_ROW_CHICKEN                      MCR_REG(0xe4f0)
+ #define   FLOW_CONTROL_ENABLE                 REG_BIT(15)
+diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+index bfdffb6a013ce..b7c6c078dcc02 100644
+--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
++++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+@@ -3015,6 +3015,11 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li
+       add_render_compute_tuning_settings(i915, wal);
++      if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_B0, STEP_FOREVER) ||
++          IS_MTL_GRAPHICS_STEP(i915, P, STEP_B0, STEP_FOREVER))
++              /* Wa_14017856879 */
++              wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN3, MTL_DISABLE_FIX_FOR_EOT_FLUSH);
++
+       if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
+           IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
+               /*
+-- 
+2.39.2
+
diff --git a/queue-6.3/drm-i915-mtl-add-workarounds-wa_14017066071-and-wa_1.patch b/queue-6.3/drm-i915-mtl-add-workarounds-wa_14017066071-and-wa_1.patch
new file mode 100644 (file)
index 0000000..95e8edd
--- /dev/null
@@ -0,0 +1,62 @@
+From ac4ebce04733b7200231b2c1101936568d497736 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Mar 2023 18:23:35 -0300
+Subject: drm/i915/mtl: Add workarounds Wa_14017066071 and Wa_14017654203
+
+From: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
+
+[ Upstream commit 5fba65efa7cfb8cef227a2c555deb10327a5e27b ]
+
+Both workarounds require the same implementation and apply to MTL P and
+M from stepping A0 to B0 (exclusive).
+
+v2:
+  - Remove unrelated brace removal. (Matt)
+
+Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
+Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230329212336.106161-2-gustavo.sousa@intel.com
+Stable-dep-of: 81900e3a3775 ("drm/i915: disable sampler indirect state in bindless heap")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_gt_regs.h     | 1 +
+ drivers/gpu/drm/i915/gt/intel_workarounds.c | 9 +++++++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+index be0f6e305c881..15b8636853ff0 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
++++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+@@ -1145,6 +1145,7 @@
+ #define   ENABLE_SMALLPL                      REG_BIT(15)
+ #define   SC_DISABLE_POWER_OPTIMIZATION_EBB   REG_BIT(9)
+ #define   GEN11_SAMPLER_ENABLE_HEADLESS_MSG   REG_BIT(5)
++#define   MTL_DISABLE_SAMPLER_SC_OOO          REG_BIT(3)
+ #define GEN9_HALF_SLICE_CHICKEN7              MCR_REG(0xe194)
+ #define   DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA     REG_BIT(15)
+diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+index 485c5cc5d0f96..bfdffb6a013ce 100644
+--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
++++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+@@ -3015,6 +3015,15 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li
+       add_render_compute_tuning_settings(i915, wal);
++      if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
++          IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0))
++              /*
++               * Wa_14017066071
++               * Wa_14017654203
++               */
++              wa_mcr_masked_en(wal, GEN10_SAMPLER_MODE,
++                               MTL_DISABLE_SAMPLER_SC_OOO);
++
+       if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
+           IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0) ||
+           IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_FOREVER) ||
+-- 
+2.39.2
+
index 9b69a0aecebe46274f92c9206447bfcfbaf62186..9d1830e64280ceba72ba55b8493e6590fa8530e3 100644 (file)
@@ -213,3 +213,12 @@ fs-ntfs3-fix-null-ptr-deref-on-inode-i_op-in-ntfs_lookup.patch
 fs-ntfs3-refactoring-of-various-minor-issues.patch
 revert-net-sched-flower-fix-wrong-handle-assignment-during-filter-change.patch
 drm-msm-adreno-adreno_gpu-use-suspend-instead-of-idle-on-load-error.patch
+drm-amd-display-merge-dc_link.h-into-dc.h-and-dc_typ.patch
+drm-amd-display-hpd-rx-irq-not-working-with-edp-inte.patch
+drm-i915-add-_pick_even_2ranges.patch
+drm-i915-mtl-add-workarounds-wa_14017066071-and-wa_1.patch
+drm-i915-mtl-add-wa_14017856879.patch
+drm-i915-disable-sampler-indirect-state-in-bindless-.patch
+drm-amd-display-add-minimum-z8-residency-debug-optio.patch
+drm-amd-display-update-minimum-stutter-residency-for.patch
+drm-amd-display-lowering-min-z8-residency-time.patch