Commit 6513104b authored by Hersen Wu's avatar Hersen Wu Committed by Alex Deucher

drm/amd/display: dsc mst 2 4K displays go dark with 2 lane HBR3

[Why]
call stack of amdgpu dsc mst pbn, slot num calculation is as below:
-compute_bpp_x16_from_target_bandwidth
-decide_dsc_target_bpp_x16
-setup_dsc_config
-dc_dsc_compute_bandwidth_range
-compute_mst_dsc_configs_for_link
-compute_mst_dsc_configs_for_state

from pbn -> dsc target bpp_x16

bpp_x16 is calulated by compute_bpp_x16_from_target_bandwidth.
Beside pixel clock and bpp, num_slices_h and bpp_increment_div
will also affect bpp_x16.

from dsc target bpp_x16 -> pbn

within dm_update_mst_vcpi_slots_for_dsc,
pbn = drm_dp_calc_pbn_mode(clock, bpp_x16, true);

drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc)
{
  return DIV_ROUND_UP_ULL(mul_u32_u32(clock * (bpp / 16), 64 * 1006),
            8 * 54 * 1000 * 1000);
}

bpp / 16 trunc digits after decimal point. This will cause calculation
delta. drm_dp_calc_pbn_mode does not have other informations,
like num_slices_h, bpp_increment_div. therefore, it does not do revese
calcuation properly from bpp_x16 to pbn.

pbn from drm_dp_calc_pbn_mode is less than pbn from
compute_mst_dsc_configs_for_state. This cause not enough mst slot
allocated to display. display could not visually light up.

[How]
pass pbn from compute_mst_dsc_configs_for_state to
dm_update_mst_vcpi_slots_for_dsc

