As per DisplayID v2.0 Errata E9 spec
Signed-off-by: Yaroslav Bolyukin iam@lach.pw --- drivers/gpu/drm/drm_edid.c | 31 ++++++++++++++++++++----------- include/drm/drm_connector.h | 6 ++++++ include/drm/drm_displayid.h | 4 ++++ 3 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a7663f9a1..83ee685c8 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5270,7 +5270,7 @@ static void drm_parse_vesa_mso_data(struct drm_connector *connector, if (oui(vesa->oui[0], vesa->oui[1], vesa->oui[2]) != VESA_IEEE_OUI) return;
- if (sizeof(*vesa) != sizeof(*block) + block->num_bytes) { + if (block->num_bytes < 5) { drm_dbg_kms(connector->dev, "Unexpected VESA vendor block size\n"); return; } @@ -5290,20 +5290,29 @@ static void drm_parse_vesa_mso_data(struct drm_connector *connector, break; }
- if (!info->mso_stream_count) { - info->mso_pixel_overlap = 0; - return; + info->mso_pixel_overlap = 0; + + if (info->mso_stream_count) { + info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso); + if (info->mso_pixel_overlap > 8) { + drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n", + info->mso_pixel_overlap); + info->mso_pixel_overlap = 8; + } + + drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n", + info->mso_stream_count, info->mso_pixel_overlap); }
- info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso); - if (info->mso_pixel_overlap > 8) { - drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n", - info->mso_pixel_overlap); - info->mso_pixel_overlap = 8; + if (block->num_bytes < 7) { + /* DSC bpp is optional */ + return; }
- drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n", - info->mso_stream_count, info->mso_pixel_overlap); + info->dp_dsc_bpp = FIELD_GET(DISPLAYID_VESA_DSC_BPP_INT, vesa->dsc_bpp_int) * 16 + + FIELD_GET(DISPLAYID_VESA_DSC_BPP_FRACT, vesa->dsc_bpp_fract); + + drm_dbg_kms(connector->dev, "DSC bits per pixel %u\n", info->dp_dsc_bpp); }
static void drm_update_mso(struct drm_connector *connector, const struct edid *edid) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 5e36eb3df..04ef0e995 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -634,6 +634,12 @@ struct drm_display_info { * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels. */ u8 mso_pixel_overlap; + + /** + * @dp_dsc_bpp: DP Display-Stream-Compression (DSC) timing's target + * DST bits per pixel in 6.4 fixed point format. 0 means undefined + */ + u16 dp_dsc_bpp; };
int drm_display_info_set_bus_formats(struct drm_display_info *info, diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h index 7ffbd9f7b..1be6deddc 100644 --- a/include/drm/drm_displayid.h +++ b/include/drm/drm_displayid.h @@ -131,12 +131,16 @@ struct displayid_detailed_timing_block {
#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)
struct displayid_vesa_vendor_specific_block { struct displayid_block base; u8 oui[3]; u8 data_structure_type; u8 mso; + u8 dsc_bpp_int; + u8 dsc_bpp_fract; } __packed;
/* DisplayID iteration */
base-commit: 1528038385c0a706aac9ac165eeb24044fef6825
VESA vendor header from DisplayID spec may contain fixed bit per pixel rate, it should be respected by drm driver
Signed-off-by: Yaroslav Bolyukin iam@lach.pw --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 ++ drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 3 ++- drivers/gpu/drm/amd/display/dc/dc_types.h | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 29f07c26d..b34dd89ae 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -118,6 +118,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
+ edid_caps->dsc_fixed_bits_per_pixel_x16 = connector->display_info.dp_dsc_bpp; + sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads); if (sad_count <= 0) return result; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 57cf4cb82..f8516ec70 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -105,6 +105,8 @@ static bool dc_stream_construct(struct dc_stream_state *stream,
/* EDID CAP translation for HDMI 2.0 */ stream->timing.flags.LTE_340MCSC_SCRAMBLE = dc_sink_data->edid_caps.lte_340mcsc_scramble; + stream->timing.dsc_fixed_bits_per_pixel_x16 = + dc_sink_data->edid_caps.dsc_fixed_bits_per_pixel_x16;
memset(&stream->timing.dsc_cfg, 0, sizeof(stream->timing.dsc_cfg)); stream->timing.dsc_cfg.num_slices_h = 0; @@ -738,4 +740,3 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream) "\tlink: %d\n", stream->link->link_index); } - diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 0285a4b38..ce2e11d70 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -227,6 +227,9 @@ struct dc_edid_caps { bool edid_hdmi; bool hdr_supported;
+ /* DisplayPort caps */ + uint32_t dsc_fixed_bits_per_pixel_x16; + struct dc_panel_patch panel_patch; };
[Public]
Hi,
Thanks for the patch and it LGTM. Feel free to add Reviewed-by: Wayne Lin Wayne.Lin@amd.com
-----Original Message----- From: Yaroslav Bolyukin iam@lach.pw Sent: Sunday, February 13, 2022 9:31 PM To: linux-kernel@vger.kernel.org; dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org Cc: Thomas Zimmermann tzimmermann@suse.de; David Airlie airlied@linux.ie; Rodrigo Siqueira Rodrigo.Siqueira@amd.com; Pan, Xinhui Xinhui.Pan@amd.com; Leo Li sunpeng.li@amd.com; Alex Deucher alexander.deucher@amd.com; Christian K?nig christian.koenig@amd.com; Yaroslav Bolyukin iam@lach.pw Subject: [2/2] drm/amd: use fixed dsc bits-per-pixel from edid
VESA vendor header from DisplayID spec may contain fixed bit per pixel rate, it should be respected by drm driver
Signed-off-by: Yaroslav Bolyukin iam@lach.pw
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 ++ drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 3 ++- drivers/gpu/drm/amd/display/dc/dc_types.h | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 29f07c26d..b34dd89ae 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -118,6 +118,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
edid_caps->dsc_fixed_bits_per_pixel_x16 =
+connector->display_info.dp_dsc_bpp;
sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads); if (sad_count <= 0) return result;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 57cf4cb82..f8516ec70 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -105,6 +105,8 @@ static bool dc_stream_construct(struct dc_stream_state *stream,
/* EDID CAP translation for HDMI 2.0 */ stream->timing.flags.LTE_340MCSC_SCRAMBLE = dc_sink_data->edid_caps.lte_340mcsc_scramble;
stream->timing.dsc_fixed_bits_per_pixel_x16 =
dc_sink_data->edid_caps.dsc_fixed_bits_per_pixel_x16; memset(&stream->timing.dsc_cfg, 0, sizeof(stream->timing.dsc_cfg)); stream->timing.dsc_cfg.num_slices_h = 0; @@ -738,4 +740,3 @@ void dc_stream_log(const struct dc *dc, const struct
dc_stream_state *stream) "\tlink: %d\n", stream->link->link_index); }
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 0285a4b38..ce2e11d70 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -227,6 +227,9 @@ struct dc_edid_caps { bool edid_hdmi; bool hdr_supported;
/* DisplayPort caps */
uint32_t dsc_fixed_bits_per_pixel_x16;
struct dc_panel_patch panel_patch;
};
-- Regards, Wayne Lin
Subject prefix should be drm/edid.
On Sun, 13 Feb 2022, Yaroslav Bolyukin iam@lach.pw wrote:
As per DisplayID v2.0 Errata E9 spec
Please be more elaborate about the changes.
You also need to update drm_reset_display_info().
BR, Jani.
Signed-off-by: Yaroslav Bolyukin iam@lach.pw
drivers/gpu/drm/drm_edid.c | 31 ++++++++++++++++++++----------- include/drm/drm_connector.h | 6 ++++++ include/drm/drm_displayid.h | 4 ++++ 3 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a7663f9a1..83ee685c8 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5270,7 +5270,7 @@ static void drm_parse_vesa_mso_data(struct drm_connector *connector, if (oui(vesa->oui[0], vesa->oui[1], vesa->oui[2]) != VESA_IEEE_OUI) return;
- if (sizeof(*vesa) != sizeof(*block) + block->num_bytes) {
- if (block->num_bytes < 5) { drm_dbg_kms(connector->dev, "Unexpected VESA vendor block size\n"); return; }
@@ -5290,20 +5290,29 @@ static void drm_parse_vesa_mso_data(struct drm_connector *connector, break; }
- if (!info->mso_stream_count) {
info->mso_pixel_overlap = 0;
return;
- info->mso_pixel_overlap = 0;
- if (info->mso_stream_count) {
info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso);
if (info->mso_pixel_overlap > 8) {
drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n",
info->mso_pixel_overlap);
info->mso_pixel_overlap = 8;
}
drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n",
}info->mso_stream_count, info->mso_pixel_overlap);
- info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso);
- if (info->mso_pixel_overlap > 8) {
drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n",
info->mso_pixel_overlap);
info->mso_pixel_overlap = 8;
- if (block->num_bytes < 7) {
/* DSC bpp is optional */
}return;
- drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n",
info->mso_stream_count, info->mso_pixel_overlap);
- info->dp_dsc_bpp = FIELD_GET(DISPLAYID_VESA_DSC_BPP_INT, vesa->dsc_bpp_int) * 16 +
FIELD_GET(DISPLAYID_VESA_DSC_BPP_FRACT, vesa->dsc_bpp_fract);
- drm_dbg_kms(connector->dev, "DSC bits per pixel %u\n", info->dp_dsc_bpp);
}
static void drm_update_mso(struct drm_connector *connector, const struct edid *edid) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 5e36eb3df..04ef0e995 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -634,6 +634,12 @@ struct drm_display_info { * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels. */ u8 mso_pixel_overlap;
- /**
* @dp_dsc_bpp: DP Display-Stream-Compression (DSC) timing's target
* DST bits per pixel in 6.4 fixed point format. 0 means undefined
*/
- u16 dp_dsc_bpp;
};
int drm_display_info_set_bus_formats(struct drm_display_info *info, diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h index 7ffbd9f7b..1be6deddc 100644 --- a/include/drm/drm_displayid.h +++ b/include/drm/drm_displayid.h @@ -131,12 +131,16 @@ struct displayid_detailed_timing_block {
#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)
struct displayid_vesa_vendor_specific_block { struct displayid_block base; u8 oui[3]; u8 data_structure_type; u8 mso;
- u8 dsc_bpp_int;
- u8 dsc_bpp_fract;
} __packed;
/* DisplayID iteration */
base-commit: 1528038385c0a706aac9ac165eeb24044fef6825
As per DisplayID v2.0 Errata E9 spec "DSC pass-through timing support" VESA vendor-specific data block may contain target DSC bits per pixel fields
Signed-off-by: Yaroslav Bolyukin iam@lach.pw --- drivers/gpu/drm/drm_edid.c | 33 ++++++++++++++++++++++----------- include/drm/drm_connector.h | 6 ++++++ include/drm/drm_displayid.h | 4 ++++ 3 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a7663f9a1..ee8c2b911 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5270,7 +5270,7 @@ static void drm_parse_vesa_mso_data(struct drm_connector *connector, if (oui(vesa->oui[0], vesa->oui[1], vesa->oui[2]) != VESA_IEEE_OUI) return;
- if (sizeof(*vesa) != sizeof(*block) + block->num_bytes) { + if (block->num_bytes < 5) { drm_dbg_kms(connector->dev, "Unexpected VESA vendor block size\n"); return; } @@ -5290,20 +5290,29 @@ static void drm_parse_vesa_mso_data(struct drm_connector *connector, break; }
- if (!info->mso_stream_count) { - info->mso_pixel_overlap = 0; - return; + info->mso_pixel_overlap = 0; + + if (info->mso_stream_count) { + info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso); + if (info->mso_pixel_overlap > 8) { + drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n", + info->mso_pixel_overlap); + info->mso_pixel_overlap = 8; + } + + drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n", + info->mso_stream_count, info->mso_pixel_overlap); }
- info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso); - if (info->mso_pixel_overlap > 8) { - drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n", - info->mso_pixel_overlap); - info->mso_pixel_overlap = 8; + if (block->num_bytes < 7) { + /* DSC bpp is optional */ + return; }
- drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n", - info->mso_stream_count, info->mso_pixel_overlap); + info->dp_dsc_bpp = FIELD_GET(DISPLAYID_VESA_DSC_BPP_INT, vesa->dsc_bpp_int) * 16 + + FIELD_GET(DISPLAYID_VESA_DSC_BPP_FRACT, vesa->dsc_bpp_fract); + + drm_dbg_kms(connector->dev, "DSC bits per pixel %u\n", info->dp_dsc_bpp); }
static void drm_update_mso(struct drm_connector *connector, const struct edid *edid) @@ -5348,6 +5357,8 @@ drm_reset_display_info(struct drm_connector *connector)
info->mso_stream_count = 0; info->mso_pixel_overlap = 0; + + info->dp_dsc_bpp = 0; }
u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 5e36eb3df..04ef0e995 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -634,6 +634,12 @@ struct drm_display_info { * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels. */ u8 mso_pixel_overlap; + + /** + * @dp_dsc_bpp: DP Display-Stream-Compression (DSC) timing's target + * DST bits per pixel in 6.4 fixed point format. 0 means undefined + */ + u16 dp_dsc_bpp; };
int drm_display_info_set_bus_formats(struct drm_display_info *info, diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h index 7ffbd9f7b..1be6deddc 100644 --- a/include/drm/drm_displayid.h +++ b/include/drm/drm_displayid.h @@ -131,12 +131,16 @@ struct displayid_detailed_timing_block {
#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)
struct displayid_vesa_vendor_specific_block { struct displayid_block base; u8 oui[3]; u8 data_structure_type; u8 mso; + u8 dsc_bpp_int; + u8 dsc_bpp_fract; } __packed;
/* DisplayID iteration */
base-commit: 1528038385c0a706aac9ac165eeb24044fef6825
VESA vendor header from DisplayID spec may contain fixed bit per pixel rate, it should be respected by drm driver
Signed-off-by: Yaroslav Bolyukin iam@lach.pw Reviewed-by: Wayne Lin Wayne.Lin@amd.com --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 ++ drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 3 ++- drivers/gpu/drm/amd/display/dc/dc_types.h | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 29f07c26d..b34dd89ae 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -118,6 +118,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
+ edid_caps->dsc_fixed_bits_per_pixel_x16 = connector->display_info.dp_dsc_bpp; + sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads); if (sad_count <= 0) return result; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 57cf4cb82..f8516ec70 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -105,6 +105,8 @@ static bool dc_stream_construct(struct dc_stream_state *stream,
/* EDID CAP translation for HDMI 2.0 */ stream->timing.flags.LTE_340MCSC_SCRAMBLE = dc_sink_data->edid_caps.lte_340mcsc_scramble; + stream->timing.dsc_fixed_bits_per_pixel_x16 = + dc_sink_data->edid_caps.dsc_fixed_bits_per_pixel_x16;
memset(&stream->timing.dsc_cfg, 0, sizeof(stream->timing.dsc_cfg)); stream->timing.dsc_cfg.num_slices_h = 0; @@ -738,4 +740,3 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream) "\tlink: %d\n", stream->link->link_index); } - diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 0285a4b38..ce2e11d70 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -227,6 +227,9 @@ struct dc_edid_caps { bool edid_hdmi; bool hdr_supported;
+ /* DisplayPort caps */ + uint32_t dsc_fixed_bits_per_pixel_x16; + struct dc_panel_patch panel_patch; };
As per DisplayID v2.0 Errata E9 spec "DSC pass-through timing support" VESA vendor-specific data block may contain target DSC bits per pixel fields
Signed-off-by: Yaroslav Bolyukin iam@lach.pw --- drivers/gpu/drm/drm_edid.c | 33 ++++++++++++++++++++++----------- include/drm/drm_connector.h | 6 ++++++ include/drm/drm_displayid.h | 4 ++++ 3 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index bc43e1b32092..e2ced222a081 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5433,7 +5433,7 @@ static void drm_parse_vesa_mso_data(struct drm_connector *connector, if (oui(vesa->oui[0], vesa->oui[1], vesa->oui[2]) != VESA_IEEE_OUI) return;
- if (sizeof(*vesa) != sizeof(*block) + block->num_bytes) { + if (block->num_bytes < 5) { drm_dbg_kms(connector->dev, "Unexpected VESA vendor block size\n"); return; } @@ -5453,20 +5453,29 @@ static void drm_parse_vesa_mso_data(struct drm_connector *connector, break; }
- if (!info->mso_stream_count) { - info->mso_pixel_overlap = 0; - return; + info->mso_pixel_overlap = 0; + + if (info->mso_stream_count) { + info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso); + if (info->mso_pixel_overlap > 8) { + drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n", + info->mso_pixel_overlap); + info->mso_pixel_overlap = 8; + } + + drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n", + info->mso_stream_count, info->mso_pixel_overlap); }
- info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso); - if (info->mso_pixel_overlap > 8) { - drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n", - info->mso_pixel_overlap); - info->mso_pixel_overlap = 8; + if (block->num_bytes < 7) { + /* DSC bpp is optional */ + return; }
- drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n", - info->mso_stream_count, info->mso_pixel_overlap); + info->dp_dsc_bpp = FIELD_GET(DISPLAYID_VESA_DSC_BPP_INT, vesa->dsc_bpp_int) * 16 + + FIELD_GET(DISPLAYID_VESA_DSC_BPP_FRACT, vesa->dsc_bpp_fract); + + drm_dbg_kms(connector->dev, "DSC bits per pixel %u\n", info->dp_dsc_bpp); }
static void drm_update_mso(struct drm_connector *connector, const struct edid *edid) @@ -5511,6 +5520,8 @@ drm_reset_display_info(struct drm_connector *connector)
info->mso_stream_count = 0; info->mso_pixel_overlap = 0; + + info->dp_dsc_bpp = 0; }
u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 3ac4bf87f257..77ce9515afc4 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -634,6 +634,12 @@ struct drm_display_info { * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels. */ u8 mso_pixel_overlap; + + /** + * @dp_dsc_bpp: DP Display-Stream-Compression (DSC) timing's target + * DST bits per pixel in 6.4 fixed point format. 0 means undefined + */ + u16 dp_dsc_bpp; };
int drm_display_info_set_bus_formats(struct drm_display_info *info, diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h index 7ffbd9f7bfc7..1be6deddcce3 100644 --- a/include/drm/drm_displayid.h +++ b/include/drm/drm_displayid.h @@ -131,12 +131,16 @@ struct displayid_detailed_timing_block {
#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)
struct displayid_vesa_vendor_specific_block { struct displayid_block base; u8 oui[3]; u8 data_structure_type; u8 mso; + u8 dsc_bpp_int; + u8 dsc_bpp_fract; } __packed;
/* DisplayID iteration */
base-commit: 6a47a16dcef3fdda79a95452964d001a620db473
VESA vendor header from DisplayID spec may contain fixed bit per pixel rate, it should be respected by drm driver
Signed-off-by: Yaroslav Bolyukin iam@lach.pw Reviewed-by: Wayne Lin Wayne.Lin@amd.com --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 ++ drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 3 ++- drivers/gpu/drm/amd/display/dc/dc_types.h | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index f5f39984702f..5565d55f56f9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -119,6 +119,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
+ edid_caps->dsc_fixed_bits_per_pixel_x16 = connector->display_info.dp_dsc_bpp; + sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads); if (sad_count <= 0) return result; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index c4e871f358ab..65c90e432a39 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -105,6 +105,8 @@ static bool dc_stream_construct(struct dc_stream_state *stream,
/* EDID CAP translation for HDMI 2.0 */ stream->timing.flags.LTE_340MCSC_SCRAMBLE = dc_sink_data->edid_caps.lte_340mcsc_scramble; + stream->timing.dsc_fixed_bits_per_pixel_x16 = + dc_sink_data->edid_caps.dsc_fixed_bits_per_pixel_x16;
memset(&stream->timing.dsc_cfg, 0, sizeof(stream->timing.dsc_cfg)); stream->timing.dsc_cfg.num_slices_h = 0; @@ -773,4 +775,3 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream) } } } - diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 2ba9f528c0fe..e53c414b6c93 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -228,6 +228,9 @@ struct dc_edid_caps { bool edid_hdmi; bool hdr_supported;
+ /* DisplayPort caps */ + uint32_t dsc_fixed_bits_per_pixel_x16; + struct dc_panel_patch panel_patch; };
dri-devel@lists.freedesktop.org