drm/edid: Fix interlaced detailed timings to be frame size, not field.
cf. https://bugzilla.redhat.com/show_bug.cgi?id=533561 Signed-off-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
f2d12b8e2c
commit
b58db2c6dd
|
@ -598,6 +598,50 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EDID is delightfully ambiguous about how interlaced modes are to be
|
||||||
|
* encoded. Our internal representation is of frame height, but some
|
||||||
|
* HDTV detailed timings are encoded as field height.
|
||||||
|
*
|
||||||
|
* The format list here is from CEA, in frame size. Technically we
|
||||||
|
* should be checking refresh rate too. Whatever.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
|
||||||
|
struct detailed_pixel_timing *pt)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static const struct {
|
||||||
|
int w, h;
|
||||||
|
} cea_interlaced[] = {
|
||||||
|
{ 1920, 1080 },
|
||||||
|
{ 720, 480 },
|
||||||
|
{ 1440, 480 },
|
||||||
|
{ 2880, 480 },
|
||||||
|
{ 720, 576 },
|
||||||
|
{ 1440, 576 },
|
||||||
|
{ 2880, 576 },
|
||||||
|
};
|
||||||
|
static const int n_sizes =
|
||||||
|
sizeof(cea_interlaced)/sizeof(cea_interlaced[0]);
|
||||||
|
|
||||||
|
if (!(pt->misc & DRM_EDID_PT_INTERLACED))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < n_sizes; i++) {
|
||||||
|
if ((mode->hdisplay == cea_interlaced[i].w) &&
|
||||||
|
(mode->vdisplay == cea_interlaced[i].h / 2)) {
|
||||||
|
mode->vdisplay *= 2;
|
||||||
|
mode->vsync_start *= 2;
|
||||||
|
mode->vsync_end *= 2;
|
||||||
|
mode->vtotal *= 2;
|
||||||
|
mode->vtotal |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mode->flags |= DRM_MODE_FLAG_INTERLACE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_detailed - create a new mode from an EDID detailed timing section
|
* drm_mode_detailed - create a new mode from an EDID detailed timing section
|
||||||
* @dev: DRM device (needed to create new mode)
|
* @dev: DRM device (needed to create new mode)
|
||||||
|
@ -680,8 +724,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
|
||||||
|
|
||||||
drm_mode_set_name(mode);
|
drm_mode_set_name(mode);
|
||||||
|
|
||||||
if (pt->misc & DRM_EDID_PT_INTERLACED)
|
drm_mode_do_interlace_quirk(mode, pt);
|
||||||
mode->flags |= DRM_MODE_FLAG_INTERLACE;
|
|
||||||
|
|
||||||
if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
|
if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
|
||||||
pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
|
pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
|
||||||
|
|
Loading…
Reference in New Issue