提交 1c4a814e 编写于 作者: D Daniel Vetter

drm/i915/sdvo: Robustify the dtd<->drm_mode conversions

We've failed to properly clear out the flags when converting a dtd to
a drm mode. For more paranoia just memset the entire structure (and
drop the now redundant clears).

Also since

commit 135c81b8
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Sun Jul 21 21:37:09 2013 +0200

    drm/i915: clean up crtc timings computation

we don't update the crtc timings any more properly, so do that again.

v2: Remove more redundant clearing, spotted by Ville.

v3: Actually make it compile. Oops.

v4: Use a temporary structure to fill in the mode and copy it over
with drm_mode_copy. This will ensure we don't clobber the mode list or
id. Suggested by Ville.

Cc: Rodrigo Vivi <rodrigo.vivi@gmail.com>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reported-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
[danvet: Use the = {}; structure clearing instead of memset as
suggested by Ville.]
Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
上级 3cea210f
...@@ -788,6 +788,8 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, ...@@ -788,6 +788,8 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
uint16_t h_sync_offset, v_sync_offset; uint16_t h_sync_offset, v_sync_offset;
int mode_clock; int mode_clock;
memset(dtd, 0, sizeof(*dtd));
width = mode->hdisplay; width = mode->hdisplay;
height = mode->vdisplay; height = mode->vdisplay;
...@@ -830,48 +832,51 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, ...@@ -830,48 +832,51 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
if (mode->flags & DRM_MODE_FLAG_PVSYNC) if (mode->flags & DRM_MODE_FLAG_PVSYNC)
dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE;
dtd->part2.sdvo_flags = 0;
dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
dtd->part2.reserved = 0;
} }
static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode,
const struct intel_sdvo_dtd *dtd) const struct intel_sdvo_dtd *dtd)
{ {
mode->hdisplay = dtd->part1.h_active; struct drm_display_mode mode = {};
mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; mode.hdisplay = dtd->part1.h_active;
mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off;
mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
mode->htotal = mode->hdisplay + dtd->part1.h_blank; mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width;
mode->htotal += (dtd->part1.h_high & 0xf) << 8; mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
mode.htotal = mode.hdisplay + dtd->part1.h_blank;
mode->vdisplay = dtd->part1.v_active; mode.htotal += (dtd->part1.h_high & 0xf) << 8;
mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
mode->vsync_start = mode->vdisplay; mode.vdisplay = dtd->part1.v_active;
mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; mode.vsync_start = mode.vdisplay;
mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
mode->vsync_end = mode->vsync_start + mode.vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
mode.vsync_start += dtd->part2.v_sync_off_high & 0xc0;
mode.vsync_end = mode.vsync_start +
(dtd->part2.v_sync_off_width & 0xf); (dtd->part2.v_sync_off_width & 0xf);
mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
mode->vtotal = mode->vdisplay + dtd->part1.v_blank; mode.vtotal = mode.vdisplay + dtd->part1.v_blank;
mode->vtotal += (dtd->part1.v_high & 0xf) << 8; mode.vtotal += (dtd->part1.v_high & 0xf) << 8;
mode->clock = dtd->part1.clock * 10; mode.clock = dtd->part1.clock * 10;
mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE)
mode->flags |= DRM_MODE_FLAG_INTERLACE; mode.flags |= DRM_MODE_FLAG_INTERLACE;
if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
mode->flags |= DRM_MODE_FLAG_PHSYNC; mode.flags |= DRM_MODE_FLAG_PHSYNC;
else else
mode->flags |= DRM_MODE_FLAG_NHSYNC; mode.flags |= DRM_MODE_FLAG_NHSYNC;
if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
mode->flags |= DRM_MODE_FLAG_PVSYNC; mode.flags |= DRM_MODE_FLAG_PVSYNC;
else else
mode->flags |= DRM_MODE_FLAG_NVSYNC; mode.flags |= DRM_MODE_FLAG_NVSYNC;
drm_mode_set_crtcinfo(&mode, 0);
drm_mode_copy(pmode, &mode);
} }
static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo) static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册