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]>
---
 drivers/gpu/drm/drm_displayid_internal.h |  4 ++++
 drivers/gpu/drm/drm_edid.c               | 16 ++++++++++++++++
 include/drm/drm_connector.h              |  6 ++++++
 3 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_displayid_internal.h 
b/drivers/gpu/drm/drm_displayid_internal.h
index 38f9d628e2d6..7246ffdcd908 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 4fa39989e446..1c51158fa3a3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6588,6 +6588,21 @@ static void drm_parse_vesa_specific_block(struct 
drm_connector *connector,
                            connector->base.id, connector->name,
                            info->mso_stream_count, info->mso_pixel_overlap);
        }
+
+       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 x16 %u\n",
+                           connector->base.id, connector->name,
+                           info->dp_dsc_bpp_x16);
+       }
 }
 
 static void drm_update_vesa_specific_block(struct drm_connector *connector,
@@ -6636,6 +6651,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.0

Reply via email to