]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/drm_crtc_helper.c
Merge branch 'kvm-updates/2.6.38' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[~andy/linux] / drivers / gpu / drm / drm_crtc_helper.c
index 2d4e17a004dbb2f09bae780c56f36138c4b1beca..952b3d4fb2a68fcdbc7e9062a723e9a1c383e3a3 100644 (file)
@@ -336,7 +336,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
                              struct drm_framebuffer *old_fb)
 {
        struct drm_device *dev = crtc->dev;
-       struct drm_display_mode *adjusted_mode, saved_mode;
+       struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
        struct drm_encoder_helper_funcs *encoder_funcs;
        int saved_x, saved_y;
@@ -350,6 +350,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
        if (!crtc->enabled)
                return true;
 
+       saved_hwmode = crtc->hwmode;
        saved_mode = crtc->mode;
        saved_x = crtc->x;
        saved_y = crtc->y;
@@ -427,11 +428,21 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 
        }
 
+       /* Store real post-adjustment hardware mode. */
+       crtc->hwmode = *adjusted_mode;
+
+       /* Calculate and store various constants which
+        * are later needed by vblank and swap-completion
+        * timestamping. They are derived from true hwmode.
+        */
+       drm_calc_timestamping_constants(crtc);
+
        /* XXX free adjustedmode */
        drm_mode_destroy(dev, adjusted_mode);
        /* FIXME: add subpixel order */
 done:
        if (!ret) {
+               crtc->hwmode = saved_hwmode;
                crtc->mode = saved_mode;
                crtc->x = saved_x;
                crtc->y = saved_y;
@@ -650,6 +661,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                                                      old_fb)) {
                                DRM_ERROR("failed to set mode on [CRTC:%d]\n",
                                          set->crtc->base.id);
+                               set->crtc->fb = old_fb;
                                ret = -EINVAL;
                                goto fail;
                        }
@@ -664,8 +676,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                        set->crtc->fb = set->fb;
                ret = crtc_funcs->mode_set_base(set->crtc,
                                                set->x, set->y, old_fb);
-               if (ret != 0)
+               if (ret != 0) {
+                       set->crtc->fb = old_fb;
                        goto fail;
+               }
        }
        DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
        for (i = 0; i < set->num_connectors; i++) {