drm/radeon: properly handle vbios fake edid sizing

The comment in the vbios structure says:
// = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128

This fake edid struct has not been used in a long time, so I'm
not sure if there were actually any boards out there with a non-128 byte
EDID, but align the code with the comment.

Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Reported-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://lists.freedesktop.org/archives/amd-gfx/2024-June/109964.html
Fixes: c324acd503 ("drm/radeon/kms: parse the extended LCD info block")
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Alex Deucher 2024-07-23 13:31:58 -04:00
parent 8155566a26
commit 17c6baff3d

View File

@ -1717,26 +1717,29 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
if (fake_edid_record->ucFakeEDIDLength) {
struct edid *edid;
int edid_size =
max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
edid = kmalloc(edid_size, GFP_KERNEL);
if (edid) {
memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
fake_edid_record->ucFakeEDIDLength);
int edid_size;
if (fake_edid_record->ucFakeEDIDLength == 128)
edid_size = fake_edid_record->ucFakeEDIDLength;
else
edid_size = fake_edid_record->ucFakeEDIDLength * 128;
edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
edid_size, GFP_KERNEL);
if (edid) {
if (drm_edid_is_valid(edid)) {
rdev->mode_info.bios_hardcoded_edid = edid;
rdev->mode_info.bios_hardcoded_edid_size = edid_size;
} else
} else {
kfree(edid);
}
}
record += struct_size(fake_edid_record,
ucFakeEDIDString,
edid_size);
} else {
/* empty fake edid record must be 3 bytes long */
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
}
record += fake_edid_record->ucFakeEDIDLength ?
struct_size(fake_edid_record,
ucFakeEDIDString,
fake_edid_record->ucFakeEDIDLength) :
/* empty fake edid record must be 3 bytes long */
sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
break;
case LCD_PANEL_RESOLUTION_RECORD_TYPE:
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;