mirror of
https://github.com/torvalds/linux.git
synced 2026-06-30 01:55:39 +02:00
drm/amd/display: bandwidth update fix
Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> Acked-by: Harry Wentland <Harry.Wentland@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
45209ef719
commit
cf43759306
|
|
@ -795,159 +795,6 @@ static bool streams_changed(
|
|||
return false;
|
||||
}
|
||||
|
||||
static void fill_display_configs(
|
||||
const struct validate_context *context,
|
||||
struct dm_pp_display_configuration *pp_display_cfg)
|
||||
{
|
||||
int j;
|
||||
int num_cfgs = 0;
|
||||
|
||||
for (j = 0; j < context->stream_count; j++) {
|
||||
int k;
|
||||
|
||||
const struct core_stream *stream = context->streams[j];
|
||||
struct dm_pp_single_disp_config *cfg =
|
||||
&pp_display_cfg->disp_configs[num_cfgs];
|
||||
const struct pipe_ctx *pipe_ctx = NULL;
|
||||
|
||||
for (k = 0; k < MAX_PIPES; k++)
|
||||
if (stream == context->res_ctx.pipe_ctx[k].stream) {
|
||||
pipe_ctx = &context->res_ctx.pipe_ctx[k];
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT(pipe_ctx != NULL);
|
||||
|
||||
num_cfgs++;
|
||||
cfg->signal = pipe_ctx->stream->signal;
|
||||
cfg->pipe_idx = pipe_ctx->pipe_idx;
|
||||
cfg->src_height = stream->public.src.height;
|
||||
cfg->src_width = stream->public.src.width;
|
||||
cfg->ddi_channel_mapping =
|
||||
stream->sink->link->ddi_channel_mapping.raw;
|
||||
cfg->transmitter =
|
||||
stream->sink->link->link_enc->transmitter;
|
||||
cfg->link_settings.lane_count =
|
||||
stream->sink->link->public.cur_link_settings.lane_count;
|
||||
cfg->link_settings.link_rate =
|
||||
stream->sink->link->public.cur_link_settings.link_rate;
|
||||
cfg->link_settings.link_spread =
|
||||
stream->sink->link->public.cur_link_settings.link_spread;
|
||||
cfg->sym_clock = stream->phy_pix_clk;
|
||||
/* Round v_refresh*/
|
||||
cfg->v_refresh = stream->public.timing.pix_clk_khz * 1000;
|
||||
cfg->v_refresh /= stream->public.timing.h_total;
|
||||
cfg->v_refresh = (cfg->v_refresh + stream->public.timing.v_total / 2)
|
||||
/ stream->public.timing.v_total;
|
||||
}
|
||||
|
||||
pp_display_cfg->display_count = num_cfgs;
|
||||
}
|
||||
|
||||
static uint32_t get_min_vblank_time_us(const struct validate_context *context)
|
||||
{
|
||||
uint8_t j;
|
||||
uint32_t min_vertical_blank_time = -1;
|
||||
|
||||
for (j = 0; j < context->stream_count; j++) {
|
||||
const struct dc_stream *stream = &context->streams[j]->public;
|
||||
uint32_t vertical_blank_in_pixels = 0;
|
||||
uint32_t vertical_blank_time = 0;
|
||||
|
||||
vertical_blank_in_pixels = stream->timing.h_total *
|
||||
(stream->timing.v_total
|
||||
- stream->timing.v_addressable);
|
||||
|
||||
vertical_blank_time = vertical_blank_in_pixels
|
||||
* 1000 / stream->timing.pix_clk_khz;
|
||||
|
||||
if (min_vertical_blank_time > vertical_blank_time)
|
||||
min_vertical_blank_time = vertical_blank_time;
|
||||
}
|
||||
|
||||
return min_vertical_blank_time;
|
||||
}
|
||||
|
||||
static int determine_sclk_from_bounding_box(
|
||||
const struct core_dc *dc,
|
||||
int required_sclk)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Some asics do not give us sclk levels, so we just report the actual
|
||||
* required sclk
|
||||
*/
|
||||
if (dc->sclk_lvls.num_levels == 0)
|
||||
return required_sclk;
|
||||
|
||||
for (i = 0; i < dc->sclk_lvls.num_levels; i++) {
|
||||
if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk)
|
||||
return dc->sclk_lvls.clocks_in_khz[i];
|
||||
}
|
||||
/*
|
||||
* even maximum level could not satisfy requirement, this
|
||||
* is unexpected at this stage, should have been caught at
|
||||
* validation time
|
||||
*/
|
||||
ASSERT(0);
|
||||
return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1];
|
||||
}
|
||||
|
||||
void pplib_apply_display_requirements(
|
||||
struct core_dc *dc,
|
||||
const struct validate_context *context,
|
||||
struct dm_pp_display_configuration *pp_display_cfg)
|
||||
{
|
||||
pp_display_cfg->all_displays_in_sync =
|
||||
context->bw_results.all_displays_in_sync;
|
||||
pp_display_cfg->nb_pstate_switch_disable =
|
||||
context->bw_results.nbp_state_change_enable == false;
|
||||
pp_display_cfg->cpu_cc6_disable =
|
||||
context->bw_results.cpuc_state_change_enable == false;
|
||||
pp_display_cfg->cpu_pstate_disable =
|
||||
context->bw_results.cpup_state_change_enable == false;
|
||||
pp_display_cfg->cpu_pstate_separation_time =
|
||||
context->bw_results.blackout_recovery_time_us;
|
||||
|
||||
pp_display_cfg->min_memory_clock_khz = context->bw_results.required_yclk
|
||||
/ MEMORY_TYPE_MULTIPLIER;
|
||||
|
||||
pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box(
|
||||
dc,
|
||||
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 =
|
||||
get_min_vblank_time_us(context);
|
||||
/* TODO: dce11.2*/
|
||||
pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0;
|
||||
|
||||
pp_display_cfg->disp_clk_khz = context->dispclk_khz;
|
||||
|
||||
fill_display_configs(context, pp_display_cfg);
|
||||
|
||||
/* TODO: is this still applicable?*/
|
||||
if (pp_display_cfg->display_count == 1) {
|
||||
const struct dc_crtc_timing *timing =
|
||||
&context->streams[0]->public.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
|
||||
/ timing->pix_clk_khz;
|
||||
}
|
||||
|
||||
if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof(
|
||||
struct dm_pp_display_configuration)) != 0)
|
||||
dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
|
||||
|
||||
dc->prev_display_config = *pp_display_cfg;
|
||||
|
||||
}
|
||||
|
||||
bool dc_commit_streams(
|
||||
struct dc *dc,
|
||||
const struct dc_stream *streams[],
|
||||
|
|
@ -1036,9 +883,6 @@ bool dc_commit_streams(
|
|||
context->streams[i]->public.timing.pix_clk_khz);
|
||||
}
|
||||
|
||||
pplib_apply_display_requirements(core_dc,
|
||||
context, &context->pp_display_cfg);
|
||||
|
||||
resource_validate_ctx_destruct(core_dc->current_context);
|
||||
|
||||
if (core_dc->temp_flip_context != core_dc->current_context) {
|
||||
|
|
@ -1065,7 +909,6 @@ bool dc_pre_update_surfaces_to_stream(
|
|||
{
|
||||
int i, j;
|
||||
struct core_dc *core_dc = DC_TO_CORE(dc);
|
||||
int prev_disp_clk = core_dc->current_context->dispclk_khz;
|
||||
struct dc_stream_status *stream_status = NULL;
|
||||
struct validate_context *context;
|
||||
bool ret = true;
|
||||
|
|
@ -1150,16 +993,7 @@ bool dc_pre_update_surfaces_to_stream(
|
|||
goto unexpected_fail;
|
||||
}
|
||||
|
||||
if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)
|
||||
&& prev_disp_clk < context->dispclk_khz) {
|
||||
pplib_apply_display_requirements(core_dc, context,
|
||||
&context->pp_display_cfg);
|
||||
context->res_ctx.pool->display_clock->funcs->set_clock(
|
||||
context->res_ctx.pool->display_clock,
|
||||
context->dispclk_khz * 115 / 100);
|
||||
core_dc->current_context->bw_results.dispclk_khz = context->dispclk_khz;
|
||||
core_dc->current_context->dispclk_khz = context->dispclk_khz;
|
||||
}
|
||||
core_dc->hwss.set_bandwidth(core_dc, context, false);
|
||||
|
||||
for (i = 0; i < new_surface_count; i++)
|
||||
for (j = 0; j < context->res_ctx.pool->pipe_count; j++) {
|
||||
|
|
@ -1206,10 +1040,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
|
|||
return false;
|
||||
}
|
||||
|
||||
core_dc->hwss.set_bandwidth(core_dc);
|
||||
|
||||
/*TODO: dce specific*/
|
||||
pplib_apply_display_requirements(core_dc, context, &context->pp_display_cfg);
|
||||
core_dc->hwss.set_bandwidth(core_dc, context, true);
|
||||
|
||||
resource_validate_ctx_destruct(core_dc->current_context);
|
||||
core_dc->current_context = context;
|
||||
|
|
|
|||
|
|
@ -104,22 +104,18 @@ static bool dce100_enable_display_power_gating(
|
|||
return false;
|
||||
}
|
||||
|
||||
static void set_display_mark_for_pipe_if_needed(struct core_dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct validate_context *context)
|
||||
{
|
||||
/* Do nothing until we have proper bandwitdth calcs */
|
||||
}
|
||||
|
||||
static void set_displaymarks(
|
||||
const struct core_dc *dc, struct validate_context *context)
|
||||
{
|
||||
/* Do nothing until we have proper bandwitdth calcs */
|
||||
}
|
||||
|
||||
static void set_bandwidth(struct core_dc *dc)
|
||||
static void set_bandwidth(
|
||||
struct core_dc *dc,
|
||||
struct validate_context *context,
|
||||
bool decrease_allowed)
|
||||
{
|
||||
/* Do nothing until we have proper bandwitdth calcs */
|
||||
dc->hwss.set_displaymarks(dc, context);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -132,7 +128,6 @@ bool dce100_hw_sequencer_construct(struct core_dc *dc)
|
|||
/* TODO: dce80 is empty implementation at the moment*/
|
||||
dc->hwss.enable_display_power_gating = dce100_enable_display_power_gating;
|
||||
dc->hwss.set_displaymarks = set_displaymarks;
|
||||
dc->hwss.increase_watermarks_for_pipe = set_display_mark_for_pipe_if_needed;
|
||||
dc->hwss.set_bandwidth = set_bandwidth;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1209,93 +1209,6 @@ static uint32_t compute_pstate_blackout_duration(
|
|||
return total_dest_line_time_ns;
|
||||
}
|
||||
|
||||
/* get the index of the pipe_ctx if there were no gaps in the pipe_ctx array*/
|
||||
int get_bw_result_idx(
|
||||
struct resource_context *res_ctx,
|
||||
int pipe_idx)
|
||||
{
|
||||
int i, collapsed_idx;
|
||||
|
||||
if (res_ctx->pipe_ctx[pipe_idx].top_pipe)
|
||||
return 3;
|
||||
|
||||
collapsed_idx = 0;
|
||||
for (i = 0; i < pipe_idx; i++) {
|
||||
if (res_ctx->pipe_ctx[i].stream)
|
||||
collapsed_idx++;
|
||||
}
|
||||
|
||||
return collapsed_idx;
|
||||
}
|
||||
|
||||
static bool is_watermark_set_a_greater(
|
||||
const struct bw_watermarks *set_a,
|
||||
const struct bw_watermarks *set_b)
|
||||
{
|
||||
if (set_a->a_mark > set_b->a_mark
|
||||
|| set_a->b_mark > set_b->b_mark
|
||||
|| set_a->c_mark > set_b->c_mark
|
||||
|| set_a->d_mark > set_b->d_mark)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool did_watermarks_increase(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct validate_context *context,
|
||||
struct validate_context *old_context)
|
||||
{
|
||||
int collapsed_pipe_idx = get_bw_result_idx(&context->res_ctx,
|
||||
pipe_ctx->pipe_idx);
|
||||
int old_collapsed_pipe_idx = get_bw_result_idx(&old_context->res_ctx,
|
||||
pipe_ctx->pipe_idx);
|
||||
struct pipe_ctx *old_pipe_ctx = &old_context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
|
||||
|
||||
if (!old_pipe_ctx->stream)
|
||||
return true;
|
||||
|
||||
if (is_watermark_set_a_greater(
|
||||
&context->bw_results.nbp_state_change_wm_ns[collapsed_pipe_idx],
|
||||
&old_context->bw_results.nbp_state_change_wm_ns[old_collapsed_pipe_idx]))
|
||||
return true;
|
||||
if (is_watermark_set_a_greater(
|
||||
&context->bw_results.stutter_exit_wm_ns[collapsed_pipe_idx],
|
||||
&old_context->bw_results.stutter_exit_wm_ns[old_collapsed_pipe_idx]))
|
||||
return true;
|
||||
if (is_watermark_set_a_greater(
|
||||
&context->bw_results.urgent_wm_ns[collapsed_pipe_idx],
|
||||
&old_context->bw_results.urgent_wm_ns[old_collapsed_pipe_idx]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void program_wm_for_pipe(struct core_dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct validate_context *context)
|
||||
{
|
||||
int total_dest_line_time_ns = compute_pstate_blackout_duration(
|
||||
dc->bw_vbios.blackout_duration,
|
||||
pipe_ctx->stream);
|
||||
int bw_result_idx = get_bw_result_idx(&context->res_ctx,
|
||||
pipe_ctx->pipe_idx);
|
||||
|
||||
pipe_ctx->mi->funcs->mem_input_program_display_marks(
|
||||
pipe_ctx->mi,
|
||||
context->bw_results.nbp_state_change_wm_ns[bw_result_idx],
|
||||
context->bw_results.stutter_exit_wm_ns[bw_result_idx],
|
||||
context->bw_results.urgent_wm_ns[bw_result_idx],
|
||||
total_dest_line_time_ns);
|
||||
|
||||
if (pipe_ctx->top_pipe)
|
||||
pipe_ctx->mi->funcs->mem_input_program_chroma_display_marks(
|
||||
pipe_ctx->mi,
|
||||
context->bw_results.nbp_state_change_wm_ns[bw_result_idx + 1],
|
||||
context->bw_results.stutter_exit_wm_ns[bw_result_idx + 1],
|
||||
context->bw_results.urgent_wm_ns[bw_result_idx + 1],
|
||||
total_dest_line_time_ns);
|
||||
}
|
||||
|
||||
void dce110_set_displaymarks(
|
||||
const struct core_dc *dc,
|
||||
struct validate_context *context)
|
||||
|
|
@ -1589,7 +1502,7 @@ static void reset_hw_ctx_wrap(
|
|||
}
|
||||
}
|
||||
|
||||
/*TODO: const validate_context*/
|
||||
|
||||
enum dc_status dce110_apply_ctx_to_hw(
|
||||
struct core_dc *dc,
|
||||
struct validate_context *context)
|
||||
|
|
@ -1768,7 +1681,7 @@ enum dc_status dce110_apply_ctx_to_hw(
|
|||
return status;
|
||||
}
|
||||
|
||||
dc->hwss.set_displaymarks(dc, context);
|
||||
dc->hwss.set_bandwidth(dc, context, true);
|
||||
|
||||
/* to save power */
|
||||
apply_min_clocks(dc, context, &clocks_state, false);
|
||||
|
|
@ -1777,6 +1690,7 @@ enum dc_status dce110_apply_ctx_to_hw(
|
|||
|
||||
switch_dp_clock_sources(dc, &context->res_ctx);
|
||||
|
||||
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2135,7 +2049,6 @@ static void init_hw(struct core_dc *dc)
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: move this to apply_ctx_tohw some how?*/
|
||||
static void dce110_power_on_pipe_if_needed(
|
||||
struct core_dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
|
|
@ -2180,31 +2093,175 @@ static void dce110_power_on_pipe_if_needed(
|
|||
}
|
||||
}
|
||||
|
||||
static void dce110_increase_watermarks_for_pipe(
|
||||
struct core_dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct validate_context *context)
|
||||
static void fill_display_configs(
|
||||
const struct validate_context *context,
|
||||
struct dm_pp_display_configuration *pp_display_cfg)
|
||||
{
|
||||
if (did_watermarks_increase(pipe_ctx, context, dc->current_context))
|
||||
program_wm_for_pipe(dc, pipe_ctx, context);
|
||||
int j;
|
||||
int num_cfgs = 0;
|
||||
|
||||
for (j = 0; j < context->stream_count; j++) {
|
||||
int k;
|
||||
|
||||
const struct core_stream *stream = context->streams[j];
|
||||
struct dm_pp_single_disp_config *cfg =
|
||||
&pp_display_cfg->disp_configs[num_cfgs];
|
||||
const struct pipe_ctx *pipe_ctx = NULL;
|
||||
|
||||
for (k = 0; k < MAX_PIPES; k++)
|
||||
if (stream == context->res_ctx.pipe_ctx[k].stream) {
|
||||
pipe_ctx = &context->res_ctx.pipe_ctx[k];
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT(pipe_ctx != NULL);
|
||||
|
||||
num_cfgs++;
|
||||
cfg->signal = pipe_ctx->stream->signal;
|
||||
cfg->pipe_idx = pipe_ctx->pipe_idx;
|
||||
cfg->src_height = stream->public.src.height;
|
||||
cfg->src_width = stream->public.src.width;
|
||||
cfg->ddi_channel_mapping =
|
||||
stream->sink->link->ddi_channel_mapping.raw;
|
||||
cfg->transmitter =
|
||||
stream->sink->link->link_enc->transmitter;
|
||||
cfg->link_settings.lane_count =
|
||||
stream->sink->link->public.cur_link_settings.lane_count;
|
||||
cfg->link_settings.link_rate =
|
||||
stream->sink->link->public.cur_link_settings.link_rate;
|
||||
cfg->link_settings.link_spread =
|
||||
stream->sink->link->public.cur_link_settings.link_spread;
|
||||
cfg->sym_clock = stream->phy_pix_clk;
|
||||
/* Round v_refresh*/
|
||||
cfg->v_refresh = stream->public.timing.pix_clk_khz * 1000;
|
||||
cfg->v_refresh /= stream->public.timing.h_total;
|
||||
cfg->v_refresh = (cfg->v_refresh + stream->public.timing.v_total / 2)
|
||||
/ stream->public.timing.v_total;
|
||||
}
|
||||
|
||||
pp_display_cfg->display_count = num_cfgs;
|
||||
}
|
||||
|
||||
static void dce110_set_bandwidth(struct core_dc *dc)
|
||||
static uint32_t get_min_vblank_time_us(const struct validate_context *context)
|
||||
{
|
||||
uint8_t j;
|
||||
uint32_t min_vertical_blank_time = -1;
|
||||
|
||||
for (j = 0; j < context->stream_count; j++) {
|
||||
const struct dc_stream *stream = &context->streams[j]->public;
|
||||
uint32_t vertical_blank_in_pixels = 0;
|
||||
uint32_t vertical_blank_time = 0;
|
||||
|
||||
vertical_blank_in_pixels = stream->timing.h_total *
|
||||
(stream->timing.v_total
|
||||
- stream->timing.v_addressable);
|
||||
|
||||
vertical_blank_time = vertical_blank_in_pixels
|
||||
* 1000 / stream->timing.pix_clk_khz;
|
||||
|
||||
if (min_vertical_blank_time > vertical_blank_time)
|
||||
min_vertical_blank_time = vertical_blank_time;
|
||||
}
|
||||
|
||||
return min_vertical_blank_time;
|
||||
}
|
||||
|
||||
static int determine_sclk_from_bounding_box(
|
||||
const struct core_dc *dc,
|
||||
int required_sclk)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dc->current_context->res_ctx.pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &dc->current_context->res_ctx.pipe_ctx[i];
|
||||
/*
|
||||
* Some asics do not give us sclk levels, so we just report the actual
|
||||
* required sclk
|
||||
*/
|
||||
if (dc->sclk_lvls.num_levels == 0)
|
||||
return required_sclk;
|
||||
|
||||
if (!pipe_ctx->stream)
|
||||
continue;
|
||||
for (i = 0; i < dc->sclk_lvls.num_levels; i++) {
|
||||
if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk)
|
||||
return dc->sclk_lvls.clocks_in_khz[i];
|
||||
}
|
||||
/*
|
||||
* even maximum level could not satisfy requirement, this
|
||||
* is unexpected at this stage, should have been caught at
|
||||
* validation time
|
||||
*/
|
||||
ASSERT(0);
|
||||
return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1];
|
||||
}
|
||||
|
||||
program_wm_for_pipe(dc, pipe_ctx, dc->current_context);
|
||||
static void pplib_apply_display_requirements(
|
||||
struct core_dc *dc,
|
||||
struct validate_context *context)
|
||||
{
|
||||
struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
|
||||
|
||||
pp_display_cfg->all_displays_in_sync =
|
||||
context->bw_results.all_displays_in_sync;
|
||||
pp_display_cfg->nb_pstate_switch_disable =
|
||||
context->bw_results.nbp_state_change_enable == false;
|
||||
pp_display_cfg->cpu_cc6_disable =
|
||||
context->bw_results.cpuc_state_change_enable == false;
|
||||
pp_display_cfg->cpu_pstate_disable =
|
||||
context->bw_results.cpup_state_change_enable == false;
|
||||
pp_display_cfg->cpu_pstate_separation_time =
|
||||
context->bw_results.blackout_recovery_time_us;
|
||||
|
||||
pp_display_cfg->min_memory_clock_khz = context->bw_results.required_yclk
|
||||
/ MEMORY_TYPE_MULTIPLIER;
|
||||
|
||||
pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box(
|
||||
dc,
|
||||
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 =
|
||||
get_min_vblank_time_us(context);
|
||||
/* TODO: dce11.2*/
|
||||
pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0;
|
||||
|
||||
pp_display_cfg->disp_clk_khz = context->dispclk_khz;
|
||||
|
||||
fill_display_configs(context, pp_display_cfg);
|
||||
|
||||
/* TODO: is this still applicable?*/
|
||||
if (pp_display_cfg->display_count == 1) {
|
||||
const struct dc_crtc_timing *timing =
|
||||
&context->streams[0]->public.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
|
||||
/ timing->pix_clk_khz;
|
||||
}
|
||||
|
||||
dc->current_context->res_ctx.pool->display_clock->funcs->set_clock(
|
||||
dc->current_context->res_ctx.pool->display_clock,
|
||||
dc->current_context->dispclk_khz * 115 / 100);
|
||||
if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof(
|
||||
struct dm_pp_display_configuration)) != 0)
|
||||
dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
|
||||
|
||||
dc->prev_display_config = *pp_display_cfg;
|
||||
}
|
||||
|
||||
static void dce110_set_bandwidth(
|
||||
struct core_dc *dc,
|
||||
struct validate_context *context,
|
||||
bool decrease_allowed)
|
||||
{
|
||||
dc->hwss.set_displaymarks(dc, context);
|
||||
|
||||
if (decrease_allowed || context->dispclk_khz > dc->current_context->dispclk_khz) {
|
||||
context->res_ctx.pool->display_clock->funcs->set_clock(
|
||||
context->res_ctx.pool->display_clock,
|
||||
context->dispclk_khz * 115 / 100);
|
||||
dc->current_context->bw_results.dispclk_khz = context->dispclk_khz;
|
||||
dc->current_context->dispclk_khz = context->dispclk_khz;
|
||||
}
|
||||
|
||||
pplib_apply_display_requirements(dc, context);
|
||||
}
|
||||
|
||||
static void dce110_program_front_end_for_pipe(
|
||||
|
|
@ -2335,15 +2392,6 @@ static void dce110_program_front_end_for_pipe(
|
|||
pipe_ctx->scl_data.recout.y);
|
||||
}
|
||||
|
||||
static void dce110_prepare_pipe_for_context(
|
||||
struct core_dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct validate_context *context)
|
||||
{
|
||||
dce110_power_on_pipe_if_needed(dc, pipe_ctx, context);
|
||||
dc->hwss.increase_watermarks_for_pipe(dc, pipe_ctx, context);
|
||||
}
|
||||
|
||||
static void dce110_apply_ctx_for_surface(
|
||||
struct core_dc *dc,
|
||||
struct core_surface *surface,
|
||||
|
|
@ -2388,7 +2436,7 @@ static void dce110_power_down_fe(struct core_dc *dc, struct pipe_ctx *pipe)
|
|||
static const struct hw_sequencer_funcs dce110_funcs = {
|
||||
.init_hw = init_hw,
|
||||
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
||||
.prepare_pipe_for_context = dce110_prepare_pipe_for_context,
|
||||
.prepare_pipe_for_context = dce110_power_on_pipe_if_needed,
|
||||
.apply_ctx_for_surface = dce110_apply_ctx_for_surface,
|
||||
.set_plane_config = set_plane_config,
|
||||
.update_plane_addr = update_plane_addr,
|
||||
|
|
@ -2407,7 +2455,6 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
|||
.power_down_front_end = dce110_power_down_fe,
|
||||
.pipe_control_lock = dce_pipe_control_lock,
|
||||
.set_displaymarks = dce110_set_displaymarks,
|
||||
.increase_watermarks_for_pipe = dce110_increase_watermarks_for_pipe,
|
||||
.set_bandwidth = dce110_set_bandwidth,
|
||||
.set_drr = set_drr,
|
||||
.set_static_screen_control = set_static_screen_control,
|
||||
|
|
|
|||
|
|
@ -106,23 +106,18 @@ static bool dce80_enable_display_power_gating(
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void set_display_mark_for_pipe_if_needed(struct core_dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct validate_context *context)
|
||||
{
|
||||
/* Do nothing until we have proper bandwitdth calcs */
|
||||
}
|
||||
|
||||
static void set_displaymarks(
|
||||
const struct core_dc *dc, struct validate_context *context)
|
||||
{
|
||||
/* Do nothing until we have proper bandwitdth calcs */
|
||||
}
|
||||
|
||||
static void set_bandwidth(struct core_dc *dc)
|
||||
static void set_bandwidth(
|
||||
struct core_dc *dc,
|
||||
struct validate_context *context,
|
||||
bool decrease_allowed)
|
||||
{
|
||||
/* Do nothing until we have proper bandwitdth calcs */
|
||||
dc->hwss.set_displaymarks(dc, context);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -133,7 +128,6 @@ bool dce80_hw_sequencer_construct(struct core_dc *dc)
|
|||
dc->hwss.enable_display_power_gating = dce80_enable_display_power_gating;
|
||||
dc->hwss.pipe_control_lock = dce_pipe_control_lock;
|
||||
dc->hwss.set_displaymarks = set_displaymarks;
|
||||
dc->hwss.increase_watermarks_for_pipe = set_display_mark_for_pipe_if_needed;
|
||||
dc->hwss.set_bandwidth = set_bandwidth;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -124,11 +124,10 @@ struct hw_sequencer_funcs {
|
|||
const struct core_dc *dc,
|
||||
struct validate_context *context);
|
||||
|
||||
void (*increase_watermarks_for_pipe)(struct core_dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct validate_context *context);
|
||||
|
||||
void (*set_bandwidth)(struct core_dc *dc);
|
||||
void (*set_bandwidth)(
|
||||
struct core_dc *dc,
|
||||
struct validate_context *context,
|
||||
bool decrease_allowed);
|
||||
|
||||
void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes,
|
||||
int vmin, int vmax);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user