drm/amd/display: Add block sequence support for bandwidth programming operations

[why]
Bandwidth clock programming build and execution phases were coupled,
preventing the HWSS from orchestrating them through block sequencing.

[how]
Separate clock programming into build and execute phases across
latest versions. Build phase populates the clk_mgr internal block
sequence array, then registers a single CLK_MGR_UPDATE_CLOCKS HWSS step.
Execute phase dispatches the pre-built sequence. Add HWSS operations for
clk_mgr_set_max_memclk, hubbub_program_watermarks, hubbub_program_arbiter,
and hubbub_program_compbuf_segments.

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Bhuvanachandra Pinninti <BhuvanaChandra.Pinninti@amd.com>
Signed-off-by: George Zhang <george.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Bhuvanachandra Pinninti
2026-04-24 19:52:25 +05:30
committed by Alex Deucher
parent b34e4c1d05
commit f3403ab74a
9 changed files with 416 additions and 5 deletions

View File

@@ -10,6 +10,7 @@
#include "dcn31/dcn31_clk_mgr.h"
#include "dcn32/dcn32_clk_mgr.h"
#include "dcn401/dcn401_clk_mgr.h"
#include "hw_sequencer.h"
#include "reg_helper.h"
#include "core_types.h"
#include "dm_helpers.h"
@@ -1085,7 +1086,8 @@ static unsigned int dcn401_build_update_display_clocks_sequence(
struct clk_mgr *clk_mgr_base,
struct dc_state *context,
struct dc_clocks *new_clocks,
bool safe_to_lower)
bool safe_to_lower,
unsigned int num_steps_start)
{
struct clk_mgr_internal *clk_mgr_internal = TO_CLK_MGR_INTERNAL(clk_mgr_base);
struct dcn401_clk_mgr *clk_mgr401 = TO_DCN401_CLK_MGR(clk_mgr_internal);
@@ -1100,7 +1102,7 @@ static unsigned int dcn401_build_update_display_clocks_sequence(
bool frl_present = false;
unsigned int i;
unsigned int num_steps = 0;
unsigned int num_steps = num_steps_start;
/* CLK_MGR401_READ_CLOCKS_FROM_DENTIST */
if (clk_mgr_base->clks.dispclk_khz == 0 ||
@@ -1239,6 +1241,44 @@ static unsigned int dcn401_build_update_display_clocks_sequence(
return num_steps;
}
/*
* Build-for-BLS functions.
* These build both bandwidth and display clock sequences into the clk_mgr's
* internal block sequence array, then add a single CLK_MGR_UPDATE_CLOCKS step
* to the HWSS block sequence whose executor will call
* execute_clk_mgr_block_sequence to dispatch all accumulated steps.
*/
void dcn401_build_clock_update_for_bls(
struct clk_mgr *clk_mgr_base,
struct dc_state *context,
bool safe_to_lower,
struct block_sequence_state *seq_state)
{
struct clk_mgr_internal *clk_mgr_internal = TO_CLK_MGR_INTERNAL(clk_mgr_base);
struct dcn401_clk_mgr *clk_mgr401 = TO_DCN401_CLK_MGR(clk_mgr_internal);
unsigned int num_bw_steps;
unsigned int total_steps;
/* Build bandwidth clocks sequence starting at index 0 */
num_bw_steps = dcn401_build_update_bandwidth_clocks_sequence(clk_mgr_base,
context,
&context->bw_ctx.bw.dcn.clk,
safe_to_lower);
/* Build display clocks sequence appended after bandwidth steps */
total_steps = dcn401_build_update_display_clocks_sequence(clk_mgr_base,
context,
&context->bw_ctx.bw.dcn.clk,
safe_to_lower,
num_bw_steps);
/* Store total step count for the executor */
clk_mgr401->num_block_sequence_steps = total_steps;
/* Add single HWSS step that will execute all clk_mgr block sequence steps */
hwss_add_clk_mgr_update_clocks(seq_state, clk_mgr_base);
}
static void dcn401_update_clocks(struct clk_mgr *clk_mgr_base,
struct dc_state *context,
bool safe_to_lower)
@@ -1260,7 +1300,8 @@ static void dcn401_update_clocks(struct clk_mgr *clk_mgr_base,
num_steps = dcn401_build_update_display_clocks_sequence(clk_mgr_base,
context,
&context->bw_ctx.bw.dcn.clk,
safe_to_lower);
safe_to_lower,
0);
/* execute sequence */
dcn401_execute_block_sequence(clk_mgr_base, num_steps);
@@ -1549,6 +1590,14 @@ unsigned int dcn401_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_typ
return 0;
}
static void dcn401_execute_clk_mgr_block_sequence_bls(struct clk_mgr *clk_mgr_base)
{
struct clk_mgr_internal *clk_mgr_internal = TO_CLK_MGR_INTERNAL(clk_mgr_base);
struct dcn401_clk_mgr *clk_mgr401 = TO_DCN401_CLK_MGR(clk_mgr_internal);
dcn401_execute_block_sequence(clk_mgr_base, clk_mgr401->num_block_sequence_steps);
}
static struct clk_mgr_funcs dcn401_funcs = {
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn401_get_dtb_ref_freq_khz,
@@ -1566,6 +1615,8 @@ static struct clk_mgr_funcs dcn401_funcs = {
.get_hard_min_fclk = dcn401_get_hard_min_fclk,
.is_dc_mode_present = dcn401_is_dc_mode_present,
.get_max_clock_khz = dcn401_get_max_clock_khz,
.build_clock_update_for_bls = dcn401_build_clock_update_for_bls,
.execute_clk_mgr_block_sequence = dcn401_execute_clk_mgr_block_sequence_bls,
};
struct clk_mgr_internal *dcn401_clk_mgr_construct(

View File

@@ -102,6 +102,7 @@ struct dcn401_clk_mgr {
struct clk_mgr_internal base;
struct dcn401_clk_mgr_block_sequence block_sequence[DCN401_CLK_MGR_MAX_SEQUENCE_SIZE];
unsigned int num_block_sequence_steps;
};
void dcn401_init_clocks(struct clk_mgr *clk_mgr_base);
@@ -114,4 +115,12 @@ void dcn401_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr);
unsigned int dcn401_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_type clk_type);
struct block_sequence_state;
void dcn401_build_clock_update_for_bls(
struct clk_mgr *clk_mgr_base,
struct dc_state *context,
bool safe_to_lower,
struct block_sequence_state *seq_state);
#endif /* __DCN401_CLK_MGR_H_ */

View File

@@ -4256,8 +4256,8 @@ static void commit_planes_do_stream_update_sequence(struct dc *dc,
hwss_add_dc_set_optimized_required(&seq_state, dc, true);
} else {
if (get_seamless_boot_stream_count(context) == 0)
hwss_add_prepare_bandwidth(&seq_state, dc, dc->current_state);
if (get_seamless_boot_stream_count(context) == 0 && dc->hwss.prepare_bandwidth_sequence)
dc->hwss.prepare_bandwidth_sequence(dc, dc->current_state, &seq_state);
hwss_add_link_set_dpms_on(&seq_state, dc->current_state, dpms_pipe_ctx);
}
} else if (pipe_ctx->stream->link->wa_flags.blank_stream_on_ocs_change && stream_update->output_color_space

View File

@@ -37,6 +37,7 @@
#include "dchubbub.h"
#include "dccg.h"
#include "abm.h"
#include "clk_mgr.h"
#include "dcn10/dcn10_hubbub.h"
#include "dce/dmub_hw_lock_mgr.h"
#include "link_service.h"
@@ -1668,6 +1669,21 @@ void hwss_execute_sequence(struct dc *dc,
case LINK_SET_DPMS_ON:
hwss_link_set_dpms_on(params);
break;
case CLK_MGR_SET_MAX_MEMCLK:
hwss_clk_mgr_set_max_memclk(params);
break;
case CLK_MGR_UPDATE_CLOCKS:
hwss_clk_mgr_update_clocks(params);
break;
case HUBBUB_PROGRAM_WATERMARKS:
hwss_hubbub_program_watermarks(params);
break;
case HUBBUB_PROGRAM_ARBITER:
hwss_hubbub_program_arbiter(params);
break;
case HUBBUB_PROGRAM_COMPBUF_SEGMENTS:
hwss_hubbub_program_compbuf_segments(params);
break;
default:
ASSERT(false);
break;
@@ -3849,6 +3865,70 @@ void hwss_dsc_set_config_simple(union block_sequence_params *params)
dsc->funcs->dsc_set_config(dsc, dsc_cfg, dsc_optc_cfg);
}
/*
* Clock manager executor functions
*/
void hwss_clk_mgr_set_max_memclk(union block_sequence_params *params)
{
struct clk_mgr *clk_mgr = params->clk_mgr_set_max_memclk_params.clk_mgr;
unsigned int memclk_mhz = params->clk_mgr_set_max_memclk_params.memclk_mhz;
if (clk_mgr && clk_mgr->funcs && clk_mgr->funcs->set_max_memclk)
clk_mgr->funcs->set_max_memclk(clk_mgr, memclk_mhz);
}
void hwss_clk_mgr_update_clocks(union block_sequence_params *params)
{
struct clk_mgr *clk_mgr = params->clk_mgr_update_clocks_params.clk_mgr;
if (clk_mgr && clk_mgr->funcs && clk_mgr->funcs->execute_clk_mgr_block_sequence)
clk_mgr->funcs->execute_clk_mgr_block_sequence(clk_mgr);
}
/*
* Hubbub executor functions
*/
void hwss_hubbub_program_watermarks(union block_sequence_params *params)
{
struct dc *dc = params->hubbub_program_watermarks_params.dc;
struct hubbub *hubbub = params->hubbub_program_watermarks_params.hubbub;
union dcn_watermark_set *watermarks = params->hubbub_program_watermarks_params.watermarks;
unsigned int refclk_mhz = params->hubbub_program_watermarks_params.refclk_mhz;
bool safe_to_lower = params->hubbub_program_watermarks_params.safe_to_lower;
if (hubbub && hubbub->funcs && hubbub->funcs->program_watermarks) {
bool wm_changed = hubbub->funcs->program_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
if (dc && !safe_to_lower)
dc->optimized_required |= wm_changed;
}
}
void hwss_hubbub_program_arbiter(union block_sequence_params *params)
{
struct dc *dc = params->hubbub_program_arbiter_params.dc;
struct hubbub *hubbub = params->hubbub_program_arbiter_params.hubbub;
struct dml2_display_arb_regs *arb_regs = params->hubbub_program_arbiter_params.arb_regs;
bool safe_to_lower = params->hubbub_program_arbiter_params.safe_to_lower;
if (hubbub && hubbub->funcs && hubbub->funcs->program_arbiter) {
bool arb_changed = hubbub->funcs->program_arbiter(hubbub, arb_regs, safe_to_lower);
if (dc && !safe_to_lower)
dc->optimized_required |= arb_changed;
}
}
void hwss_hubbub_program_compbuf_segments(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_program_compbuf_segments_params.hubbub;
unsigned int compbuf_size = params->hubbub_program_compbuf_segments_params.compbuf_size;
bool safe_to_lower = params->hubbub_program_compbuf_segments_params.safe_to_lower;
if (hubbub && hubbub->funcs && hubbub->funcs->program_compbuf_segments)
hubbub->funcs->program_compbuf_segments(hubbub, compbuf_size, safe_to_lower);
}
void hwss_add_dccg_set_dto_dscclk(struct block_sequence_state *seq_state,
struct dccg *dccg, int inst, int num_slices_h)
{
@@ -4909,6 +4989,9 @@ void hwss_add_hpo_dp_stream_enc_update_dp_info_packets_sdp_line_num(struct block
}
}
/*
* Clock manager helper functions
*/
void hwss_add_hpo_dp_stream_enc_update_dp_info_packets(struct block_sequence_state *seq_state,
struct pipe_ctx *pipe_ctx)
{
@@ -4919,6 +5002,28 @@ void hwss_add_hpo_dp_stream_enc_update_dp_info_packets(struct block_sequence_sta
}
}
void hwss_add_clk_mgr_set_max_memclk(struct block_sequence_state *seq_state,
struct clk_mgr *clk_mgr,
unsigned int memclk_mhz)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = CLK_MGR_SET_MAX_MEMCLK;
seq_state->steps[*seq_state->num_steps].params.clk_mgr_set_max_memclk_params.clk_mgr = clk_mgr;
seq_state->steps[*seq_state->num_steps].params.clk_mgr_set_max_memclk_params.memclk_mhz = memclk_mhz;
(*seq_state->num_steps)++;
}
}
void hwss_add_clk_mgr_update_clocks(struct block_sequence_state *seq_state,
struct clk_mgr *clk_mgr)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = CLK_MGR_UPDATE_CLOCKS;
seq_state->steps[*seq_state->num_steps].params.clk_mgr_update_clocks_params.clk_mgr = clk_mgr;
(*seq_state->num_steps)++;
}
}
void hwss_add_stream_enc_update_dp_info_packets_sdp_line_num(struct block_sequence_state *seq_state,
struct pipe_ctx *pipe_ctx)
{
@@ -5022,6 +5127,26 @@ void hwss_add_setup_periodic_interrupt(struct block_sequence_state *seq_state,
(*seq_state->num_steps)++;
}
}
/*
* Hubbub helper functions
*/
void hwss_add_hubbub_program_watermarks(struct block_sequence_state *seq_state,
struct dc *dc,
struct hubbub *hubbub,
union dcn_watermark_set *watermarks,
unsigned int refclk_mhz,
bool safe_to_lower)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PROGRAM_WATERMARKS;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_watermarks_params.dc = dc;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_watermarks_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_watermarks_params.watermarks = watermarks;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_watermarks_params.refclk_mhz = refclk_mhz;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_watermarks_params.safe_to_lower = safe_to_lower;
(*seq_state->num_steps)++;
}
}
void hwss_add_dp_trace_source_sequence(struct block_sequence_state *seq_state,
struct dc_link *link,
@@ -5035,6 +5160,22 @@ void hwss_add_dp_trace_source_sequence(struct block_sequence_state *seq_state,
}
}
void hwss_add_hubbub_program_arbiter(struct block_sequence_state *seq_state,
struct dc *dc,
struct hubbub *hubbub,
struct dml2_display_arb_regs *arb_regs,
bool safe_to_lower)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PROGRAM_ARBITER;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_arbiter_params.dc = dc;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_arbiter_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_arbiter_params.arb_regs = arb_regs;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_arbiter_params.safe_to_lower = safe_to_lower;
(*seq_state->num_steps)++;
}
}
void hwss_add_set_dmdata_attributes(struct block_sequence_state *seq_state,
struct pipe_ctx *pipe_ctx)
{
@@ -5119,6 +5260,19 @@ void hwss_add_disable_audio_stream(struct block_sequence_state *seq_state,
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_program_compbuf_segments(struct block_sequence_state *seq_state,
struct hubbub *hubbub,
unsigned int compbuf_size,
bool safe_to_lower)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PROGRAM_COMPBUF_SEGMENTS;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_compbuf_segments_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_compbuf_segments_params.compbuf_size = compbuf_size;
seq_state->steps[*seq_state->num_steps].params.hubbub_program_compbuf_segments_params.safe_to_lower = safe_to_lower;
(*seq_state->num_steps)++;
}
}
void hwss_add_prepare_bandwidth(struct block_sequence_state *seq_state,
struct dc *dc,

View File

@@ -1496,6 +1496,57 @@ void dcn401_prepare_bandwidth(struct dc *dc,
}
}
void dcn401_prepare_bandwidth_sequence(struct dc *dc,
struct dc_state *context,
struct block_sequence_state *seq_state)
{
struct hubbub *hubbub = dc->res_pool->hubbub;
bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support;
unsigned int compbuf_size = 0;
/* Any transition into P-State support should disable MCLK switching first to avoid hangs */
if (p_state_change_support) {
dc->optimized_required = true;
context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
}
if (dc->clk_mgr->dc_mode_softmax_enabled)
if (dc->clk_mgr->clks.dramclk_khz <= (int)dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
context->bw_ctx.bw.dcn.clk.dramclk_khz > (int)dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
hwss_add_clk_mgr_set_max_memclk(seq_state, dc->clk_mgr,
dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
/* Build bandwidth and display clocks back-to-back (SW calc + append BLS steps) */
if (dc->clk_mgr->funcs->build_clock_update_for_bls)
dc->clk_mgr->funcs->build_clock_update_for_bls(
dc->clk_mgr, context, false, seq_state);
hwss_add_hubbub_program_watermarks(seq_state, dc, hubbub,
&context->bw_ctx.bw.dcn.watermarks,
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
false);
if (hubbub->funcs->program_arbiter)
hwss_add_hubbub_program_arbiter(seq_state, dc, hubbub,
&context->bw_ctx.bw.dcn.arb_regs, false);
if (hubbub->funcs->program_compbuf_segments) {
compbuf_size = context->bw_ctx.bw.dcn.arb_regs.compbuf_size;
dc->optimized_required |= (compbuf_size != dc->current_state->bw_ctx.bw.dcn.arb_regs.compbuf_size);
hwss_add_hubbub_program_compbuf_segments(seq_state, hubbub, compbuf_size, false);
}
if (dc->debug.fams2_config.bits.enable) {
dcn401_dmub_hw_control_lock(dc, context, true);
dcn401_fams2_update_config(dc, context, false);
dcn401_dmub_hw_control_lock(dc, context, false);
}
if (p_state_change_support != context->bw_ctx.bw.dcn.clk.p_state_change_support)
context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support;
}
void dcn401_optimize_bandwidth(
struct dc *dc,
struct dc_state *context)
@@ -1549,6 +1600,50 @@ void dcn401_optimize_bandwidth(
}
}
/*
* optimize_bandwidth_sequence is unused for now. It will be used when
* dc_commit_state_no_check is moved into block sequence pattern, similar
* to how commit_planes_do_stream_update_sequence replaces
* commit_planes_do_stream_update.
*/
void dcn401_optimize_bandwidth_sequence(struct dc *dc,
struct dc_state *context,
struct block_sequence_state *seq_state)
{
struct hubbub *hubbub = dc->res_pool->hubbub;
/* enable fams2 if needed */
if (dc->debug.fams2_config.bits.enable) {
dcn401_dmub_hw_control_lock(dc, context, true);
dcn401_fams2_update_config(dc, context, true);
dcn401_dmub_hw_control_lock(dc, context, false);
}
hwss_add_hubbub_program_watermarks(seq_state, dc, hubbub,
&context->bw_ctx.bw.dcn.watermarks,
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
true);
if (hubbub->funcs->program_arbiter)
hwss_add_hubbub_program_arbiter(seq_state, dc, hubbub,
&context->bw_ctx.bw.dcn.arb_regs, true);
if (dc->clk_mgr->dc_mode_softmax_enabled)
if (dc->clk_mgr->clks.dramclk_khz > (int)dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
context->bw_ctx.bw.dcn.clk.dramclk_khz <= (int)dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
hwss_add_clk_mgr_set_max_memclk(seq_state, dc->clk_mgr,
dc->clk_mgr->bw_params->dc_mode_softmax_memclk);
if (hubbub->funcs->program_compbuf_segments)
hwss_add_hubbub_program_compbuf_segments(seq_state, hubbub,
context->bw_ctx.bw.dcn.arb_regs.compbuf_size, true);
/* Build bandwidth and display clocks (SW calc + append BLS steps) */
if (dc->clk_mgr->funcs->build_clock_update_for_bls)
dc->clk_mgr->funcs->build_clock_update_for_bls(
dc->clk_mgr, context, true, seq_state);
}
void dcn401_dmub_hw_control_lock(struct dc *dc,
struct dc_state *context,
bool lock)

View File

@@ -70,10 +70,20 @@ void dcn401_wait_for_dcc_meta_propagation(const struct dc *dc,
void dcn401_prepare_bandwidth(struct dc *dc,
struct dc_state *context);
struct block_sequence_state;
void dcn401_prepare_bandwidth_sequence(struct dc *dc,
struct dc_state *context,
struct block_sequence_state *seq_state);
void dcn401_optimize_bandwidth(
struct dc *dc,
struct dc_state *context);
void dcn401_optimize_bandwidth_sequence(struct dc *dc,
struct dc_state *context,
struct block_sequence_state *seq_state);
void dcn401_dmub_hw_control_lock(struct dc *dc,
struct dc_state *context,
bool lock);

View File

@@ -44,7 +44,9 @@ static const struct hw_sequencer_funcs dcn401_funcs = {
.interdependent_update_lock = dcn401_interdependent_update_lock,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn401_prepare_bandwidth,
.prepare_bandwidth_sequence = dcn401_prepare_bandwidth_sequence,
.optimize_bandwidth = dcn401_optimize_bandwidth,
.optimize_bandwidth_sequence = dcn401_optimize_bandwidth_sequence,
.update_bandwidth = dcn401_update_bandwidth,
.set_drr = dcn10_set_drr,
.get_position = dcn10_get_position,

View File

@@ -894,6 +894,36 @@ struct disable_audio_stream_params {
struct pipe_ctx *pipe_ctx;
};
struct clk_mgr_set_max_memclk_params {
struct clk_mgr *clk_mgr;
unsigned int memclk_mhz;
};
struct clk_mgr_update_clocks_params {
struct clk_mgr *clk_mgr;
};
struct hubbub_program_watermarks_params {
struct dc *dc;
struct hubbub *hubbub;
union dcn_watermark_set *watermarks;
unsigned int refclk_mhz;
bool safe_to_lower;
};
struct hubbub_program_arbiter_params {
struct dc *dc;
struct hubbub *hubbub;
struct dml2_display_arb_regs *arb_regs;
bool safe_to_lower;
};
struct hubbub_program_compbuf_segments_params {
struct hubbub *hubbub;
unsigned int compbuf_size;
bool safe_to_lower;
};
struct prepare_bandwidth_params {
struct dc *dc;
struct dc_state *context;
@@ -1057,6 +1087,11 @@ union block_sequence_params {
struct disable_audio_stream_params disable_audio_stream_params;
struct prepare_bandwidth_params prepare_bandwidth_params;
struct link_set_dpms_on_params link_set_dpms_on_params;
struct clk_mgr_set_max_memclk_params clk_mgr_set_max_memclk_params;
struct clk_mgr_update_clocks_params clk_mgr_update_clocks_params;
struct hubbub_program_watermarks_params hubbub_program_watermarks_params;
struct hubbub_program_arbiter_params hubbub_program_arbiter_params;
struct hubbub_program_compbuf_segments_params hubbub_program_compbuf_segments_params;
};
enum block_sequence_func {
@@ -1209,6 +1244,11 @@ enum block_sequence_func {
DISABLE_AUDIO_STREAM,
PREPARE_BANDWIDTH,
LINK_SET_DPMS_ON,
CLK_MGR_SET_MAX_MEMCLK,
CLK_MGR_UPDATE_CLOCKS,
HUBBUB_PROGRAM_WATERMARKS,
HUBBUB_PROGRAM_ARBITER,
HUBBUB_PROGRAM_COMPBUF_SEGMENTS,
/* This must be the last value in this enum, add new ones above */
HWSS_BLOCK_SEQUENCE_FUNC_COUNT
};
@@ -1316,8 +1356,14 @@ struct hw_sequencer_funcs {
/* Bandwidth Related */
void (*prepare_bandwidth)(struct dc *dc, struct dc_state *context);
void (*prepare_bandwidth_sequence)(struct dc *dc,
struct dc_state *context,
struct block_sequence_state *seq_state);
bool (*update_bandwidth)(struct dc *dc, struct dc_state *context);
void (*optimize_bandwidth)(struct dc *dc, struct dc_state *context);
void (*optimize_bandwidth_sequence)(struct dc *dc,
struct dc_state *context,
struct block_sequence_state *seq_state);
/* Infopacket Related */
void (*set_avmute)(struct pipe_ctx *pipe_ctx, bool enable);
@@ -2475,4 +2521,40 @@ void hwss_add_link_set_dpms_on(struct block_sequence_state *seq_state,
struct dc_state *state,
struct pipe_ctx *pipe_ctx);
/* Clock manager BLS executor functions */
void hwss_clk_mgr_set_max_memclk(union block_sequence_params *params);
void hwss_clk_mgr_update_clocks(union block_sequence_params *params);
void hwss_hubbub_program_watermarks(union block_sequence_params *params);
void hwss_hubbub_program_arbiter(union block_sequence_params *params);
void hwss_hubbub_program_compbuf_segments(union block_sequence_params *params);
/* Clock manager BLS add-helper functions */
void hwss_add_clk_mgr_set_max_memclk(struct block_sequence_state *seq_state,
struct clk_mgr *clk_mgr,
unsigned int memclk_mhz);
void hwss_add_clk_mgr_update_clocks(struct block_sequence_state *seq_state,
struct clk_mgr *clk_mgr);
void hwss_add_hubbub_program_watermarks(struct block_sequence_state *seq_state,
struct dc *dc,
struct hubbub *hubbub,
union dcn_watermark_set *watermarks,
unsigned int refclk_mhz,
bool safe_to_lower);
void hwss_add_hubbub_program_arbiter(struct block_sequence_state *seq_state,
struct dc *dc,
struct hubbub *hubbub,
struct dml2_display_arb_regs *arb_regs,
bool safe_to_lower);
void hwss_add_hubbub_program_compbuf_segments(struct block_sequence_state *seq_state,
struct hubbub *hubbub,
unsigned int compbuf_size,
bool safe_to_lower);
#endif /* __DC_HW_SEQUENCER_H__ */

View File

@@ -320,6 +320,8 @@ struct clk_states {
uint32_t dprefclk_khz;
};
struct block_sequence_state;
struct clk_mgr_funcs {
/*
* This function should set new clocks based on the input "safe_to_lower".
@@ -409,6 +411,12 @@ struct clk_mgr_funcs {
void (*get_requested_memory_qos)(
struct clk_mgr *clk_mgr,
struct dc_requested_memory_qos *qos);
void (*build_clock_update_for_bls)(struct clk_mgr *clk_mgr,
struct dc_state *context, bool safe_to_lower,
struct block_sequence_state *seq_state);
void (*execute_clk_mgr_block_sequence)(struct clk_mgr *clk_mgr);
};
struct clk_mgr {