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
