[PATCH v6 6/7] drm/edid: parse DRM VESA dsc bpp target

Yaroslav Bolyukin posted 7 patches 5 days, 16 hours ago
[PATCH v6 6/7] drm/edid: parse DRM VESA dsc bpp target
Posted by Yaroslav Bolyukin 5 days, 16 hours ago
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 <iam@lach.pw>
---
 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 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 7bdc99d5084a..b2502be2e807 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6591,6 +6591,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,
@@ -6639,6 +6654,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
Re: [PATCH v6 6/7] drm/edid: parse DRM VESA dsc bpp target
Posted by Jani Nikula 5 days, 9 hours ago
On Wed, 26 Nov 2025, Yaroslav Bolyukin <iam@lach.pw> wrote:
> 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 <iam@lach.pw>
> ---
>  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 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 7bdc99d5084a..b2502be2e807 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -6591,6 +6591,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);

Use drm_fixed.h, and do something like this:

	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));

and you'll get the actual x.y in the output.


> +	}
>  }
>  
>  static void drm_update_vesa_specific_block(struct drm_connector *connector,
> @@ -6639,6 +6654,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.
>  	 */

-- 
Jani Nikula, Intel