From 86458ff9af0967a0a9290c5093e9d97149a895ea Mon Sep 17 00:00:00 2001 From: David Rokhvarg Date: Fri, 5 Feb 2016 14:07:16 -0500 Subject: [PATCH 0774/1110] drm/amd/dal: Fix Bandwidth Calculations for up-to 6 displays. Also, fix stack overflow by using a realistic max number of displays, instead of the magic number of 3 (PPLib input was overwritten when 4th display was pluggedin). Signed-off-by: David Rokhvarg Acked-by: Jordan Lazare --- drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c | 15 ++++++--- drivers/gpu/drm/amd/dal/dc/core/dc.c | 2 +- drivers/gpu/drm/amd/dal/dc/core/dc_resource.c | 38 +++++++++++----------- drivers/gpu/drm/amd/dal/dc/core/dc_target.c | 6 ++-- drivers/gpu/drm/amd/dal/dc/dc_types.h | 1 - drivers/gpu/drm/amd/dal/dc/dm_services.h | 2 +- drivers/gpu/drm/amd/dal/dc/dm_services_types.h | 2 -- drivers/gpu/drm/amd/dal/dc/inc/core_types.h | 2 ++ drivers/gpu/drm/amd/dal/dc/inc/resource.h | 3 +- 9 files changed, 40 insertions(+), 31 deletions(-) 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 8faabbc..2b69536 100644 --- a/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c +++ b/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c @@ -3706,9 +3706,15 @@ bool bw_calcs(struct dc_context *ctx, const struct bw_calcs_dceip *dceip, struct bw_calcs_results *bw_results_internal = dm_alloc( ctx, sizeof(struct bw_calcs_results)); struct bw_calcs_mode_data_internal *bw_data_internal = - dm_alloc( - ctx, sizeof(struct bw_calcs_mode_data_internal)); + dm_alloc(ctx, sizeof(struct bw_calcs_mode_data_internal)); + switch (mode_data->number_of_displays) { + case (6): + /* fall through */ + case (5): + /* fall through */ + case (4): + /* fall through */ case (3): bw_data_internal->d2_htotal = mode_data->displays_data[2].h_total; @@ -3722,6 +3728,7 @@ bool bw_calcs(struct dc_context *ctx, const struct bw_calcs_dceip *dceip, mode_data->displays_data[2].graphics_scale_ratio; bw_data_internal->d2_graphics_stereo_mode = mode_data->displays_data[2].graphics_stereo_mode; + /* fall through */ case (2): bw_data_internal->d1_display_write_back_dwb_enable = false; bw_data_internal->d1_underlay_mode = bw_def_none; @@ -3738,7 +3745,7 @@ bool bw_calcs(struct dc_context *ctx, const struct bw_calcs_dceip *dceip, mode_data->displays_data[1].graphics_scale_ratio; bw_data_internal->d1_graphics_stereo_mode = mode_data->displays_data[1].graphics_stereo_mode; - + /* fall through */ case (1): bw_data_internal->d0_fbc_enable = mode_data->displays_data[0].fbc_enable; @@ -3759,7 +3766,7 @@ bool bw_calcs(struct dc_context *ctx, const struct bw_calcs_dceip *dceip, mode_data->displays_data[0].graphics_scale_ratio; bw_data_internal->d0_graphics_stereo_mode = mode_data->displays_data[0].graphics_stereo_mode; - + /* fall through */ default: /* data for all displays */ bw_data_internal->number_of_displays = diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc.c b/drivers/gpu/drm/amd/dal/dc/core/dc.c index 0b8f158..0af63f8 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc.c @@ -607,7 +607,7 @@ bool dc_commit_targets( program_timing_sync(dc->ctx, context); - pplib_apply_display_requirements(dc, context); + pplib_apply_display_requirements(dc, context, &context->pp_display_cfg); /* TODO: disable unused plls*/ fail: diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c index 6375678..eea4eec 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c @@ -530,47 +530,47 @@ void pplib_apply_safe_state( void pplib_apply_display_requirements( const struct dc *dc, - const struct validate_context *context) + const struct validate_context *context, + struct dc_pp_display_configuration *pp_display_cfg) { - struct dc_pp_display_configuration pp_display_cfg = { 0 }; - pp_display_cfg.all_displays_in_sync = + pp_display_cfg->all_displays_in_sync = context->bw_results.all_displays_in_sync; - pp_display_cfg.nb_pstate_switch_disable = + pp_display_cfg->nb_pstate_switch_disable = context->bw_results.nbp_state_change_enable == false; - pp_display_cfg.cpu_cc6_disable = + pp_display_cfg->cpu_cc6_disable = context->bw_results.cpuc_state_change_enable == false; - pp_display_cfg.cpu_pstate_disable = + pp_display_cfg->cpu_pstate_disable = context->bw_results.cpup_state_change_enable == false; - pp_display_cfg.cpu_pstate_separation_time = + pp_display_cfg->cpu_pstate_separation_time = context->bw_results.required_blackout_duration_us; - pp_display_cfg.min_memory_clock_khz = context->bw_results.required_yclk + pp_display_cfg->min_memory_clock_khz = context->bw_results.required_yclk / MEMORY_TYPE_MULTIPLIER; - pp_display_cfg.min_engine_clock_khz = context->bw_results.required_sclk; - pp_display_cfg.min_engine_clock_deep_sleep_khz + pp_display_cfg->min_engine_clock_khz = context->bw_results.required_sclk; + pp_display_cfg->min_engine_clock_deep_sleep_khz = context->bw_results.required_sclk_deep_sleep; - pp_display_cfg.avail_mclk_switch_time_us = + pp_display_cfg->avail_mclk_switch_time_us = get_min_vblank_time_us(context); - pp_display_cfg.avail_mclk_switch_time_in_disp_active_us = 0; + pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; - pp_display_cfg.disp_clk_khz = context->bw_results.dispclk_khz; + pp_display_cfg->disp_clk_khz = context->bw_results.dispclk_khz; - fill_display_configs(context, &pp_display_cfg); + fill_display_configs(context, pp_display_cfg); /* TODO: is this still applicable?*/ - if (pp_display_cfg.display_count == 1) { + if (pp_display_cfg->display_count == 1) { const struct dc_crtc_timing *timing = &context->targets[0]->public.streams[0]->timing; - pp_display_cfg.crtc_index = - pp_display_cfg.disp_configs[0].pipe_idx; - pp_display_cfg.line_time_in_us = timing->h_total * 1000 + pp_display_cfg->crtc_index = + pp_display_cfg->disp_configs[0].pipe_idx; + pp_display_cfg->line_time_in_us = timing->h_total * 1000 / timing->pix_clk_khz; } - dm_pp_apply_display_requirements(dc->ctx, &pp_display_cfg); + dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); } /* Maximum TMDS single link pixel clock 165MHz */ diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c index e93e73d..7980e9f 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c @@ -288,7 +288,8 @@ bool dc_commit_surfaces_to_target( if (prev_disp_clk < dc->current_context.bw_results.dispclk_khz) { dc->hwss.program_bw(dc, &dc->current_context); - pplib_apply_display_requirements(dc, &dc->current_context); + pplib_apply_display_requirements(dc, &dc->current_context, + &dc->current_context.pp_display_cfg); } if (current_enabled_surface_count > 0 && new_enabled_surface_count == 0) @@ -322,7 +323,8 @@ bool dc_commit_surfaces_to_target( /* Lower display clock if necessary */ if (prev_disp_clk > dc->current_context.bw_results.dispclk_khz) { dc->hwss.program_bw(dc, &dc->current_context); - pplib_apply_display_requirements(dc, &dc->current_context); + pplib_apply_display_requirements(dc, &dc->current_context, + &dc->current_context.pp_display_cfg); } return true; diff --git a/drivers/gpu/drm/amd/dal/dc/dc_types.h b/drivers/gpu/drm/amd/dal/dc/dc_types.h index 21aad94..2abdda7 100644 --- a/drivers/gpu/drm/amd/dal/dc/dc_types.h +++ b/drivers/gpu/drm/amd/dal/dc/dc_types.h @@ -749,7 +749,6 @@ struct dc_csc_adjustments { struct fixed31_32 hue; }; - enum { MAX_LANES = 2, MAX_COFUNC_PATH = 6, diff --git a/drivers/gpu/drm/amd/dal/dc/dm_services.h b/drivers/gpu/drm/amd/dal/dc/dm_services.h index 206c0b7..33f700e 100644 --- a/drivers/gpu/drm/amd/dal/dc/dm_services.h +++ b/drivers/gpu/drm/amd/dal/dc/dm_services.h @@ -303,7 +303,7 @@ struct dc_pp_display_configuration { bool all_displays_in_sync; uint8_t display_count; - struct dc_pp_single_disp_config disp_configs[3]; + struct dc_pp_single_disp_config disp_configs[MAX_COFUNC_PATH]; /*Controller Index of primary display - used in MCLK SMC switching hang * SW Workaround*/ diff --git a/drivers/gpu/drm/amd/dal/dc/dm_services_types.h b/drivers/gpu/drm/amd/dal/dc/dm_services_types.h index bc458aa..7c8b31f 100644 --- a/drivers/gpu/drm/amd/dal/dc/dm_services_types.h +++ b/drivers/gpu/drm/amd/dal/dc/dm_services_types.h @@ -26,8 +26,6 @@ #ifndef __DM_SERVICES_TYPES_H__ #define __DM_SERVICES_TYPES_H__ -#define INVALID_DISPLAY_INDEX 0xffffffff - #if defined __KERNEL__ #include diff --git a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h index 6a81518..bd7bd2b 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h @@ -345,6 +345,8 @@ struct validate_context { struct bw_calcs_mode_data bw_mode_data; /* The output from BW and WM calculations. */ struct bw_calcs_output bw_results; + /* Note: this is a big structure, do *not* put on stack! */ + struct dc_pp_display_configuration pp_display_cfg; }; diff --git a/drivers/gpu/drm/amd/dal/dc/inc/resource.h b/drivers/gpu/drm/amd/dal/dc/inc/resource.h index bda92e3..b4936b4 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/resource.h @@ -69,7 +69,8 @@ void pplib_apply_safe_state(const struct dc *dc); void pplib_apply_display_requirements( const struct dc *dc, - const struct validate_context *context); + const struct validate_context *context, + struct dc_pp_display_configuration *pp_display_cfg); void build_info_frame(struct core_stream *stream); -- 2.7.4