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

drm/amd/display: Add internal display info

[Why & How]
Get internal display info from vbios and pass it to dmub fw to determine
if multiple display optmization is needed.

Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Yongqiang Sun and committed by
Alex Deucher
c85ef99a 49d067dc

+92
+73
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
··· 65 65 GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) 66 66 #endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */ 67 67 68 + 69 + //TODO: Remove this temp define after atomfirmware.h is updated. 70 + #define ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE 23 71 + 72 + 68 73 #define DC_LOGGER \ 69 74 bp->base.ctx->logger 70 75 ··· 1460 1455 return NULL; 1461 1456 } 1462 1457 1458 + static struct atom_disp_connector_caps_record *get_disp_connector_caps_record( 1459 + struct bios_parser *bp, 1460 + struct atom_display_object_path_v2 *object) 1461 + { 1462 + struct atom_common_record_header *header; 1463 + uint32_t offset; 1464 + 1465 + if (!object) { 1466 + BREAK_TO_DEBUGGER(); /* Invalid object */ 1467 + return NULL; 1468 + } 1469 + 1470 + offset = object->disp_recordoffset + bp->object_info_tbl_offset; 1471 + 1472 + for (;;) { 1473 + header = GET_IMAGE(struct atom_common_record_header, offset); 1474 + 1475 + if (!header) 1476 + return NULL; 1477 + 1478 + offset += header->record_size; 1479 + 1480 + if (header->record_type == LAST_RECORD_TYPE || 1481 + !header->record_size) 1482 + break; 1483 + 1484 + if (header->record_type != ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE) 1485 + continue; 1486 + 1487 + if (sizeof(struct atom_disp_connector_caps_record) <= 1488 + header->record_size) 1489 + return (struct atom_disp_connector_caps_record *)header; 1490 + } 1491 + 1492 + return NULL; 1493 + } 1494 + 1495 + static enum bp_result bios_parser_get_disp_connector_caps_info( 1496 + struct dc_bios *dcb, 1497 + struct graphics_object_id object_id, 1498 + struct bp_disp_connector_caps_info *info) 1499 + { 1500 + struct bios_parser *bp = BP_FROM_DCB(dcb); 1501 + struct atom_display_object_path_v2 *object; 1502 + struct atom_disp_connector_caps_record *record = NULL; 1503 + 1504 + if (!info) 1505 + return BP_RESULT_BADINPUT; 1506 + 1507 + object = get_bios_object(bp, object_id); 1508 + 1509 + if (!object) 1510 + return BP_RESULT_BADINPUT; 1511 + 1512 + record = get_disp_connector_caps_record(bp, object); 1513 + if (!record) 1514 + return BP_RESULT_NORECORD; 1515 + 1516 + info->INTERNAL_DISPLAY = (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY) 1517 + ? 1 : 0; 1518 + info->INTERNAL_DISPLAY_BL = (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL) 1519 + ? 1 : 0; 1520 + 1521 + return BP_RESULT_OK; 1522 + } 1523 + 1463 1524 static enum bp_result get_vram_info_v23( 1464 1525 struct bios_parser *bp, 1465 1526 struct dc_vram_info *info) ··· 2534 2463 .enable_lvtma_control = bios_parser_enable_lvtma_control, 2535 2464 2536 2465 .get_soc_bb_info = bios_parser_get_soc_bb_info, 2466 + 2467 + .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info, 2537 2468 }; 2538 2469 2539 2470 static bool bios_parser2_construct(
+7
drivers/gpu/drm/amd/display/dc/core/dc_link.c
··· 1369 1369 struct integrated_info info = {{{ 0 }}}; 1370 1370 struct dc_bios *bios = init_params->dc->ctx->dc_bios; 1371 1371 const struct dc_vbios_funcs *bp_funcs = bios->funcs; 1372 + struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 }; 1372 1373 1373 1374 DC_LOGGER_INIT(dc_ctx->logger); 1374 1375 ··· 1389 1388 1390 1389 link->link_id = 1391 1390 bios->funcs->get_connector_id(bios, init_params->connector_index); 1391 + 1392 + 1393 + if (bios->funcs->get_disp_connector_caps_info) { 1394 + bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info); 1395 + link->is_internal_display = disp_connect_caps_info.INTERNAL_DISPLAY; 1396 + } 1392 1397 1393 1398 if (link->link_id.type != OBJECT_TYPE_CONNECTOR) { 1394 1399 dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
+5
drivers/gpu/drm/amd/display/dc/dc_bios_types.h
··· 144 144 enum bp_result (*get_soc_bb_info)( 145 145 struct dc_bios *dcb, 146 146 struct bp_soc_bb_info *soc_bb_info); 147 + 148 + enum bp_result (*get_disp_connector_caps_info)( 149 + struct dc_bios *dcb, 150 + struct graphics_object_id object_id, 151 + struct bp_disp_connector_caps_info *info); 147 152 }; 148 153 149 154 struct bios_registers {
+1
drivers/gpu/drm/amd/display/dc/dc_link.h
··· 101 101 bool aux_access_disabled; 102 102 bool sync_lt_in_progress; 103 103 bool lttpr_non_transparent_mode; 104 + bool is_internal_display; 104 105 105 106 /* caps is the same as reported_link_cap. link_traing use 106 107 * reported_link_cap. Will clean up. TODO
+5
drivers/gpu/drm/amd/display/include/bios_parser_types.h
··· 309 309 struct spread_spectrum_flags flags; 310 310 }; 311 311 312 + struct bp_disp_connector_caps_info { 313 + uint32_t INTERNAL_DISPLAY : 1; 314 + uint32_t INTERNAL_DISPLAY_BL : 1; 315 + }; 316 + 312 317 struct bp_encoder_cap_info { 313 318 uint32_t DP_HBR2_CAP:1; 314 319 uint32_t DP_HBR2_EN:1;
+1
drivers/gpu/drm/amd/include/atomfirmware.h
··· 725 725 ATOM_ENCODER_CAP_RECORD_TYPE=20, 726 726 ATOM_BRACKET_LAYOUT_RECORD_TYPE=21, 727 727 ATOM_CONNECTOR_FORCED_TMDS_CAP_RECORD_TYPE=22, 728 + ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE=23, 728 729 ATOM_RECORD_END_TYPE =0xFF, 729 730 }; 730 731