mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-23 17:46:33 -04:00
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:
committed by
Alex Deucher
parent
b34e4c1d05
commit
f3403ab74a
@@ -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(
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user