drm/i915: use i915 and Ironlake CRTC enable/disable functions in prepare/commit
authorJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 10 Sep 2010 17:47:20 +0000 (10:47 -0700)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 10 Sep 2010 22:12:55 +0000 (23:12 +0100)
This will allow us to optimize our prepare/commit paths a bit better.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
[ickle: minor tweak to handle the cursor across pipe resizing]
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/intel_display.c

index fecb98c2d8ad5df3b7407e675fa9c164ffa33771..98276b8454fc710ec9a9a1132121b91c7a13490f 100644 (file)
@@ -2478,16 +2478,60 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
        }
 }
 
-static void intel_crtc_prepare (struct drm_crtc *crtc)
+/* Prepare for a mode set.
+ *
+ * Note we could be a lot smarter here.  We need to figure out which outputs
+ * will be enabled, which disabled (in short, how the config will changes)
+ * and perform the minimum necessary steps to accomplish that, e.g. updating
+ * watermarks, FBC configuration, making sure PLLs are programmed correctly,
+ * panel fitting is in the proper state, etc.
+ */
+static void i9xx_crtc_prepare(struct drm_crtc *crtc)
 {
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+       struct drm_device *dev = crtc->dev;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+       intel_crtc->cursor_on = false;
+       intel_crtc_update_cursor(crtc);
+
+       i9xx_crtc_disable(crtc);
+       intel_clear_scanline_wait(dev);
 }
 
-static void intel_crtc_commit (struct drm_crtc *crtc)
+static void i9xx_crtc_commit(struct drm_crtc *crtc)
 {
-       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+       struct drm_device *dev = crtc->dev;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+       intel_update_watermarks(dev);
+       i9xx_crtc_enable(crtc);
+
+       intel_crtc->cursor_on = true;
+       intel_crtc_update_cursor(crtc);
+}
+
+static void ironlake_crtc_prepare(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+       intel_crtc->cursor_on = false;
+       intel_crtc_update_cursor(crtc);
+
+       ironlake_crtc_disable(crtc);
+       intel_clear_scanline_wait(dev);
+}
+
+static void ironlake_crtc_commit(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+       intel_update_watermarks(dev);
+       ironlake_crtc_enable(crtc);
+
+       intel_crtc->cursor_on = true;
+       intel_crtc_update_cursor(crtc);
 }
 
 void intel_encoder_prepare (struct drm_encoder *encoder)
@@ -5184,14 +5228,12 @@ cleanup_work:
        return ret;
 }
 
-static const struct drm_crtc_helper_funcs intel_helper_funcs = {
+static struct drm_crtc_helper_funcs intel_helper_funcs = {
        .dpms = intel_crtc_dpms,
        .mode_fixup = intel_crtc_mode_fixup,
        .mode_set = intel_crtc_mode_set,
        .mode_set_base = intel_pipe_set_base,
        .mode_set_base_atomic = intel_pipe_set_base_atomic,
-       .prepare = intel_crtc_prepare,
-       .commit = intel_crtc_commit,
        .load_lut = intel_crtc_load_lut,
 };
 
@@ -5241,6 +5283,15 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 
        intel_crtc->cursor_addr = 0;
        intel_crtc->dpms_mode = -1;
+
+       if (HAS_PCH_SPLIT(dev)) {
+               intel_helper_funcs.prepare = ironlake_crtc_prepare;
+               intel_helper_funcs.commit = ironlake_crtc_commit;
+       } else {
+               intel_helper_funcs.prepare = i9xx_crtc_prepare;
+               intel_helper_funcs.commit = i9xx_crtc_commit;
+       }
+
        drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
 
        intel_crtc->busy = false;