]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/i915: fixup interlaced vertical timings confusion, part 1
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Sat, 28 Jan 2012 13:49:20 +0000 (14:49 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 10 Feb 2012 16:24:06 +0000 (17:24 +0100)
We have a pretty decent confusion about vertical timings of interlaced
modes. Peter Ross has written a patch that makes interlace modes work
on a lot more platforms/output combinations by doubling the vertical
timings.

The issue with that patch is that core drm _does_ support specifying
whether we want these vertical timings in fields or frames, we just
haven't managed to consistently use this facility. The relavant
function is drm_mode_set_crtcinfo, which fills in the crtc timing
information.

The first thing to note is that the drm core keeps interlaced modes in
frames, but displays modelines in fields. So when the crtc modeset
helper copies over the mode into adjusted_mode it will already contain
vertical timings in half-frames. The result is that the fixup code in
intel_crtc_mode_fixup doesn't actually do anything (in most cases at
least).

Now gen3+ natively supports interlaced modes and wants the vertical
timings in frames. Which is what sdvo already fixes up, at least under
some conditions.

There are a few other place that demand vertical timings in fields
but never actually deal with interlaced modes, so use frame timings
for consistency, too. These are:
- lvds panel,
- dvo encoders - dvo is the only way gen2 could support interlaced
  mode, but currently we don't support any encoders that do.
- tv out - despite that the tv dac sends out an interlaced signal it
  expects a progressive mode pipe configuration.
All these encoders enforce progressive modes by resetting
interlace_allowed.

Hence we always want crtc vertical timings in frames. Enforce this in
our crtc mode_fixup function and rip out any redudant timing
computations from the encoders' mode_fixup function.

v2-4: Adjust the vertical timings a bit.

v5: Split out the 'subtract-one for interlaced' fixes.

v6: Clarify issues around tv-out and gen2.

Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Tested-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Tested-by: Christopher Egert <cme3000@gmail.com>
Tested-by: Alfonso Fiore <alfonso.fiore@gmail.com>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c

index efe56a2c4f4b88be123078a3be8501e1e1e74d85..41d4e82f412a48ca7afb8abe7f2020d4ed60b443 100644 (file)
@@ -3437,11 +3437,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
                        return false;
        }
 
-       /* XXX some encoders set the crtcinfo, others don't.
-        * Obviously we need some form of conflict resolution here...
-        */
-       if (adjusted_mode->crtc_htotal == 0)
-               drm_mode_set_crtcinfo(adjusted_mode, 0);
+       /* All interlaced capable intel hw wants timings in frames. */
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        return true;
 }
index 6eda1b51c63633ec0e3f175aae41e673427da877..020a7d7f744dcc9608d9a652d2b0d0d4b1035ea7 100644 (file)
@@ -157,7 +157,6 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
                C(vsync_end);
                C(vtotal);
                C(clock);
-               drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
 #undef C
        }
 
index 23a543cdfa99286cf62348ed7d3df0f7ed95bdb6..5542e9006f966e32fba157cfe3858fae4f74d061 100644 (file)
@@ -264,7 +264,7 @@ i830_activate_pipe_a(struct drm_device *dev)
        DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n");
 
        mode = drm_mode_duplicate(dev, &vesa_640x480);
-       drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+       drm_mode_set_crtcinfo(mode, 0);
        if (!drm_crtc_helper_set_mode(&crtc->base, mode,
                                       crtc->base.x, crtc->base.y,
                                       crtc->base.fb))
index c935cdaa2154facc89b69c35cc49032192702a5f..230a141dbea34da3feff3e4fc043d780a6975fdd 100644 (file)
@@ -48,7 +48,7 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
 
        adjusted_mode->clock = fixed_mode->clock;
 
-       drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
 }
 
 /* adjusted_mode has been preset to be the panel's fixed mode */
index e334ec33a47d4eb0cbd731c0c834de6c2102c458..5b480bbad68cf6028e41a25ee6e70ecfb7f2f483 100644 (file)
@@ -944,7 +944,6 @@ intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo,
 
        intel_sdvo_get_mode_from_dtd(adjusted_mode, &intel_sdvo->input_dtd);
 
-       drm_mode_set_crtcinfo(adjusted_mode, 0);
        return true;
 }
 
index 1571be37ce3e36b1089994a3454c4a23f8a733e6..05f765ef546450efcc56844ff29e589c4c23d028 100644 (file)
@@ -1240,7 +1240,7 @@ intel_tv_detect(struct drm_connector *connector, bool force)
        int type;
 
        mode = reported_modes[0];
-       drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
+       drm_mode_set_crtcinfo(&mode, 0);
 
        if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) {
                type = intel_tv_detect_type(intel_tv, connector);