All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: <Roman.Li@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: <Harry.Wentland@amd.com>, <Sunpeng.Li@amd.com>,
	<Rodrigo.Siqueira@amd.com>, <Aurabindo.Pillai@amd.com>,
	<roman.li@amd.com>, <wayne.lin@amd.com>,
	<agustin.gutierrez@amd.com>, <chiahsuan.chung@amd.com>,
	<jerry.zuo@amd.com>, Samson Tam <Samson.Tam@amd.com>
Subject: [PATCH 07/24] drm/amd/display: enable EASF support for DCN40
Date: Thu, 16 May 2024 15:26:30 -0400	[thread overview]
Message-ID: <20240516192647.1522729-8-Roman.Li@amd.com> (raw)
In-Reply-To: <20240516192647.1522729-1-Roman.Li@amd.com>

From: Samson Tam <Samson.Tam@amd.com>

[Why]
Enable adaptive scaler support for DCN401

[How]
- Enable build flag for SPL
- Set prefer_easf flag to true
- Apply light linear scaling policy based on transfer function and pixel
  format.  Choose between linear or non-linear scaling
- Set matrix_mode based on pixel format
- Disable ring estimator
- Add missing EASF register defines, masks, and writes
- Disable EASF if scale ratio or number of taps is unsupported and when
  bypassing the scaler
- Add debug flags and registry keys for debugging SPL and EASF
- Add support for Visual Confirm with EASF

Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Samson Tam <Samson.Tam@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  11 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |   3 +
 .../gpu/drm/amd/display/dc/dc_spl_translate.c |  15 +-
 .../amd/display/dc/dpp/dcn401/dcn401_dpp.h    |   6 +-
 .../display/dc/dpp/dcn401/dcn401_dpp_dscl.c   | 207 +++++++++++++++++-
 .../dc/resource/dcn401/dcn401_resource.c      |   1 +
 .../dc/resource/dcn401/dcn401_resource.h      |  48 +++-
 drivers/gpu/drm/amd/display/dc/spl/dc_spl.c   |  95 ++++++--
 .../gpu/drm/amd/display/dc/spl/dc_spl_types.h |  30 ++-
 9 files changed, 382 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 70c39eef99e5..ce1991e06049 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1500,8 +1500,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 	pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface(
 			pipe_ctx->plane_state->format);
 
