drm/amd/display: Avoid conflict between HDR multiplier and 3dlut
[WHY] There can be a conflict between OS HDR multiplier and 3dlut HDR multiplier, which are both sent to DC. [HOW] Instead of having dc determine which HDR multiplier to use, make the decision in dm and send only the intended value in a surface update. Store the current OS HDR multiplier and determine whether to use it or the 3dlut's multiplier before sending the surface update to dc. Send multiplier to dc in fixed31_32 format, dc then converts it to hw format. Signed-off-by: Michael Strauss <michael.strauss@amd.com> Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
9185e8adb4
commit
46250a0cba
|
@ -1469,11 +1469,6 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
|
|||
elevate_update_type(&update_type, UPDATE_TYPE_MED);
|
||||
}
|
||||
|
||||
if (u->plane_info->sdr_white_level != u->surface->sdr_white_level) {
|
||||
update_flags->bits.sdr_white_level = 1;
|
||||
elevate_update_type(&update_type, UPDATE_TYPE_MED);
|
||||
}
|
||||
|
||||
if (u->plane_info->dcc.enable != u->surface->dcc.enable
|
||||
|| u->plane_info->dcc.independent_64b_blks != u->surface->dcc.independent_64b_blks
|
||||
|| u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) {
|
||||
|
@ -1620,6 +1615,12 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
|
|||
update_flags->bits.gamma_change = 1;
|
||||
}
|
||||
|
||||
if (u->hdr_mult.value)
|
||||
if (u->hdr_mult.value != u->surface->hdr_mult.value) {
|
||||
update_flags->bits.hdr_mult = 1;
|
||||
elevate_update_type(&overall_type, UPDATE_TYPE_MED);
|
||||
}
|
||||
|
||||
if (update_flags->bits.in_transfer_func_change) {
|
||||
type = UPDATE_TYPE_MED;
|
||||
elevate_update_type(&overall_type, type);
|
||||
|
@ -1801,8 +1802,6 @@ static void copy_surface_update_to_plane(
|
|||
srf_update->plane_info->global_alpha_value;
|
||||
surface->dcc =
|
||||
srf_update->plane_info->dcc;
|
||||
surface->sdr_white_level =
|
||||
srf_update->plane_info->sdr_white_level;
|
||||
surface->layer_index =
|
||||
srf_update->plane_info->layer_index;
|
||||
}
|
||||
|
@ -1847,6 +1846,10 @@ static void copy_surface_update_to_plane(
|
|||
memcpy(surface->lut3d_func, srf_update->lut3d_func,
|
||||
sizeof(*surface->lut3d_func));
|
||||
|
||||
if (srf_update->hdr_mult.value)
|
||||
surface->hdr_mult =
|
||||
srf_update->hdr_mult;
|
||||
|
||||
if (srf_update->blend_tf &&
|
||||
(surface->blend_tf !=
|
||||
srf_update->blend_tf))
|
||||
|
|
|
@ -667,7 +667,7 @@ union dc_3dlut_state {
|
|||
struct dc_3dlut {
|
||||
struct kref refcount;
|
||||
struct tetrahedral_params lut_3d;
|
||||
uint32_t hdr_multiplier;
|
||||
struct fixed31_32 hdr_multiplier;
|
||||
bool initialized; /*remove after diag fix*/
|
||||
union dc_3dlut_state state;
|
||||
struct dc_context *ctx;
|
||||
|
@ -694,7 +694,7 @@ union surface_update_flags {
|
|||
uint32_t horizontal_mirror_change:1;
|
||||
uint32_t per_pixel_alpha_change:1;
|
||||
uint32_t global_alpha_change:1;
|
||||
uint32_t sdr_white_level:1;
|
||||
uint32_t hdr_mult:1;
|
||||
uint32_t rotation_change:1;
|
||||
uint32_t swizzle_change:1;
|
||||
uint32_t scaling_change:1;
|
||||
|
@ -738,7 +738,7 @@ struct dc_plane_state {
|
|||
struct dc_bias_and_scale *bias_and_scale;
|
||||
struct dc_csc_transform input_csc_color_matrix;
|
||||
struct fixed31_32 coeff_reduction_factor;
|
||||
uint32_t sdr_white_level;
|
||||
struct fixed31_32 hdr_mult;
|
||||
|
||||
// TODO: No longer used, remove
|
||||
struct dc_hdr_static_metadata hdr_static_ctx;
|
||||
|
@ -783,7 +783,6 @@ struct dc_plane_info {
|
|||
enum dc_rotation_angle rotation;
|
||||
enum plane_stereo_format stereo_format;
|
||||
enum dc_color_space color_space;
|
||||
unsigned int sdr_white_level;
|
||||
bool horizontal_mirror;
|
||||
bool visible;
|
||||
bool per_pixel_alpha;
|
||||
|
@ -807,7 +806,7 @@ struct dc_surface_update {
|
|||
const struct dc_flip_addrs *flip_addr;
|
||||
const struct dc_plane_info *plane_info;
|
||||
const struct dc_scaling_info *scaling_info;
|
||||
|
||||
struct fixed31_32 hdr_mult;
|
||||
/* following updates require alloc/sleep/spin that is not isr safe,
|
||||
* null means no updates
|
||||
*/
|
||||
|
|
|
@ -2457,16 +2457,20 @@ static void dcn10_blank_pixel_data(
|
|||
|
||||
void set_hdr_multiplier(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct fixed31_32 multiplier = dc_fixpt_from_fraction(
|
||||
pipe_ctx->plane_state->sdr_white_level, 80);
|
||||
struct fixed31_32 multiplier = pipe_ctx->plane_state->hdr_mult;
|
||||
uint32_t hw_mult = 0x1f000; // 1.0 default multiplier
|
||||
struct custom_float_format fmt;
|
||||
bool mult_negative; // True if fixed31_32 sign bit indicates negative value
|
||||
uint32_t mult_int; // int component of fixed31_32
|
||||
|
||||
fmt.exponenta_bits = 6;
|
||||
fmt.mantissa_bits = 12;
|
||||
fmt.sign = true;
|
||||
|
||||
if (pipe_ctx->plane_state->sdr_white_level > 80)
|
||||
mult_negative = multiplier.value >> 63 != 0;
|
||||
mult_int = multiplier.value >> 32;
|
||||
|
||||
if (mult_int && !mult_negative) // Check if greater than 1
|
||||
convert_to_custom_float_format(multiplier, &fmt, &hw_mult);
|
||||
|
||||
pipe_ctx->plane_res.dpp->funcs->dpp_set_hdr_multiplier(
|
||||
|
|
|
@ -734,14 +734,6 @@ bool dcn20_set_shaper_3dlut(
|
|||
else
|
||||
result = dpp_base->funcs->dpp_program_3dlut(dpp_base, NULL);
|
||||
|
||||
if (plane_state->lut3d_func &&
|
||||
plane_state->lut3d_func->state.bits.initialized == 1 &&
|
||||
plane_state->lut3d_func->hdr_multiplier != 0)
|
||||
dpp_base->funcs->dpp_set_hdr_multiplier(dpp_base,
|
||||
plane_state->lut3d_func->hdr_multiplier);
|
||||
else
|
||||
dpp_base->funcs->dpp_set_hdr_multiplier(dpp_base, 0x1f000);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1382,7 +1374,7 @@ static void dcn20_program_pipe(
|
|||
dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
|
||||
|
||||
if (pipe_ctx->update_flags.bits.enable
|
||||
|| pipe_ctx->plane_state->update_flags.bits.sdr_white_level)
|
||||
|| pipe_ctx->plane_state->update_flags.bits.hdr_mult)
|
||||
set_hdr_multiplier(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->update_flags.bits.enable ||
|
||||
|
|
Loading…
Reference in New Issue