drm/i915: Add distrust_bios_wm flag to dev_priv (v2)
authorMatt Roper <matthew.d.roper@intel.com>
Thu, 12 May 2016 14:06:02 +0000 (07:06 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Fri, 13 May 2016 14:33:54 +0000 (07:33 -0700)
SKL-style platforms can't fully trust the watermark/DDB settings
programmed by the BIOS and need to do extra sanitization on their first
atomic update.  Add a flag to dev_priv that is set during hardware
readout and cleared at the end of the first commit.

Note that for the somewhat common case where everything is turned off
when the driver starts up, we don't need to bother with a recompute...we
know exactly what the DDB should be (all zero's) so just setup the DDB
directly in that case.

v2:
 - Move clearing of distrust_bios_wm up below the swap_state call since
   it's a more natural / self-explanatory location.  (Maarten)
 - Use dev_priv->active_crtcs to test whether any CRTC's are turned on
   during HW WM readout rather than trying to count the active CRTC's
   again ourselves.  (Maarten)

Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-9-git-send-email-matthew.d.roper@intel.com
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_pm.c

index fb7fd7de2b7640347df4041dda6fdd41efe83ee7..985defce9908a527649e7815569689c92499a6c0 100644 (file)
@@ -1995,6 +1995,13 @@ struct drm_i915_private {
                 * cstate->wm.need_postvbl_update.
                 */
                struct mutex wm_mutex;
+
+               /*
+                * Set during HW readout of watermarks/DDB.  Some platforms
+                * need to know when we're still using BIOS-provided values
+                * (which we don't fully trust).
+                */
+               bool distrust_bios_wm;
        } wm;
 
        struct i915_runtime_pm pm;
index 5d9909049180fcf2c73369ee092e41d6fc55c6f0..102320c7f3b7a8d02d6ea519a38d52cdef9bd26c 100644 (file)
@@ -13594,6 +13594,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 
        drm_atomic_helper_swap_state(dev, state);
        dev_priv->wm.config = intel_state->wm_config;
+       dev_priv->wm.distrust_bios_wm = false;
        intel_shared_dpll_commit(state);
 
        if (intel_state->modeset) {
index ca38f6c0e3c87a99eae11d67618e23bac5b7ce47..87fae2e93c40f8706e6c6219f91b54f078ecf05a 100644 (file)
@@ -4026,6 +4026,14 @@ void skl_wm_get_hw_state(struct drm_device *dev)
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
                skl_pipe_wm_get_hw_state(crtc);
 
+       if (dev_priv->active_crtcs) {
+               /* Fully recompute DDB on first atomic commit */
+               dev_priv->wm.distrust_bios_wm = true;
+       } else {
+               /* Easy/common case; just sanitize DDB now if everything off */
+               memset(ddb, 0, sizeof(*ddb));
+       }
+
        /* Calculate plane data rates */
        for_each_intel_crtc(dev, intel_crtc) {
                struct intel_crtc_state *cstate = intel_crtc->config;