aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-09-11 03:58:49 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-09-11 18:36:59 -0400
commit1c4a814e35a2fb5500e94ec60370c53a2fb592ac (patch)
tree9957b231a4f5089e96c2f225c7944497409739a8 /drivers/gpu/drm
parent3cea210f2c7c50e67287207a6548314491f49f31 (diff)
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>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c63
1 files changed, 34 insertions, 29 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 5033c74966aa..49482fd5b76c 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -788,6 +788,8 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
788 uint16_t h_sync_offset, v_sync_offset; 788 uint16_t h_sync_offset, v_sync_offset;
789 int mode_clock; 789 int mode_clock;
790 790
791 memset(dtd, 0, sizeof(*dtd));
792
791 width = mode->hdisplay; 793 width = mode->hdisplay;
792 height = mode->vdisplay; 794 height = mode->vdisplay;
793 795
@@ -830,48 +832,51 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
830 if (mode->flags & DRM_MODE_FLAG_PVSYNC) 832 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
831 dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; 833 dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE;
832 834
833 dtd->part2.sdvo_flags = 0;
834 dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; 835 dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
835 dtd->part2.reserved = 0;
836} 836}
837 837
838static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, 838static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode,
839 const struct intel_sdvo_dtd *dtd) 839 const struct intel_sdvo_dtd *dtd)
840{ 840{
841 mode->hdisplay = dtd->part1.h_active; 841 struct drm_display_mode mode = {};
842 mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; 842
843 mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; 843 mode.hdisplay = dtd->part1.h_active;
844 mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; 844 mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
845 mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; 845 mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off;
846 mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; 846 mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
847 mode->htotal = mode->hdisplay + dtd->part1.h_blank; 847 mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width;
848 mode->htotal += (dtd->part1.h_high & 0xf) << 8; 848 mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
849 849 mode.htotal = mode.hdisplay + dtd->part1.h_blank;
850 mode->vdisplay = dtd->part1.v_active; 850 mode.htotal += (dtd->part1.h_high & 0xf) << 8;
851 mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; 851
852 mode->vsync_start = mode->vdisplay; 852 mode.vdisplay = dtd->part1.v_active;
853 mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; 853 mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
854 mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; 854 mode.vsync_start = mode.vdisplay;
855 mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; 855 mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
856 mode->vsync_end = mode->vsync_start + 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 +
857 (dtd->part2.v_sync_off_width & 0xf); 859 (dtd->part2.v_sync_off_width & 0xf);
858 mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; 860 mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
859 mode->vtotal = mode->vdisplay + dtd->part1.v_blank; 861 mode.vtotal = mode.vdisplay + dtd->part1.v_blank;
860 mode->vtotal += (dtd->part1.v_high & 0xf) << 8; 862 mode.vtotal += (dtd->part1.v_high & 0xf) << 8;
861 863
862 mode->clock = dtd->part1.clock * 10; 864 mode.clock = dtd->part1.clock * 10;
863 865
864 mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
865 if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) 866 if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE)
866 mode->flags |= DRM_MODE_FLAG_INTERLACE; 867 mode.flags |= DRM_MODE_FLAG_INTERLACE;
867 if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) 868 if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
868 mode->flags |= DRM_MODE_FLAG_PHSYNC; 869 mode.flags |= DRM_MODE_FLAG_PHSYNC;
869 else 870 else
870 mode->flags |= DRM_MODE_FLAG_NHSYNC; 871 mode.flags |= DRM_MODE_FLAG_NHSYNC;
871 if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) 872 if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
872 mode->flags |= DRM_MODE_FLAG_PVSYNC; 873 mode.flags |= DRM_MODE_FLAG_PVSYNC;
873 else 874 else
874 mode->flags |= DRM_MODE_FLAG_NVSYNC; 875 mode.flags |= DRM_MODE_FLAG_NVSYNC;
876
877 drm_mode_set_crtcinfo(&mode, 0);
878
879 drm_mode_copy(pmode, &mode);
875} 880}
876 881
877static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo) 882static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo)