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:
Michael Strauss 2019-11-03 09:35:03 -05:00 committed by Alex Deucher
parent 9185e8adb4
commit 46250a0cba
4 changed files with 22 additions and 24 deletions

View File

@ -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))

View File

@ -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
*/

View File

@ -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(

View File

@ -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 ||