summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorMartin Tsai <Martin.Tsai@amd.com>2026-09-09 17:16:45 +0800
committerAlex Deucher <alexander.deucher@amd.com>2026-10-07 12:06:17 -0400
commitf65cda7eacab466bf50965179918e1af9c33b84b (patch)
tree77babb2cc9a80bd663e5e5fa17c655a8d6ef811d /drivers/gpu
parent9fac7d8be40a10c6bd4e5f954736bd21158f0a7a (diff)
drm/amd/display: allow skipping link bandwidth clear
[why] To set link bandwidth with zero could hit error protection from Sink panel to fail link training and cause screen corruption. [how] To skip link bw cleaning in two conditions: 1. eDP v1.5 or latter, because the last write will take effect. 2. Sink requires not to clear it. Reviewed-by: Anthony Koo <anthony.koo@amd.com> Signed-off-by: Martin Tsai <Martin.Tsai@amd.com> Signed-off-by: Roman Li <roman.li@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dp_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c20
-rw-r--r--drivers/gpu/drm/amd/display/include/link_service_types.h1
5 files changed, 25 insertions, 5 deletions
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 fef857c7336b..5926e8a4f95a 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
@@ -263,6 +263,11 @@ void dc_link_set_preferred_training_settings(struct dc *dc,
lt_overrides, link, skip_immediate_retrain);
}
+void dc_link_set_skip_link_bw_clear(struct dc_link *link, bool skip)
+{
+ link->preferred_training_settings.skip_link_bw_clear = skip;
+}
+
bool dc_dp_trace_is_initialized(struct dc_link *link)
{
return link->dc->link_srv->dp_trace_is_initialized(link);
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index d2256c454424..957e15e4a84c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -2869,6 +2869,9 @@ void dc_link_set_preferred_training_settings(struct dc *dc,
struct dc_link *link,
bool skip_immediate_retrain);
+/* Configure the sink-specific policy for future DP link training. */
+void dc_link_set_skip_link_bw_clear(struct dc_link *link, bool skip);
+
/* return - true if FEC is supported with connected DP RX, false otherwise */
bool dc_link_is_fec_supported(const struct dc_link *link);
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 d0ba9ad67a3e..b0e91b321f43 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -203,6 +203,7 @@ struct dc_link_training_overrides {
bool *enhanced_framing;
bool *mst_enable;
bool *fec_enable;
+ bool skip_link_bw_clear;
};
union payload_table_update_status {
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
index 04eedec8a230..3be36d1063de 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
@@ -724,6 +724,8 @@ void override_training_settings(
{
uint32_t lane;
+ lt_settings->skip_link_bw_clear = overrides->skip_link_bw_clear;
+
/* Override link spread */
if (!link->dp_ss_off && overrides->downspread != NULL)
lt_settings->link_settings.link_spread = *overrides->downspread ?
@@ -1095,7 +1097,7 @@ enum dc_status dpcd_set_link_settings(
struct dc_link *link,
const struct link_training_settings *lt_settings)
{
- uint8_t rate;
+ uint8_t rate = 0;
enum dc_status status;
union down_spread_ctrl downspread = {0};
@@ -1129,7 +1131,7 @@ enum dc_status dpcd_set_link_settings(
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_13 &&
lt_settings->link_settings.use_link_rate_set == true) {
- rate = 0;
+
/* WA for some MUX chips that will power down with eDP and lose supported
* link rate set for eDP 1.4. Source reads DPCD 0x010 again to ensure
* MUX chip gets link rate set back before link training.
@@ -1140,9 +1142,17 @@ enum dc_status dpcd_set_link_settings(
core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
supported_link_rates, sizeof(supported_link_rates));
}
- status = core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
- if (status != DC_OK)
- DC_LOG_ERROR("%s:%d: core_link_write_dpcd (DP_LINK_BW_SET) failed\n", __func__, __LINE__);
+
+ /*
+ * It doesn't need to clear 0x100 in below two conditions:
+ * 1. eDP v1.5 or later, because the last write will take effect in Sink.
+ * 2. Sink requires not to clear 0x100.
+ */
+ if (!lt_settings->skip_link_bw_clear && link->dpcd_caps.edp_rev <= DP_EDP_14b) {
+ status = core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
+ if (status != DC_OK)
+ DC_LOG_ERROR("%s:%d: core_link_write_dpcd (DP_LINK_BW_SET) failed\n", __func__, __LINE__);
+ }
status = core_link_write_dpcd(link, DP_LINK_RATE_SET,
&lt_settings->link_settings.link_rate_set, 1);
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 da74ed66c8f9..798d83238828 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -73,6 +73,7 @@ struct link_training_settings {
enum dc_pre_emphasis *pre_emphasis;
enum dc_post_cursor2 *post_cursor2;
bool should_set_fec_ready;
+ bool skip_link_bw_clear;
union dc_dp_ffe_preset *ffe_preset;
uint16_t cr_pattern_time;