Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Jun Lei <jun.lei@amd.com>
Signed-off-by: Samson Tam <Samson.Tam@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Samson Tam and committed by
Alex Deucher
c2ed7002 c03fca61

+28 -15
+12
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 2596 2596 elevate_update_type(&overall_type, UPDATE_TYPE_MED); 2597 2597 } 2598 2598 2599 + if (u->sdr_white_level_nits) 2600 + if (u->sdr_white_level_nits != u->surface->sdr_white_level_nits) { 2601 + update_flags->bits.sdr_white_level_nits = 1; 2602 + elevate_update_type(&overall_type, UPDATE_TYPE_FULL); 2603 + } 2604 + 2599 2605 if (u->cm2_params) { 2600 2606 if ((u->cm2_params->component_settings.shaper_3dlut_setting 2601 2607 != u->surface->mcm_shaper_3dlut_setting) ··· 2881 2875 if (srf_update->hdr_mult.value) 2882 2876 surface->hdr_mult = 2883 2877 srf_update->hdr_mult; 2878 + 2879 + if (srf_update->sdr_white_level_nits) 2880 + surface->sdr_white_level_nits = 2881 + srf_update->sdr_white_level_nits; 2884 2882 2885 2883 if (srf_update->blend_tf) 2886 2884 memcpy(&surface->blend_tf, srf_update->blend_tf, ··· 4689 4679 srf_updates[i].scaling_info || 4690 4680 (srf_updates[i].hdr_mult.value && 4691 4681 srf_updates[i].hdr_mult.value != srf_updates->surface->hdr_mult.value) || 4682 + (srf_updates[i].sdr_white_level_nits && 4683 + srf_updates[i].sdr_white_level_nits != srf_updates->surface->sdr_white_level_nits) || 4692 4684 srf_updates[i].in_transfer_func || 4693 4685 srf_updates[i].func_shaper || 4694 4686 srf_updates[i].lut3d_func ||
+3
drivers/gpu/drm/amd/display/dc/dc.h
··· 1269 1269 uint32_t tmz_changed:1; 1270 1270 uint32_t mcm_transfer_function_enable_change:1; /* disable or enable MCM transfer func */ 1271 1271 uint32_t full_update:1; 1272 + uint32_t sdr_white_level_nits:1; 1272 1273 } bits; 1273 1274 1274 1275 uint32_t raw; ··· 1352 1351 bool adaptive_sharpness_en; 1353 1352 int sharpness_level; 1354 1353 enum linear_light_scaling linear_light_scaling; 1354 + unsigned int sdr_white_level_nits; 1355 1355 }; 1356 1356 1357 1357 struct dc_plane_info { ··· 1510 1508 */ 1511 1509 struct dc_cm2_parameters *cm2_params; 1512 1510 const struct dc_csc_transform *cursor_csc_color_matrix; 1511 + unsigned int sdr_white_level_nits; 1513 1512 }; 1514 1513 1515 1514 /*
+1 -8
drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
··· 191 191 */ 192 192 spl_in->is_fullscreen = dm_helpers_is_fullscreen(pipe_ctx->stream->ctx, pipe_ctx->stream); 193 193 spl_in->is_hdr_on = dm_helpers_is_hdr_on(pipe_ctx->stream->ctx, pipe_ctx->stream); 194 - spl_in->hdr_multx100 = 0; 195 - if (spl_in->is_hdr_on) { 196 - spl_in->hdr_multx100 = (uint32_t)dc_fixpt_floor(dc_fixpt_mul(plane_state->hdr_mult, 197 - dc_fixpt_from_int(100))); 198 - /* Disable sharpness for HDR Mult > 6.0 */ 199 - if (spl_in->hdr_multx100 > 600) 200 - spl_in->adaptive_sharpness.enable = false; 201 - } 194 + spl_in->sdr_white_level_nits = plane_state->sdr_white_level_nits; 202 195 } 203 196 204 197 /// @brief Translate SPL output parameters to pipe context
+11 -6
drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
··· 1155 1155 } 1156 1156 1157 1157 /* Calculate C0-C3 coefficients based on HDR_mult */ 1158 - static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint32_t hdr_multx100) 1158 + static void spl_calculate_c0_c3_hdr(struct dscl_prog_data *dscl_prog_data, uint32_t sdr_white_level_nits) 1159 1159 { 1160 1160 struct spl_fixed31_32 hdr_mult, c0_mult, c1_mult, c2_mult; 1161 1161 struct spl_fixed31_32 c0_calc, c1_calc, c2_calc; 1162 1162 struct spl_custom_float_format fmt; 1163 + uint32_t hdr_multx100_int; 1163 1164 1164 - SPL_ASSERT(hdr_multx100); 1165 - hdr_mult = spl_fixpt_from_fraction((long long)hdr_multx100, 100LL); 1165 + if ((sdr_white_level_nits >= 80) && (sdr_white_level_nits <= 480)) 1166 + hdr_multx100_int = sdr_white_level_nits * 100 / 80; 1167 + else 1168 + hdr_multx100_int = 100; /* default for 80 nits otherwise */ 1169 + 1170 + hdr_mult = spl_fixpt_from_fraction((long long)hdr_multx100_int, 100LL); 1166 1171 c0_mult = spl_fixpt_from_fraction(2126LL, 10000LL); 1167 1172 c1_mult = spl_fixpt_from_fraction(7152LL, 10000LL); 1168 1173 c2_mult = spl_fixpt_from_fraction(722LL, 10000LL); ··· 1196 1191 static void spl_set_easf_data(struct spl_scratch *spl_scratch, struct spl_out *spl_out, bool enable_easf_v, 1197 1192 bool enable_easf_h, enum linear_light_scaling lls_pref, 1198 1193 enum spl_pixel_format format, enum system_setup setup, 1199 - uint32_t hdr_multx100) 1194 + uint32_t sdr_white_level_nits) 1200 1195 { 1201 1196 struct dscl_prog_data *dscl_prog_data = spl_out->dscl_prog_data; 1202 1197 if (enable_easf_v) { ··· 1504 1499 dscl_prog_data->easf_ltonl_en = 1; // Linear input 1505 1500 if ((setup == HDR_L) && (spl_is_rgb8(format))) { 1506 1501 /* Calculate C0-C3 coefficients based on HDR multiplier */ 1507 - spl_calculate_c0_c3_hdr(dscl_prog_data, hdr_multx100); 1502 + spl_calculate_c0_c3_hdr(dscl_prog_data, sdr_white_level_nits); 1508 1503 } else { // HDR_L ( DWM ) and SDR_L 1509 1504 dscl_prog_data->easf_matrix_c0 = 1510 1505 0x4EF7; // fp1.5.10, C0 coefficient (LN_rec709: 0.2126 * (2^14)/125 = 27.86590720) ··· 1755 1750 1756 1751 // Set EASF 1757 1752 spl_set_easf_data(&spl_scratch, spl_out, enable_easf_v, enable_easf_h, spl_in->lls_pref, 1758 - spl_in->basic_in.format, setup, spl_in->hdr_multx100); 1753 + spl_in->basic_in.format, setup, spl_in->sdr_white_level_nits); 1759 1754 1760 1755 // Set iSHARP 1761 1756 vratio = spl_fixpt_ceil(spl_scratch.scl_data.ratios.vert);
+1 -1
drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
··· 518 518 bool is_hdr_on; 519 519 int h_active; 520 520 int v_active; 521 - int hdr_multx100; 521 + int sdr_white_level_nits; 522 522 }; 523 523 // end of SPL inputs 524 524