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.

efi/libstub: gop: Add support for reading EDID

Add support for EFI_EDID_DISCOVERED_PROTOCOL and EFI_EDID_ACTIVE_PROTOCOL
as defined in UEFI 2.8, sec 12.9. Define GUIDs and data structures in the
rsp header files.

In the GOP setup function, read the EDID of the primary GOP device. First
try EFI_EDID_ACTIVE_PROTOCOL, which supports user-specified EDID data. Or
else try EFI_EDID_DISCOVERED_PROTOCOL, which returns the display device's
native EDID. If no EDID could be retrieved, clear the storage.

Rename efi_setup_gop() to efi_setup_graphics() to reflect the changes
Let callers pass an optional instance of struct edid_data, if they are
interested.

While screen_info and edid_info come from the same device handle, they
should be considered indendent data. The former refers to the graphics
mode, the latter refers to the display device. GOP devices might not
provide both.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

authored by

Thomas Zimmermann and committed by
Ard Biesheuvel
17029cdd ae42b9c5

+69 -4
+1 -1
drivers/firmware/efi/libstub/efi-stub.c
··· 56 56 { 57 57 struct screen_info *si, tmp = {}; 58 58 59 - if (efi_setup_gop(&tmp) != EFI_SUCCESS) 59 + if (efi_setup_graphics(&tmp, NULL) != EFI_SUCCESS) 60 60 return NULL; 61 61 62 62 si = alloc_screen_info();
+30 -1
drivers/firmware/efi/libstub/efistub.h
··· 34 34 #define EFI_ALLOC_LIMIT ULONG_MAX 35 35 #endif 36 36 37 + struct edid_info; 38 + struct screen_info; 39 + 37 40 extern bool efi_no5lvl; 38 41 extern bool efi_nochunk; 39 42 extern bool efi_nokaslr; ··· 581 578 } mixed_mode; 582 579 }; 583 580 581 + typedef union efi_edid_discovered_protocol efi_edid_discovered_protocol_t; 582 + 583 + union efi_edid_discovered_protocol { 584 + struct { 585 + u32 size_of_edid; 586 + u8 *edid; 587 + }; 588 + struct { 589 + u32 size_of_edid; 590 + u32 edid; 591 + } mixed_mode; 592 + }; 593 + 594 + typedef union efi_edid_active_protocol efi_edid_active_protocol_t; 595 + 596 + union efi_edid_active_protocol { 597 + struct { 598 + u32 size_of_edid; 599 + u8 *edid; 600 + }; 601 + struct { 602 + u32 size_of_edid; 603 + u32 edid; 604 + } mixed_mode; 605 + }; 606 + 584 607 typedef union { 585 608 struct { 586 609 u32 revision; ··· 1114 1085 1115 1086 void efi_parse_option_graphics(char *option); 1116 1087 1117 - efi_status_t efi_setup_gop(struct screen_info *si); 1088 + efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid); 1118 1089 1119 1090 efi_status_t handle_cmdline_files(efi_loaded_image_t *image, 1120 1091 const efi_char16_t *optstr,
+35 -1
drivers/firmware/efi/libstub/gop.c
··· 12 12 #include <linux/string.h> 13 13 #include <asm/efi.h> 14 14 #include <asm/setup.h> 15 + #include <video/edid.h> 15 16 16 17 #include "efistub.h" 17 18 ··· 414 413 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; 415 414 } 416 415 416 + static void setup_edid_info(struct edid_info *edid, u32 gop_size_of_edid, u8 *gop_edid) 417 + { 418 + if (!gop_edid || gop_size_of_edid < 128) 419 + memset(edid->dummy, 0, sizeof(edid->dummy)); 420 + else 421 + memcpy(edid->dummy, gop_edid, min(gop_size_of_edid, sizeof(edid->dummy))); 422 + } 423 + 417 424 static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_handle_t handles[], 418 425 efi_graphics_output_protocol_t **found_gop) 419 426 { ··· 478 469 return first_gop_handle; 479 470 } 480 471 481 - efi_status_t efi_setup_gop(struct screen_info *si) 472 + efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid) 482 473 { 483 474 efi_handle_t *handles __free(efi_pool) = NULL; 484 475 efi_handle_t handle; ··· 502 493 /* EFI framebuffer */ 503 494 if (si) 504 495 setup_screen_info(si, gop); 496 + 497 + /* Display EDID for primary GOP */ 498 + if (edid) { 499 + efi_edid_discovered_protocol_t *discovered_edid; 500 + efi_edid_active_protocol_t *active_edid; 501 + u32 gop_size_of_edid = 0; 502 + u8 *gop_edid = NULL; 503 + 504 + status = efi_bs_call(handle_protocol, handle, &EFI_EDID_ACTIVE_PROTOCOL_GUID, 505 + (void **)&active_edid); 506 + if (status == EFI_SUCCESS) { 507 + gop_size_of_edid = active_edid->size_of_edid; 508 + gop_edid = active_edid->edid; 509 + } else { 510 + status = efi_bs_call(handle_protocol, handle, 511 + &EFI_EDID_DISCOVERED_PROTOCOL_GUID, 512 + (void **)&discovered_edid); 513 + if (status == EFI_SUCCESS) { 514 + gop_size_of_edid = discovered_edid->size_of_edid; 515 + gop_edid = discovered_edid->edid; 516 + } 517 + } 518 + 519 + setup_edid_info(edid, gop_size_of_edid, gop_edid); 520 + } 505 521 506 522 return EFI_SUCCESS; 507 523 }
+1 -1
drivers/firmware/efi/libstub/x86-stub.c
··· 488 488 { 489 489 struct screen_info *si = memset(&boot_params->screen_info, 0, sizeof(*si)); 490 490 491 - efi_setup_gop(si); 491 + efi_setup_graphics(si, NULL); 492 492 } 493 493 494 494 static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status)
+2
include/linux/efi.h
··· 373 373 #define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID EFI_GUID(0x8b843e20, 0x8132, 0x4852, 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c) 374 374 #define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID EFI_GUID(0x05c99a21, 0xc70f, 0x4ad2, 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e) 375 375 #define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a) 376 + #define EFI_EDID_DISCOVERED_PROTOCOL_GUID EFI_GUID(0x1c0c34f6, 0xd380, 0x41fa, 0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa) 377 + #define EFI_EDID_ACTIVE_PROTOCOL_GUID EFI_GUID(0xbd8c1056, 0x9f36, 0x44ec, 0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86) 376 378 #define EFI_PCI_IO_PROTOCOL_GUID EFI_GUID(0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a) 377 379 #define EFI_FILE_INFO_ID EFI_GUID(0x09576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) 378 380 #define EFI_SYSTEM_RESOURCE_TABLE_GUID EFI_GUID(0xb122a263, 0x3661, 0x4f68, 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80)