Commit 17c6baff authored by Alex Deucher's avatar Alex Deucher
Browse files

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: default avatarThomas Weißschuh <linux@weissschuh.net>
Reported-by: default avatarThomas Weißschuh <linux@weissschuh.net>
Link: https://lists.freedesktop.org/archives/amd-gfx/2024-June/109964.html


Fixes: c324acd5 ("drm/radeon/kms: parse the extended LCD info block")
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8155566a
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -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 += fake_edid_record->ucFakeEDIDLength ?
						  struct_size(fake_edid_record,
						record += struct_size(fake_edid_record,
								      ucFakeEDIDString,
							      fake_edid_record->ucFakeEDIDLength) :
								      edid_size);
					} else {
						/* empty fake edid record must be 3 bytes long */
						  sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
						record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
					}
					break;
				case LCD_PANEL_RESOLUTION_RECORD_TYPE:
					panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;