diff options
Diffstat (limited to 'meta-amdfalconx86/recipes-kernel/linux/files/0521-drm-amd-dal-atomic-validate-fix.patch')
-rw-r--r-- | meta-amdfalconx86/recipes-kernel/linux/files/0521-drm-amd-dal-atomic-validate-fix.patch | 719 |
1 files changed, 719 insertions, 0 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/linux/files/0521-drm-amd-dal-atomic-validate-fix.patch b/meta-amdfalconx86/recipes-kernel/linux/files/0521-drm-amd-dal-atomic-validate-fix.patch new file mode 100644 index 00000000..ee478073 --- /dev/null +++ b/meta-amdfalconx86/recipes-kernel/linux/files/0521-drm-amd-dal-atomic-validate-fix.patch @@ -0,0 +1,719 @@ +From ba1bf08179af26ce8a1d8ac3b597085aa5424c13 Mon Sep 17 00:00:00 2001 +From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Date: Thu, 19 Nov 2015 14:35:10 -0500 +Subject: [PATCH 0521/1110] drm/amd/dal: atomic validate fix + +Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Signed-off-by: Harry Wentland <harry.wentland@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +--- + .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c | 379 ++++++++++++--------- + .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h | 10 +- + drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c | 4 +- + .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 2 +- + .../gpu/drm/amd/dal/dc/dce110/dce110_resource.c | 26 +- + drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h | 2 +- + 6 files changed, 235 insertions(+), 188 deletions(-) + +diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c +index 59a6a28..1b46426 100644 +--- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c ++++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c +@@ -337,7 +337,7 @@ static void dm_crtc_cursor_reset(struct drm_crtc *crtc) + } + } + static bool fill_rects_from_plane_state( +- struct drm_plane_state *state, ++ const struct drm_plane_state *state, + struct dc_surface *surface) + { + surface->src_rect.x = state->src_x >> 16; +@@ -388,7 +388,7 @@ static bool fill_rects_from_plane_state( + return true; + } + static bool get_fb_info( +- struct amdgpu_framebuffer *amdgpu_fb, ++ const struct amdgpu_framebuffer *amdgpu_fb, + uint64_t *tiling_flags, + uint64_t *fb_location) + { +@@ -412,11 +412,11 @@ static bool get_fb_info( + } + static void fill_plane_attributes_from_fb( + struct dc_surface *surface, +- struct amdgpu_framebuffer *amdgpu_fb) ++ const struct amdgpu_framebuffer *amdgpu_fb) + { + uint64_t tiling_flags; + uint64_t fb_location; +- struct drm_framebuffer *fb = &amdgpu_fb->base; ++ const struct drm_framebuffer *fb = &amdgpu_fb->base; + + get_fb_info( + amdgpu_fb, +@@ -495,7 +495,7 @@ static void fill_plane_attributes_from_fb( + } + + static void fill_gamma_from_crtc( +- struct drm_crtc *crtc, ++ const struct drm_crtc *crtc, + struct dc_surface *dc_surface) + { + int i; +@@ -524,10 +524,10 @@ static void fill_gamma_from_crtc( + } + + static void fill_plane_attributes( +- struct dc_surface *surface, +- struct drm_crtc *crtc) ++ struct dc_surface *surface, ++ const struct drm_crtc *crtc) + { +- struct amdgpu_framebuffer *amdgpu_fb = ++ const struct amdgpu_framebuffer *amdgpu_fb = + to_amdgpu_framebuffer(crtc->primary->state->fb); + fill_rects_from_plane_state(crtc->primary->state, surface); + fill_plane_attributes_from_fb( +@@ -538,33 +538,11 @@ static void fill_plane_attributes( + if (crtc->mode.private_flags & + AMDGPU_CRTC_MODE_PRIVATE_FLAGS_GAMMASET) { + fill_gamma_from_crtc(crtc, surface); +- /* reset trigger of gamma */ +- crtc->mode.private_flags &= +- ~AMDGPU_CRTC_MODE_PRIVATE_FLAGS_GAMMASET; + } + } + + /*****************************************************************************/ + +-struct amdgpu_connector *aconnector_from_drm_crtc( +- struct drm_crtc *crtc, +- struct drm_atomic_state *state) +-{ +- struct drm_connector *connector; +- struct amdgpu_connector *aconnector; +- struct drm_connector_state *conn_state; +- uint8_t i; +- +- for_each_connector_in_state(state, connector, conn_state, i) { +- aconnector = to_amdgpu_connector(connector); +- if (connector->state->crtc == crtc) +- return aconnector; +- } +- +- /* If we get here, not found. */ +- return NULL; +-} +- + struct amdgpu_connector *aconnector_from_drm_crtc_id( + const struct drm_crtc *crtc) + { +@@ -592,11 +570,10 @@ struct amdgpu_connector *aconnector_from_drm_crtc_id( + + static void dm_dc_surface_commit( + struct dc *dc, +- struct drm_crtc *crtc, +- struct amdgpu_framebuffer *afb) ++ struct drm_crtc *crtc) + { + struct dc_surface *dc_surface; +- struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); ++ const struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + struct dc_target *dc_target = acrtc->target; + + if (!dc_target) { +@@ -619,6 +596,12 @@ static void dm_dc_surface_commit( + /* Surface programming */ + + fill_plane_attributes(dc_surface, crtc); ++ if (crtc->mode.private_flags & ++ AMDGPU_CRTC_MODE_PRIVATE_FLAGS_GAMMASET) { ++ /* reset trigger of gamma */ ++ crtc->mode.private_flags &= ++ ~AMDGPU_CRTC_MODE_PRIVATE_FLAGS_GAMMASET; ++ } + + if (false == dc_commit_surfaces_to_target( + dc, +@@ -1343,8 +1326,8 @@ static void clear_unrelated_fields(struct drm_plane_state *state) + } + + static bool page_flip_needed( +- struct drm_plane_state *new_state, +- struct drm_plane_state *old_state) ++ const struct drm_plane_state *new_state, ++ const struct drm_plane_state *old_state) + { + struct drm_plane_state old_state_tmp; + struct drm_plane_state new_state_tmp; +@@ -1499,70 +1482,6 @@ fail: + + } + +-int dm_add_surface_to_validation_set(struct drm_plane *plane, +- struct drm_plane_state *state, struct dc_surface **surface) +-{ +- int res; +- +- struct amdgpu_framebuffer *afb; +- struct amdgpu_connector *aconnector; +- struct drm_crtc *crtc; +- struct drm_framebuffer *fb; +- +- struct drm_device *dev; +- struct amdgpu_device *adev; +- +- res = -EINVAL; +- +- if (NULL == plane || NULL == state) { +- DRM_ERROR("invalid parameters dm_plane_atomic_check\n"); +- return res; +- } +- +- crtc = state->crtc; +- fb = state->fb; +- +- +- afb = to_amdgpu_framebuffer(fb); +- +- if (NULL == state->crtc) { +- return res; +- } +- +- aconnector = aconnector_from_drm_crtc(crtc, state->state); +- +- if (NULL == aconnector) { +- DRM_ERROR("Connector is NULL in dm_plane_atomic_check\n"); +- return res; +- } +- +- if (NULL == aconnector->dc_sink) { +- DRM_ERROR("dc_sink is NULL in dm_plane_atomic_check\n"); +- return res; +- } +- dev = state->crtc->dev; +- adev = dev->dev_private; +- +- *surface = dc_create_surface(adev->dm.dc); +- if (NULL == *surface){ +- DRM_ERROR("surface is NULL\n"); +- return res; +- } +- +- if (!fill_rects_from_plane_state( state, *surface)) { +- DRM_ERROR("Failed to fill surface!\n"); +- goto fail; +- } +- +- fill_plane_attributes_from_fb(*surface, afb); +- +- return MODE_OK; +- +-fail: +- dc_surface_release(*surface); +- return res; +-} +- + static const struct drm_plane_helper_funcs dm_plane_helper_funcs = { + .prepare_fb = dm_plane_helper_prepare_fb, + .cleanup_fb = dm_plane_helper_cleanup_fb, +@@ -1951,8 +1870,7 @@ enum dm_commit_action { + DM_COMMIT_ACTION_SET + }; + +-enum dm_commit_action get_dm_commit_action(struct drm_crtc *crtc, +- struct drm_crtc_state *state) ++static enum dm_commit_action get_dm_commit_action(struct drm_crtc_state *state) + { + /* mode changed means either actually mode changed or enabled changed */ + /* active changed means dpms changed */ +@@ -2103,7 +2021,7 @@ int amdgpu_dm_atomic_commit( + struct amdgpu_display_manager *dm = &adev->dm; + struct drm_plane *plane; + struct drm_plane_state *old_plane_state; +- uint32_t i; ++ uint32_t i, j; + int32_t ret; + uint32_t commit_targets_count = 0; + uint32_t new_crtcs_count = 0; +@@ -2140,25 +2058,34 @@ int amdgpu_dm_atomic_commit( + /* update changed items */ + for_each_crtc_in_state(state, crtc, old_crtc_state, i) { + struct amdgpu_crtc *acrtc; +- struct amdgpu_connector *aconnector; ++ struct amdgpu_connector *aconnector = NULL; + enum dm_commit_action action; + struct drm_crtc_state *new_state = crtc->state; ++ struct drm_connector *connector; ++ struct drm_connector_state *old_con_state; + + acrtc = to_amdgpu_crtc(crtc); +- aconnector = aconnector_from_drm_crtc(crtc, state); ++ ++ for_each_connector_in_state(state, ++ connector, old_con_state, j) { ++ if (connector->state->crtc == crtc) { ++ aconnector = to_amdgpu_connector(connector); ++ break; ++ } ++ } + + /* handles headless hotplug case, updating new_state and + * aconnector as needed + */ + handle_headless_hotplug(acrtc, new_state, &aconnector); +- +- action = get_dm_commit_action(crtc, new_state); +- + if (!aconnector) { +- DRM_ERROR("Can't find connector for crtc %d\n", acrtc->crtc_id); ++ DRM_ERROR("Can't find connector for crtc %d\n", ++ acrtc->crtc_id); + break; + } + ++ action = get_dm_commit_action(new_state); ++ + switch (action) { + case DM_COMMIT_ACTION_DPMS_ON: + case DM_COMMIT_ACTION_SET: { +@@ -2167,7 +2094,7 @@ int amdgpu_dm_atomic_commit( + create_target_for_sink( + aconnector, + &crtc->state->mode); +- ++ DRM_DEBUG_KMS("Atomic commit: SET.\n"); + if (!new_target) { + /* + * this could happen because of issues with +@@ -2218,6 +2145,7 @@ int amdgpu_dm_atomic_commit( + + case DM_COMMIT_ACTION_DPMS_OFF: + case DM_COMMIT_ACTION_RESET: ++ DRM_DEBUG_KMS("Atomic commit: RESET.\n"); + /* i.e. reset mode */ + if (acrtc->target) { + manage_dm_interrupts(adev, acrtc, false); +@@ -2266,10 +2194,7 @@ int amdgpu_dm_atomic_commit( + crtc->state->event, + 0); + else +- dm_dc_surface_commit( +- dm->dc, +- crtc, +- to_amdgpu_framebuffer(fb)); ++ dm_dc_surface_commit(dm->dc, crtc); + } + } + +@@ -2295,102 +2220,224 @@ int amdgpu_dm_atomic_commit( + return 0; + } + ++static uint32_t add_val_sets_surface( ++ struct dc_validation_set *val_sets, ++ uint32_t set_count, ++ const struct dc_target *target, ++ const struct dc_surface *surface) ++{ ++ uint32_t i = 0; ++ ++ while (i < set_count) { ++ if (val_sets[i].target == target) ++ break; ++ ++i; ++ } ++ ++ val_sets[i].surfaces[val_sets[i].surface_count] = surface; ++ val_sets[i].surface_count++; ++ ++ return val_sets[i].surface_count; ++} ++ ++static uint32_t update_in_val_sets_target( ++ struct dc_validation_set *val_sets, ++ uint32_t set_count, ++ const struct dc_target *old_target, ++ const struct dc_target *new_target) ++{ ++ uint32_t i = 0; ++ ++ while (i < set_count) { ++ if (val_sets[i].target == old_target) ++ break; ++ ++i; ++ } ++ ++ val_sets[i].target = new_target; ++ ++ if (i == set_count) { ++ /* nothing found. add new one to the end */ ++ return set_count + 1; ++ } ++ ++ return set_count; ++} ++ ++static uint32_t remove_from_val_sets( ++ struct dc_validation_set *val_sets, ++ uint32_t set_count, ++ const struct dc_target *target) ++{ ++ uint32_t i = 0; ++ ++ while (i < set_count) { ++ if (val_sets[i].target == target) ++ break; ++ ++i; ++ } ++ ++ if (i == set_count) { ++ /* nothing found */ ++ return set_count; ++ } ++ ++ memmove( ++ &val_sets[i], ++ &val_sets[i + 1], ++ sizeof(struct dc_validation_set *) * (set_count - i - 1)); ++ ++ return set_count - 1; ++} ++ + int amdgpu_dm_atomic_check(struct drm_device *dev, +- struct drm_atomic_state *s) ++ struct drm_atomic_state *state) + { + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_plane *plane; + struct drm_plane_state *plane_state; +- struct drm_connector *connector; +- struct drm_connector_state *conn_state; +- int i, j, ret, set_count; ++ int i, j, ret, set_count, new_target_count; + struct dc_validation_set set[MAX_TARGET_NUM] = {{ 0 }}; ++ struct dc_target *new_targets[MAX_TARGET_NUM] = { 0 }; + struct amdgpu_device *adev = dev->dev_private; +- struct amdgpu_connector *aconnector = NULL; +- set_count = 0; ++ struct dc *dc = adev->dm.dc; + +- ret = drm_atomic_helper_check(dev,s); ++ ret = drm_atomic_helper_check(dev, state); + + if (ret) { +- DRM_ERROR("Atomic state integrity validation failed with error :%d !\n",ret); ++ DRM_ERROR("Atomic state validation failed with error :%d !\n", ++ ret); + return ret; + } + + ret = -EINVAL; + +- if (s->num_connector > MAX_TARGET_NUM) { ++ if (state->num_connector > MAX_TARGET_NUM) { + DRM_ERROR("Exceeded max targets number !\n"); + return ret; + } + ++ /* copy existing configuration */ ++ new_target_count = 0; ++ set_count = 0; ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ ++ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); ++ ++ if (acrtc->target) { ++ set[set_count].target = acrtc->target; ++ ++set_count; ++ } ++ } + +- for_each_crtc_in_state(s, crtc, crtc_state, i) { ++ /* update changed items */ ++ for_each_crtc_in_state(state, crtc, crtc_state, i) { ++ struct amdgpu_crtc *acrtc = NULL; ++ struct amdgpu_connector *aconnector = NULL; + enum dm_commit_action action; +- aconnector = NULL; ++ struct drm_connector *connector; ++ struct drm_connector_state *con_state; + +- action = get_dm_commit_action(crtc, crtc_state); +- if (action == DM_COMMIT_ACTION_DPMS_OFF || DM_COMMIT_ACTION_RESET) +- continue; ++ acrtc = to_amdgpu_crtc(crtc); + +- for_each_connector_in_state(s, connector, conn_state, j) { +- if (conn_state->crtc && conn_state->crtc == crtc) { ++ for_each_connector_in_state(state, connector, con_state, j) { ++ if (con_state->crtc == crtc) { + aconnector = to_amdgpu_connector(connector); +- /*I assume at most once connector for CRTC*/ + break; + } + } + +- /*In this case validate against existing connector if possible*/ +- if (!aconnector) +- aconnector = aconnector_from_drm_crtc(crtc, s); ++ /*TODO: ++ handle_headless_hotplug(acrtc, crtc_state, &aconnector);*/ + +- if (!aconnector || !aconnector->dc_sink) +- continue; ++ action = get_dm_commit_action(crtc_state); + +- set[set_count].surface_count = 0; +- ret = dm_create_validation_set_for_target(&aconnector->base, +- &crtc_state->adjusted_mode, &set[set_count]); +- if (ret) +- { +- DRM_ERROR("Creation of validation set target failed !\n"); +- goto end; ++ switch (action) { ++ case DM_COMMIT_ACTION_DPMS_ON: ++ case DM_COMMIT_ACTION_SET: { ++ struct drm_display_mode mode = crtc_state->mode; ++ struct dc_target *new_target = NULL; ++ ++ if (!aconnector) { ++ DRM_ERROR("Can't find connector for crtc %d\n", ++ acrtc->crtc_id); ++ goto connector_not_found; ++ } ++ new_target = ++ create_target_for_sink( ++ aconnector, ++ &mode); ++ new_targets[new_target_count] = new_target; ++ ++ set_count = update_in_val_sets_target( ++ set, ++ set_count, ++ acrtc->target, ++ new_target); ++ new_target_count++; ++ break; + } + +- for_each_plane_in_state(s, plane, plane_state, j) { +- /*Since we use drm_atomic_helper_set_config as our hook we garnteed to have the mask in correct state*/ +- if (crtc_state->plane_mask & (1 << drm_plane_index(plane))) { +- if (set[set_count].surface_count == MAX_SURFACE_NUM) { +- DRM_ERROR("Exceeded max surfaces number per target!\n"); +- ret = MODE_OK; +- goto end; +- } ++ case DM_COMMIT_ACTION_NOTHING: ++ break; ++ case DM_COMMIT_ACTION_DPMS_OFF: ++ case DM_COMMIT_ACTION_RESET: ++ /* i.e. reset mode */ ++ if (acrtc->target) { ++ set_count = remove_from_val_sets( ++ set, ++ set_count, ++ acrtc->target); ++ } ++ break; ++ } ++ } ++ + +- ret = dm_add_surface_to_validation_set(plane,plane_state, +- (struct dc_surface **)&(set[set_count].surfaces[set[set_count].surface_count])); ++ for (i = 0; i < set_count; i++) { ++ for_each_plane_in_state(state, plane, plane_state, j) { ++ struct drm_plane_state *old_plane_state = plane->state; ++ struct drm_framebuffer *fb = plane_state->fb; ++ struct amdgpu_crtc *acrtc = ++ to_amdgpu_crtc(plane_state->crtc); + +- if (ret) { +- DRM_ERROR("Failed to add surface for validation!\n"); +- goto end; +- } ++ if (!fb || acrtc->target != set[i].target) ++ continue; ++ if (!plane_state->crtc->state->planes_changed) ++ continue; + +- set[set_count].surface_count++; ++ if (!page_flip_needed(plane_state, old_plane_state)) { ++ struct dc_surface *surface = ++ dc_create_surface(dc); ++ ++ fill_plane_attributes( ++ surface, plane_state->crtc); ++ add_val_sets_surface( ++ set, ++ set_count, ++ acrtc->target, ++ surface); + } + } + +- set_count++; + } + +- if (!set_count || dc_validate_resources(adev->dm.dc, set, set_count)) { +- ret = MODE_OK; +- } +-end: ++ if (set_count == 0 || dc_validate_resources(dc, set, set_count)) ++ ret = 0; + +- for (i = 0; i < MAX_TARGET_NUM; i++) { +- if (set[i].target) +- dc_target_release((struct dc_target *)set[i].target); ++connector_not_found: ++ for (i = 0; i < set_count; i++) { ++ for (j = 0; j < set[i].surface_count; j++) { ++ dc_surface_release( ++ (struct dc_surface *)set[i].surfaces[j]); ++ } + } ++ for (i = 0; i < new_target_count; i++) ++ dc_target_release(new_targets[i]); + +- return ret; ++ if (ret != 0) ++ DRM_ERROR("Atomic check failed.\n"); + ++ return ret; + } +diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h +index bda39be..0df4636 100644 +--- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h ++++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.h +@@ -59,25 +59,17 @@ void dm_add_display_info( + + int amdgpu_dm_connector_get_modes(struct drm_connector *connector); + +-struct amdgpu_connector *aconnector_from_drm_crtc( +- struct drm_crtc *crtc, +- struct drm_atomic_state *state); +- + int amdgpu_dm_atomic_commit( + struct drm_device *dev, + struct drm_atomic_state *state, + bool async); + int amdgpu_dm_atomic_check(struct drm_device *dev, +- struct drm_atomic_state *state); ++ struct drm_atomic_state *state); + + int dm_create_validation_set_for_target( + struct drm_connector *connector, + struct drm_display_mode *mode, + struct dc_validation_set *val_set); +-int dm_add_surface_to_validation_set( +- struct drm_plane *plane, +- struct drm_plane_state *state, +- struct dc_surface **surface); + + void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector); + struct drm_connector_state *amdgpu_dm_connector_atomic_duplicate_state( +diff --git a/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c b/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c +index 5c72a66..346028a 100644 +--- a/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c ++++ b/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c +@@ -3457,7 +3457,7 @@ bool bw_calcs(struct dc_context *ctx, const struct bw_calcs_input_dceip *dceip, + bw_results_internal->cpup_state_change_enable; + calcs_output->stutter_mode_enable = + bw_results_internal->stutter_mode_enable; +- calcs_output->dispclk = ++ calcs_output->dispclk_khz = + mul(bw_results_internal->dispclk, + int_to_fixed(1000)).value >> 24; + calcs_output->required_sclk = +@@ -3474,7 +3474,7 @@ bool bw_calcs(struct dc_context *ctx, const struct bw_calcs_input_dceip *dceip, + calcs_output->cpuc_state_change_enable = true; + calcs_output->cpup_state_change_enable = true; + calcs_output->stutter_mode_enable = true; +- calcs_output->dispclk = 0; ++ calcs_output->dispclk_khz = 0; + calcs_output->required_sclk = 0; + } + +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c +index 394b645..24e35cd 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c +@@ -1237,7 +1237,7 @@ static void set_display_clock(struct validate_context *context) + context->res_ctx.min_clocks.min_dclk_khz);*/ + } else + dal_display_clock_set_clock(context->res_ctx.pool.display_clock, +- context->bw_results.dispclk); ++ context->bw_results.dispclk_khz); + + /* TODO: When changing display engine clock, DMCU WaitLoop must be + * reconfigured in order to maintain the same delays within DMCU +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c +index 0499976..6eb8152 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c +@@ -44,6 +44,9 @@ enum dce110_clk_src_array_id { + DCE110_CLK_SRC_TOTAL + }; + ++#define DCE110_MAX_DISPCLK 643000 ++#define DCE110_MAX_SCLK 626000 ++ + static void set_vendor_info_packet(struct core_stream *stream, + struct hw_info_packet *info_packet) + { +@@ -1197,22 +1200,27 @@ enum dc_status dce110_validate_bandwidth( + LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS, + "%s: Start bandwidth calculations", + __func__); +- if (true == bw_calcs( +- dc->ctx, +- &dc->bw_dceip, +- &dc->bw_vbios, +- &context->bw_mode_data, +- &context->bw_results)) ++ if (!bw_calcs( ++ dc->ctx, ++ &dc->bw_dceip, ++ &dc->bw_vbios, ++ &context->bw_mode_data, ++ &context->bw_results)) ++ result = DC_FAIL_BANDWIDTH_VALIDATE; ++ else + result = DC_OK; +- else { ++ ++ ++ if (context->bw_results.dispclk_khz > DCE110_MAX_DISPCLK ++ || context->bw_results.required_sclk > DCE110_MAX_SCLK) + result = DC_FAIL_BANDWIDTH_VALIDATE; ++ ++ if (result == DC_FAIL_BANDWIDTH_VALIDATE) + dal_logger_write(dc->ctx->logger, + LOG_MAJOR_BWM, + LOG_MINOR_BWM_MODE_VALIDATION, + "%s: Bandwidth validation failed!", + __func__); +- } +- + + dal_logger_write(dc->ctx->logger, + LOG_MAJOR_BWM, +diff --git a/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h b/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h +index f7315c6..a0c0fef 100644 +--- a/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h ++++ b/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h +@@ -434,7 +434,7 @@ struct bw_calcs_output { + struct bw_watermarks stutter_exit_watermark[4]; + struct bw_watermarks nbp_state_change_watermark[4]; + uint32_t required_sclk; +- uint32_t dispclk; ++ uint32_t dispclk_khz; + }; + + +-- +2.7.4 + |