-	if (pipe_ctx->stream->ctx->dc->config.use_spl)	{
 #if defined(CONFIG_DRM_AMD_DC_FP)
+	if ((pipe_ctx->stream->ctx->dc->config.use_spl)	&& (!pipe_ctx->stream->ctx->dc->debug.disable_spl)) {
 		struct spl_in *spl_in = &pipe_ctx->plane_res.spl_in;
 		struct spl_out *spl_out = &pipe_ctx->plane_res.spl_out;
 
@@ -1516,15 +1516,18 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 
 		// Convert pipe_ctx to respective input params for SPL
 		translate_SPL_in_params_from_pipe_ctx(pipe_ctx, spl_in);
+		/* Pass visual confirm debug information */
+		calculate_adjust_recout_for_visual_confirm(pipe_ctx,
+			&spl_in->debug.visual_confirm_base_offset,
+			&spl_in->debug.visual_confirm_dpp_offset);
 		// Set SPL output parameters to dscl_prog_data to be used for hw registers
 		spl_out->dscl_prog_data = resource_get_dscl_prog_data(pipe_ctx);
 		// Calculate scaler parameters from SPL
 		res = spl_calculate_scaler_params(spl_in, spl_out);
 		// Convert respective out params from SPL to scaler data
 		translate_SPL_out_params_to_pipe_ctx(pipe_ctx, spl_out);
-#endif
 	} else {
-
+#endif
 	/* depends on h_active */
 	calculate_recout(pipe_ctx);
 	/* depends on pixel format */
@@ -1604,7 +1607,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 		pipe_ctx->plane_res.scl_data.viewport.height = MIN_VIEWPORT_SIZE;
 	if (pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
 		pipe_ctx->plane_res.scl_data.viewport.width = MIN_VIEWPORT_SIZE;
+#ifdef CONFIG_DRM_AMD_DC_FP
 	}
+#endif
 	DC_LOG_SCALER("%s pipe %d:\nViewport: height:%d width:%d x:%d y:%d  Recout: height:%d width:%d x:%d y:%d  HACTIVE:%d VACTIVE:%d\n"
 			"src_rect: height:%d width:%d x:%d y:%d  dst_rect: height:%d width:%d x:%d y:%d  clip_rect: height:%d width:%d x:%d y:%d\n",
 			__func__,
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index fd948e4cec0d..5ae74558632b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1038,6 +1038,9 @@ struct dc_debug_options {
 	union dmub_fams2_global_feature_config fams2_config;
 	bool enable_legacy_clock_update;
 	unsigned int force_cositing;
+	unsigned int disable_spl;
+	unsigned int force_easf;
+	unsigned int force_lls;
 };
 
 
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 daf97688e901..6e37b166802b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
@@ -129,6 +129,11 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
 	populate_spltaps_from_taps(&spl_in->scaling_quality, &plane_state->scaling_quality);
 	// Translate edge adaptive scaler preference
 	spl_in->prefer_easf = pipe_ctx->stream->ctx->dc->config.prefer_easf;
+	spl_in->disable_easf = false;
+	if (pipe_ctx->stream->ctx->dc->debug.force_easf == 1)
+		spl_in->prefer_easf = false;
+	else if (pipe_ctx->stream->ctx->dc->debug.force_easf == 2)
+		spl_in->disable_easf = true;
 	// Translate adaptive sharpening preference
 	spl_in->adaptive_sharpness.enable = plane_state->adaptive_sharpness_en;
 	if (plane_state->sharpnessX1000 == 0)	{
@@ -141,13 +146,19 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
 		spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
 	}
 	// Translate linear light scaling preference
-	spl_in->lls_pref = plane_state->linear_light_scaling;
-
+	if (pipe_ctx->stream->ctx->dc->debug.force_lls > 0)
+		spl_in->lls_pref = pipe_ctx->stream->ctx->dc->debug.force_lls;
+	else
+		spl_in->lls_pref = plane_state->linear_light_scaling;
 	/* Translate chroma subsampling offset ( cositing ) */
 	if (pipe_ctx->stream->ctx->dc->debug.force_cositing)
 		spl_in->basic_in.cositing = pipe_ctx->stream->ctx->dc->debug.force_cositing - 1;
 	else
 		spl_in->basic_in.cositing = plane_state->cositing;
+	/* Translate transfer function */
+	spl_in->basic_in.tf_type = (enum spl_transfer_func_type) plane_state->in_transfer_func.type;
+	spl_in->basic_in.tf_predefined_type = (enum spl_transfer_func_predefined) plane_state->in_transfer_func.tf;
+
 }
 
 /// @brief Translate SPL output parameters to pipe context
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h
index 7ab657ad3a20..1aaae7a5bd41 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h
@@ -373,7 +373,11 @@
 	TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_SLOPE_P, mask_sh), \
 	TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_EN_N, mask_sh), \
 	TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_PIVOT_N, mask_sh), \
