display_types/timing.rs
1/// Video timing support reported in the display range limits descriptor (`0xFD`), byte 10.
2///
3/// Indicates which timing generation formula (if any) the display supports beyond the
4/// explicitly listed modes.
5#[non_exhaustive]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum TimingFormula {
9 /// Default GTF supported (byte 10 = `0x00`).
10 ///
11 /// The display accepts any timing within its range limits that satisfies the
12 /// default GTF parameters. Requires bit 0 of the Feature Support byte (`0x18`) to be set.
13 DefaultGtf,
14 /// Range limits only; no secondary timing formula (byte 10 = `0x01`).
15 ///
16 /// The display supports only the video timing modes explicitly listed in the EDID.
17 RangeLimitsOnly,
18 /// Secondary GTF curve supported (byte 10 = `0x02`).
19 ///
20 /// The display accepts timings using either the default GTF or the secondary GTF curve
21 /// whose parameters are stored in bytes 12–17.
22 SecondaryGtf(GtfSecondaryParams),
23 /// CVT timing supported (byte 10 = `0x04`), with parameters from bytes 11–17.
24 ///
25 /// The display accepts Coordinated Video Timings within its range limits.
26 /// Requires bit 0 of the Feature Support byte (`0x18`) to be set.
27 Cvt(CvtSupportParams),
28}
29
30/// GTF secondary curve parameters decoded from a display range limits descriptor (`0xFD`).
31///
32/// Used when [`TimingFormula::SecondaryGtf`] is active (byte 10 = `0x02`).
33/// The GTF formula selects the secondary curve for horizontal frequencies at or above
34/// [`start_freq_khz`][Self::start_freq_khz] and the default curve below it.
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct GtfSecondaryParams {
38 /// Start break frequency in kHz (byte 12 × 2).
39 pub start_freq_khz: u16,
40 /// GTF `C` parameter (0–127); byte 13 ÷ 2.
41 pub c: u8,
42 /// GTF `M` parameter (0–65535); bytes 14–15, little-endian.
43 pub m: u16,
44 /// GTF `K` parameter (0–255); byte 16.
45 pub k: u8,
46 /// GTF `J` parameter (0–127); byte 17 ÷ 2.
47 pub j: u8,
48}
49
50/// CVT support parameters decoded from a display range limits descriptor (`0xFD`).
51///
52/// Used when [`TimingFormula::Cvt`] is active (byte 10 = `0x04`).
53#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct CvtSupportParams {
56 /// CVT standard version, encoded as two BCD nibbles (e.g., `0x11` = version 1.1).
57 pub version: u8,
58 /// Additional pixel clock precision: 6-bit value from byte 12 bits 7–2.
59 ///
60 /// The maximum pixel clock is: `(descriptor byte 9 × 10 MHz) − (pixel_clock_adjust × 0.25 MHz)`.
61 /// When all six bits are set (`63`), byte 9 was already rounded up to the nearest 10 MHz.
62 pub pixel_clock_adjust: u8,
63 /// Maximum number of horizontal active pixels, or `None` if there is no limit.
64 ///
65 /// Computed as `8 × (byte 13 + 256 × (byte 12 bits 1–0))`. `None` when the 10-bit
66 /// combined value is zero.
67 pub max_h_active_pixels: Option<u16>,
68 /// Aspect ratios the display supports for CVT-generated timings.
69 pub supported_aspect_ratios: CvtAspectRatios,
70 /// Preferred aspect ratio for CVT-generated timings, or `None` for a reserved value.
71 pub preferred_aspect_ratio: Option<CvtAspectRatio>,
72 /// Standard CVT blanking (normal blanking) is supported.
73 pub standard_blanking: bool,
74 /// Reduced CVT blanking is supported (preferred over standard blanking).
75 pub reduced_blanking: bool,
76 /// Display scaling capabilities.
77 pub scaling: CvtScaling,
78 /// Preferred vertical refresh rate in Hz, or `None` if byte 17 = `0x00` (reserved).
79 pub preferred_v_rate: Option<u8>,
80}
81
82bitflags::bitflags! {
83 /// Aspect ratios supported for CVT-generated timings (byte 14 of a `0xFD` descriptor).
84 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
85 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
86 pub struct CvtAspectRatios: u8 {
87 /// 4∶3 aspect ratio supported.
88 const R4_3 = 0x80;
89 /// 16∶9 aspect ratio supported.
90 const R16_9 = 0x40;
91 /// 16∶10 aspect ratio supported.
92 const R16_10 = 0x20;
93 /// 5∶4 aspect ratio supported.
94 const R5_4 = 0x10;
95 /// 15∶9 aspect ratio supported.
96 const R15_9 = 0x08;
97 }
98}
99
100bitflags::bitflags! {
101 /// Display scaling capabilities reported in byte 16 of a `0xFD` CVT descriptor.
102 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
103 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
104 pub struct CvtScaling: u8 {
105 /// Input horizontal active pixels can exceed the display's preferred horizontal count.
106 const HORIZONTAL_SHRINK = 0x80;
107 /// Input horizontal active pixels can be fewer than the display's preferred horizontal count.
108 const HORIZONTAL_STRETCH = 0x40;
109 /// Input vertical active lines can exceed the display's preferred vertical count.
110 const VERTICAL_SHRINK = 0x20;
111 /// Input vertical active lines can be fewer than the display's preferred vertical count.
112 const VERTICAL_STRETCH = 0x10;
113 }
114}
115
116/// Preferred aspect ratio for CVT-generated timings, decoded from byte 15 bits 7–5.
117#[non_exhaustive]
118#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
119#[derive(Debug, Clone, Copy, PartialEq, Eq)]
120pub enum CvtAspectRatio {
121 /// 4∶3 preferred aspect ratio.
122 R4_3,
123 /// 16∶9 preferred aspect ratio.
124 R16_9,
125 /// 16∶10 preferred aspect ratio.
126 R16_10,
127 /// 5∶4 preferred aspect ratio.
128 R5_4,
129 /// 15∶9 preferred aspect ratio.
130 R15_9,
131}