drm/i915: Optimize VLV/CHV display FIFO updates
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 9 Mar 2017 15:44:34 +0000 (17:44 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 13 Mar 2017 19:15:10 +0000 (21:15 +0200)
Use I915_{READ,WRITE}_FW() for updating the DSPARB registers on
VLV/CHV. This is less expesive as we can grab the uncore.lock across
the entire sequence of reads and writes instead of each register
access grabbing it.

This also allows us to eliminate the dsparb lock entirely as the
uncore.lock now effectively protects the contents of the DSPARB
registers.

v2: Add a note that interrupts are already disabled (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170309154434.29303-6-ville.syrjala@linux.intel.com
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_pm.c

index 1af54717fa81cc2d00be6f9471216edb7ad3e449..e312b61ba6bbbc1fecbd0ed4f2da2c0407fa09b5 100644 (file)
@@ -825,7 +825,6 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
 
        spin_lock_init(&dev_priv->mm.object_stat_lock);
        spin_lock_init(&dev_priv->mmio_flip_lock);
-       spin_lock_init(&dev_priv->wm.dsparb_lock);
        mutex_init(&dev_priv->sb_lock);
        mutex_init(&dev_priv->modeset_restore_lock);
        mutex_init(&dev_priv->av_mutex);
index d11c96405a5346a8d936bd853197bd701a898b95..48ff648122898b31d6ee9fdbf1c0f16804838159 100644 (file)
@@ -2375,9 +2375,6 @@ struct drm_i915_private {
        } sagv_status;
 
        struct {
-               /* protects DSPARB registers on pre-g4x/vlv/chv */
-               spinlock_t dsparb_lock;
-
                /*
                 * Raw watermark latency values:
                 * in 0.1us units for WM0,
index bf34672c972e4d31ef886bb5f9bbe6745c934b3c..2ca38ae4421ed02656d9601f61f24a7fff18a1f5 100644 (file)
@@ -1358,13 +1358,22 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
 
        trace_vlv_fifo_size(crtc, sprite0_start, sprite1_start, fifo_size);
 
-       spin_lock(&dev_priv->wm.dsparb_lock);
+       /*
+        * uncore.lock serves a double purpose here. It allows us to
+        * use the less expensive I915_{READ,WRITE}_FW() functions, and
+        * it protects the DSPARB registers from getting clobbered by
+        * parallel updates from multiple pipes.
+        *
+        * intel_pipe_update_start() has already disabled interrupts
+        * for us, so a plain spin_lock() is sufficient here.
+        */
+       spin_lock(&dev_priv->uncore.lock);
 
        switch (crtc->pipe) {
                uint32_t dsparb, dsparb2, dsparb3;
        case PIPE_A:
-               dsparb = I915_READ(DSPARB);
-               dsparb2 = I915_READ(DSPARB2);
+               dsparb = I915_READ_FW(DSPARB);
+               dsparb2 = I915_READ_FW(DSPARB2);
 
                dsparb &= ~(VLV_FIFO(SPRITEA, 0xff) |
                            VLV_FIFO(SPRITEB, 0xff));
@@ -1376,12 +1385,12 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
                dsparb2 |= (VLV_FIFO(SPRITEA_HI, sprite0_start >> 8) |
                           VLV_FIFO(SPRITEB_HI, sprite1_start >> 8));
 
-               I915_WRITE(DSPARB, dsparb);
-               I915_WRITE(DSPARB2, dsparb2);
+               I915_WRITE_FW(DSPARB, dsparb);
+               I915_WRITE_FW(DSPARB2, dsparb2);
                break;
        case PIPE_B:
-               dsparb = I915_READ(DSPARB);
-               dsparb2 = I915_READ(DSPARB2);
+               dsparb = I915_READ_FW(DSPARB);
+               dsparb2 = I915_READ_FW(DSPARB2);
 
                dsparb &= ~(VLV_FIFO(SPRITEC, 0xff) |
                            VLV_FIFO(SPRITED, 0xff));
@@ -1393,12 +1402,12 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
                dsparb2 |= (VLV_FIFO(SPRITEC_HI, sprite0_start >> 8) |
                           VLV_FIFO(SPRITED_HI, sprite1_start >> 8));
 
-               I915_WRITE(DSPARB, dsparb);
-               I915_WRITE(DSPARB2, dsparb2);
+               I915_WRITE_FW(DSPARB, dsparb);
+               I915_WRITE_FW(DSPARB2, dsparb2);
                break;
        case PIPE_C:
-               dsparb3 = I915_READ(DSPARB3);
-               dsparb2 = I915_READ(DSPARB2);
+               dsparb3 = I915_READ_FW(DSPARB3);
+               dsparb2 = I915_READ_FW(DSPARB2);
 
                dsparb3 &= ~(VLV_FIFO(SPRITEE, 0xff) |
                             VLV_FIFO(SPRITEF, 0xff));
@@ -1410,16 +1419,16 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
                dsparb2 |= (VLV_FIFO(SPRITEE_HI, sprite0_start >> 8) |
                           VLV_FIFO(SPRITEF_HI, sprite1_start >> 8));
 
-               I915_WRITE(DSPARB3, dsparb3);
-               I915_WRITE(DSPARB2, dsparb2);
+               I915_WRITE_FW(DSPARB3, dsparb3);
+               I915_WRITE_FW(DSPARB2, dsparb2);
                break;
        default:
                break;
        }
 
-       POSTING_READ(DSPARB);
+       POSTING_READ_FW(DSPARB);
 
-       spin_unlock(&dev_priv->wm.dsparb_lock);
+       spin_unlock(&dev_priv->uncore.lock);
 }
 
 #undef VLV_FIFO