-	TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_SLOPE_N, mask_sh)
+	TF_SF(DSCL0_ISHARP_NLDELTA_SOFT_CLIP, ISHARP_NLDELTA_SCLIP_SLOPE_N, mask_sh), \
+	TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT, SCL_V_INIT_FRAC_BOT, mask_sh),\
+	TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT, SCL_V_INIT_INT_BOT, mask_sh),\
+	TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT_C, SCL_V_INIT_FRAC_BOT_C, mask_sh),\
+	TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT_C, SCL_V_INIT_INT_BOT_C, mask_sh)
 
 #define DPP_REG_FIELD_LIST_DCN401(type) \
 	DPP_REG_FIELD_LIST_DCN3(type); \
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 d9a08cd160b3..4b1e52803c7a 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
@@ -294,7 +294,7 @@ static void dpp401_dscl_set_scl_filter(
 	const uint16_t *filter_h_c = NULL;
 	const uint16_t *filter_v_c = NULL;
 
-	if (dpp->base.ctx->dc->config.use_spl)  {
+	if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
 		filter_h = scl_data->dscl_prog_data.filter_h;
 		filter_v = scl_data->dscl_prog_data.filter_v;
 		filter_h_c = scl_data->dscl_prog_data.filter_h_c;
@@ -523,7 +523,7 @@ static void dpp401_dscl_set_manual_ratio_init(
 {
 	uint32_t init_frac = 0;
 	uint32_t init_int = 0;
-	if (dpp->base.ctx->dc->config.use_spl)  {
+	if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
 		REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0,
 			SCL_H_SCALE_RATIO, data->dscl_prog_data.ratios.h_scale_ratio);
 
@@ -669,7 +669,7 @@ static void dpp401_dscl_program_easf(struct dpp *dpp_base, const struct scaler_d
 			SCL_SC_MATRIX_MODE, scl_data->dscl_prog_data.easf_matrix_mode);
 	REG_UPDATE(DSCL_SC_MODE,
 			SCL_SC_LTONL_EN, scl_data->dscl_prog_data.easf_ltonl_en);
-	// DSCL_EASF_V_MODE
+	/* DSCL_EASF_V_MODE */
 	REG_UPDATE(DSCL_EASF_V_MODE,
 			SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en);
 	REG_UPDATE(DSCL_EASF_V_MODE,
@@ -716,7 +716,87 @@ static void dpp401_dscl_program_easf(struct dpp *dpp_base, const struct scaler_d
 			SCL_EASF_V_BF_MINA, scl_data->dscl_prog_data.easf_v_bf_mina);
 	REG_UPDATE(DSCL_EASF_V_BF_FINAL_MAX_MIN,
 			SCL_EASF_V_BF_MINB, scl_data->dscl_prog_data.easf_v_bf_minb);
-	// DSCL_EASF_H_MODE
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
+			SCL_EASF_V_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg0);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
+			SCL_EASF_V_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg0);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG0,
+			SCL_EASF_V_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg0);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
+			SCL_EASF_V_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg1);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
+			SCL_EASF_V_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg1);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG1,
+			SCL_EASF_V_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg1);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
+			SCL_EASF_V_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg2);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
+			SCL_EASF_V_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg2);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG2,
+			SCL_EASF_V_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg2);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
+			SCL_EASF_V_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg3);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
+			SCL_EASF_V_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg3);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG3,
+			SCL_EASF_V_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg3);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
+			SCL_EASF_V_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg4);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
+			SCL_EASF_V_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg4);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG4,
+			SCL_EASF_V_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg4);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
+			SCL_EASF_V_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg5);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
+			SCL_EASF_V_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg5);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG5,
+			SCL_EASF_V_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg5);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
+			SCL_EASF_V_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg6);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
+			SCL_EASF_V_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg6);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG6,
+			SCL_EASF_V_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg6);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG7,
+			SCL_EASF_V_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg7);
+	REG_UPDATE(DSCL_EASF_V_BF1_PWL_SEG7,
+			SCL_EASF_V_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg7);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
+			SCL_EASF_V_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set0);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
+			SCL_EASF_V_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set0);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG0,
+			SCL_EASF_V_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set0);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
+			SCL_EASF_V_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set1);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
+			SCL_EASF_V_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set1);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG1,
+			SCL_EASF_V_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set1);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
+			SCL_EASF_V_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set2);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
+			SCL_EASF_V_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set2);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG2,
+			SCL_EASF_V_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set2);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
+			SCL_EASF_V_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set3);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
+			SCL_EASF_V_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set3);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG3,
+			SCL_EASF_V_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set3);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
+			SCL_EASF_V_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set4);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
+			SCL_EASF_V_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set4);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG4,
+			SCL_EASF_V_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set4);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG5,
+			SCL_EASF_V_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set5);
+	REG_UPDATE(DSCL_EASF_V_BF3_PWL_SEG5,
+			SCL_EASF_V_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set5);
+	/* DSCL_EASF_H_MODE */
 	REG_UPDATE(DSCL_EASF_H_MODE,
 			SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en);
 	REG_UPDATE(DSCL_EASF_H_MODE,
@@ -751,6 +831,117 @@ static void dpp401_dscl_program_easf(struct dpp *dpp_base, const struct scaler_d
 			SCL_EASF_H_BF_MINA, scl_data->dscl_prog_data.easf_h_bf_mina);
 	REG_UPDATE(DSCL_EASF_H_BF_FINAL_MAX_MIN,
 			SCL_EASF_H_BF_MINB, scl_data->dscl_prog_data.easf_h_bf_minb);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
+			SCL_EASF_H_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg0);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
+			SCL_EASF_H_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg0);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG0,
+			SCL_EASF_H_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg0);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
+			SCL_EASF_H_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg1);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
+			SCL_EASF_H_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg1);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG1,
+			SCL_EASF_H_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg1);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
+			SCL_EASF_H_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg2);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
+			SCL_EASF_H_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg2);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG2,
+			SCL_EASF_H_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg2);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
+			SCL_EASF_H_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg3);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
+			SCL_EASF_H_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg3);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG3,
+			SCL_EASF_H_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg3);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
+			SCL_EASF_H_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg4);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
+			SCL_EASF_H_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg4);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG4,
+			SCL_EASF_H_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg4);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
+			SCL_EASF_H_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg5);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
+			SCL_EASF_H_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg5);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG5,
+			SCL_EASF_H_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg5);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
+			SCL_EASF_H_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg6);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
+			SCL_EASF_H_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg6);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG6,
+			SCL_EASF_H_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg6);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG7,
+			SCL_EASF_H_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg7);
+	REG_UPDATE(DSCL_EASF_H_BF1_PWL_SEG7,
+			SCL_EASF_H_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg7);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
+			SCL_EASF_H_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set0);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
+			SCL_EASF_H_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set0);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG0,
+			SCL_EASF_H_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set0);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
+			SCL_EASF_H_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set1);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
+			SCL_EASF_H_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set1);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG1,
+			SCL_EASF_H_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set1);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
+			SCL_EASF_H_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set2);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
+			SCL_EASF_H_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set2);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG2,
+			SCL_EASF_H_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set2);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
+			SCL_EASF_H_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set3);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
+			SCL_EASF_H_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set3);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG3,
+			SCL_EASF_H_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set3);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
+			SCL_EASF_H_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set4);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
+			SCL_EASF_H_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set4);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG4,
+			SCL_EASF_H_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set4);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG5,
+			SCL_EASF_H_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set5);
+	REG_UPDATE(DSCL_EASF_H_BF3_PWL_SEG5,
+			SCL_EASF_H_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set5);
+	/* DSCL_EASF_SC_MATRIX_C0C1, DSCL_EASF_SC_MATRIX_C2C3 */
+	REG_UPDATE(DSCL_SC_MATRIX_C0C1,
+			SCL_SC_MATRIX_C0, scl_data->dscl_prog_data.easf_matrix_c0);
+	REG_UPDATE(DSCL_SC_MATRIX_C0C1,
+			SCL_SC_MATRIX_C1, scl_data->dscl_prog_data.easf_matrix_c1);
+	REG_UPDATE(DSCL_SC_MATRIX_C2C3,
+			SCL_SC_MATRIX_C2, scl_data->dscl_prog_data.easf_matrix_c2);
+	REG_UPDATE(DSCL_SC_MATRIX_C2C3,
+			SCL_SC_MATRIX_C3, scl_data->dscl_prog_data.easf_matrix_c3);
+	PERF_TRACE();
+}
+/**
+ * dpp401_dscl_disable_easf - Disable EASF when no scaling (1:1)
+ *
+ * @dpp_base: High level DPP struct
+ * @scl_data: scalaer_data info
+ *
+ * When we have 1:1 scaling, we need to disable EASF
+ *
+ */
+static void dpp401_dscl_disable_easf(struct dpp *dpp_base, const struct scaler_data *scl_data)
+{
+	struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
+
+	PERF_TRACE();
+	/* DSCL_EASF_V_MODE */
+	REG_UPDATE(DSCL_EASF_V_MODE,
+			SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en);
+	/* DSCL_EASF_H_MODE */
+	REG_UPDATE(DSCL_EASF_H_MODE,
+			SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en);
 	PERF_TRACE();
 }
 static void dpp401_dscl_set_isharp_filter(
@@ -852,7 +1043,7 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
 
 	dpp->scl_data = *scl_data;
 
-	if (dpp->base.ctx->dc->config.use_spl)  {
+	if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
 		dscl_mode = (enum dscl_mode_sel) scl_data->dscl_prog_data.dscl_mode;
 		rect = (struct rect *)&scl_data->dscl_prog_data.recout;
 		mpc_width = scl_data->dscl_prog_data.mpc_size.width;
@@ -900,8 +1091,12 @@ void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
 	lb_config =  dpp401_dscl_find_lb_memory_config(dpp, scl_data);
 	dpp401_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
 
-	if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
+	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);
 		return;
+	}
 
 	/* Black offsets */
 	if (REG(SCL_BLACK_OFFSET)) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
