Commit e56e3cff authored by Roman Li's avatar Roman Li Committed by Alex Deucher
Browse files

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: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: default avatarRoman Li <Roman.Li@amd.com>
Signed-off-by: default avatarAlex Hung <alex.hung@amd.com>
Tested-by: default avatarDan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6e5b72ac
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -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)
+76 −65
Original line number Diff line number Diff line
@@ -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,7 +704,6 @@ 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);
@@ -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 /
@@ -1120,12 +1134,12 @@ void dcn42_clk_mgr_construct(
				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 : 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 */
@@ -1133,9 +1147,6 @@ void dcn42_clk_mgr_construct(
		/* 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*/

+1 −1
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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 (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 (u->cm_hist_control) {
		update_flags->bits.cm_hist_change = 1;
		elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM);
	}

	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;
	}

	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;
	/* Shaper, 3DLUT, 1DLUT */
	if (srf_update->cm) {
		memcpy(&surface->cm, srf_update->cm,
				sizeof(surface->cm));
	}

	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 */
+32 −9
Original line number Diff line number Diff line
@@ -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,11 +436,17 @@ 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);
		if (enable_cursor_offload && dc->hwss.update_cursor_offload_pipe)
@@ -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;
	}
}

Loading