From: Andri Yngvason <[email protected]> This includes YUV420 as well YUV444 and Auto. Auto will fallback to RGB to keep things sane and still working, similar to i915.
Signed-off-by: Werner Sembach <[email protected]> Signed-off-by: Andri Yngvason <[email protected]> Signed-off-by: Marius Vlad <[email protected]> Co-Developed-by: Andri Yngvason <[email protected]> Co-Developed-by: Marius Vlad <[email protected]> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 74 +++++++++++++++++-- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 13 ++++ 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index cc19c4bfd623..beb127471a61 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6426,15 +6426,32 @@ static void fill_stream_properties_from_drm_display_mode( timing_out->h_border_right = 0; timing_out->v_border_top = 0; timing_out->v_border_bottom = 0; - /* TODO: un-hardcode */ - if (drm_mode_is_420_only(info, mode_in) || (drm_mode_is_420_also(info, mode_in) && - aconnector && aconnector->force_yuv420_output)) + + if (drm_mode_is_420_also(info, mode_in) && aconnector && + (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR420 && + aconnector->force_yuv420_output)) { timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420; - else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444) - && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) + } else if ((connector_state && connector_state->color_format == DRM_COLOR_FORMAT_YCBCR444 && + connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444) + && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) { timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444; - else + } else if (connector_state && connector_state->color_format == DRM_COLOR_FORMAT_RGB444 && + !drm_mode_is_420_only(info, mode_in)) { timing_out->pixel_encoding = PIXEL_ENCODING_RGB; + } else { + /* + * connector_state->force_color_format not possible + * || connector_state->force_color_format == 0 (auto) + * || connector_state->force_color_format == DRM_COLOR_FORMAT_YCBCR422 + */ + if (drm_mode_is_420_only(info, mode_in)) + timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420; + else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444) + && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) + timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444; + else + timing_out->pixel_encoding = PIXEL_ENCODING_RGB; + } timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE; timing_out->display_color_depth = convert_color_depth_from_display_info( @@ -7664,6 +7681,37 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc, return dc_result; } +static enum dc_status +dm_validate_stream_color_format(const struct drm_connector_state *drm_state, + const struct dc_stream_state *stream) +{ + if (!drm_state->color_format || + drm_state->color_format == DRM_COLOR_FORMAT_NONE) + return DC_OK; + + enum dc_pixel_encoding encoding = PIXEL_ENCODING_UNDEFINED; + switch (drm_state->color_format) { + case DRM_COLOR_FORMAT_AUTO: + case DRM_COLOR_FORMAT_RGB444: + encoding = PIXEL_ENCODING_RGB; + break; + case DRM_COLOR_FORMAT_YCBCR444: + encoding = PIXEL_ENCODING_YCBCR444; + break; + case DRM_COLOR_FORMAT_YCBCR422: + encoding = PIXEL_ENCODING_YCBCR422; + break; + case DRM_COLOR_FORMAT_YCBCR420: + encoding = PIXEL_ENCODING_YCBCR420; + break; + default: + break; + } + + return encoding == stream->timing.pixel_encoding ? + DC_OK : DC_UNSUPPORTED_VALUE; +} + struct dc_stream_state * create_validate_stream_for_sink(struct drm_connector *connector, const struct drm_display_mode *drm_mode, @@ -7709,6 +7757,9 @@ create_validate_stream_for_sink(struct drm_connector *connector, if (dc_result == DC_OK) dc_result = dm_validate_stream_and_context(adev->dm.dc, stream); + if (dc_result == DC_OK) + dc_result = dm_validate_stream_color_format(drm_state, stream); + if (dc_result != DC_OK) { DRM_DEBUG_KMS("Pruned mode %d x %d (clk %d) %s %s -- %s\n", drm_mode->hdisplay, @@ -8477,6 +8528,13 @@ static const u32 supported_colorspaces = BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) | BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); +static const u32 supported_colorformats = + DRM_COLOR_FORMAT_AUTO | + DRM_COLOR_FORMAT_RGB444 | + DRM_COLOR_FORMAT_YCBCR444 | + DRM_COLOR_FORMAT_YCBCR422 | + DRM_COLOR_FORMAT_YCBCR420; + void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, struct amdgpu_dm_connector *aconnector, int connector_type, @@ -8564,10 +8622,14 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, if (connector_type == DRM_MODE_CONNECTOR_HDMIA) { if (!drm_mode_create_hdmi_colorspace_property(&aconnector->base, supported_colorspaces)) drm_connector_attach_colorspace_property(&aconnector->base); + if (!drm_mode_create_hdmi_color_format_property(&aconnector->base, supported_colorformats)) + drm_connector_attach_color_format_property(&aconnector->base); } else if ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !aconnector->mst_root) || connector_type == DRM_MODE_CONNECTOR_eDP) { if (!drm_mode_create_dp_colorspace_property(&aconnector->base, supported_colorspaces)) drm_connector_attach_colorspace_property(&aconnector->base); + if (!drm_mode_create_dp_color_format_property(&aconnector->base, supported_colorformats)) + drm_connector_attach_color_format_property(&aconnector->base); } if (connector_type == DRM_MODE_CONNECTOR_HDMIA || diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 6a817508c826..01f8f26fde0a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -52,6 +52,13 @@ #define PEAK_FACTOR_X1000 1006 +static const u32 supported_colorformats = + DRM_COLOR_FORMAT_AUTO | + DRM_COLOR_FORMAT_RGB444 | + DRM_COLOR_FORMAT_YCBCR444 | + DRM_COLOR_FORMAT_YCBCR422 | + DRM_COLOR_FORMAT_YCBCR420; + /* * This function handles both native AUX and I2C-Over-AUX transactions. */ @@ -679,6 +686,12 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, if (connector->max_bpc_property) drm_connector_attach_max_bpc_property(connector, 8, 16); + connector->color_format_property = master->base.color_format_property; + if (connector->color_format_property) { + if (!drm_mode_create_dp_color_format_property(&aconnector->base, supported_colorformats)) + drm_connector_attach_color_format_property(&aconnector->base); + } + connector->vrr_capable_property = master->base.vrr_capable_property; if (connector->vrr_capable_property) drm_connector_attach_vrr_capable_property(connector); -- 2.47.2