index a55421363772..fc43e7b5ec90 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
@@ -1845,6 +1845,7 @@ static bool dcn401_resource_construct(
 	dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
 	dc->caps.color.mpc.ocsc = 1;
 	dc->config.use_spl = true;
+	dc->config.prefer_easf = true;
 	dc->config.dc_mode_clk_limit_support = true;
 	dc->config.enable_windowed_mpo_odm = true;
 	/* read VBIOS LTTPR caps */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
index 5d5e01903ca1..a638c410e32a 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
@@ -342,7 +342,53 @@ bool dcn401_validate_bandwidth(struct dc *dc,
 	SRI_ARR(OBUF_MEM_PWR_CTRL, DSCL, id),                                    \
 	SRI_ARR(DSCL_MEM_PWR_STATUS, DSCL, id),                                  \
 	SRI_ARR(DSCL_MEM_PWR_CTRL, DSCL, id),                                    \
-	SRI_ARR(DSCL_CONTROL, DSCL, id)
+	SRI_ARR(DSCL_CONTROL, DSCL, id),                                         \
+	SRI_ARR(DSCL_SC_MODE, DSCL, id),                                         \
+	SRI_ARR(DSCL_EASF_H_MODE, DSCL, id),                                     \
+	SRI_ARR(DSCL_EASF_H_BF_CNTL, DSCL, id),                                  \
+	SRI_ARR(DSCL_EASF_H_RINGEST_EVENTAP_REDUCE, DSCL, id),                   \
+	SRI_ARR(DSCL_EASF_H_RINGEST_EVENTAP_GAIN, DSCL, id),                     \
+	SRI_ARR(DSCL_EASF_H_BF_FINAL_MAX_MIN, DSCL, id),                         \
+	SRI_ARR(DSCL_EASF_H_BF1_PWL_SEG0, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF1_PWL_SEG1, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF1_PWL_SEG2, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF1_PWL_SEG3, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF1_PWL_SEG4, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF1_PWL_SEG5, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF1_PWL_SEG6, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF1_PWL_SEG7, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF3_PWL_SEG0, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF3_PWL_SEG1, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF3_PWL_SEG2, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF3_PWL_SEG3, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF3_PWL_SEG4, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_H_BF3_PWL_SEG5, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_MODE, DSCL, id),                                     \
+	SRI_ARR(DSCL_EASF_V_BF_CNTL, DSCL, id),                                  \
+	SRI_ARR(DSCL_EASF_V_RINGEST_3TAP_CNTL1, DSCL, id),                       \
+	SRI_ARR(DSCL_EASF_V_RINGEST_3TAP_CNTL2, DSCL, id),                       \
+	SRI_ARR(DSCL_EASF_V_RINGEST_3TAP_CNTL3, DSCL, id),                       \
+	SRI_ARR(DSCL_EASF_V_RINGEST_EVENTAP_REDUCE, DSCL, id),                   \
+	SRI_ARR(DSCL_EASF_V_RINGEST_EVENTAP_GAIN, DSCL, id),                     \
+	SRI_ARR(DSCL_EASF_V_BF_FINAL_MAX_MIN, DSCL, id),                         \
+	SRI_ARR(DSCL_EASF_V_BF1_PWL_SEG0, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF1_PWL_SEG1, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF1_PWL_SEG2, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF1_PWL_SEG3, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF1_PWL_SEG4, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF1_PWL_SEG5, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF1_PWL_SEG6, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF1_PWL_SEG7, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF3_PWL_SEG0, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF3_PWL_SEG1, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF3_PWL_SEG2, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF3_PWL_SEG3, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF3_PWL_SEG4, DSCL, id),                             \
+	SRI_ARR(DSCL_EASF_V_BF3_PWL_SEG5, DSCL, id),                             \
+	SRI_ARR(DSCL_SC_MATRIX_C0C1, DSCL, id),                                  \
+	SRI_ARR(DSCL_SC_MATRIX_C2C3, DSCL, id),                                  \
+	SRI_ARR(SCL_VERT_FILTER_INIT_BOT, DSCL, id),                             \
+	SRI_ARR(SCL_VERT_FILTER_INIT_BOT_C, DSCL, id)
 
 /* OPP */
 #define OPP_REG_LIST_DCN401_RI(id)                                              \
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 542cd6cdef46..82fbd2b59c70 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
@@ -324,14 +324,18 @@ static void spl_calculate_recout(struct spl_in *spl_in, struct spl_out *spl_out)
 	overlapping_area = intersect_rec(&mpc_slice_of_plane_clip, &odm_slice);
 
 	if (overlapping_area.height > 0 &&
-			overlapping_area.width > 0)
+			overlapping_area.width > 0) {
 		/* shift the overlapping area so it is with respect to current
 		 * ODM slice's position
 		 */
 		spl_out->scl_data.recout = shift_rec(
 				&overlapping_area,
 				-odm_slice.x, -odm_slice.y);
-	else
+		spl_out->scl_data.recout.height -=
+			spl_in->debug.visual_confirm_base_offset;
+		spl_out->scl_data.recout.height -=
+			spl_in->debug.visual_confirm_dpp_offset;
+	} else
 		/* if there is no overlap, zero recout */
 		memset(&spl_out->scl_data.recout, 0,
 				sizeof(struct spl_rect));
@@ -493,13 +497,11 @@ static void spl_calculate_init_and_vp(bool flip_scan_dir,
 
 static bool spl_is_yuv420(enum spl_pixel_format format)
 {
-	switch (format) {
-	case SPL_PIXEL_FORMAT_420BPP8:
-	case SPL_PIXEL_FORMAT_420BPP10:
+	if ((format >= SPL_PIXEL_FORMAT_VIDEO_BEGIN) &&
+		(format <= SPL_PIXEL_FORMAT_VIDEO_END))
 		return true;
-	default:
-		return false;
-	}
+
+	return false;
 }
 
 /*Calculate inits and viewport */
@@ -969,12 +971,17 @@ static bool enable_easf(int scale_ratio, int taps,
 }
 /* Set EASF data */
 static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
-	bool enable_easf_v, bool enable_easf_h, enum linear_light_scaling lls_pref)
+	bool enable_easf_v, bool enable_easf_h, enum linear_light_scaling lls_pref,
+	enum spl_pixel_format format)
 {
-	dscl_prog_data->easf_matrix_mode = 0;
+	if (spl_is_yuv420(format)) /* TODO: 0 = RGB, 1 = YUV */
+		dscl_prog_data->easf_matrix_mode = 1;
+	else
+		dscl_prog_data->easf_matrix_mode = 0;
+
 	if (enable_easf_v) {
 		dscl_prog_data->easf_v_en = true;
-		dscl_prog_data->easf_v_ring = 1;
+		dscl_prog_data->easf_v_ring = 0;
 		dscl_prog_data->easf_v_sharp_factor = 1;
 		dscl_prog_data->easf_v_bf1_en = 1;	// 1-bit, BF1 calculation enable, 0=disable, 1=enable
 		dscl_prog_data->easf_v_bf2_mode = 0xF;	// 4-bit, BF2 calculation mode
@@ -1081,10 +1088,12 @@ static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
 				0x0780;	// FP0.6.6, BF3 Input value PWL Segment 5 (0.5)
 			dscl_prog_data->easf_v_bf3_pwl_base_set5 = -63;	// S0.6, BF3 Base PWL Segment 5
 		}
-	}
+	} else
+		dscl_prog_data->easf_v_en = false;
+
 	if (enable_easf_h) {
 		dscl_prog_data->easf_h_en = true;
-		dscl_prog_data->easf_h_ring = 1;
+		dscl_prog_data->easf_h_ring = 0;
 		dscl_prog_data->easf_h_sharp_factor = 1;
 		dscl_prog_data->easf_h_bf1_en =
 			1;	// 1-bit, BF1 calculation enable, 0=disable, 1=enable
@@ -1177,7 +1186,9 @@ static void spl_set_easf_data(struct dscl_prog_data *dscl_prog_data,
 				0x0780;	// FP0.6.6, BF3 Input value PWL Segment 5 (0.5)
 			dscl_prog_data->easf_h_bf3_pwl_base_set5 = -63;	// S0.6, BF3 Base PWL Segment 5
 		} // if (lls_pref == LLS_PREF_YES)
-	}
+	} else
+		dscl_prog_data->easf_h_en = false;
+
 	if (lls_pref == LLS_PREF_YES)	{
 		dscl_prog_data->easf_ltonl_en = 1;	// Linear input
 		dscl_prog_data->easf_matrix_c0 =
@@ -1304,12 +1315,40 @@ static bool spl_get_isharp_en(struct adaptive_sharpness adp_sharpness,
 	}
 	return enable_isharp;
 }
