Commit de534c1c authored by Mike Hsieh's avatar Mike Hsieh Committed by Alex Deucher
Browse files

drm/amd/display: Add height granularity limitation for dsc slice height calculation



[WHY]
eDP add new limitation for Y granularity for selected update feature.
DSC does not include this limitation while calculating slice height.

[HOW]
Add new limitation while looking for DSC slice height.

Reviewed-by: default avatarCruise Hung <Cruise.Hung@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarMike Hsieh <Mike.Hsieh@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2d51f3af
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -5786,6 +5786,10 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
	struct dc *dc = sink->ctx->dc;
	struct dc_dsc_bw_range bw_range = {0};
	struct dc_dsc_config dsc_cfg = {0};
	struct dc_dsc_config_options dsc_options = {0};

	dc_dsc_get_default_config_option(dc, &dsc_options);
	dsc_options.max_target_bpp_limit_override_x16 = max_dsc_target_bpp_limit_override * 16;

	verified_link_cap = dc_link_get_link_cap(stream->link);
	link_bw_in_kbps = dc_link_bandwidth_kbps(stream->link, verified_link_cap);
@@ -5808,8 +5812,7 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
		if (bw_range.max_kbps < link_bw_in_kbps) {
			if (dc_dsc_compute_config(dc->res_pool->dscs[0],
					dsc_caps,
					dc->debug.dsc_min_slice_height_override,
					max_dsc_target_bpp_limit_override,
					&dsc_options,
					0,
					&stream->timing,
					&dsc_cfg)) {
@@ -5823,8 +5826,7 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,

	if (dc_dsc_compute_config(dc->res_pool->dscs[0],
				dsc_caps,
				dc->debug.dsc_min_slice_height_override,
				max_dsc_target_bpp_limit_override,
				&dsc_options,
				link_bw_in_kbps,
				&stream->timing,
				&dsc_cfg)) {
@@ -5845,6 +5847,10 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
	u32 dsc_max_supported_bw_in_kbps;
	u32 max_dsc_target_bpp_limit_override =
		drm_connector->display_info.max_dsc_bpp;
	struct dc_dsc_config_options dsc_options = {0};

	dc_dsc_get_default_config_option(dc, &dsc_options);
	dsc_options.max_target_bpp_limit_override_x16 = max_dsc_target_bpp_limit_override * 16;

	link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
							dc_link_get_link_cap(aconnector->dc_link));
@@ -5863,8 +5869,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
		if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) {
			if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
						dsc_caps,
						aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
						max_dsc_target_bpp_limit_override,
						&dsc_options,
						link_bandwidth_kbps,
						&stream->timing,
						&stream->timing.dsc_cfg)) {
@@ -5881,8 +5886,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
					dsc_max_supported_bw_in_kbps > 0)
				if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
						dsc_caps,
						aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
						max_dsc_target_bpp_limit_override,
						&dsc_options,
						dsc_max_supported_bw_in_kbps,
						&stream->timing,
						&stream->timing.dsc_cfg)) {
+10 −6
Original line number Diff line number Diff line
@@ -678,16 +678,19 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
{
	struct drm_connector *drm_connector;
	int i;
	struct dc_dsc_config_options dsc_options = {0};

	for (i = 0; i < count; i++) {
		drm_connector = &params[i].aconnector->base;

		dc_dsc_get_default_config_option(params[i].sink->ctx->dc, &dsc_options);
		dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;

		memset(&params[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg));
		if (vars[i + k].dsc_enabled && dc_dsc_compute_config(
					params[i].sink->ctx->dc->res_pool->dscs[0],
					&params[i].sink->dsc_caps.dsc_dec_caps,
					params[i].sink->ctx->dc->debug.dsc_min_slice_height_override,
					drm_connector->display_info.max_dsc_bpp,
					&dsc_options,
					0,
					params[i].timing,
					&params[i].timing->dsc_cfg)) {
@@ -730,15 +733,16 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn)
	u64 kbps;

	struct drm_connector *drm_connector = &param.aconnector->base;
	uint32_t max_dsc_target_bpp_limit_override =
		drm_connector->display_info.max_dsc_bpp;
	struct dc_dsc_config_options dsc_options = {0};

	dc_dsc_get_default_config_option(param.sink->ctx->dc, &dsc_options);
	dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;

	kbps = div_u64((u64)pbn * 994 * 8 * 54, 64);
	dc_dsc_compute_config(
			param.sink->ctx->dc->res_pool->dscs[0],
			&param.sink->dsc_caps.dsc_dec_caps,
			param.sink->ctx->dc->debug.dsc_min_slice_height_override,
			max_dsc_target_bpp_limit_override,
			&dsc_options,
			(int) kbps, param.timing, &dsc_config);

	return dsc_config.bits_per_pixel;
+9 −2
Original line number Diff line number Diff line
@@ -54,6 +54,12 @@ struct dc_dsc_policy {
	bool enable_dsc_when_not_needed;
};

struct dc_dsc_config_options {
	uint32_t dsc_min_slice_height_override;
	uint32_t max_target_bpp_limit_override_x16;
	uint32_t slight_height_granularity;
};

bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
		const uint8_t *dpcd_dsc_basic_data,
		const uint8_t *dpcd_dsc_ext_data,
@@ -71,8 +77,7 @@ bool dc_dsc_compute_bandwidth_range(
bool dc_dsc_compute_config(
		const struct display_stream_compressor *dsc,
		const struct dsc_dec_dpcd_caps *dsc_sink_caps,
		uint32_t dsc_min_slice_height_override,
		uint32_t max_target_bpp_limit_override,
		const struct dc_dsc_config_options *options,
		uint32_t target_bandwidth_kbps,
		const struct dc_crtc_timing *timing,
		struct dc_dsc_config *dsc_cfg);
@@ -100,4 +105,6 @@ void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable);

void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable);

void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options);

#endif
+21 −12
Original line number Diff line number Diff line
@@ -79,8 +79,7 @@ static bool setup_dsc_config(
		const struct dsc_enc_caps *dsc_enc_caps,
		int target_bandwidth_kbps,
		const struct dc_crtc_timing *timing,
		int min_slice_height_override,
		int max_dsc_target_bpp_limit_override_x16,
		const struct dc_dsc_config_options *options,
		struct dc_dsc_config *dsc_cfg);

static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size)
@@ -352,6 +351,11 @@ bool dc_dsc_compute_bandwidth_range(
	struct dsc_enc_caps dsc_enc_caps;
	struct dsc_enc_caps dsc_common_caps;
	struct dc_dsc_config config;
	struct dc_dsc_config_options options = {0};

	options.dsc_min_slice_height_override = dsc_min_slice_height_override;
	options.max_target_bpp_limit_override_x16 = max_bpp_x16;
	options.slight_height_granularity = 1;

	get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz);

