[PATCH 10/14] drm/amd/display: Add sharpness control interface

Hamza Mahfooz hamza.mahfooz at amd.com
Tue Aug 27 16:37:30 UTC 2024


From: Relja Vojvodic <Relja.Vojvodic at amd.com>

- 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: Samson Tam <samson.tam at amd.com>
Signed-off-by: Relja Vojvodic <Relja.Vojvodic at amd.com>
Signed-off-by: Hamza Mahfooz <hamza.mahfooz at amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |   8 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |   3 +-
 .../gpu/drm/amd/display/dc/dc_spl_translate.c |  46 ++--
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |   3 +
 .../display/dc/dpp/dcn401/dcn401_dpp_dscl.c   |  24 +-
 drivers/gpu/drm/amd/display/dc/spl/dc_spl.c   |   4 +-
 .../display/dc/spl/dc_spl_isharp_filters.c    | 213 +++++-------------
 .../display/dc/spl/dc_spl_isharp_filters.h    |   2 +-
 .../gpu/drm/amd/display/dc/spl/dc_spl_types.h |  27 ++-
 9 files changed, 138 insertions(+), 192 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index e07e47d74664..ae788154896c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -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) {
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index aaf1d7fdb73d..1a907ff82336 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -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;
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
index 328499a77884..cd6de93eb91c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
@@ -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)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index de9bd72ca514..14ea47eda0c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -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(
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
index 703d7b51c6c2..01f98139292e 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
@@ -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,7 +1016,8 @@ 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 */
-	dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
+	if (!program_isharp_1dlut)
+		dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
 
 	/* ISHARP_NLDELTA_SOFT_CLIP */
 	REG_SET_6(ISHARP_NLDELTA_SOFT_CLIP, 0,
@@ -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 */
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
index b6d1cfc494fc..15f7eda903e6 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
@@ -1662,8 +1662,10 @@ static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data,
 		dscl_prog_data->isharp_lba.base_seg[5] = 0;	// ISHARP LBA PWL for Seg 5. BASE value in U0.6 format
 	}
 
-	spl_build_isharp_1dlut_from_reference_curve(ratio, setup, adp_sharpness.sharpness);
+
+	spl_build_isharp_1dlut_from_reference_curve(ratio, setup, adp_sharpness);
 	dscl_prog_data->isharp_delta = spl_get_pregen_filter_isharp_1D_lut(setup);
+	dscl_prog_data->sharpness_level = adp_sharpness.sharpness_level;
 
 	// Program the nldelta soft clip values
 	if (lls_pref == LLS_PREF_YES) {
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c
index 8e4bcba2932a..33712f50d303 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c
@@ -460,114 +460,6 @@ static uint16_t filter_isharp_bs_4tap_in_6_64p_s1_12[198];
 static uint16_t filter_isharp_bs_4tap_64p_s1_12[132];
 static uint16_t filter_isharp_bs_3tap_64p_s1_12[99];
 
-struct scale_ratio_to_sharpness_level_lookup scale_to_sharp_sdr_nl[3][6] = {
-	{ /* LOW */
-		{1125, 1000, 75, 100},
-		{11, 10, 6, 10},
-		{1075, 1000, 45, 100},
-		{105, 100, 3, 10},
-		{1025, 1000, 15, 100},
-		{1, 1, 0, 1},
-	},
-	{ /* MID */
-		{1125, 1000, 2, 1},
-		{11, 10, 175, 100},
-		{1075, 1000, 15, 10},
-		{105, 100, 125, 100},
-		{1025, 1000, 1, 1},
-		{1, 1, 75, 100},
-	},
-	{ /* HIGH */
-		{1125, 1000, 35, 10},
-		{11, 10, 32, 10},
-		{1075, 1000, 29, 10},
-		{105, 100, 26, 10},
-		{1025, 1000, 23, 10},
-		{1, 1, 2, 1},
-	},
-};
-
-struct scale_ratio_to_sharpness_level_lookup scale_to_sharp_sdr_l[3][6] = {
-	{ /* LOW */
-		{1125, 1000, 75, 100},
-		{11, 10, 6, 10},
-		{1075, 1000, 45, 100},
-		{105, 100, 3, 10},
-		{1025, 1000, 15, 100},
-		{1, 1, 0, 1},
-	},
-	{ /* MID */
-		{1125, 1000, 15, 10},
-		{11, 10, 135, 100},
-		{1075, 1000, 12, 10},
-		{105, 100, 105, 100},
-		{1025, 1000, 9, 10},
-		{1, 1, 75, 100},
-	},
-	{ /* HIGH */
-		{1125, 1000, 25, 10},
-		{11, 10, 23, 10},
-		{1075, 1000, 21, 10},
-		{105, 100, 19, 10},
-		{1025, 1000, 17, 10},
-		{1, 1, 15, 10},
-	},
-};
-
-struct scale_ratio_to_sharpness_level_lookup scale_to_sharp_hdr_nl[3][6] = {
-	{ /* LOW */
-		{1125, 1000, 5, 10},
-		{11, 10, 4, 10},
-		{1075, 1000, 3, 10},
-		{105, 100, 2, 10},
-		{1025, 1000, 1, 10},
-		{1, 1, 0, 1},
-	},
-	{ /* MID */
-		{1125, 1000, 1, 1},
-		{11, 10, 9, 10},
-		{1075, 1000, 8, 10},
-		{105, 100, 7, 10},
-		{1025, 1000, 6, 10},
-		{1, 1, 5, 10},
-	},
-	{ /* HIGH */
-		{1125, 1000, 15, 10},
-		{11, 10, 14, 10},
-		{1075, 1000, 13, 10},
-		{105, 100, 12, 10},
-		{1025, 1000, 11, 10},
-		{1, 1, 1, 1},
-	},
-};
-
-struct scale_ratio_to_sharpness_level_lookup scale_to_sharp_hdr_l[3][6] = {
-	{ /* LOW */
-		{1125, 1000, 75, 100},
-		{11, 10, 6, 10},
-		{1075, 1000, 45, 100},
-		{105, 100, 3, 10},
-		{1025, 1000, 15, 100},
-		{1, 1, 0, 1},
-	},
-	{ /* MID */
-		{1125, 1000, 15, 10},
-		{11, 10, 135, 100},
-		{1075, 1000, 12, 10},
-		{105, 100, 105, 100},
-		{1025, 1000, 9, 10},
-		{1, 1, 75, 100},
-	},
-	{ /* HIGH */
-		{1125, 1000, 25, 10},
-		{11, 10, 23, 10},
-		{1075, 1000, 21, 10},
-		{105, 100, 19, 10},
-		{1025, 1000, 17, 10},
-		{1, 1, 15, 10},
-	},
-};
-
 /* Pre-generated 1DLUT for given setup and sharpness level */
 struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = {
 	{
@@ -649,74 +541,72 @@ uint16_t *spl_get_filter_isharp_bs_3tap_64p(void)
 	return filter_isharp_bs_3tap_64p_s1_12;
 }
 
-void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup, enum explicit_sharpness sharpness)
+static unsigned int spl_calculate_sharpness_level(int discrete_sharpness_level, enum system_setup setup,
+		struct spl_sharpness_range sharpness_range)
 {
-	uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
-	struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level, ratio_level;
-	int j;
-	struct scale_ratio_to_sharpness_level_lookup *setup_lookup_ptr;
-	int num_sharp_ramp_levels;
-	int size_1dlut;
-	int sharp_calc_int;
-	uint32_t filter_pregen_store[ISHARP_LUT_TABLE_SIZE];
+	unsigned int sharpness_level = 0;
+
+	int min_sharpness, max_sharpness, mid_sharpness;
 
-	/*
-	 * Given scaling ratio, setup and sharpness, build pregenerated
-	 * 1DLUT tables
-	 *
-	 * Based on setup ( HDR/SDR, L/NL ), get base scale ratio to
-	 *  sharpness curve
-	 */
 	switch (setup) {
+
 	case HDR_L:
-		setup_lookup_ptr = scale_to_sharp_hdr_l[sharpness];
-		num_sharp_ramp_levels = sizeof(scale_to_sharp_hdr_l[sharpness])/
-			sizeof(struct scale_ratio_to_sharpness_level_lookup);
+		min_sharpness = sharpness_range.hdr_rgb_min;
+		max_sharpness = sharpness_range.hdr_rgb_max;
+		mid_sharpness = sharpness_range.hdr_rgb_mid;
 		break;
 	case HDR_NL:
-		setup_lookup_ptr = scale_to_sharp_hdr_nl[sharpness];
-		num_sharp_ramp_levels = sizeof(scale_to_sharp_hdr_nl[sharpness])/
-			sizeof(struct scale_ratio_to_sharpness_level_lookup);
+		/* currently no use case, use Non-linear SDR values for now */
+	case SDR_NL:
+		min_sharpness = sharpness_range.sdr_yuv_min;
+		max_sharpness = sharpness_range.sdr_yuv_max;
+		mid_sharpness = sharpness_range.sdr_yuv_mid;
 		break;
 	case SDR_L:
-		setup_lookup_ptr = scale_to_sharp_sdr_l[sharpness];
-		num_sharp_ramp_levels = sizeof(scale_to_sharp_sdr_l[sharpness])/
-			sizeof(struct scale_ratio_to_sharpness_level_lookup);
-		break;
-	case SDR_NL:
 	default:
-		setup_lookup_ptr = scale_to_sharp_sdr_nl[sharpness];
-		num_sharp_ramp_levels = sizeof(scale_to_sharp_sdr_nl[sharpness])/
-			sizeof(struct scale_ratio_to_sharpness_level_lookup);
+		min_sharpness = sharpness_range.sdr_rgb_min;
+		max_sharpness = sharpness_range.sdr_rgb_max;
+		mid_sharpness = sharpness_range.sdr_rgb_mid;
 		break;
 	}
 
-	/*
-	 * Compare desired scaling ratio and find adjusted sharpness from
-	 *  base scale ratio to sharpness curve
-	 */
-	j = 0;
-	sharp_level = spl_fixpt_zero;
-	while (j < num_sharp_ramp_levels) {
-		ratio_level = spl_fixpt_from_fraction(setup_lookup_ptr->ratio_numer,
-			setup_lookup_ptr->ratio_denom);
-		if (ratio.value >= ratio_level.value) {
-			sharp_level = spl_fixpt_from_fraction(setup_lookup_ptr->sharpness_numer,
-				setup_lookup_ptr->sharpness_denom);
-			break;
-		}
-		setup_lookup_ptr++;
-		j++;
-	}
+	int lower_half_step_size = (mid_sharpness - min_sharpness) / 5;
+	int upper_half_step_size = (max_sharpness - mid_sharpness) / 5;
+
+	// lower half linear approximation
+	if (discrete_sharpness_level < 5)
+		sharpness_level = min_sharpness + (lower_half_step_size * discrete_sharpness_level);
+	// upper half linear approximation
+	else
+		sharpness_level = mid_sharpness + (upper_half_step_size * (discrete_sharpness_level - 5));
+
+	return sharpness_level;
+}
+
+void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup,
+	struct adaptive_sharpness sharpness)
+{
+	uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
+	struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level;
+	int j;
+	int size_1dlut;
+	int sharp_calc_int;
+	uint32_t filter_pregen_store[ISHARP_LUT_TABLE_SIZE];
+
+	/* Custom sharpnessX1000 value */
+	unsigned int sharpnessX1000 = spl_calculate_sharpness_level(sharpness.sharpness_level,
+			setup, sharpness.sharpness_range);
+	sharp_level = spl_fixpt_from_fraction(sharpnessX1000, 1000);
 
 	/*
 	 * Check if pregen 1dlut table is already precalculated
 	 * If numer/denom is different, then recalculate
 	 */
-	if ((filter_isharp_1D_lut_pregen[setup].sharpness_numer == setup_lookup_ptr->sharpness_numer) &&
-		(filter_isharp_1D_lut_pregen[setup].sharpness_denom == setup_lookup_ptr->sharpness_denom))
+	if ((filter_isharp_1D_lut_pregen[setup].sharpness_numer == sharpnessX1000) &&
+		(filter_isharp_1D_lut_pregen[setup].sharpness_denom == 1000))
 		return;
 
+
 	/*
 	 * Calculate LUT_128_gained with this equation:
 	 *
@@ -737,8 +627,9 @@ void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, en
 		sharp_calc = spl_fixpt_min(spl_fixpt_from_int(255), sharp_calc);
 		sharp_calc = spl_fixpt_add(sharp_calc, spl_fixpt_from_fraction(1, 2));
 		sharp_calc_int = spl_fixpt_floor(sharp_calc);
-		if (sharp_calc_int > 255)
-			sharp_calc_int = 255;
+		/* Clamp it at 0x7F so it doesn't wrap */
+		if (sharp_calc_int > 127)
+			sharp_calc_int = 127;
 		*byte_ptr_1dlut_dst = (uint8_t)sharp_calc_int;
 
 		byte_ptr_1dlut_src++;
@@ -747,8 +638,8 @@ void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, en
 
 	/* Update 1dlut table and sharpness level */
 	memcpy((void *)filter_isharp_1D_lut_pregen[setup].value, (void *)filter_pregen_store, size_1dlut);
-	filter_isharp_1D_lut_pregen[setup].sharpness_numer = setup_lookup_ptr->sharpness_numer;
-	filter_isharp_1D_lut_pregen[setup].sharpness_denom = setup_lookup_ptr->sharpness_denom;
+	filter_isharp_1D_lut_pregen[setup].sharpness_numer = sharpnessX1000;
+	filter_isharp_1D_lut_pregen[setup].sharpness_denom = 1000;
 }
 
 uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup)
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h
index 3d023a154a92..fe0b12571f2c 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h
@@ -45,6 +45,6 @@ void spl_init_blur_scale_coeffs(void);
 void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
 	const struct spl_scaler_data *data);
 