+
+static bool spl_choose_lls_policy(enum spl_pixel_format format,
+	enum spl_transfer_func_type tf_type,
+	enum spl_transfer_func_predefined tf_predefined_type,
+	enum linear_light_scaling *lls_pref)
+{
+	if (spl_is_yuv420(format)) {
+		*lls_pref = LLS_PREF_NO;
+		if ((tf_type == SPL_TF_TYPE_PREDEFINED) || (tf_type == SPL_TF_TYPE_DISTRIBUTED_POINTS))
+			return true;
+	} else { /* RGB or YUV444 */
+		if (tf_type == SPL_TF_TYPE_PREDEFINED) {
+			if ((tf_predefined_type == SPL_TRANSFER_FUNCTION_HLG) ||
+				(tf_predefined_type == SPL_TRANSFER_FUNCTION_HLG12))
+				*lls_pref = LLS_PREF_NO;
+			else
+				*lls_pref = LLS_PREF_YES;
+			return true;
+		} else if (tf_type == SPL_TF_TYPE_BYPASS) {
+			*lls_pref = LLS_PREF_YES;
+			return true;
+		}
+	}
+	*lls_pref = LLS_PREF_NO;
+	return false;
+}
+
 /* Caclulate scaler parameters */
 bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out)
 {
 	bool res = false;
 	bool enable_easf_v = false;
 	bool enable_easf_h = false;
+	bool lls_enable_easf = true;
 	// All SPL calls
 	/* recout calculation */
 	/* depends on h_active */
@@ -1335,17 +1374,33 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out)
 
 	if (!res)
 		return res;
