Patch "[PATCH 082/135] drm/radeon: fix dp link rate selection (v2)" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
[PATCH 082/135] drm/radeon: fix dp link rate selection (v2)
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
0082-drm-radeon-fix-dp-link-rate-selection-v2.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
4c1aab8bf63b9388398f0115a60c40bbef01181cMon Sep 17 00:00:00 2001
From: Alex Deucher <[email protected]>
Date: Thu, 17 Dec 2015 10:23:34 -0500
Subject: [PATCH 082/135] drm/radeon: fix dp link rate selection (v2)
[ Upstream commit 092c96a8ab9d1bd60ada2ed385cc364ce084180e ]
Need to properly handle the max link rate in the dpcd. This prevents some cases where 5.4 Ghz is selected when it shouldn't be.
v2: simplify logic, add array bounds check
--- drivers/gpu/drm/radeon/atombios_dp.c | 108 +++++++++++---------------------- drivers/gpu/drm/radeon/radeon_dp_mst.c | 12 ++- drivers/gpu/drm/radeon/radeon_mode.h | 6 + 3 files changed, 49 insertions(+), 77 deletions(-)
drivers/gpu/drm/radeon/atombios_dp.c +36 -72
@@ -302,77 +302,31 @@ static int convert_bpc_to_bpp(int bpc)return bpc *3 ; } -/* get the max pix clock supported by the link rate and lane num */ -static int dp_get_max_dp_pix_clock (int link_rate, -int lane_num, -int bpp) -{ -return (link_rate * lane_num *8 ) / bpp; -} -/***** radeon specific DP functions *****/ -int radeon_dp_get_max_link_rate (struct drm_connector *connector, -const u8 dpcd[DP_DPCD_SIZE ]) -{ -int max_link_rate; - -if (radeon_connector_is_dp12_capable (connector)) - max_link_rate =min (drm_dp_max_link_rate (dpcd),540000 ); -else - max_link_rate =min (drm_dp_max_link_rate (dpcd),270000 ); - -return max_link_rate; -} - -/* First get the min lane# when low rate is used according to pixel clock -* (prefer low rate), second check max lane# supported by DP panel, -* if the max lane# < low rate lane# then use max lane# instead. -*/ -static int radeon_dp_get_dp_lane_number (struct drm_connector *connector, -const u8 dpcd[DP_DPCD_SIZE ], -int pix_clock) +int radeon_dp_get_dp_link_config (struct drm_connector *connector, +const u8 dpcd[DP_DPCD_SIZE ], +unsigned pix_clock, +unsigned *dp_lanes,unsigned *dp_rate) {int bpp =convert_bpc_to_bpp (radeon_get_monitor_bpc (connector)); -int max_link_rate =radeon_dp_get_max_link_rate (connector, dpcd); -int max_lane_num =drm_dp_max_lane_count (dpcd); -int lane_num; -int max_dp_pix_clock; - -for (lane_num =1 ; lane_num < max_lane_num; lane_num <<=1 ) { - max_dp_pix_clock =dp_get_max_dp_pix_clock (max_link_rate, lane_num, bpp); -if (pix_clock <= max_dp_pix_clock) -break ; - } - -return lane_num; -} - -static int radeon_dp_get_dp_link_clock (struct drm_connector *connector, -const u8 dpcd[DP_DPCD_SIZE ], -int pix_clock) -{ -int bpp =convert_bpc_to_bpp (radeon_get_monitor_bpc (connector)); -int lane_num, max_pix_clock; - -if (radeon_connector_encoder_get_dp_bridge_encoder_id (connector) == -ENCODER_OBJECT_ID_NUTMEG ) -return 270000 ; - - lane_num =radeon_dp_get_dp_lane_number (connector, dpcd, pix_clock); - max_pix_clock =dp_get_max_dp_pix_clock (162000 , lane_num, bpp); -if (pix_clock <= max_pix_clock) -return 162000 ; - max_pix_clock =dp_get_max_dp_pix_clock (270000 , lane_num, bpp); -if (pix_clock <= max_pix_clock) -return 270000 ; -if (radeon_connector_is_dp12_capable (connector)) { - max_pix_clock =dp_get_max_dp_pix_clock (540000 , lane_num, bpp); -if (pix_clock <= max_pix_clock) -return 540000 ; +static const unsigned link_rates[3 ] = {162000 ,270000 ,540000 }; +unsigned max_link_rate =drm_dp_max_link_rate (dpcd); +unsigned max_lane_num =drm_dp_max_lane_count (dpcd); +unsigned lane_num, i, max_pix_clock; + +for (lane_num =1 ; lane_num <= max_lane_num; lane_num <<=1 ) { +for (i =0 ; i <ARRAY_SIZE (link_rates) && link_rates[i] <= max_link_rate; i++) { + max_pix_clock = (lane_num * link_rates[i] *8 ) / bpp; +if (max_pix_clock >= pix_clock) { + *dp_lanes = lane_num; + *dp_rate = link_rates[i]; +return 0 ; + } + } } -return radeon_dp_get_max_link_rate (connector, dpcd); +return -EINVAL ; } static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
@@ -491,6 +445,7 @@ void radeon_dp_set_link_config(struct dr {struct radeon_connector *radeon_connector =to_radeon_connector (connector);struct radeon_connector_atom_dig *dig_connector; +int ret;if (!radeon_connector->con_priv)return ;
@@ -498,10 +453,14 @@ void radeon_dp_set_link_config(struct drif ((dig_connector->dp_sink_type ==CONNECTOR_OBJECT_ID_DISPLAYPORT ) || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { - dig_connector->dp_clock = -radeon_dp_get_dp_link_clock (connector, dig_connector->dpcd, mode->clock); - dig_connector->dp_lane_count = -radeon_dp_get_dp_lane_number (connector, dig_connector->dpcd, mode->clock); + ret =radeon_dp_get_dp_link_config (connector, dig_connector->dpcd, + mode->clock, + &dig_connector->dp_lane_count, + &dig_connector->dp_clock); +if (ret) { + dig_connector->dp_clock =0 ; + dig_connector->dp_lane_count =0 ; + } } }
@@ -510,7 +469,8 @@ int radeon_dp_mode_valid_helper(struct d {struct radeon_connector *radeon_connector =to_radeon_connector (connector);struct radeon_connector_atom_dig *dig_connector; -int dp_clock; +unsigned dp_clock, dp_lanes; +int ret;if ((mode->clock >340000 ) && (!radeon_connector_is_dp12_capable (connector)))
@@ -520,8 +480,12 @@ int radeon_dp_mode_valid_helper(struct dreturn MODE_CLOCK_HIGH ; dig_connector = radeon_connector->con_priv; - dp_clock = -radeon_dp_get_dp_link_clock (connector, dig_connector->dpcd, mode->clock); + ret =radeon_dp_get_dp_link_config (connector, dig_connector->dpcd, + mode->clock, + &dp_lanes, + &dp_clock); +if (ret) +return MODE_CLOCK_HIGH ;if ((dp_clock ==540000 ) && (!radeon_connector_is_dp12_capable (connector)))
drivers/gpu/drm/radeon/radeon_dp_mst.c +9 -3
@@ -525,11 +525,17 @@ static bool radeon_mst_mode_fixup(structdrm_mode_set_crtcinfo (adjusted_mode,0 ); {struct radeon_connector_atom_dig *dig_connector; +int ret; dig_connector = mst_enc->connector->con_priv; - dig_connector->dp_lane_count =drm_dp_max_lane_count (dig_connector->dpcd); - dig_connector->dp_clock =radeon_dp_get_max_link_rate (&mst_enc->connector->base, - dig_connector->dpcd); + ret =radeon_dp_get_dp_link_config (&mst_enc->connector->base, + dig_connector->dpcd, adjusted_mode->clock, + &dig_connector->dp_lane_count, + &dig_connector->dp_clock); +if (ret) { + dig_connector->dp_lane_count =0 ; + dig_connector->dp_clock =0 ; + }DRM_DEBUG_KMS ("dig clock %p %d %d\n" , dig_connector, dig_connector->dp_lane_count, dig_connector->dp_clock); }
drivers/gpu/drm/radeon/radeon_mode.h +4 -2
@@ -757,8 +757,10 @@ extern u8 radeon_dp_getsinktype(struct rextern bool radeon_dp_getdpcd (struct radeon_connector *radeon_connector);extern int radeon_dp_get_panel_mode (struct drm_encoder *encoder,struct drm_connector *connector); -int radeon_dp_get_max_link_rate (struct drm_connector *connector, -const u8 *dpcd); +extern int radeon_dp_get_dp_link_config (struct drm_connector *connector, +const u8 *dpcd, +unsigned pix_clock, +unsigned *dp_lanes,unsigned *dp_rate);extern void radeon_dp_set_rx_power_state (struct drm_connector *connector,u8 power_state);extern void radeon_dp_aux_init (struct radeon_connector *radeon_connector);
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/0081-drm-amdgpu-fix-dp-link-rate-selection-v2.patch queue-4.4/0114-drm-radeon-mst-fix-regression-in-lane-link-handling.patch queue-4.4/0112-ALSA-hda-add-AMD-Polaris-10-11-AZ-PCI-IDs-with-prope.patch queue-4.4/0082-drm-radeon-fix-dp-link-rate-selection-v2.patch