mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
drm/amd/display: Read EDID from VBIOS embedded panel info
Some board manufacturers hardcode the EDID for the embedded
panel in the VBIOS. This EDID should be used when the panel
doesn't have a DDC.
For reference, see the legacy non-DC display code:
amdgpu_atombios_encoder_get_lcd_info()
This is necessary to support embedded connectors without DDC.
Fixes: 4562236b3b ("drm/amd/dc: Add dc display driver (v2)")
Link: https://gitlab.freedesktop.org/drm/amd/-/work_items/5192
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
155baf3038
commit
eb105e63b4
|
|
@ -1313,6 +1313,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)
|
||||
|
|
@ -1429,6 +1483,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;
|
||||
}
|
||||
|
||||
|
|
@ -1554,6 +1612,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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user