+
+	/*
+	 * If lls_pref is LLS_PREF_DONT_CARE, then use pixel format and transfer
+	 *  function to determine whether to use LINEAR or NONLINEAR scaling
+	 */
+	if (spl_in->lls_pref == LLS_PREF_DONT_CARE)
+		lls_enable_easf = spl_choose_lls_policy(spl_in->basic_in.format,
+			spl_in->basic_in.tf_type, spl_in->basic_in.tf_predefined_type,
+			&spl_in->lls_pref);
+
 	// Save all calculated parameters in dscl_prog_data structure to program hw registers
 	spl_set_dscl_prog_data(spl_in, spl_out);
-	// Enable EASF on vertical?
+
 	int vratio = dc_fixpt_ceil(spl_out->scl_data.ratios.vert);
 	int hratio = dc_fixpt_ceil(spl_out->scl_data.ratios.horz);
-	enable_easf_v = enable_easf(vratio, spl_out->scl_data.taps.v_taps, spl_in->lls_pref, spl_in->prefer_easf);
-	// Enable EASF on horizontal?
-	enable_easf_h = enable_easf(hratio, spl_out->scl_data.taps.h_taps, spl_in->lls_pref, spl_in->prefer_easf);
+	if (!lls_enable_easf || spl_in->disable_easf) {
+		enable_easf_v = false;
+		enable_easf_h = false;
+	} else {
+		/* Enable EASF on vertical? */
+		enable_easf_v = enable_easf(vratio, spl_out->scl_data.taps.v_taps, spl_in->lls_pref, spl_in->prefer_easf);
+		/* Enable EASF on horizontal? */
+		enable_easf_h = enable_easf(hratio, spl_out->scl_data.taps.h_taps, spl_in->lls_pref, spl_in->prefer_easf);
+	}
 	// Set EASF