-void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup, enum explicit_sharpness sharpness);
+void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup, struct adaptive_sharpness sharpness);
 uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup);
 #endif /* __DC_SPL_ISHARP_FILTERS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
index 7c1a21c2305d..85b19ebe2c57 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
@@ -407,6 +407,7 @@ struct dscl_prog_data {
 	/* blur and scale filter */
 	const uint16_t *filter_blur_scale_v;
 	const uint16_t *filter_blur_scale_h;
+	int sharpness_level; /* Track sharpness level */
 };
 
 /* SPL input and output definitions */
@@ -460,14 +461,26 @@ struct basic_out {
 	bool alpha_en;
 	bool use_two_pixels_per_container;
 };
-enum explicit_sharpness	{
-	SHARPNESS_LOW = 0,
-	SHARPNESS_MID,
-	SHARPNESS_HIGH
-};
-struct adaptive_sharpness	{
+enum sharpness_setting	{
+	SHARPNESS_HW_OFF = 0,
+	SHARPNESS_ZERO,
+	SHARPNESS_CUSTOM
+};
+struct spl_sharpness_range {
+	int sdr_rgb_min;
+	int sdr_rgb_max;
+	int sdr_rgb_mid;
+	int sdr_yuv_min;
+	int sdr_yuv_max;
+	int sdr_yuv_mid;
+	int hdr_rgb_min;
+	int hdr_rgb_max;
+	int hdr_rgb_mid;
+};
+struct adaptive_sharpness {
 	bool enable;
-	enum explicit_sharpness sharpness;
+	int sharpness_level;
+	struct spl_sharpness_range sharpness_range;
 };
 enum linear_light_scaling	{	// convert it in translation logic
 	LLS_PREF_DONT_CARE = 0,
-- 
2.46.0



More information about the amd-gfx mailing list