drm/amd/display: DML21 Reintegration For Various Fixes

Reintegrate latest DML21 code.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Austin Zheng <Austin.Zheng@amd.com>
Signed-off-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Austin Zheng 2024-11-25 17:16:53 -05:00 committed by Alex Deucher
parent bb4090cda9
commit be4e350931
30 changed files with 2820 additions and 1732 deletions

View File

@ -73,9 +73,8 @@ AMD_DAL_DML2 = $(addprefix $(AMDDALPATH)/dc/dml2/,$(DML2))
AMD_DISPLAY_FILES += $(AMD_DAL_DML2)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml_top.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml_top_mcache.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml2_top_optimization := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml2_top_interfaces.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml2_top_soc15.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.o := $(dml2_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_factory.o := $(dml2_ccflags)
@ -94,9 +93,8 @@ CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/dml21_translation_helper.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/dml21_utils.o := $(dml2_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml2/dml21/inc/dml2_debug.o := $(dml2_ccflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml_top.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml_top_mcache.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml2_top_optimization.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml2_top_interfaces.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_top/dml2_top_soc15.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/src/dml2_core/dml2_core_factory.o := $(dml2_rcflags)
@ -113,9 +111,8 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/dml21_translation_helper.o := $(dml2_r
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/dml21_utils.o := $(dml2_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2/dml21/inc/dml2_debug.o := $(dml2_rcflags)
DML21 := src/dml2_top/dml_top.o
DML21 += src/dml2_top/dml_top_mcache.o
DML21 += src/dml2_top/dml2_top_optimization.o
DML21 := src/dml2_top/dml2_top_interfaces.o
DML21 += src/dml2_top/dml2_top_soc15.o
DML21 += src/inc/dml2_debug.o
DML21 += src/dml2_core/dml2_core_dcn4.o
DML21 += src/dml2_core/dml2_core_factory.o

View File

@ -8318,7 +8318,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
if (clk_cfg->dcfclk_option != dml_use_override_freq)
locals->Dcfclk = mode_lib->ms.DCFCLK;
else
locals->Dcfclk = clk_cfg->dcfclk_freq_mhz;
locals->Dcfclk = clk_cfg->dcfclk_mhz;
#ifdef __DML_VBA_DEBUG__
dml_print_dml_policy(&mode_lib->ms.policy);
@ -8371,7 +8371,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
if (clk_cfg->dispclk_option == dml_use_required_freq)
locals->Dispclk = locals->Dispclk_calculated;
else if (clk_cfg->dispclk_option == dml_use_override_freq)
locals->Dispclk = clk_cfg->dispclk_freq_mhz;
locals->Dispclk = clk_cfg->dispclk_mhz;
else
locals->Dispclk = mode_lib->ms.state.dispclk_mhz;
#ifdef __DML_VBA_DEBUG__
@ -8412,7 +8412,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
if (clk_cfg->dppclk_option[k] == dml_use_required_freq)
locals->Dppclk[k] = locals->Dppclk_calculated[k];
else if (clk_cfg->dppclk_option[k] == dml_use_override_freq)
locals->Dppclk[k] = clk_cfg->dppclk_freq_mhz[k];
locals->Dppclk[k] = clk_cfg->dppclk_mhz[k];
else
locals->Dppclk[k] = mode_lib->ms.state.dppclk_mhz;
#ifdef __DML_VBA_DEBUG__

View File

@ -28,6 +28,7 @@
#define __DISPLAY_MODE_CORE_STRUCT_H__
#include "display_mode_lib_defines.h"
#include "dml_top_display_cfg_types.h"
enum dml_project_id {
dml_project_invalid = 0,
@ -49,7 +50,9 @@ enum dml_use_mall_for_pstate_change_mode {
dml_use_mall_pstate_change_disable = 0,
dml_use_mall_pstate_change_full_frame = 1,
dml_use_mall_pstate_change_sub_viewport = 2,
dml_use_mall_pstate_change_phantom_pipe = 3
dml_use_mall_pstate_change_phantom_pipe = 3,
dml_use_mall_pstate_change_phantom_pipe_no_data_return = 4,
dml_use_mall_pstate_change_imall = 5
};
enum dml_use_mall_for_static_screen_mode {
dml_use_mall_static_screen_disable = 0,
@ -171,7 +174,11 @@ enum dml_swizzle_mode {
dml_sw_256kb_z_x = 28,
dml_sw_256kb_s_x = 29,
dml_sw_256kb_d_x = 30,
dml_sw_256kb_r_x = 31
dml_sw_256kb_r_x = 31,
dml_sw_256b_2d = 32,
dml_sw_4kb_2d = 33,
dml_sw_64kb_2d = 34,
dml_sw_256kb_2d = 35
};
enum dml_lb_depth {
dml_lb_6 = 0,
@ -223,24 +230,28 @@ enum dml_mpc_use_policy {
dml_mpc_disabled = 0,
dml_mpc_as_possible = 1,
dml_mpc_as_needed_for_voltage = 2,
dml_mpc_as_needed_for_pstate_and_voltage = 3
dml_mpc_as_needed_for_pstate_and_voltage = 3,
dml_mpc_as_needed = 4,
dml_mpc_2to1 = 5
};
enum dml_odm_use_policy {
dml_odm_use_policy_bypass = 0,
dml_odm_use_policy_combine_as_needed = 1,
dml_odm_use_policy_combine_2to1 = 2,
dml_odm_use_policy_combine_4to1 = 3,
dml_odm_use_policy_split_1to2 = 4,
dml_odm_use_policy_mso_1to2 = 5,
dml_odm_use_policy_mso_1to4 = 6
dml_odm_use_policy_combine_3to1 = 3,
dml_odm_use_policy_combine_4to1 = 4,
dml_odm_use_policy_split_1to2 = 5,
dml_odm_use_policy_mso_1to2 = 6,
dml_odm_use_policy_mso_1to4 = 7
};
enum dml_odm_mode {
dml_odm_mode_bypass = 0,
dml_odm_mode_combine_2to1 = 1,
dml_odm_mode_combine_4to1 = 2,
dml_odm_mode_split_1to2 = 3,
dml_odm_mode_mso_1to2 = 4,
dml_odm_mode_mso_1to4 = 5
dml_odm_mode_combine_3to1 = 2,
dml_odm_mode_combine_4to1 = 3,
dml_odm_mode_split_1to2 = 4,
dml_odm_mode_mso_1to2 = 5,
dml_odm_mode_mso_1to4 = 6
};
enum dml_writeback_configuration {
dml_whole_buffer_for_single_stream_no_interleave = 0,
@ -289,6 +300,17 @@ struct soc_state_bounding_box_st {
dml_float_t fclk_change_latency_us;
dml_float_t usr_retraining_latency_us;
dml_bool_t use_ideal_dram_bw_strobe;
dml_float_t g6_temp_read_blackout_us;
struct {
dml_uint_t urgent_ramp_uclk_cycles;
dml_uint_t trip_to_memory_uclk_cycles;
dml_uint_t meta_trip_to_memory_uclk_cycles;
dml_uint_t maximum_latency_when_urgent_uclk_cycles;
dml_uint_t average_latency_when_urgent_uclk_cycles;
dml_uint_t maximum_latency_when_non_urgent_uclk_cycles;
dml_uint_t average_latency_when_non_urgent_uclk_cycles;
} dml_dcn401_uclk_dpm_dependent_soc_qos_params;
};
struct soc_bounding_box_st {
@ -297,7 +319,7 @@ struct soc_bounding_box_st {
dml_float_t pcierefclk_mhz;
dml_float_t refclk_mhz;
dml_float_t amclk_mhz;
dml_float_t max_outstanding_reqs;
dml_uint_t max_outstanding_reqs;
dml_float_t pct_ideal_sdp_bw_after_urgent;
dml_float_t pct_ideal_fabric_bw_after_urgent;
dml_float_t pct_ideal_dram_bw_after_urgent_pixel_only;
@ -308,6 +330,16 @@ struct soc_bounding_box_st {
dml_float_t max_avg_fabric_bw_use_normal_percent;
dml_float_t max_avg_dram_bw_use_normal_percent;
dml_float_t max_avg_dram_bw_use_normal_strobe_percent;
dml_float_t svp_prefetch_pct_ideal_sdp_bw_after_urgent;
dml_float_t svp_prefetch_pct_ideal_fabric_bw_after_urgent;
dml_float_t svp_prefetch_pct_ideal_dram_bw_after_urgent_pixel_only;
dml_float_t svp_prefetch_pct_ideal_dram_bw_after_urgent_pixel_and_vm;
dml_float_t svp_prefetch_pct_ideal_dram_bw_after_urgent_vm_only;
dml_float_t svp_prefetch_max_avg_sdp_bw_use_normal_percent;
dml_float_t svp_prefetch_max_avg_fabric_bw_use_normal_percent;
dml_float_t svp_prefetch_max_avg_dram_bw_use_normal_percent;
dml_uint_t round_trip_ping_latency_dcfclk_cycles;
dml_uint_t urgent_out_of_order_return_per_channel_pixel_only_bytes;
dml_uint_t urgent_out_of_order_return_per_channel_pixel_and_vm_bytes;
@ -324,6 +356,26 @@ struct soc_bounding_box_st {
dml_uint_t mall_allocated_for_dcn_mbytes;
dml_float_t dispclk_dppclk_vco_speed_mhz;
dml_bool_t do_urgent_latency_adjustment;
dml_uint_t mem_word_bytes;
dml_uint_t num_dcc_mcaches;
dml_uint_t mcache_size_bytes;
dml_uint_t mcache_line_size_bytes;
struct {
dml_bool_t UseNewDCN401SOCParameters;
dml_uint_t df_qos_response_time_fclk_cycles;
dml_uint_t max_round_trip_to_furthest_cs_fclk_cycles;
dml_uint_t mall_overhead_fclk_cycles;
dml_uint_t meta_trip_adder_fclk_cycles;
dml_uint_t average_transport_distance_fclk_cycles;
dml_float_t umc_urgent_ramp_latency_margin;
dml_float_t umc_max_latency_margin;
dml_float_t umc_average_latency_margin;
dml_float_t fabric_max_transport_latency_margin;
dml_float_t fabric_average_transport_latency_margin;
} dml_dcn401_soc_qos_params;
};
struct ip_params_st {
@ -515,6 +567,10 @@ struct dml_plane_cfg_st {
dml_uint_t CursorWidth[__DML_NUM_PLANES__];
dml_uint_t CursorBPP[__DML_NUM_PLANES__];
dml_bool_t setup_for_tdlut[__DML_NUM_PLANES__];
enum dml2_tdlut_addressing_mode tdlut_addressing_mode[__DML_NUM_PLANES__];
enum dml2_tdlut_width_mode tdlut_width_mode[__DML_NUM_PLANES__];
enum dml_use_mall_for_static_screen_mode UseMALLForStaticScreen[__DML_NUM_PLANES__];
enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[__DML_NUM_PLANES__];
@ -604,6 +660,17 @@ struct dml_hw_resource_st {
dml_float_t DLGRefClkFreqMHz; /// <brief DLG Global Reference timer
};
/// @brief To control the clk usage for model programming
struct dml_clk_cfg_st {
enum dml_clk_cfg_policy dcfclk_option; ///< brief Use for mode_program; user can select between use the min require clk req as calculated by DML or use the test-specific freq
enum dml_clk_cfg_policy dispclk_option; ///< brief Use for mode_program; user can select between use the min require clk req as calculated by DML or use the test-specific freq
enum dml_clk_cfg_policy dppclk_option[__DML_NUM_PLANES__];
dml_float_t dcfclk_mhz;
dml_float_t dispclk_mhz;
dml_float_t dppclk_mhz[__DML_NUM_PLANES__];
}; // dml_clk_cfg_st
/// @brief DML display configuration.
/// Describe how to display a surface in multi-plane setup and output to different output and writeback using the specified timgin
struct dml_display_cfg_st {
@ -616,19 +683,9 @@ struct dml_display_cfg_st {
unsigned int num_timings;
struct dml_hw_resource_st hw; //< brief for mode programming
struct dml_clk_cfg_st clk_overrides; //< brief for mode programming clk override
}; // dml_display_cfg_st
/// @brief To control the clk usage for model programming
struct dml_clk_cfg_st {
enum dml_clk_cfg_policy dcfclk_option; ///< brief Use for mode_program; user can select between use the min require clk req as calculated by DML or use the test-specific freq
enum dml_clk_cfg_policy dispclk_option; ///< brief Use for mode_program; user can select between use the min require clk req as calculated by DML or use the test-specific freq
enum dml_clk_cfg_policy dppclk_option[__DML_NUM_PLANES__];
dml_float_t dcfclk_freq_mhz;
dml_float_t dispclk_freq_mhz;
dml_float_t dppclk_freq_mhz[__DML_NUM_PLANES__];
}; // dml_clk_cfg_st
/// @brief DML mode evaluation and programming policy
/// Those knobs that affect mode support and mode programming
struct dml_mode_eval_policy_st {

View File

@ -690,12 +690,12 @@ __DML_DLL_EXPORT__ void dml_print_clk_cfg(const struct dml_clk_cfg_st *clk_cfg)
dml_print("DML: clk_cfg: dcfclk_option = %d\n", clk_cfg->dcfclk_option);
dml_print("DML: clk_cfg: dispclk_option = %d\n", clk_cfg->dispclk_option);
dml_print("DML: clk_cfg: dcfclk_freq_mhz = %f\n", clk_cfg->dcfclk_freq_mhz);
dml_print("DML: clk_cfg: dispclk_freq_mhz = %f\n", clk_cfg->dispclk_freq_mhz);
dml_print("DML: clk_cfg: dcfclk_mhz = %f\n", clk_cfg->dcfclk_mhz);
dml_print("DML: clk_cfg: dispclk_mhz = %f\n", clk_cfg->dispclk_mhz);
for (dml_uint_t i = 0; i < DCN_DML__NUM_PLANE; i++) {
dml_print("DML: clk_cfg: i=%d, dppclk_option = %d\n", i, clk_cfg->dppclk_option[i]);
dml_print("DML: clk_cfg: i=%d, dppclk_freq_mhz = %f\n", i, clk_cfg->dppclk_freq_mhz[i]);
dml_print("DML: clk_cfg: i=%d, dppclk_mhz = %f\n", i, clk_cfg->dppclk_mhz[i]);
}
}

View File

@ -1226,22 +1226,22 @@ void dml21_set_dc_p_state_type(
bool sub_vp_enabled)
{
switch (stream_programming->uclk_pstate_method) {
case dml2_uclk_pstate_support_method_vactive:
case dml2_uclk_pstate_support_method_fw_vactive_drr:
case dml2_pstate_method_vactive:
case dml2_pstate_method_fw_vactive_drr:
pipe_ctx->p_state_type = P_STATE_V_ACTIVE;
break;
case dml2_uclk_pstate_support_method_vblank:
case dml2_uclk_pstate_support_method_fw_vblank_drr:
case dml2_pstate_method_vblank:
case dml2_pstate_method_fw_vblank_drr:
if (sub_vp_enabled)
pipe_ctx->p_state_type = P_STATE_V_BLANK_SUB_VP;
else
pipe_ctx->p_state_type = P_STATE_V_BLANK;
break;
case dml2_uclk_pstate_support_method_fw_subvp_phantom:
case dml2_uclk_pstate_support_method_fw_subvp_phantom_drr:
case dml2_pstate_method_fw_svp:
case dml2_pstate_method_fw_svp_drr:
pipe_ctx->p_state_type = P_STATE_SUB_VP;
break;
case dml2_uclk_pstate_support_method_fw_drr:
case dml2_pstate_method_fw_drr:
if (sub_vp_enabled)
pipe_ctx->p_state_type = P_STATE_DRR_SUB_VP;
else

View File

@ -344,6 +344,7 @@ static const struct dml2_ip_capabilities dml2_dcn401_max_ip_caps = {
.config_return_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 22,
.compressed_buffer_segment_size_in_kbytes = 64,
.cursor_buffer_size = 24,
.max_flip_time_us = 80,
.max_flip_time_lines = 32,
.hostvm_mode = 0,

View File

@ -10,9 +10,10 @@
#define DML2_MAX_PLANES 8
#define DML2_MAX_DCN_PIPES 8
#define DML2_MAX_MCACHES 8 // assume plane is going to be supported by a max of 8 mcaches
#define DML2_MAX_WRITEBACK 3
enum dml2_swizzle_mode {
dml2_sw_linear,
dml2_sw_linear, // SW_LINEAR accepts 256 byte aligned pitch and also 128 byte aligned pitch if DCC is not enabled
dml2_sw_256b_2d,
dml2_sw_4kb_2d,
dml2_sw_64kb_2d,
@ -24,7 +25,8 @@ enum dml2_swizzle_mode {
dml2_gfx11_sw_64kb_d_x,
dml2_gfx11_sw_64kb_r_x,
dml2_gfx11_sw_256kb_d_x,
dml2_gfx11_sw_256kb_r_x
dml2_gfx11_sw_256kb_r_x,
};
enum dml2_source_format_class {
@ -38,7 +40,13 @@ enum dml2_source_format_class {
dml2_rgbe_alpha = 9,
dml2_rgbe = 10,
dml2_mono_8 = 11,
dml2_mono_16 = 12
dml2_mono_16 = 12,
dml2_422_planar_8 = 13,
dml2_422_planar_10 = 14,
dml2_422_planar_12 = 15,
dml2_422_packed_8 = 16,
dml2_422_packed_10 = 17,
dml2_422_packed_12 = 18
};
enum dml2_rotation_angle {
@ -121,15 +129,6 @@ enum dml2_dsc_enable_option {
dml2_dsc_enable_if_necessary = 2
};
enum dml2_pstate_support_method {
dml2_pstate_method_uninitialized,
dml2_pstate_method_not_supported,
dml2_pstate_method_vactive,
dml2_pstate_method_vblank,
dml2_pstate_method_svp,
dml2_pstate_method_drr
};
enum dml2_tdlut_addressing_mode {
dml2_tdlut_sw_linear = 0,
dml2_tdlut_simple_linear = 1
@ -287,22 +286,23 @@ struct dml2_link_output_cfg {
bool validate_output; // Do not validate the link configuration for this display stream.
};
struct dml2_writeback_cfg {
bool enable;
struct dml2_writeback_info {
enum dml2_source_format_class pixel_format;
unsigned int active_writebacks_per_surface;
unsigned long input_width;
unsigned long input_height;
unsigned long output_width;
unsigned long output_height;
unsigned long v_taps;
unsigned long h_taps;
unsigned long v_taps_chroma;
unsigned long h_taps_chroma;
double h_ratio;
double v_ratio;
};
struct {
bool enabled;
unsigned long input_width;
unsigned long input_height;
unsigned long output_width;
unsigned long output_height;
unsigned long v_taps;
unsigned long h_taps;
double h_ratio;
double v_ratio;
} scaling_info;
struct dml2_writeback_cfg {
unsigned int active_writebacks_per_stream;
struct dml2_writeback_info writeback_stream[DML2_MAX_WRITEBACK];
};
struct dml2_plane_parameters {

View File

@ -167,11 +167,13 @@ struct dml2_ip_capabilities {
unsigned int max_num_dp2p0_streams;
unsigned int max_num_hdmi_frl_outputs;
unsigned int max_num_dp2p0_outputs;
unsigned int max_num_wb;
unsigned int rob_buffer_size_kbytes;
unsigned int config_return_buffer_size_in_kbytes;
unsigned int config_return_buffer_segment_size_in_kbytes;
unsigned int meta_fifo_size_in_kentries;
unsigned int compressed_buffer_segment_size_in_kbytes;
unsigned int cursor_buffer_size;
unsigned int max_flip_time_us;
unsigned int max_flip_time_lines;
unsigned int hostvm_mode;

View File

@ -26,20 +26,14 @@ enum dml2_project_id {
dml2_project_dcn4x_stage2_auto_drr_svp = 3,
};
enum dml2_dram_clock_change_support {
dml2_dram_clock_change_vactive = 0,
dml2_dram_clock_change_vblank = 1,
dml2_dram_clock_change_vblank_and_vactive = 2,
dml2_dram_clock_change_drr = 3,
dml2_dram_clock_change_mall_svp = 4,
dml2_dram_clock_change_mall_full_frame = 6,
dml2_dram_clock_change_unsupported = 7
};
enum dml2_fclock_change_support {
dml2_fclock_change_vactive = 0,
dml2_fclock_change_vblank = 1,
dml2_fclock_change_unsupported = 2
enum dml2_pstate_change_support {
dml2_pstate_change_vactive = 0,
dml2_pstate_change_vblank = 1,
dml2_pstate_change_vblank_and_vactive = 2,
dml2_pstate_change_drr = 3,
dml2_pstate_change_mall_svp = 4,
dml2_pstate_change_mall_full_frame = 6,
dml2_pstate_change_unsupported = 7
};
enum dml2_output_type_and_rate__type {
@ -202,24 +196,23 @@ struct dml2_mcache_surface_allocation {
} informative;
};
enum dml2_uclk_pstate_support_method {
dml2_uclk_pstate_support_method_not_supported = 0,
/* hw */
dml2_uclk_pstate_support_method_vactive = 1,
dml2_uclk_pstate_support_method_vblank = 2,
dml2_uclk_pstate_support_method_reserved_hw = 5,
/* fw */
dml2_uclk_pstate_support_method_fw_subvp_phantom = 6,
dml2_uclk_pstate_support_method_reserved_fw = 10,
/* fw w/drr */
dml2_uclk_pstate_support_method_fw_vactive_drr = 11,
dml2_uclk_pstate_support_method_fw_vblank_drr = 12,
dml2_uclk_pstate_support_method_fw_subvp_phantom_drr = 13,
dml2_uclk_pstate_support_method_reserved_fw_drr_fixed = 20,
dml2_uclk_pstate_support_method_fw_drr = 21,
dml2_uclk_pstate_support_method_reserved_fw_drr_var = 22,
dml2_uclk_pstate_support_method_count
enum dml2_pstate_method {
dml2_pstate_method_na = 0,
/* hw exclusive modes */
dml2_pstate_method_vactive = 1,
dml2_pstate_method_vblank = 2,
dml2_pstate_method_reserved_hw = 5,
/* fw assisted exclusive modes */
dml2_pstate_method_fw_svp = 6,
dml2_pstate_method_reserved_fw = 10,
/* fw assisted modes requiring drr modulation */
dml2_pstate_method_fw_vactive_drr = 11,
dml2_pstate_method_fw_vblank_drr = 12,
dml2_pstate_method_fw_svp_drr = 13,
dml2_pstate_method_reserved_fw_drr_clamped = 20,
dml2_pstate_method_fw_drr = 21,
dml2_pstate_method_reserved_fw_drr_var = 22,
dml2_pstate_method_count
};
struct dml2_per_plane_programming {
@ -241,7 +234,7 @@ struct dml2_per_plane_programming {
// If a stream is using odm split, then this value is always 1
unsigned int num_dpps_required;
enum dml2_uclk_pstate_support_method uclk_pstate_support_method;
enum dml2_pstate_method uclk_pstate_support_method;
// MALL size requirements for MALL SS and SubVP
unsigned int surface_size_mall_bytes;
@ -281,7 +274,7 @@ struct dml2_per_stream_programming {
unsigned int num_odms_required;
enum dml2_uclk_pstate_support_method uclk_pstate_method;
enum dml2_pstate_method uclk_pstate_method;
struct {
bool enabled;
@ -340,7 +333,7 @@ struct dml2_mode_support_info {
bool DCCMetaBufferSizeNotExceeded;
bool TotalVerticalActiveBandwidthSupport;
bool VActiveBandwidthSupport;
enum dml2_fclock_change_support FCLKChangeSupport[DML2_MAX_PLANES];
enum dml2_pstate_change_support FCLKChangeSupport[DML2_MAX_PLANES];
bool USRRetrainingSupport;
bool PrefetchSupported;
bool DynamicMetadataSupported;
@ -362,6 +355,7 @@ struct dml2_mode_support_info {
unsigned int AlignedYPitch[DML2_MAX_PLANES];
unsigned int AlignedCPitch[DML2_MAX_PLANES];
bool g6_temp_read_support;
bool temp_read_or_ppt_support;
}; // dml2_mode_support_info
struct dml2_display_cfg_programming {
@ -445,7 +439,7 @@ struct dml2_display_cfg_programming {
double pstate_change_us;
double fclk_pstate_change_us;
double usr_retraining_us;
double g6_temp_read_watermark_us;
double temp_read_or_ppt_watermark_us;
} watermarks;
struct {
@ -654,6 +648,7 @@ struct dml2_display_cfg_programming {
double DisplayPipeLineDeliveryTimeLumaPrefetch[DML2_MAX_PLANES];
double DisplayPipeLineDeliveryTimeChromaPrefetch[DML2_MAX_PLANES];
double WritebackRequiredBandwidth;
double WritebackAllowDRAMClockChangeEndPosition[DML2_MAX_PLANES];
double WritebackAllowFCLKChangeEndPosition[DML2_MAX_PLANES];
double DSCCLK_calculated[DML2_MAX_PLANES];
@ -663,6 +658,7 @@ struct dml2_display_cfg_programming {
double MaxActiveDRAMClockChangeLatencySupported[DML2_MAX_PLANES];
unsigned int PrefetchMode[DML2_MAX_PLANES]; // LEGACY_ONLY
bool ROBUrgencyAvoidance;
double LowestPrefetchMargin;
} misc;
struct dml2_mode_support_info mode_support_info;
@ -676,6 +672,7 @@ struct dml2_display_cfg_programming {
bool failed_mcache_validation;
bool failed_dpmm;
bool failed_mode_programming;
bool failed_map_watermarks;
} informative;
};

View File

@ -9,7 +9,7 @@
#include "dml2_debug.h"
#include "lib_float_math.h"
static const struct dml2_core_ip_params core_dcn4_ip_caps_base = {
struct dml2_core_ip_params core_dcn4_ip_caps_base = {
// Hardcoded values for DCN3x
.vblank_nom_default_us = 668,
.remote_iommu_outstanding_translations = 256,
@ -90,6 +90,7 @@ static void patch_ip_caps_with_explicit_ip_params(struct dml2_ip_capabilities *i
ip_caps->config_return_buffer_segment_size_in_kbytes = ip_params->config_return_buffer_segment_size_in_kbytes;
ip_caps->meta_fifo_size_in_kentries = ip_params->meta_fifo_size_in_kentries;
ip_caps->compressed_buffer_segment_size_in_kbytes = ip_params->compressed_buffer_segment_size_in_kbytes;
ip_caps->cursor_buffer_size = ip_params->cursor_buffer_size;
ip_caps->max_flip_time_us = ip_params->max_flip_time_us;
ip_caps->max_flip_time_lines = ip_params->max_flip_time_lines;
ip_caps->hostvm_mode = ip_params->hostvm_mode;
@ -114,6 +115,7 @@ static void patch_ip_params_with_ip_caps(struct dml2_core_ip_params *ip_params,
ip_params->config_return_buffer_segment_size_in_kbytes = ip_caps->config_return_buffer_segment_size_in_kbytes;
ip_params->meta_fifo_size_in_kentries = ip_caps->meta_fifo_size_in_kentries;
ip_params->compressed_buffer_segment_size_in_kbytes = ip_caps->compressed_buffer_segment_size_in_kbytes;
ip_params->cursor_buffer_size = ip_caps->cursor_buffer_size;
ip_params->max_flip_time_us = ip_caps->max_flip_time_us;
ip_params->max_flip_time_lines = ip_caps->max_flip_time_lines;
ip_params->hostvm_mode = ip_caps->hostvm_mode;
@ -316,28 +318,9 @@ static void pack_mode_programming_params_with_implicit_subvp(struct dml2_core_in
// Setup the appropriate p-state strategy
if (display_cfg->stage3.performed && display_cfg->stage3.success) {
switch (display_cfg->stage3.pstate_switch_modes[plane_index]) {
case dml2_uclk_pstate_support_method_vactive:
case dml2_uclk_pstate_support_method_vblank:
case dml2_uclk_pstate_support_method_fw_subvp_phantom:
case dml2_uclk_pstate_support_method_fw_drr:
case dml2_uclk_pstate_support_method_fw_vactive_drr:
case dml2_uclk_pstate_support_method_fw_vblank_drr:
case dml2_uclk_pstate_support_method_fw_subvp_phantom_drr:
programming->plane_programming[plane_index].uclk_pstate_support_method = display_cfg->stage3.pstate_switch_modes[plane_index];
break;
case dml2_uclk_pstate_support_method_reserved_hw:
case dml2_uclk_pstate_support_method_reserved_fw:
case dml2_uclk_pstate_support_method_reserved_fw_drr_fixed:
case dml2_uclk_pstate_support_method_reserved_fw_drr_var:
case dml2_uclk_pstate_support_method_not_supported:
case dml2_uclk_pstate_support_method_count:
default:
programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_not_supported;
break;
}
programming->plane_programming[plane_index].uclk_pstate_support_method = display_cfg->stage3.pstate_switch_modes[plane_index];
} else {
programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_not_supported;
programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_na;
}
dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &programming->plane_programming[plane_index].surface_size_mall_bytes, dml_internal_pipe_index);
@ -573,18 +556,18 @@ bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out
in_out->programming->plane_programming[plane_index].num_dpps_required = core->clean_me_up.mode_lib.mp.NoOfDPP[plane_index];
if (in_out->programming->display_config.plane_descriptors[plane_index].overrides.legacy_svp_config == dml2_svp_mode_override_main_pipe)
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_fw_svp;
else if (in_out->programming->display_config.plane_descriptors[plane_index].overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe)
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_fw_svp;
else if (in_out->programming->display_config.plane_descriptors[plane_index].overrides.legacy_svp_config == dml2_svp_mode_override_phantom_pipe_no_data_return)
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_fw_subvp_phantom;
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_fw_svp;
else {
if (core->clean_me_up.mode_lib.mp.MaxActiveDRAMClockChangeLatencySupported[plane_index] >= core->clean_me_up.mode_lib.soc.power_management_parameters.dram_clk_change_blackout_us)
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_vactive;
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_vactive;
else if (core->clean_me_up.mode_lib.mp.TWait[plane_index] >= core->clean_me_up.mode_lib.soc.power_management_parameters.dram_clk_change_blackout_us)
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_vblank;
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_vblank;
else
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_uclk_pstate_support_method_not_supported;
in_out->programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_na;
}
dml2_core_calcs_get_mall_allocation(&core->clean_me_up.mode_lib, &in_out->programming->plane_programming[plane_index].surface_size_mall_bytes, dml_internal_pipe_index);

View File

@ -28,7 +28,7 @@ void dml2_core_calcs_get_plane_support_info(const struct dml2_display_cfg *displ
void dml2_core_calcs_get_informative(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_cfg_programming *out);
void dml2_core_calcs_get_stream_support_info(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct core_stream_support_info *out, int plane_index);
void dml2_core_calcs_get_mall_allocation(struct dml2_core_internal_display_mode_lib *mode_lib, unsigned int *out, int pipe_index);
void dml2_core_calcs_get_stream_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, const struct display_configuation_with_meta *display_cfg, union dmub_cmd_fams2_config *fams2_base_programming, union dmub_cmd_fams2_config *fams2_sub_programming, enum dml2_uclk_pstate_support_method pstate_method, int plane_index);
void dml2_core_calcs_get_stream_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, const struct display_configuation_with_meta *display_cfg, union dmub_cmd_fams2_config *fams2_base_programming, union dmub_cmd_fams2_config *fams2_sub_programming, enum dml2_pstate_method pstate_method, int plane_index);
void dml2_core_calcs_get_global_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, const struct display_configuation_with_meta *display_cfg, struct dmub_cmd_fams2_global_config *fams2_global_config);
void dml2_core_calcs_get_dpte_row_height(unsigned int *dpte_row_height, struct dml2_core_internal_display_mode_lib *mode_lib, bool is_plane1, enum dml2_source_format_class SourcePixelFormat, enum dml2_swizzle_mode SurfaceTiling, enum dml2_rotation_angle ScanDirection, unsigned int pitch, unsigned int GPUVMMinPageSizeKBytes);

View File

@ -201,7 +201,7 @@ struct dml2_core_internal_watermarks {
double Z8StutterExitWatermark;
double Z8StutterEnterPlusExitWatermark;
double USRRetrainingWatermark;
double g6_temp_read_watermark_us;
double temp_read_or_ppt_watermark_us;
};
struct dml2_core_internal_mode_support_info {
@ -252,8 +252,8 @@ struct dml2_core_internal_mode_support_info {
bool PTEBufferSizeNotExceeded;
bool DCCMetaBufferSizeNotExceeded;
enum dml2_dram_clock_change_support DRAMClockChangeSupport[DML2_MAX_PLANES];
enum dml2_fclock_change_support FCLKChangeSupport[DML2_MAX_PLANES];
enum dml2_pstate_change_support DRAMClockChangeSupport[DML2_MAX_PLANES];
enum dml2_pstate_change_support FCLKChangeSupport[DML2_MAX_PLANES];
bool global_dram_clock_change_supported;
bool global_fclk_change_supported;
bool USRRetrainingSupport;
@ -318,12 +318,15 @@ struct dml2_core_internal_mode_support_info {
bool avg_bandwidth_support_ok[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max];
double max_urgent_latency_us;
double max_non_urgent_latency_us;
double avg_non_urgent_latency_us;
double avg_urgent_latency_us;
double df_response_time_us;
bool incorrect_imall_usage;
bool g6_temp_read_support;
bool temp_read_or_ppt_support;
struct dml2_core_internal_watermarks watermarks;
};
@ -378,8 +381,8 @@ struct dml2_core_internal_mode_support {
unsigned int DETBufferSizeC[DML2_MAX_PLANES];
unsigned int SwathHeightY[DML2_MAX_PLANES];
unsigned int SwathHeightC[DML2_MAX_PLANES];
unsigned int SwathWidthY[DML2_MAX_PLANES];
unsigned int SwathWidthC[DML2_MAX_PLANES];
unsigned int SwathWidthY[DML2_MAX_PLANES]; // per-pipe
unsigned int SwathWidthC[DML2_MAX_PLANES]; // per-pipe
// ----------------------------------
// Intermediates/Informational
@ -476,9 +479,9 @@ struct dml2_core_internal_mode_support {
// Bandwidth Related Info
double BandwidthAvailableForImmediateFlip;
double SurfaceReadBandwidthLuma[DML2_MAX_PLANES]; // no dcc overhead, for the plane
double SurfaceReadBandwidthChroma[DML2_MAX_PLANES];
double WriteBandwidth[DML2_MAX_PLANES];
double vactive_sw_bw_l[DML2_MAX_PLANES]; // no dcc overhead, for the plane
double vactive_sw_bw_c[DML2_MAX_PLANES];
double WriteBandwidth[DML2_MAX_PLANES][DML2_MAX_WRITEBACK];
double RequiredPrefetchPixelDataBWLuma[DML2_MAX_PLANES];
double RequiredPrefetchPixelDataBWChroma[DML2_MAX_PLANES];
double cursor_bw[DML2_MAX_PLANES];
@ -539,7 +542,7 @@ struct dml2_core_internal_mode_program {
unsigned int qos_param_index; // to access the uclk dependent dpm table
unsigned int active_min_uclk_dpm_index; // to access the min_clk table
double FabricClock; /// <brief Basically just the clock freq at the min (or given) state
double DCFCLK; /// <brief Basically just the clock freq at the min (or given) state and max combine setting
//double DCFCLK; /// <brief Basically just the clock freq at the min (or given) state and max combine setting
double dram_bw_mbps;
double uclk_freq_mhz;
unsigned int NoOfDPP[DML2_MAX_PLANES];
@ -562,14 +565,14 @@ struct dml2_core_internal_mode_program {
double BytePerPixelInDETC[DML2_MAX_PLANES];
unsigned int BytePerPixelY[DML2_MAX_PLANES];
unsigned int BytePerPixelC[DML2_MAX_PLANES];
unsigned int SwathWidthY[DML2_MAX_PLANES];
unsigned int SwathWidthC[DML2_MAX_PLANES];
unsigned int SwathWidthY[DML2_MAX_PLANES]; // per-pipe
unsigned int SwathWidthC[DML2_MAX_PLANES]; // per-pipe
unsigned int req_per_swath_ub_l[DML2_MAX_PLANES];
unsigned int req_per_swath_ub_c[DML2_MAX_PLANES];
unsigned int SwathWidthSingleDPPY[DML2_MAX_PLANES];
unsigned int SwathWidthSingleDPPC[DML2_MAX_PLANES];
double SurfaceReadBandwidthLuma[DML2_MAX_PLANES];
double SurfaceReadBandwidthChroma[DML2_MAX_PLANES];
double vactive_sw_bw_l[DML2_MAX_PLANES];
double vactive_sw_bw_c[DML2_MAX_PLANES];
double excess_vactive_fill_bw_l[DML2_MAX_PLANES];
double excess_vactive_fill_bw_c[DML2_MAX_PLANES];
@ -797,8 +800,9 @@ struct dml2_core_internal_mode_program {
double MaxActiveFCLKChangeLatencySupported;
bool USRRetrainingSupport;
bool g6_temp_read_support;
enum dml2_fclock_change_support FCLKChangeSupport[DML2_MAX_PLANES];
enum dml2_dram_clock_change_support DRAMClockChangeSupport[DML2_MAX_PLANES];
bool temp_read_or_ppt_support;
enum dml2_pstate_change_support FCLKChangeSupport[DML2_MAX_PLANES];
enum dml2_pstate_change_support DRAMClockChangeSupport[DML2_MAX_PLANES];
bool global_dram_clock_change_supported;
bool global_fclk_change_supported;
double MaxActiveDRAMClockChangeLatencySupported[DML2_MAX_PLANES];
@ -846,6 +850,8 @@ struct dml2_core_internal_mode_program {
bool mall_comb_mcache_l[DML2_MAX_PLANES];
bool mall_comb_mcache_c[DML2_MAX_PLANES];
bool lc_comb_mcache[DML2_MAX_PLANES];
double impacted_prefetch_margin_us[DML2_MAX_PLANES];
};
struct dml2_core_internal_SOCParametersList {
@ -862,6 +868,7 @@ struct dml2_core_internal_SOCParametersList {
double USRRetrainingLatency;
double SMNLatency;
double g6_temp_read_blackout_us;
double temp_read_or_ppt_blackout_us;
double max_urgent_latency_us;
double df_response_time_us;
enum dml2_qos_param_type qos_type;
@ -961,6 +968,17 @@ struct dml2_core_calcs_mode_support_locals {
unsigned int pstate_bytes_required_l[DML2_MAX_PLANES];
unsigned int pstate_bytes_required_c[DML2_MAX_PLANES];
double prefetch_sw_bytes[DML2_MAX_PLANES];
double Tpre_rounded[DML2_MAX_PLANES];
double Tpre_oto[DML2_MAX_PLANES];
bool recalc_prefetch_schedule;
bool recalc_prefetch_done;
double impacted_dst_y_pre[DML2_MAX_PLANES];
double line_times[DML2_MAX_PLANES];
enum dml2_source_format_class pixel_format[DML2_MAX_PLANES];
unsigned int lb_source_lines_l[DML2_MAX_PLANES];
unsigned int lb_source_lines_c[DML2_MAX_PLANES];
};
struct dml2_core_calcs_mode_programming_locals {
@ -1041,6 +1059,16 @@ struct dml2_core_calcs_mode_programming_locals {
unsigned int pstate_bytes_required_l[DML2_MAX_PLANES];
unsigned int pstate_bytes_required_c[DML2_MAX_PLANES];
double prefetch_sw_bytes[DML2_MAX_PLANES];
double Tpre_rounded[DML2_MAX_PLANES];
double Tpre_oto[DML2_MAX_PLANES];
bool recalc_prefetch_schedule;
double impacted_dst_y_pre[DML2_MAX_PLANES];
double line_times[DML2_MAX_PLANES];
enum dml2_source_format_class pixel_format[DML2_MAX_PLANES];
unsigned int lb_source_lines_l[DML2_MAX_PLANES];
unsigned int lb_source_lines_c[DML2_MAX_PLANES];
};
struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals {
@ -1048,6 +1076,7 @@ struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_local
double ActiveFCLKChangeLatencyMargin[DML2_MAX_PLANES];
double USRRetrainingLatencyMargin[DML2_MAX_PLANES];
double g6_temp_read_latency_margin[DML2_MAX_PLANES];
double temp_read_or_ppt_latency_margin[DML2_MAX_PLANES];
double EffectiveLBLatencyHidingY;
double EffectiveLBLatencyHidingC;
@ -1185,17 +1214,14 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_locals {
double LineTime;
double dst_y_prefetch_equ;
double prefetch_bw_oto;
double per_pipe_vactive_sw_bw;
double Tvm_oto;
double Tr0_oto;
double Tvm_no_trip_oto;
double Tr0_no_trip_oto;
double Tvm_oto_lines;
double Tr0_oto_lines;
double dst_y_prefetch_oto;
double TimeForFetchingVM;
double TimeForFetchingRowInVBlank;
double dst_y_per_vm_no_trip_vblank;
double dst_y_per_row_no_trip_vblank;
double LinesToRequestPrefetchPixelData;
unsigned int HostVMDynamicLevelsTrips;
double trip_to_mem;
@ -1203,15 +1229,12 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_locals {
double Tr0_trips_rounded;
double max_Tsw;
double Lsw_oto;
double Lsw_equ;
double Tpre_rounded;
double prefetch_bw_equ;
double Tvm_equ;
double Tr0_equ;
double Tdmbf;
double Tdmec;
double Tdmsks;
double prefetch_sw_bytes;
double total_row_bytes;
double prefetch_bw_pr;
double bytes_pp;
@ -1225,6 +1248,7 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_locals {
double prefetch_bw2;
double prefetch_bw3;
double prefetch_bw4;
double dst_y_prefetch_equ_impacted;
double TWait_p;
unsigned int cursor_prefetch_bytes;
@ -1545,17 +1569,18 @@ struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_param
// Output
struct dml2_core_internal_watermarks *Watermark;
enum dml2_dram_clock_change_support *DRAMClockChangeSupport;
enum dml2_pstate_change_support *DRAMClockChangeSupport;
bool *global_dram_clock_change_supported;
double *MaxActiveDRAMClockChangeLatencySupported;
unsigned int *SubViewportLinesNeededInMALL;
enum dml2_fclock_change_support *FCLKChangeSupport;
enum dml2_pstate_change_support *FCLKChangeSupport;
bool *global_fclk_change_supported;
double *MaxActiveFCLKChangeLatencySupported;
bool *USRRetrainingSupport;
double *VActiveLatencyHidingMargin;
double *VActiveLatencyHidingUs;
bool *g6_temp_read_support;
bool *temp_read_or_ppt_support;
};
@ -1727,8 +1752,8 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_params {
double PrefetchSourceLinesC;
unsigned int VInitPreFillC;
unsigned int MaxNumSwathC;
unsigned int swath_width_luma_ub;
unsigned int swath_width_chroma_ub;
unsigned int swath_width_luma_ub; // per-pipe
unsigned int swath_width_chroma_ub; // per-pipe
unsigned int SwathHeightY;
unsigned int SwathHeightC;
double TWait;
@ -1750,6 +1775,10 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_params {
unsigned int meta_row_bytes;
double mall_prefetch_sdp_overhead_factor;
double impacted_dst_y_pre;
double vactive_sw_bw_l; // per surface bw
double vactive_sw_bw_c; // per surface bw
// output
unsigned int *DSTXAfterScaler;
unsigned int *DSTYAfterScaler;
@ -1767,6 +1796,8 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_params {
double *Tdmdl_vm;
double *Tdmdl;
double *TSetup;
double *Tpre_rounded;
double *Tpre_oto;
double *Tvm_trips;
double *Tr0_trips;
double *Tvm_trips_flip;
@ -1777,6 +1808,47 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_params {
unsigned int *VUpdateWidthPix;
unsigned int *VReadyOffsetPix;
double *prefetch_cursor_bw;
double *prefetch_sw_bytes;
};
struct dml2_core_calcs_CheckGlobalPrefetchAdmissibility_params {
unsigned int num_active_planes;
enum dml2_source_format_class *pixel_format;
unsigned int rob_buffer_size_kbytes;
unsigned int compressed_buffer_size_kbytes;
unsigned int chunk_bytes_l; // same for all planes
unsigned int chunk_bytes_c;
unsigned int *detile_buffer_size_bytes_l;
unsigned int *detile_buffer_size_bytes_c;
unsigned int *full_swath_bytes_l;
unsigned int *full_swath_bytes_c;
unsigned int *lb_source_lines_l;
unsigned int *lb_source_lines_c;
unsigned int *swath_height_l;
unsigned int *swath_height_c;
double *prefetch_sw_bytes;
double *Tpre_rounded;
double *Tpre_oto;
double estimated_dcfclk_mhz;
double estimated_urg_bandwidth_required_mbps;
double *line_time;
double *dst_y_prefetch;
// output
bool *recalc_prefetch_schedule;
double *impacted_dst_y_pre;
};
struct dml2_core_calcs_CheckGlobalPrefetchAdmissibility_locals {
unsigned int max_Trpd_dcfclk_cycles;
unsigned int burst_bytes_to_fill_det;
double time_to_fill_det_us;
unsigned int accumulated_return_path_dcfclk_cycles[DML2_MAX_PLANES];
bool prefetch_global_check_passed;
unsigned int src_swath_bytes_l[DML2_MAX_PLANES];
unsigned int src_swath_bytes_c[DML2_MAX_PLANES];
unsigned int src_detile_buf_size_bytes_l[DML2_MAX_PLANES];
unsigned int src_detile_buf_size_bytes_c[DML2_MAX_PLANES];
};
struct dml2_core_calcs_calculate_mcache_row_bytes_params {
@ -2004,6 +2076,7 @@ struct dml2_core_internal_scratch {
struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals;
struct dml2_core_calcs_CalculateVMRowAndSwath_locals CalculateVMRowAndSwath_locals;
struct dml2_core_calcs_CalculatePrefetchSchedule_locals CalculatePrefetchSchedule_locals;
struct dml2_core_calcs_CheckGlobalPrefetchAdmissibility_locals CheckGlobalPrefetchAdmissibility_locals;
struct dml2_core_shared_CalculateSwathAndDETConfiguration_locals CalculateSwathAndDETConfiguration_locals;
struct dml2_core_shared_TruncToValidBPP_locals TruncToValidBPP_locals;
struct dml2_core_shared_CalculateDETBufferSize_locals CalculateDETBufferSize_locals;
@ -2019,6 +2092,7 @@ struct dml2_core_internal_scratch {
struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params CalculateSwathAndDETConfiguration_params;
struct dml2_core_calcs_CalculateStutterEfficiency_params CalculateStutterEfficiency_params;
struct dml2_core_calcs_CalculatePrefetchSchedule_params CalculatePrefetchSchedule_params;
struct dml2_core_calcs_CheckGlobalPrefetchAdmissibility_params CheckGlobalPrefetchAdmissibility_params;
struct dml2_core_calcs_calculate_mcache_setting_params calculate_mcache_setting_params;
struct dml2_core_calcs_calculate_tdlut_setting_params calculate_tdlut_setting_params;
struct dml2_core_shared_calculate_vm_and_row_bytes_params calculate_vm_and_row_bytes_params;
@ -2038,7 +2112,6 @@ struct dml2_core_internal_display_mode_lib {
// Used to hold input; intermediate and output of the calculations
struct dml2_core_internal_mode_support ms; // struct for mode support
struct dml2_core_internal_mode_program mp; // struct for mode programming
// Available overridable calculators for core_shared.
// if null, core_shared will use default calculators.
struct dml2_core_shared_calculation_funcs funcs;
@ -2051,7 +2124,6 @@ struct dml2_core_calcs_mode_support_ex {
const struct dml2_display_cfg *in_display_cfg;
const struct dml2_mcg_min_clock_table *min_clk_table;
int min_clk_index;
//unsigned int in_state_index;
struct dml2_core_internal_mode_support_info *out_evaluation_info;
};
@ -2064,7 +2136,6 @@ struct dml2_core_calcs_mode_programming_ex {
const struct dml2_mcg_min_clock_table *min_clk_table;
const struct core_display_cfg_support_info *cfg_support_info;
int min_clk_index;
struct dml2_display_cfg_programming *programming;
};

View File

@ -63,6 +63,150 @@ bool dml2_core_utils_is_420(enum dml2_source_format_class source_format)
case dml2_mono_16:
val = 0;
break;
case dml2_422_planar_8:
val = 0;
break;
case dml2_422_planar_10:
val = 0;
break;
case dml2_422_planar_12:
val = 0;
break;
case dml2_422_packed_8:
val = 0;
break;
case dml2_422_packed_10:
val = 0;
break;
case dml2_422_packed_12:
val = 0;
break;
default:
DML2_ASSERT(0);
break;
}
return val;
}
bool dml2_core_utils_is_422_planar(enum dml2_source_format_class source_format)
{
bool val = false;
switch (source_format) {
case dml2_444_8:
val = 0;
break;
case dml2_444_16:
val = 0;
break;
case dml2_444_32:
val = 0;
break;
case dml2_444_64:
val = 0;
break;
case dml2_420_8:
val = 0;
break;
case dml2_420_10:
val = 0;
break;
case dml2_420_12:
val = 0;
break;
case dml2_rgbe_alpha:
val = 0;
break;
case dml2_rgbe:
val = 0;
break;
case dml2_mono_8:
val = 0;
break;
case dml2_mono_16:
val = 0;
break;
case dml2_422_planar_8:
val = 1;
break;
case dml2_422_planar_10:
val = 1;
break;
case dml2_422_planar_12:
val = 1;
break;
case dml2_422_packed_8:
val = 0;
break;
case dml2_422_packed_10:
val = 0;
break;
case dml2_422_packed_12:
val = 0;
break;
default:
DML2_ASSERT(0);
break;
}
return val;
}
bool dml2_core_utils_is_422_packed(enum dml2_source_format_class source_format)
{
bool val = false;
switch (source_format) {
case dml2_444_8:
val = 0;
break;
case dml2_444_16:
val = 0;
break;
case dml2_444_32:
val = 0;
break;
case dml2_444_64:
val = 0;
break;
case dml2_420_8:
val = 0;
break;
case dml2_420_10:
val = 0;
break;
case dml2_420_12:
val = 0;
break;
case dml2_rgbe_alpha:
val = 0;
break;
case dml2_rgbe:
val = 0;
break;
case dml2_mono_8:
val = 0;
break;
case dml2_mono_16:
val = 0;
break;
case dml2_422_planar_8:
val = 0;
break;
case dml2_422_planar_10:
val = 0;
break;
case dml2_422_planar_12:
val = 0;
break;
case dml2_422_packed_8:
val = 1;
break;
case dml2_422_packed_10:
val = 1;
break;
case dml2_422_packed_12:
val = 1;
break;
default:
DML2_ASSERT(0);
break;
@ -154,9 +298,9 @@ void dml2_core_utils_print_mode_support_info(const struct dml2_core_internal_mod
dml2_printf("DML: support: DynamicMetadataSupported = %d\n", support->DynamicMetadataSupported);
if (!fail_only || support->VRatioInPrefetchSupported == 0)
dml2_printf("DML: support: VRatioInPrefetchSupported = %d\n", support->VRatioInPrefetchSupported);
if (!fail_only || support->PTEBufferSizeNotExceeded == 1)
if (!fail_only || support->PTEBufferSizeNotExceeded == 0)
dml2_printf("DML: support: PTEBufferSizeNotExceeded = %d\n", support->PTEBufferSizeNotExceeded);
if (!fail_only || support->DCCMetaBufferSizeNotExceeded == 1)
if (!fail_only || support->DCCMetaBufferSizeNotExceeded == 0)
dml2_printf("DML: support: DCCMetaBufferSizeNotExceeded = %d\n", support->DCCMetaBufferSizeNotExceeded);
if (!fail_only || support->ExceededMALLSize == 1)
dml2_printf("DML: support: ExceededMALLSize = %d\n", support->ExceededMALLSize);
@ -280,39 +424,49 @@ bool dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters *plane_c
return is_phantom;
}
unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode)
unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel)
{
switch (sw_mode) {
case (dml2_sw_linear):
return 256; break;
case (dml2_sw_256b_2d):
return 256; break;
case (dml2_sw_4kb_2d):
return 4096; break;
case (dml2_sw_64kb_2d):
return 65536; break;
case (dml2_sw_256kb_2d):
return 262144; break;
case (dml2_gfx11_sw_linear):
return 256; break;
case (dml2_gfx11_sw_64kb_d):
return 65536; break;
case (dml2_gfx11_sw_64kb_d_t):
return 65536; break;
case (dml2_gfx11_sw_64kb_d_x):
return 65536; break;
case (dml2_gfx11_sw_64kb_r_x):
return 65536; break;
case (dml2_gfx11_sw_256kb_d_x):
return 262144; break;
case (dml2_gfx11_sw_256kb_r_x):
return 262144; break;
default:
if (sw_mode == dml2_sw_linear)
return 256;
else if (sw_mode == dml2_sw_256b_2d)
return 256;
else if (sw_mode == dml2_sw_4kb_2d)
return 4096;
else if (sw_mode == dml2_sw_64kb_2d)
return 65536;
else if (sw_mode == dml2_sw_256kb_2d)
return 262144;
else if (sw_mode == dml2_gfx11_sw_linear)
return 256;
else if (sw_mode == dml2_gfx11_sw_64kb_d)
return 65536;
else if (sw_mode == dml2_gfx11_sw_64kb_d_t)
return 65536;
else if (sw_mode == dml2_gfx11_sw_64kb_d_x)
return 65536;
else if (sw_mode == dml2_gfx11_sw_64kb_r_x)
return 65536;
else if (sw_mode == dml2_gfx11_sw_256kb_d_x)
return 262144;
else if (sw_mode == dml2_gfx11_sw_256kb_r_x)
return 262144;
else {
DML2_ASSERT(0);
return 256;
};
}
bool dml2_core_utils_get_segment_horizontal_contiguous(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel)
{
return (byte_per_pixel != 2);
}
bool dml2_core_utils_is_linear(enum dml2_swizzle_mode sw_mode)
{
return (sw_mode == dml2_sw_linear || sw_mode == dml2_sw_linear_256b || sw_mode == dml2_linear_64elements);
};
bool dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan)
{
@ -325,7 +479,6 @@ bool dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan)
return is_vert;
}
int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode)
{
int unsigned version = 0;
@ -334,17 +487,17 @@ int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode)
sw_mode == dml2_sw_256b_2d ||
sw_mode == dml2_sw_4kb_2d ||
sw_mode == dml2_sw_64kb_2d ||
sw_mode == dml2_sw_256kb_2d) {
sw_mode == dml2_sw_256kb_2d)
version = 12;
} else if (sw_mode == dml2_gfx11_sw_linear ||
else if (sw_mode == dml2_gfx11_sw_linear ||
sw_mode == dml2_gfx11_sw_64kb_d ||
sw_mode == dml2_gfx11_sw_64kb_d_t ||
sw_mode == dml2_gfx11_sw_64kb_d_x ||
sw_mode == dml2_gfx11_sw_64kb_r_x ||
sw_mode == dml2_gfx11_sw_256kb_d_x ||
sw_mode == dml2_gfx11_sw_256kb_r_x) {
sw_mode == dml2_gfx11_sw_256kb_r_x)
version = 11;
} else {
else {
dml2_printf("ERROR: Invalid sw_mode setting! val=%u\n", sw_mode);
DML2_ASSERT(0);
}

View File

@ -11,6 +11,8 @@
double dml2_core_utils_div_rem(double dividend, unsigned int divisor, unsigned int *remainder);
const char *dml2_core_utils_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type);
bool dml2_core_utils_is_420(enum dml2_source_format_class source_format);
bool dml2_core_utils_is_422_planar(enum dml2_source_format_class source_format);
bool dml2_core_utils_is_422_packed(enum dml2_source_format_class source_format);
void dml2_core_utils_print_mode_support_info(const struct dml2_core_internal_mode_support_info *support, bool fail_only);
const char *dml2_core_utils_internal_soc_state_type_str(enum dml2_core_internal_soc_state_type dml2_core_internal_soc_state_type);
void dml2_core_utils_get_stream_output_bpp(double *out_bpp, const struct dml2_display_cfg *display_cfg);
@ -18,8 +20,10 @@ unsigned int dml2_core_utils_round_to_multiple(unsigned int num, unsigned int mu
unsigned int dml2_core_util_get_num_active_pipes(int unsigned num_planes, const struct core_display_cfg_support_info *cfg_support_info);
void dml2_core_utils_pipe_plane_mapping(const struct core_display_cfg_support_info *cfg_support_info, unsigned int *pipe_plane);
bool dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters *plane_cfg);
unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode);
unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel);
bool dml2_core_utils_get_segment_horizontal_contiguous(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel);
bool dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan);
bool dml2_core_utils_is_linear(enum dml2_swizzle_mode sw_mode);
int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode);
unsigned int dml2_core_utils_get_qos_param_index(unsigned long uclk_freq_khz, const struct dml2_dcn4_uclk_dpm_dependent_qos_params *per_uclk_dpm_params);
unsigned int dml2_core_utils_get_active_min_uclk_dpm_index(unsigned long uclk_freq_khz, const struct dml2_soc_state_table *clk_table);

View File

@ -180,7 +180,7 @@ static bool add_margin_and_round_to_dfs_grainularity(double clock_khz, double ma
clock_khz *= 1.0 + margin;
divider = (unsigned int)((int)DFS_DIVIDER_RANGE_SCALE_FACTOR * (vco_freq_khz / clock_khz));
divider = (unsigned int)(DFS_DIVIDER_RANGE_SCALE_FACTOR * (vco_freq_khz / clock_khz));
/* we want to floor here to get higher clock than required rather than lower */
if (divider < DFS_DIVIDER_RANGE_2_START) {
@ -711,7 +711,7 @@ bool dpmm_dcn4_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out *in_
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].fclk_pstate = (int unsigned)(mode_lib->mp.Watermark.FCLKChangeWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_enter = (int unsigned)(mode_lib->mp.Watermark.StutterEnterPlusExitWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_exit = (int unsigned)(mode_lib->mp.Watermark.StutterExitWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].temp_read_or_ppt = (int unsigned)(mode_lib->mp.Watermark.g6_temp_read_watermark_us * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].temp_read_or_ppt = (int unsigned)(mode_lib->mp.Watermark.temp_read_or_ppt_watermark_us * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].uclk_pstate = (int unsigned)(mode_lib->mp.Watermark.DRAMClockChangeWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].urgent = (int unsigned)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].usr = (int unsigned)(mode_lib->mp.Watermark.USRRetrainingWatermark * refclk_freq_in_mhz);
@ -725,7 +725,7 @@ bool dpmm_dcn4_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out *in_
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B].fclk_pstate = (int unsigned)(mode_lib->mp.Watermark.FCLKChangeWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B].sr_enter = (int unsigned)(mode_lib->mp.Watermark.StutterEnterPlusExitWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B].sr_exit = (int unsigned)(mode_lib->mp.Watermark.StutterExitWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B].temp_read_or_ppt = (int unsigned)(mode_lib->mp.Watermark.g6_temp_read_watermark_us * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B].temp_read_or_ppt = (int unsigned)(mode_lib->mp.Watermark.temp_read_or_ppt_watermark_us * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B].uclk_pstate = (int unsigned)(mode_lib->mp.Watermark.DRAMClockChangeWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B].urgent = (int unsigned)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz);
dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B].usr = (int unsigned)(mode_lib->mp.Watermark.USRRetrainingWatermark * refclk_freq_in_mhz);

View File

@ -13,32 +13,32 @@ static const double MIN_BLANK_STUTTER_FACTOR = 3.0;
static const struct dml2_pmo_pstate_strategy base_strategy_list_1_display[] = {
// VActive Preferred
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_na, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
// Then SVP
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_fw_svp, dml2_pstate_method_na, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
// Then VBlank
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = false,
},
// Then DRR
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_fw_drr, dml2_pstate_method_na, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
// Finally VBlank, but allow base clocks for latency to increase
/*
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
*/
@ -49,56 +49,56 @@ static const int base_strategy_list_1_display_size = sizeof(base_strategy_list_1
static const struct dml2_pmo_pstate_strategy base_strategy_list_2_display[] = {
// VActive only is preferred
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
// Then VActive + VBlank
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = false,
},
// Then VBlank only
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = false,
},
// Then SVP + VBlank
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_fw_svp, dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = false,
},
// Then SVP + DRR
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_fw_svp, dml2_pstate_method_fw_drr, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
// Then SVP + SVP
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_fw_svp, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_fw_svp, dml2_pstate_method_fw_svp, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
// Then DRR + VActive
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_fw_drr, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
// Then DRR + DRR
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_fw_drr, dml2_pstate_method_fw_drr, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
// Finally VBlank, but allow base clocks for latency to increase
/*
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na },
.allow_state_increase = true,
},
*/
@ -109,32 +109,32 @@ static const int base_strategy_list_2_display_size = sizeof(base_strategy_list_2
static const struct dml2_pmo_pstate_strategy base_strategy_list_3_display[] = {
// All VActive
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_na },
.allow_state_increase = true,
},
// VActive + 1 VBlank
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vblank, dml2_pstate_method_na },
.allow_state_increase = false,
},
// All VBlank
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_na },
.allow_state_increase = false,
},
// All DRR
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_fw_drr, dml2_pstate_method_fw_drr, dml2_pstate_method_fw_drr, dml2_pstate_method_na },
.allow_state_increase = true,
},
// All VBlank, with state increase allowed
/*
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_na },
.per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_na },
.allow_state_increase = true,
},
*/
@ -145,32 +145,32 @@ static const int base_strategy_list_3_display_size = sizeof(base_strategy_list_3
static const struct dml2_pmo_pstate_strategy base_strategy_list_4_display[] = {
// All VActive
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive },
.per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vactive },
.allow_state_increase = true,
},
// VActive + 1 VBlank
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vactive, dml2_pmo_pstate_strategy_vblank },
.per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vblank },
.allow_state_increase = false,
},
// All Vblank
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank },
.per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank },
.allow_state_increase = false,
},
// All DRR
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr, dml2_pmo_pstate_strategy_fw_drr },
.per_stream_pstate_method = { dml2_pstate_method_fw_drr, dml2_pstate_method_fw_drr, dml2_pstate_method_fw_drr, dml2_pstate_method_fw_drr },
.allow_state_increase = true,
},
// All VBlank, with state increase allowed
/*
{
.per_stream_pstate_method = { dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank, dml2_pmo_pstate_strategy_vblank },
.per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank },
.allow_state_increase = true,
},
*/
@ -355,29 +355,30 @@ bool pmo_dcn4_fams2_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_o
return result;
}
static enum dml2_pmo_pstate_method convert_strategy_to_drr_variant(const enum dml2_pmo_pstate_method base_strategy)
static enum dml2_pstate_method convert_strategy_to_drr_variant(const enum dml2_pstate_method base_strategy)
{
enum dml2_pmo_pstate_method variant_strategy = 0;
enum dml2_pstate_method variant_strategy = 0;
switch (base_strategy) {
case dml2_pmo_pstate_strategy_vactive:
variant_strategy = dml2_pmo_pstate_strategy_fw_vactive_drr;
case dml2_pstate_method_vactive:
variant_strategy = dml2_pstate_method_fw_vactive_drr;
break;
case dml2_pmo_pstate_strategy_vblank:
variant_strategy = dml2_pmo_pstate_strategy_fw_vblank_drr;
case dml2_pstate_method_vblank:
variant_strategy = dml2_pstate_method_fw_vblank_drr;
break;
case dml2_pmo_pstate_strategy_fw_svp:
variant_strategy = dml2_pmo_pstate_strategy_fw_svp_drr;
case dml2_pstate_method_fw_svp:
variant_strategy = dml2_pstate_method_fw_svp_drr;
break;
case dml2_pmo_pstate_strategy_fw_vactive_drr:
case dml2_pmo_pstate_strategy_fw_vblank_drr:
case dml2_pmo_pstate_strategy_fw_svp_drr:
case dml2_pmo_pstate_strategy_fw_drr:
case dml2_pmo_pstate_strategy_reserved_hw:
case dml2_pmo_pstate_strategy_reserved_fw:
case dml2_pmo_pstate_strategy_reserved_fw_drr_clamped:
case dml2_pmo_pstate_strategy_reserved_fw_drr_var:
case dml2_pmo_pstate_strategy_na:
case dml2_pstate_method_fw_vactive_drr:
case dml2_pstate_method_fw_vblank_drr:
case dml2_pstate_method_fw_svp_drr:
case dml2_pstate_method_fw_drr:
case dml2_pstate_method_reserved_hw:
case dml2_pstate_method_reserved_fw:
case dml2_pstate_method_reserved_fw_drr_clamped:
case dml2_pstate_method_reserved_fw_drr_var:
case dml2_pstate_method_count:
case dml2_pstate_method_na:
default:
/* no variant for this mode */
variant_strategy = base_strategy;
@ -419,23 +420,22 @@ static unsigned int get_num_expanded_strategies(
static void insert_strategy_into_expanded_list(
const struct dml2_pmo_pstate_strategy *per_stream_pstate_strategy,
int stream_count,
struct dml2_pmo_init_data *init_data)
const int stream_count,
struct dml2_pmo_pstate_strategy *expanded_strategy_list,
unsigned int *num_expanded_strategies)
{
struct dml2_pmo_pstate_strategy *expanded_strategy_list = NULL;
if (expanded_strategy_list && num_expanded_strategies) {
memcpy(&expanded_strategy_list[*num_expanded_strategies], per_stream_pstate_strategy, sizeof(struct dml2_pmo_pstate_strategy));
expanded_strategy_list = get_expanded_strategy_list(init_data, stream_count);
if (expanded_strategy_list) {
memcpy(&expanded_strategy_list[init_data->pmo_dcn4.num_expanded_strategies_per_list[stream_count - 1]], per_stream_pstate_strategy, sizeof(struct dml2_pmo_pstate_strategy));
init_data->pmo_dcn4.num_expanded_strategies_per_list[stream_count - 1]++;
(*num_expanded_strategies)++;
}
}
static void expand_base_strategy(struct dml2_pmo_instance *pmo,
static void expand_base_strategy(
const struct dml2_pmo_pstate_strategy *base_strategy,
unsigned int stream_count)
const unsigned int stream_count,
struct dml2_pmo_pstate_strategy *expanded_strategy_list,
unsigned int *num_expanded_strategies)
{
bool skip_to_next_stream;
bool expanded_strategy_added;
@ -473,7 +473,7 @@ static void expand_base_strategy(struct dml2_pmo_instance *pmo,
if (i >= stream_count - 1) {
/* insert into strategy list */
insert_strategy_into_expanded_list(&cur_strategy_list, stream_count, &pmo->init_data);
insert_strategy_into_expanded_list(&cur_strategy_list, stream_count, expanded_strategy_list, num_expanded_strategies);
expanded_strategy_added = true;
} else {
/* skip to next stream */
@ -512,9 +512,9 @@ static void expand_base_strategy(struct dml2_pmo_instance *pmo,
static bool is_variant_method_valid(const struct dml2_pmo_pstate_strategy *base_strategy,
const struct dml2_pmo_pstate_strategy *variant_strategy,
unsigned int num_streams_per_base_method[PMO_DCN4_MAX_DISPLAYS],
unsigned int num_streams_per_variant_method[PMO_DCN4_MAX_DISPLAYS],
unsigned int stream_count)
const unsigned int num_streams_per_base_method[PMO_DCN4_MAX_DISPLAYS],
const unsigned int num_streams_per_variant_method[PMO_DCN4_MAX_DISPLAYS],
const unsigned int stream_count)
{
bool valid = true;
unsigned int i;
@ -522,7 +522,7 @@ static bool is_variant_method_valid(const struct dml2_pmo_pstate_strategy *base_
/* check all restrictions are met */
for (i = 0; i < stream_count; i++) {
/* vblank + vblank_drr variants are invalid */
if (base_strategy->per_stream_pstate_method[i] == dml2_pmo_pstate_strategy_vblank &&
if (base_strategy->per_stream_pstate_method[i] == dml2_pstate_method_vblank &&
((num_streams_per_base_method[i] > 0 && num_streams_per_variant_method[i] > 0) ||
num_streams_per_variant_method[i] > 1)) {
valid = false;
@ -533,9 +533,12 @@ static bool is_variant_method_valid(const struct dml2_pmo_pstate_strategy *base_
return valid;
}
static void expand_variant_strategy(struct dml2_pmo_instance *pmo,
static void expand_variant_strategy(
const struct dml2_pmo_pstate_strategy *base_strategy,
unsigned int stream_count)
const unsigned int stream_count,
const bool should_permute,
struct dml2_pmo_pstate_strategy *expanded_strategy_list,
unsigned int *num_expanded_strategies)
{
bool variant_found;
unsigned int i, j;
@ -544,7 +547,7 @@ static void expand_variant_strategy(struct dml2_pmo_instance *pmo,
unsigned int num_streams_per_method[PMO_DCN4_MAX_DISPLAYS] = { 0 };
unsigned int num_streams_per_base_method[PMO_DCN4_MAX_DISPLAYS] = { 0 };
unsigned int num_streams_per_variant_method[PMO_DCN4_MAX_DISPLAYS] = { 0 };
enum dml2_pmo_pstate_method per_stream_variant_method[DML2_MAX_PLANES];
enum dml2_pstate_method per_stream_variant_method[DML2_MAX_PLANES];
struct dml2_pmo_pstate_strategy variant_strategy = { 0 };
/* determine number of displays per method */
@ -585,7 +588,13 @@ static void expand_variant_strategy(struct dml2_pmo_instance *pmo,
}
if (variant_found && is_variant_method_valid(base_strategy, &variant_strategy, num_streams_per_base_method, num_streams_per_variant_method, stream_count)) {
expand_base_strategy(pmo, &variant_strategy, stream_count);
if (should_permute) {
/* permutations are permitted, proceed to expand */
expand_base_strategy(&variant_strategy, stream_count, expanded_strategy_list, num_expanded_strategies);
} else {
/* no permutations allowed, so add to list now */
insert_strategy_into_expanded_list(&variant_strategy, stream_count, expanded_strategy_list, num_expanded_strategies);
}
}
/* rollback to earliest method with bases remaining */
@ -612,18 +621,19 @@ static void expand_variant_strategy(struct dml2_pmo_instance *pmo,
}
}
static void expand_base_strategies(
struct dml2_pmo_instance *pmo,
const struct dml2_pmo_pstate_strategy *base_strategies_list,
const unsigned int num_base_strategies,
unsigned int stream_count)
void pmo_dcn4_fams2_expand_base_pstate_strategies(
const struct dml2_pmo_pstate_strategy *base_strategies_list,
const unsigned int num_base_strategies,
const unsigned int stream_count,
struct dml2_pmo_pstate_strategy *expanded_strategy_list,
unsigned int *num_expanded_strategies)
{
unsigned int i;
/* expand every explicit base strategy (except all DRR) */
for (i = 0; i < num_base_strategies; i++) {
expand_base_strategy(pmo, &base_strategies_list[i], stream_count);
expand_variant_strategy(pmo, &base_strategies_list[i], stream_count);
expand_base_strategy(&base_strategies_list[i], stream_count, expanded_strategy_list, num_expanded_strategies);
expand_variant_strategy(&base_strategies_list[i], stream_count, true, expanded_strategy_list, num_expanded_strategies);
}
}
@ -652,25 +662,45 @@ bool pmo_dcn4_fams2_initialize(struct dml2_pmo_initialize_in_out *in_out)
DML2_ASSERT(base_strategy_list_1_display_size <= PMO_DCN4_MAX_BASE_STRATEGIES);
/* populate list */
expand_base_strategies(pmo, base_strategy_list_1_display, base_strategy_list_1_display_size, 1);
pmo_dcn4_fams2_expand_base_pstate_strategies(
base_strategy_list_1_display,
base_strategy_list_1_display_size,
i,
pmo->init_data.pmo_dcn4.expanded_strategy_list_1_display,
&pmo->init_data.pmo_dcn4.num_expanded_strategies_per_list[i - 1]);
break;
case 2:
DML2_ASSERT(base_strategy_list_2_display_size <= PMO_DCN4_MAX_BASE_STRATEGIES);
/* populate list */
expand_base_strategies(pmo, base_strategy_list_2_display, base_strategy_list_2_display_size, 2);
pmo_dcn4_fams2_expand_base_pstate_strategies(
base_strategy_list_2_display,
base_strategy_list_2_display_size,
i,
pmo->init_data.pmo_dcn4.expanded_strategy_list_2_display,
&pmo->init_data.pmo_dcn4.num_expanded_strategies_per_list[i - 1]);
break;
case 3:
DML2_ASSERT(base_strategy_list_3_display_size <= PMO_DCN4_MAX_BASE_STRATEGIES);
/* populate list */
expand_base_strategies(pmo, base_strategy_list_3_display, base_strategy_list_3_display_size, 3);
pmo_dcn4_fams2_expand_base_pstate_strategies(
base_strategy_list_3_display,
base_strategy_list_3_display_size,
i,
pmo->init_data.pmo_dcn4.expanded_strategy_list_3_display,
&pmo->init_data.pmo_dcn4.num_expanded_strategies_per_list[i - 1]);
break;
case 4:
DML2_ASSERT(base_strategy_list_4_display_size <= PMO_DCN4_MAX_BASE_STRATEGIES);
/* populate list */
expand_base_strategies(pmo, base_strategy_list_4_display, base_strategy_list_4_display_size, 4);
pmo_dcn4_fams2_expand_base_pstate_strategies(
base_strategy_list_4_display,
base_strategy_list_4_display_size,
i,
pmo->init_data.pmo_dcn4.expanded_strategy_list_4_display,
&pmo->init_data.pmo_dcn4.num_expanded_strategies_per_list[i - 1]);
break;
}
}
@ -941,11 +971,8 @@ static void build_synchronized_timing_groups(
/* find synchronizable timing groups */
for (j = i + 1; j < display_config->display_config.num_streams; j++) {
if (memcmp(master_timing,
&display_config->display_config.stream_descriptors[j].timing,
sizeof(struct dml2_timing_cfg)) == 0 &&
display_config->display_config.stream_descriptors[i].output.output_encoder == display_config->display_config.stream_descriptors[j].output.output_encoder &&
(display_config->display_config.stream_descriptors[i].output.output_encoder != dml2_hdmi || //hdmi requires formats match
display_config->display_config.stream_descriptors[i].output.output_format == display_config->display_config.stream_descriptors[j].output.output_format)) {
&display_config->display_config.stream_descriptors[j].timing,
sizeof(struct dml2_timing_cfg)) == 0) {
set_bit_in_bitfield(&pmo->scratch.pmo_dcn4.synchronized_timing_group_masks[timing_group_idx], j);
set_bit_in_bitfield(&stream_mapped_mask, j);
}
@ -1106,24 +1133,73 @@ static void insert_into_candidate_list(const struct dml2_pmo_pstate_strategy *ps
scratch->pmo_dcn4.num_pstate_candidates++;
}
static bool all_planes_match_method(const struct display_configuation_with_meta *display_cfg, int plane_mask, enum dml2_pmo_pstate_method method)
static enum dml2_pstate_method uclk_pstate_strategy_override_to_pstate_method(const enum dml2_uclk_pstate_change_strategy override_strategy)
{
enum dml2_pstate_method method = dml2_pstate_method_na;
switch (override_strategy) {
case dml2_uclk_pstate_change_strategy_force_vactive:
method = dml2_pstate_method_vactive;
break;
case dml2_uclk_pstate_change_strategy_force_vblank:
method = dml2_pstate_method_vblank;
break;
case dml2_uclk_pstate_change_strategy_force_drr:
method = dml2_pstate_method_fw_drr;
break;
case dml2_uclk_pstate_change_strategy_force_mall_svp:
method = dml2_pstate_method_fw_svp;
break;
case dml2_uclk_pstate_change_strategy_force_mall_full_frame:
case dml2_uclk_pstate_change_strategy_auto:
default:
method = dml2_pstate_method_na;
}
return method;
}
static enum dml2_uclk_pstate_change_strategy pstate_method_to_uclk_pstate_strategy_override(const enum dml2_pstate_method method)
{
enum dml2_uclk_pstate_change_strategy override_strategy = dml2_uclk_pstate_change_strategy_auto;
switch (method) {
case dml2_pstate_method_vactive:
case dml2_pstate_method_fw_vactive_drr:
override_strategy = dml2_uclk_pstate_change_strategy_force_vactive;
break;
case dml2_pstate_method_vblank:
case dml2_pstate_method_fw_vblank_drr:
override_strategy = dml2_uclk_pstate_change_strategy_force_vblank;
break;
case dml2_pstate_method_fw_svp:
case dml2_pstate_method_fw_svp_drr:
override_strategy = dml2_uclk_pstate_change_strategy_force_mall_svp;
break;
case dml2_pstate_method_fw_drr:
override_strategy = dml2_uclk_pstate_change_strategy_force_drr;
break;
case dml2_pstate_method_reserved_hw:
case dml2_pstate_method_reserved_fw:
case dml2_pstate_method_reserved_fw_drr_clamped:
case dml2_pstate_method_reserved_fw_drr_var:
case dml2_pstate_method_count:
case dml2_pstate_method_na:
default:
override_strategy = dml2_uclk_pstate_change_strategy_auto;
}
return override_strategy;
}
static bool all_planes_match_method(const struct display_configuation_with_meta *display_cfg, int plane_mask, enum dml2_pstate_method method)
{
unsigned char i;
enum dml2_uclk_pstate_change_strategy matching_strategy = (enum dml2_uclk_pstate_change_strategy) dml2_pmo_pstate_strategy_na;
if (method == dml2_pmo_pstate_strategy_vactive || method == dml2_pmo_pstate_strategy_fw_vactive_drr)
matching_strategy = dml2_uclk_pstate_change_strategy_force_vactive;
else if (method == dml2_pmo_pstate_strategy_vblank || method == dml2_pmo_pstate_strategy_fw_vblank_drr)
matching_strategy = dml2_uclk_pstate_change_strategy_force_vblank;
else if (method == dml2_pmo_pstate_strategy_fw_svp)
matching_strategy = dml2_uclk_pstate_change_strategy_force_mall_svp;
else if (method == dml2_pmo_pstate_strategy_fw_drr)
matching_strategy = dml2_uclk_pstate_change_strategy_force_drr;
for (i = 0; i < DML2_MAX_PLANES; i++) {
if (is_bit_set_in_bitfield(plane_mask, i)) {
if (display_cfg->display_config.plane_descriptors[i].overrides.uclk_pstate_change_strategy != dml2_uclk_pstate_change_strategy_auto &&
display_cfg->display_config.plane_descriptors[i].overrides.uclk_pstate_change_strategy != matching_strategy)
display_cfg->display_config.plane_descriptors[i].overrides.uclk_pstate_change_strategy != pstate_method_to_uclk_pstate_strategy_override(method))
return false;
}
}
@ -1149,32 +1225,33 @@ static void build_method_scheduling_params(
static struct dml2_fams2_per_method_common_meta *get_per_method_common_meta(
struct dml2_pmo_instance *pmo,
enum dml2_pmo_pstate_method stream_pstate_method,
enum dml2_pstate_method stream_pstate_method,
int stream_idx)
{
struct dml2_fams2_per_method_common_meta *stream_method_fams2_meta = NULL;
switch (stream_pstate_method) {
case dml2_pmo_pstate_strategy_vactive:
case dml2_pmo_pstate_strategy_fw_vactive_drr:
case dml2_pstate_method_vactive:
case dml2_pstate_method_fw_vactive_drr:
stream_method_fams2_meta = &pmo->scratch.pmo_dcn4.stream_fams2_meta[stream_idx].method_vactive.common;
break;
case dml2_pmo_pstate_strategy_vblank:
case dml2_pmo_pstate_strategy_fw_vblank_drr:
case dml2_pstate_method_vblank:
case dml2_pstate_method_fw_vblank_drr:
stream_method_fams2_meta = &pmo->scratch.pmo_dcn4.stream_fams2_meta[stream_idx].method_vblank.common;
break;
case dml2_pmo_pstate_strategy_fw_svp:
case dml2_pmo_pstate_strategy_fw_svp_drr:
case dml2_pstate_method_fw_svp:
case dml2_pstate_method_fw_svp_drr:
stream_method_fams2_meta = &pmo->scratch.pmo_dcn4.stream_fams2_meta[stream_idx].method_subvp.common;
break;
case dml2_pmo_pstate_strategy_fw_drr:
case dml2_pstate_method_fw_drr:
stream_method_fams2_meta = &pmo->scratch.pmo_dcn4.stream_fams2_meta[stream_idx].method_drr.common;
break;
case dml2_pmo_pstate_strategy_reserved_hw:
case dml2_pmo_pstate_strategy_reserved_fw:
case dml2_pmo_pstate_strategy_reserved_fw_drr_clamped:
case dml2_pmo_pstate_strategy_reserved_fw_drr_var:
case dml2_pmo_pstate_strategy_na:
case dml2_pstate_method_reserved_hw:
case dml2_pstate_method_reserved_fw:
case dml2_pstate_method_reserved_fw_drr_clamped:
case dml2_pstate_method_reserved_fw_drr_var:
case dml2_pstate_method_count:
case dml2_pstate_method_na:
default:
stream_method_fams2_meta = NULL;
}
@ -1215,7 +1292,7 @@ static bool is_timing_group_schedulable(
if (is_bit_set_in_bitfield(pmo->scratch.pmo_dcn4.synchronized_timing_group_masks[timing_group_idx], i)) {
stream_method_fams2_meta = get_per_method_common_meta(pmo, pstate_strategy->per_stream_pstate_method[i], i);
if (!stream_method_fams2_meta)
return false;
continue;
if (group_fams2_meta->allow_start_otg_vline < stream_method_fams2_meta->allow_start_otg_vline) {
/* set group allow start to larger otg vline */
@ -1295,7 +1372,7 @@ static bool is_config_schedulable(
if (j_disallow_us < jp1_disallow_us) {
/* swap as A < B */
swap(s->pmo_dcn4.sorted_group_gtl_disallow_index[j],
s->pmo_dcn4.sorted_group_gtl_disallow_index[j+1]);
s->pmo_dcn4.sorted_group_gtl_disallow_index[j+1]);
swapped = true;
}
}
@ -1354,7 +1431,7 @@ static bool is_config_schedulable(
if (j_period_us < jp1_period_us) {
/* swap as A < B */
swap(s->pmo_dcn4.sorted_group_gtl_period_index[j],
s->pmo_dcn4.sorted_group_gtl_period_index[j+1]);
s->pmo_dcn4.sorted_group_gtl_period_index[j+1]);
swapped = true;
}
}
@ -1413,7 +1490,7 @@ static bool is_config_schedulable(
static bool stream_matches_drr_policy(struct dml2_pmo_instance *pmo,
const struct display_configuation_with_meta *display_cfg,
const enum dml2_pmo_pstate_method stream_pstate_method,
const enum dml2_pstate_method stream_pstate_method,
unsigned int stream_index)
{
const struct dml2_stream_parameters *stream_descriptor = &display_cfg->display_config.stream_descriptors[stream_index];
@ -1494,19 +1571,19 @@ static bool validate_pstate_support_strategy_cofunctionality(struct dml2_pmo_ins
strategy_matches_drr_requirements &=
stream_matches_drr_policy(pmo, display_cfg, pstate_strategy->per_stream_pstate_method[stream_index], stream_index);
if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp ||
pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_svp ||
pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_svp_drr) {
svp_count++;
set_bit_in_bitfield(&svp_stream_mask, stream_index);
} else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
} else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_drr) {
drr_count++;
set_bit_in_bitfield(&drr_stream_mask, stream_index);
} else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vactive ||
pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
} else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pstate_method_vactive ||
pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_vactive_drr) {
vactive_count++;
set_bit_in_bitfield(&vactive_stream_mask, stream_index);
} else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vblank ||
pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
} else if (pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pstate_method_vblank ||
pstate_strategy->per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_vblank_drr) {
vblank_count++;
set_bit_in_bitfield(&vblank_stream_mask, stream_index);
}
@ -1625,7 +1702,7 @@ static void build_fams2_meta_per_stream(struct dml2_pmo_instance *pmo,
/* for single stream, guarantee at least an instant of allow */
stream_fams2_meta->method_vactive.max_vactive_det_fill_delay_otg_vlines = (unsigned int)math_floor(
math_max2(0.0,
timing->v_active - stream_fams2_meta->min_allow_width_otg_vlines - stream_fams2_meta->dram_clk_change_blackout_otg_vlines));
timing->v_active - math_max2(1.0, stream_fams2_meta->min_allow_width_otg_vlines) - stream_fams2_meta->dram_clk_change_blackout_otg_vlines));
} else {
/* for multi stream, bound to a max fill time defined by IP caps */
stream_fams2_meta->method_vactive.max_vactive_det_fill_delay_otg_vlines =
@ -1738,8 +1815,10 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
struct display_configuation_with_meta *display_config;
const struct dml2_plane_parameters *plane_descriptor;
const struct dml2_pmo_pstate_strategy *strategy_list = NULL;
struct dml2_pmo_pstate_strategy override_base_strategy = { 0 };
unsigned int strategy_list_size = 0;
unsigned char plane_index, stream_index, i;
bool build_override_strategy = true;
state->performed = true;
in_out->base_display_config->stage3.min_clk_index_for_latency = in_out->base_display_config->stage1.min_clk_index_for_latency;
@ -1763,7 +1842,11 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
set_bit_in_bitfield(&s->pmo_dcn4.stream_plane_mask[plane_descriptor->stream_index], plane_index);
state->pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_vactive;
state->pstate_switch_modes[plane_index] = dml2_pstate_method_vactive;
build_override_strategy &= plane_descriptor->overrides.uclk_pstate_change_strategy != dml2_uclk_pstate_change_strategy_auto;
override_base_strategy.per_stream_pstate_method[plane_descriptor->stream_index] =
uclk_pstate_strategy_override_to_pstate_method(plane_descriptor->overrides.uclk_pstate_change_strategy);
}
// Figure out which streams can do vactive, and also build up implicit SVP and FAMS2 meta
@ -1781,13 +1864,30 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
/* get synchronized timing groups */
build_synchronized_timing_groups(pmo, display_config);
strategy_list = get_expanded_strategy_list(&pmo->init_data, display_config->display_config.num_streams);
if (!strategy_list)
return false;
if (build_override_strategy) {
/* build expanded override strategy list (no permutations) */
override_base_strategy.allow_state_increase = true;
s->pmo_dcn4.num_expanded_override_strategies = 0;
insert_strategy_into_expanded_list(&override_base_strategy,
display_config->display_config.num_streams,
s->pmo_dcn4.expanded_override_strategy_list,
&s->pmo_dcn4.num_expanded_override_strategies);
expand_variant_strategy(&override_base_strategy,
display_config->display_config.num_streams,
false,
s->pmo_dcn4.expanded_override_strategy_list,
&s->pmo_dcn4.num_expanded_override_strategies);
strategy_list_size = get_num_expanded_strategies(&pmo->init_data, display_config->display_config.num_streams);
/* use override strategy list */
strategy_list = s->pmo_dcn4.expanded_override_strategy_list;
strategy_list_size = s->pmo_dcn4.num_expanded_override_strategies;
} else {
/* use predefined strategy list */
strategy_list = get_expanded_strategy_list(&pmo->init_data, display_config->display_config.num_streams);
strategy_list_size = get_num_expanded_strategies(&pmo->init_data, display_config->display_config.num_streams);
}
if (strategy_list_size == 0)
if (!strategy_list || strategy_list_size == 0)
return false;
s->pmo_dcn4.num_pstate_candidates = 0;
@ -1799,7 +1899,7 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
}
if (s->pmo_dcn4.num_pstate_candidates > 0) {
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.num_pstate_candidates - 1].allow_state_increase = true;
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.num_pstate_candidates-1].allow_state_increase = true;
s->pmo_dcn4.cur_pstate_candidate = -1;
return true;
} else {
@ -1832,7 +1932,7 @@ static void reset_display_configuration(struct display_configuation_with_meta *d
// Reset strategy to auto
plane->overrides.uclk_pstate_change_strategy = dml2_uclk_pstate_change_strategy_auto;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_not_supported;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_na;
}
}
@ -1849,7 +1949,7 @@ static void setup_planes_for_drr_by_mask(struct display_configuation_with_meta *
plane->overrides.uclk_pstate_change_strategy = dml2_uclk_pstate_change_strategy_force_drr;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_fw_drr;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_fw_drr;
}
}
@ -1867,7 +1967,7 @@ static void setup_planes_for_svp_by_mask(struct display_configuation_with_meta *
for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
stream_index = (char)display_config->display_config.plane_descriptors[plane_index].stream_index;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_fw_subvp_phantom;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_fw_svp;
}
}
@ -1890,7 +1990,7 @@ static void setup_planes_for_svp_drr_by_mask(struct display_configuation_with_me
for (plane_index = 0; plane_index < display_config->display_config.num_planes; plane_index++) {
if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
stream_index = (char)display_config->display_config.plane_descriptors[plane_index].stream_index;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_fw_subvp_phantom_drr;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_fw_svp_drr;
}
}
@ -1915,7 +2015,7 @@ static void setup_planes_for_vblank_by_mask(struct display_configuation_with_met
plane->overrides.reserved_vblank_time_ns = (long)math_max2(pmo->soc_bb->power_management_parameters.dram_clk_change_blackout_us * 1000.0,
plane->overrides.reserved_vblank_time_ns);
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_vblank;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_vblank;
}
}
@ -1933,7 +2033,7 @@ static void setup_planes_for_vblank_drr_by_mask(struct display_configuation_with
plane = &display_config->display_config.plane_descriptors[plane_index];
plane->overrides.reserved_vblank_time_ns = (long)(pmo->soc_bb->power_management_parameters.dram_clk_change_blackout_us * 1000);
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_fw_vblank_drr;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_fw_vblank_drr;
}
}
}
@ -1949,7 +2049,7 @@ static void setup_planes_for_vactive_by_mask(struct display_configuation_with_me
if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
stream_index = display_config->display_config.plane_descriptors[plane_index].stream_index;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_vactive;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_vactive;
if (!pmo->options->disable_vactive_det_fill_bw_pad) {
display_config->display_config.plane_descriptors[plane_index].overrides.max_vactive_det_fill_delay_us =
@ -1970,7 +2070,7 @@ static void setup_planes_for_vactive_drr_by_mask(struct display_configuation_wit
if (is_bit_set_in_bitfield(plane_mask, plane_index)) {
stream_index = display_config->display_config.plane_descriptors[plane_index].stream_index;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_uclk_pstate_support_method_fw_vactive_drr;
display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_fw_vactive_drr;
if (!pmo->options->disable_vactive_det_fill_bw_pad) {
display_config->display_config.plane_descriptors[plane_index].overrides.max_vactive_det_fill_delay_us =
@ -1992,26 +2092,26 @@ static bool setup_display_config(struct display_configuation_with_meta *display_
for (stream_index = 0; stream_index < display_config->display_config.num_streams; stream_index++) {
if (pmo->scratch.pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_na) {
if (pmo->scratch.pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pstate_method_na) {
success = false;
break;
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vactive) {
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pstate_method_vactive) {
setup_planes_for_vactive_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vblank) {
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pstate_method_vblank) {
setup_planes_for_vblank_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp) {
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_svp) {
fams2_required = true;
setup_planes_for_svp_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_vactive_drr) {
fams2_required = true;
setup_planes_for_vactive_drr_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_vblank_drr) {
fams2_required = true;
setup_planes_for_vblank_drr_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_svp_drr) {
fams2_required = true;
setup_planes_for_svp_drr_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
} else if (scratch->pmo_dcn4.pstate_strategy_candidates[strategy_index].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_drr) {
fams2_required = true;
setup_planes_for_drr_by_mask(display_config, pmo, scratch->pmo_dcn4.stream_plane_mask[stream_index]);
}
@ -2066,34 +2166,34 @@ bool pmo_dcn4_fams2_test_for_pstate_support(struct dml2_pmo_test_for_pstate_supp
for (stream_index = 0; stream_index < in_out->base_display_config->display_config.num_streams; stream_index++) {
struct dml2_fams2_meta *stream_fams2_meta = &s->pmo_dcn4.stream_fams2_meta[stream_index];
if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vactive ||
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vactive_drr) {
if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_vactive ||
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_vactive_drr) {
if (get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < (MIN_VACTIVE_MARGIN_PCT * in_out->instance->soc_bb->power_management_parameters.dram_clk_change_blackout_us) ||
get_vactive_det_fill_latency_delay_us(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) > stream_fams2_meta->method_vactive.max_vactive_det_fill_delay_us) {
p_state_supported = false;
break;
}
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_vblank ||
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_vblank_drr) {
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_vblank ||
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_vblank_drr) {
if (get_minimum_reserved_time_us_for_planes(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) <
REQUIRED_RESERVED_TIME ||
get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_VBLANK) {
p_state_supported = false;
break;
}
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp ||
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_svp_drr) {
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_svp ||
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_svp_drr) {
if (in_out->base_display_config->stage3.stream_svp_meta[stream_index].valid == false) {
p_state_supported = false;
break;
}
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_fw_drr) {
if (!all_planes_match_method(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index], dml2_pmo_pstate_strategy_fw_drr) ||
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_drr) {
if (!all_planes_match_method(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index], dml2_pstate_method_fw_drr) ||
get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_DRR) {
p_state_supported = false;
break;
}
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pmo_pstate_strategy_na) {
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_na) {
p_state_supported = false;
break;
}

View File

@ -23,4 +23,11 @@ bool pmo_dcn4_fams2_init_for_stutter(struct dml2_pmo_init_for_stutter_in_out *in
bool pmo_dcn4_fams2_test_for_stutter(struct dml2_pmo_test_for_stutter_in_out *in_out);
bool pmo_dcn4_fams2_optimize_for_stutter(struct dml2_pmo_optimize_for_stutter_in_out *in_out);
void pmo_dcn4_fams2_expand_base_pstate_strategies(
const struct dml2_pmo_pstate_strategy *base_strategies_list,
const unsigned int num_base_strategies,
const unsigned int stream_count,
struct dml2_pmo_pstate_strategy *expanded_strategy_list,
unsigned int *num_expanded_strategies);
#endif

View File

@ -72,7 +72,6 @@ bool dml2_pmo_create(enum dml2_project_id project_id, struct dml2_pmo_instance *
out->init_for_stutter = pmo_dcn4_fams2_init_for_stutter;
out->test_for_stutter = pmo_dcn4_fams2_test_for_stutter;
out->optimize_for_stutter = pmo_dcn4_fams2_optimize_for_stutter;
result = true;
break;
case dml2_project_invalid:

View File

@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#include "dml_top.h"
#include "dml2_internal_shared_types.h"
#include "dml2_top_soc15.h"
unsigned int dml2_get_instance_size_bytes(void)
{
return sizeof(struct dml2_instance);
}
bool dml2_initialize_instance(struct dml2_initialize_instance_in_out *in_out)
{
switch (in_out->options.project_id) {
case dml2_project_dcn4x_stage1:
return false;
case dml2_project_dcn4x_stage2:
case dml2_project_dcn4x_stage2_auto_drr_svp:
return dml2_top_soc15_initialize_instance(in_out);
case dml2_project_invalid:
default:
return false;
}
}
bool dml2_check_mode_supported(struct dml2_check_mode_supported_in_out *in_out)
{
if (!in_out->dml2_instance->funcs.check_mode_supported)
return false;
return in_out->dml2_instance->funcs.check_mode_supported(in_out);
}
bool dml2_build_mode_programming(struct dml2_build_mode_programming_in_out *in_out)
{
if (!in_out->dml2_instance->funcs.build_mode_programming)
return false;
return in_out->dml2_instance->funcs.build_mode_programming(in_out);
}
bool dml2_build_mcache_programming(struct dml2_build_mcache_programming_in_out *in_out)
{
if (!in_out->dml2_instance->funcs.build_mcache_programming)
return false;
return in_out->dml2_instance->funcs.build_mcache_programming(in_out);
}

View File

@ -0,0 +1,4 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.

View File

@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#ifndef __DML2_TOP_LEGACY_H__
#define __DML2_TOP_LEGACY_H__
#include "dml2_internal_shared_types.h"
bool dml2_top_legacy_initialize_instance(struct dml2_initialize_instance_in_out *in_out);
#endif /* __DML2_TOP_LEGACY_H__ */

View File

@ -1,307 +0,0 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#include "dml2_top_optimization.h"
#include "dml2_internal_shared_types.h"
#include "dml_top_mcache.h"
static void copy_display_configuration_with_meta(struct display_configuation_with_meta *dst, const struct display_configuation_with_meta *src)
{
memcpy(dst, src, sizeof(struct display_configuation_with_meta));
}
bool dml2_top_optimization_init_function_min_clk_for_latency(const struct optimization_init_function_params *params)
{
struct dml2_optimization_stage1_state *state = &params->display_config->stage1;
state->performed = true;
return true;
}
bool dml2_top_optimization_test_function_min_clk_for_latency(const struct optimization_test_function_params *params)
{
struct dml2_optimization_stage1_state *state = &params->display_config->stage1;
return state->min_clk_index_for_latency == 0;
}
bool dml2_top_optimization_optimize_function_min_clk_for_latency(const struct optimization_optimize_function_params *params)
{
bool result = false;
if (params->display_config->stage1.min_clk_index_for_latency > 0) {
copy_display_configuration_with_meta(params->optimized_display_config, params->display_config);
params->optimized_display_config->stage1.min_clk_index_for_latency--;
result = true;
}
return result;
}
bool dml2_top_optimization_test_function_mcache(const struct optimization_test_function_params *params)
{
struct dml2_optimization_test_function_locals *l = params->locals;
bool mcache_success = false;
bool result = false;
memset(l, 0, sizeof(struct dml2_optimization_test_function_locals));
l->test_mcache.calc_mcache_count_params.dml2_instance = params->dml;
l->test_mcache.calc_mcache_count_params.display_config = &params->display_config->display_config;
l->test_mcache.calc_mcache_count_params.mcache_allocations = params->display_config->stage2.mcache_allocations;
result = dml2_top_mcache_calc_mcache_count_and_offsets(&l->test_mcache.calc_mcache_count_params); // use core to get the basic mcache_allocations
if (result) {
l->test_mcache.assign_global_mcache_ids_params.allocations = params->display_config->stage2.mcache_allocations;
l->test_mcache.assign_global_mcache_ids_params.num_allocations = params->display_config->display_config.num_planes;
dml2_top_mcache_assign_global_mcache_ids(&l->test_mcache.assign_global_mcache_ids_params);
l->test_mcache.validate_admissibility_params.dml2_instance = params->dml;
l->test_mcache.validate_admissibility_params.display_cfg = &params->display_config->display_config;
l->test_mcache.validate_admissibility_params.mcache_allocations = params->display_config->stage2.mcache_allocations;
l->test_mcache.validate_admissibility_params.cfg_support_info = &params->display_config->mode_support_result.cfg_support_info;
mcache_success = dml2_top_mcache_validate_admissability(&l->test_mcache.validate_admissibility_params); // also find the shift to make mcache allocation works
memcpy(params->display_config->stage2.per_plane_mcache_support, l->test_mcache.validate_admissibility_params.per_plane_status, sizeof(bool) * DML2_MAX_PLANES);
}
return mcache_success;
}
bool dml2_top_optimization_optimize_function_mcache(const struct optimization_optimize_function_params *params)
{
struct dml2_optimization_optimize_function_locals *l = params->locals;
bool optimize_success = false;
if (params->last_candidate_supported == false)
return false;
copy_display_configuration_with_meta(params->optimized_display_config, params->display_config);
l->optimize_mcache.optimize_mcache_params.instance = &params->dml->pmo_instance;
l->optimize_mcache.optimize_mcache_params.dcc_mcache_supported = params->display_config->stage2.per_plane_mcache_support;
l->optimize_mcache.optimize_mcache_params.display_config = &params->display_config->display_config;
l->optimize_mcache.optimize_mcache_params.optimized_display_cfg = &params->optimized_display_config->display_config;
l->optimize_mcache.optimize_mcache_params.cfg_support_info = &params->optimized_display_config->mode_support_result.cfg_support_info;
optimize_success = params->dml->pmo_instance.optimize_dcc_mcache(&l->optimize_mcache.optimize_mcache_params);
return optimize_success;
}
bool dml2_top_optimization_init_function_vmin(const struct optimization_init_function_params *params)
{
struct dml2_optimization_init_function_locals *l = params->locals;
l->vmin.init_params.instance = &params->dml->pmo_instance;
l->vmin.init_params.base_display_config = params->display_config;
return params->dml->pmo_instance.init_for_vmin(&l->vmin.init_params);
}
bool dml2_top_optimization_test_function_vmin(const struct optimization_test_function_params *params)
{
struct dml2_optimization_test_function_locals *l = params->locals;
l->test_vmin.pmo_test_vmin_params.instance = &params->dml->pmo_instance;
l->test_vmin.pmo_test_vmin_params.display_config = params->display_config;
l->test_vmin.pmo_test_vmin_params.vmin_limits = &params->dml->soc_bbox.vmin_limit;
return params->dml->pmo_instance.test_for_vmin(&l->test_vmin.pmo_test_vmin_params);
}
bool dml2_top_optimization_optimize_function_vmin(const struct optimization_optimize_function_params *params)
{
struct dml2_optimization_optimize_function_locals *l = params->locals;
if (params->last_candidate_supported == false)
return false;
l->optimize_vmin.pmo_optimize_vmin_params.instance = &params->dml->pmo_instance;
l->optimize_vmin.pmo_optimize_vmin_params.base_display_config = params->display_config;
l->optimize_vmin.pmo_optimize_vmin_params.optimized_display_config = params->optimized_display_config;
return params->dml->pmo_instance.optimize_for_vmin(&l->optimize_vmin.pmo_optimize_vmin_params);
}
bool dml2_top_optimization_perform_optimization_phase(struct dml2_optimization_phase_locals *l, const struct optimization_phase_params *params)
{
bool test_passed = false;
bool optimize_succeeded = true;
bool candidate_validation_passed = true;
struct optimization_init_function_params init_params = { 0 };
struct optimization_test_function_params test_params = { 0 };
struct optimization_optimize_function_params optimize_params = { 0 };
if (!params->dml ||
!params->optimize_function ||
!params->test_function ||
!params->display_config ||
!params->optimized_display_config)
return false;
copy_display_configuration_with_meta(&l->cur_candidate_display_cfg, params->display_config);
init_params.locals = &l->init_function_locals;
init_params.dml = params->dml;
init_params.display_config = &l->cur_candidate_display_cfg;
if (params->init_function && !params->init_function(&init_params))
return false;
test_params.locals = &l->test_function_locals;
test_params.dml = params->dml;
test_params.display_config = &l->cur_candidate_display_cfg;
test_passed = params->test_function(&test_params);
while (!test_passed && optimize_succeeded) {
memset(&optimize_params, 0, sizeof(struct optimization_optimize_function_params));
optimize_params.locals = &l->optimize_function_locals;
optimize_params.dml = params->dml;
optimize_params.display_config = &l->cur_candidate_display_cfg;
optimize_params.optimized_display_config = &l->next_candidate_display_cfg;
optimize_params.last_candidate_supported = candidate_validation_passed;
optimize_succeeded = params->optimize_function(&optimize_params);
if (optimize_succeeded) {
l->mode_support_params.instance = &params->dml->core_instance;
l->mode_support_params.display_cfg = &l->next_candidate_display_cfg;
l->mode_support_params.min_clk_table = &params->dml->min_clk_table;
if (l->next_candidate_display_cfg.stage3.performed)
l->mode_support_params.min_clk_index = l->next_candidate_display_cfg.stage3.min_clk_index_for_latency;
else
l->mode_support_params.min_clk_index = l->next_candidate_display_cfg.stage1.min_clk_index_for_latency;
candidate_validation_passed = params->dml->core_instance.mode_support(&l->mode_support_params);
l->next_candidate_display_cfg.mode_support_result = l->mode_support_params.mode_support_result;
}
if (optimize_succeeded && candidate_validation_passed) {
memset(&test_params, 0, sizeof(struct optimization_test_function_params));
test_params.locals = &l->test_function_locals;
test_params.dml = params->dml;
test_params.display_config = &l->next_candidate_display_cfg;
test_passed = params->test_function(&test_params);
copy_display_configuration_with_meta(&l->cur_candidate_display_cfg, &l->next_candidate_display_cfg);
// If optimization is not all or nothing, then store partial progress in output
if (!params->all_or_nothing)
copy_display_configuration_with_meta(params->optimized_display_config, &l->next_candidate_display_cfg);
}
}
if (test_passed)
copy_display_configuration_with_meta(params->optimized_display_config, &l->cur_candidate_display_cfg);
return test_passed;
}
bool dml2_top_optimization_perform_optimization_phase_1(struct dml2_optimization_phase_locals *l, const struct optimization_phase_params *params)
{
int highest_state, lowest_state, cur_state;
bool supported = false;
if (!params->dml ||
!params->optimize_function ||
!params->test_function ||
!params->display_config ||
!params->optimized_display_config)
return false;
copy_display_configuration_with_meta(&l->cur_candidate_display_cfg, params->display_config);
highest_state = l->cur_candidate_display_cfg.stage1.min_clk_index_for_latency;
lowest_state = 0;
while (highest_state > lowest_state) {
cur_state = (highest_state + lowest_state) / 2;
l->mode_support_params.instance = &params->dml->core_instance;
l->mode_support_params.display_cfg = &l->cur_candidate_display_cfg;
l->mode_support_params.min_clk_table = &params->dml->min_clk_table;
l->mode_support_params.min_clk_index = cur_state;
supported = params->dml->core_instance.mode_support(&l->mode_support_params);
if (supported) {
l->cur_candidate_display_cfg.mode_support_result = l->mode_support_params.mode_support_result;
highest_state = cur_state;
} else {
lowest_state = cur_state + 1;
}
}
l->cur_candidate_display_cfg.stage1.min_clk_index_for_latency = lowest_state;
copy_display_configuration_with_meta(params->optimized_display_config, &l->cur_candidate_display_cfg);
return true;
}
bool dml2_top_optimization_init_function_uclk_pstate(const struct optimization_init_function_params *params)
{
struct dml2_optimization_init_function_locals *l = params->locals;
l->uclk_pstate.init_params.instance = &params->dml->pmo_instance;
l->uclk_pstate.init_params.base_display_config = params->display_config;
return params->dml->pmo_instance.init_for_uclk_pstate(&l->uclk_pstate.init_params);
}
bool dml2_top_optimization_test_function_uclk_pstate(const struct optimization_test_function_params *params)
{
struct dml2_optimization_test_function_locals *l = params->locals;
l->uclk_pstate.test_params.instance = &params->dml->pmo_instance;
l->uclk_pstate.test_params.base_display_config = params->display_config;
return params->dml->pmo_instance.test_for_uclk_pstate(&l->uclk_pstate.test_params);
}
bool dml2_top_optimization_optimize_function_uclk_pstate(const struct optimization_optimize_function_params *params)
{
struct dml2_optimization_optimize_function_locals *l = params->locals;
l->uclk_pstate.optimize_params.instance = &params->dml->pmo_instance;
l->uclk_pstate.optimize_params.base_display_config = params->display_config;
l->uclk_pstate.optimize_params.optimized_display_config = params->optimized_display_config;
l->uclk_pstate.optimize_params.last_candidate_failed = !params->last_candidate_supported;
return params->dml->pmo_instance.optimize_for_uclk_pstate(&l->uclk_pstate.optimize_params);
}
bool dml2_top_optimization_init_function_stutter(const struct optimization_init_function_params *params)
{
struct dml2_optimization_init_function_locals *l = params->locals;
l->uclk_pstate.init_params.instance = &params->dml->pmo_instance;
l->uclk_pstate.init_params.base_display_config = params->display_config;
return params->dml->pmo_instance.init_for_stutter(&l->stutter.stutter_params);
}
bool dml2_top_optimization_test_function_stutter(const struct optimization_test_function_params *params)
{
struct dml2_optimization_test_function_locals *l = params->locals;
l->stutter.stutter_params.instance = &params->dml->pmo_instance;
l->stutter.stutter_params.base_display_config = params->display_config;
return params->dml->pmo_instance.test_for_stutter(&l->stutter.stutter_params);
}
bool dml2_top_optimization_optimize_function_stutter(const struct optimization_optimize_function_params *params)
{
struct dml2_optimization_optimize_function_locals *l = params->locals;
l->stutter.stutter_params.instance = &params->dml->pmo_instance;
l->stutter.stutter_params.base_display_config = params->display_config;
l->stutter.stutter_params.optimized_display_config = params->optimized_display_config;
l->stutter.stutter_params.last_candidate_failed = !params->last_candidate_supported;
return params->dml->pmo_instance.optimize_for_stutter(&l->stutter.stutter_params);
}

View File

@ -1,33 +0,0 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#ifndef __DML2_TOP_OPTIMIZATION_H__
#define __DML2_TOP_OPTIMIZATION_H__
#include "dml2_external_lib_deps.h"
#include "dml2_internal_shared_types.h"
bool dml2_top_optimization_perform_optimization_phase(struct dml2_optimization_phase_locals *l, const struct optimization_phase_params *params);
bool dml2_top_optimization_perform_optimization_phase_1(struct dml2_optimization_phase_locals *l, const struct optimization_phase_params *params);
bool dml2_top_optimization_init_function_min_clk_for_latency(const struct optimization_init_function_params *params);
bool dml2_top_optimization_test_function_min_clk_for_latency(const struct optimization_test_function_params *params);
bool dml2_top_optimization_optimize_function_min_clk_for_latency(const struct optimization_optimize_function_params *params);
bool dml2_top_optimization_test_function_mcache(const struct optimization_test_function_params *params);
bool dml2_top_optimization_optimize_function_mcache(const struct optimization_optimize_function_params *params);
bool dml2_top_optimization_init_function_uclk_pstate(const struct optimization_init_function_params *params);
bool dml2_top_optimization_test_function_uclk_pstate(const struct optimization_test_function_params *params);
bool dml2_top_optimization_optimize_function_uclk_pstate(const struct optimization_optimize_function_params *params);
bool dml2_top_optimization_init_function_vmin(const struct optimization_init_function_params *params);
bool dml2_top_optimization_test_function_vmin(const struct optimization_test_function_params *params);
bool dml2_top_optimization_optimize_function_vmin(const struct optimization_optimize_function_params *params);
bool dml2_top_optimization_init_function_stutter(const struct optimization_init_function_params *params);
bool dml2_top_optimization_test_function_stutter(const struct optimization_test_function_params *params);
bool dml2_top_optimization_optimize_function_stutter(const struct optimization_optimize_function_params *params);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,13 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#ifndef __DML_TOP_MCACHE_H__
#define __DML_TOP_MCACHE_H__
#include "dml2_external_lib_deps.h"
#include "dml_top_display_cfg_types.h"
#include "dml_top_types.h"
#ifndef __DML2_TOP_SOC15_H__
#define __DML2_TOP_SOC15_H__
#include "dml2_internal_shared_types.h"
bool dml2_top_soc15_initialize_instance(struct dml2_initialize_instance_in_out *in_out);
bool dml2_top_mcache_calc_mcache_count_and_offsets(struct top_mcache_calc_mcache_count_and_offsets_in_out *params);
void dml2_top_mcache_assign_global_mcache_ids(struct top_mcache_assign_global_mcache_ids_in_out *params);
bool dml2_top_mcache_validate_admissability(struct top_mcache_validate_admissability_in_out *params);
bool dml2_top_mcache_build_mcache_programming(struct dml2_build_mcache_programming_in_out *params);
bool dml2_top_mcache_unit_test(void);
#endif
bool dml2_top_soc15_build_mcache_programming(struct dml2_build_mcache_programming_in_out *params);
#endif /* __DML2_TOP_SOC15_H__ */

View File

@ -1,549 +0,0 @@
// SPDX-License-Identifier: MIT
//
// Copyright 2024 Advanced Micro Devices, Inc.
#include "dml2_debug.h"
#include "dml_top_mcache.h"
#include "lib_float_math.h"
#include "dml2_internal_shared_types.h"
/*
* Takes an input set of mcache boundaries and finds the appropriate setting of cache programming.
* Returns true if a valid set of programming can be made, and false otherwise. "Valid" means
* that the horizontal viewport does not span more than 2 cache slices.
*
* It optionally also can apply a constant shift to all the cache boundaries.
*/
static const uint32_t MCACHE_ID_UNASSIGNED = 0xF;
static const uint32_t SPLIT_LOCATION_UNDEFINED = 0xFFFF;
static bool calculate_first_second_splitting(const int *mcache_boundaries, int num_boundaries, int shift,
int pipe_h_vp_start, int pipe_h_vp_end, int *first_offset, int *second_offset)
{
const int MAX_VP = 0xFFFFFF;
int left_cache_id;
int right_cache_id;
int range_start;
int range_end;
bool success = false;
if (num_boundaries <= 1) {
if (first_offset && second_offset) {
*first_offset = 0;
*second_offset = -1;
}
success = true;
return success;
} else {
range_start = 0;
for (left_cache_id = 0; left_cache_id < num_boundaries; left_cache_id++) {
range_end = mcache_boundaries[left_cache_id] - shift - 1;
if (range_start <= pipe_h_vp_start && pipe_h_vp_start <= range_end)
break;
range_start = range_end + 1;
}
range_end = MAX_VP;
for (right_cache_id = num_boundaries - 1; right_cache_id >= -1; right_cache_id--) {
if (right_cache_id >= 0)
range_start = mcache_boundaries[right_cache_id] - shift;
else
range_start = 0;
if (range_start <= pipe_h_vp_end && pipe_h_vp_end <= range_end) {
break;
}
range_end = range_start - 1;
}
right_cache_id = (right_cache_id + 1) % num_boundaries;
if (right_cache_id == left_cache_id) {
if (first_offset && second_offset) {
*first_offset = left_cache_id;
*second_offset = -1;
}
success = true;
} else if (right_cache_id == (left_cache_id + 1) % num_boundaries) {
if (first_offset && second_offset) {
*first_offset = left_cache_id;
*second_offset = right_cache_id;
}
success = true;
}
}
return success;
}
/*
* For a given set of pipe start/end x positions, checks to see it can support the input mcache splitting.
* It also attempts to "optimize" by finding a shift if the default 0 shift does not work.
*/
static bool find_shift_for_valid_cache_id_assignment(int *mcache_boundaries, unsigned int num_boundaries,
int *pipe_vp_startx, int *pipe_vp_endx, unsigned int pipe_count, int shift_granularity, int *shift)
{
int max_shift = 0xFFFF;
unsigned int pipe_index;
unsigned int i, slice_width;
bool success = false;
for (i = 0; i < num_boundaries; i++) {
if (i == 0)
slice_width = mcache_boundaries[i];
else
slice_width = mcache_boundaries[i] - mcache_boundaries[i - 1];
if (max_shift > (int)slice_width) {
max_shift = slice_width;
}
}
for (*shift = 0; *shift <= max_shift; *shift += shift_granularity) {
success = true;
for (pipe_index = 0; pipe_index < pipe_count; pipe_index++) {
if (!calculate_first_second_splitting(mcache_boundaries, num_boundaries, *shift,
pipe_vp_startx[pipe_index], pipe_vp_endx[pipe_index], 0, 0)) {
success = false;
break;
}
}
if (success)
break;
}
return success;
}
/*
* Counts the number of elements inside input array within the given span length.
* Formally, what is the size of the largest subset of the array where the largest and smallest element
* differ no more than the span.
*/
static unsigned int count_elements_in_span(int *array, unsigned int array_size, unsigned int span)
{
unsigned int i;
unsigned int span_start_value;
unsigned int span_start_index;
unsigned int greatest_element_count;
if (array_size == 0)
return 1;
if (span == 0)
return array_size > 0 ? 1 : 0;
span_start_value = 0;
span_start_index = 0;
greatest_element_count = 0;
while (span_start_index < array_size) {
for (i = span_start_index; i < array_size; i++) {
if (array[i] - span_start_value <= span) {
if (i - span_start_index + 1 > greatest_element_count) {
greatest_element_count = i - span_start_index + 1;
}
} else
break;
}
span_start_index++;
if (span_start_index < array_size) {
span_start_value = array[span_start_index - 1] + 1;
}
}
return greatest_element_count;
}
static bool calculate_h_split_for_scaling_transform(int full_vp_width, int h_active, int num_pipes,
enum dml2_scaling_transform scaling_transform, int *pipe_vp_x_start, int *pipe_vp_x_end)
{
int i, slice_width;
const char MAX_SCL_VP_OVERLAP = 3;
bool success = false;
switch (scaling_transform) {
case dml2_scaling_transform_centered:
case dml2_scaling_transform_aspect_ratio:
case dml2_scaling_transform_fullscreen:
slice_width = full_vp_width / num_pipes;
for (i = 0; i < num_pipes; i++) {
pipe_vp_x_start[i] = i * slice_width;
pipe_vp_x_end[i] = (i + 1) * slice_width - 1;
if (pipe_vp_x_start[i] < MAX_SCL_VP_OVERLAP)
pipe_vp_x_start[i] = 0;
else
pipe_vp_x_start[i] -= MAX_SCL_VP_OVERLAP;
if (pipe_vp_x_end[i] > full_vp_width - MAX_SCL_VP_OVERLAP - 1)
pipe_vp_x_end[i] = full_vp_width - 1;
else
pipe_vp_x_end[i] += MAX_SCL_VP_OVERLAP;
}
break;
case dml2_scaling_transform_explicit:
default:
success = false;
break;
}
return success;
}
bool dml2_top_mcache_validate_admissability(struct top_mcache_validate_admissability_in_out *params)
{
struct dml2_instance *dml = (struct dml2_instance *)params->dml2_instance;
struct dml2_top_mcache_validate_admissability_locals *l = &dml->scratch.mcache_validate_admissability_locals;
const int MAX_PIXEL_OVERLAP = 6;
int max_per_pipe_vp_p0 = 0;
int max_per_pipe_vp_p1 = 0;
int temp, p0shift, p1shift;
unsigned int plane_index = 0;
unsigned int i;
unsigned int odm_combine_factor;
unsigned int mpc_combine_factor;
unsigned int num_dpps;
unsigned int num_boundaries;
enum dml2_scaling_transform scaling_transform;
const struct dml2_plane_parameters *plane;
const struct dml2_stream_parameters *stream;
bool p0pass = false;
bool p1pass = false;
bool all_pass = true;
for (plane_index = 0; plane_index < params->display_cfg->num_planes; plane_index++) {
if (!params->display_cfg->plane_descriptors[plane_index].surface.dcc.enable)
continue;
plane = &params->display_cfg->plane_descriptors[plane_index];
stream = &params->display_cfg->stream_descriptors[plane->stream_index];
num_dpps = odm_combine_factor = params->cfg_support_info->stream_support_info[plane->stream_index].odms_used;
if (odm_combine_factor == 1)
num_dpps = mpc_combine_factor = (unsigned int)params->cfg_support_info->plane_support_info[plane_index].dpps_used;
else
mpc_combine_factor = 1;
if (odm_combine_factor > 1) {
max_per_pipe_vp_p0 = plane->surface.plane0.width;
temp = (unsigned int)math_ceil(plane->composition.scaler_info.plane0.h_ratio * stream->timing.h_active / odm_combine_factor);
if (temp < max_per_pipe_vp_p0)
max_per_pipe_vp_p0 = temp;
max_per_pipe_vp_p1 = plane->surface.plane1.width;
temp = (unsigned int)math_ceil(plane->composition.scaler_info.plane1.h_ratio * stream->timing.h_active / odm_combine_factor);
if (temp < max_per_pipe_vp_p1)
max_per_pipe_vp_p1 = temp;
} else {
max_per_pipe_vp_p0 = plane->surface.plane0.width / mpc_combine_factor;
max_per_pipe_vp_p1 = plane->surface.plane1.width / mpc_combine_factor;
}
max_per_pipe_vp_p0 += 2 * MAX_PIXEL_OVERLAP;
max_per_pipe_vp_p1 += MAX_PIXEL_OVERLAP;
p0shift = 0;
p1shift = 0;
// The last element in the unshifted boundary array will always be the first pixel outside the
// plane, which means theres no mcache associated with it, so -1
num_boundaries = params->mcache_allocations[plane_index].num_mcaches_plane0 == 0 ? 0 : params->mcache_allocations[plane_index].num_mcaches_plane0 - 1;
if ((count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane0,
num_boundaries, max_per_pipe_vp_p0) <= 1) && (num_boundaries <= num_dpps)) {
p0pass = true;
}
num_boundaries = params->mcache_allocations[plane_index].num_mcaches_plane1 == 0 ? 0 : params->mcache_allocations[plane_index].num_mcaches_plane1 - 1;
if ((count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane1,
num_boundaries, max_per_pipe_vp_p1) <= 1) && (num_boundaries <= num_dpps)) {
p1pass = true;
}
if (!p0pass || !p1pass) {
if (odm_combine_factor > 1) {
num_dpps = odm_combine_factor;
scaling_transform = plane->composition.scaling_transform;
} else {
num_dpps = mpc_combine_factor;
scaling_transform = dml2_scaling_transform_fullscreen;
}
if (!p0pass) {
if (plane->composition.viewport.stationary) {
calculate_h_split_for_scaling_transform(plane->surface.plane0.width,
stream->timing.h_active, num_dpps, scaling_transform,
&l->plane0.pipe_vp_startx[plane_index], &l->plane0.pipe_vp_endx[plane_index]);
p0pass = find_shift_for_valid_cache_id_assignment(params->mcache_allocations[plane_index].mcache_x_offsets_plane0,
params->mcache_allocations[plane_index].num_mcaches_plane0,
&l->plane0.pipe_vp_startx[plane_index], &l->plane0.pipe_vp_endx[plane_index], num_dpps,
params->mcache_allocations[plane_index].shift_granularity.p0, &p0shift);
}
}
if (!p1pass) {
if (plane->composition.viewport.stationary) {
calculate_h_split_for_scaling_transform(plane->surface.plane1.width,
stream->timing.h_active, num_dpps, scaling_transform,
&l->plane0.pipe_vp_startx[plane_index], &l->plane0.pipe_vp_endx[plane_index]);
p1pass = find_shift_for_valid_cache_id_assignment(params->mcache_allocations[plane_index].mcache_x_offsets_plane1,
params->mcache_allocations[plane_index].num_mcaches_plane1,
&l->plane1.pipe_vp_startx[plane_index], &l->plane1.pipe_vp_endx[plane_index], num_dpps,
params->mcache_allocations[plane_index].shift_granularity.p1, &p1shift);
}
}
}
if (p0pass && p1pass) {
for (i = 0; i < params->mcache_allocations[plane_index].num_mcaches_plane0; i++) {
params->mcache_allocations[plane_index].mcache_x_offsets_plane0[i] -= p0shift;
}
for (i = 0; i < params->mcache_allocations[plane_index].num_mcaches_plane1; i++) {
params->mcache_allocations[plane_index].mcache_x_offsets_plane1[i] -= p1shift;
}
}
params->per_plane_status[plane_index] = p0pass && p1pass;
all_pass &= p0pass && p1pass;
}
return all_pass;
}
static void reset_mcache_allocations(struct dml2_hubp_pipe_mcache_regs *per_plane_pipe_mcache_regs)
{
// Initialize all entries to special valid MCache ID and special valid split coordinate
per_plane_pipe_mcache_regs->main.p0.mcache_id_first = MCACHE_ID_UNASSIGNED;
per_plane_pipe_mcache_regs->main.p0.mcache_id_second = MCACHE_ID_UNASSIGNED;
per_plane_pipe_mcache_regs->main.p0.split_location = SPLIT_LOCATION_UNDEFINED;
per_plane_pipe_mcache_regs->mall.p0.mcache_id_first = MCACHE_ID_UNASSIGNED;
per_plane_pipe_mcache_regs->mall.p0.mcache_id_second = MCACHE_ID_UNASSIGNED;
per_plane_pipe_mcache_regs->mall.p0.split_location = SPLIT_LOCATION_UNDEFINED;
per_plane_pipe_mcache_regs->main.p1.mcache_id_first = MCACHE_ID_UNASSIGNED;
per_plane_pipe_mcache_regs->main.p1.mcache_id_second = MCACHE_ID_UNASSIGNED;
per_plane_pipe_mcache_regs->main.p1.split_location = SPLIT_LOCATION_UNDEFINED;
per_plane_pipe_mcache_regs->mall.p1.mcache_id_first = MCACHE_ID_UNASSIGNED;
per_plane_pipe_mcache_regs->mall.p1.mcache_id_second = MCACHE_ID_UNASSIGNED;
per_plane_pipe_mcache_regs->mall.p1.split_location = SPLIT_LOCATION_UNDEFINED;
}
bool dml2_top_mcache_build_mcache_programming(struct dml2_build_mcache_programming_in_out *params)
{
bool success = true;
int config_index, pipe_index;
int first_offset, second_offset;
int free_per_plane_reg_index = 0;
memset(params->per_plane_pipe_mcache_regs, 0, DML2_MAX_PLANES * DML2_MAX_DCN_PIPES * sizeof(struct dml2_hubp_pipe_mcache_regs *));
for (config_index = 0; config_index < params->num_configurations; config_index++) {
for (pipe_index = 0; pipe_index < params->mcache_configurations[config_index].num_pipes; pipe_index++) {
// Allocate storage for the mcache regs
params->per_plane_pipe_mcache_regs[config_index][pipe_index] = &params->mcache_regs_set[free_per_plane_reg_index++];
reset_mcache_allocations(params->per_plane_pipe_mcache_regs[config_index][pipe_index]);
if (params->mcache_configurations[config_index].plane_descriptor->surface.dcc.enable) {
// P0 always enabled
if (!calculate_first_second_splitting(params->mcache_configurations[config_index].mcache_allocation->mcache_x_offsets_plane0,
params->mcache_configurations[config_index].mcache_allocation->num_mcaches_plane0,
0,
params->mcache_configurations[config_index].pipe_configurations[pipe_index].plane0.viewport_x_start,
params->mcache_configurations[config_index].pipe_configurations[pipe_index].plane0.viewport_x_start +
params->mcache_configurations[config_index].pipe_configurations[pipe_index].plane0.viewport_width - 1,
&first_offset, &second_offset)) {
success = false;
break;
}
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->main.p0.mcache_id_first =
params->mcache_configurations[config_index].mcache_allocation->global_mcache_ids_plane0[first_offset];
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->mall.p0.mcache_id_first =
params->mcache_configurations[config_index].mcache_allocation->global_mcache_ids_mall_plane0[first_offset];
if (second_offset >= 0) {
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->main.p0.mcache_id_second =
params->mcache_configurations[config_index].mcache_allocation->global_mcache_ids_plane0[second_offset];
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->main.p0.split_location =
params->mcache_configurations[config_index].mcache_allocation->mcache_x_offsets_plane0[first_offset] - 1;
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->mall.p0.mcache_id_second =
params->mcache_configurations[config_index].mcache_allocation->global_mcache_ids_mall_plane0[second_offset];
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->mall.p0.split_location =
params->mcache_configurations[config_index].mcache_allocation->mcache_x_offsets_plane0[first_offset] - 1;
}
// Populate P1 if enabled
if (params->mcache_configurations[config_index].pipe_configurations[pipe_index].plane1_enabled) {
if (!calculate_first_second_splitting(params->mcache_configurations[config_index].mcache_allocation->mcache_x_offsets_plane1,
params->mcache_configurations[config_index].mcache_allocation->num_mcaches_plane1,
0,
params->mcache_configurations[config_index].pipe_configurations[pipe_index].plane1.viewport_x_start,
params->mcache_configurations[config_index].pipe_configurations[pipe_index].plane1.viewport_x_start +
params->mcache_configurations[config_index].pipe_configurations[pipe_index].plane1.viewport_width - 1,
&first_offset, &second_offset)) {
success = false;
break;
}
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->main.p1.mcache_id_first =
params->mcache_configurations[config_index].mcache_allocation->global_mcache_ids_plane1[first_offset];
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->mall.p1.mcache_id_first =
params->mcache_configurations[config_index].mcache_allocation->global_mcache_ids_mall_plane1[first_offset];
if (second_offset >= 0) {
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->main.p1.mcache_id_second =
params->mcache_configurations[config_index].mcache_allocation->global_mcache_ids_plane1[second_offset];
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->main.p1.split_location =
params->mcache_configurations[config_index].mcache_allocation->mcache_x_offsets_plane1[first_offset] - 1;
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->mall.p1.mcache_id_second =
params->mcache_configurations[config_index].mcache_allocation->global_mcache_ids_mall_plane1[second_offset];
params->per_plane_pipe_mcache_regs[config_index][pipe_index]->mall.p1.split_location =
params->mcache_configurations[config_index].mcache_allocation->mcache_x_offsets_plane1[first_offset] - 1;
}
}
}
}
}
return success;
}
void dml2_top_mcache_assign_global_mcache_ids(struct top_mcache_assign_global_mcache_ids_in_out *params)
{
int i;
unsigned int j;
int next_unused_cache_id = 0;
for (i = 0; i < params->num_allocations; i++) {
if (!params->allocations[i].valid)
continue;
for (j = 0; j < params->allocations[i].num_mcaches_plane0; j++) {
params->allocations[i].global_mcache_ids_plane0[j] = next_unused_cache_id++;
}
for (j = 0; j < params->allocations[i].num_mcaches_plane1; j++) {
params->allocations[i].global_mcache_ids_plane1[j] = next_unused_cache_id++;
}
// The "psuedo-last" slice is always wrapped around
params->allocations[i].global_mcache_ids_plane0[params->allocations[i].num_mcaches_plane0] =
params->allocations[i].global_mcache_ids_plane0[0];
params->allocations[i].global_mcache_ids_plane1[params->allocations[i].num_mcaches_plane1] =
params->allocations[i].global_mcache_ids_plane1[0];
// If we need dedicated caches for mall requesting, then we assign them here.
if (params->allocations[i].requires_dedicated_mall_mcache) {
for (j = 0; j < params->allocations[i].num_mcaches_plane0; j++) {
params->allocations[i].global_mcache_ids_mall_plane0[j] = next_unused_cache_id++;
}
for (j = 0; j < params->allocations[i].num_mcaches_plane1; j++) {
params->allocations[i].global_mcache_ids_mall_plane1[j] = next_unused_cache_id++;
}
// The "psuedo-last" slice is always wrapped around
params->allocations[i].global_mcache_ids_mall_plane0[params->allocations[i].num_mcaches_plane0] =
params->allocations[i].global_mcache_ids_mall_plane0[0];
params->allocations[i].global_mcache_ids_mall_plane1[params->allocations[i].num_mcaches_plane1] =
params->allocations[i].global_mcache_ids_mall_plane1[0];
}
// If P0 and P1 are sharing caches, then it means the largest mcache IDs for p0 and p1 can be the same
// since mcache IDs are always ascending, then it means the largest mcacheID of p1 should be the
// largest mcacheID of P0
if (params->allocations[i].num_mcaches_plane0 > 0 && params->allocations[i].num_mcaches_plane1 > 0 &&
params->allocations[i].last_slice_sharing.plane0_plane1) {
params->allocations[i].global_mcache_ids_plane1[params->allocations[i].num_mcaches_plane1 - 1] =
params->allocations[i].global_mcache_ids_plane0[params->allocations[i].num_mcaches_plane0 - 1];
}
// If we need dedicated caches handle last slice sharing
if (params->allocations[i].requires_dedicated_mall_mcache) {
if (params->allocations[i].num_mcaches_plane0 > 0 && params->allocations[i].num_mcaches_plane1 > 0 &&
params->allocations[i].last_slice_sharing.plane0_plane1) {
params->allocations[i].global_mcache_ids_mall_plane1[params->allocations[i].num_mcaches_plane1 - 1] =
params->allocations[i].global_mcache_ids_mall_plane0[params->allocations[i].num_mcaches_plane0 - 1];
}
// If mall_comb_mcache_l is set then it means that largest mcache ID for MALL p0 can be same as regular read p0
if (params->allocations[i].num_mcaches_plane0 > 0 && params->allocations[i].last_slice_sharing.mall_comb_mcache_p0) {
params->allocations[i].global_mcache_ids_mall_plane0[params->allocations[i].num_mcaches_plane0 - 1] =
params->allocations[i].global_mcache_ids_plane0[params->allocations[i].num_mcaches_plane0 - 1];
}
// If mall_comb_mcache_c is set then it means that largest mcache ID for MALL p1 can be same as regular
// read p1 (which can be same as regular read p0 if plane0_plane1 is also set)
if (params->allocations[i].num_mcaches_plane1 > 0 && params->allocations[i].last_slice_sharing.mall_comb_mcache_p1) {
params->allocations[i].global_mcache_ids_mall_plane1[params->allocations[i].num_mcaches_plane1 - 1] =
params->allocations[i].global_mcache_ids_plane1[params->allocations[i].num_mcaches_plane1 - 1];
}
}
// If you don't need dedicated mall mcaches, the mall mcache assignments are identical to the normal requesting
if (!params->allocations[i].requires_dedicated_mall_mcache) {
memcpy(params->allocations[i].global_mcache_ids_mall_plane0, params->allocations[i].global_mcache_ids_plane0,
sizeof(params->allocations[i].global_mcache_ids_mall_plane0));
memcpy(params->allocations[i].global_mcache_ids_mall_plane1, params->allocations[i].global_mcache_ids_plane1,
sizeof(params->allocations[i].global_mcache_ids_mall_plane1));
}
}
}
bool dml2_top_mcache_calc_mcache_count_and_offsets(struct top_mcache_calc_mcache_count_and_offsets_in_out *params)
{
struct dml2_instance *dml = (struct dml2_instance *)params->dml2_instance;
struct dml2_top_mcache_verify_mcache_size_locals *l = &dml->scratch.mcache_verify_mcache_size_locals;
unsigned int total_mcaches_required;
unsigned int i;
bool result = false;
if (dml->soc_bbox.num_dcc_mcaches == 0) {
return true;
}
total_mcaches_required = 0;
l->calc_mcache_params.instance = &dml->core_instance;
for (i = 0; i < params->display_config->num_planes; i++) {
if (!params->display_config->plane_descriptors[i].surface.dcc.enable) {
memset(&params->mcache_allocations[i], 0, sizeof(struct dml2_mcache_surface_allocation));
continue;
}
l->calc_mcache_params.plane_descriptor = &params->display_config->plane_descriptors[i];
l->calc_mcache_params.mcache_allocation = &params->mcache_allocations[i];
l->calc_mcache_params.plane_index = i;
if (!dml->core_instance.calculate_mcache_allocation(&l->calc_mcache_params)) {
result = false;
break;
}
if (params->mcache_allocations[i].valid) {
total_mcaches_required += params->mcache_allocations[i].num_mcaches_plane0 + params->mcache_allocations[i].num_mcaches_plane1;
if (params->mcache_allocations[i].last_slice_sharing.plane0_plane1)
total_mcaches_required--;
}
}
dml2_printf("DML_CORE_DCN3::%s: plane_%d, total_mcaches_required=%d\n", __func__, i, total_mcaches_required);
if (total_mcaches_required > dml->soc_bbox.num_dcc_mcaches) {
result = false;
} else {
result = true;
}
return result;
}

View File

@ -4,6 +4,11 @@
#include "dml2_debug.h"
int dml2_log_internal(const char *format, ...)
{
return 0;
}
int dml2_printf(const char *format, ...)
{
#ifdef _DEBUG

View File

@ -8,9 +8,53 @@
#ifdef _DEBUG
#define DML2_ASSERT(condition) dml2_assert(condition)
#else
#define DML2_ASSERT(condition)
#define DML2_ASSERT(condition) ((void)0)
#endif
/*
* DML_LOG_FATAL - fatal errors for unrecoverable DML states until a restart.
* DML_LOG_ERROR - unexpected but recoverable failures inside DML
* DML_LOG_WARN - unexpected inputs or events to DML
* DML_LOG_INFO - high level tracing of DML interfaces
* DML_LOG_DEBUG - detailed tracing of DML internal components
* DML_LOG_VERBOSE - detailed tracing of DML calculation procedure
*/
#if !defined(DML_LOG_LEVEL)
#if defined(_DEBUG) && defined(_DEBUG_PRINTS)
/* for backward compatibility with old macros */
#define DML_LOG_LEVEL 5
#else
#define DML_LOG_LEVEL 0
#endif
#endif
#define DML_LOG_FATAL(fmt, ...) dml2_log_internal(fmt, ## __VA_ARGS__)
#if DML_LOG_LEVEL >= 1
#define DML_LOG_ERROR(fmt, ...) dml2_log_internal(fmt, ## __VA_ARGS__)
#else
#define DML_LOG_ERROR(fmt, ...) ((void)0)
#endif
#if DML_LOG_LEVEL >= 2
#define DML_LOG_WARN(fmt, ...) dml2_log_internal(fmt, ## __VA_ARGS__)
#else
#define DML_LOG_WARN(fmt, ...) ((void)0)
#endif
#if DML_LOG_LEVEL >= 3
#define DML_LOG_INFO(fmt, ...) dml2_log_internal(fmt, ## __VA_ARGS__)
#else
#define DML_LOG_INFO(fmt, ...) ((void)0)
#endif
#if DML_LOG_LEVEL >= 4
#define DML_LOG_DEBUG(fmt, ...) dml2_log_internal(fmt, ## __VA_ARGS__)
#else
#define DML_LOG_DEBUG(fmt, ...) ((void)0)
#endif
#if DML_LOG_LEVEL >= 5
#define DML_LOG_VERBOSE(fmt, ...) dml2_log_internal(fmt, ## __VA_ARGS__)
#else
#define DML_LOG_VERBOSE(fmt, ...) ((void)0)
#endif
int dml2_log_internal(const char *format, ...);
int dml2_printf(const char *format, ...);
void dml2_assert(int condition);

View File

@ -8,7 +8,6 @@
#include "dml2_external_lib_deps.h"
#include "dml_top_types.h"
#include "dml2_core_shared_types.h"
/*
* DML2 MCG Types and Interfaces
*/
@ -63,7 +62,6 @@ struct dml2_mcg_build_min_clock_table_params_in_out {
*/
struct dml2_mcg_min_clock_table *min_clk_table;
};
struct dml2_mcg_instance {
bool (*build_min_clock_table)(struct dml2_mcg_build_min_clock_table_params_in_out *in_out);
bool (*unit_test)(void);
@ -81,7 +79,6 @@ struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out {
struct dml2_soc_bb *soc_bb;
struct dml2_mcg_min_clock_table *min_clk_table;
const struct display_configuation_with_meta *display_cfg;
struct {
bool perform_pseudo_map;
struct dml2_core_internal_soc_bb *soc_bb;
@ -309,7 +306,7 @@ struct dml2_optimization_stage3_state {
// The pstate support mode for each plane
// The number of valid elements == display_cfg.num_planes
// The indexing of pstate_switch_modes matches plane_descriptors[]
enum dml2_uclk_pstate_support_method pstate_switch_modes[DML2_MAX_PLANES];
enum dml2_pstate_method pstate_switch_modes[DML2_MAX_PLANES];
// Meta-data for implicit SVP generation, indexed by stream index
struct dml2_implicit_svp_meta stream_svp_meta[DML2_MAX_PLANES];
@ -356,6 +353,12 @@ struct display_configuation_with_meta {
struct dml2_optimization_stage5_state stage5;
};
struct dml2_pmo_pstate_strategy {
enum dml2_pstate_method per_stream_pstate_method[DML2_MAX_PLANES];
bool allow_state_increase;
};
struct dml2_core_mode_support_in_out {
/*
* Inputs
@ -365,7 +368,6 @@ struct dml2_core_mode_support_in_out {
struct dml2_mcg_min_clock_table *min_clk_table;
int min_clk_index;
/*
* Outputs
*/
@ -395,7 +397,6 @@ struct dml2_core_mode_programming_in_out {
struct dml2_core_instance *instance;
const struct display_configuation_with_meta *display_cfg;
const struct core_display_cfg_support_info *cfg_support_info;
/*
* Outputs (also Input the clk freq are also from programming struct)
*/
@ -445,6 +446,7 @@ struct dml2_core_internal_state_intermediates {
struct dml2_core_mode_support_locals {
struct dml2_core_calcs_mode_support_ex mode_support_ex_params;
struct dml2_display_cfg svp_expanded_display_cfg;
struct dml2_calculate_mcache_allocation_in_out calc_mcache_allocation_params;
};
struct dml2_core_mode_programming_locals {
@ -600,34 +602,11 @@ struct dml2_pmo_optimize_for_stutter_in_out {
struct display_configuation_with_meta *optimized_display_config;
};
enum dml2_pmo_pstate_method {
dml2_pmo_pstate_strategy_na = 0,
/* hw exclusive modes */
dml2_pmo_pstate_strategy_vactive = 1,
dml2_pmo_pstate_strategy_vblank = 2,
dml2_pmo_pstate_strategy_reserved_hw = 5,
/* fw assisted exclusive modes */
dml2_pmo_pstate_strategy_fw_svp = 6,
dml2_pmo_pstate_strategy_reserved_fw = 10,
/* fw assisted modes requiring drr modulation */
dml2_pmo_pstate_strategy_fw_vactive_drr = 11,
dml2_pmo_pstate_strategy_fw_vblank_drr = 12,
dml2_pmo_pstate_strategy_fw_svp_drr = 13,
dml2_pmo_pstate_strategy_reserved_fw_drr_clamped = 20,
dml2_pmo_pstate_strategy_fw_drr = 21,
dml2_pmo_pstate_strategy_reserved_fw_drr_var = 22,
};
struct dml2_pmo_pstate_strategy {
enum dml2_pmo_pstate_method per_stream_pstate_method[DML2_MAX_PLANES];
bool allow_state_increase;
};
#define PMO_NO_DRR_STRATEGY_MASK (((1 << (dml2_pmo_pstate_strategy_reserved_fw - dml2_pmo_pstate_strategy_na + 1)) - 1) << dml2_pmo_pstate_strategy_na)
#define PMO_DRR_STRATEGY_MASK (((1 << (dml2_pmo_pstate_strategy_reserved_fw_drr_var - dml2_pmo_pstate_strategy_fw_vactive_drr + 1)) - 1) << dml2_pmo_pstate_strategy_fw_vactive_drr)
#define PMO_DRR_CLAMPED_STRATEGY_MASK (((1 << (dml2_pmo_pstate_strategy_reserved_fw_drr_clamped - dml2_pmo_pstate_strategy_fw_vactive_drr + 1)) - 1) << dml2_pmo_pstate_strategy_fw_vactive_drr)
#define PMO_DRR_VAR_STRATEGY_MASK (((1 << (dml2_pmo_pstate_strategy_reserved_fw_drr_var - dml2_pmo_pstate_strategy_fw_drr + 1)) - 1) << dml2_pmo_pstate_strategy_fw_drr)
#define PMO_FW_STRATEGY_MASK (((1 << (dml2_pmo_pstate_strategy_reserved_fw_drr_var - dml2_pmo_pstate_strategy_fw_svp + 1)) - 1) << dml2_pmo_pstate_strategy_fw_svp)
#define PMO_NO_DRR_STRATEGY_MASK (((1 << (dml2_pstate_method_reserved_fw - dml2_pstate_method_na + 1)) - 1) << dml2_pstate_method_na)
#define PMO_DRR_STRATEGY_MASK (((1 << (dml2_pstate_method_reserved_fw_drr_var - dml2_pstate_method_fw_vactive_drr + 1)) - 1) << dml2_pstate_method_fw_vactive_drr)
#define PMO_DRR_CLAMPED_STRATEGY_MASK (((1 << (dml2_pstate_method_reserved_fw_drr_clamped - dml2_pstate_method_fw_vactive_drr + 1)) - 1) << dml2_pstate_method_fw_vactive_drr)
#define PMO_DRR_VAR_STRATEGY_MASK (((1 << (dml2_pstate_method_reserved_fw_drr_var - dml2_pstate_method_fw_drr + 1)) - 1) << dml2_pstate_method_fw_drr)
#define PMO_FW_STRATEGY_MASK (((1 << (dml2_pstate_method_reserved_fw_drr_var - dml2_pstate_method_fw_svp + 1)) - 1) << dml2_pstate_method_fw_svp)
#define PMO_DCN4_MAX_DISPLAYS 4
#define PMO_DCN4_MAX_NUM_VARIANTS 2
@ -645,6 +624,8 @@ struct dml2_pmo_scratch {
int stream_mask;
} pmo_dcn3;
struct {
struct dml2_pmo_pstate_strategy expanded_override_strategy_list[2 * 2 * 2 * 2];
unsigned int num_expanded_override_strategies;
struct dml2_pmo_pstate_strategy pstate_strategy_candidates[DML2_PMO_PSTATE_CANDIDATE_LIST_SIZE];
int num_pstate_candidates;
int cur_pstate_candidate;
@ -706,7 +687,6 @@ struct dml2_pmo_instance {
int mpc_combine_limit;
int odm_combine_limit;
int mcg_clock_table_size;
union {
struct {
struct {
@ -963,7 +943,13 @@ struct dml2_top_mcache_validate_admissability_locals {
struct dml2_top_display_cfg_support_info {
const struct dml2_display_cfg *display_config;
struct core_display_cfg_support_info core_info;
enum dml2_pstate_support_method per_plane_pstate_method[DML2_MAX_PLANES];
};
struct dml2_top_funcs {
bool (*check_mode_supported)(struct dml2_check_mode_supported_in_out *in_out);
bool (*build_mode_programming)(struct dml2_build_mode_programming_in_out *in_out);
bool (*build_mcache_programming)(struct dml2_build_mcache_programming_in_out *in_out);
bool (*unit_test)(void);
};
struct dml2_instance {
@ -978,8 +964,8 @@ struct dml2_instance {
struct dml2_ip_capabilities ip_caps;
struct dml2_mcg_min_clock_table min_clk_table;
struct dml2_pmo_options pmo_options;
struct dml2_top_funcs funcs;
struct {
struct dml2_initialize_instance_locals initialize_instance_locals;