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]> > --- > 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 >
