Loading drivers/gpu/drm/drm_edid.c +52 −48 Original line number Diff line number Diff line Loading @@ -252,16 +252,18 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, { struct drm_display_mode *mode; int hsize = t->hsize * 8 + 248, vsize; unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) >> EDID_TIMING_ASPECT_SHIFT; mode = drm_mode_create(dev); if (!mode) return NULL; if (t->aspect_ratio == 0) if (aspect_ratio == 0) vsize = (hsize * 10) / 16; else if (t->aspect_ratio == 1) else if (aspect_ratio == 1) vsize = (hsize * 3) / 4; else if (t->aspect_ratio == 2) else if (aspect_ratio == 2) vsize = (hsize * 4) / 5; else vsize = (hsize * 9) / 16; Loading @@ -288,17 +290,24 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, { struct drm_display_mode *mode; struct detailed_pixel_timing *pt = &timing->data.pixel_data; unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo; unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 8 | pt->hsync_offset_lo; unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 6 | pt->hsync_pulse_width_lo; unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) | (pt->vsync_offset_pulse_width_lo & 0xf); unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; /* ignore tiny modes */ if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 || ((pt->vactive_hi << 8) | pt->hactive_lo) < 64) if (hactive < 64 || vactive < 64) return NULL; if (pt->stereo) { if (pt->misc & DRM_EDID_PT_STEREO) { printk(KERN_WARNING "stereo mode not supported\n"); return NULL; } if (!pt->separate_sync) { if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) { printk(KERN_WARNING "integrated sync not supported\n"); return NULL; } Loading @@ -310,41 +319,36 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->type = DRM_MODE_TYPE_DRIVER; if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) timing->pixel_clock = 1088; mode->clock = timing->pixel_clock * 10; mode->hdisplay = (pt->hactive_hi << 8) | pt->hactive_lo; mode->hsync_start = mode->hdisplay + ((pt->hsync_offset_hi << 8) | pt->hsync_offset_lo); mode->hsync_end = mode->hsync_start + ((pt->hsync_pulse_width_hi << 8) | pt->hsync_pulse_width_lo); mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo); mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo; mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) | pt->vsync_offset_lo); mode->vsync_end = mode->vsync_start + ((pt->vsync_pulse_width_hi << 4) | pt->vsync_pulse_width_lo); mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo); timing->pixel_clock = cpu_to_le16(1088); mode->clock = le16_to_cpu(timing->pixel_clock) * 10; mode->hdisplay = hactive; mode->hsync_start = mode->hdisplay + hsync_offset; mode->hsync_end = mode->hsync_start + hsync_pulse_width; mode->htotal = mode->hdisplay + hblank; mode->vdisplay = vactive; mode->vsync_start = mode->vdisplay + vsync_offset; mode->vsync_end = mode->vsync_start + vsync_pulse_width; mode->vtotal = mode->vdisplay + vblank; drm_mode_set_name(mode); if (pt->interlaced) if (pt->misc & DRM_EDID_PT_INTERLACED) mode->flags |= DRM_MODE_FLAG_INTERLACE; if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { pt->hsync_positive = 1; pt->vsync_positive = 1; pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; } mode->flags |= pt->hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; mode->flags |= pt->vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; mode->width_mm = pt->width_mm_lo | (pt->width_mm_hi << 8); mode->height_mm = pt->height_mm_lo | (pt->height_mm_hi << 8); mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; if (quirks & EDID_QUIRK_DETAILED_IN_CM) { mode->width_mm *= 10; Loading Loading @@ -465,7 +469,7 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid struct drm_display_mode *newmode; /* If std timings bytes are 1, 1 it's empty */ if (t->hsize == 1 && (t->aspect_ratio | t->vfreq) == 1) if (t->hsize == 1 && t->vfreq_aspect == 1) continue; newmode = drm_mode_std(dev, &edid->standard_timings[i]); Loading Loading @@ -509,7 +513,7 @@ static int add_detailed_info(struct drm_connector *connector, continue; /* First detailed mode is preferred */ if (i == 0 && edid->preferred_timing) if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) newmode->type |= DRM_MODE_TYPE_PREFERRED; drm_mode_probed_add(connector, newmode); Loading Loading @@ -767,22 +771,22 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) edid_fixup_preferred(connector, quirks); connector->display_info.serration_vsync = edid->serration_vsync; connector->display_info.sync_on_green = edid->sync_on_green; connector->display_info.composite_sync = edid->composite_sync; connector->display_info.separate_syncs = edid->separate_syncs; connector->display_info.blank_to_black = edid->blank_to_black; connector->display_info.video_level = edid->video_level; connector->display_info.digital = edid->digital; connector->display_info.serration_vsync = (edid->input & DRM_EDID_INPUT_SERRATION_VSYNC) ? 1 : 0; connector->display_info.sync_on_green = (edid->input & DRM_EDID_INPUT_SYNC_ON_GREEN) ? 1 : 0; connector->display_info.composite_sync = (edid->input & DRM_EDID_INPUT_COMPOSITE_SYNC) ? 1 : 0; connector->display_info.separate_syncs = (edid->input & DRM_EDID_INPUT_SEPARATE_SYNCS) ? 1 : 0; connector->display_info.blank_to_black = (edid->input & DRM_EDID_INPUT_BLANK_TO_BLACK) ? 1 : 0; connector->display_info.video_level = (edid->input & DRM_EDID_INPUT_VIDEO_LEVEL) >> 5; connector->display_info.digital = (edid->input & DRM_EDID_INPUT_DIGITAL) ? 1 : 0; connector->display_info.width_mm = edid->width_cm * 10; connector->display_info.height_mm = edid->height_cm * 10; connector->display_info.gamma = edid->gamma; connector->display_info.gtf_supported = edid->default_gtf; connector->display_info.standard_color = edid->standard_color; connector->display_info.display_type = edid->display_type; connector->display_info.active_off_supported = edid->pm_active_off; connector->display_info.suspend_supported = edid->pm_suspend; connector->display_info.standby_supported = edid->pm_standby; connector->display_info.gtf_supported = (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) ? 1 : 0; connector->display_info.standard_color = (edid->features & DRM_EDID_FEATURE_STANDARD_COLOR) ? 1 : 0; connector->display_info.display_type = (edid->features & DRM_EDID_FEATURE_DISPLAY_TYPE) >> 3; connector->display_info.active_off_supported = (edid->features & DRM_EDID_FEATURE_PM_ACTIVE_OFF) ? 1 : 0; connector->display_info.suspend_supported = (edid->features & DRM_EDID_FEATURE_PM_SUSPEND) ? 1 : 0; connector->display_info.standby_supported = (edid->features & DRM_EDID_FEATURE_PM_STANDBY) ? 1 : 0; connector->display_info.gamma = edid->gamma; return num_modes; Loading drivers/gpu/drm/radeon/radeon_display.c +1 −1 Original line number Diff line number Diff line Loading @@ -351,7 +351,7 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) radeon_i2c_do_lock(radeon_connector, 0); if (edid) { /* update digital bits here */ if (edid->digital) if (edid->input & DRM_EDID_INPUT_DIGITAL) radeon_connector->use_digital = 1; else radeon_connector->use_digital = 0; Loading include/drm/drm_edid.h +43 −49 Original line number Diff line number Diff line Loading @@ -28,53 +28,49 @@ #define EDID_LENGTH 128 #define DDC_ADDR 0x50 #ifdef BIG_ENDIAN #error "EDID structure is little endian, need big endian versions" #else struct est_timings { u8 t1; u8 t2; u8 mfg_rsvd; } __attribute__((packed)); /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ #define EDID_TIMING_ASPECT_SHIFT 0 #define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT) /* need to add 60 */ #define EDID_TIMING_VFREQ_SHIFT 2 #define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT) struct std_timing { u8 hsize; /* need to multiply by 8 then add 248 */ u8 vfreq:6; /* need to add 60 */ u8 aspect_ratio:2; /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ u8 vfreq_aspect; } __attribute__((packed)); #define DRM_EDID_PT_HSYNC_POSITIVE (1 << 6) #define DRM_EDID_PT_VSYNC_POSITIVE (1 << 5) #define DRM_EDID_PT_SEPARATE_SYNC (3 << 3) #define DRM_EDID_PT_STEREO (1 << 2) #define DRM_EDID_PT_INTERLACED (1 << 1) /* If detailed data is pixel timing */ struct detailed_pixel_timing { u8 hactive_lo; u8 hblank_lo; u8 hblank_hi:4; u8 hactive_hi:4; u8 hactive_hblank_hi; u8 vactive_lo; u8 vblank_lo; u8 vblank_hi:4; u8 vactive_hi:4; u8 vactive_vblank_hi; u8 hsync_offset_lo; u8 hsync_pulse_width_lo; u8 vsync_pulse_width_lo:4; u8 vsync_offset_lo:4; u8 vsync_pulse_width_hi:2; u8 vsync_offset_hi:2; u8 hsync_pulse_width_hi:2; u8 hsync_offset_hi:2; u8 vsync_offset_pulse_width_lo; u8 hsync_vsync_offset_pulse_width_hi; u8 width_mm_lo; u8 height_mm_lo; u8 height_mm_hi:4; u8 width_mm_hi:4; u8 width_height_mm_hi; u8 hborder; u8 vborder; u8 unknown0:1; u8 hsync_positive:1; u8 vsync_positive:1; u8 separate_sync:2; u8 stereo:1; u8 unknown6:1; u8 interlaced:1; u8 misc; } __attribute__((packed)); /* If it's not pixel timing, it'll be one of the below */ Loading @@ -88,18 +84,16 @@ struct detailed_data_monitor_range { u8 min_hfreq_khz; u8 max_hfreq_khz; u8 pixel_clock_mhz; /* need to multiply by 10 */ u16 sec_gtf_toggle; /* A000=use above, 20=use below */ /* FIXME: byte order */ __le16 sec_gtf_toggle; /* A000=use above, 20=use below */ u8 hfreq_start_khz; /* need to multiply by 2 */ u8 c; /* need to divide by 2 */ u16 m; /* FIXME: byte order */ __le16 m; u8 k; u8 j; /* need to divide by 2 */ } __attribute__((packed)); struct detailed_data_wpindex { u8 white_y_lo:2; u8 white_x_lo:2; u8 pad:4; u8 white_xy_lo; /* Upper 2 bits each */ u8 white_x_hi; u8 white_y_hi; u8 gamma; /* need to divide by 100 then add 1 */ Loading Loading @@ -134,13 +128,29 @@ struct detailed_non_pixel { #define EDID_DETAIL_MONITOR_SERIAL 0xff struct detailed_timing { u16 pixel_clock; /* need to multiply by 10 KHz */ /* FIXME: byte order */ __le16 pixel_clock; /* need to multiply by 10 KHz */ union { struct detailed_pixel_timing pixel_data; struct detailed_non_pixel other_data; } data; } __attribute__((packed)); #define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 7) #define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 5) #define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 4) #define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3) #define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 2) #define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 1) #define DRM_EDID_INPUT_DIGITAL (1 << 0) /* bits above must be zero if set */ #define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 7) #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 6) #define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 5) #define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ #define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 2) #define DRM_EDID_FEATURE_PM_SUSPEND (1 << 1) #define DRM_EDID_FEATURE_PM_STANDBY (1 << 0) struct edid { u8 header[8]; /* Vendor & product info */ Loading @@ -153,25 +163,11 @@ struct edid { u8 version; u8 revision; /* Display info: */ /* input definition */ u8 serration_vsync:1; u8 sync_on_green:1; u8 composite_sync:1; u8 separate_syncs:1; u8 blank_to_black:1; u8 video_level:2; u8 digital:1; /* bits below must be zero if set */ u8 input; u8 width_cm; u8 height_cm; u8 gamma; /* feature support */ u8 default_gtf:1; u8 preferred_timing:1; u8 standard_color:1; u8 display_type:2; /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ u8 pm_active_off:1; u8 pm_suspend:1; u8 pm_standby:1; u8 features; /* Color characteristics */ u8 red_green_lo; u8 black_white_lo; Loading @@ -195,8 +191,6 @@ struct edid { u8 checksum; } __attribute__((packed)); #endif /* little endian structs */ #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) #endif /* __DRM_EDID_H__ */ Loading
drivers/gpu/drm/drm_edid.c +52 −48 Original line number Diff line number Diff line Loading @@ -252,16 +252,18 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, { struct drm_display_mode *mode; int hsize = t->hsize * 8 + 248, vsize; unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) >> EDID_TIMING_ASPECT_SHIFT; mode = drm_mode_create(dev); if (!mode) return NULL; if (t->aspect_ratio == 0) if (aspect_ratio == 0) vsize = (hsize * 10) / 16; else if (t->aspect_ratio == 1) else if (aspect_ratio == 1) vsize = (hsize * 3) / 4; else if (t->aspect_ratio == 2) else if (aspect_ratio == 2) vsize = (hsize * 4) / 5; else vsize = (hsize * 9) / 16; Loading @@ -288,17 +290,24 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, { struct drm_display_mode *mode; struct detailed_pixel_timing *pt = &timing->data.pixel_data; unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo; unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 8 | pt->hsync_offset_lo; unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 6 | pt->hsync_pulse_width_lo; unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) | (pt->vsync_offset_pulse_width_lo & 0xf); unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; /* ignore tiny modes */ if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 || ((pt->vactive_hi << 8) | pt->hactive_lo) < 64) if (hactive < 64 || vactive < 64) return NULL; if (pt->stereo) { if (pt->misc & DRM_EDID_PT_STEREO) { printk(KERN_WARNING "stereo mode not supported\n"); return NULL; } if (!pt->separate_sync) { if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) { printk(KERN_WARNING "integrated sync not supported\n"); return NULL; } Loading @@ -310,41 +319,36 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->type = DRM_MODE_TYPE_DRIVER; if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) timing->pixel_clock = 1088; mode->clock = timing->pixel_clock * 10; mode->hdisplay = (pt->hactive_hi << 8) | pt->hactive_lo; mode->hsync_start = mode->hdisplay + ((pt->hsync_offset_hi << 8) | pt->hsync_offset_lo); mode->hsync_end = mode->hsync_start + ((pt->hsync_pulse_width_hi << 8) | pt->hsync_pulse_width_lo); mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo); mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo; mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) | pt->vsync_offset_lo); mode->vsync_end = mode->vsync_start + ((pt->vsync_pulse_width_hi << 4) | pt->vsync_pulse_width_lo); mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo); timing->pixel_clock = cpu_to_le16(1088); mode->clock = le16_to_cpu(timing->pixel_clock) * 10; mode->hdisplay = hactive; mode->hsync_start = mode->hdisplay + hsync_offset; mode->hsync_end = mode->hsync_start + hsync_pulse_width; mode->htotal = mode->hdisplay + hblank; mode->vdisplay = vactive; mode->vsync_start = mode->vdisplay + vsync_offset; mode->vsync_end = mode->vsync_start + vsync_pulse_width; mode->vtotal = mode->vdisplay + vblank; drm_mode_set_name(mode); if (pt->interlaced) if (pt->misc & DRM_EDID_PT_INTERLACED) mode->flags |= DRM_MODE_FLAG_INTERLACE; if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { pt->hsync_positive = 1; pt->vsync_positive = 1; pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; } mode->flags |= pt->hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; mode->flags |= pt->vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; mode->width_mm = pt->width_mm_lo | (pt->width_mm_hi << 8); mode->height_mm = pt->height_mm_lo | (pt->height_mm_hi << 8); mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; if (quirks & EDID_QUIRK_DETAILED_IN_CM) { mode->width_mm *= 10; Loading Loading @@ -465,7 +469,7 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid struct drm_display_mode *newmode; /* If std timings bytes are 1, 1 it's empty */ if (t->hsize == 1 && (t->aspect_ratio | t->vfreq) == 1) if (t->hsize == 1 && t->vfreq_aspect == 1) continue; newmode = drm_mode_std(dev, &edid->standard_timings[i]); Loading Loading @@ -509,7 +513,7 @@ static int add_detailed_info(struct drm_connector *connector, continue; /* First detailed mode is preferred */ if (i == 0 && edid->preferred_timing) if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) newmode->type |= DRM_MODE_TYPE_PREFERRED; drm_mode_probed_add(connector, newmode); Loading Loading @@ -767,22 +771,22 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) edid_fixup_preferred(connector, quirks); connector->display_info.serration_vsync = edid->serration_vsync; connector->display_info.sync_on_green = edid->sync_on_green; connector->display_info.composite_sync = edid->composite_sync; connector->display_info.separate_syncs = edid->separate_syncs; connector->display_info.blank_to_black = edid->blank_to_black; connector->display_info.video_level = edid->video_level; connector->display_info.digital = edid->digital; connector->display_info.serration_vsync = (edid->input & DRM_EDID_INPUT_SERRATION_VSYNC) ? 1 : 0; connector->display_info.sync_on_green = (edid->input & DRM_EDID_INPUT_SYNC_ON_GREEN) ? 1 : 0; connector->display_info.composite_sync = (edid->input & DRM_EDID_INPUT_COMPOSITE_SYNC) ? 1 : 0; connector->display_info.separate_syncs = (edid->input & DRM_EDID_INPUT_SEPARATE_SYNCS) ? 1 : 0; connector->display_info.blank_to_black = (edid->input & DRM_EDID_INPUT_BLANK_TO_BLACK) ? 1 : 0; connector->display_info.video_level = (edid->input & DRM_EDID_INPUT_VIDEO_LEVEL) >> 5; connector->display_info.digital = (edid->input & DRM_EDID_INPUT_DIGITAL) ? 1 : 0; connector->display_info.width_mm = edid->width_cm * 10; connector->display_info.height_mm = edid->height_cm * 10; connector->display_info.gamma = edid->gamma; connector->display_info.gtf_supported = edid->default_gtf; connector->display_info.standard_color = edid->standard_color; connector->display_info.display_type = edid->display_type; connector->display_info.active_off_supported = edid->pm_active_off; connector->display_info.suspend_supported = edid->pm_suspend; connector->display_info.standby_supported = edid->pm_standby; connector->display_info.gtf_supported = (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) ? 1 : 0; connector->display_info.standard_color = (edid->features & DRM_EDID_FEATURE_STANDARD_COLOR) ? 1 : 0; connector->display_info.display_type = (edid->features & DRM_EDID_FEATURE_DISPLAY_TYPE) >> 3; connector->display_info.active_off_supported = (edid->features & DRM_EDID_FEATURE_PM_ACTIVE_OFF) ? 1 : 0; connector->display_info.suspend_supported = (edid->features & DRM_EDID_FEATURE_PM_SUSPEND) ? 1 : 0; connector->display_info.standby_supported = (edid->features & DRM_EDID_FEATURE_PM_STANDBY) ? 1 : 0; connector->display_info.gamma = edid->gamma; return num_modes; Loading
drivers/gpu/drm/radeon/radeon_display.c +1 −1 Original line number Diff line number Diff line Loading @@ -351,7 +351,7 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) radeon_i2c_do_lock(radeon_connector, 0); if (edid) { /* update digital bits here */ if (edid->digital) if (edid->input & DRM_EDID_INPUT_DIGITAL) radeon_connector->use_digital = 1; else radeon_connector->use_digital = 0; Loading
include/drm/drm_edid.h +43 −49 Original line number Diff line number Diff line Loading @@ -28,53 +28,49 @@ #define EDID_LENGTH 128 #define DDC_ADDR 0x50 #ifdef BIG_ENDIAN #error "EDID structure is little endian, need big endian versions" #else struct est_timings { u8 t1; u8 t2; u8 mfg_rsvd; } __attribute__((packed)); /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ #define EDID_TIMING_ASPECT_SHIFT 0 #define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT) /* need to add 60 */ #define EDID_TIMING_VFREQ_SHIFT 2 #define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT) struct std_timing { u8 hsize; /* need to multiply by 8 then add 248 */ u8 vfreq:6; /* need to add 60 */ u8 aspect_ratio:2; /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ u8 vfreq_aspect; } __attribute__((packed)); #define DRM_EDID_PT_HSYNC_POSITIVE (1 << 6) #define DRM_EDID_PT_VSYNC_POSITIVE (1 << 5) #define DRM_EDID_PT_SEPARATE_SYNC (3 << 3) #define DRM_EDID_PT_STEREO (1 << 2) #define DRM_EDID_PT_INTERLACED (1 << 1) /* If detailed data is pixel timing */ struct detailed_pixel_timing { u8 hactive_lo; u8 hblank_lo; u8 hblank_hi:4; u8 hactive_hi:4; u8 hactive_hblank_hi; u8 vactive_lo; u8 vblank_lo; u8 vblank_hi:4; u8 vactive_hi:4; u8 vactive_vblank_hi; u8 hsync_offset_lo; u8 hsync_pulse_width_lo; u8 vsync_pulse_width_lo:4; u8 vsync_offset_lo:4; u8 vsync_pulse_width_hi:2; u8 vsync_offset_hi:2; u8 hsync_pulse_width_hi:2; u8 hsync_offset_hi:2; u8 vsync_offset_pulse_width_lo; u8 hsync_vsync_offset_pulse_width_hi; u8 width_mm_lo; u8 height_mm_lo; u8 height_mm_hi:4; u8 width_mm_hi:4; u8 width_height_mm_hi; u8 hborder; u8 vborder; u8 unknown0:1; u8 hsync_positive:1; u8 vsync_positive:1; u8 separate_sync:2; u8 stereo:1; u8 unknown6:1; u8 interlaced:1; u8 misc; } __attribute__((packed)); /* If it's not pixel timing, it'll be one of the below */ Loading @@ -88,18 +84,16 @@ struct detailed_data_monitor_range { u8 min_hfreq_khz; u8 max_hfreq_khz; u8 pixel_clock_mhz; /* need to multiply by 10 */ u16 sec_gtf_toggle; /* A000=use above, 20=use below */ /* FIXME: byte order */ __le16 sec_gtf_toggle; /* A000=use above, 20=use below */ u8 hfreq_start_khz; /* need to multiply by 2 */ u8 c; /* need to divide by 2 */ u16 m; /* FIXME: byte order */ __le16 m; u8 k; u8 j; /* need to divide by 2 */ } __attribute__((packed)); struct detailed_data_wpindex { u8 white_y_lo:2; u8 white_x_lo:2; u8 pad:4; u8 white_xy_lo; /* Upper 2 bits each */ u8 white_x_hi; u8 white_y_hi; u8 gamma; /* need to divide by 100 then add 1 */ Loading Loading @@ -134,13 +128,29 @@ struct detailed_non_pixel { #define EDID_DETAIL_MONITOR_SERIAL 0xff struct detailed_timing { u16 pixel_clock; /* need to multiply by 10 KHz */ /* FIXME: byte order */ __le16 pixel_clock; /* need to multiply by 10 KHz */ union { struct detailed_pixel_timing pixel_data; struct detailed_non_pixel other_data; } data; } __attribute__((packed)); #define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 7) #define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 5) #define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 4) #define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3) #define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 2) #define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 1) #define DRM_EDID_INPUT_DIGITAL (1 << 0) /* bits above must be zero if set */ #define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 7) #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 6) #define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 5) #define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ #define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 2) #define DRM_EDID_FEATURE_PM_SUSPEND (1 << 1) #define DRM_EDID_FEATURE_PM_STANDBY (1 << 0) struct edid { u8 header[8]; /* Vendor & product info */ Loading @@ -153,25 +163,11 @@ struct edid { u8 version; u8 revision; /* Display info: */ /* input definition */ u8 serration_vsync:1; u8 sync_on_green:1; u8 composite_sync:1; u8 separate_syncs:1; u8 blank_to_black:1; u8 video_level:2; u8 digital:1; /* bits below must be zero if set */ u8 input; u8 width_cm; u8 height_cm; u8 gamma; /* feature support */ u8 default_gtf:1; u8 preferred_timing:1; u8 standard_color:1; u8 display_type:2; /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ u8 pm_active_off:1; u8 pm_suspend:1; u8 pm_standby:1; u8 features; /* Color characteristics */ u8 red_green_lo; u8 black_white_lo; Loading @@ -195,8 +191,6 @@ struct edid { u8 checksum; } __attribute__((packed)); #endif /* little endian structs */ #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) #endif /* __DRM_EDID_H__ */