graphics/edid: Add support for digital display info; solves #17462

* We pack the first 8 bits into a union for the raw
  edid since alignment matters.
* Handing the raw_edid is a bit ugly, so in the edid struct
  we drop the input_type from the union since packing doesn't
  matter as much.

Change-Id: I32dbfe9484f9eb83cf491a44d30a32ca36d65b7b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4775
Reviewed-by: Alex von Gluck IV <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Alexander von Gluck IV
2021-12-18 15:21:30 +00:00
committed by Adrien Destugues
parent 6a9aea9dfd
commit 65ed50c713
4 changed files with 80 additions and 38 deletions
+22 -10
View File
@@ -25,18 +25,30 @@ typedef struct {
uint8 revision; uint8 revision;
} edid1_version; } edid1_version;
// analog input parameters
typedef struct {
uint8 input_voltage; // 0=0.7V/0.3V, 1=0.714V/0.286,
// 2=1V/0.4V, 3=0.7V/0V
bool setup; // true if voltage configurable
bool sep_sync;
bool comp_sync;
bool sync_on_green;
bool sync_serr;
} edid1_analog_params;
// digital input parameters
typedef struct {
uint8 bit_depth;
uint8 interface;
} edid1_digital_params;
// display info // display info
typedef struct { typedef struct {
BBITFIELD8_7 ( uint8 input_type;
input_type : 1, // 1 : digital edid1_analog_params analog_params;
input_voltage : 2, // 0=0.7V/0.3V, 1=0.714V/0.286, edid1_digital_params digital_params;
// 2=1V/0.4V, 3=0.7V/0V
setup : 1, // true if voltage configurable
sep_sync : 1,
comp_sync : 1,
sync_on_green : 1,
sync_serr : 1
);
uint8 h_size; uint8 h_size;
uint8 v_size; uint8 v_size;
uint8 gamma; // (x+100)/100 uint8 gamma; // (x+100)/100
+24 -4
View File
@@ -61,11 +61,11 @@ typedef struct _PACKED {
} edid1_version_raw; } edid1_version_raw;
// display info // analog input parameters
typedef struct _PACKED { typedef struct _PACKED {
BBITFIELD8_7 ( BBITFIELD8_7 (
input_type : 1, // 1 : digital input_type : 1, // 0 : analog, 1 : digital
input_voltage : 2, // 0=0.7V/0.3V, 1=0.714V/0.286, input_voltage : 2, // 0=0.7V/0.3V, 1=0.714V/0.286,
// 2=1V/0.4V, 3=0.7V/0V // 2=1V/0.4V, 3=0.7V/0V
setup : 1, // true if voltage configurable setup : 1, // true if voltage configurable
sep_sync : 1, sep_sync : 1,
@@ -73,6 +73,26 @@ typedef struct _PACKED {
sync_on_green : 1, sync_on_green : 1,
sync_serr : 1 sync_serr : 1
); );
} edid1_analog_params_raw;
// digital input parameters
typedef struct _PACKED {
BBITFIELD8_3 (
input_type : 1, // 0 : analog, 1 : digital
bit_depth : 3, // 0=undefined, 1=6,2=8,3=10,4=12,5=14,6=16,7=reserved
interface : 4 // 0=undefined, 2=HDMIa, 3=HDMIb
// 4=MDDI, 5=DisplayPort
);
} edid1_digital_params_raw;
// display info
typedef struct _PACKED {
union {
edid1_analog_params_raw analog_params;
edid1_digital_params_raw digital_params;
};
uint8 h_size; uint8 h_size;
uint8 v_size; uint8 v_size;
uint8 gamma; // (x+100)/100 uint8 gamma; // (x+100)/100
+22 -9
View File
@@ -43,20 +43,33 @@ static void
decode_version(edid1_version *version, const edid1_version_raw *raw) decode_version(edid1_version *version, const edid1_version_raw *raw)
{ {
version->version = raw->version; version->version = raw->version;
version->revision = raw->revision; version->revision = raw->revision;
} }
static void static void
decode_display(edid1_display *display, const edid1_display_raw *raw) decode_display(edid1_display *display, const edid1_display_raw *raw)
{ {
display->input_type = raw->input_type; // We need to dig into one of the union to get the first
display->input_voltage = raw->input_voltage; // bit which should always align. then we can pick the right
display->setup = raw->setup; // data structure to parse.
display->sep_sync = raw->sep_sync; display->input_type = raw->analog_params.input_type;
display->comp_sync = raw->comp_sync;
display->sync_on_green = raw->sync_on_green; if (display->input_type != 0) {
display->sync_serr = raw->sync_serr; // digital
display->digital_params.bit_depth = 0;
if (raw->digital_params.bit_depth > 0 && raw->digital_params.bit_depth < 7)
display->digital_params.bit_depth = raw->digital_params.bit_depth * 2 + 4;
display->digital_params.interface = raw->digital_params.interface;
} else {
// analog
display->analog_params.input_voltage = raw->analog_params.input_voltage;
display->analog_params.setup = raw->analog_params.setup;
display->analog_params.sep_sync = raw->analog_params.sep_sync;
display->analog_params.comp_sync = raw->analog_params.comp_sync;
display->analog_params.sync_on_green = raw->analog_params.sync_on_green;
display->analog_params.sync_serr = raw->analog_params.sync_serr;
}
display->h_size = raw->h_size; display->h_size = raw->h_size;
display->v_size = raw->v_size; display->v_size = raw->v_size;
+12 -15
View File
@@ -4,12 +4,6 @@
*/ */
/*!
Part of DDC driver
Dumps EDID content
*/
#include "edid.h" #include "edid.h"
#if !defined(_KERNEL_MODE) && !defined(_BOOT_MODE) #if !defined(_KERNEL_MODE) && !defined(_BOOT_MODE)
# include "ddc_int.h" # include "ddc_int.h"
@@ -23,20 +17,23 @@ edid_dump(edid1_info *edid)
{ {
int i, j; int i, j;
dprintf("Vendor: %s\n", edid->vendor.manufacturer); dprintf("EDID info:\n");
dprintf("Product ID: %d\n", (int)edid->vendor.prod_id); dprintf(" Vendor: %s\n", edid->vendor.manufacturer);
dprintf("Serial #: %d\n", (int)edid->vendor.serial); dprintf(" Product ID: %d\n", (int)edid->vendor.prod_id);
dprintf("Produced in week/year: %d/%d\n", edid->vendor.week, dprintf(" Serial #: %d\n", (int)edid->vendor.serial);
dprintf(" Produced in week/year: %d/%d\n", edid->vendor.week,
edid->vendor.year); edid->vendor.year);
dprintf("EDID version: %d.%d\n", edid->version.version, dprintf(" EDID version: %d.%d\n", edid->version.version,
edid->version.revision); edid->version.revision);
dprintf("Type: %s\n", edid->display.input_type ? "Digital" : "Analog"); dprintf(" Type: %s\n", edid->display.input_type != 0 ? "Digital" : "Analog");
dprintf("Size: %d cm x %d cm\n", edid->display.h_size, if (edid->display.input_type != 0)
dprintf(" Digtial Bit Depth: %d\n", edid->display.digital_params.bit_depth);
dprintf(" Size: %d cm x %d cm\n", edid->display.h_size,
edid->display.v_size); edid->display.v_size);
dprintf("Gamma=%.3f\n", (edid->display.gamma + 100) / 100.0); dprintf(" Gamma=%.3f\n", (edid->display.gamma + 100) / 100.0);
dprintf("White (X,Y)=(%.3f,%.3f)\n", edid->display.white_x / 1024.0, dprintf(" White (X,Y)=(%.3f,%.3f)\n", edid->display.white_x / 1024.0,
edid->display.white_y / 1024.0); edid->display.white_y / 1024.0);
dprintf("Supported Future Video Modes:\n"); dprintf("Supported Future Video Modes:\n");