diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4704-drm-amd-display-add-dsc-policy-getter.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4704-drm-amd-display-add-dsc-policy-getter.patch | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4704-drm-amd-display-add-dsc-policy-getter.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4704-drm-amd-display-add-dsc-policy-getter.patch new file mode 100644 index 00000000..5f335a3e --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4704-drm-amd-display-add-dsc-policy-getter.patch @@ -0,0 +1,235 @@ +From 564a7172d20f0f68566d58fd9278058ca1e93291 Mon Sep 17 00:00:00 2001 +From: Wenjing Liu <Wenjing.Liu@amd.com> +Date: Fri, 15 Nov 2019 11:24:54 -0500 +Subject: [PATCH 4704/4736] drm/amd/display: add dsc policy getter + +dc needs to expose its internal dsc policy. + +Signed-off-by: Wenjing Liu <Wenjing.Liu@amd.com> +Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com> +Acked-by: Leo Li <sunpeng.li@amd.com> +Signed-off-by: Rahul Kumar <rahul.kumar1@amd.com> +--- + drivers/gpu/drm/amd/display/dc/dc_dsc.h | 14 ++- + drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 103 ++++++++++++-------- + 2 files changed, 75 insertions(+), 42 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h b/drivers/gpu/drm/amd/display/dc/dc_dsc.h +index d98b89bad353..8ec09813ee17 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h +@@ -45,6 +45,14 @@ struct display_stream_compressor { + int inst; + }; + ++struct dc_dsc_policy { ++ bool use_min_slices_h; ++ int max_slices_h; // Maximum available if 0 ++ int min_slice_height; // Must not be less than 8 ++ uint32_t max_target_bpp; ++ uint32_t min_target_bpp; ++}; ++ + bool dc_dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_basic_data, + const uint8_t *dpcd_dsc_ext_data, + struct dsc_dec_dpcd_caps *dsc_sink_caps); +@@ -66,7 +74,7 @@ bool dc_dsc_compute_config( + const struct dc_crtc_timing *timing, + struct dc_dsc_config *dsc_cfg); + +-bool dc_dsc_get_bpp_range_for_pixel_encoding(enum dc_pixel_encoding pixel_enc, +- uint32_t *min_bpp, +- uint32_t *max_bpp); ++void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, ++ struct dc_dsc_policy *policy); ++ + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +index f2b724d7e372..7469315144c1 100644 +--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c ++++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +@@ -27,19 +27,6 @@ + #include <drm/drm_dp_helper.h> + #include "dc.h" + +-struct dc_dsc_policy { +- bool use_min_slices_h; +- int max_slices_h; // Maximum available if 0 +- int min_sice_height; // Must not be less than 8 +-}; +- +-const struct dc_dsc_policy dsc_policy = { +- .use_min_slices_h = true, // DSC Policy: Use minimum number of slices that fits the pixel clock +- .max_slices_h = 0, // DSC Policy: Use max available slices (in our case 4 for or 8, depending on the mode) +- .min_sice_height = 108, // DSC Policy: Use slice height recommended by VESA DSC Spreadsheet user guide +-}; +- +- + /* This module's internal functions */ + + static uint32_t dc_dsc_bandwidth_in_kbps_from_timing( +@@ -370,6 +357,7 @@ static void get_dsc_bandwidth_range( + * or if it couldn't be applied based on DSC policy. + */ + static bool decide_dsc_target_bpp_x16( ++ const struct dc_dsc_policy *policy, + const struct dsc_enc_caps *dsc_common_caps, + const int target_bandwidth_kbps, + const struct dc_crtc_timing *timing, +@@ -377,13 +365,10 @@ static bool decide_dsc_target_bpp_x16( + { + bool should_use_dsc = false; + struct dc_dsc_bw_range range; +- uint32_t min_target_bpp = 0; +- uint32_t max_target_bpp = 0; + + memset(&range, 0, sizeof(range)); + +- dc_dsc_get_bpp_range_for_pixel_encoding(timing->pixel_encoding, &min_target_bpp, &max_target_bpp); +- get_dsc_bandwidth_range(min_target_bpp, max_target_bpp, ++ get_dsc_bandwidth_range(policy->min_target_bpp, policy->max_target_bpp, + dsc_common_caps, timing, &range); + if (target_bandwidth_kbps >= range.stream_kbps) { + /* enough bandwidth without dsc */ +@@ -579,9 +564,11 @@ static bool setup_dsc_config( + bool is_dsc_possible = false; + int pic_height; + int slice_height; ++ struct dc_dsc_policy policy; + + memset(dsc_cfg, 0, sizeof(struct dc_dsc_config)); + ++ dc_dsc_get_policy_for_timing(timing, &policy); + pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right; + pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; + +@@ -597,7 +584,12 @@ static bool setup_dsc_config( + goto done; + + if (target_bandwidth_kbps > 0) { +- is_dsc_possible = decide_dsc_target_bpp_x16(&dsc_common_caps, target_bandwidth_kbps, timing, &target_bpp); ++ is_dsc_possible = decide_dsc_target_bpp_x16( ++ &policy, ++ &dsc_common_caps, ++ target_bandwidth_kbps, ++ timing, ++ &target_bpp); + dsc_cfg->bits_per_pixel = target_bpp; + } + if (!is_dsc_possible) +@@ -699,20 +691,20 @@ static bool setup_dsc_config( + if (!is_dsc_possible) + goto done; + +- if (dsc_policy.use_min_slices_h) { ++ if (policy.use_min_slices_h) { + if (min_slices_h > 0) + num_slices_h = min_slices_h; + else if (max_slices_h > 0) { // Fall back to max slices if min slices is not working out +- if (dsc_policy.max_slices_h) +- num_slices_h = min(dsc_policy.max_slices_h, max_slices_h); ++ if (policy.max_slices_h) ++ num_slices_h = min(policy.max_slices_h, max_slices_h); + else + num_slices_h = max_slices_h; + } else + is_dsc_possible = false; + } else { + if (max_slices_h > 0) { +- if (dsc_policy.max_slices_h) +- num_slices_h = min(dsc_policy.max_slices_h, max_slices_h); ++ if (policy.max_slices_h) ++ num_slices_h = min(policy.max_slices_h, max_slices_h); + else + num_slices_h = max_slices_h; + } else if (min_slices_h > 0) // Fall back to min slices if max slices is not possible +@@ -734,7 +726,7 @@ static bool setup_dsc_config( + // Slice height (i.e. number of slices per column): start with policy and pick the first one that height is divisible by. + // For 4:2:0 make sure the slice height is divisible by 2 as well. + if (min_slice_height_override == 0) +- slice_height = min(dsc_policy.min_sice_height, pic_height); ++ slice_height = min(policy.min_slice_height, pic_height); + else + slice_height = min(min_slice_height_override, pic_height); + +@@ -906,29 +898,62 @@ bool dc_dsc_compute_config( + } + + +-bool dc_dsc_get_bpp_range_for_pixel_encoding(enum dc_pixel_encoding pixel_enc, +- uint32_t *min_bpp, +- uint32_t *max_bpp) ++void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, struct dc_dsc_policy *policy) + { +- bool result = true; ++ uint32_t bpc = 0; ++ ++ policy->min_target_bpp = 0; ++ policy->max_target_bpp = 0; ++ ++ /* DSC Policy: Use minimum number of slices that fits the pixel clock */ ++ policy->use_min_slices_h = true; + +- switch (pixel_enc) { ++ /* DSC Policy: Use max available slices ++ * (in our case 4 for or 8, depending on the mode) ++ */ ++ policy->max_slices_h = 0; ++ ++ /* DSC Policy: Use slice height recommended ++ * by VESA DSC Spreadsheet user guide ++ */ ++ policy->min_slice_height = 108; ++ ++ /* DSC Policy: follow DP specs with an internal upper limit to 16 bpp ++ * for better interoperability ++ */ ++ switch (timing->display_color_depth) { ++ case COLOR_DEPTH_888: ++ bpc = 8; ++ break; ++ case COLOR_DEPTH_101010: ++ bpc = 10; ++ break; ++ case COLOR_DEPTH_121212: ++ bpc = 12; ++ break; ++ default: ++ return; ++ } ++ switch (timing->pixel_encoding) { + case PIXEL_ENCODING_RGB: + case PIXEL_ENCODING_YCBCR444: +- case PIXEL_ENCODING_YCBCR422: +- *min_bpp = 8; +- *max_bpp = 16; ++ case PIXEL_ENCODING_YCBCR422: /* assume no YCbCr422 native support */ ++ /* DP specs limits to 8 */ ++ policy->min_target_bpp = 8; ++ /* DP specs limits to 3 x bpc */ ++ policy->max_target_bpp = 3 * bpc; + break; + case PIXEL_ENCODING_YCBCR420: +- *min_bpp = 6; +- *max_bpp = 16; ++ /* DP specs limits to 6 */ ++ policy->min_target_bpp = 6; ++ /* DP specs limits to 1.5 x bpc assume bpc is an even number */ ++ policy->max_target_bpp = bpc * 3 / 2; + break; + default: +- *min_bpp = 0; +- *max_bpp = 0; +- result = false; ++ return; + } +- +- return result; ++ /* internal upper limit to 16 bpp */ ++ if (policy->max_target_bpp > 16) ++ policy->max_target_bpp = 16; + } + +-- +2.17.1 + |