Commit 4c4583fd authored by Joshua Ashton's avatar Joshua Ashton Committed by Alex Deucher

drm/amd/display: Hook up 'content type' property for HDMI

Implements the 'content type' property for HDMI connectors.
Verified by checking the avi infoframe on a connected TV.

This also simplifies a lot of the code in that area as well, there were
a lot of temp variables doing very little and unnecessary logic
that was quite confusing.

It is not necessary to check for support in the EDID before sending a
'content type' value in the avi infoframe also.

v2:
- rebase to amd-staging-drm-next
- mark CRTC state for reset if content_type differs

Reviewed-by: Harry Wentland <harry.wentland@amd.com> (v1)
Signed-off-by: default avatarJoshua Ashton <joshua@froggi.es>
Co-developed-by: default avatarMelissa Wen <mwen@igalia.com>
Signed-off-by: default avatarMelissa Wen <mwen@igalia.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5838f74c
...@@ -5457,6 +5457,24 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing, ...@@ -5457,6 +5457,24 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing,
return color_space; return color_space;
} }
static enum display_content_type
get_output_content_type(const struct drm_connector_state *connector_state)
{
switch (connector_state->content_type) {
default:
case DRM_MODE_CONTENT_TYPE_NO_DATA:
return DISPLAY_CONTENT_TYPE_NO_DATA;
case DRM_MODE_CONTENT_TYPE_GRAPHICS:
return DISPLAY_CONTENT_TYPE_GRAPHICS;
case DRM_MODE_CONTENT_TYPE_PHOTO:
return DISPLAY_CONTENT_TYPE_PHOTO;
case DRM_MODE_CONTENT_TYPE_CINEMA:
return DISPLAY_CONTENT_TYPE_CINEMA;
case DRM_MODE_CONTENT_TYPE_GAME:
return DISPLAY_CONTENT_TYPE_GAME;
}
}
static bool adjust_colour_depth_from_display_info( static bool adjust_colour_depth_from_display_info(
struct dc_crtc_timing *timing_out, struct dc_crtc_timing *timing_out,
const struct drm_display_info *info) const struct drm_display_info *info)
...@@ -5591,6 +5609,7 @@ static void fill_stream_properties_from_drm_display_mode( ...@@ -5591,6 +5609,7 @@ static void fill_stream_properties_from_drm_display_mode(
} }
stream->output_color_space = get_output_color_space(timing_out, connector_state); stream->output_color_space = get_output_color_space(timing_out, connector_state);
stream->content_type = get_output_content_type(connector_state);
} }
static void fill_audio_info(struct audio_info *audio_info, static void fill_audio_info(struct audio_info *audio_info,
...@@ -6791,6 +6810,14 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn, ...@@ -6791,6 +6810,14 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
new_crtc_state->mode_changed = true; new_crtc_state->mode_changed = true;
} }
if (new_con_state->content_type != old_con_state->content_type) {
new_crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(new_crtc_state))
return PTR_ERR(new_crtc_state);
new_crtc_state->mode_changed = true;
}
if (!drm_connector_atomic_hdr_metadata_equal(old_con_state, new_con_state)) { if (!drm_connector_atomic_hdr_metadata_equal(old_con_state, new_con_state)) {
struct dc_info_packet hdr_infopacket; struct dc_info_packet hdr_infopacket;
...@@ -7426,6 +7453,11 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, ...@@ -7426,6 +7453,11 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
adev->mode_info.abm_level_property, 0); adev->mode_info.abm_level_property, 0);
} }
if (connector_type == DRM_MODE_CONNECTOR_HDMIA) {
/* Content Type is currently only implemented for HDMI. */
drm_connector_attach_content_type_property(&aconnector->base);
}
if (connector_type == DRM_MODE_CONNECTOR_HDMIA) { if (connector_type == DRM_MODE_CONNECTOR_HDMIA) {
if (!drm_mode_create_hdmi_colorspace_property(&aconnector->base, supported_colorspaces)) if (!drm_mode_create_hdmi_colorspace_property(&aconnector->base, supported_colorspaces))
drm_connector_attach_colorspace_property(&aconnector->base); drm_connector_attach_colorspace_property(&aconnector->base);
......
...@@ -3928,14 +3928,9 @@ static void set_avi_info_frame( ...@@ -3928,14 +3928,9 @@ static void set_avi_info_frame(
uint32_t pixel_encoding = 0; uint32_t pixel_encoding = 0;
enum scanning_type scan_type = SCANNING_TYPE_NODATA; enum scanning_type scan_type = SCANNING_TYPE_NODATA;
enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA; enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA;
bool itc = false;
uint8_t itc_value = 0;
uint8_t cn0_cn1 = 0;
unsigned int cn0_cn1_value = 0;
uint8_t *check_sum = NULL; uint8_t *check_sum = NULL;
uint8_t byte_index = 0; uint8_t byte_index = 0;
union hdmi_info_packet hdmi_info; union hdmi_info_packet hdmi_info;
union display_content_support support = {0};
unsigned int vic = pipe_ctx->stream->timing.vic; unsigned int vic = pipe_ctx->stream->timing.vic;
unsigned int rid = pipe_ctx->stream->timing.rid; unsigned int rid = pipe_ctx->stream->timing.rid;
unsigned int fr_ind = pipe_ctx->stream->timing.fr_index; unsigned int fr_ind = pipe_ctx->stream->timing.fr_index;
...@@ -4045,49 +4040,27 @@ static void set_avi_info_frame( ...@@ -4045,49 +4040,27 @@ static void set_avi_info_frame(
/* Active Format Aspect ratio - same as Picture Aspect Ratio. */ /* Active Format Aspect ratio - same as Picture Aspect Ratio. */
hdmi_info.bits.R0_R3 = ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE; hdmi_info.bits.R0_R3 = ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE;
/* TODO: un-hardcode cn0_cn1 and itc */ switch (stream->content_type) {
case DISPLAY_CONTENT_TYPE_NO_DATA:
cn0_cn1 = 0; hdmi_info.bits.CN0_CN1 = 0;
cn0_cn1_value = 0; hdmi_info.bits.ITC = 0;
break;
itc = true; case DISPLAY_CONTENT_TYPE_GRAPHICS:
itc_value = 1; hdmi_info.bits.CN0_CN1 = 0;
hdmi_info.bits.ITC = 1;
support = stream->content_support; break;
case DISPLAY_CONTENT_TYPE_PHOTO:
if (itc) { hdmi_info.bits.CN0_CN1 = 1;
if (!support.bits.valid_content_type) { hdmi_info.bits.ITC = 1;
cn0_cn1_value = 0; break;
} else { case DISPLAY_CONTENT_TYPE_CINEMA:
if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GRAPHICS) { hdmi_info.bits.CN0_CN1 = 2;
if (support.bits.graphics_content == 1) { hdmi_info.bits.ITC = 1;
cn0_cn1_value = 0; break;
} case DISPLAY_CONTENT_TYPE_GAME:
} else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_PHOTO) { hdmi_info.bits.CN0_CN1 = 3;
if (support.bits.photo_content == 1) { hdmi_info.bits.ITC = 1;
cn0_cn1_value = 1; break;
} else {
cn0_cn1_value = 0;
itc_value = 0;
}
} else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_CINEMA) {
if (support.bits.cinema_content == 1) {
cn0_cn1_value = 2;
} else {
cn0_cn1_value = 0;
itc_value = 0;
}
} else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GAME) {
if (support.bits.game_content == 1) {
cn0_cn1_value = 3;
} else {
cn0_cn1_value = 0;
itc_value = 0;
}
}
}
hdmi_info.bits.CN0_CN1 = cn0_cn1_value;
hdmi_info.bits.ITC = itc_value;
} }
if (stream->qs_bit == 1) { if (stream->qs_bit == 1) {
......
...@@ -212,6 +212,7 @@ struct dc_stream_state { ...@@ -212,6 +212,7 @@ struct dc_stream_state {
struct dc_csc_transform csc_color_matrix; struct dc_csc_transform csc_color_matrix;
enum dc_color_space output_color_space; enum dc_color_space output_color_space;
enum display_content_type content_type;
enum dc_dither_option dither_option; enum dc_dither_option dither_option;
enum view_3d_format view_format; enum view_3d_format view_format;
......
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