@@ -360,7 +364,7 @@ bool dc_dsc_compute_bandwidth_range(

	if (is_dsc_possible)
		is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing,
				dsc_min_slice_height_override, max_bpp_x16, &config);
				&options, &config);

	if (is_dsc_possible)
		is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16,
@@ -740,8 +744,7 @@ static bool setup_dsc_config(
		const struct dsc_enc_caps *dsc_enc_caps,
		int target_bandwidth_kbps,
		const struct dc_crtc_timing *timing,
		int min_slice_height_override,
		int max_dsc_target_bpp_limit_override_x16,
		const struct dc_dsc_config_options *options,
		struct dc_dsc_config *dsc_cfg)
{
	struct dsc_enc_caps dsc_common_caps;
@@ -760,7 +763,7 @@ static bool setup_dsc_config(

	memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));

	dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override_x16, &policy);
	dc_dsc_get_policy_for_timing(timing, options->max_target_bpp_limit_override_x16, &policy);
	pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right;
	pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;

@@ -909,12 +912,13 @@ static bool setup_dsc_config(

	// Slice height (i.e. number of slices per column): start with policy and pick the first one that height is divisible by.
	// For 4:2:0 make sure the slice height is divisible by 2 as well.
	if (min_slice_height_override == 0)
	if (options->dsc_min_slice_height_override == 0)
		slice_height = min(policy.min_slice_height, pic_height);
	else
		slice_height = min(min_slice_height_override, pic_height);
		slice_height = min((int)(options->dsc_min_slice_height_override), pic_height);

	while (slice_height < pic_height && (pic_height % slice_height != 0 ||
		slice_height % options->slight_height_granularity != 0 ||
		(timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 && slice_height % 2 != 0)))
		slice_height++;

@@ -958,8 +962,7 @@ static bool setup_dsc_config(
bool dc_dsc_compute_config(
		const struct display_stream_compressor *dsc,
		const struct dsc_dec_dpcd_caps *dsc_sink_caps,
		uint32_t dsc_min_slice_height_override,
		uint32_t max_target_bpp_limit_override,
		const struct dc_dsc_config_options *options,
		uint32_t target_bandwidth_kbps,
		const struct dc_crtc_timing *timing,
		struct dc_dsc_config *dsc_cfg)
@@ -971,8 +974,7 @@ bool dc_dsc_compute_config(
	is_dsc_possible = setup_dsc_config(dsc_sink_caps,
		&dsc_enc_caps,
		target_bandwidth_kbps,
		timing, dsc_min_slice_height_override,
		max_target_bpp_limit_override * 16, dsc_cfg);
		timing, options, dsc_cfg);
	return is_dsc_possible;
}

@@ -1104,3 +1106,10 @@ void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable)
{
	dsc_policy_disable_dsc_stream_overhead = disable;
}

void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options)
{
	options->dsc_min_slice_height_override = dc->debug.dsc_min_slice_height_override;
	options->max_target_bpp_limit_override_x16 = 0;
	options->slight_height_granularity = 1;
}