| From 64fd76135c5b0e58275ea83cf25f941293720819 Mon Sep 17 00:00:00 2001 |
| From: Martin Leung <martin.leung@amd.com> |
| Date: Wed, 13 Feb 2019 17:06:31 -0500 |
| Subject: drm/amd/display: half bandwidth for YCbCr420 during validation |
| |
| [ Upstream commit 162f807858d15bde60cf373a3ad46e03200ad9d8 ] |
| |
| [Why] |
| used to be unable to run 4:2:0 if using a dongle because 4k60 bandwidth |
| exceeded dongle caps |
| |
| [How] |
| half pixel clock during comparison to dongle cap. *Could get stuck on black |
| screen on monitor that don't support 420 but will be selecting 420 as |
| preferred mode* |
| |
| Signed-off-by: Martin Leung <martin.leung@amd.com> |
| Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com> |
| Acked-by: Aidan Wood <Aidan.Wood@amd.com> |
| Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/drm/amd/display/dc/core/dc_link.c | 33 +++++++++++-------- |
| 1 file changed, 20 insertions(+), 13 deletions(-) |
| |
| 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 ea2f271e234bd..419e8de8c0f48 100644 |
| --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c |
| +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c |
| @@ -2074,11 +2074,28 @@ static void disable_link(struct dc_link *link, enum signal_type signal) |
| } |
| } |
| |
| +static uint32_t get_timing_pixel_clock_100hz(const struct dc_crtc_timing *timing) |
| +{ |
| + |
| + uint32_t pxl_clk = timing->pix_clk_100hz; |
| + |
| + if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
| + pxl_clk /= 2; |
| + else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) |
| + pxl_clk = pxl_clk * 2 / 3; |
| + |
| + if (timing->display_color_depth == COLOR_DEPTH_101010) |
| + pxl_clk = pxl_clk * 10 / 8; |
| + else if (timing->display_color_depth == COLOR_DEPTH_121212) |
| + pxl_clk = pxl_clk * 12 / 8; |
| + |
| + return pxl_clk; |
| +} |
| + |
| static bool dp_active_dongle_validate_timing( |
| const struct dc_crtc_timing *timing, |
| const struct dpcd_caps *dpcd_caps) |
| { |
| - unsigned int required_pix_clk_100hz = timing->pix_clk_100hz; |
| const struct dc_dongle_caps *dongle_caps = &dpcd_caps->dongle_caps; |
| |
| switch (dpcd_caps->dongle_type) { |
| @@ -2115,13 +2132,6 @@ static bool dp_active_dongle_validate_timing( |
| return false; |
| } |
| |
| - |
| - /* Check Color Depth and Pixel Clock */ |
| - if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
| - required_pix_clk_100hz /= 2; |
| - else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) |
| - required_pix_clk_100hz = required_pix_clk_100hz * 2 / 3; |
| - |
| switch (timing->display_color_depth) { |
| case COLOR_DEPTH_666: |
| case COLOR_DEPTH_888: |
| @@ -2130,14 +2140,11 @@ static bool dp_active_dongle_validate_timing( |
| case COLOR_DEPTH_101010: |
| if (dongle_caps->dp_hdmi_max_bpc < 10) |
| return false; |
| - required_pix_clk_100hz = required_pix_clk_100hz * 10 / 8; |
| break; |
| case COLOR_DEPTH_121212: |
| if (dongle_caps->dp_hdmi_max_bpc < 12) |
| return false; |
| - required_pix_clk_100hz = required_pix_clk_100hz * 12 / 8; |
| break; |
| - |
| case COLOR_DEPTH_141414: |
| case COLOR_DEPTH_161616: |
| default: |
| @@ -2145,7 +2152,7 @@ static bool dp_active_dongle_validate_timing( |
| return false; |
| } |
| |
| - if (required_pix_clk_100hz > (dongle_caps->dp_hdmi_max_pixel_clk * 10)) |
| + if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk * 10)) |
| return false; |
| |
| return true; |
| @@ -2166,7 +2173,7 @@ enum dc_status dc_link_validate_mode_timing( |
| return DC_OK; |
| |
| /* Passive Dongle */ |
| - if (0 != max_pix_clk && timing->pix_clk_100hz > max_pix_clk) |
| + if (max_pix_clk != 0 && get_timing_pixel_clock_100hz(timing) > max_pix_clk) |
| return DC_EXCEED_DONGLE_CAP; |
| |
| /* Active Dongle*/ |
| -- |
| 2.20.1 |
| |