aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4704-drm-amd-display-add-dsc-policy-getter.patch
diff options
context:
space:
mode:
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.patch235
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
+