framebuffer: report display EDID data
This allows to see the display in Screen preferences, and know its DPI and physical size (as much as EDID data can be trusted). This information could be used to compute the default font size, for example, so it's important that all drivers provide it whenever possible. Change-Id: Ic3d04e53cf5fcb24e22d35661d2b364a257947da Reviewed-on: https://review.haiku-os.org/c/haiku/+/6576 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
29f8da76d7
commit
37e1b12911
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 Adrien Destugues <[email protected]>
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <efi/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define EFI_EDID_DISCOVERED_PROTOCOL_GUID \
|
||||||
|
{0x1c0c34f6, 0xd380, 0x41fa, {0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa}}
|
||||||
|
|
||||||
|
#define EFI_EDID_ACTIVE_PROTOCOL_GUID \
|
||||||
|
{0xbd8c1056, 0x9f36, 0x44ec, {0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86}}
|
||||||
|
|
||||||
|
#define EFI_EDID_OVERRIDE_PROTOCOL_GUID \
|
||||||
|
{0x48ecb431, 0xfb72, 0x45c0, {0xa9, 0x22, 0xf4, 0x58, 0xfe, 0x04, 0x0b, 0xd5}}
|
||||||
|
|
||||||
|
|
||||||
|
struct efi_edid_protocol {
|
||||||
|
uint32_t SizeOfEdid;
|
||||||
|
uint8_t* Edid;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct efi_edid_override_protocol {
|
||||||
|
efi_status (*GetEdid) (struct efi_edid_override_protocol* self, efi_handle* child,
|
||||||
|
uint32_t* attributes, size_t* edidSize, uint8_t** edid) EFIAPI;
|
||||||
|
};
|
||||||
@@ -29,6 +29,7 @@ uint32 framebuffer_accelerant_mode_count(void);
|
|||||||
status_t framebuffer_get_mode_list(display_mode *dm);
|
status_t framebuffer_get_mode_list(display_mode *dm);
|
||||||
status_t framebuffer_set_display_mode(display_mode *modeToSet);
|
status_t framebuffer_set_display_mode(display_mode *modeToSet);
|
||||||
status_t framebuffer_get_display_mode(display_mode *currentMode);
|
status_t framebuffer_get_display_mode(display_mode *currentMode);
|
||||||
|
status_t framebuffer_get_edid_info(void *info, size_t size, uint32 *_version);
|
||||||
status_t framebuffer_get_frame_buffer_config(frame_buffer_config *config);
|
status_t framebuffer_get_frame_buffer_config(frame_buffer_config *config);
|
||||||
status_t framebuffer_get_pixel_clock_limits(display_mode *dm, uint32 *low,
|
status_t framebuffer_get_pixel_clock_limits(display_mode *dm, uint32 *low,
|
||||||
uint32 *high);
|
uint32 *high);
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ get_accelerant_hook(uint32 feature, void* data)
|
|||||||
return (void*)framebuffer_set_display_mode;
|
return (void*)framebuffer_set_display_mode;
|
||||||
case B_GET_DISPLAY_MODE:
|
case B_GET_DISPLAY_MODE:
|
||||||
return (void*)framebuffer_get_display_mode;
|
return (void*)framebuffer_get_display_mode;
|
||||||
|
case B_GET_EDID_INFO:
|
||||||
|
return (void*)framebuffer_get_edid_info;
|
||||||
case B_GET_FRAME_BUFFER_CONFIG:
|
case B_GET_FRAME_BUFFER_CONFIG:
|
||||||
return (void*)framebuffer_get_frame_buffer_config;
|
return (void*)framebuffer_get_frame_buffer_config;
|
||||||
case B_GET_PIXEL_CLOCK_LIMITS:
|
case B_GET_PIXEL_CLOCK_LIMITS:
|
||||||
|
|||||||
@@ -113,6 +113,22 @@ framebuffer_get_display_mode(display_mode* _currentMode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
framebuffer_get_edid_info(void* info, size_t size, uint32* _version)
|
||||||
|
{
|
||||||
|
TRACE(("framebuffer_get_edid_info()\n"));
|
||||||
|
|
||||||
|
if (!gInfo->shared_info->has_edid)
|
||||||
|
return B_ERROR;
|
||||||
|
if (size < sizeof(struct edid1_info))
|
||||||
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
|
memcpy(info, &gInfo->shared_info->edid_info, sizeof(struct edid1_info));
|
||||||
|
*_version = EDID_VERSION_1;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
framebuffer_get_frame_buffer_config(frame_buffer_config* config)
|
framebuffer_get_frame_buffer_config(frame_buffer_config* config)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -197,6 +197,13 @@ framebuffer_init(framebuffer_info& info)
|
|||||||
sharedInfo.current_mode.space = get_color_space_for_depth(
|
sharedInfo.current_mode.space = get_color_space_for_depth(
|
||||||
bufferInfo->depth);
|
bufferInfo->depth);
|
||||||
|
|
||||||
|
edid1_info* edidInfo = (edid1_info*)get_boot_item(VESA_EDID_BOOT_INFO,
|
||||||
|
NULL);
|
||||||
|
if (edidInfo != NULL) {
|
||||||
|
sharedInfo.has_edid = true;
|
||||||
|
memcpy(&sharedInfo.edid_info, edidInfo, sizeof(edid1_info));
|
||||||
|
}
|
||||||
|
|
||||||
dprintf(DEVICE_NAME ": framebuffer_init() completed successfully!\n");
|
dprintf(DEVICE_NAME ": framebuffer_init() completed successfully!\n");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
SubDir HAIKU_TOP src system boot platform efi ;
|
SubDir HAIKU_TOP src system boot platform efi ;
|
||||||
|
|
||||||
|
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel boot ] ;
|
UsePrivateHeaders [ FDirName kernel boot ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel platform ] ;
|
UsePrivateHeaders [ FDirName kernel platform ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel boot platform efi ] ;
|
UsePrivateHeaders [ FDirName kernel boot platform efi ] ;
|
||||||
@@ -38,6 +39,8 @@ local platform_src =
|
|||||||
quirks.cpp
|
quirks.cpp
|
||||||
smp.cpp
|
smp.cpp
|
||||||
serial.cpp
|
serial.cpp
|
||||||
|
|
||||||
|
decode_edid.c
|
||||||
;
|
;
|
||||||
|
|
||||||
local support_libs ;
|
local support_libs ;
|
||||||
@@ -50,6 +53,7 @@ if $(TARGET_ARCH) != x86_64 && $(TARGET_ARCH) != x86 {
|
|||||||
local platform ;
|
local platform ;
|
||||||
for platform in [ MultiBootSubDirSetup efi ] {
|
for platform in [ MultiBootSubDirSetup efi ] {
|
||||||
on $(platform) {
|
on $(platform) {
|
||||||
|
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ;
|
||||||
|
|
||||||
BootMergeObject boot_platform_efi_common.o :
|
BootMergeObject boot_platform_efi_common.o :
|
||||||
$(platform_src)
|
$(platform_src)
|
||||||
|
|||||||
@@ -15,9 +15,11 @@
|
|||||||
#include <boot/stage2.h>
|
#include <boot/stage2.h>
|
||||||
#include <boot/stdio.h>
|
#include <boot/stdio.h>
|
||||||
#include <drivers/driver_settings.h>
|
#include <drivers/driver_settings.h>
|
||||||
|
#include <edid.h>
|
||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
|
|
||||||
#include "efi_platform.h"
|
#include "efi_platform.h"
|
||||||
|
#include <efi/protocol/edid.h>
|
||||||
#include <efi/protocol/graphics-output.h>
|
#include <efi/protocol/graphics-output.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -37,7 +39,9 @@ struct video_mode {
|
|||||||
|
|
||||||
|
|
||||||
static efi_guid sGraphicsOutputGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
static efi_guid sGraphicsOutputGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||||
|
static efi_guid sEdidActiveGuid = EFI_EDID_ACTIVE_PROTOCOL_GUID;
|
||||||
static efi_graphics_output_protocol *sGraphicsOutput;
|
static efi_graphics_output_protocol *sGraphicsOutput;
|
||||||
|
static efi_edid_protocol *sEdidActiveProtocol;
|
||||||
static size_t sGraphicsMode;
|
static size_t sGraphicsMode;
|
||||||
static struct list sModeList;
|
static struct list sModeList;
|
||||||
static uint32 sModeCount;
|
static uint32 sModeCount;
|
||||||
@@ -151,15 +155,16 @@ platform_init_video(void)
|
|||||||
{
|
{
|
||||||
list_init(&sModeList);
|
list_init(&sModeList);
|
||||||
|
|
||||||
// we don't support VESA modes or EDID
|
// we don't support VESA modes
|
||||||
gKernelArgs.vesa_modes = NULL;
|
gKernelArgs.vesa_modes = NULL;
|
||||||
gKernelArgs.vesa_modes_size = 0;
|
gKernelArgs.vesa_modes_size = 0;
|
||||||
|
|
||||||
gKernelArgs.edid_info = NULL;
|
gKernelArgs.edid_info = NULL;
|
||||||
|
|
||||||
// make a guess at the best video mode to use, and save the mode ID
|
// make a guess at the best video mode to use, and save the mode ID for switching to graphics
|
||||||
// for switching to graphics mode
|
// mode
|
||||||
efi_status status = kBootServices->LocateProtocol(&sGraphicsOutputGuid,
|
efi_status status = kBootServices->LocateProtocol(&sGraphicsOutputGuid, NULL,
|
||||||
NULL, (void **)&sGraphicsOutput);
|
(void **)&sGraphicsOutput);
|
||||||
if (sGraphicsOutput == NULL || status != EFI_SUCCESS) {
|
if (sGraphicsOutput == NULL || status != EFI_SUCCESS) {
|
||||||
dprintf("GOP protocol not found\n");
|
dprintf("GOP protocol not found\n");
|
||||||
gKernelArgs.frame_buffer.enabled = false;
|
gKernelArgs.frame_buffer.enabled = false;
|
||||||
@@ -228,6 +233,17 @@ platform_init_video(void)
|
|||||||
gKernelArgs.frame_buffer.enabled = true;
|
gKernelArgs.frame_buffer.enabled = true;
|
||||||
sModeChosen = false;
|
sModeChosen = false;
|
||||||
sSettingsLoaded = false;
|
sSettingsLoaded = false;
|
||||||
|
|
||||||
|
status = kBootServices->LocateProtocol(&sEdidActiveGuid, NULL, (void **)&sEdidActiveProtocol);
|
||||||
|
if ((sEdidActiveProtocol != NULL) && (status == EFI_SUCCESS)
|
||||||
|
&& (sEdidActiveProtocol->SizeOfEdid) != 0) {
|
||||||
|
edid1_info* edid_info = (edid1_info*)kernel_args_malloc(sizeof(edid1_info));
|
||||||
|
if (edid_info != NULL) {
|
||||||
|
edid_decode(edid_info, (edid1_raw*)sEdidActiveProtocol->Edid);
|
||||||
|
gKernelArgs.edid_info = edid_info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user