-	spl_set_easf_data(spl_out->dscl_prog_data, enable_easf_v, enable_easf_h, spl_in->lls_pref);
-	// Set iSHARP
+	spl_set_easf_data(spl_out->dscl_prog_data, enable_easf_v, enable_easf_h, spl_in->lls_pref,
+		spl_in->basic_in.format);	// Set iSHARP
 	bool enable_isharp = spl_get_isharp_en(spl_in->adaptive_sharpness, vratio, hratio,
 								spl_out->scl_data.taps);
 	if (enable_isharp)
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 c5ef15f16c68..0c9edee0582e 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
@@ -132,6 +132,26 @@ struct spl_scaler_data {
 	struct spl_inits inits;
 };
 
+enum spl_transfer_func_type {
+	SPL_TF_TYPE_PREDEFINED,
+	SPL_TF_TYPE_DISTRIBUTED_POINTS,
+	SPL_TF_TYPE_BYPASS,
+	SPL_TF_TYPE_HWPWL
+};
+
+enum spl_transfer_func_predefined {
+	SPL_TRANSFER_FUNCTION_SRGB,
+	SPL_TRANSFER_FUNCTION_BT709,
+	SPL_TRANSFER_FUNCTION_PQ,
+	SPL_TRANSFER_FUNCTION_LINEAR,
+	SPL_TRANSFER_FUNCTION_UNITY,
+	SPL_TRANSFER_FUNCTION_HLG,
+	SPL_TRANSFER_FUNCTION_HLG12,
+	SPL_TRANSFER_FUNCTION_GAMMA22,
+	SPL_TRANSFER_FUNCTION_GAMMA24,
+	SPL_TRANSFER_FUNCTION_GAMMA26
+};
+
 /*==============================================================*/
 /* Below structs are defined to hold hw register data */
 
@@ -400,7 +420,8 @@ struct basic_in	{
 	int mpc_combine_h; // MPC Horizontal Combine Factor (split_count)
 	int mpc_combine_v; // MPC Vertical Combine Factor (split_idx)
 	// Inputs for adaptive scaler - TODO
-	// struct dc_transfer_func transfer_func;	//	Transfer function
+	enum spl_transfer_func_type tf_type; /* Transfer function type */
+	enum spl_transfer_func_predefined tf_predefined_type; /* Transfer function predefined type */
 	// enum dc_transfer_func_predefined tf;
 	enum spl_color_space color_space;	//	Color Space
 	unsigned int max_luminance;	//	Max Luminance TODO: Is determined in dc_hw_sequencer.c is_sdr
@@ -441,6 +462,11 @@ struct spl_funcs	{
 		int *num_part_c);
 };
 
