aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2647-drm-amd-display-Add-timing-validation-against-dongle.patch
diff options
context:
space:
mode:
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.patch189
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
+