On Thu, 30 Oct 2025, Alex Deucher <[email protected]> wrote:
> On Tue, Oct 28, 2025 at 5:26 PM Jani Nikula <[email protected]> wrote:
>>
>> Add a mechanism for DisplayID specific quirks, and add the first quirk
>> to ignore DisplayID section checksum errors.
>>
>> It would be quite inconvenient to pass existing EDID quirks from
>> drm_edid.c for DisplayID parsing. Not all places doing DisplayID
>> iteration have the quirks readily available, and would have to pass it
>> in all places. Simply add a separate array of DisplayID specific EDID
>> quirks. We do end up checking it every time we iterate DisplayID blocks,
>> but hopefully the number of quirks remains small.
>>
>> There are a few laptop models with DisplayID checksum failures, leading
>> to higher refresh rates only present in the DisplayID blocks being
>> ignored. Add a quirk for the panel in the machines.
>>
>> Reported-by: Tiago Martins Araújo <[email protected]>
>> Closes: 
>> https://lore.kernel.org/r/cacrbrpgvlp5lanxufi6z0s7xmbag4x5y2yolbdxfovtfggq...@mail.gmail.com
>> Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14703
>> Signed-off-by: Jani Nikula <[email protected]>
>
> Series is:
> Acked-by: Alex Deucher <[email protected]>

Thanks, pushed to drm-misc-next.

BR,
Jani.


>
>> ---
>>  drivers/gpu/drm/drm_displayid.c          | 41 +++++++++++++++++++++---
>>  drivers/gpu/drm/drm_displayid_internal.h |  2 ++
>>  2 files changed, 39 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_displayid.c 
>> b/drivers/gpu/drm/drm_displayid.c
>> index 20b453d2b854..58d0bb6d2676 100644
>> --- a/drivers/gpu/drm/drm_displayid.c
>> +++ b/drivers/gpu/drm/drm_displayid.c
>> @@ -9,6 +9,34 @@
>>  #include "drm_crtc_internal.h"
>>  #include "drm_displayid_internal.h"
>>
>> +enum {
>> +       QUIRK_IGNORE_CHECKSUM,
>> +};
>> +
>> +struct displayid_quirk {
>> +       const struct drm_edid_ident ident;
>> +       u8 quirks;
>> +};
>> +
>> +static const struct displayid_quirk quirks[] = {
>> +       {
>> +               .ident = DRM_EDID_IDENT_INIT('C', 'S', 'O', 5142, 
>> "MNE007ZA1-5"),
>> +               .quirks = BIT(QUIRK_IGNORE_CHECKSUM),
>> +       },
>> +};
>> +
>> +static u8 get_quirks(const struct drm_edid *drm_edid)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < ARRAY_SIZE(quirks); i++) {
>> +               if (drm_edid_match(drm_edid, &quirks[i].ident))
>> +                       return quirks[i].quirks;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>>  static const struct displayid_header *
>>  displayid_get_header(const u8 *displayid, int length, int index)
>>  {
>> @@ -23,7 +51,7 @@ displayid_get_header(const u8 *displayid, int length, int 
>> index)
>>  }
>>
>>  static const struct displayid_header *
>> -validate_displayid(const u8 *displayid, int length, int idx)
>> +validate_displayid(const u8 *displayid, int length, int idx, bool 
>> ignore_checksum)
>>  {
>>         int i, dispid_length;
>>         u8 csum = 0;
>> @@ -41,8 +69,11 @@ validate_displayid(const u8 *displayid, int length, int 
>> idx)
>>         for (i = 0; i < dispid_length; i++)
>>                 csum += displayid[idx + i];
>>         if (csum) {
>> -               DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", 
>> csum);
>> -               return ERR_PTR(-EINVAL);
>> +               DRM_NOTE("DisplayID checksum invalid, remainder is %d%s\n", 
>> csum,
>> +                        ignore_checksum ? " (ignoring)" : "");
>> +
>> +               if (!ignore_checksum)
>> +                       return ERR_PTR(-EINVAL);
>>         }
>>
>>         return base;
>> @@ -52,6 +83,7 @@ static const u8 *find_next_displayid_extension(struct 
>> displayid_iter *iter)
>>  {
>>         const struct displayid_header *base;
>>         const u8 *displayid;
>> +       bool ignore_checksum = iter->quirks & BIT(QUIRK_IGNORE_CHECKSUM);
>>
>>         displayid = drm_edid_find_extension(iter->drm_edid, DISPLAYID_EXT, 
>> &iter->ext_index);
>>         if (!displayid)
>> @@ -61,7 +93,7 @@ static const u8 *find_next_displayid_extension(struct 
>> displayid_iter *iter)
>>         iter->length = EDID_LENGTH - 1;
>>         iter->idx = 1;
>>
>> -       base = validate_displayid(displayid, iter->length, iter->idx);
>> +       base = validate_displayid(displayid, iter->length, iter->idx, 
>> ignore_checksum);
>>         if (IS_ERR(base))
>>                 return NULL;
>>
>> @@ -76,6 +108,7 @@ void displayid_iter_edid_begin(const struct drm_edid 
>> *drm_edid,
>>         memset(iter, 0, sizeof(*iter));
>>
>>         iter->drm_edid = drm_edid;
>> +       iter->quirks = get_quirks(drm_edid);
>>  }
>>
>>  static const struct displayid_block *
>> diff --git a/drivers/gpu/drm/drm_displayid_internal.h 
>> b/drivers/gpu/drm/drm_displayid_internal.h
>> index 957dd0619f5c..5b1b32f73516 100644
>> --- a/drivers/gpu/drm/drm_displayid_internal.h
>> +++ b/drivers/gpu/drm/drm_displayid_internal.h
>> @@ -167,6 +167,8 @@ struct displayid_iter {
>>
>>         u8 version;
>>         u8 primary_use;
>> +
>> +       u8 quirks;
>>  };
>>
>>  void displayid_iter_edid_begin(const struct drm_edid *drm_edid,
>> --
>> 2.47.3
>>

-- 
Jani Nikula, Intel

Reply via email to