mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
drm/amd/display: Wrong colorimetry workaround
[ Upstream commit b1a98cf89a ]
[Why]
For FreeSync HDR, native color space flag in AMD VSIF(BT.709) should be
used when intepreting content and color space flag in VSC or AVI
infoFrame should be ignored. However, it turned out some userspace
application still use color flag in VSC or AVI infoFrame which is
incorrect.
[How]
Transfer function is used when building the VSC and AVI infoFrame. Set
colorimetry to BT.709 when all the following match:
1. Pixel format is YCbCr;
2. In FreeSync 2 HDR, color is COLOR_SPACE_2020_YCBCR;
3. Transfer function is TRANSFER_FUNC_GAMMA_22;
Tested-by: Mark Broadworth <mark.broadworth@amd.com>
Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Ma Hanghong <hanghong.ma@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: e6a7df96facd ("drm/amd/display: Fix MST Null Ptr for RV")
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
@@ -5938,6 +5938,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||||||
bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false;
|
bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false;
|
||||||
int mode_refresh;
|
int mode_refresh;
|
||||||
int preferred_refresh = 0;
|
int preferred_refresh = 0;
|
||||||
|
enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN;
|
||||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||||
struct dsc_dec_dpcd_caps dsc_caps;
|
struct dsc_dec_dpcd_caps dsc_caps;
|
||||||
#endif
|
#endif
|
||||||
@@ -6071,7 +6072,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||||||
if (stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED)
|
if (stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED)
|
||||||
stream->use_vsc_sdp_for_colorimetry = true;
|
stream->use_vsc_sdp_for_colorimetry = true;
|
||||||
}
|
}
|
||||||
mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space);
|
if (stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22)
|
||||||
|
tf = TRANSFER_FUNC_GAMMA_22;
|
||||||
|
mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space, tf);
|
||||||
aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
|
aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3038,6 +3038,12 @@ static void set_avi_info_frame(
|
|||||||
hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED;
|
hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pixel_encoding && color_space == COLOR_SPACE_2020_YCBCR &&
|
||||||
|
stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
|
||||||
|
hdmi_info.bits.EC0_EC2 = 0;
|
||||||
|
hdmi_info.bits.C0_C1 = COLORIMETRY_ITU709;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: un-hardcode aspect ratio */
|
/* TODO: un-hardcode aspect ratio */
|
||||||
aspect = stream->timing.aspect_ratio;
|
aspect = stream->timing.aspect_ratio;
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ struct mod_vrr_params;
|
|||||||
|
|
||||||
void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
|
void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
|
||||||
struct dc_info_packet *info_packet,
|
struct dc_info_packet *info_packet,
|
||||||
enum dc_color_space cs);
|
enum dc_color_space cs,
|
||||||
|
enum color_transfer_func tf);
|
||||||
|
|
||||||
void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
|
void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
|
||||||
struct dc_info_packet *info_packet);
|
struct dc_info_packet *info_packet);
|
||||||
|
|||||||
@@ -132,7 +132,8 @@ enum ColorimetryYCCDP {
|
|||||||
|
|
||||||
void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
|
void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
|
||||||
struct dc_info_packet *info_packet,
|
struct dc_info_packet *info_packet,
|
||||||
enum dc_color_space cs)
|
enum dc_color_space cs,
|
||||||
|
enum color_transfer_func tf)
|
||||||
{
|
{
|
||||||
unsigned int vsc_packet_revision = vsc_packet_undefined;
|
unsigned int vsc_packet_revision = vsc_packet_undefined;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@@ -382,6 +383,9 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
|
|||||||
colorimetryFormat = ColorimetryYCC_DP_AdobeYCC;
|
colorimetryFormat = ColorimetryYCC_DP_AdobeYCC;
|
||||||
else if (cs == COLOR_SPACE_2020_YCBCR)
|
else if (cs == COLOR_SPACE_2020_YCBCR)
|
||||||
colorimetryFormat = ColorimetryYCC_DP_ITU2020YCbCr;
|
colorimetryFormat = ColorimetryYCC_DP_ITU2020YCbCr;
|
||||||
|
|
||||||
|
if (cs == COLOR_SPACE_2020_YCBCR && tf == TRANSFER_FUNC_GAMMA_22)
|
||||||
|
colorimetryFormat = ColorimetryYCC_DP_ITU709;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user