2008-11-07 14:05:41 -08:00
/*
* Copyright © 2007 - 2008 Intel Corporation
* Jesse Barnes < jesse . barnes @ intel . com >
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE COPYRIGHT HOLDER ( S ) OR AUTHOR ( S ) BE LIABLE FOR ANY CLAIM , DAMAGES OR
* OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE ,
* ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE .
*/
# ifndef __DRM_EDID_H__
# define __DRM_EDID_H__
# include <linux/types.h>
# define EDID_LENGTH 128
# define DDC_ADDR 0x50
2010-08-03 14:38:17 -04:00
# define CEA_EXT 0x02
# define VTB_EXT 0x10
# define DI_EXT 0x40
# define LS_EXT 0x50
# define MI_EXT 0x60
2008-11-07 14:05:41 -08:00
struct est_timings {
u8 t1 ;
u8 t2 ;
u8 mfg_rsvd ;
} __attribute__ ( ( packed ) ) ;
2009-06-15 16:56:07 +02:00
/* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */
2009-06-23 12:36:32 +02:00
# define EDID_TIMING_ASPECT_SHIFT 6
2009-06-15 16:56:07 +02:00
# define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT)
/* need to add 60 */
2009-06-23 12:36:32 +02:00
# define EDID_TIMING_VFREQ_SHIFT 0
2009-06-15 16:56:07 +02:00
# define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT)
2008-11-07 14:05:41 -08:00
struct std_timing {
u8 hsize ; /* need to multiply by 8 then add 248 */
2009-06-15 16:56:07 +02:00
u8 vfreq_aspect ;
2008-11-07 14:05:41 -08:00
} __attribute__ ( ( packed ) ) ;
2009-06-23 12:36:32 +02:00
# define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1)
# define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2)
2009-06-15 16:56:07 +02:00
# define DRM_EDID_PT_SEPARATE_SYNC (3 << 3)
2009-06-23 12:36:32 +02:00
# define DRM_EDID_PT_STEREO (1 << 5)
# define DRM_EDID_PT_INTERLACED (1 << 7)
2009-06-15 16:56:07 +02:00
2008-11-07 14:05:41 -08:00
/* If detailed data is pixel timing */
struct detailed_pixel_timing {
u8 hactive_lo ;
u8 hblank_lo ;
2009-06-15 16:56:07 +02:00
u8 hactive_hblank_hi ;
2008-11-07 14:05:41 -08:00
u8 vactive_lo ;
u8 vblank_lo ;
2009-06-15 16:56:07 +02:00
u8 vactive_vblank_hi ;
2008-11-07 14:05:41 -08:00
u8 hsync_offset_lo ;
u8 hsync_pulse_width_lo ;
2009-06-15 16:56:07 +02:00
u8 vsync_offset_pulse_width_lo ;
u8 hsync_vsync_offset_pulse_width_hi ;
2008-11-07 14:05:41 -08:00
u8 width_mm_lo ;
u8 height_mm_lo ;
2009-06-15 16:56:07 +02:00
u8 width_height_mm_hi ;
2008-11-07 14:05:41 -08:00
u8 hborder ;
u8 vborder ;
2009-06-15 16:56:07 +02:00
u8 misc ;
2008-11-07 14:05:41 -08:00
} __attribute__ ( ( packed ) ) ;
/* If it's not pixel timing, it'll be one of the below */
struct detailed_data_string {
u8 str [ 13 ] ;
} __attribute__ ( ( packed ) ) ;
struct detailed_data_monitor_range {
u8 min_vfreq ;
u8 max_vfreq ;
u8 min_hfreq_khz ;
u8 max_hfreq_khz ;
u8 pixel_clock_mhz ; /* need to multiply by 10 */
2012-04-13 16:33:37 -04:00
u8 flags ;
union {
struct {
u8 reserved ;
u8 hfreq_start_khz ; /* need to multiply by 2 */
u8 c ; /* need to divide by 2 */
__le16 m ;
u8 k ;
u8 j ; /* need to divide by 2 */
2012-04-23 17:40:49 +01:00
} __attribute__ ( ( packed ) ) gtf2 ;
2012-04-13 16:33:37 -04:00
struct {
u8 version ;
u8 data1 ; /* high 6 bits: extra clock resolution */
u8 data2 ; /* plus low 2 of above: max hactive */
u8 supported_aspects ;
u8 flags ; /* preferred aspect and blanking support */
u8 supported_scalings ;
u8 preferred_refresh ;
2012-04-23 17:40:49 +01:00
} __attribute__ ( ( packed ) ) cvt ;
2012-04-13 16:33:37 -04:00
} formula ;
2008-11-07 14:05:41 -08:00
} __attribute__ ( ( packed ) ) ;
struct detailed_data_wpindex {
2009-06-23 12:36:32 +02:00
u8 white_yx_lo ; /* Lower 2 bits each */
2008-11-07 14:05:41 -08:00
u8 white_x_hi ;
u8 white_y_hi ;
u8 gamma ; /* need to divide by 100 then add 1 */
} __attribute__ ( ( packed ) ) ;
struct detailed_data_color_point {
u8 windex1 ;
u8 wpindex1 [ 3 ] ;
u8 windex2 ;
u8 wpindex2 [ 3 ] ;
} __attribute__ ( ( packed ) ) ;
2009-12-03 17:44:40 -05:00
struct cvt_timing {
u8 code [ 3 ] ;
} __attribute__ ( ( packed ) ) ;
2008-11-07 14:05:41 -08:00
struct detailed_non_pixel {
u8 pad1 ;
u8 type ; /* ff=serial, fe=string, fd=monitor range, fc=monitor name
fb = color point data , fa = standard timing data ,
f9 = undefined , f8 = mfg . reserved */
u8 pad2 ;
union {
struct detailed_data_string str ;
struct detailed_data_monitor_range range ;
struct detailed_data_wpindex color ;
2010-05-14 13:06:19 +02:00
struct std_timing timings [ 6 ] ;
2009-12-03 17:44:40 -05:00
struct cvt_timing cvt [ 4 ] ;
2008-11-07 14:05:41 -08:00
} data ;
} __attribute__ ( ( packed ) ) ;
2009-12-03 17:44:39 -05:00
# define EDID_DETAIL_EST_TIMINGS 0xf7
# define EDID_DETAIL_CVT_3BYTE 0xf8
# define EDID_DETAIL_COLOR_MGMT_DATA 0xf9
2008-11-07 14:05:41 -08:00
# define EDID_DETAIL_STD_MODES 0xfa
# define EDID_DETAIL_MONITOR_CPDATA 0xfb
# define EDID_DETAIL_MONITOR_NAME 0xfc
# define EDID_DETAIL_MONITOR_RANGE 0xfd
# define EDID_DETAIL_MONITOR_STRING 0xfe
# define EDID_DETAIL_MONITOR_SERIAL 0xff
struct detailed_timing {
2009-06-15 16:56:07 +02:00
__le16 pixel_clock ; /* need to multiply by 10 KHz */
2008-11-07 14:05:41 -08:00
union {
struct detailed_pixel_timing pixel_data ;
struct detailed_non_pixel other_data ;
} data ;
} __attribute__ ( ( packed ) ) ;
2009-06-23 12:36:32 +02:00
# define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 0)
# define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 1)
# define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 2)
2009-06-15 16:56:07 +02:00
# define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3)
2009-06-23 12:36:32 +02:00
# define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 4)
# define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 5)
2011-04-15 12:49:23 -07:00
# define DRM_EDID_INPUT_DIGITAL (1 << 7)
# define DRM_EDID_DIGITAL_DEPTH_MASK (7 << 4)
# define DRM_EDID_DIGITAL_DEPTH_UNDEF (0 << 4)
# define DRM_EDID_DIGITAL_DEPTH_6 (1 << 4)
# define DRM_EDID_DIGITAL_DEPTH_8 (2 << 4)
# define DRM_EDID_DIGITAL_DEPTH_10 (3 << 4)
# define DRM_EDID_DIGITAL_DEPTH_12 (4 << 4)
# define DRM_EDID_DIGITAL_DEPTH_14 (5 << 4)
# define DRM_EDID_DIGITAL_DEPTH_16 (6 << 4)
# define DRM_EDID_DIGITAL_DEPTH_RSVD (7 << 4)
# define DRM_EDID_DIGITAL_TYPE_UNDEF (0)
# define DRM_EDID_DIGITAL_TYPE_DVI (1)
# define DRM_EDID_DIGITAL_TYPE_HDMI_A (2)
# define DRM_EDID_DIGITAL_TYPE_HDMI_B (3)
# define DRM_EDID_DIGITAL_TYPE_MDDI (4)
# define DRM_EDID_DIGITAL_TYPE_DP (5)
2009-06-15 16:56:07 +02:00
2009-06-23 12:36:32 +02:00
# define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 0)
# define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 1)
# define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 2)
2011-04-15 13:48:57 -07:00
/* If analog */
2009-06-15 16:56:07 +02:00
# define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */
2011-04-15 13:48:57 -07:00
/* If digital */
# define DRM_EDID_FEATURE_COLOR_MASK (3 << 3)
# define DRM_EDID_FEATURE_RGB (0 << 3)
# define DRM_EDID_FEATURE_RGB_YCRCB444 (1 << 3)
# define DRM_EDID_FEATURE_RGB_YCRCB422 (2 << 3)
# define DRM_EDID_FEATURE_RGB_YCRCB (3 << 3) /* both 4:4:4 and 4:2:2 */
2009-06-23 12:36:32 +02:00
# define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 5)
# define DRM_EDID_FEATURE_PM_SUSPEND (1 << 6)
# define DRM_EDID_FEATURE_PM_STANDBY (1 << 7)
2009-06-15 16:56:07 +02:00
2008-11-07 14:05:41 -08:00
struct edid {
u8 header [ 8 ] ;
/* Vendor & product info */
u8 mfg_id [ 2 ] ;
u8 prod_code [ 2 ] ;
u32 serial ; /* FIXME: byte order */
u8 mfg_week ;
u8 mfg_year ;
/* EDID version */
u8 version ;
u8 revision ;
/* Display info: */
2009-06-15 16:56:07 +02:00
u8 input ;
2008-11-07 14:05:41 -08:00
u8 width_cm ;
u8 height_cm ;
u8 gamma ;
2009-06-15 16:56:07 +02:00
u8 features ;
2008-11-07 14:05:41 -08:00
/* Color characteristics */
u8 red_green_lo ;
u8 black_white_lo ;
u8 red_x ;
u8 red_y ;
u8 green_x ;
u8 green_y ;
u8 blue_x ;
u8 blue_y ;
u8 white_x ;
u8 white_y ;
/* Est. timings and mfg rsvd timings*/
struct est_timings established_timings ;
/* Standard timings 1-8*/
struct std_timing standard_timings [ 8 ] ;
/* Detailing timings 1-4 */
struct detailed_timing detailed_timings [ 4 ] ;
/* Number of 128 byte ext. blocks */
u8 extensions ;
/* Checksum */
u8 checksum ;
} __attribute__ ( ( packed ) ) ;
# define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
2011-09-05 14:23:20 +08:00
struct drm_encoder ;
struct drm_connector ;
struct drm_display_mode ;
void drm_edid_to_eld ( struct drm_connector * connector , struct edid * edid ) ;
int drm_av_sync_delay ( struct drm_connector * connector ,
struct drm_display_mode * mode ) ;
struct drm_connector * drm_select_eld ( struct drm_encoder * encoder ,
struct drm_display_mode * mode ) ;
2012-03-18 22:37:33 +01:00
int drm_load_edid_firmware ( struct drm_connector * connector ) ;
2011-09-05 14:23:20 +08:00
2008-11-07 14:05:41 -08:00
# endif /* __DRM_EDID_H__ */