diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2647-drm-amd-display-Add-timing-validation-against-dongle.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2647-drm-amd-display-Add-timing-validation-against-dongle.patch | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2647-drm-amd-display-Add-timing-validation-against-dongle.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2647-drm-amd-display-Add-timing-validation-against-dongle.patch new file mode 100644 index 00000000..61c0c14c --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2647-drm-amd-display-Add-timing-validation-against-dongle.patch @@ -0,0 +1,189 @@ +From 42ed57b765431b67de8aeba48c91758542b3fdba Mon Sep 17 00:00:00 2001 +From: Eric Yang <Eric.Yang2@amd.com> +Date: Wed, 18 Oct 2017 20:22:40 -0400 +Subject: [PATCH 2647/4131] drm/amd/display: Add timing validation against + dongle cap + +For DP active dongles, the dpcd dongle caps are read but not +used to validate mode timing. This addresses this. + +In particular, this change fixes light up on the HDMI 4k TV +connected through DP active dongle. Since the 4k TV defaults +to YCbCr420, which the dongle don't support. + +This change does not address MST cases, a more generalized +approach must be taken for that. + +Signed-off-by: Eric Yang <Eric.Yang2@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 1 + + drivers/gpu/drm/amd/display/dc/core/dc_link.c | 70 +++++++++++++++++++++++- + drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 21 ++++++- + drivers/gpu/drm/amd/display/dc/inc/core_status.h | 2 +- + 4 files changed, 91 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index a178838..c690b48 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -128,6 +128,7 @@ static bool create_links( + link->link_id.id = CONNECTOR_ID_VIRTUAL; + link->link_id.enum_id = ENUM_ID_1; + link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL); ++ link->link_status.dpcd_caps = &link->dpcd_caps; + + enc_init.ctx = dc->ctx; + enc_init.channel = CHANNEL_ID_UNKNOWN; +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +index e70612e..18294df 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +@@ -1801,12 +1801,75 @@ static void disable_link(struct dc_link *link, enum signal_type signal) + link->link_enc->funcs->disable_output(link->link_enc, signal, link); + } + ++bool dp_active_dongle_validate_timing( ++ const struct dc_crtc_timing *timing, ++ const struct dc_dongle_caps *dongle_caps) ++{ ++ unsigned int required_pix_clk = timing->pix_clk_khz; ++ ++ if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || ++ dongle_caps->extendedCapValid == false) ++ return true; ++ ++ /* Check Pixel Encoding */ ++ switch (timing->pixel_encoding) { ++ case PIXEL_ENCODING_RGB: ++ case PIXEL_ENCODING_YCBCR444: ++ break; ++ case PIXEL_ENCODING_YCBCR422: ++ if (!dongle_caps->is_dp_hdmi_ycbcr422_pass_through) ++ return false; ++ break; ++ case PIXEL_ENCODING_YCBCR420: ++ if (!dongle_caps->is_dp_hdmi_ycbcr420_pass_through) ++ return false; ++ break; ++ default: ++ /* Invalid Pixel Encoding*/ ++ return false; ++ } ++ ++ ++ /* Check Color Depth and Pixel Clock */ ++ if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ++ required_pix_clk /= 2; ++ ++ switch (timing->display_color_depth) { ++ case COLOR_DEPTH_666: ++ case COLOR_DEPTH_888: ++ /*888 and 666 should always be supported*/ ++ break; ++ case COLOR_DEPTH_101010: ++ if (dongle_caps->dp_hdmi_max_bpc < 10) ++ return false; ++ required_pix_clk = required_pix_clk * 10 / 8; ++ break; ++ case COLOR_DEPTH_121212: ++ if (dongle_caps->dp_hdmi_max_bpc < 12) ++ return false; ++ required_pix_clk = required_pix_clk * 12 / 8; ++ break; ++ ++ case COLOR_DEPTH_141414: ++ case COLOR_DEPTH_161616: ++ default: ++ /* These color depths are currently not supported */ ++ return false; ++ } ++ ++ if (required_pix_clk > dongle_caps->dp_hdmi_max_pixel_clk) ++ return false; ++ ++ return true; ++} ++ + enum dc_status dc_link_validate_mode_timing( + const struct dc_stream_state *stream, + struct dc_link *link, + const struct dc_crtc_timing *timing) + { + uint32_t max_pix_clk = stream->sink->dongle_max_pix_clk; ++ struct dc_dongle_caps *dongle_caps = &link->link_status.dpcd_caps->dongle_caps; + + /* A hack to avoid failing any modes for EDID override feature on + * topology change such as lower quality cable for DP or different dongle +@@ -1814,8 +1877,13 @@ enum dc_status dc_link_validate_mode_timing( + if (link->remote_sinks[0]) + return DC_OK; + ++ /* Passive Dongle */ + if (0 != max_pix_clk && timing->pix_clk_khz > max_pix_clk) +- return DC_EXCEED_DONGLE_MAX_CLK; ++ return DC_EXCEED_DONGLE_CAP; ++ ++ /* Active Dongle*/ ++ if (!dp_active_dongle_validate_timing(timing, dongle_caps)) ++ return DC_EXCEED_DONGLE_CAP; + + switch (stream->signal) { + case SIGNAL_TYPE_EDP: +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +index ced4248..8e97b42 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +@@ -2062,6 +2062,24 @@ bool is_dp_active_dongle(const struct dc_link *link) + (dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER); + } + ++static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc) ++{ ++ switch (bpc) { ++ case DOWN_STREAM_MAX_8BPC: ++ return 8; ++ case DOWN_STREAM_MAX_10BPC: ++ return 10; ++ case DOWN_STREAM_MAX_12BPC: ++ return 12; ++ case DOWN_STREAM_MAX_16BPC: ++ return 16; ++ default: ++ break; ++ } ++ ++ return -1; ++} ++ + static void get_active_converter_info( + uint8_t data, struct dc_link *link) + { +@@ -2131,7 +2149,8 @@ static void get_active_converter_info( + hdmi_caps.bits.YCrCr420_CONVERSION; + + link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc = +- hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT; ++ translate_dpcd_max_bpc( ++ hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT); + + link->dpcd_caps.dongle_caps.extendedCapValid = true; + } +diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h b/drivers/gpu/drm/amd/display/dc/inc/core_status.h +index 01df856..94fc310 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h +@@ -38,7 +38,7 @@ enum dc_status { + DC_FAIL_DETACH_SURFACES = 8, + DC_FAIL_SURFACE_VALIDATE = 9, + DC_NO_DP_LINK_BANDWIDTH = 10, +- DC_EXCEED_DONGLE_MAX_CLK = 11, ++ DC_EXCEED_DONGLE_CAP = 11, + DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 12, + DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */ + DC_FAIL_SCALING = 14, +-- +2.7.4 + |