1
0
mirror of https://github.com/openbsd/src.git synced 2026-06-18 07:13:36 +02:00

drm/amd/display: Read EDID from VBIOS embedded panel info

From Timur Kristof
8b85ffe5205262682b4dc9e2e35beaeb7365aceb in linux-6.18.y/6.18.33
9ea16f64189bf7b6ba50fc7f0325b3c1f836d105 in mainline linux
This commit is contained in:
jsg
2026-05-25 09:49:17 +00:00
parent a2be9e02f3
commit 3d237fe2de
2 changed files with 66 additions and 0 deletions
@@ -1215,6 +1215,60 @@ static enum bp_result bios_parser_get_embedded_panel_info(
return BP_RESULT_FAILURE;
}
static enum bp_result get_embedded_panel_extra_info(
struct bios_parser *bp,
struct embedded_panel_info *info,
const uint32_t table_offset)
{
uint8_t *record = bios_get_image(&bp->base, table_offset, 1);
ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record;
ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record;
while (*record != ATOM_RECORD_END_TYPE) {
switch (*record) {
case LCD_MODE_PATCH_RECORD_MODE_TYPE:
record += sizeof(ATOM_PATCH_RECORD_MODE);
break;
case LCD_RTS_RECORD_TYPE:
record += sizeof(ATOM_LCD_RTS_RECORD);
break;
case LCD_CAP_RECORD_TYPE:
record += sizeof(ATOM_LCD_MODE_CONTROL_CAP);
break;
case LCD_FAKE_EDID_PATCH_RECORD_TYPE:
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
if (fake_edid_record->ucFakeEDIDLength) {
if (fake_edid_record->ucFakeEDIDLength == 128)
info->fake_edid_size =
fake_edid_record->ucFakeEDIDLength;
else
info->fake_edid_size =
fake_edid_record->ucFakeEDIDLength * 128;
info->fake_edid = fake_edid_record->ucFakeEDIDString;
record += struct_size(fake_edid_record,
ucFakeEDIDString,
info->fake_edid_size);
} else {
/* empty fake edid record must be 3 bytes long */
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
}
break;
case LCD_PANEL_RESOLUTION_RECORD_TYPE:
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
info->panel_width_mm = panel_res_record->usHSize;
info->panel_height_mm = panel_res_record->usVSize;
record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD);
break;
default:
return BP_RESULT_BADBIOSTABLE;
}
}
return BP_RESULT_OK;
}
static enum bp_result get_embedded_panel_info_v1_2(
struct bios_parser *bp,
struct embedded_panel_info *info)
@@ -1331,6 +1385,10 @@ static enum bp_result get_embedded_panel_info_v1_2(
if (ATOM_PANEL_MISC_API_ENABLED & lvds->ucLVDS_Misc)
info->lcd_timing.misc_info.API_ENABLED = true;
if (lvds->usExtInfoTableOffset)
return get_embedded_panel_extra_info(bp, info,
le16_to_cpu(lvds->usExtInfoTableOffset) + DATA_TABLES(LCD_Info));
return BP_RESULT_OK;
}
@@ -1456,6 +1514,10 @@ static enum bp_result get_embedded_panel_info_v1_3(
(uint32_t) (ATOM_PANEL_MISC_V13_GREY_LEVEL &
lvds->ucLCD_Misc) >> ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT;
if (lvds->usExtInfoTableOffset)
return get_embedded_panel_extra_info(bp, info,
le16_to_cpu(lvds->usExtInfoTableOffset) + DATA_TABLES(LCD_Info));
return BP_RESULT_OK;
}
@@ -153,6 +153,10 @@ struct embedded_panel_info {
uint32_t drr_enabled;
uint32_t min_drr_refresh_rate;
bool realtek_eDPToLVDS;
uint16_t panel_width_mm;
uint16_t panel_height_mm;
uint16_t fake_edid_size;
const uint8_t *fake_edid;
};
struct dc_firmware_info {