Skip to main content

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}