/** * @file edid.h * * @ingroup i386_pc386 * * @brief VESA EDID definitions. * * This file contains definitions for constants related to * VESA Extended Display Identification Data. * More information can be found at * * VESA public standards may be found at * */ /* * Copyright (C) 2014 Jan Doležal (dolezj21@fel.cvut.cz) * CTU in Prague. * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. */ #ifndef _EDID_H #define _EDID_H #ifndef ASM /* ASM */ #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include #define EDID_INLINE_ROUTINE RTEMS_INLINE_ROUTINE /* VESA Enhanced Extended Display Identification Data (E-EDID) Proposed Release A, March 27, 2007 */ /* *** Detailed Timing Descriptor Flags *** */ #define EDID1_DTD_Flag_InterlacedOff 7 #define EDID1_DTD_Flag_InterlacedMask 0x1 #define EDID1_DTD_Flag_StereoModeOff 0 #define EDID1_DTD_Flag_StereoModeMask 0xC1 /* values for stereo flag */ #define EDID1_DTD_Stereo_FldSeqRightOnSync 0x40 #define EDID1_DTD_Stereo_FldSeqLeftOnSync 0x80 #define EDID1_DTD_Stereo_2wItlvdRightOnEven 0x41 #define EDID1_DTD_Stereo_2wItlvdLeftOnEven 0x81 #define EDID1_DTD_Stereo_4wInterleaved 0xC0 #define EDID1_DTD_Stereo_SideBySideItlvd 0xC1 /* Analog = 0, Digital = 1 */ #define EDID1_DTD_Flag_DigitalOff 4 #define EDID1_DTD_Flag_DigitalMask 0x1 /* Analog */ #define EDID1_DTD_BipolarAnalogComposSyncOff 3 #define EDID1_DTD_BipolarAnalogComposSyncMask 0x1 #define EDID1_DTD_WithSerrationsOff 2 #define EDID1_DTD_WithSerrationsMask 0x1 /* Digital */ #define EDID1_DTD_DigitalSeparateSyncOff 3 #define EDID1_DTD_DigitalSeparateSyncMask 0x1 /* when DigitalSeparateSync == 0 -> it is composite and WithSerrations defined up in Analog part applies */ #define EDID1_DTD_VerticalSyncIsPositiveOff 2 #define EDID1_DTD_VerticalSyncIsPositiveMask 0x1 #define EDID1_DTD_HorizontalSyncIsPositiveOff 1 #define EDID1_DTD_HorizontalSyncIsPositiveMask 0x1 typedef struct { uint8_t PixelClock_div10000[2]; uint8_t HorizontalActiveLow; uint8_t HorizontalBlankingLow; uint8_t HorizontalBlanking_ActiveHigh; uint8_t VerticalActiveLow; uint8_t VerticalBlankingLow; uint8_t VerticalBlanking_ActiveHigh; uint8_t HorizontalSyncOffsetLow; uint8_t HorizontalSyncPulseWidthLow; uint8_t VerticalSyncPulseWidth_OffsetLow; uint8_t Vert_Hor_SyncPulseWidth_Offset_High; uint8_t HorizontalImageSizeLow; uint8_t VerticalImageSizeLow; uint8_t Vertical_HorizontalImageSizeHigh; uint8_t HorizontalBorder; uint8_t VerticalBorder; uint8_t Flags; } RTEMS_PACKED EDID_detailed_timing_descriptor; EDID_INLINE_ROUTINE uint16_t DTD_horizontal_active ( EDID_detailed_timing_descriptor *dtd) { return (dtd->HorizontalActiveLow | (dtd->HorizontalBlanking_ActiveHigh & 0xF0) << 4); } EDID_INLINE_ROUTINE uint16_t DTD_horizontal_blanking ( EDID_detailed_timing_descriptor *dtd) { return (dtd->HorizontalBlankingLow | (dtd->HorizontalBlanking_ActiveHigh & 0xF) << 8); } EDID_INLINE_ROUTINE uint16_t DTD_vertical_active ( EDID_detailed_timing_descriptor *dtd) { return (dtd->VerticalActiveLow | (dtd->VerticalBlanking_ActiveHigh & 0xF0) << 4); } EDID_INLINE_ROUTINE uint16_t DTD_vertical_blanking ( EDID_detailed_timing_descriptor *dtd) { return (dtd->VerticalBlankingLow | (dtd->VerticalBlanking_ActiveHigh & 0xF) << 8); } EDID_INLINE_ROUTINE uint16_t DTD_vertical_sync_pulse_width ( EDID_detailed_timing_descriptor *dtd) { return ((dtd->VerticalSyncPulseWidth_OffsetLow & 0xF) | (dtd->Vert_Hor_SyncPulseWidth_Offset_High & 0x3) << 4); } EDID_INLINE_ROUTINE uint16_t DTD_vertical_sync_offset ( EDID_detailed_timing_descriptor *dtd) { return ((dtd->VerticalSyncPulseWidth_OffsetLow >> 4) | (dtd->Vert_Hor_SyncPulseWidth_Offset_High & 0xC) << 2); } EDID_INLINE_ROUTINE uint16_t DTD_horizontal_sync_pulse_width ( EDID_detailed_timing_descriptor *dtd) { return (dtd->HorizontalSyncPulseWidthLow | (dtd->Vert_Hor_SyncPulseWidth_Offset_High & 0x30) << 4); } EDID_INLINE_ROUTINE uint16_t DTD_horizontal_sync_offset ( EDID_detailed_timing_descriptor *dtd) { return (dtd->HorizontalSyncOffsetLow | (dtd->Vert_Hor_SyncPulseWidth_Offset_High & 0xC0) << 2); } EDID_INLINE_ROUTINE uint16_t DTD_vertical_image_size ( EDID_detailed_timing_descriptor *dtd) { return (dtd->VerticalImageSizeLow | (dtd->Vertical_HorizontalImageSizeHigh & 0xF) << 8); } EDID_INLINE_ROUTINE uint16_t DTD_horizontal_image_size ( EDID_detailed_timing_descriptor *dtd) { return (dtd->HorizontalImageSizeLow | (dtd->Vertical_HorizontalImageSizeHigh & 0xF0) << 4); } typedef struct { uint8_t ColorPointWhitePointIndexNumber; uint8_t ColorPointWhiteLowBits; uint8_t ColorPointWhite_x; uint8_t ColorPointWhite_y; uint8_t ColorPointWhiteGamma; } RTEMS_PACKED EDID_color_point_data; /* Basic Display Parameters */ /* Monitor Descriptor - Data Type Tag */ #define EDID_DTT_MonitorSerialNumber 0xFF #define EDID_DTT_ASCIIString 0xFE #define EDID_DTT_MonitorRangeLimits 0xFD typedef struct { uint8_t MinVerticalRateInHz; uint8_t MaxVerticalRateInHz; uint8_t MinHorizontalInKHz; uint8_t MaxHorizontalInKHz; uint8_t MaxSupportedPixelClockIn10MHz; /* see VESA, Generalized Timing Formula Standard - GTF Version 1.0, December 18, 1996 */ uint8_t GTFStandard[8]; } RTEMS_PACKED EDID_monitor_range_limits; #define EDID_DTT_MonitorName 0xFC #define EDID_DTT_AdditionalColorPointData 0xFB /* Standard Timing Identification */ #define EDID_DTT_AdditionalSTI 0xFA #define EDID_DTT_DisplayColorManagement 0xF9 #define EDID_DTT_CVT3ByteTimingCodes 0xF8 #define EDID1_CVT_AspectRatioOff 2 #define EDID1_CVT_AspectRatioMask 0x3 #define EDID1_CVT_AddressableLinesHighOff 4 #define EDID1_CVT_AddressableLinesHighMask 0xF /* next 5 bits indicate supported vertical rates */ #define EDID1_CVT_VerticalRate60HzRBOff 0 #define EDID1_CVT_VerticalRate60HzRBMask 0x1 #define EDID1_CVT_VerticalRate85HzOff 1 #define EDID1_CVT_VerticalRate85HzMask 0x1 #define EDID1_CVT_VerticalRate75HzOff 2 #define EDID1_CVT_VerticalRate75HzMask 0x1 #define EDID1_CVT_VerticalRate60HzOff 3 #define EDID1_CVT_VerticalRate60HzMask 0x1 #define EDID1_CVT_VerticalRate50HzOff 4 #define EDID1_CVT_VerticalRate50HzMask 0x1 #define EDID1_CVT_PreferredVerticalRateOff 5 #define EDID1_CVT_PreferredVerticalRateMask 0x3 #define EDID_CVT_AspectRatio_4_3 0 #define EDID_CVT_AspectRatio_16_9 1 #define EDID_CVT_AspectRatio_16_10 2 #define EDID_CVT_AspectRatio_15_9 3 #define EDID_CVT_PrefVertRate50Hz 0 #define EDID_CVT_PrefVertRate60Hz 1 #define EDID_CVT_PrefVertRate75Hz 2 #define EDID_CVT_PrefVertRate85Hz 3 typedef struct { uint8_t AddressableLinesLow; uint8_t AspectRatio_AddressableLinesHigh; uint8_t VerticalRate_PreferredVerticalRate; } RTEMS_PACKED EDID_CVT_3_byte_code_descriptor; typedef struct { uint8_t VersionNumber; EDID_CVT_3_byte_code_descriptor cvt[4]; } RTEMS_PACKED EDID_CVT_timing_codes_3B; EDID_INLINE_ROUTINE uint16_t edid1_CVT_addressable_lines_high ( EDID_CVT_3_byte_code_descriptor *cvt) { return (cvt->AddressableLinesLow | (cvt->VerticalRate_PreferredVerticalRate & (EDID1_CVT_AddressableLinesHighMask<AspectRatio_AddressableLinesHigh >> EDID1_CVT_AspectRatioOff) & EDID1_CVT_AspectRatioMask; } #define EDID_DTT_EstablishedTimingsIII 0xF7 typedef struct { uint8_t RevisionNumber; uint8_t EST_III[12]; } RTEMS_PACKED EDID_established_timings_III; enum EST_III { EST_1152x864_75Hz = 0, EST_1024x768_85Hz = 1, EST_800x600_85Hz = 2, EST_848x480_60Hz = 3, EST_640x480_85Hz = 4, EST_720x400_85Hz = 5, EST_640x400_85Hz = 6, EST_640x350_85Hz = 7, EST_1280x1024_85Hz = 8, EST_1280x1024_60Hz = 9, EST_1280x960_85Hz = 10, EST_1280x960_60Hz = 11, EST_1280x768_85Hz = 12, EST_1280x768_75Hz = 13, EST_1280x768_60Hz = 14, EST_1280x768_60HzRB = 15, EST_1400x1050_75Hz = 16, EST_1400x1050_60Hz = 17, EST_1400x1050_60HzRB= 18, EST_1400x900_85Hz = 19, EST_1400x900_75Hz = 20, EST_1400x900_60Hz = 21, EST_1400x900_60HzRB = 22, EST_1360x768_60Hz = 23, EST_1600x1200_70Hz = 24, EST_1600x1200_65Hz = 25, EST_1600x1200_60Hz = 26, EST_1680x1050_85Hz = 27, EST_1680x1050_75Hz = 28, EST_1680x1050_60Hz = 29, EST_1680x1050_60HzRB= 30, EST_1400x1050_85Hz = 31, EST_1920x1200_60Hz = 32, EST_1920x1200_60HzRB= 33, EST_1856x1392_75Hz = 34, EST_1856x1392_60Hz = 35, EST_1792x1344_75Hz = 36, EST_1792x1344_60Hz = 37, EST_1600x1200_85Hz = 38, EST_1600x1200_75Hz = 39, EST_1920x1440_75Hz = 44, EST_1920x1440_60Hz = 45, EST_1920x1200_85Hz = 46, EST_1920x1200_75Hz = 47, }; #define EDID_DTT_DescriptorSpaceUnused 0x10 /* DTT 0x0 - 0xF are manufacturer specific */ typedef struct { uint8_t Flag0[2]; uint8_t Flag1; uint8_t DataTypeTag; uint8_t Flag2; uint8_t DescriptorData[13]; } RTEMS_PACKED EDID_monitor_descriptor; union EDID_DTD_MD { EDID_detailed_timing_descriptor dtd; EDID_monitor_descriptor md; } RTEMS_PACKED; #define EDID1_STI_ImageAspectRatioOff 0 #define EDID1_STI_ImageAspectRatioMask 0x3 #define EDID1_STI_RefreshRateOff 2 #define EDID1_STI_RefreshRateMask 0x3F #define EDID_STI_DescriptorUnused 0x0101 #define EDID_STI_AspectRatio_16_10 0 #define EDID_STI_AspectRatio_4_3 1 #define EDID_STI_AspectRatio_5_4 2 #define EDID_STI_AspectRatio_16_9 3 typedef struct { uint8_t HorizontalActivePixels; uint8_t ImageAspectRatio_RefreshRate; } RTEMS_PACKED EDID_standard_timing_identification; /* Video Input Definition */ /* Analog = 0, Digital = 1 */ #define EDID1_VID_DigitalSignalLevelOff 7 #define EDID1_VID_DigitalSignalLevelMask 0x1 /* for EDID1_VID_DigitalSignalLevelOff = 1 (Digital) */ #define EDID1_VID_ColorBitDepthOff 4 #define EDID1_VID_ColorBitDepthMask 0x7 /* see CBD */ #define EDID1_VID_DigitalVideoStandardSuppOff 0 #define EDID1_VID_DigitalVideoStandardSuppMask 0xF /* see DVS */ /* for EDID1_VID_DigitalSignalLevelOff = 0 (Analog) */ #define EDID1_VID_SignalLevelStandardOff 5 #define EDID1_VID_SignalLevelStandardMask 0x3 #define EDID1_VID_VideoSetupBlankOff 4 #define EDID1_VID_VideoSetupBlankMask 0x1 #define EDID1_VID_SeparateSyncHandVSignalsOff 3 #define EDID1_VID_SeparateSyncHandVSignalsMask 0x1 #define EDID1_VID_SyncSignalOnHorizontalOff 2 #define EDID1_VID_SyncSignalOnHorizontalMask 0x1 #define EDID1_VID_SyncSignalOnGreenOff 1 #define EDID1_VID_SyncSignalOnGreenMask 0x1 #define EDID1_VID_SerationOnVerticalSyncOff 0 #define EDID1_VID_SerationOnVerticalSyncMask 0x1 /* Analog Interface Data Format - Signal Level Standard */ #define EDID_SLS_0700_0300_1000Vpp 0x0 #define EDID_SLS_0714_0286_1000Vpp 0x1 #define EDID_SLS_1000_0400_1400Vpp 0x2 #define EDID_SLS_0700_0000_0700Vpp 0x3 /* Color Bit Depths */ #define CBD_undef 0x0 #define CBD_6bPerPrimaryColor 0x1 #define CBD_8bPerPrimaryColor 0x2 #define CBD_10bPerPrimaryColor 0x3 #define CBD_12bPerPrimaryColor 0x4 #define CBD_14bPerPrimaryColor 0x5 #define CBD_16bPerPrimaryColor 0x6 #define CBD_reserved 0x7 /* Digital Video Standard Supported */ #define DVS_undef 0x0 #define DVS_DVI 0x1 #define DVS_HDMI-a 0x2 #define DVS_HDMI-b 0x3 #define DVS_MDDI 0x4 #define DVS_DiplayPort 0x5 /* Feature Support */ #define EDID1_Feature_GTFSupported_mask 0x1 #define EDID1_Feature_GTFSupported_off 0 #define EDID1_Feature_PreferredTimingMode_mask 0x1 #define EDID1_Feature_PreferredTimingMode_off 1 #define EDID1_Feature_StandardDefaultColorSpace_mask 0x1 #define EDID1_Feature_StandardDefaultColorSpace_off 2 #define EDID1_Feature_DisplayType_mask 0x2 #define EDID1_Feature_DisplayType_off 3 /* Refer to VESA DPMS Specification */ #define EDID1_Feature_ActiveOff_mask 0x1 #define EDID1_Feature_ActiveOff_off 5 #define EDID1_Feature_Suspend_mask 0x1 #define EDID1_Feature_Suspend_off 6 #define EDID1_Feature_StandBy_mask 0x1 #define EDID1_Feature_StandBy_off 7 /* analog - Display Color Type */ #define EDID_DisplayType_Monochrome 0 #define EDID_DisplayType_RGBcolor 1 #define EDID_DisplayType_nonRGBcolor 2 #define EDID_DisplayType_undef 3 /* digital - Supported Color Encoding Formats */ #define EDID_DisplayType_RGB444 0 #define EDID_DisplayType_RGB444YCrCb444 1 #define EDID_DisplayType_RGB444YCrCb422 2 #define EDID_DisplayType_RGB444YCrCb444YCrCb422 3 typedef struct { uint8_t Header[8]; /* Vendor Product Identification */ uint8_t IDManufacturerName[2]; uint8_t IDProductCode[2]; uint8_t IDSerialNumber[4]; uint8_t WeekofManufacture; uint8_t YearofManufacture; /* EDID Structure Version Revision Level */ uint8_t Version; uint8_t Revision; /* Basic Display Parameters Features */ /* Video Input Definition */ uint8_t VideoInputDefinition; uint8_t MaxHorizontalImageSize; uint8_t MaxVerticalImageSize; uint8_t DisplayTransferCharacteristic; /* Feature Support */ uint8_t Features; /* Color Characteristics */ uint8_t GreenRedLow; uint8_t WhiteBlueLow; uint8_t RedXHigh; uint8_t RedYHigh; uint8_t GreenXHigh; uint8_t GreenYHigh; uint8_t BlueXHigh; uint8_t BlueYHigh; uint8_t WhiteXHigh; uint8_t WhiteYHigh; /* Established Timings I, II, Manufacturer's */ uint8_t EST_I_II_Man[3]; /* Standard Timing Identification */ EDID_standard_timing_identification STI[8]; /* Detailed Timing Descriptions / Monitor Descriptions */ union EDID_DTD_MD dtd_md[4]; uint8_t ExtensionFlag; uint8_t Checksum; } RTEMS_PACKED EDID_edid1; EDID_INLINE_ROUTINE uint16_t edid1_RedX (EDID_edid1 *edid) { return (edid->RedXHigh<<2) | (edid->GreenRedLow>>6); } EDID_INLINE_ROUTINE uint16_t edid1_RedY (EDID_edid1 *edid) { return (edid->RedYHigh<<2) | (edid->GreenRedLow>>4)&&0x3; } EDID_INLINE_ROUTINE uint16_t edid1_GreenX (EDID_edid1 *edid) { return (edid->GreenXHigh<<2) | (edid->GreenRedLow>>2)&&0x3; } EDID_INLINE_ROUTINE uint16_t edid1_GreenY (EDID_edid1 *edid) { return (edid->GreenYHigh<<2) | (edid->GreenRedLow&0x3); } EDID_INLINE_ROUTINE uint16_t edid1_BlueX (EDID_edid1 *edid) { return (edid->BlueXHigh<<2) | (edid->WhiteBlueLow>>6); } EDID_INLINE_ROUTINE uint16_t edid1_BlueY (EDID_edid1 *edid) { return (edid->BlueYHigh<<2) | (edid->WhiteBlueLow>>4)&&0x3; } EDID_INLINE_ROUTINE uint16_t edid1_WhiteX (EDID_edid1 *edid) { return (edid->WhiteXHigh<<2) | (edid->WhiteBlueLow>>2)&&0x3; } EDID_INLINE_ROUTINE uint16_t edid1_WhiteY (EDID_edid1 *edid) { return (edid->WhiteYHigh<<2) | (edid->WhiteBlueLow&0x3); } EDID_INLINE_ROUTINE int edid1_STI_is_unused ( const EDID_standard_timing_identification *edid_sti) { return (edid_sti->HorizontalActivePixels == (uint8_t)EDID_STI_DescriptorUnused) && (edid_sti->ImageAspectRatio_RefreshRate == (uint8_t)(EDID_STI_DescriptorUnused >> 8)); } enum edid1_established_timings { /* Established Timings I */ EST_800x600_60Hz = 0, EST_800x600_56Hz = 1, EST_640x480_75Hz = 2, EST_640x480_72Hz = 3, EST_640x480_67Hz = 4, EST_640x480_60Hz = 5, EST_720x400_88Hz = 6, EST_720x400_70Hz = 7, /* Established Timings II */ EST_1280x1024_75Hz = 8, EST_1024x768_75Hz = 9, EST_1024x768_70Hz = 10, EST_1024x768_60Hz = 11, EST_1024x768_87Hz = 12, EST_832x624_75Hz = 13, EST_800x600_75Hz = 14, EST_800x600_72Hz = 15, /* Manufacturer's Timings */ EST_1152x870_75Hz = 23, }; EDID_INLINE_ROUTINE uint8_t edid1_established_tim ( EDID_edid1 *edid, enum edid1_established_timings est) { return (uint8_t)(edid->EST_I_II_Man[est/8] & (est%8)); } #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* ASM */ #endif /* _VBE_H */