Commit efaf1575 authored by Relja Vojvodic's avatar Relja Vojvodic Committed by Alex Deucher
Browse files

drm/amd/display: Add sharpness control interface



- Add interface for controlling shapness level input into DCN.
- Update SPL to support custom sharpness values.
- Add support for different sharpness values depending on YUV/RGB
  content.

Reviewed-by: default avatarSamson Tam <samson.tam@amd.com>
Signed-off-by: default avatarRelja Vojvodic <Relja.Vojvodic@amd.com>
Signed-off-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6e841094
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -2690,6 +2690,9 @@ static enum surface_update_type check_update_surfaces_for_stream(
				stream_update->vrr_active_variable || stream_update->vrr_active_fixed))
			su_flags->bits.fams_changed = 1;

		if (stream_update->scaler_sharpener_update)
			su_flags->bits.scaler_sharpener = 1;

		if (su_flags->raw != 0)
			overall_type = UPDATE_TYPE_FULL;

@@ -3022,6 +3025,8 @@ static void copy_stream_update_to_stream(struct dc *dc,
			update->dsc_config = NULL;
		}
	}
	if (update->scaler_sharpener_update)
		stream->scaler_sharpener_update = *update->scaler_sharpener_update;
}

static void backup_planes_and_stream_state(
@@ -4713,7 +4718,8 @@ static bool full_update_required(struct dc *dc,
			stream_update->func_shaper ||
			stream_update->lut3d_func ||
			stream_update->pending_test_pattern ||
			stream_update->crtc_timing_adjust))
			stream_update->crtc_timing_adjust ||
			stream_update->scaler_sharpener_update))
		return true;

	if (stream) {
+2 −1
Original line number Diff line number Diff line
@@ -1052,6 +1052,7 @@ struct dc_debug_options {
	unsigned int disable_spl;
	unsigned int force_easf;
	unsigned int force_sharpness;
	unsigned int force_sharpness_level;
	unsigned int force_lls;
	bool notify_dpia_hr_bw;
	bool enable_ips_visual_confirm;
@@ -1348,7 +1349,7 @@ struct dc_plane_state {
	enum mpcc_movable_cm_location mcm_location;
	struct dc_csc_transform cursor_csc_color_matrix;
	bool adaptive_sharpness_en;
	unsigned int sharpnessX1000;
	int sharpness_level;
	enum linear_light_scaling linear_light_scaling;
};

+29 −17
Original line number Diff line number Diff line
@@ -139,24 +139,36 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
	else if (pipe_ctx->stream->ctx->dc->debug.force_easf == 2)
		spl_in->disable_easf = true;
	/* Translate adaptive sharpening preference */
	if (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 0) {
		spl_in->adaptive_sharpness.enable = (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 1) ? true : false;
		if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 2)
			spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW;
		else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 3)
			spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID;
		else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness >= 4)
			spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
	} else {
		spl_in->adaptive_sharpness.enable = plane_state->adaptive_sharpness_en;
		if (plane_state->sharpnessX1000 == 0)
	unsigned int sharpness_setting = pipe_ctx->stream->ctx->dc->debug.force_sharpness;
	unsigned int force_sharpness_level = pipe_ctx->stream->ctx->dc->debug.force_sharpness_level;
	if (sharpness_setting == SHARPNESS_HW_OFF)
		spl_in->adaptive_sharpness.enable = false;
	else if (sharpness_setting == SHARPNESS_ZERO) {
		spl_in->adaptive_sharpness.enable = true;
		spl_in->adaptive_sharpness.sharpness_level = 0;
	} else if (sharpness_setting == SHARPNESS_CUSTOM) {
		spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_min = 0;
		spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_max = 1750;
		spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_mid = 750;
		spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_min = 0;
		spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_max = 3500;
		spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_mid = 1500;
		spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_min = 0;
		spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_max = 2750;
		spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_mid = 1500;

		if (force_sharpness_level > 0) {
			if (force_sharpness_level > 10)
				force_sharpness_level = 10;
			spl_in->adaptive_sharpness.enable = true;
			spl_in->adaptive_sharpness.sharpness_level = force_sharpness_level;
		} else if (!plane_state->adaptive_sharpness_en) {
			spl_in->adaptive_sharpness.enable = false;
		else if (plane_state->sharpnessX1000 < 999)
			spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW;
		else if (plane_state->sharpnessX1000 < 1999)
			spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID;
		else // Any other value is high sharpness
			spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
			spl_in->adaptive_sharpness.sharpness_level = 0;
		} else {
			spl_in->adaptive_sharpness.enable = true;
			spl_in->adaptive_sharpness.sharpness_level = plane_state->sharpness_level;
		}
	}
	// Translate linear light scaling preference
	if (pipe_ctx->stream->ctx->dc->debug.force_lls > 0)
+3 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ union stream_update_flags {
		uint32_t mst_bw : 1;
		uint32_t crtc_timing_adjust : 1;
		uint32_t fams_changed : 1;
		uint32_t scaler_sharpener : 1;
	} bits;

	uint32_t raw;
@@ -308,6 +309,7 @@ struct dc_stream_state {
	bool is_phantom;

	struct luminance_data lumin_data;
	bool scaler_sharpener_update;
};

#define ABM_LEVEL_IMMEDIATE_DISABLE 255
@@ -353,6 +355,7 @@ struct dc_stream_update {
	struct dc_cursor_attributes *cursor_attributes;
	struct dc_cursor_position *cursor_position;
	bool *hw_cursor_req;
	bool *scaler_sharpener_update;
};

bool dc_is_stream_unchanged(
+21 −3
Original line number Diff line number Diff line
@@ -957,6 +957,7 @@ static void dpp401_dscl_set_isharp_filter(
 */
static void dpp401_dscl_program_isharp(struct dpp *dpp_base,
		const struct scaler_data *scl_data,
		bool program_isharp_1dlut,
		bool *bs_coeffs_updated)
{
	struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
@@ -1015,6 +1016,7 @@ static void dpp401_dscl_program_isharp(struct dpp *dpp_base,
		ISHARP_LBA_PWL_BASE_SEG5, scl_data->dscl_prog_data.isharp_lba.base_seg[5]);

	/* ISHARP_DELTA_LUT */
	if (!program_isharp_1dlut)
		dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);

	/* ISHARP_NLDELTA_SOFT_CLIP */
@@ -1071,13 +1073,29 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
			dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
	bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
				&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
	bool program_isharp_1dlut = false;
	bool bs_coeffs_updated = false;


	if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
		return;

	PERF_TRACE();

	/* If only sharpness has changed, then only update 1dlut, then return */
	if (scl_data->dscl_prog_data.isharp_en &&
		(dpp->scl_data.dscl_prog_data.sharpness_level
		!= scl_data->dscl_prog_data.sharpness_level)) {
		/* ISHARP_DELTA_LUT */
		dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
		dpp->scl_data.dscl_prog_data.sharpness_level = scl_data->dscl_prog_data.sharpness_level;
		dpp->scl_data.dscl_prog_data.isharp_delta = scl_data->dscl_prog_data.isharp_delta;

		if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
			return;
		program_isharp_1dlut = true;
	}

	dpp->scl_data = *scl_data;

	if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
@@ -1131,7 +1149,7 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
	if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) {
		if (dpp->base.ctx->dc->config.prefer_easf)
			dpp401_dscl_disable_easf(dpp_base, scl_data);
		dpp401_dscl_program_isharp(dpp_base, scl_data, &bs_coeffs_updated);
		dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);
		return;
	}

@@ -1165,7 +1183,7 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
	 *   WB scaler coeffs and toggle coeff RAM together
	 */
	//if (dpp->base.ctx->dc->config.prefer_easf)
	dpp401_dscl_program_isharp(dpp_base, scl_data, &bs_coeffs_updated);
	dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);

	dpp401_dscl_set_scl_filter(dpp, scl_data, ycbcr, bs_coeffs_updated);
	/* Edge adaptive scaler function configuration */
Loading