Cc: stable@vger.kernel.org
Reviewed-by: default avatarScott Foster <Scott.Foster@amd.com>
Acked-by: default avatarMikita Lipski <mikita.lipski@amd.com>
Signed-off-by: default avatarHersen Wu <hersenwu@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 63f8bee4
...@@ -7092,14 +7092,15 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = { ...@@ -7092,14 +7092,15 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = {
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
struct dc_state *dc_state) struct dc_state *dc_state,
struct dsc_mst_fairness_vars *vars)
{ {
struct dc_stream_state *stream = NULL; struct dc_stream_state *stream = NULL;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *new_con_state; struct drm_connector_state *new_con_state;
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
struct dm_connector_state *dm_conn_state; struct dm_connector_state *dm_conn_state;
int i, j, clock, bpp; int i, j, clock;
int vcpi, pbn_div, pbn = 0; int vcpi, pbn_div, pbn = 0;
for_each_new_connector_in_state(state, connector, new_con_state, i) { for_each_new_connector_in_state(state, connector, new_con_state, i) {
...@@ -7138,9 +7139,15 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, ...@@ -7138,9 +7139,15 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
} }
pbn_div = dm_mst_get_pbn_divider(stream->link); pbn_div = dm_mst_get_pbn_divider(stream->link);
bpp = stream->timing.dsc_cfg.bits_per_pixel;
clock = stream->timing.pix_clk_100hz / 10; clock = stream->timing.pix_clk_100hz / 10;
pbn = drm_dp_calc_pbn_mode(clock, bpp, true); /* pbn is calculated by compute_mst_dsc_configs_for_state*/
for (j = 0; j < dc_state->stream_count; j++) {
if (vars[j].aconnector == aconnector) {
pbn = vars[j].pbn;
break;
}
}
vcpi = drm_dp_mst_atomic_enable_dsc(state, vcpi = drm_dp_mst_atomic_enable_dsc(state,
aconnector->port, aconnector->port,
pbn, pbn_div, pbn, pbn_div,
...@@ -10546,6 +10553,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -10546,6 +10553,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
int ret, i; int ret, i;
bool lock_and_validation_needed = false; bool lock_and_validation_needed = false;
struct dm_crtc_state *dm_old_crtc_state; struct dm_crtc_state *dm_old_crtc_state;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dsc_mst_fairness_vars vars[MAX_PIPES];
#endif
trace_amdgpu_dm_atomic_check_begin(state); trace_amdgpu_dm_atomic_check_begin(state);
...@@ -10776,10 +10786,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -10776,10 +10786,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
goto fail; goto fail;
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
if (!compute_mst_dsc_configs_for_state(state, dm_state->context)) if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars))
goto fail; goto fail;
ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context); ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars);
if (ret) if (ret)
goto fail; goto fail;
#endif #endif
......
...@@ -518,12 +518,7 @@ struct dsc_mst_fairness_params { ...@@ -518,12 +518,7 @@ struct dsc_mst_fairness_params {
uint32_t num_slices_h; uint32_t num_slices_h;
uint32_t num_slices_v; uint32_t num_slices_v;
uint32_t bpp_overwrite; uint32_t bpp_overwrite;
}; struct amdgpu_dm_connector *aconnector;
struct dsc_mst_fairness_vars {
int pbn;
bool dsc_enabled;
int bpp_x16;
}; };
static int kbps_to_peak_pbn(int kbps) static int kbps_to_peak_pbn(int kbps)
...@@ -750,12 +745,12 @@ static void try_disable_dsc(struct drm_atomic_state *state, ...@@ -750,12 +745,12 @@ static void try_disable_dsc(struct drm_atomic_state *state,
static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
struct dc_state *dc_state, struct dc_state *dc_state,
struct dc_link *dc_link) struct dc_link *dc_link,
struct dsc_mst_fairness_vars *vars)
{ {
int i; int i;
struct dc_stream_state *stream; struct dc_stream_state *stream;
struct dsc_mst_fairness_params params[MAX_PIPES]; struct dsc_mst_fairness_params params[MAX_PIPES];
struct dsc_mst_fairness_vars vars[MAX_PIPES];
struct amdgpu_dm_connector *aconnector; struct amdgpu_dm_connector *aconnector;
int count = 0; int count = 0;
bool debugfs_overwrite = false; bool debugfs_overwrite = false;
...@@ -776,6 +771,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, ...@@ -776,6 +771,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
params[count].timing = &stream->timing; params[count].timing = &stream->timing;
params[count].sink = stream->sink; params[count].sink = stream->sink;
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
params[count].aconnector = aconnector;
params[count].port = aconnector->port; params[count].port = aconnector->port;
params[count].clock_force_enable = aconnector->dsc_settings.dsc_force_enable; params[count].clock_force_enable = aconnector->dsc_settings.dsc_force_enable;
if (params[count].clock_force_enable == DSC_CLK_FORCE_ENABLE) if (params[count].clock_force_enable == DSC_CLK_FORCE_ENABLE)
...@@ -798,6 +794,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, ...@@ -798,6 +794,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
} }
/* Try no compression */ /* Try no compression */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
vars[i].aconnector = params[i].aconnector;
vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
vars[i].dsc_enabled = false; vars[i].dsc_enabled = false;
vars[i].bpp_x16 = 0; vars[i].bpp_x16 = 0;
...@@ -851,7 +848,8 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, ...@@ -851,7 +848,8 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
} }
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
struct dc_state *dc_state) struct dc_state *dc_state,
struct dsc_mst_fairness_vars *vars)
{ {
int i, j; int i, j;
struct dc_stream_state *stream; struct dc_stream_state *stream;
...@@ -882,7 +880,7 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, ...@@ -882,7 +880,7 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
return false; return false;
mutex_lock(&aconnector->mst_mgr.lock); mutex_lock(&aconnector->mst_mgr.lock);
if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link)) { if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars)) {
mutex_unlock(&aconnector->mst_mgr.lock); mutex_unlock(&aconnector->mst_mgr.lock);
return false; return false;
} }
......
...@@ -39,8 +39,17 @@ void ...@@ -39,8 +39,17 @@ void
dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev); dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev);
#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_DC_DCN)
struct dsc_mst_fairness_vars {
int pbn;
bool dsc_enabled;
int bpp_x16;
struct amdgpu_dm_connector *aconnector;
};
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
struct dc_state *dc_state); struct dc_state *dc_state,
struct dsc_mst_fairness_vars *vars);
#endif #endif
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment