The values returned by drm_dp_get_adjust_request_voltage() and drm_dp_get_adjust_request_pre_emphasis() are raw unshifted 2-bit values, but DPCD_*_SET macros expect them to be shifted into their respective bit positions. Without right-shifting first, the combined training_lane register value becomes corrupted whenever pre-emphasis or voltage swing is non-zero, leading to failed link training and black screen.
Add right shift by DP_TRAIN_VOLTAGE_SWING_SHIFT and DP_TRAIN_PRE_EMPHASIS_SHIFT for both voltage swing and pre-emphasis values before constructing training_lane, in both the adjust training lane and clock recovery paths. Reported-by: Vicente Bergas <[email protected]> Closes: https://lore.kernel.org/all/CAAMcf8D-d+5n=h44kekbsqwy42m+o32w+mo-r15vqwnyyhj...@mail.gmail.com/ Fixes: d84b087c7662 ("drm/bridge: analogix_dp: Apply DP helper APIs to get adjusted voltages and pre-emphasises") Signed-off-by: Damon Ding <[email protected]> --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 7a85774aaac1..1d39a354c3d9 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -309,7 +309,9 @@ static void analogix_dp_get_adjust_training_lane(struct analogix_dp_device *dp, lane_count = dp->link_train.lane_count; for (lane = 0; lane < lane_count; lane++) { voltage_swing = drm_dp_get_adjust_request_voltage(link_status, lane); + voltage_swing >>= DP_TRAIN_VOLTAGE_SWING_SHIFT; pre_emphasis = drm_dp_get_adjust_request_pre_emphasis(link_status, lane); + pre_emphasis >>= DP_TRAIN_PRE_EMPHASIS_SHIFT; training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | DPCD_PRE_EMPHASIS_SET(pre_emphasis); @@ -355,7 +357,9 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp) for (lane = 0; lane < lane_count; lane++) { training_lane = analogix_dp_get_lane_link_training(dp, lane); voltage_swing = drm_dp_get_adjust_request_voltage(link_status, lane); + voltage_swing >>= DP_TRAIN_VOLTAGE_SWING_SHIFT; pre_emphasis = drm_dp_get_adjust_request_pre_emphasis(link_status, lane); + pre_emphasis >>= DP_TRAIN_PRE_EMPHASIS_SHIFT; if (DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing && DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis) -- 2.34.1
