edid: parse timing data from CVT range limit descriptor

Signed-off-by: Simon Ser <contact@emersion.fr>
This commit is contained in:
Simon Ser 2022-08-09 10:22:38 +02:00
parent 7c8bcb09eb
commit c637a9daf8
5 changed files with 171 additions and 32 deletions

View file

@ -341,6 +341,24 @@ display_range_limits_type_name(enum di_edid_display_range_limits_type type)
abort(); abort();
} }
static const char *
cvt_aspect_ratio_name(enum di_edid_cvt_aspect_ratio aspect_ratio)
{
switch (aspect_ratio) {
case DI_EDID_CVT_ASPECT_RATIO_4_3:
return "4:3";
case DI_EDID_CVT_ASPECT_RATIO_16_9:
return "16:9";
case DI_EDID_CVT_ASPECT_RATIO_16_10:
return "16:10";
case DI_EDID_CVT_ASPECT_RATIO_5_4:
return "5:4";
case DI_EDID_CVT_ASPECT_RATIO_15_9:
return "15:9";
}
abort();
}
static void static void
print_display_desc(const struct di_edid *edid, print_display_desc(const struct di_edid *edid,
const struct di_edid_display_descriptor *desc) const struct di_edid_display_descriptor *desc)
@ -397,6 +415,51 @@ print_display_desc(const struct di_edid *edid,
printf(" K: %u\n", (int) range_limits->secondary_gtf->k); printf(" K: %u\n", (int) range_limits->secondary_gtf->k);
printf(" J: %.1f%%\n", range_limits->secondary_gtf->j); printf(" J: %.1f%%\n", range_limits->secondary_gtf->j);
break; break;
case DI_EDID_DISPLAY_RANGE_LIMITS_CVT:
printf(" CVT version %d.%d\n",
range_limits->cvt->version,
range_limits->cvt->revision);
if (range_limits->cvt->max_horiz_px != 0)
printf(" Max active pixels per line: %d\n",
range_limits->cvt->max_horiz_px);
printf(" Supported aspect ratios:");
if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_4_3)
printf(" 4:3");
if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_16_9)
printf(" 16:9");
if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_16_10)
printf(" 16:10");
if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_5_4)
printf(" 5:4");
if (range_limits->cvt->supported_aspect_ratio & DI_EDID_CVT_ASPECT_RATIO_15_9)
printf(" 15:9");
printf("\n");
printf(" Preferred aspect ratio: %s\n",
cvt_aspect_ratio_name(range_limits->cvt->preferred_aspect_ratio));
if (range_limits->cvt->standard_blanking)
printf(" Supports CVT standard blanking\n");
if (range_limits->cvt->reduced_blanking)
printf(" Supports CVT reduced blanking\n");
if (range_limits->cvt->supported_scaling != 0) {
printf(" Supported display scaling:\n");
if (range_limits->cvt->supported_scaling & DI_EDID_CVT_SCALING_HORIZ_SHRINK)
printf(" Horizontal shrink\n");
if (range_limits->cvt->supported_scaling & DI_EDID_CVT_SCALING_HORIZ_STRETCH)
printf(" Horizontal stretch\n");
if (range_limits->cvt->supported_scaling & DI_EDID_CVT_SCALING_VERT_SHRINK)
printf(" Vertical shrink\n");
if (range_limits->cvt->supported_scaling & DI_EDID_CVT_SCALING_VERT_STRETCH)
printf(" Vertical stretch\n");
}
printf(" Preferred vertical refresh: %d Hz\n",
range_limits->cvt->preferred_vert_refresh_hz);
break;
default: default:
break; break;
} }

62
edid.c
View file

