Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 135c81b8c3c9a70d7b55758c9c2a247a4abb7b64
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: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
[danvet: Use the = {}; structure clearing instead of memset as
suggested by Ville.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

+33 -28
+33 -28
drivers/gpu/drm/i915/intel_sdvo.c
··· 788 788 uint16_t h_sync_offset, v_sync_offset; 789 789 int mode_clock; 790 790 791 + memset(dtd, 0, sizeof(*dtd)); 792 + 791 793 width = mode->hdisplay; 792 794 height = mode->vdisplay; 793 795 ··· 832 830 if (mode->flags & DRM_MODE_FLAG_PVSYNC) 833 831 dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; 834 832 835 - dtd->part2.sdvo_flags = 0; 836 833 dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; 837 - dtd->part2.reserved = 0; 838 834 } 839 835 840 - static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, 836 + static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode, 841 837 const struct intel_sdvo_dtd *dtd) 842 838 { 843 - mode->hdisplay = dtd->part1.h_active; 844 - mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; 845 - mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; 846 - mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; 847 - mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; 848 - mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; 849 - mode->htotal = mode->hdisplay + dtd->part1.h_blank; 850 - mode->htotal += (dtd->part1.h_high & 0xf) << 8; 839 + struct drm_display_mode mode = {}; 851 840 852 - mode->vdisplay = dtd->part1.v_active; 853 - mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; 854 - mode->vsync_start = mode->vdisplay; 855 - mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; 856 - mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; 857 - mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; 858 - mode->vsync_end = mode->vsync_start + 841 + mode.hdisplay = dtd->part1.h_active; 842 + mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; 843 + mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off; 844 + mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; 845 + mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width; 846 + mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; 847 + mode.htotal = mode.hdisplay + dtd->part1.h_blank; 848 + mode.htotal += (dtd->part1.h_high & 0xf) << 8; 849 + 850 + mode.vdisplay = dtd->part1.v_active; 851 + mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; 852 + mode.vsync_start = mode.vdisplay; 853 + mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; 854 + mode.vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; 855 + mode.vsync_start += dtd->part2.v_sync_off_high & 0xc0; 856 + mode.vsync_end = mode.vsync_start + 859 857 (dtd->part2.v_sync_off_width & 0xf); 860 - mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; 861 - mode->vtotal = mode->vdisplay + dtd->part1.v_blank; 862 - mode->vtotal += (dtd->part1.v_high & 0xf) << 8; 858 + mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; 859 + mode.vtotal = mode.vdisplay + dtd->part1.v_blank; 860 + mode.vtotal += (dtd->part1.v_high & 0xf) << 8; 863 861 864 - mode->clock = dtd->part1.clock * 10; 862 + mode.clock = dtd->part1.clock * 10; 865 863 866 - mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); 867 864 if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) 868 - mode->flags |= DRM_MODE_FLAG_INTERLACE; 865 + mode.flags |= DRM_MODE_FLAG_INTERLACE; 869 866 if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) 870 - mode->flags |= DRM_MODE_FLAG_PHSYNC; 867 + mode.flags |= DRM_MODE_FLAG_PHSYNC; 871 868 else 872 - mode->flags |= DRM_MODE_FLAG_NHSYNC; 869 + mode.flags |= DRM_MODE_FLAG_NHSYNC; 873 870 if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) 874 - mode->flags |= DRM_MODE_FLAG_PVSYNC; 871 + mode.flags |= DRM_MODE_FLAG_PVSYNC; 875 872 else 876 - mode->flags |= DRM_MODE_FLAG_NVSYNC; 873 + mode.flags |= DRM_MODE_FLAG_NVSYNC; 874 + 875 + drm_mode_set_crtcinfo(&mode, 0); 876 + 877 + drm_mode_copy(pmode, &mode); 877 878 } 878 879 879 880 static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo)