diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
21 files changed, 225 insertions, 71 deletions
| diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index c9aede2f783d..8f8a13c7cf73 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2697,7 +2697,8 @@ void dc_commit_updates_for_stream(struct dc *dc,  		struct dc_surface_update *srf_updates,  		int surface_count,  		struct dc_stream_state *stream, -		struct dc_stream_update *stream_update) +		struct dc_stream_update *stream_update, +		struct dc_state *state)  {  	const struct dc_stream_status *stream_status;  	enum surface_update_type update_type; @@ -2716,12 +2717,6 @@ void dc_commit_updates_for_stream(struct dc *dc,  	if (update_type >= UPDATE_TYPE_FULL) { -		struct dc_plane_state *new_planes[MAX_SURFACES]; - -		memset(new_planes, 0, sizeof(new_planes)); - -		for (i = 0; i < surface_count; i++) -			new_planes[i] = srf_updates[i].surface;  		/* initialize scratch memory for building context */  		context = dc_create_state(dc); @@ -2730,21 +2725,15 @@ void dc_commit_updates_for_stream(struct dc *dc,  			return;  		} -		dc_resource_state_copy_construct( -				dc->current_state, context); +		dc_resource_state_copy_construct(state, context); -		/*remove old surfaces from context */ -		if (!dc_rem_all_planes_for_stream(dc, stream, context)) { -			DC_ERROR("Failed to remove streams for new validate context!\n"); -			return; -		} +		for (i = 0; i < dc->res_pool->pipe_count; i++) { +			struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; +			struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; -		/* add surface to context */ -		if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) { -			DC_ERROR("Failed to add streams for new validate context!\n"); -			return; +			if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) +				new_pipe->plane_state->force_full_update = true;  		} -  	} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index fa5059f71727..bd0101013ec8 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2602,7 +2602,6 @@ bool dc_link_set_backlight_level(const struct dc_link *link,  			if (pipe_ctx->plane_state == NULL)  				frame_ramp = 0;  		} else { -			ASSERT(false);  			return false;  		} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 4eee3a55fa30..18ed0d3f247e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -887,6 +887,7 @@ struct dc_plane_state {  	int layer_index;  	union surface_update_flags update_flags; +	bool flip_int_enabled;  	/* private to DC core */  	struct dc_plane_status status;  	struct dc_context *ctx; diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index a4f7ec888c67..80b67b860091 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -294,7 +294,8 @@ void dc_commit_updates_for_stream(struct dc *dc,  		struct dc_surface_update *srf_updates,  		int surface_count,  		struct dc_stream_state *stream, -		struct dc_stream_update *stream_update); +		struct dc_stream_update *stream_update, +		struct dc_state *state);  /*   * Log the current stream state.   */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index 9e796dfeac20..714c71a5fbde 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -1257,6 +1257,16 @@ void hubp1_soft_reset(struct hubp *hubp, bool reset)  	REG_UPDATE(DCHUBP_CNTL, HUBP_DISABLE, reset ? 1 : 0);  } +void hubp1_set_flip_int(struct hubp *hubp) +{ +	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); + +	REG_UPDATE(DCSURF_SURFACE_FLIP_INTERRUPT, +		SURFACE_FLIP_INT_MASK, 1); + +	return; +} +  void hubp1_init(struct hubp *hubp)  {  	//do nothing @@ -1290,6 +1300,7 @@ static const struct hubp_funcs dcn10_hubp_funcs = {  	.dmdata_load = NULL,  	.hubp_soft_reset = hubp1_soft_reset,  	.hubp_in_blank = hubp1_in_blank, +	.hubp_set_flip_int = hubp1_set_flip_int,  };  /*****************************************/ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h index a9a6ed7f4f99..e2f2f6995935 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h @@ -74,6 +74,7 @@  	SRI(DCSURF_SURFACE_EARLIEST_INUSE_C, HUBPREQ, id),\  	SRI(DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C, HUBPREQ, id),\  	SRI(DCSURF_SURFACE_CONTROL, HUBPREQ, id),\ +	SRI(DCSURF_SURFACE_FLIP_INTERRUPT, HUBPREQ, id),\  	SRI(HUBPRET_CONTROL, HUBPRET, id),\  	SRI(DCN_EXPANSION_MODE, HUBPREQ, id),\  	SRI(DCHUBP_REQ_SIZE_CONFIG, HUBP, id),\ @@ -183,6 +184,7 @@  	uint32_t DCSURF_SURFACE_EARLIEST_INUSE_C; \  	uint32_t DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C; \  	uint32_t DCSURF_SURFACE_CONTROL; \ +	uint32_t DCSURF_SURFACE_FLIP_INTERRUPT; \  	uint32_t HUBPRET_CONTROL; \  	uint32_t DCN_EXPANSION_MODE; \  	uint32_t DCHUBP_REQ_SIZE_CONFIG; \ @@ -332,6 +334,7 @@  	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_META_SURFACE_TMZ_C, mask_sh),\  	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_EN, mask_sh),\  	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\ +	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK, mask_sh),\  	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\  	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\  	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\ @@ -531,6 +534,7 @@  	type PRIMARY_SURFACE_DCC_IND_64B_BLK;\  	type SECONDARY_SURFACE_DCC_EN;\  	type SECONDARY_SURFACE_DCC_IND_64B_BLK;\ +	type SURFACE_FLIP_INT_MASK;\  	type DET_BUF_PLANE1_BASE_ADDRESS;\  	type CROSSBAR_SRC_CB_B;\  	type CROSSBAR_SRC_CR_R;\ @@ -777,4 +781,6 @@ void hubp1_read_state_common(struct hubp *hubp);  bool hubp1_in_blank(struct hubp *hubp);  void hubp1_soft_reset(struct hubp *hubp, bool reset); +void hubp1_set_flip_int(struct hubp *hubp); +  #endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 89912bb5014f..9ba5c624770d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2196,6 +2196,13 @@ static void dcn10_enable_plane(  	if (dc->debug.sanity_checks) {  		hws->funcs.verify_allow_pstate_change_high(dc);  	} + +	if (!pipe_ctx->top_pipe +		&& pipe_ctx->plane_state +		&& pipe_ctx->plane_state->flip_int_enabled +		&& pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int) +			pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp); +  }  void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index 59024653430c..e4701825b5a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c @@ -480,7 +480,6 @@ unsigned int dcn10_get_dig_frontend(struct link_encoder *enc)  		break;  	default:  		// invalid source select DIG -		ASSERT(false);  		result = ENGINE_ID_UNKNOWN;  	} diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c index 0df0da2e6a4d..bec7059f6d5d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c @@ -1597,6 +1597,7 @@ static struct hubp_funcs dcn20_hubp_funcs = {  	.validate_dml_output = hubp2_validate_dml_output,  	.hubp_in_blank = hubp1_in_blank,  	.hubp_soft_reset = hubp1_soft_reset, +	.hubp_set_flip_int = hubp1_set_flip_int,  }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 0726fb435e2a..aece1103331d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1146,6 +1146,12 @@ void dcn20_enable_plane(  		pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);  	} +	if (!pipe_ctx->top_pipe +		&& pipe_ctx->plane_state +		&& pipe_ctx->plane_state->flip_int_enabled +		&& pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int) +			pipe_ctx->plane_res.hubp->funcs->hubp_set_flip_int(pipe_ctx->plane_res.hubp); +  //	if (dc->debug.sanity_checks) {  //		dcn10_verify_allow_pstate_change_high(dc);  //	} @@ -1501,38 +1507,8 @@ static void dcn20_update_dchubp_dpp(  	if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed  			|| pipe_ctx->stream->update_flags.bits.gamut_remap  			|| pipe_ctx->stream->update_flags.bits.out_csc) { -		struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; - -		if (mpc->funcs->set_gamut_remap) { -			int i; -			int mpcc_id = hubp->inst; -			struct mpc_grph_gamut_adjustment adjust; -			bool enable_remap_dpp = false; - -			memset(&adjust, 0, sizeof(adjust)); -			adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; - -			/* save the enablement of gamut remap for dpp */ -			enable_remap_dpp = pipe_ctx->stream->gamut_remap_matrix.enable_remap; - -			/* force bypass gamut remap for dpp/cm */ -			pipe_ctx->stream->gamut_remap_matrix.enable_remap = false; -			dc->hwss.program_gamut_remap(pipe_ctx); - -			/* restore gamut remap flag and use this remap into mpc */ -			pipe_ctx->stream->gamut_remap_matrix.enable_remap = enable_remap_dpp; - -			/* build remap matrix for top plane if enabled */ -			if (enable_remap_dpp && pipe_ctx->top_pipe == NULL) { -					adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; -					for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) -						adjust.temperature_matrix[i] = -								pipe_ctx->stream->gamut_remap_matrix.matrix[i]; -			} -			mpc->funcs->set_gamut_remap(mpc, mpcc_id, &adjust); -		} else -			/* dpp/cm gamut remap*/ -			dc->hwss.program_gamut_remap(pipe_ctx); +		/* dpp/cm gamut remap*/ +		dc->hwss.program_gamut_remap(pipe_ctx);  		/*call the dcn2 method which uses mpc csc*/  		dc->hwss.program_output_csc(dc, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c index fa013496e26b..2f9bfaeaba8d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c @@ -341,8 +341,7 @@ void enc2_hw_init(struct link_encoder *enc)  	} else {  		AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110); -		AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c4d); - +		AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a);  	}  	//AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32; diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index f9045852728f..b0c9180b808f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -838,6 +838,7 @@ static struct hubp_funcs dcn21_hubp_funcs = {  	.hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,  	.hubp_init = hubp21_init,  	.validate_dml_output = hubp21_validate_dml_output, +	.hubp_set_flip_int = hubp1_set_flip_int,  };  bool hubp21_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index 072f8c880924..4a3df13c9e49 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -296,7 +296,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {  	.num_banks = 8,  	.num_chans = 4,  	.vmm_page_size_bytes = 4096, -	.dram_clock_change_latency_us = 11.72, +	.dram_clock_change_latency_us = 23.84,  	.return_bus_width_bytes = 64,  	.dispclk_dppclk_vco_speed_mhz = 3600,  	.xfc_bus_transport_time_us = 4, @@ -1062,8 +1062,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s  {  	int i; -	DC_FP_START(); -  	if (dc->bb_overrides.sr_exit_time_ns) {  		for (i = 0; i < WM_SET_COUNT; i++) {  			  dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us = @@ -1088,8 +1086,6 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s  				dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;  		}  	} - -	DC_FP_END();  }  void dcn21_calculate_wm( @@ -1339,7 +1335,7 @@ static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc,  	int vlevel = 0;  	int pipe_split_from[MAX_PIPES];  	int pipe_cnt = 0; -	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); +	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);  	DC_LOGGER_INIT(dc->ctx->logger);  	BW_VAL_TRACE_COUNT(); @@ -1599,6 +1595,11 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param  	dcn2_1_soc.num_chans = bw_params->num_channels;  	ASSERT(clk_table->num_entries); +	/* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */ +	for (i = 0; i < dcn2_1_soc.num_states + 1; i++) { +		clock_limits[i] = dcn2_1_soc.clock_limits[i]; +	} +  	for (i = 0; i < clk_table->num_entries; i++) {  		/* loop backwards*/  		for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c index 41a1d0e9b7e2..e0df9b0065f9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c @@ -113,6 +113,7 @@ bool cm3_helper_translate_curve_to_hw_format(  	struct pwl_result_data *rgb_resulted;  	struct pwl_result_data *rgb;  	struct pwl_result_data *rgb_plus_1; +	struct pwl_result_data *rgb_minus_1;  	struct fixed31_32 end_value;  	int32_t region_start, region_end; @@ -140,7 +141,7 @@ bool cm3_helper_translate_curve_to_hw_format(  		region_start = -MAX_LOW_POINT;  		region_end   = NUMBER_REGIONS - MAX_LOW_POINT;  	} else { -		/* 10 segments +		/* 11 segments  		 * segment is from 2^-10 to 2^0  		 * There are less than 256 points, for optimization  		 */ @@ -154,9 +155,10 @@ bool cm3_helper_translate_curve_to_hw_format(  		seg_distr[7] = 4;  		seg_distr[8] = 4;  		seg_distr[9] = 4; +		seg_distr[10] = 1;  		region_start = -10; -		region_end = 0; +		region_end = 1;  	}  	for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) @@ -189,6 +191,10 @@ bool cm3_helper_translate_curve_to_hw_format(  	rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];  	rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; +	rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red; +	rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green; +	rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue; +  	// All 3 color channels have same x  	corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),  					     dc_fixpt_from_int(region_start)); @@ -259,15 +265,18 @@ bool cm3_helper_translate_curve_to_hw_format(  	rgb = rgb_resulted;  	rgb_plus_1 = rgb_resulted + 1; +	rgb_minus_1 = rgb;  	i = 1;  	while (i != hw_points + 1) { -		if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) -			rgb_plus_1->red = rgb->red; -		if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) -			rgb_plus_1->green = rgb->green; -		if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) -			rgb_plus_1->blue = rgb->blue; +		if (i >= hw_points - 1) { +			if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) +				rgb_plus_1->red = dc_fixpt_add(rgb->red, rgb_minus_1->delta_red); +			if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) +				rgb_plus_1->green = dc_fixpt_add(rgb->green, rgb_minus_1->delta_green); +			if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) +				rgb_plus_1->blue = dc_fixpt_add(rgb->blue, rgb_minus_1->delta_blue); +		}  		rgb->delta_red   = dc_fixpt_sub(rgb_plus_1->red,   rgb->red);  		rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); @@ -283,6 +292,7 @@ bool cm3_helper_translate_curve_to_hw_format(  		}  		++rgb_plus_1; +		rgb_minus_1 = rgb;  		++rgb;  		++i;  	} diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c index 88ffa9ff1ed1..f24612523248 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c @@ -511,6 +511,7 @@ static struct hubp_funcs dcn30_hubp_funcs = {  	.hubp_init = hubp3_init,  	.hubp_in_blank = hubp1_in_blank,  	.hubp_soft_reset = hubp1_soft_reset, +	.hubp_set_flip_int = hubp1_set_flip_int,  };  bool hubp3_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h index 705fbfc37502..8a32772d4e91 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h @@ -134,6 +134,7 @@  	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_EN, mask_sh),\  	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_BLK, mask_sh),\  	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_BLK_C, mask_sh),\ +	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK, mask_sh),\  	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\  	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\  	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 9620fb8a27dc..06dc1e2e8383 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -539,6 +539,8 @@ void dcn30_init_hw(struct dc *dc)  					fe = dc->links[i]->link_enc->funcs->get_dig_frontend(  										dc->links[i]->link_enc); +					if (fe == ENGINE_ID_UNKNOWN) +						continue;  					for (j = 0; j < dc->res_pool->stream_enc_count; j++) {  						if (fe == dc->res_pool->stream_enc[j]->id) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 8d0f663489ac..fb7f1dea3c46 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -2508,6 +2508,19 @@ static const struct resource_funcs dcn30_res_pool_funcs = {  	.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,  }; +#define CTX ctx + +#define REG(reg_name) \ +	(DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) + +static uint32_t read_pipe_fuses(struct dc_context *ctx) +{ +	uint32_t value = REG_READ(CC_DC_PIPE_DIS); +	/* Support for max 6 pipes */ +	value = value & 0x3f; +	return value; +} +  static bool dcn30_resource_construct(  	uint8_t num_virtual_links,  	struct dc *dc, @@ -2517,6 +2530,15 @@ static bool dcn30_resource_construct(  	struct dc_context *ctx = dc->ctx;  	struct irq_service_init_data init_data;  	struct ddc_service_init_data ddc_init_data; +	uint32_t pipe_fuses = read_pipe_fuses(ctx); +	uint32_t num_pipes = 0; + +	if (!(pipe_fuses == 0 || pipe_fuses == 0x3e)) { +		BREAK_TO_DEBUGGER(); +		dm_error("DC: Unexpected fuse recipe for navi2x !\n"); +		/* fault to single pipe */ +		pipe_fuses = 0x3e; +	}  	DC_FP_START(); @@ -2650,6 +2672,15 @@ static bool dcn30_resource_construct(  	/* PP Lib and SMU interfaces */  	init_soc_bounding_box(dc, pool); +	num_pipes = dcn3_0_ip.max_num_dpp; + +	for (i = 0; i < dcn3_0_ip.max_num_dpp; i++) +		if (pipe_fuses & 1 << i) +			num_pipes--; + +	dcn3_0_ip.max_num_dpp = num_pipes; +	dcn3_0_ip.max_num_otg = num_pipes; +  	dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30);  	/* IRQ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c index 5d4b2c60192e..c494235016e0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c @@ -1619,12 +1619,106 @@ static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *b  	dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30);  } +static void calculate_wm_set_for_vlevel( +		int vlevel, +		struct wm_range_table_entry *table_entry, +		struct dcn_watermarks *wm_set, +		struct display_mode_lib *dml, +		display_e2e_pipe_params_st *pipes, +		int pipe_cnt) +{ +	double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us; + +	ASSERT(vlevel < dml->soc.num_states); +	/* only pipe 0 is read for voltage and dcf/soc clocks */ +	pipes[0].clks_cfg.voltage = vlevel; +	pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz; +	pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz; + +	dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us; +	dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us; +	dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us; + +	wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000; +	wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000; +	wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000; +	wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000; +	wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000; +	wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000; +	wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000; +	wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000; +	dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached; + +} + +static void dcn301_calculate_wm_and_dlg( +		struct dc *dc, struct dc_state *context, +		display_e2e_pipe_params_st *pipes, +		int pipe_cnt, +		int vlevel_req) +{ +	int i, pipe_idx; +	int vlevel, vlevel_max; +	struct wm_range_table_entry *table_entry; +	struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; + +	ASSERT(bw_params); + +	vlevel_max = bw_params->clk_table.num_entries - 1; + +	/* WM Set D */ +	table_entry = &bw_params->wm_table.entries[WM_D]; +	if (table_entry->wm_type == WM_TYPE_RETRAINING) +		vlevel = 0; +	else +		vlevel = vlevel_max; +	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d, +						&context->bw_ctx.dml, pipes, pipe_cnt); +	/* WM Set C */ +	table_entry = &bw_params->wm_table.entries[WM_C]; +	vlevel = min(max(vlevel_req, 2), vlevel_max); +	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, +						&context->bw_ctx.dml, pipes, pipe_cnt); +	/* WM Set B */ +	table_entry = &bw_params->wm_table.entries[WM_B]; +	vlevel = min(max(vlevel_req, 1), vlevel_max); +	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, +						&context->bw_ctx.dml, pipes, pipe_cnt); + +	/* WM Set A */ +	table_entry = &bw_params->wm_table.entries[WM_A]; +	vlevel = min(vlevel_req, vlevel_max); +	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a, +						&context->bw_ctx.dml, pipes, pipe_cnt); + +	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { +		if (!context->res_ctx.pipe_ctx[i].stream) +			continue; + +		pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); +		pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); + +		if (dc->config.forced_clocks) { +			pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; +			pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; +		} +		if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) +			pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; +		if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) +			pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; + +		pipe_idx++; +	} + +	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); +} +  static struct resource_funcs dcn301_res_pool_funcs = {  	.destroy = dcn301_destroy_resource_pool,  	.link_enc_create = dcn301_link_encoder_create,  	.panel_cntl_create = dcn301_panel_cntl_create,  	.validate_bandwidth = dcn30_validate_bandwidth, -	.calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg, +	.calculate_wm_and_dlg = dcn301_calculate_wm_and_dlg,  	.populate_dml_pipes = dcn30_populate_dml_pipes_from_context,  	.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,  	.add_stream_to_ctx = dcn30_add_stream_to_ctx, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index 22f3f643ed1b..346dcd87dc10 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -191,6 +191,8 @@ struct hubp_funcs {  	bool (*hubp_in_blank)(struct hubp *hubp);  	void (*hubp_soft_reset)(struct hubp *hubp, bool reset); +	void (*hubp_set_flip_int)(struct hubp *hubp); +  };  #endif diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c index 1b971265418b..0e0f494fbb5e 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c @@ -168,6 +168,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = {  	.ack = NULL  }; +static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { +	.set = NULL, +	.ack = NULL +}; +  #undef BASE_INNER  #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg @@ -230,6 +235,17 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = {  		.funcs = &vblank_irq_info_funcs\  	} +/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic + * of DCE's DC_IRQ_SOURCE_VUPDATEx. + */ +#define vupdate_no_lock_int_entry(reg_num)\ +	[DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ +		IRQ_REG_ENTRY(OTG, reg_num,\ +			OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ +			OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ +		.funcs = &vupdate_no_lock_irq_info_funcs\ +	} +  #define vblank_int_entry(reg_num)\  	[DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\  		IRQ_REG_ENTRY(OTG, reg_num,\ @@ -338,6 +354,12 @@ irq_source_info_dcn21[DAL_IRQ_SOURCES_NUMBER] = {  	vupdate_int_entry(3),  	vupdate_int_entry(4),  	vupdate_int_entry(5), +	vupdate_no_lock_int_entry(0), +	vupdate_no_lock_int_entry(1), +	vupdate_no_lock_int_entry(2), +	vupdate_no_lock_int_entry(3), +	vupdate_no_lock_int_entry(4), +	vupdate_no_lock_int_entry(5),  	vblank_int_entry(0),  	vblank_int_entry(1),  	vblank_int_entry(2), | 
