Commit c2ed7002 authored by Samson Tam's avatar Samson Tam Committed by Alex Deucher

drm/amd/display: Use SDR white level to calculate matrix coefficients

[WHY]
Certain profiles have higher HDR multiplier than SDR white level max
which is not currently supported.

[HOW]
Use SDR white level when calculating matrix coefficients for HDR RGB MPO
path instead of HDR multiplier.

Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Reviewed-by: default avatarJun Lei <jun.lei@amd.com>
Signed-off-by: default avatarSamson Tam <Samson.Tam@amd.com>
Signed-off-by: default avatarAlex Hung <alex.hung@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c03fca61
...@@ -2596,6 +2596,12 @@ static enum surface_update_type det_surface_update(const struct dc *dc, ...@@ -2596,6 +2596,12 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
elevate_update_type(&overall_type, UPDATE_TYPE_MED); elevate_update_type(&overall_type, UPDATE_TYPE_MED);
} }
if (u->sdr_white_level_nits)
if (u->sdr_white_level_nits != u->surface->sdr_white_level_nits) {
update_flags->bits.sdr_white_level_nits = 1;
elevate_update_type(&overall_type, UPDATE_TYPE_FULL);
}
if (u->cm2_params) { if (u->cm2_params) {
if ((u->cm2_params->component_settings.shaper_3dlut_setting if ((u->cm2_params->component_settings.shaper_3dlut_setting
!= u->surface->mcm_shaper_3dlut_setting) != u->surface->mcm_shaper_3dlut_setting)
...@@ -2876,6 +2882,10 @@ static void copy_surface_update_to_plane( ...@@ -2876,6 +2882,10 @@ static void copy_surface_update_to_plane(
surface->hdr_mult = surface->hdr_mult =
srf_update->hdr_mult; srf_update->hdr_mult;
if (srf_update->sdr_white_level_nits)
surface->sdr_white_level_nits =
srf_update->sdr_white_level_nits;
if (srf_update->blend_tf) if (srf_update->blend_tf)
memcpy(&surface->blend_tf, srf_update->blend_tf, memcpy(&surface->blend_tf, srf_update->blend_tf,
sizeof(surface->blend_tf)); sizeof(surface->blend_tf));
...@@ -4679,6 +4689,8 @@ static bool full_update_required(struct dc *dc, ...@@ -4679,6 +4689,8 @@ static bool full_update_required(struct dc *dc,
srf_updates[i].scaling_info || srf_updates[i].scaling_info ||
(srf_updates[i].hdr_mult.value && (srf_updates[i].hdr_mult.value &&
srf_updates[i].hdr_mult.value != srf_updates->surface->hdr_mult.value) || srf_updates[i].hdr_mult.value != srf_updates->surface->hdr_mult.value) ||
(srf_updates[i].sdr_white_level_nits &&
srf_updates[i].sdr_white_level_nits != srf_updates->surface->sdr_white_level_nits) ||
srf_updates[i].in_transfer_func || srf_updates[i].in_transfer_func ||
srf_updates[i].func_shaper || srf_updates[i].func_shaper ||
srf_updates[i].lut3d_func || srf_updates[i].lut3d_func ||
......
...@@ -1269,6 +1269,7 @@ union surface_update_flags { ...@@ -1269,6 +1269,7 @@ union surface_update_flags {
uint32_t tmz_changed:1; uint32_t tmz_changed:1;
uint32_t mcm_transfer_function_enable_change:1; /* disable or enable MCM transfer func */ uint32_t mcm_transfer_function_enable_change:1; /* disable or enable MCM transfer func */
uint32_t full_update:1; uint32_t full_update:1;
uint32_t sdr_white_level_nits:1;
} bits; } bits;
uint32_t raw; uint32_t raw;
...@@ -1351,6 +1352,7 @@ struct dc_plane_state { ...@@ -1351,6 +1352,7 @@ struct dc_plane_state {
bool adaptive_sharpness_en; bool adaptive_sharpness_en;
int sharpness_level; int sharpness_level;
enum linear_light_scaling linear_light_scaling; enum linear_light_scaling linear_light_scaling;
unsigned int sdr_white_level_nits;
}; };
struct dc_plane_info { struct dc_plane_info {
...@@ -1508,6 +1510,7 @@ struct dc_surface_update { ...@@ -1508,6 +1510,7 @@ struct dc_surface_update {
*/ */
struct dc_cm2_parameters *cm2_params; struct dc_cm2_parameters *cm2_params;
const struct dc_csc_transform *cursor_csc_color_matrix; const struct dc_csc_transform *cursor_csc_color_matrix;
unsigned int sdr_white_level_nits;
}; };
/* /*
......
...@@ -191,14 +191,7 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl ...@@ -191,14 +191,7 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
*/ */
spl_in->is_fullscreen = dm_helpers_is_fullscreen(pipe_ctx->stream->ctx, pipe_ctx->stream); spl_in->is_fullscreen = dm_helpers_is_fullscreen(pipe_ctx->stream->ctx, pipe_ctx->stream);
spl_in->is_hdr_on = dm_helpers_is_hdr_on(pipe_ctx->stream->ctx, pipe_ctx->stream); spl_in->is_hdr_on = dm_helpers_is_hdr_on(pipe_ctx->stream->ctx, pipe_ctx->stream);
spl_in->hdr_multx100 = 0; spl_in->sdr_white_level_nits = plane_state->sdr_white_level_nits;
if (spl_in->is_hdr_on) {
spl_in->hdr_multx100 = (uint32_t)dc_fixpt_floor(dc_fixpt_mul(plane_state->hdr_mult,
dc_fixpt_from_int(100)));
/* Disable sharpness for HDR Mult > 6.0 */
if (spl_in->hdr_multx100 > 600)
spl_in->adaptive_sharpness.enable = false;
}
} }
/// @brief Translate SPL output parameters to pipe context /// @brief Translate SPL output parameters to pipe context
......
...@@ -1155,14 +1155,19 @@ static void spl_set_dscl_prog_data(struct spl_in *spl_in, struct spl_scratch *sp ...@@ -1155,14 +1155,19 @@ static void spl_set_dscl_prog_data(struct spl_in *spl_in, struct spl_scratch *sp
} }
/* Calculate C0-C3 coefficients based on HDR_mult */ /* Calculate C0-C3 coefficients based on HDR_mult */
static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint32_t hdr_multx100) static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint32_t sdr_white_level_nits)
{ {
struct spl_fixed31_32 hdr_mult, c0_mult, c1_mult, c2_mult; struct spl_fixed31_32 hdr_mult, c0_mult, c1_mult, c2_mult;
struct spl_fixed31_32 c0_calc, c1_calc, c2_calc; struct spl_fixed31_32 c0_calc, c1_calc, c2_calc;
struct spl_custom_float_format fmt; struct spl_custom_float_format fmt;
uint32_t hdr_multx100_int;
SPL_ASSERT(hdr_multx100); if ((sdr_white_level_nits >= 80) && (sdr_white_level_nits <= 480))
hdr_mult = spl_fixpt_from_fraction((long long)hdr_multx100, 100LL); hdr_multx100_int = sdr_white_level_nits * 100 / 80;
else
hdr_multx100_int = 100; /* default for 80 nits otherwise */
hdr_mult = spl_fixpt_from_fraction((long long)hdr_multx100_int, 100LL);
c0_mult = spl_fixpt_from_fraction(2126LL, 10000LL); c0_mult = spl_fixpt_from_fraction(2126LL, 10000LL);
c1_mult = spl_fixpt_from_fraction(7152LL, 10000LL); c1_mult = spl_fixpt_from_fraction(7152LL, 10000LL);
c2_mult = spl_fixpt_from_fraction(722LL, 10000LL); c2_mult = spl_fixpt_from_fraction(722LL, 10000LL);
...@@ -1191,7 +1196,7 @@ static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint3 ...@@ -1191,7 +1196,7 @@ static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint3
static void spl_set_easf_data(struct spl_scratch *spl_scratch, struct spl_out *spl_out, bool enable_easf_v, static void spl_set_easf_data(struct spl_scratch *spl_scratch, struct spl_out *spl_out, bool enable_easf_v,
bool enable_easf_h, enum linear_light_scaling lls_pref, bool enable_easf_h, enum linear_light_scaling lls_pref,
enum spl_pixel_format format, enum system_setup setup, enum spl_pixel_format format, enum system_setup setup,
uint32_t hdr_multx100) uint32_t sdr_white_level_nits)
{ {
struct dscl_prog_data *dscl_prog_data = spl_out->dscl_prog_data; struct dscl_prog_data *dscl_prog_data = spl_out->dscl_prog_data;
if (enable_easf_v) { if (enable_easf_v) {
...@@ -1499,7 +1504,7 @@ static void spl_set_easf_data(struct spl_scratch *spl_scratch, struct spl_out *s ...@@ -1499,7 +1504,7 @@ static void spl_set_easf_data(struct spl_scratch *spl_scratch, struct spl_out *s
dscl_prog_data->easf_ltonl_en = 1; // Linear input dscl_prog_data->easf_ltonl_en = 1; // Linear input
if ((setup == HDR_L) && (spl_is_rgb8(format))) { if ((setup == HDR_L) && (spl_is_rgb8(format))) {
/* Calculate C0-C3 coefficients based on HDR multiplier */ /* Calculate C0-C3 coefficients based on HDR multiplier */
spl_calculate_c0_c3_hdr(dscl_prog_data, hdr_multx100); spl_calculate_c0_c3_hdr(dscl_prog_data, sdr_white_level_nits);
} else { // HDR_L ( DWM ) and SDR_L } else { // HDR_L ( DWM ) and SDR_L
dscl_prog_data->easf_matrix_c0 = dscl_prog_data->easf_matrix_c0 =
0x4EF7; // fp1.5.10, C0 coefficient (LN_rec709: 0.2126 * (2^14)/125 = 27.86590720) 0x4EF7; // fp1.5.10, C0 coefficient (LN_rec709: 0.2126 * (2^14)/125 = 27.86590720)
...@@ -1750,7 +1755,7 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out) ...@@ -1750,7 +1755,7 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out)
// Set EASF // Set EASF
spl_set_easf_data(&spl_scratch, spl_out, enable_easf_v, enable_easf_h, spl_in->lls_pref, spl_set_easf_data(&spl_scratch, spl_out, enable_easf_v, enable_easf_h, spl_in->lls_pref,
spl_in->basic_in.format, setup, spl_in->hdr_multx100); spl_in->basic_in.format, setup, spl_in->sdr_white_level_nits);
// Set iSHARP // Set iSHARP
vratio = spl_fixpt_ceil(spl_scratch.scl_data.ratios.vert); vratio = spl_fixpt_ceil(spl_scratch.scl_data.ratios.vert);
......
...@@ -518,7 +518,7 @@ struct spl_in { ...@@ -518,7 +518,7 @@ struct spl_in {
bool is_hdr_on; bool is_hdr_on;
int h_active; int h_active;
int v_active; int v_active;
int hdr_multx100; int sdr_white_level_nits;
}; };
// end of SPL inputs // end of SPL inputs
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment