From: Sasha Levin Date: Mon, 15 May 2023 01:42:06 +0000 (-0400) Subject: Fixes for 6.3 X-Git-Tag: v4.14.315~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=814e03ec05449ec80fe66b5a26f9f77ecf2aeb85;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.3 Signed-off-by: Sasha Levin --- 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 index 00000000000..532a09ff0be --- /dev/null +++ b/queue-6.3/drm-amd-display-add-minimum-z8-residency-debug-optio.patch @@ -0,0 +1,70 @@ +From 7ce03654e704cdd33b8a4c16df43331707aafba6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Feb 2023 11:17:50 -0500 +Subject: drm/amd/display: Add minimum Z8 residency debug option + +From: Nicholas Kazlauskas + +[ 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 +Acked-by: Qingqing Zhuo +Signed-off-by: Nicholas Kazlauskas +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Stable-dep-of: d893f39320e1 ("drm/amd/display: Lowering min Z8 residency time") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..675a9c43e03 --- /dev/null +++ b/queue-6.3/drm-amd-display-hpd-rx-irq-not-working-with-edp-inte.patch @@ -0,0 +1,83 @@ +From 664f303c2e9f234a8715a31a13da2b55132f4ac0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Feb 2023 20:47:57 +0800 +Subject: drm/amd/display: hpd rx irq not working with eDP interface + +From: Robin Chen + +[ 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 +Reviewed-by: Wenjing Liu +Acked-by: Qingqing Zhuo +Signed-off-by: Robin Chen +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6a56bbfad99 --- /dev/null +++ b/queue-6.3/drm-amd-display-lowering-min-z8-residency-time.patch @@ -0,0 +1,41 @@ +From 5b16d9935c404461d324662b51b3647e2e417e57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Apr 2023 10:49:38 -0400 +Subject: drm/amd/display: Lowering min Z8 residency time + +From: Leo Chen + +[ 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 +Reviewed-by: Nicholas Kazlauskas +Acked-by: Rodrigo Siqueira +Signed-off-by: Leo Chen +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..11a552ae673 --- /dev/null +++ b/queue-6.3/drm-amd-display-merge-dc_link.h-into-dc.h-and-dc_typ.patch @@ -0,0 +1,1757 @@ +From 1632799554eb11bc9cfbde13ca9d6727a97552d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Qingqing Zhuo +Signed-off-by: Wenjing Liu +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Stable-dep-of: eeefe7c4820b ("drm/amd/display: hpd rx irq not working with eDP interface") +Signed-off-by: Sasha Levin +--- + .../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 + +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 index 00000000000..cf8fc78f3d2 --- /dev/null +++ b/queue-6.3/drm-amd-display-update-minimum-stutter-residency-for.patch @@ -0,0 +1,43 @@ +From 4b234b9f6d239320eb4806a32b75d3e6afeb03eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Feb 2023 10:27:10 -0500 +Subject: drm/amd/display: Update minimum stutter residency for DCN314 Z8 + +From: Nicholas Kazlauskas + +[ 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 +Acked-by: Qingqing Zhuo +Signed-off-by: Nicholas Kazlauskas +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Stable-dep-of: d893f39320e1 ("drm/amd/display: Lowering min Z8 residency time") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0a008ea399b --- /dev/null +++ b/queue-6.3/drm-i915-add-_pick_even_2ranges.patch @@ -0,0 +1,83 @@ +From e7db02b4037e04a2186d0f86e7e6b121909b4e9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Jan 2023 10:24:03 -0800 +Subject: drm/i915: Add _PICK_EVEN_2RANGES() + +From: Lucas De Marchi + +[ 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 +Reviewed-by: Anusha Srivatsa +Acked-by: Jani Nikula +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 +--- + 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 index 00000000000..7ed626e89d0 --- /dev/null +++ b/queue-6.3/drm-i915-disable-sampler-indirect-state-in-bindless-.patch @@ -0,0 +1,81 @@ +From 7d3c1239a3c2d42a74d3f614883f6754c771f11d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Apr 2023 12:32:37 +0300 +Subject: drm/i915: disable sampler indirect state in bindless heap + +From: Lionel Landwerlin + +[ 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 +Cc: stable@vger.kernel.org +Reviewed-by: Haridhar Kalvala +Signed-off-by: Matt Roper +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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..34e71fa1eb2 --- /dev/null +++ b/queue-6.3/drm-i915-mtl-add-wa_14017856879.patch @@ -0,0 +1,57 @@ +From 01f6748b6c01765907b92d7d63b4c0de534f8b69 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Apr 2023 23:02:20 +0530 +Subject: drm/i915/mtl: Add Wa_14017856879 + +From: Haridhar Kalvala + +[ Upstream commit 4b51210f98c2b89ce37aede5b8dc5105be0572c6 ] + +Wa_14017856879 implementation for mtl. + +Bspec: 46046 + +Signed-off-by: Haridhar Kalvala +Reviewed-by: Gustavo Sousa +Signed-off-by: Matt Roper +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 +--- + 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 index 00000000000..95e8eddf741 --- /dev/null +++ b/queue-6.3/drm-i915-mtl-add-workarounds-wa_14017066071-and-wa_1.patch @@ -0,0 +1,62 @@ +From ac4ebce04733b7200231b2c1101936568d497736 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Mar 2023 18:23:35 -0300 +Subject: drm/i915/mtl: Add workarounds Wa_14017066071 and Wa_14017654203 + +From: Radhakrishna Sripada + +[ 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 +Signed-off-by: Gustavo Sousa +Reviewed-by: Matt Roper +Signed-off-by: Matt Roper +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 +--- + 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 + diff --git a/queue-6.3/series b/queue-6.3/series index 9b69a0aeceb..9d1830e6428 100644 --- a/queue-6.3/series +++ b/queue-6.3/series @@ -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