Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: 4562236b3bc0 ("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>
(cherry picked from commit eb105e63b474c11ef6a84a1c6b18100d851ff364)

authored by

Timur Kristóf and committed by
Alex Deucher
9ea16f64 60af4605

+66
+62
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
··· 1313 1313 return BP_RESULT_FAILURE; 1314 1314 } 1315 1315 1316 + static enum bp_result get_embedded_panel_extra_info( 1317 + struct bios_parser *bp, 1318 + struct embedded_panel_info *info, 1319 + const uint32_t table_offset) 1320 + { 1321 + uint8_t *record = bios_get_image(&bp->base, table_offset, 1); 1322 + ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; 1323 + ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; 1324 + 1325 + while (*record != ATOM_RECORD_END_TYPE) { 1326 + switch (*record) { 1327 + case LCD_MODE_PATCH_RECORD_MODE_TYPE: 1328 + record += sizeof(ATOM_PATCH_RECORD_MODE); 1329 + break; 1330 + case LCD_RTS_RECORD_TYPE: 1331 + record += sizeof(ATOM_LCD_RTS_RECORD); 1332 + break; 1333 + case LCD_CAP_RECORD_TYPE: 1334 + record += sizeof(ATOM_LCD_MODE_CONTROL_CAP); 1335 + break; 1336 + case LCD_FAKE_EDID_PATCH_RECORD_TYPE: 1337 + fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; 1338 + if (fake_edid_record->ucFakeEDIDLength) { 1339 + if (fake_edid_record->ucFakeEDIDLength == 128) 1340 + info->fake_edid_size = 1341 + fake_edid_record->ucFakeEDIDLength; 1342 + else 1343 + info->fake_edid_size = 1344 + fake_edid_record->ucFakeEDIDLength * 128; 1345 + 1346 + info->fake_edid = fake_edid_record->ucFakeEDIDString; 1347 + 1348 + record += struct_size(fake_edid_record, 1349 + ucFakeEDIDString, 1350 + info->fake_edid_size); 1351 + } else { 1352 + /* empty fake edid record must be 3 bytes long */ 1353 + record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1; 1354 + } 1355 + break; 1356 + case LCD_PANEL_RESOLUTION_RECORD_TYPE: 1357 + panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; 1358 + info->panel_width_mm = panel_res_record->usHSize; 1359 + info->panel_height_mm = panel_res_record->usVSize; 1360 + record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD); 1361 + break; 1362 + default: 1363 + return BP_RESULT_BADBIOSTABLE; 1364 + } 1365 + } 1366 + 1367 + return BP_RESULT_OK; 1368 + } 1369 + 1316 1370 static enum bp_result get_embedded_panel_info_v1_2( 1317 1371 struct bios_parser *bp, 1318 1372 struct embedded_panel_info *info) ··· 1482 1428 1483 1429 if (ATOM_PANEL_MISC_API_ENABLED & lvds->ucLVDS_Misc) 1484 1430 info->lcd_timing.misc_info.API_ENABLED = true; 1431 + 1432 + if (lvds->usExtInfoTableOffset) 1433 + return get_embedded_panel_extra_info(bp, info, 1434 + le16_to_cpu(lvds->usExtInfoTableOffset) + DATA_TABLES(LCD_Info)); 1485 1435 1486 1436 return BP_RESULT_OK; 1487 1437 } ··· 1611 1553 info->lcd_timing.misc_info.GREY_LEVEL = 1612 1554 (uint32_t) (ATOM_PANEL_MISC_V13_GREY_LEVEL & 1613 1555 lvds->ucLCD_Misc) >> ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT; 1556 + 1557 + if (lvds->usExtInfoTableOffset) 1558 + return get_embedded_panel_extra_info(bp, info, 1559 + le16_to_cpu(lvds->usExtInfoTableOffset) + DATA_TABLES(LCD_Info)); 1614 1560 1615 1561 return BP_RESULT_OK; 1616 1562 }
+4
drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
··· 153 153 uint32_t drr_enabled; 154 154 uint32_t min_drr_refresh_rate; 155 155 bool realtek_eDPToLVDS; 156 + uint16_t panel_width_mm; 157 + uint16_t panel_height_mm; 158 + uint16_t fake_edid_size; 159 + const uint8_t *fake_edid; 156 160 }; 157 161 158 162 struct dc_firmware_info {