{
}
+static void __init efi_arch_edid(EFI_HANDLE gop_handle)
+{
+}
+
static void __init efi_arch_memory_setup(void)
{
}
pushw %dx
pushw %di
- cmpb $1, bootsym(opt_edid) # EDID disabled on cmdline (edid=no)?
+ movb bootsym(opt_edid), %al
+ cmpw $0x1313, bootsym(boot_edid_caps) # Data already retrieved?
+ je .Lcheck_edid
+ cmpb $2, %al # EDID forced on cmdline (edid=force)?
+ jne .Lno_edid
+
+.Lcheck_edid:
+ cmpb $1, %al # EDID disabled on cmdline (edid=no)?
je .Lno_edid
leaw vesa_glob_info, %di
#endif
}
+#ifdef CONFIG_VIDEO
+static bool __init copy_edid(const void *buf, unsigned int size)
+{
+ /*
+ * Be conservative - for both undersized and oversized blobs it is unclear
+ * what to actually do with them. The more that unlike the VESA BIOS
+ * interface we also have no associated "capabilities" value (which might
+ * carry a hint as to possible interpretation).
+ */
+ if ( size != ARRAY_SIZE(boot_edid_info) )
+ return false;
+
+ memcpy(boot_edid_info, buf, size);
+ boot_edid_caps = 0;
+
+ return true;
+}
+#endif
+
+static void __init efi_arch_edid(EFI_HANDLE gop_handle)
+{
+#ifdef CONFIG_VIDEO
+ static EFI_GUID __initdata active_guid = EFI_EDID_ACTIVE_PROTOCOL_GUID;
+ static EFI_GUID __initdata discovered_guid = EFI_EDID_DISCOVERED_PROTOCOL_GUID;
+ EFI_EDID_ACTIVE_PROTOCOL *active_edid;
+ EFI_EDID_DISCOVERED_PROTOCOL *discovered_edid;
+ EFI_STATUS status;
+
+ status = efi_bs->OpenProtocol(gop_handle, &active_guid,
+ (void **)&active_edid, efi_ih, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if ( status == EFI_SUCCESS &&
+ copy_edid(active_edid->Edid, active_edid->SizeOfEdid) )
+ return;
+
+ /*
+ * In case an override is in place which doesn't fit copy_edid(), also try
+ * obtaining the discovered EDID in the hope that it's better than nothing.
+ *
+ * Note that attempting to use the information in
+ * EFI_EDID_DISCOVERED_PROTOCOL when there's an override provided by
+ * EFI_EDID_ACTIVE_PROTOCOL might lead to issues.
+ */
+ status = efi_bs->OpenProtocol(gop_handle, &discovered_guid,
+ (void **)&discovered_edid, efi_ih, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if ( status == EFI_SUCCESS )
+ copy_edid(discovered_edid->Edid, discovered_edid->SizeOfEdid);
+#endif
+}
+
static void __init efi_arch_memory_setup(void)
{
unsigned int i;
void __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
+ EFI_HANDLE gop_handle;
UINTN cols, gop_mode = ~0, rows;
__set_bit(EFI_BOOT, &efi_flags);
&cols, &rows) == EFI_SUCCESS )
efi_arch_console_init(cols, rows);
- gop = efi_get_gop();
+ gop = efi_get_gop(&gop_handle);
if ( gop )
+ {
gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
+ efi_arch_edid(gop_handle);
+ }
+
efi_arch_edd();
efi_arch_cpu();
static void efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);
static void efi_console_set_mode(void);
-static EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_get_gop(void);
+static EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_get_gop(EFI_HANDLE *gop_handle);
static UINTN efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
UINTN cols, UINTN rows, UINTN depth);
static void efi_tables(void);
StdOut->SetMode(StdOut, best);
}
-static EFI_GRAPHICS_OUTPUT_PROTOCOL __init *efi_get_gop(void)
+static EFI_GRAPHICS_OUTPUT_PROTOCOL __init *efi_get_gop(EFI_HANDLE *gop_handle)
{
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
continue;
status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
if ( !EFI_ERROR(status) )
+ {
+ *gop_handle = handles[i];
break;
+ }
}
if ( handles )
efi_bs->FreePool(handles);
if ( use_cfg_file )
{
EFI_FILE_HANDLE dir_handle;
+ EFI_HANDLE gop_handle;
UINTN depth, cols, rows, size;
size = cols = rows = depth = 0;
&cols, &rows) == EFI_SUCCESS )
efi_arch_console_init(cols, rows);
- gop = efi_get_gop();
+ gop = efi_get_gop(&gop_handle);
/* Get the file system interface. */
dir_handle = get_parent_handle(loaded_image, &file_name);
dir_handle->Close(dir_handle);
if ( gop && !base_video )
+ {
gop_mode = efi_find_gop_mode(gop, cols, rows, depth);
+
+ efi_arch_edid(gop_handle);
+ }
}
/* Get the number of boot modules specified on the DT or an error (<0) */
efi_arch_edd();
- /* XXX Collect EDID info. */
efi_arch_cpu();
efi_tables();
EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
};
+
+/*
+ * EFI EDID Discovered Protocol
+ * UEFI Specification Version 2.5 Section 11.9
+ */
+#define EFI_EDID_DISCOVERED_PROTOCOL_GUID \
+ { 0x1C0C34F6, 0xD380, 0x41FA, { 0xA0, 0x49, 0x8a, 0xD0, 0x6C, 0x1A, 0x66, 0xAA} }
+
+typedef struct _EFI_EDID_DISCOVERED_PROTOCOL {
+ UINT32 SizeOfEdid;
+ UINT8 *Edid;
+} EFI_EDID_DISCOVERED_PROTOCOL;
+
+/*
+ * EFI EDID Active Protocol
+ * UEFI Specification Version 2.5 Section 11.9
+ */
+#define EFI_EDID_ACTIVE_PROTOCOL_GUID \
+ { 0xBD8C1056, 0x9F36, 0x44EC, { 0x92, 0xA8, 0xA6, 0x33, 0x7F, 0x81, 0x79, 0x86} }
+
+typedef struct _EFI_EDID_ACTIVE_PROTOCOL {
+ UINT32 SizeOfEdid;
+ UINT8 *Edid;
+} EFI_EDID_ACTIVE_PROTOCOL;
+
+/*
+ * EFI EDID Override Protocol
+ * UEFI Specification Version 2.5 Section 11.9
+ */
+#define EFI_EDID_OVERRIDE_PROTOCOL_GUID \
+ { 0x48ECB431, 0xFB72, 0x45C0, { 0xA9, 0x22, 0xF4, 0x58, 0xFE, 0x04, 0x0B, 0xD5} }
+
+INTERFACE_DECL(_EFI_EDID_OVERRIDE_PROTOCOL);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID) (
+ IN struct _EFI_EDID_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE *ChildHandle,
+ OUT UINT32 *Attributes,
+ IN OUT UINTN *EdidSize,
+ IN OUT UINT8 **Edid);
+
+typedef struct _EFI_EDID_OVERRIDE_PROTOCOL {
+ EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID GetEdid;
+} EFI_EDID_OVERRIDE_PROTOCOL;
+
#endif