drm/i915/skl: Check the DDB state at modeset
authorDamien Lespiau <damien.lespiau@intel.com>
Tue, 4 Nov 2014 17:06:52 +0000 (17:06 +0000)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 7 Nov 2014 17:42:09 +0000 (18:42 +0100)
v2: Don't check DDB on pre-SKL platforms
    Don't check DDB state on disabled pipes

v3: Squash "Expose skl_ddb_get_hw_state()"

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_pm.c

index fbe18ae..ee744a2 100644 (file)
@@ -1400,6 +1400,15 @@ static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
        return entry->end - entry->start + 1;
 }
 
+static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
+                                      const struct skl_ddb_entry *e2)
+{
+       if (e1->start == e2->start && e1->end == e2->end)
+               return true;
+
+       return false;
+}
+
 struct skl_ddb_allocation {
        struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
        struct skl_ddb_entry cursor[I915_MAX_PIPES];
index 01bc558..07fb0ff 100644 (file)
@@ -10511,6 +10511,56 @@ intel_pipe_config_compare(struct drm_device *dev,
        return true;
 }
 
+static void check_wm_state(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct skl_ddb_allocation hw_ddb, *sw_ddb;
+       struct intel_crtc *intel_crtc;
+       int plane;
+
+       if (INTEL_INFO(dev)->gen < 9)
+               return;
+
+       skl_ddb_get_hw_state(dev_priv, &hw_ddb);
+       sw_ddb = &dev_priv->wm.skl_hw.ddb;
+
+       for_each_intel_crtc(dev, intel_crtc) {
+               struct skl_ddb_entry *hw_entry, *sw_entry;
+               const enum pipe pipe = intel_crtc->pipe;
+
+               if (!intel_crtc->active)
+                       continue;
+
+               /* planes */
+               for_each_plane(pipe, plane) {
+                       hw_entry = &hw_ddb.plane[pipe][plane];
+                       sw_entry = &sw_ddb->plane[pipe][plane];
+
+                       if (skl_ddb_entry_equal(hw_entry, sw_entry))
+                               continue;
+
+                       DRM_ERROR("mismatch in DDB state pipe %c plane %d "
+                                 "(expected (%u,%u), found (%u,%u))\n",
+                                 pipe_name(pipe), plane + 1,
+                                 sw_entry->start, sw_entry->end,
+                                 hw_entry->start, hw_entry->end);
+               }
+
+               /* cursor */
+               hw_entry = &hw_ddb.cursor[pipe];
+               sw_entry = &sw_ddb->cursor[pipe];
+
+               if (skl_ddb_entry_equal(hw_entry, sw_entry))
+                       continue;
+
+               DRM_ERROR("mismatch in DDB state pipe %c cursor "
+                         "(expected (%u,%u), found (%u,%u))\n",
+                         pipe_name(pipe),
+                         sw_entry->start, sw_entry->end,
+                         hw_entry->start, hw_entry->end);
+       }
+}
+
 static void
 check_connector_state(struct drm_device *dev)
 {
@@ -10710,6 +10760,7 @@ check_shared_dpll_state(struct drm_device *dev)
 void
 intel_modeset_check_state(struct drm_device *dev)
 {
+       check_wm_state(dev);
        check_connector_state(dev);
        check_encoder_state(dev);
        check_crtc_state(dev);
index 1cdd6f9..cb0e9db 100644 (file)
@@ -1165,6 +1165,8 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv);
 void gen6_rps_boost(struct drm_i915_private *dev_priv);
 void ilk_wm_get_hw_state(struct drm_device *dev);
 void skl_wm_get_hw_state(struct drm_device *dev);
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+                         struct skl_ddb_allocation *ddb /* out */);
 
 
 /* intel_sdvo.c */
index 8b7abc7..159c2e0 100644 (file)
@@ -3057,8 +3057,8 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
        entry->end = (reg >> 16) & 0x3ff;
 }
 
-static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
-                                struct skl_ddb_allocation *ddb /* out */)
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+                         struct skl_ddb_allocation *ddb /* out */)
 {
        struct drm_device *dev = dev_priv->dev;
        enum pipe pipe;