+struct spl_debug {
+	int visual_confirm_base_offset;
+	int visual_confirm_dpp_offset;
+};
+
 struct spl_in	{
 	struct basic_out basic_out;
 	struct basic_in basic_in;
@@ -452,6 +478,8 @@ struct spl_in	{
 	struct adaptive_sharpness adaptive_sharpness;	//	Adaptive Sharpness
 	enum linear_light_scaling lls_pref;	//	Linear Light Scaling
 	bool prefer_easf;
+	bool disable_easf;
+	struct spl_debug debug;
 };
 // end of SPL inputs
 
-- 
2.34.1


  parent reply	other threads:[~2024-05-16 19:27 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-16 19:26 [PATCH 00/24] DC Patches May 16, 2024 Roman.Li
2024-05-16 19:26 ` [PATCH 01/24] drm/amd/display: Move DSC functions from dc.c to dc_dsc.c Roman.Li
2024-05-16 19:26 ` [PATCH 02/24] drm/amd/display: Remove duplicate configuration Roman.Li
2024-05-16 19:26 ` [PATCH 03/24] drm/amd/display: Add missing enable and disable symclk_se functions for dcn401 Roman.Li
2024-05-16 19:26 ` [PATCH 04/24] drm/amd/display: Fix incorrect DCN401 comparison Roman.Li
2024-05-16 19:26 ` [PATCH 05/24] drm/amd/display: Use the correct TMDS function to avoid DVI issues Roman.Li
2024-05-16 19:26 ` [PATCH 06/24] drm/amd/display: Adjust incorrect indentations and spaces Roman.Li
2024-05-16 19:26 ` Roman.Li [this message]
2024-05-16 19:26 ` [PATCH 08/24] drm/amd/display: Refactor HUBBUB into component folder for DCN401 Roman.Li
2024-05-16 19:26 ` [PATCH 09/24] drm/amd/display: Modify HPO pixel clock programming to support DPM Roman.Li
2024-05-16 19:26 ` [PATCH 10/24] drm/amd/display: Add missing DML2 var helpers Roman.Li
2024-05-16 19:26 ` [PATCH 11/24] drm/amd/display: Add NULL check within get_target_mpc_factor Roman.Li
2024-05-16 19:26 ` [PATCH 12/24] drm/amd/display: Deallocate DML 2.1 Memory Allocation Roman.Li
2024-05-16 19:26 ` [PATCH 13/24] drm/amd/display: Add 3DLUT DMA load trigger Roman.Li
2024-05-16 19:26 ` [PATCH 14/24] drm/amd/display: Clear shared dmub firmware state on init Roman.Li
2024-05-16 19:26 ` [PATCH 15/24] drm/amd/display: Add ips status info to debugfs Roman.Li
2024-05-16 19:26 ` [PATCH 16/24] drm/amd/display: Fix pipe addition logic in calc_blocks_to_ungate DCN35 Roman.Li
2024-05-16 19:26 ` [PATCH 17/24] drm/amd/display: Remove redundant idle optimization check Roman.Li
2024-05-16 19:26 ` [PATCH 18/24] drm/amd/display: fix a typo which causes an incorrect ODM combine setup Roman.Li
2024-05-16 19:26 ` [PATCH 19/24] drm/amd/display: Fix ODM + underscan case with cursor Roman.Li
2024-05-16 19:26 ` [PATCH 20/24] drm/amd/display: Disable DCN401 idle optimizations Roman.Li
2024-05-16 19:26 ` [PATCH 21/24] drm/amd/display: Correct display clocks update block sequence Roman.Li
2024-05-16 19:26 ` [PATCH 22/24] drm/amd/display: Not fallback if link BW is smaller than req BW Roman.Li
2024-05-16 19:26 ` [PATCH 23/24] drm/amd/display: Fix POWERPC_64 compilation Roman.Li
2024-05-16 19:33   ` Aurabindo Pillai
2024-05-16 19:26 ` [PATCH 24/24] drm/amd/display: 3.2.286 Roman.Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240516192647.1522729-8-Roman.Li@amd.com \
    --to=roman.li@amd.com \
    --cc=Aurabindo.Pillai@amd.com \
    --cc=Harry.Wentland@amd.com \
    --cc=Rodrigo.Siqueira@amd.com \
    --cc=Samson.Tam@amd.com \
    --cc=Sunpeng.Li@amd.com \
    --cc=agustin.gutierrez@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=chiahsuan.chung@amd.com \
    --cc=jerry.zuo@amd.com \
    --cc=wayne.lin@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.