@ -496,12 +496,13 @@ parse_display_range_limits(struct di_edid *edid,
struct di_edid_display_range_limits_priv *priv) struct di_edid_display_range_limits_priv *priv)
{ {
uint8_t offset_flags, vert_offset_flags, horiz_offset_flags; uint8_t offset_flags, vert_offset_flags, horiz_offset_flags;
uint8_t support_flags; uint8_t support_flags, preferred_aspect_ratio;
int max_vert_offset = 0, min_vert_offset = 0; int max_vert_offset = 0, min_vert_offset = 0;
int max_horiz_offset = 0, min_horiz_offset = 0; int max_horiz_offset = 0, min_horiz_offset = 0;
size_t i; size_t i;
struct di_edid_display_range_limits *base; struct di_edid_display_range_limits *base;
struct di_edid_display_range_limits_secondary_gtf *secondary_gtf; struct di_edid_display_range_limits_secondary_gtf *secondary_gtf;
struct di_edid_display_range_limits_cvt *cvt;
base = &priv->base; base = &priv->base;
@ -633,7 +634,64 @@ parse_display_range_limits(struct di_edid *edid,
base->secondary_gtf = secondary_gtf; base->secondary_gtf = secondary_gtf;
break; break;
case DI_EDID_DISPLAY_RANGE_LIMITS_CVT: case DI_EDID_DISPLAY_RANGE_LIMITS_CVT:
/* TODO: parse video timing data in bytes 11 to 17 */ cvt = &priv->cvt;
cvt->version = get_bit_range(data[11], 7, 4);
cvt->revision = get_bit_range(data[11], 3, 0);
base->max_pixel_clock_hz -= get_bit_range(data[12], 7, 2) * 250 * 1000;
cvt->max_horiz_px = 8 * ((get_bit_range(data[12], 1, 0) << 8) | data[13]);
cvt->supported_aspect_ratio = data[14];
if (get_bit_range(data[14], 2, 0) != 0)
add_failure_until(edid, 4,
"Display Range Limits: Reserved bits of byte 14 are non-zero.");
preferred_aspect_ratio = get_bit_range(data[15], 7, 5);
switch (preferred_aspect_ratio) {
case 0:
cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_4_3;
break;
case 1:
cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_16_9;
break;
case 2:
cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_16_10;
break;
case 3:
cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_5_4;
break;
case 4:
cvt->preferred_aspect_ratio = DI_EDID_CVT_ASPECT_RATIO_15_9;
break;
default:
/* Reserved */
add_failure_until(edid, 4,
"Display Range Limits: Invalid preferred aspect ratio 0x%02x.",
preferred_aspect_ratio);
return false;
}
cvt->standard_blanking = has_bit(data[15], 3);
cvt->reduced_blanking = has_bit(data[15], 4);
if (get_bit_range(data[15], 2, 0) != 0)
add_failure_until(edid, 4,
"Display Range Limits: Reserved bits of byte 15 are non-zero.");
cvt->supported_scaling = data[16];
if (get_bit_range(data[16], 3, 0) != 0)
add_failure_until(edid, 4,
"Display Range Limits: Reserved bits of byte 16 are non-zero.");
cvt->preferred_vert_refresh_hz = data[17];
if (cvt->preferred_vert_refresh_hz == 0) {
add_failure_until(edid, 4,
"Display Range Limits: Preferred vertical refresh rate must be specified.");
return false;
}
base->cvt = cvt;
break; break;
case DI_EDID_DISPLAY_RANGE_LIMITS_BARE: case DI_EDID_DISPLAY_RANGE_LIMITS_BARE:
case DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF: case DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF:

View file

@ -84,6 +84,7 @@ struct di_edid {
struct di_edid_display_range_limits_priv { struct di_edid_display_range_limits_priv {
struct di_edid_display_range_limits base; struct di_edid_display_range_limits base;
struct di_edid_display_range_limits_secondary_gtf secondary_gtf; struct di_edid_display_range_limits_secondary_gtf secondary_gtf;
struct di_edid_display_range_limits_cvt cvt;
}; };
struct di_edid_display_descriptor { struct di_edid_display_descriptor {

View file

@ -558,6 +558,40 @@ struct di_edid_display_range_limits_secondary_gtf {
float c, m, k, j; float c, m, k, j;
}; };
enum di_edid_cvt_aspect_ratio {
DI_EDID_CVT_ASPECT_RATIO_4_3 = 1 << 7,
DI_EDID_CVT_ASPECT_RATIO_16_9 = 1 << 6,
DI_EDID_CVT_ASPECT_RATIO_16_10 = 1 << 5,
DI_EDID_CVT_ASPECT_RATIO_5_4 = 1 << 4,
DI_EDID_CVT_ASPECT_RATIO_15_9 = 1 << 3,
};
enum di_edid_cvt_scaling {
DI_EDID_CVT_SCALING_HORIZ_SHRINK = 1 << 7,
DI_EDID_CVT_SCALING_HORIZ_STRETCH = 1 << 6,
DI_EDID_CVT_SCALING_VERT_SHRINK = 1 << 5,
DI_EDID_CVT_SCALING_VERT_STRETCH = 1 << 4,
};
struct di_edid_display_range_limits_cvt {
int32_t version, revision;
/* Maximum active pixels per line, zero for no limit */
int32_t max_horiz_px;
/* Supported aspect ratio, bitfield of enum di_edid_cvt_aspect_ratio */
uint32_t supported_aspect_ratio;
/* Preferred aspect ratio */
enum di_edid_cvt_aspect_ratio preferred_aspect_ratio;
/* Whether standard CVT blanking is supported */
bool standard_blanking;
/* Whether reduced CVT blanking is supported */
bool reduced_blanking;
/* Supported types of display scaling, bitfield of
* enum di_edid_cvt_scaling */
uint32_t supported_scaling;
/* Preferred vertical refresh rate, in Hz */
int32_t preferred_vert_refresh_hz;
};
/** /**
* EDID display range limits, defined in section 3.10.3.3.1. * EDID display range limits, defined in section 3.10.3.3.1.
*/ */
@ -569,13 +603,16 @@ struct di_edid_display_range_limits {
int32_t min_horiz_rate_hz, max_horiz_rate_hz; int32_t min_horiz_rate_hz, max_horiz_rate_hz;
/* Maximum pixel clock in Hz, zero if unset, rounded to the nearest /* Maximum pixel clock in Hz, zero if unset, rounded to the nearest
* multiple of 10 MHz */ * multiple of 0.25 MHz if CVT, otherwise to the nearest multiple of
* 10 MHz */
int32_t max_pixel_clock_hz; int32_t max_pixel_clock_hz;
enum di_edid_display_range_limits_type type; enum di_edid_display_range_limits_type type;
/* For SECONDARY_GTF limits, NULL otherwise */ /* For SECONDARY_GTF limits, NULL otherwise */
const struct di_edid_display_range_limits_secondary_gtf *secondary_gtf; const struct di_edid_display_range_limits_secondary_gtf *secondary_gtf;
/* For CVT limits, NULL otherwise */
const struct di_edid_display_range_limits_cvt *cvt;
}; };
/** /**

View file

@ -23,26 +23,7 @@
Detailed Timing Descriptors: Detailed Timing Descriptors:
DTD 1: 2560x1440 59.950550 Hz 16:9 88.787 kHz 241.500000 MHz (597 mm x 336 mm) DTD 1: 2560x1440 59.950550 Hz 16:9 88.787 kHz 241.500000 MHz (597 mm x 336 mm)
Hfront 48 Hsync 32 Hback 80 Hpol P Hfront 48 Hsync 32 Hback 80 Hpol P
@@ -53,18 +53,6 @@ @@ -79,35 +79,29 @@
Display Product Serial Number: 'UY5171500307'
Display Range Limits:
Monitor ranges (CVT): 50-75 Hz V, 24-90 kHz H, max dotclock 250 MHz
- CVT version 1.1
- Max active pixels per line: 6400
- Supported aspect ratios: 4:3 16:9
- Preferred aspect ratio: 16:9
- Supports CVT standard blanking
- Supports CVT reduced blanking
- Supported display scaling:
- Horizontal shrink
- Horizontal stretch
- Vertical shrink
- Vertical stretch
- Preferred vertical refresh: 60 Hz
Display Product Name: 'VP2768 Series'
Extension blocks: 1
Checksum: 0xa0
@@ -79,35 +67,29 @@
Supports YCbCr 4:2:2 Supports YCbCr 4:2:2
Native detailed modes: 1 Native detailed modes: 1
Video Data Block: Video Data Block:
@ -94,7 +75,7 @@
DTD 4: 1280x720 60.000000 Hz 16:9 45.000 kHz 74.250000 MHz (597 mm x 336 mm) DTD 4: 1280x720 60.000000 Hz 16:9 45.000 kHz 74.250000 MHz (597 mm x 336 mm)
Hfront 110 Hsync 40 Hback 220 Hpol P Hfront 110 Hsync 40 Hback 220 Hpol P
Vfront 5 Vsync 5 Vback 20 Vpol P Vfront 5 Vsync 5 Vback 20 Vpol P
@@ -117,28 +99,8 @@ @@ -117,28 +111,14 @@
DTD 6: 1920x1080 50.000000 Hz 16:9 56.250 kHz 148.500000 MHz (597 mm x 336 mm) DTD 6: 1920x1080 50.000000 Hz 16:9 56.250 kHz 148.500000 MHz (597 mm x 336 mm)
Hfront 528 Hsync 44 Hback 148 Hpol P Hfront 528 Hsync 44 Hback 148 Hpol P
Vfront 4 Vsync 5 Vback 36 Vpol P Vfront 4 Vsync 5 Vback 36 Vpol P
@ -111,17 +92,16 @@
- Base EDID: Some timings are out of range of the Monitor Ranges: - Base EDID: Some timings are out of range of the Monitor Ranges:
- Vertical Freq: 24.000 - 75.062 Hz (Monitor: 50.000 - 75.000 Hz) - Vertical Freq: 24.000 - 75.062 Hz (Monitor: 50.000 - 75.000 Hz)
- -
-Failures: Failures:
-
-Block 0, Base EDID: Block 0, Base EDID:
- Basic Display Parameters & Features: sRGB is signaled, but the chromaticities do not match. - Basic Display Parameters & Features: sRGB is signaled, but the chromaticities do not match.
- Display Range Limits: Reserved bits of byte 14 are non-zero. Display Range Limits: Reserved bits of byte 14 are non-zero.
- Display Range Limits: Reserved bits of byte 15 are non-zero. Display Range Limits: Reserved bits of byte 15 are non-zero.
- Display Range Limits: Reserved bits of byte 16 are non-zero. Display Range Limits: Reserved bits of byte 16 are non-zero.
-Block 1, CTA-861 Extension Block: -Block 1, CTA-861 Extension Block:
- Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues. - Missing VCDB, needed for Set Selectable RGB Quantization to avoid interop issues.
-EDID: -EDID:
- CTA-861: Native progressive timings are a mix of several resolutions. - CTA-861: Native progressive timings are a mix of several resolutions.
- -
-EDID conformity: FAIL EDID conformity: FAIL
+EDID conformity: PASS