[PATCH] drm/drm_edid: Refactor HFVSDB parsing for DSC1.2
Nautiyal, Ankit K
ankit.k.nautiyal at intel.com
Wed Aug 10 14:45:59 UTC 2022
On 8/2/2022 8:19 PM, Jani Nikula wrote:
> On Fri, 22 Jul 2022, Ankit Nautiyal <ankit.k.nautiyal at intel.com> wrote:
>> DSC capabilities are given in bytes 11-13 of VSDB (i.e. bytes 8-10 of
>> SCDS). Since minimum length of Data block is 7, all bytes greater than 7
>> must be read only after checking the length of the data block.
>>
>> This patch adds check for data block length before reading relavant DSC
>> bytes. It also corrects min DSC BPC to 8, and minor refactoring for
>> better readability, and proper log messages.
> I think this patch tries to do too much at once. Please split it up. One
> thing per patch.
>
> I think the logging is excessive, and what logging remains should use
> drm_dbg_kms() instead of DRM_DEBUG_KMS().
>
> Further comments inline.
Hi Jani,
Thanks for the comments. I do agree, it makes more sense to have a
separate patches with incremental changes.
Will send another series with the comments addressed.
Please find the response inline:
>
>> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
>> ---
>> drivers/gpu/drm/drm_edid.c | 124 +++++++++++++++++++++++--------------
>> 1 file changed, 77 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index bbc25e3b7220..f683a8d5fd31 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -5703,12 +5703,58 @@ static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
>> hdmi->y420_dc_modes = dc_mask;
>> }
>>
>> +static void drm_parse_dsc_slice_info(u8 dsc_max_slices,
>> + struct drm_hdmi_dsc_cap *hdmi_dsc)
> Arguments should always be in the order: context, destination, source.
Noted. Will take care in the next patch.
>
>> +{
>> + switch (dsc_max_slices) {
>> + case 1:
>> + hdmi_dsc->max_slices = 1;
>> + hdmi_dsc->clk_per_slice = 340;
>> + break;
>> + case 2:
>> + hdmi_dsc->max_slices = 2;
>> + hdmi_dsc->clk_per_slice = 340;
>> + break;
>> + case 3:
>> + hdmi_dsc->max_slices = 4;
>> + hdmi_dsc->clk_per_slice = 340;
>> + break;
>> + case 4:
>> + hdmi_dsc->max_slices = 8;
>> + hdmi_dsc->clk_per_slice = 340;
>> + break;
>> + case 5:
>> + hdmi_dsc->max_slices = 8;
>> + hdmi_dsc->clk_per_slice = 400;
>> + break;
>> + case 6:
>> + hdmi_dsc->max_slices = 12;
>> + hdmi_dsc->clk_per_slice = 400;
>> + break;
>> + case 7:
>> + hdmi_dsc->max_slices = 16;
>> + hdmi_dsc->clk_per_slice = 400;
>> + break;
>> + case 0:
>> + default:
>> + hdmi_dsc->max_slices = 0;
>> + hdmi_dsc->clk_per_slice = 0;
>> + }
>> +}
>> +
>> /* Sink Capability Data Structure */
>> static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
>> const u8 *hf_scds)
>> {
>> struct drm_display_info *display = &connector->display_info;
>> struct drm_hdmi_info *hdmi = &display->hdmi;
>> + u8 db_length = hf_scds[0] & 0x1F;
> There's cea_db_payload_len() for this, and you can use that directly
> instead of caching the value to a local variable.
Right, will use the function here.
>
>> + u8 dsc_max_frl_rate;
>> + u8 dsc_max_slices;
> These two are local to a tiny if block and should be declared there.
Agreed. Will fix in the next patchset.
>
>> + struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
>> +
>> + if (db_length < 7 || db_length > 31)
>> + return;
> Both cea_db_is_hdmi_forum_vsdb() and cea_db_is_hdmi_forum_scdb() check
> the payload is >= 7 bytes before this one even gets called.
>
> There's no reason to not parse the first 31 bytes if the length is > 31
> bytes. That condition just breaks future compatibility for no reason.
Makes sense, will drop these checks.
>
>>
>> display->has_hdmi_infoframe = true;
>>
>> @@ -5749,17 +5795,25 @@ static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
>>
>> if (hf_scds[7]) {
>> u8 max_frl_rate;
>> - u8 dsc_max_frl_rate;
>> - u8 dsc_max_slices;
>> - struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
>>
>> - DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
>> max_frl_rate = (hf_scds[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
>> + if (max_frl_rate)
>> + DRM_DEBUG_KMS("HDMI2.1 FRL support detected\n");
>> +
>> drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
>> &hdmi->max_frl_rate_per_lane);
>> +
>> + drm_parse_ycbcr420_deep_color_info(connector, hf_scds);
>> + }
>> +
>> + if (db_length < 11)
>> + return;
>> +
>> + if (hf_scds[11]) {
> Matter of taste, but I'd probably make these
>
> if (cea_db_payload_len(hf_scds) >= 11 && hf_scds[11])
>
> and drop the early returns, and add a single (or very few) debug logging
> call at the end.
Hmm. We can get rid of early return.
Will have a separate patch to have logging call at the end with
drm_dbg_kms as suggested.
>
>> hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
>>
>> if (hdmi_dsc->v_1p2) {
>> + DRM_DEBUG_KMS("HDMI DSC1.2 support detected\n");
>> hdmi_dsc->native_420 = hf_scds[11] & DRM_EDID_DSC_NATIVE_420;
>> hdmi_dsc->all_bpp = hf_scds[11] & DRM_EDID_DSC_ALL_BPP;
>>
>> @@ -5770,52 +5824,28 @@ static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
>> else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
>> hdmi_dsc->bpc_supported = 10;
>> else
>> - hdmi_dsc->bpc_supported = 0;
>> -
>> - dsc_max_frl_rate = (hf_scds[12] & DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
>> - drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
>> - &hdmi_dsc->max_frl_rate_per_lane);
>> - hdmi_dsc->total_chunk_kbytes = hf_scds[13] & DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
>> -
>> - dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
>> - switch (dsc_max_slices) {
>> - case 1:
>> - hdmi_dsc->max_slices = 1;
>> - hdmi_dsc->clk_per_slice = 340;
>> - break;
>> - case 2:
>> - hdmi_dsc->max_slices = 2;
>> - hdmi_dsc->clk_per_slice = 340;
>> - break;
>> - case 3:
>> - hdmi_dsc->max_slices = 4;
>> - hdmi_dsc->clk_per_slice = 340;
>> - break;
>> - case 4:
>> - hdmi_dsc->max_slices = 8;
>> - hdmi_dsc->clk_per_slice = 340;
>> - break;
>> - case 5:
>> - hdmi_dsc->max_slices = 8;
>> - hdmi_dsc->clk_per_slice = 400;
>> - break;
>> - case 6:
>> - hdmi_dsc->max_slices = 12;
>> - hdmi_dsc->clk_per_slice = 400;
>> - break;
>> - case 7:
>> - hdmi_dsc->max_slices = 16;
>> - hdmi_dsc->clk_per_slice = 400;
>> - break;
>> - case 0:
>> - default:
>> - hdmi_dsc->max_slices = 0;
>> - hdmi_dsc->clk_per_slice = 0;
>> - }
> Splitting this to a separate function should be a non-functional prep
> patch.
Right makes sense. Will have this change as a separate patch.
Regards,
Ankit
>
> BR,
> Jani.
>
>> + /* Supports min 8 BPC if DSC1.2 is supported*/
>> + hdmi_dsc->bpc_supported = 8;
>> }
>> }
>>
>> - drm_parse_ycbcr420_deep_color_info(connector, hf_scds);
>> + if (db_length < 12)
>> + return;
>> +
>> + if (hdmi_dsc->v_1p2 && hf_scds[12]) {
>> + dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
>> + drm_parse_dsc_slice_info(dsc_max_slices, hdmi_dsc);
>> +
>> + dsc_max_frl_rate = (hf_scds[12] & DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
>> + drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
>> + &hdmi_dsc->max_frl_rate_per_lane);
>> + }
>> +
>> + if (db_length < 13)
>> + return;
>> +
>> + if (hdmi_dsc->v_1p2 && hf_scds[13])
>> + hdmi_dsc->total_chunk_kbytes = hf_scds[13] & DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
>> }
>>
>> static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
More information about the dri-devel
mailing list