drm/amd/display: Sync dcn42 with DC 3.2.373

This patch provides a bulk merge to align driver
support for DCN42 with Display Core version 3.2.373.

It includes upgrade for:
- clk_mgr
- dml2/dml21
- optc
- hubp
- mpc
- optc
- hwseq

Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Roman Li <Roman.Li@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Roman Li
2026-03-11 13:58:07 -04:00
committed by Alex Deucher
parent 6e5b72ac22
commit e56e3cff2a
63 changed files with 1518 additions and 1904 deletions
@@ -794,13 +794,11 @@ static enum bp_result bios_parser_external_encoder_control(
static enum bp_result bios_parser_dac_load_detection(
struct dc_bios *dcb,
enum engine_id engine_id,
struct graphics_object_id ext_enc_id)
enum engine_id engine_id)
{
struct bios_parser *bp = BP_FROM_DCB(dcb);
struct dc_context *ctx = dcb->ctx;
struct bp_load_detection_parameters bp_params = {0};
struct bp_external_encoder_control ext_cntl = {0};
enum bp_result bp_result = BP_RESULT_UNSUPPORTED;
uint32_t bios_0_scratch;
uint32_t device_id_mask = 0;
@@ -826,13 +824,6 @@ static enum bp_result bios_parser_dac_load_detection(
bp_params.engine_id = engine_id;
bp_result = bp->cmd_tbl.dac_load_detection(bp, &bp_params);
} else if (ext_enc_id.id) {
if (!bp->cmd_tbl.external_encoder_control)
return BP_RESULT_UNSUPPORTED;
ext_cntl.action = EXTERNAL_ENCODER_CONTROL_DAC_LOAD_DETECT;
ext_cntl.encoder_id = ext_enc_id;
bp_result = bp->cmd_tbl.external_encoder_control(bp, &ext_cntl);
}
if (bp_result != BP_RESULT_OK)
@@ -87,21 +87,18 @@ static const struct clk_mgr_mask clk_mgr_mask_dcn42 = {
#define TO_CLK_MGR_DCN42(clk_mgr_int)\
container_of(clk_mgr_int, struct clk_mgr_dcn42, base)
int dcn42_get_active_display_cnt_wa(
struct dc *dc,
struct dc_state *context,
int *all_active_disps)
bool dcn42_has_active_display(struct dc *dc, const struct dc_state *context)
{
int i, display_count = 0;
bool tmds_present = false;
int i, active_count = 0;
for (i = 0; i < context->stream_count; i++) {
const struct dc_stream_state *stream = context->streams[i];
if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
tmds_present = true;
/* Checking stream / link detection ensuring that PHY is active*/
if (dc_is_hdmi_signal(stream->signal) ||
dc_is_dvi_signal(stream->signal) ||
(dc_is_dp_signal(stream->signal) && !stream->dpms_off))
active_count++;
}
for (i = 0; i < dc->link_count; i++) {
@@ -110,15 +107,10 @@ int dcn42_get_active_display_cnt_wa(
/* abusing the fact that the dig and phy are coupled to see if the phy is enabled */
if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
link->link_enc->funcs->is_dig_enabled(link->link_enc))
display_count++;
active_count++;
}
if (all_active_disps != NULL)
*all_active_disps = display_count;
/* WA for hang on HDMI after display off back on*/
if (display_count == 0 && tmds_present)
display_count = 1;
return display_count;
return active_count > 0;
}
static uint32_t dcn42_get_clock_freq_from_clkip(struct clk_mgr *clk_mgr_base, enum clock_type clock)
@@ -223,20 +215,18 @@ void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
struct dc *dc = clk_mgr_base->ctx->dc;
int display_count = 0;
bool update_dppclk = false;
bool update_dispclk = false;
bool dpp_clock_lowered = false;
int all_active_disps = 0;
bool has_active_display;
if (dc->work_arounds.skip_clock_update)
return;
display_count = dcn42_get_active_display_cnt_wa(dc, context, &all_active_disps);
has_active_display = dcn42_has_active_display(dc, context);
if (new_clocks->dtbclk_en && new_clocks->ref_dtbclk_khz < 590000)
new_clocks->ref_dtbclk_khz = 600000;
/*
* if it is safe to lower, but we are already in the lower state, we don't have to do anything
* also if safe to lower is false, we just go in the higher state
@@ -256,7 +246,7 @@ void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
/* check that we're not already in lower */
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
/* if we can go lower, go lower */
if (display_count == 0)
if (has_active_display == false)
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
}
} else {
@@ -314,7 +304,7 @@ void dcn42_update_clocks(struct clk_mgr *clk_mgr_base,
}
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) &&
(new_clocks->dispclk_khz > 0 || (safe_to_lower && display_count == 0))) {
(new_clocks->dispclk_khz > 0 || (safe_to_lower && has_active_display == false))) {
int requested_dispclk_khz = new_clocks->dispclk_khz;
dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
@@ -461,7 +451,6 @@ static void dcn42_dump_clk_registers(struct clk_state_registers_and_bypass *regs
// REGISTER VALUES
DC_LOG_SMU("reg_name,value,clk_type\n");
DC_LOG_SMU("CLK1_CLK3_CURRENT_CNT,%d,dcfclk\n",
internal.CLK8_CLK3_CURRENT_CNT);
@@ -594,6 +583,7 @@ void dcn42_init_clocks(struct clk_mgr *clk_mgr_base)
else
clk_mgr_base->dp_dto_source_clock_in_khz = clk_mgr_base->dprefclk_khz;
DC_LOG_SMU("dp_dto_source_clock %d, dprefclk %d\n", clk_mgr_base->dp_dto_source_clock_in_khz, clk_mgr_base->dprefclk_khz);
dcn42_dump_clk_registers(&clk_mgr_base->boot_snapshot, clk_mgr);
clk_mgr_base->clks.ref_dtbclk_khz = clk_mgr_base->boot_snapshot.dtbclk * 10;
@@ -602,6 +592,12 @@ void dcn42_init_clocks(struct clk_mgr *clk_mgr_base)
clk_mgr_base->clks.dtbclk_en = true;
}
if (clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels != 0) {
/*skip to get clock table and notify pmfw watermark range again*/
DC_LOG_SMU("skip to get dpm_clks from pmfw from resume and acr\n");
return;
}
smu_dpm_clks.dpm_clks = (DpmClocks_t_dcn42 *)dm_helpers_allocate_gpu_mem(
clk_mgr_base->ctx,
DC_MEM_ALLOC_TYPE_GART,
@@ -708,10 +704,9 @@ void dcn42_init_clocks(struct clk_mgr *clk_mgr_base)
/* DTBCLK*/
clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz = clk_mgr_base->clks.ref_dtbclk_khz / 1000;
clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels = 1;
/* Refresh bounding box */
clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box(
clk_mgr_base->ctx->dc, clk_mgr_base->bw_params);
clk_mgr_base->ctx->dc, clk_mgr_base->bw_params);
}
}
if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0)
@@ -823,7 +818,6 @@ static void dcn42_read_ss_info_from_lut(struct clk_mgr_internal *clk_mgr)
}
}
/* Exposed for dcn42b reuse */
void dcn42_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn42_watermarks *table)
{
int i, num_valid_sets;
@@ -882,18 +876,42 @@ void dcn42_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn42_
void dcn42_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
{
int i = 0;
struct dcn42_watermarks *table = NULL;
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
struct clk_mgr_dcn42 *clk_mgr_dcn42 = TO_CLK_MGR_DCN42(clk_mgr);
struct dcn42_watermarks *table = clk_mgr_dcn42->smu_wm_set.wm_set;
if (!clk_mgr->smu_ver)
return;
/*send once already skip*/
if (clk_mgr_base->bw_params->wm_table.entries[WM_A].valid == true)
return;
clk_mgr_dcn42->smu_wm_set.wm_set = (struct dcn42_watermarks *)dm_helpers_allocate_gpu_mem(
clk_mgr->base.ctx,
DC_MEM_ALLOC_TYPE_GART,
sizeof(struct dcn42_watermarks),
&clk_mgr_dcn42->smu_wm_set.mc_address.quad_part);
ASSERT(clk_mgr_dcn42->smu_wm_set.wm_set);
table = clk_mgr_dcn42->smu_wm_set.wm_set;
if (!table || clk_mgr_dcn42->smu_wm_set.mc_address.quad_part == 0)
return;
memset(table, 0, sizeof(*table));
/*same as previous asic, set wm valid before building watermark ranges*/
for (i = 0; i < WM_SET_COUNT; i++) {
clk_mgr_base->bw_params->wm_table.entries[i].wm_inst = i;
if (i >= clk_mgr_base->bw_params->clk_table.num_entries) {
clk_mgr_base->bw_params->wm_table.entries[i].valid = false;
continue;
}
clk_mgr_base->bw_params->wm_table.entries[i].wm_type = WM_TYPE_PSTATE_CHG;
clk_mgr_base->bw_params->wm_table.entries[i].valid = true;
}
/* build watermark_range will check this valid range*/
dcn42_build_watermark_ranges(clk_mgr_base->bw_params, table);
dcn42_smu_set_dram_addr_high(clk_mgr,
@@ -901,18 +919,21 @@ void dcn42_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
dcn42_smu_set_dram_addr_low(clk_mgr,
clk_mgr_dcn42->smu_wm_set.mc_address.low_part);
dcn42_smu_transfer_wm_table_dram_2_smu(clk_mgr);
if (clk_mgr_dcn42->smu_wm_set.wm_set && clk_mgr_dcn42->smu_wm_set.mc_address.quad_part != 0)
dm_helpers_free_gpu_mem(clk_mgr->base.ctx, DC_MEM_ALLOC_TYPE_GART,
clk_mgr_dcn42->smu_wm_set.wm_set);
}
void dcn42_set_low_power_state(struct clk_mgr *clk_mgr_base)
{
int display_count;
struct dc *dc = clk_mgr_base->ctx->dc;
struct dc_state *context = dc->current_state;
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
display_count = dcn42_get_active_display_cnt_wa(dc, context, NULL);
/* if we can go lower, go lower */
if (display_count == 0)
if (dcn42_has_active_display(dc, context) == false)
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
}
@@ -1093,14 +1114,7 @@ void dcn42_clk_mgr_construct(
clk_mgr->base.dprefclk_ss_divider = 1000;
clk_mgr->base.ss_on_dprefclk = false;
clk_mgr->base.dfs_ref_freq_khz = 48000; /*sync with pmfw*/
clk_mgr->smu_wm_set.wm_set = (struct dcn42_watermarks *)dm_helpers_allocate_gpu_mem(
clk_mgr->base.base.ctx,
DC_MEM_ALLOC_TYPE_GART,
sizeof(struct dcn42_watermarks),
&clk_mgr->smu_wm_set.mc_address.quad_part);
ASSERT(clk_mgr->smu_wm_set.wm_set);
clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
/* Changed from DCN3.2_clock_frequency doc to match
* dcn32_dump_clk_registers from 4 * dentist_vco_freq_khz /
@@ -1108,34 +1122,31 @@ void dcn42_clk_mgr_construct(
*/
clk_mgr->base.base.dprefclk_khz = 600000;
clk_mgr->base.smu_present = false;
clk_mgr->base.smu_ver = dcn42_smu_get_pmfw_version(&clk_mgr->base);
if (clk_mgr->base.smu_ver && clk_mgr->base.smu_ver != -1)
clk_mgr->base.smu_present = true;
clk_mgr->base.smu_present = false;
clk_mgr->base.smu_ver = dcn42_smu_get_pmfw_version(&clk_mgr->base);
if (clk_mgr->base.smu_ver && clk_mgr->base.smu_ver != -1)
clk_mgr->base.smu_present = true;
if (ctx->dc_bios->integrated_info) {
clk_mgr->base.base.dentist_vco_freq_khz = ctx->dc_bios->integrated_info->dentist_vco_freq;
if (ctx->dc_bios->integrated_info) {
clk_mgr->base.base.dentist_vco_freq_khz = ctx->dc_bios->integrated_info->dentist_vco_freq;
if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType)
dcn42_bw_params.wm_table = lpddr5_wm_table;
else
dcn42_bw_params.wm_table = ddr5_wm_table;
if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType)
dcn42_bw_params.wm_table = lpddr5_wm_table;
else
dcn42_bw_params.wm_table = ddr5_wm_table;
dcn42_bw_params.vram_type = ctx->dc_bios->integrated_info->memory_type;
dcn42_bw_params.dram_channel_width_bytes = ctx->dc_bios->integrated_info->memory_type == 0x22 ? 8 : 4;
dcn42_bw_params.num_channels = ctx->dc_bios->integrated_info->ma_channel_number ? ctx->dc_bios->integrated_info->ma_channel_number : 1;
clk_mgr->base.base.dprefclk_khz = dcn42_smu_get_dprefclk(&clk_mgr->base);
clk_mgr->base.base.clks.ref_dtbclk_khz = dcn42_smu_get_dtbclk(&clk_mgr->base);
}
/* in case we don't get a value from the BIOS, use default */
if (clk_mgr->base.base.dentist_vco_freq_khz == 0)
clk_mgr->base.base.dentist_vco_freq_khz = 3000000; /* 3000MHz */
dcn42_bw_params.vram_type = ctx->dc_bios->integrated_info->memory_type;
dcn42_bw_params.dram_channel_width_bytes = ctx->dc_bios->integrated_info->memory_type == 0x22 ? 8 : 4;
dcn42_bw_params.num_channels = ctx->dc_bios->integrated_info->ma_channel_number ? ctx->dc_bios->integrated_info->ma_channel_number : 4;
}
/* Saved clocks configured at boot for debug purposes */
dcn42_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, clk_mgr);
/* in case we don't get a value from the BIOS, use default */
if (clk_mgr->base.base.dentist_vco_freq_khz == 0)
clk_mgr->base.base.dentist_vco_freq_khz = 3000000; /* 3000MHz */
/* Saved clocks configured at boot for debug purposes */
dcn42_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, clk_mgr);
if (clk_mgr->base.smu_present)
clk_mgr->base.base.dprefclk_khz = dcn42_smu_get_dprefclk(&clk_mgr->base);
clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
dce_clock_read_ss_info(&clk_mgr->base);
/*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/
@@ -59,7 +59,6 @@ void dcn42_clk_mgr_construct(struct dc_context *ctx,
void dcn42_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int);
/* Exposed for dcn42b reuse */
void dcn42_init_single_clock(unsigned int *entry_0,
uint32_t *smu_entry_0,
uint8_t num_levels);
@@ -76,4 +75,5 @@ int dcn42_get_active_display_cnt_wa(struct dc *dc, struct dc_state *context, int
void dcn42_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, bool safe_to_lower);
void dcn42_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, int ref_dtbclk_khz);
bool dcn42_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base);
bool dcn42_has_active_display(struct dc *dc, const struct dc_state *context);
#endif //__DCN42_CLK_MGR_H__
+42 -53
View File
@@ -2895,16 +2895,27 @@ static struct surface_update_descriptor det_surface_update(
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
if (u->blend_tf || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
if (u->cm || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) {
update_flags->bits.gamma_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
if (u->lut3d_func || u->func_shaper) {
if (u->cm && (u->cm->flags.bits.lut3d_enable || u->surface->cm.flags.bits.lut3d_enable)) {
update_flags->bits.lut_3d = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
if (u->cm && u->cm->flags.bits.lut3d_dma_enable != u->surface->cm.flags.bits.lut3d_dma_enable &&
u->cm->flags.bits.lut3d_enable && u->surface->cm.flags.bits.lut3d_enable) {
/* Toggling 3DLUT loading between DMA and Host is illegal */
BREAK_TO_DEBUGGER();
}
if (u->cm && u->cm->flags.bits.lut3d_enable && !u->cm->flags.bits.lut3d_dma_enable) {
/* Host loading 3DLUT requires full update but only stream lock */
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_STREAM);
}
if (u->hdr_mult.value)
if (u->hdr_mult.value != u->surface->hdr_mult.value) {
// TODO: Should be fast?
@@ -2919,24 +2930,15 @@ static struct surface_update_descriptor det_surface_update(
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
}
if (u->cm2_params) {
if (u->cm2_params->component_settings.shaper_3dlut_setting != u->surface->mcm_shaper_3dlut_setting
|| u->cm2_params->component_settings.lut1d_enable != u->surface->mcm_lut1d_enable
|| u->cm2_params->cm2_luts.lut3d_data.lut3d_src != u->surface->mcm_luts.lut3d_data.lut3d_src) {
update_flags->bits.mcm_transfer_function_enable_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
}
if (u->cm_hist_control) {
update_flags->bits.cm_hist_change = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
}
if (update_flags->bits.lut_3d &&
u->surface->mcm_luts.lut3d_data.lut3d_src != DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
}
if (check_config->enable_legacy_fast_update &&
(update_flags->bits.gamma_change ||
update_flags->bits.gamut_remap_change ||
update_flags->bits.input_csc_change ||
update_flags->bits.cm_hist_change ||
update_flags->bits.coeff_reduction_change)) {
elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL);
}
@@ -3168,6 +3170,11 @@ static void copy_surface_update_to_plane(
surface->gamma_correction.type =
srf_update->gamma->type;
}
if (srf_update->cm_hist_control) {
memcpy(&surface->cm_hist_control,
srf_update->cm_hist_control,
sizeof(surface->cm_hist_control));
}
if (srf_update->in_transfer_func) {
surface->in_transfer_func.sdr_ref_white_level =
@@ -3181,24 +3188,12 @@ static void copy_surface_update_to_plane(
sizeof(struct dc_transfer_func_distributed_points));
}
if (srf_update->cm2_params) {
surface->mcm_shaper_3dlut_setting = srf_update->cm2_params->component_settings.shaper_3dlut_setting;
surface->mcm_lut1d_enable = srf_update->cm2_params->component_settings.lut1d_enable;
surface->mcm_luts = srf_update->cm2_params->cm2_luts;
/* Shaper, 3DLUT, 1DLUT */
if (srf_update->cm) {
memcpy(&surface->cm, srf_update->cm,
sizeof(surface->cm));
}
if (srf_update->func_shaper) {
memcpy(&surface->in_shaper_func, srf_update->func_shaper,
sizeof(surface->in_shaper_func));
if (surface->mcm_shaper_3dlut_setting >= DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER)
surface->mcm_luts.shaper = &surface->in_shaper_func;
}
if (srf_update->lut3d_func)
memcpy(&surface->lut3d_func, srf_update->lut3d_func,
sizeof(surface->lut3d_func));
if (srf_update->hdr_mult.value)
surface->hdr_mult =
srf_update->hdr_mult;
@@ -3207,17 +3202,6 @@ static void copy_surface_update_to_plane(
surface->sdr_white_level_nits =
srf_update->sdr_white_level_nits;
if (srf_update->blend_tf) {
memcpy(&surface->blend_tf, srf_update->blend_tf,
sizeof(surface->blend_tf));
if (surface->mcm_lut1d_enable)
surface->mcm_luts.lut1d_func = &surface->blend_tf;
}
if (srf_update->cm2_params || srf_update->blend_tf)
surface->lut_bank_a = !surface->lut_bank_a;
if (srf_update->input_csc_color_matrix)
surface->input_csc_color_matrix =
*srf_update->input_csc_color_matrix;
@@ -4501,11 +4485,9 @@ static void commit_planes_for_stream(struct dc *dc,
if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state))
continue;
if (srf_updates[i].cm2_params &&
srf_updates[i].cm2_params->cm2_luts.lut3d_data.lut3d_src ==
DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM &&
srf_updates[i].cm2_params->component_settings.shaper_3dlut_setting ==
DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT &&
if (srf_updates[i].cm &&
srf_updates[i].cm->flags.bits.lut3d_enable &&
srf_updates[i].cm->flags.bits.lut3d_dma_enable &&
dc->hwss.trigger_3dlut_dma_load)
dc->hwss.trigger_3dlut_dma_load(dc, pipe_ctx);
@@ -5073,6 +5055,7 @@ void populate_fast_updates(struct dc_fast_update *fast_update,
fast_update[i].input_csc_color_matrix = srf_updates[i].input_csc_color_matrix;
fast_update[i].coeff_reduction_factor = srf_updates[i].coeff_reduction_factor;
fast_update[i].cursor_csc_color_matrix = srf_updates[i].cursor_csc_color_matrix;
fast_update[i].cm_hist_control = srf_updates[i].cm_hist_control;
}
}
@@ -5090,6 +5073,7 @@ static bool fast_updates_exist(const struct dc_fast_update *fast_update, int sur
fast_update[i].gamut_remap_matrix ||
fast_update[i].input_csc_color_matrix ||
fast_update[i].cursor_csc_color_matrix ||
fast_update[i].cm_hist_control ||
fast_update[i].coeff_reduction_factor)
return true;
}
@@ -5110,6 +5094,7 @@ bool fast_nonaddr_updates_exist(struct dc_fast_update *fast_update, int surface_
fast_update[i].gamma ||
fast_update[i].gamut_remap_matrix ||
fast_update[i].coeff_reduction_factor ||
fast_update[i].cm_hist_control ||
fast_update[i].cursor_csc_color_matrix)
return true;
}
@@ -5151,6 +5136,12 @@ static bool full_update_required(
const struct dc_stream_update *stream_update,
const struct dc_stream_state *stream)
{
const union dc_plane_cm_flags blend_only_flags = {
.bits = {
.blend_enable = 1,
}
};
if (full_update_required_weak(dc, srf_updates, surface_count, stream_update, stream))
return true;
@@ -5163,14 +5154,12 @@ static bool full_update_required(
(srf_updates[i].sdr_white_level_nits &&
srf_updates[i].sdr_white_level_nits != srf_updates->surface->sdr_white_level_nits) ||
srf_updates[i].in_transfer_func ||
srf_updates[i].func_shaper ||
srf_updates[i].lut3d_func ||
srf_updates[i].surface->force_full_update ||
(srf_updates[i].flip_addr &&
srf_updates[i].flip_addr->address.tmz_surface != srf_updates[i].surface->address.tmz_surface) ||
(srf_updates[i].cm2_params &&
(srf_updates[i].cm2_params->component_settings.shaper_3dlut_setting != srf_updates[i].surface->mcm_shaper_3dlut_setting ||
srf_updates[i].cm2_params->component_settings.lut1d_enable != srf_updates[i].surface->mcm_lut1d_enable))))
(srf_updates[i].cm &&
((srf_updates[i].cm->flags.all != blend_only_flags.all && srf_updates[i].cm->flags.all != 0) ||
(srf_updates[i].surface->cm.flags.all != blend_only_flags.all && srf_updates[i].surface->cm.flags.all != 0)))))
return true;
}
@@ -6898,7 +6887,7 @@ bool dc_capture_register_software_state(struct dc *dc, struct dc_register_softwa
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
/* MPCC blending tree and mode control - capture actual blend configuration */
state->mpc.mpcc_mode[i] = (plane_state->blend_tf.type != TF_TYPE_BYPASS) ? 1 : 0;
state->mpc.mpcc_mode[i] = (plane_state->cm.blend_func.type != TF_TYPE_BYPASS) ? 1 : 0;
state->mpc.mpcc_alpha_blend_mode[i] = plane_state->per_pixel_alpha ? 1 : 0;
state->mpc.mpcc_alpha_multiplied_mode[i] = plane_state->pre_multiplied_alpha ? 1 : 0;
state->mpc.mpcc_blnd_active_overlap_only[i] = 0; /* Default - no overlap restriction */
@@ -33,6 +33,7 @@
#include "dc_dmub_srv.h"
#include "dc_state_priv.h"
#include "dc_stream_priv.h"
#include "dce/dmub_hw_lock_mgr.h"
#define DC_LOGGER dc->ctx->logger
#ifndef MIN
@@ -171,10 +172,12 @@ struct dc_stream_state *dc_create_stream_for_sink(
goto fail;
stream = kzalloc_obj(struct dc_stream_state, GFP_ATOMIC);
if (stream == NULL)
goto fail;
stream->update_scratch = kzalloc((int32_t) dc_update_scratch_space_size(), GFP_ATOMIC);
if (stream->update_scratch == NULL)
goto fail;
@@ -245,7 +248,6 @@ const struct dc_stream_status *dc_stream_get_status_const(
const struct dc_stream_state *stream)
{
struct dc *dc = stream->ctx->dc;
return dc_state_get_stream_status(dc->current_state, stream);
}
@@ -257,6 +259,7 @@ void program_cursor_attributes(
struct resource_context *res_ctx;
struct pipe_ctx *pipe_to_program = NULL;
bool enable_cursor_offload = dc_dmub_srv_is_cursor_offload_enabled(dc);
bool unlock_dmub = false;
if (!stream)
return;
@@ -275,6 +278,12 @@ void program_cursor_attributes(
if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update) {
dc->hwss.begin_cursor_offload_update(dc, pipe_ctx);
} else {
if (dc->hwss.dmub_hw_control_lock && pipe_ctx->stream &&
should_use_dmub_inbox0_lock_for_link(dc, pipe_ctx->stream->link)) {
dc->hwss.dmub_hw_control_lock(dc, dc->current_state, true);
unlock_dmub = true;
}
dc->hwss.cursor_lock(dc, pipe_to_program, true);
if (pipe_to_program->next_odm_pipe)
dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, true);
@@ -297,6 +306,9 @@ void program_cursor_attributes(
dc->hwss.cursor_lock(dc, pipe_to_program, false);
if (pipe_to_program->next_odm_pipe)
dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, false);
if (unlock_dmub)
dc->hwss.dmub_hw_control_lock(dc, dc->current_state, false);
}
}
}
@@ -404,6 +416,7 @@ void program_cursor_position(
struct resource_context *res_ctx;
struct pipe_ctx *pipe_to_program = NULL;
bool enable_cursor_offload = dc_dmub_srv_is_cursor_offload_enabled(dc);
bool unlock_dmub = false;
if (!stream)
return;
@@ -423,10 +436,16 @@ void program_cursor_position(
if (!pipe_to_program) {
pipe_to_program = pipe_ctx;
if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update)
if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update) {
dc->hwss.begin_cursor_offload_update(dc, pipe_ctx);
else
} else {
if (dc->hwss.dmub_hw_control_lock && pipe_ctx->stream &&
should_use_dmub_inbox0_lock_for_link(dc, pipe_ctx->stream->link)) {
dc->hwss.dmub_hw_control_lock(dc, dc->current_state, true);
unlock_dmub = true;
}
dc->hwss.cursor_lock(dc, pipe_to_program, true);
}
}
dc->hwss.set_cursor_position(pipe_ctx);
@@ -438,10 +457,14 @@ void program_cursor_position(
}
if (pipe_to_program) {
if (enable_cursor_offload && dc->hwss.commit_cursor_offload_update)
if (enable_cursor_offload && dc->hwss.commit_cursor_offload_update) {
dc->hwss.commit_cursor_offload_update(dc, pipe_to_program);
else
} else {
dc->hwss.cursor_lock(dc, pipe_to_program, false);
if (unlock_dmub)
dc->hwss.dmub_hw_control_lock(dc, dc->current_state, false);
}
}
}
@@ -523,8 +546,10 @@ bool dc_stream_program_cursor_position(
struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
/* trigger event on first pipe with current stream */
if (stream == pipe_ctx->stream) {
pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
if (stream == pipe_ctx->stream &&
pipe_ctx->stream_res.tg->funcs->program_manual_trigger) {
pipe_ctx->stream_res.tg->funcs->program_manual_trigger(
pipe_ctx->stream_res.tg);
break;
}
}
@@ -984,7 +1009,6 @@ void dc_stream_release_3dlut_for_stream(
if (rmcm_3dlut) {
rmcm_3dlut->isInUse = false;
rmcm_3dlut->stream = NULL;
rmcm_3dlut->protection_bits = 0;
}
}
@@ -996,7 +1020,6 @@ void dc_stream_init_rmcm_3dlut(struct dc *dc)
for (int i = 0; i < num_rmcm; i++) {
dc->res_pool->rmcm_3dlut[i].isInUse = false;
dc->res_pool->rmcm_3dlut[i].stream = NULL;
dc->res_pool->rmcm_3dlut[i].protection_bits = 0;
}
}
@@ -139,6 +139,9 @@ const struct dc_plane_status *dc_plane_get_status(
if (pipe_ctx->plane_state && flags.bits.address)
pipe_ctx->plane_state->status.is_flip_pending = false;
if (pipe_ctx->plane_state && flags.bits.histogram)
memset(&pipe_ctx->plane_state->status.cm_hist, 0,
sizeof(pipe_ctx->plane_state->status.cm_hist));
break;
}
@@ -154,6 +157,12 @@ const struct dc_plane_status *dc_plane_get_status(
if (flags.bits.address)
dc->hwss.update_pending_status(pipe_ctx);
if (flags.bits.histogram) {
struct dpp *dpp = pipe_ctx->plane_res.dpp;
if (dpp && dpp->funcs->dpp_cm_hist_read)
dpp->funcs->dpp_cm_hist_read(dpp, &pipe_ctx->plane_state->status.cm_hist);
}
}
return plane_status;
+49 -10
View File
@@ -1404,15 +1404,50 @@ struct lut_mem_mapping {
struct dc_rmcm_3dlut {
bool isInUse;
const struct dc_stream_state *stream;
uint8_t protection_bits;
};
struct dc_3dlut {
struct kref refcount;
struct tetrahedral_params lut_3d;
struct fixed31_32 hdr_multiplier;
union dc_3dlut_state state;
};
/* 3DLUT DMA (Fast Load) params */
struct dc_3dlut_dma {
struct dc_plane_address addr;
enum dc_cm_lut_swizzle swizzle;
enum dc_cm_lut_pixel_format format;
uint16_t bias; /* FP1.5.10 */
uint16_t scale; /* FP1.5.10 */
enum dc_cm_lut_size size;
};
/* color manager */
union dc_plane_cm_flags {
unsigned int all;
struct {
unsigned int shaper_enable : 1;
unsigned int lut3d_enable : 1;
unsigned int blend_enable : 1;
/* whether legacy (lut3d_func) or DMA is valid */
unsigned int lut3d_dma_enable : 1;
/* RMCM lut to be used instead of MCM */
unsigned int rmcm_enable : 1;
unsigned int reserved: 27;
} bits;
};
struct dc_plane_cm {
struct kref refcount;
struct dc_transfer_func shaper_func;
union {
struct dc_3dlut lut3d_func;
struct dc_3dlut_dma lut3d_dma;
};
struct dc_transfer_func blend_func;
union dc_plane_cm_flags flags;
};
/*
* This structure is filled in by dc_surface_get_status and contains
* the last requested address and the currently active address so the called
@@ -1490,14 +1525,18 @@ struct dc_plane_state {
struct fixed31_32 hdr_mult;
struct colorspace_transform gamut_remap_matrix;
// TODO: No longer used, remove
struct dc_hdr_static_metadata hdr_static_ctx;
enum dc_color_space color_space;
bool lut_bank_a;
struct dc_hdr_static_metadata hdr_static_ctx;
struct dc_3dlut lut3d_func;
struct dc_transfer_func in_shaper_func;
struct dc_transfer_func blend_tf;
enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
bool mcm_lut1d_enable;
struct dc_cm2_func_luts mcm_luts;
enum mpcc_movable_cm_location mcm_location;
struct dc_plane_cm cm;
struct dc_transfer_func *gamcor_tf;
enum surface_pixel_format format;
@@ -1534,11 +1573,6 @@ struct dc_plane_state {
bool is_statically_allocated;
enum chroma_cositing cositing;
enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting;
bool mcm_lut1d_enable;
struct dc_cm2_func_luts mcm_luts;
bool lut_bank_a;
enum mpcc_movable_cm_location mcm_location;
struct dc_csc_transform cursor_csc_color_matrix;
bool adaptive_sharpness_en;
int adaptive_sharpness_policy;
@@ -1884,6 +1918,7 @@ struct dc_surface_update {
* change cm2_params.cm2_luts: Fast update
*/
const struct dc_cm2_parameters *cm2_params;
const struct dc_plane_cm *cm;
const struct dc_csc_transform *cursor_csc_color_matrix;
unsigned int sdr_white_level_nits;
struct dc_bias_and_scale bias_and_scale;
@@ -1928,6 +1963,10 @@ struct dc_3dlut *dc_create_3dlut_func(void);
void dc_3dlut_func_release(struct dc_3dlut *lut);
void dc_3dlut_func_retain(struct dc_3dlut *lut);
struct dc_plane_cm *dc_plane_cm_create(void);
void dc_plane_cm_release(struct dc_plane_cm *cm);
void dc_plane_cm_retain(struct dc_plane_cm *cm);
void dc_post_update_surfaces_to_stream(
struct dc *dc);
@@ -102,8 +102,7 @@ struct dc_vbios_funcs {
struct bp_external_encoder_control *cntl);
enum bp_result (*dac_load_detection)(
struct dc_bios *bios,
enum engine_id engine_id,
struct graphics_object_id ext_enc_id);
enum engine_id engine_id);
enum bp_result (*transmitter_control)(
struct dc_bios *bios,
struct bp_transmitter_control *cntl);
@@ -31,6 +31,7 @@
union dc_plane_status_update_flags {
struct {
uint32_t address : 1;
uint32_t histogram : 1;
} bits;
uint32_t raw;
};
+24
View File
@@ -1483,4 +1483,28 @@ struct dc_validation_dpia_set {
uint32_t required_bw;
};
enum dc_cm_lut_swizzle {
CM_LUT_3D_SWIZZLE_LINEAR_RGB,
CM_LUT_3D_SWIZZLE_LINEAR_BGR,
CM_LUT_1D_PACKED_LINEAR
};
enum dc_cm_lut_pixel_format {
CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB,
CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB,
CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB,
CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB,
CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10,
CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10
};
enum dc_cm_lut_size {
CM_LUT_SIZE_NONE,
CM_LUT_SIZE_999,
CM_LUT_SIZE_171717,
CM_LUT_SIZE_333333,
CM_LUT_SIZE_454545,
CM_LUT_SIZE_656565,
};
#endif /* DC_TYPES_H_ */
@@ -827,6 +827,16 @@ void dccg401_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint3
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 1);
break;
case 4:
if (dccg_dcn->dccg_mask->SYMCLKE_FE_ROOT_GATE_DISABLE) {
REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
SYMCLKE_FE_EN, 1,
SYMCLKE_FE_SRC_SEL, link_enc_inst);
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 1);
}
break;
default:
return;
}
}
@@ -855,6 +865,16 @@ void dccg401_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint
SYMCLKD_FE_EN, 0,
SYMCLKD_FE_SRC_SEL, 0);
break;
case 4:
if (dccg_dcn->dccg_mask->SYMCLKE_FE_ROOT_GATE_DISABLE) {
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 0);
REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
SYMCLKE_FE_EN, 0,
SYMCLKE_FE_SRC_SEL, 0);
}
break;
default:
return;
}
}
@@ -28,6 +28,14 @@
#include "dc_types.h"
#include "core_types.h"
static bool dmub_hw_lock_has_inbox0_lock(const struct dc *dc)
{
return dc->ctx && dc->ctx->dmub_srv &&
dc->hwss.dmub_hw_control_lock &&
dc->hwss.dmub_hw_control_lock_fast &&
dc->ctx->dmub_srv->dmub->meta_info.feature_bits.bits.inbox0_lock_support;
}
void dmub_hw_lock_mgr_cmd(struct dc_dmub_srv *dmub_srv,
bool lock,
union dmub_hw_lock_flags *hw_locks,
@@ -105,5 +113,13 @@ bool should_use_dmub_inbox1_lock(const struct dc *dc, const struct dc_link *link
if (dc->ctx->dce_version >= DCN_VERSION_4_01)
return false;
if (dmub_hw_lock_has_inbox0_lock(dc))
return false;
return dmub_hw_lock_mgr_does_link_require_lock(dc, link);
}
bool should_use_dmub_inbox0_lock_for_link(const struct dc *dc, const struct dc_link *link)
{
return dmub_hw_lock_has_inbox0_lock(dc) && dmub_hw_lock_mgr_does_link_require_lock(dc, link);
}
@@ -67,4 +67,17 @@ bool dmub_hw_lock_mgr_does_link_require_lock(const struct dc *dc, const struct d
*/
bool dmub_hw_lock_mgr_does_context_require_lock(const struct dc *dc, const struct dc_state *context);
/**
* should_use_dmub_inbox0_lock_for_link() - Checks if the inbox0 interlock with DMU should be used.
*
* Is not functionally equivalent to inbox1 as DMUB will not own programming of the relevant locking
* registers.
*
* @dc: pointer to DC object
* @link: optional pointer to the link object to check for enabled link features
*
* Return: true if the inbox0 lock should be used, false otherwise
*/
bool should_use_dmub_inbox0_lock_for_link(const struct dc *dc, const struct dc_link *link);
#endif /*_DMUB_HW_LOCK_MGR_H_ */
@@ -601,36 +601,31 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
plane->composition.viewport.stationary = false;
if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
if (plane_state->cm.flags.bits.lut3d_dma_enable) {
plane->tdlut.setup_for_tdlut = true;
switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.layout) {
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
switch (plane_state->cm.lut3d_dma.swizzle) {
case CM_LUT_3D_SWIZZLE_LINEAR_RGB:
case CM_LUT_3D_SWIZZLE_LINEAR_BGR:
plane->tdlut.tdlut_addressing_mode = dml2_tdlut_sw_linear;
break;
case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
case CM_LUT_1D_PACKED_LINEAR:
default:
plane->tdlut.tdlut_addressing_mode = dml2_tdlut_simple_linear;
break;
}
switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.size) {
case DC_CM2_GPU_MEM_SIZE_171717:
plane->tdlut.tdlut_width_mode = dml2_tdlut_width_17_cube;
break;
case DC_CM2_GPU_MEM_SIZE_333333:
switch (plane_state->cm.lut3d_dma.size) {
case CM_LUT_SIZE_333333:
plane->tdlut.tdlut_width_mode = dml2_tdlut_width_33_cube;
break;
// handling when use case and HW support available
case DC_CM2_GPU_MEM_SIZE_454545:
case DC_CM2_GPU_MEM_SIZE_656565:
break;
case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
case CM_LUT_SIZE_171717:
default:
//plane->tdlut.tdlut_width_mode = dml2_tdlut_width_flatten; // dml2_tdlut_width_flatten undefined
plane->tdlut.tdlut_width_mode = dml2_tdlut_width_17_cube;
break;
}
}
plane->tdlut.setup_for_tdlut |= dml_ctx->config.force_tdlut_enable;
plane->dynamic_meta_data.enable = false;
@@ -967,5 +962,8 @@ void dml21_init_min_clocks_for_dc_state(struct dml2_context *in_ctx, struct dc_s
min_clocks->phyclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.phyclk.clk_values_khz[lowest_dpm_state_index];
min_clocks->stutter_efficiency.base_efficiency = 1;
min_clocks->stutter_efficiency.low_power_efficiency = 1;
min_clocks->stutter_efficiency.z8_stutter_efficiency = 1;
min_clocks->stutter_efficiency.z8_stutter_period = 100000;
min_clocks->zstate_support = DCN_ZSTATE_SUPPORT_ALLOW;
}
@@ -374,6 +374,7 @@ void dml21_handle_phantom_streams_planes(const struct dc *dc, struct dc_state *c
dml2_map_dc_pipes(dml_ctx, context, NULL, &dml_ctx->v21.dml_to_dc_pipe_mapping, dc->current_state);
}
static unsigned int dml21_build_fams2_stream_programming_v2(const struct dc *dc,
struct dc_state *context,
struct dml2_context *dml_ctx)
@@ -9,16 +9,21 @@
#include "dml21_utils.h"
#include "dml21_translation_helper.h"
#include "dml2_dc_resource_mgmt.h"
#include "dc_fpu.h"
#if !defined(DC_RUN_WITH_PREEMPTION_ENABLED)
#define DC_RUN_WITH_PREEMPTION_ENABLED(code) code
#endif // !DC_RUN_WITH_PREEMPTION_ENABLED
#define INVALID -1
static bool dml21_allocate_memory(struct dml2_context **dml_ctx)
{
*dml_ctx = vzalloc(sizeof(struct dml2_context));
DC_RUN_WITH_PREEMPTION_ENABLED(*dml_ctx = vzalloc(sizeof(struct dml2_context)));
if (!(*dml_ctx))
return false;
(*dml_ctx)->v21.dml_init.dml2_instance = vzalloc(sizeof(struct dml2_instance));
DC_RUN_WITH_PREEMPTION_ENABLED((*dml_ctx)->v21.dml_init.dml2_instance = vzalloc(sizeof(struct dml2_instance)));
if (!((*dml_ctx)->v21.dml_init.dml2_instance))
return false;
@@ -28,7 +33,7 @@ static bool dml21_allocate_memory(struct dml2_context **dml_ctx)
(*dml_ctx)->v21.mode_support.display_config = &(*dml_ctx)->v21.display_config;
(*dml_ctx)->v21.mode_programming.display_config = (*dml_ctx)->v21.mode_support.display_config;
(*dml_ctx)->v21.mode_programming.programming = vzalloc(sizeof(struct dml2_display_cfg_programming));
DC_RUN_WITH_PREEMPTION_ENABLED((*dml_ctx)->v21.mode_programming.programming = vzalloc(sizeof(struct dml2_display_cfg_programming)));
if (!((*dml_ctx)->v21.mode_programming.programming))
return false;
@@ -70,8 +75,9 @@ static void dml21_init(const struct dc *in_dc, struct dml2_context *dml_ctx, con
bool dml21_create(const struct dc *in_dc, struct dml2_context **dml_ctx, const struct dml2_configuration_options *config)
{
/* Allocate memory for initializing DML21 instance */
if (!dml21_allocate_memory(dml_ctx))
if (!dml21_allocate_memory(dml_ctx)) {
return false;
}
dml21_init(in_dc, *dml_ctx, config);
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2026 Advanced Micro Devices, Inc. */
//
// Copyright 2024 Advanced Micro Devices, Inc.
#ifndef __DML_DML_DCN42_SOC_BB__
#define __DML_DML_DCN42_SOC_BB__
@@ -9,39 +10,39 @@
static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params = {
.derate_table = {
.system_active_urgent = {
.dram_derate_percent_pixel = 22,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 76,
.dcfclk_derate_percent = 100,
.dram_derate_percent_pixel = 65,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 60,
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
},
.system_active_average = {
.dram_derate_percent_pixel = 17,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 57,
.dcfclk_derate_percent = 75,
.dram_derate_percent_pixel = 30,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 30,
.fclk_derate_percent = 60,
.dcfclk_derate_percent = 60,
},
.dcn_mall_prefetch_urgent = {
.dram_derate_percent_pixel = 40,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 83,
.dcfclk_derate_percent = 100,
.dram_derate_percent_pixel = 65,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 60,
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
},
.dcn_mall_prefetch_average = {
.dram_derate_percent_pixel = 33,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 62,
.dcfclk_derate_percent = 83,
.dram_derate_percent_pixel = 30,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 30,
.fclk_derate_percent = 60,
.dcfclk_derate_percent = 60,
},
.system_idle_average = {
.dram_derate_percent_pixel = 70,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 83,
.dcfclk_derate_percent = 100,
.dram_derate_percent_pixel = 30,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 30,
.fclk_derate_percent = 60,
.dcfclk_derate_percent = 60,
},
},
.writeback = {
@@ -50,80 +51,71 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params =
.scaling_factor_mhz = 0,
},
.qos_params = {
.dcn4x = {
.df_qos_response_time_fclk_cycles = 300,
.max_round_trip_to_furthest_cs_fclk_cycles = 350,
.mall_overhead_fclk_cycles = 50,
.meta_trip_adder_fclk_cycles = 36,
.average_transport_distance_fclk_cycles = 257,
.umc_urgent_ramp_latency_margin = 50,
.umc_max_latency_margin = 30,
.umc_average_latency_margin = 20,
.fabric_max_transport_latency_margin = 20,
.fabric_average_transport_latency_margin = 10,
.per_uclk_dpm_params = {
{
.minimum_uclk_khz = 97 * 1000,
.urgent_ramp_uclk_cycles = 472,
.trip_to_memory_uclk_cycles = 827,
.meta_trip_to_memory_uclk_cycles = 827,
.maximum_latency_when_urgent_uclk_cycles = 72,
.average_latency_when_urgent_uclk_cycles = 61,
.maximum_latency_when_non_urgent_uclk_cycles = 827,
.average_latency_when_non_urgent_uclk_cycles = 118,
},
.dcn32x = {
.loaded_round_trip_latency_fclk_cycles = 106,
.urgent_latency_us = {
.base_latency_us = 4,
.base_latency_pixel_vm_us = 4,
.base_latency_vm_us = 4,
.scaling_factor_fclk_us = 0,
.scaling_factor_mhz = 0,
},
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
},
},
.qos_type = dml2_qos_param_type_dcn4x,
.qos_type = dml2_qos_param_type_dcn3,
};
static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.clk_table = {
.wck_ratio = {
.clk_values_khz = {2},
},
.uclk = {
.clk_values_khz = {97000},
.clk_values_khz = {400000},
.num_clk_values = 1,
},
.fclk = {
.clk_values_khz = {300000, 2500000},
.num_clk_values = 2,
.clk_values_khz = {400000},
.num_clk_values = 1,
},
.dcfclk = {
.clk_values_khz = {200000, 1564000},
.num_clk_values = 2,
.clk_values_khz = {200000},
.num_clk_values = 1,
},
.dispclk = {
.clk_values_khz = {100000, 1500000},
.num_clk_values = 2,
.clk_values_khz = {1500000},
.num_clk_values = 1,
},
.dppclk = {
.clk_values_khz = {100000, 1500000},
.num_clk_values = 2,
.clk_values_khz = {1500000},
.num_clk_values = 1,
},
.dtbclk = {
.clk_values_khz = {600000, 600000},
.num_clk_values = 2,
.clk_values_khz = {600000},
.num_clk_values = 1,
},
.phyclk = {
.clk_values_khz = {810000, 810000},
.num_clk_values = 2,
.clk_values_khz = {810000},
.num_clk_values = 1,
},
.socclk = {
.clk_values_khz = {300000, 1200000},
.num_clk_values = 2,
.clk_values_khz = {600000},
.num_clk_values = 1,
},
.dscclk = {
.clk_values_khz = {500000, 500000},
.num_clk_values = 2,
.clk_values_khz = {500000},
.num_clk_values = 1,
},
.phyclk_d18 = {
.clk_values_khz = {667000, 667000},
.num_clk_values = 2,
.clk_values_khz = {667000},
.num_clk_values = 1,
},
.phyclk_d32 = {
.clk_values_khz = {625000, 625000},
.num_clk_values = 2,
.clk_values_khz = {625000},
.num_clk_values = 1,
},
.dram_config = {
.channel_width_bytes = 4,
@@ -135,39 +127,39 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.qos_parameters = {
.derate_table = {
.system_active_urgent = {
.dram_derate_percent_pixel = 22,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 76,
.dcfclk_derate_percent = 100,
.dram_derate_percent_pixel = 65,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 60,
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
},
.system_active_average = {
.dram_derate_percent_pixel = 15,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 57,
.dcfclk_derate_percent = 75,
.dram_derate_percent_pixel = 30,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 30,
.fclk_derate_percent = 60,
.dcfclk_derate_percent = 60,
},
.dcn_mall_prefetch_urgent = {
.dram_derate_percent_pixel = 40,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 83,
.dcfclk_derate_percent = 100,
.dram_derate_percent_pixel = 65,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 60,
.fclk_derate_percent = 80,
.dcfclk_derate_percent = 80,
},
.dcn_mall_prefetch_average = {
.dram_derate_percent_pixel = 30,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 62,
.dcfclk_derate_percent = 83,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 30,
.fclk_derate_percent = 60,
.dcfclk_derate_percent = 60,
},
.system_idle_average = {
.dram_derate_percent_pixel = 70,
.dram_derate_percent_vm = 0,
.dram_derate_percent_pixel_and_vm = 0,
.fclk_derate_percent = 83,
.dcfclk_derate_percent = 100,
.dram_derate_percent_pixel = 30,
.dram_derate_percent_vm = 30,
.dram_derate_percent_pixel_and_vm = 30,
.fclk_derate_percent = 60,
.dcfclk_derate_percent = 60,
},
},
.writeback = {
@@ -176,115 +168,25 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.scaling_factor_mhz = 0,
},
.qos_params = {
.dcn4x = {
.df_qos_response_time_fclk_cycles = 300,
.max_round_trip_to_furthest_cs_fclk_cycles = 350,
.mall_overhead_fclk_cycles = 50,
.meta_trip_adder_fclk_cycles = 36,
.average_transport_distance_fclk_cycles = 260,
.umc_urgent_ramp_latency_margin = 50,
.umc_max_latency_margin = 30,
.umc_average_latency_margin = 20,
.fabric_max_transport_latency_margin = 20,
.fabric_average_transport_latency_margin = 10,
.per_uclk_dpm_params = {
{
// State 1
.minimum_uclk_khz = 0,
.urgent_ramp_uclk_cycles = 472,
.trip_to_memory_uclk_cycles = 827,
.meta_trip_to_memory_uclk_cycles = 827,
.maximum_latency_when_urgent_uclk_cycles = 72,
.average_latency_when_urgent_uclk_cycles = 72,
.maximum_latency_when_non_urgent_uclk_cycles = 827,
.average_latency_when_non_urgent_uclk_cycles = 117,
},
{
// State 2
.minimum_uclk_khz = 0,
.urgent_ramp_uclk_cycles = 546,
.trip_to_memory_uclk_cycles = 848,
.meta_trip_to_memory_uclk_cycles = 848,
.maximum_latency_when_urgent_uclk_cycles = 146,
.average_latency_when_urgent_uclk_cycles = 146,
.maximum_latency_when_non_urgent_uclk_cycles = 848,
.average_latency_when_non_urgent_uclk_cycles = 133,
},
{
// State 3
.minimum_uclk_khz = 0,
.urgent_ramp_uclk_cycles = 564,
.trip_to_memory_uclk_cycles = 853,
.meta_trip_to_memory_uclk_cycles = 853,
.maximum_latency_when_urgent_uclk_cycles = 164,
.average_latency_when_urgent_uclk_cycles = 164,
.maximum_latency_when_non_urgent_uclk_cycles = 853,
.average_latency_when_non_urgent_uclk_cycles = 136,
},
{
// State 4
.minimum_uclk_khz = 0,
.urgent_ramp_uclk_cycles = 613,
.trip_to_memory_uclk_cycles = 869,
.meta_trip_to_memory_uclk_cycles = 869,
.maximum_latency_when_urgent_uclk_cycles = 213,
.average_latency_when_urgent_uclk_cycles = 213,
.maximum_latency_when_non_urgent_uclk_cycles = 869,
.average_latency_when_non_urgent_uclk_cycles = 149,
},
{
// State 5
.minimum_uclk_khz = 0,
.urgent_ramp_uclk_cycles = 632,
.trip_to_memory_uclk_cycles = 874,
.meta_trip_to_memory_uclk_cycles = 874,
.maximum_latency_when_urgent_uclk_cycles = 232,
.average_latency_when_urgent_uclk_cycles = 232,
.maximum_latency_when_non_urgent_uclk_cycles = 874,
.average_latency_when_non_urgent_uclk_cycles = 153,
},
{
// State 6
.minimum_uclk_khz = 0,
.urgent_ramp_uclk_cycles = 665,
.trip_to_memory_uclk_cycles = 885,
.meta_trip_to_memory_uclk_cycles = 885,
.maximum_latency_when_urgent_uclk_cycles = 265,
.average_latency_when_urgent_uclk_cycles = 265,
.maximum_latency_when_non_urgent_uclk_cycles = 885,
.average_latency_when_non_urgent_uclk_cycles = 161,
},
{
// State 7
.minimum_uclk_khz = 0,
.urgent_ramp_uclk_cycles = 689,
.trip_to_memory_uclk_cycles = 895,
.meta_trip_to_memory_uclk_cycles = 895,
.maximum_latency_when_urgent_uclk_cycles = 289,
.average_latency_when_urgent_uclk_cycles = 289,
.maximum_latency_when_non_urgent_uclk_cycles = 895,
.average_latency_when_non_urgent_uclk_cycles = 167,
},
{
// State 8
.minimum_uclk_khz = 0,
.urgent_ramp_uclk_cycles = 716,
.trip_to_memory_uclk_cycles = 902,
.meta_trip_to_memory_uclk_cycles = 902,
.maximum_latency_when_urgent_uclk_cycles = 316,
.average_latency_when_urgent_uclk_cycles = 316,
.maximum_latency_when_non_urgent_uclk_cycles = 902,
.average_latency_when_non_urgent_uclk_cycles = 174,
},
.dcn32x = {
.loaded_round_trip_latency_fclk_cycles = 106,
.urgent_latency_us = {
.base_latency_us = 4,
.base_latency_pixel_vm_us = 4,
.base_latency_vm_us = 4,
.scaling_factor_fclk_us = 0,
.scaling_factor_mhz = 0,
},
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
},
},
.qos_type = dml2_qos_param_type_dcn4x,
.qos_type = dml2_qos_param_type_dcn3,
},
.power_management_parameters = {
.dram_clk_change_blackout_us = 11.72,
.dram_clk_change_blackout_us = 29,
.fclk_change_blackout_us = 0,
.g7_ppt_blackout_us = 0,
.stutter_enter_plus_exit_latency_us = 11,
@@ -293,9 +195,9 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.z8_stutter_exit_latency_us = 200,
},
.vmin_limit = {
.dispclk_khz = 600 * 1000,
},
.vmin_limit = {
.dispclk_khz = 632 * 1000,
},
.dprefclk_mhz = 600,
.xtalclk_mhz = 24,
@@ -307,6 +209,8 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.return_bus_width_bytes = 64,
.hostvm_min_page_size_kbytes = 4,
.gpuvm_min_page_size_kbytes = 256,
.gpuvm_max_page_table_levels = 1,
.hostvm_max_non_cached_page_table_levels = 2,
.phy_downspread_percent = 0.38,
.dcn_downspread_percent = 0.38,
.dispclk_dppclk_vco_speed_mhz = 3000,
@@ -27,6 +27,19 @@ enum dml2_swizzle_mode {
dml2_gfx11_sw_256kb_d_x,
dml2_gfx11_sw_256kb_r_x,
dml2_sw_linear_256b, // GFX10 SW_LINEAR only accepts 256 byte aligned pitch
dml2_gfx10_sw_64kb_r_x,
dml2_gfx102_sw_64kb_s,
dml2_gfx102_sw_64kb_s_t,
dml2_gfx102_sw_64kb_s_x,
dml2_gfx102_sw_64kb_r_x,
dml2_linear_64elements, // GFX7 LINEAR_ALIGNED accepts pitch alignment of the maximum of 64 elements or 256 bytes
dml2_gfx7_1d_thin,
dml2_gfx7_2d_thin_gen_zero,
dml2_gfx7_2d_thin_gen_one,
dml2_gfx7_2d_thin_arlene,
dml2_gfx7_2d_thin_anubis
};
enum dml2_source_format_class {
@@ -19,6 +19,7 @@ enum dml2_project_id {
dml2_project_dcn4x_stage1,
dml2_project_dcn4x_stage2,
dml2_project_dcn4x_stage2_auto_drr_svp,
dml2_project_dcn40,
dml2_project_dcn42,
};
@@ -80,6 +81,7 @@ struct dml2_options {
struct dml2_pmo_options pmo_options;
};
struct dml2_initialize_instance_in_out {
struct dml2_instance *dml2_instance;
struct dml2_options options;
@@ -21,6 +21,7 @@ bool dml2_core_create(enum dml2_project_id project_id, struct dml2_core_instance
case dml2_project_dcn4x_stage1:
result = false;
break;
case dml2_project_dcn40:
case dml2_project_dcn4x_stage2:
case dml2_project_dcn4x_stage2_auto_drr_svp:
out->initialize = &core_dcn4_initialize;

Some files were not shown because too many files have changed in this diff Show More