Skip to content

Commit 83cbb4d

Browse files
committed
drm/displayid: add quirk to ignore DisplayID checksum errors
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 <tiago.martins.araujo@gmail.com> Closes: https://lore.kernel.org/r/CACRbrPGvLP5LANXuFi6z0S7XMbAG4X5y2YOLBDxfOVtfGGqiKQ@mail.gmail.com Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14703 Acked-by: Alex Deucher <alexander.deucher@amd.com> Tested-by: Tiago Martins Araújo <tiago.martins.araujo@gmail.com> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/c04d81ae648c5f21b3f5b7953f924718051f2798.1761681968.git.jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com>
1 parent 8b61583 commit 83cbb4d

2 files changed

Lines changed: 39 additions & 4 deletions

File tree

drivers/gpu/drm/drm_displayid.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,34 @@
99
#include "drm_crtc_internal.h"
1010
#include "drm_displayid_internal.h"
1111

12+
enum {
13+
QUIRK_IGNORE_CHECKSUM,
14+
};
15+
16+
struct displayid_quirk {
17+
const struct drm_edid_ident ident;
18+
u8 quirks;
19+
};
20+
21+
static const struct displayid_quirk quirks[] = {
22+
{
23+
.ident = DRM_EDID_IDENT_INIT('C', 'S', 'O', 5142, "MNE007ZA1-5"),
24+
.quirks = BIT(QUIRK_IGNORE_CHECKSUM),
25+
},
26+
};
27+
28+
static u8 get_quirks(const struct drm_edid *drm_edid)
29+
{
30+
int i;
31+
32+
for (i = 0; i < ARRAY_SIZE(quirks); i++) {
33+
if (drm_edid_match(drm_edid, &quirks[i].ident))
34+
return quirks[i].quirks;
35+
}
36+
37+
return 0;
38+
}
39+
1240
static const struct displayid_header *
1341
displayid_get_header(const u8 *displayid, int length, int index)
1442
{
@@ -23,7 +51,7 @@ displayid_get_header(const u8 *displayid, int length, int index)
2351
}
2452

2553
static const struct displayid_header *
26-
validate_displayid(const u8 *displayid, int length, int idx)
54+
validate_displayid(const u8 *displayid, int length, int idx, bool ignore_checksum)
2755
{
2856
int i, dispid_length;
2957
u8 csum = 0;
@@ -41,8 +69,11 @@ validate_displayid(const u8 *displayid, int length, int idx)
4169
for (i = 0; i < dispid_length; i++)
4270
csum += displayid[idx + i];
4371
if (csum) {
44-
DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", csum);
45-
return ERR_PTR(-EINVAL);
72+
DRM_NOTE("DisplayID checksum invalid, remainder is %d%s\n", csum,
73+
ignore_checksum ? " (ignoring)" : "");
74+
75+
if (!ignore_checksum)
76+
return ERR_PTR(-EINVAL);
4677
}
4778

4879
return base;
@@ -52,6 +83,7 @@ static const u8 *find_next_displayid_extension(struct displayid_iter *iter)
5283
{
5384
const struct displayid_header *base;
5485
const u8 *displayid;
86+
bool ignore_checksum = iter->quirks & BIT(QUIRK_IGNORE_CHECKSUM);
5587

5688
displayid = drm_edid_find_extension(iter->drm_edid, DISPLAYID_EXT, &iter->ext_index);
5789
if (!displayid)
@@ -61,7 +93,7 @@ static const u8 *find_next_displayid_extension(struct displayid_iter *iter)
6193
iter->length = EDID_LENGTH - 1;
6294
iter->idx = 1;
6395

64-
base = validate_displayid(displayid, iter->length, iter->idx);
96+
base = validate_displayid(displayid, iter->length, iter->idx, ignore_checksum);
6597
if (IS_ERR(base))
6698
return NULL;
6799

@@ -76,6 +108,7 @@ void displayid_iter_edid_begin(const struct drm_edid *drm_edid,
76108
memset(iter, 0, sizeof(*iter));
77109

78110
iter->drm_edid = drm_edid;
111+
iter->quirks = get_quirks(drm_edid);
79112
}
80113

81114
static const struct displayid_block *

drivers/gpu/drm/drm_displayid_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ struct displayid_iter {
167167

168168
u8 version;
169169
u8 primary_use;
170+
171+
u8 quirks;
170172
};
171173

172174
void displayid_iter_edid_begin(const struct drm_edid *drm_edid,

0 commit comments

Comments
 (0)