As per DisplayID v2.1a spec "DSC pass-through timing support",
VESA vendor-specific data block may contain target DSC bits per pixel
fields, that should be always used for the VII modes that declare they
only support working with this value (Pass-through Timing Support for
Target DSC Bits per Pixel).

Signed-off-by: Yaroslav Bolyukin <[email protected]>

fixup parse DRM vesa dsc bpp target
---
 drivers/gpu/drm/drm_displayid_internal.h |  4 ++++
 drivers/gpu/drm/drm_edid.c               | 17 +++++++++++++++++
 include/drm/drm_connector.h              |  6 ++++++
 3 files changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/drm_displayid_internal.h 
b/drivers/gpu/drm/drm_displayid_internal.h
index 55f972d32847..8f1a2f33ca1a 100644
--- a/drivers/gpu/drm/drm_displayid_internal.h
+++ b/drivers/gpu/drm/drm_displayid_internal.h
@@ -148,6 +148,8 @@ struct displayid_formula_timing_block {
 #define DISPLAYID_VESA_DP_TYPE         GENMASK(2, 0)
 #define DISPLAYID_VESA_MSO_OVERLAP     GENMASK(3, 0)
 #define DISPLAYID_VESA_MSO_MODE                GENMASK(6, 5)
+#define DISPLAYID_VESA_DSC_BPP_INT     GENMASK(5, 0)
+#define DISPLAYID_VESA_DSC_BPP_FRACT   GENMASK(3, 0)
 
 #define DISPLAYID_VESA_DP_TYPE_EDP     0
 #define DISPLAYID_VESA_DP_TYPE_DP      1
@@ -157,6 +159,8 @@ struct displayid_vesa_vendor_specific_block {
        u8 oui[3];
        u8 data_structure_type;
        u8 mso;
+       u8 dsc_bpp_int;
+       u8 dsc_bpp_fract;
 } __packed;
 
 /*
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index be8715632b91..8273920f5ba4 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -45,6 +45,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_eld.h>
 #include <drm/drm_encoder.h>
+#include <drm/drm_fixed.h>
 #include <drm/drm_print.h>
 
 #include "drm_crtc_internal.h"
@@ -6593,6 +6594,21 @@ static void drm_parse_vesa_specific_block(struct 
drm_connector *connector,
        } else {
                info->mso_pixel_overlap = 0;
        }
+
+       if (block->num_bytes < 7) {
+               /* DSC bpp is optional */
+               return;
+       }
+
+       info->dp_dsc_bpp_x16 = FIELD_GET(DISPLAYID_VESA_DSC_BPP_INT, 
vesa->dsc_bpp_int) << 4 |
+                              FIELD_GET(DISPLAYID_VESA_DSC_BPP_FRACT, 
vesa->dsc_bpp_fract);
+
+       if (info->dp_dsc_bpp_x16 > 0) {
+               drm_dbg_kms(connector->dev,
+                           "[CONNECTOR:%d:%s] DSC bits per pixel " FXP_Q4_FMT 
"\n",
+                           connector->base.id, connector->name,
+                           FXP_Q4_ARGS(info->dp_dsc_bpp_x16));
+       }
 }
 
 static void drm_update_vesa_specific_block(struct drm_connector *connector,
@@ -6641,6 +6657,7 @@ static void drm_reset_display_info(struct drm_connector 
*connector)
        info->mso_stream_count = 0;
        info->mso_pixel_overlap = 0;
        info->max_dsc_bpp = 0;
+       info->dp_dsc_bpp_x16 = 0;
 
        kfree(info->vics);
        info->vics = NULL;
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8f34f4b8183d..7decfc288aa3 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -837,6 +837,12 @@ struct drm_display_info {
         */
        u32 max_dsc_bpp;
 
+       /**
+        * @dp_dsc_bpp: DP Display-Stream-Compression (DSC) timing's target
+        * DSC bits per pixel in 6.4 fixed point format. 0 means undefined.
+        */
+       u16 dp_dsc_bpp_x16;
+
        /**
         * @vics: Array of vics_len VICs. Internal to EDID parsing.
         */
-- 
2.51.2

Reply via email to