drm/i915: Reorganize VLV DDL setup
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 5 Mar 2015 19:19:45 +0000 (21:19 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 17 Mar 2015 21:30:03 +0000 (22:30 +0100)
Introduce struct vlv_wm_values to house VLV watermark/drain latency
values. We start by using it when computing the drain latency values.

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_pm.c

index 238bfd0..5462cbf 100644 (file)
@@ -1407,6 +1407,14 @@ struct ilk_wm_values {
        enum intel_ddb_partitioning partitioning;
 };
 
+struct vlv_wm_values {
+       struct {
+               uint8_t cursor;
+               uint8_t sprite[2];
+               uint8_t primary;
+       } ddl[3];
+};
+
 struct skl_ddb_entry {
        uint16_t start, end;    /* in number of blocks, 'end' is exclusive */
 };
@@ -1769,6 +1777,7 @@ struct drm_i915_private {
                union {
                        struct ilk_wm_values hw;
                        struct skl_wm_values skl_hw;
+                       struct vlv_wm_values vlv;
                };
        } wm;
 
index 7dbc188..c9b1604 100644 (file)
@@ -739,6 +739,21 @@ static bool g4x_compute_srwm(struct drm_device *dev,
                              display, cursor);
 }
 
+static void vlv_write_wm_values(struct intel_crtc *crtc,
+                               const struct vlv_wm_values *wm)
+{
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum pipe pipe = crtc->pipe;
+
+       I915_WRITE(VLV_DDL(pipe),
+                  (wm->ddl[pipe].cursor << DDL_CURSOR_SHIFT) |
+                  (wm->ddl[pipe].sprite[1] << DDL_SPRITE_SHIFT(1)) |
+                  (wm->ddl[pipe].sprite[0] << DDL_SPRITE_SHIFT(0)) |
+                  (wm->ddl[pipe].primary << DDL_PLANE_SHIFT));
+
+       dev_priv->wm.vlv = *wm;
+}
+
 static uint8_t vlv_compute_drain_latency(struct drm_crtc *crtc,
                                         int pixel_size)
 {
@@ -785,20 +800,19 @@ static void vlv_update_drain_latency(struct drm_crtc *crtc)
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pixel_size;
        enum pipe pipe = intel_crtc->pipe;
-       int plane_dl;
+       struct vlv_wm_values wm = dev_priv->wm.vlv;
 
-       plane_dl = I915_READ(VLV_DDL(pipe)) &
-               ~(((DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK) << DDL_CURSOR_SHIFT) |
-                 ((DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK) << DDL_PLANE_SHIFT));
+       wm.ddl[pipe].primary = 0;
+       wm.ddl[pipe].cursor = 0;
 
        if (!intel_crtc_active(crtc)) {
-               I915_WRITE(VLV_DDL(pipe), plane_dl);
+               vlv_write_wm_values(intel_crtc, &wm);
                return;
        }
 
        /* Primary plane Drain Latency */
        pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;      /* BPP */
-       plane_dl = vlv_compute_drain_latency(crtc, pixel_size) << DDL_PLANE_SHIFT;
+       wm.ddl[pipe].primary = vlv_compute_drain_latency(crtc, pixel_size);
 
        /* Cursor Drain Latency
         * BPP is always 4 for cursor
@@ -807,9 +821,10 @@ static void vlv_update_drain_latency(struct drm_crtc *crtc)
 
        /* Program cursor DL only if it is enabled */
        if (intel_crtc->cursor_base)
-               plane_dl |= vlv_compute_drain_latency(crtc, pixel_size) << DDL_CURSOR_SHIFT;
+               wm.ddl[pipe].cursor =
+                       vlv_compute_drain_latency(crtc, pixel_size);
 
-       I915_WRITE(VLV_DDL(pipe), plane_dl);
+       vlv_write_wm_values(intel_crtc, &wm);
 }
 
 #define single_plane_enabled(mask) is_power_of_2(mask)
@@ -967,17 +982,18 @@ static void valleyview_update_sprite_wm(struct drm_plane *plane,
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int pipe = to_intel_plane(plane)->pipe;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       enum pipe pipe = intel_crtc->pipe;
        int sprite = to_intel_plane(plane)->plane;
-       int sprite_dl;
-
-       sprite_dl = I915_READ(VLV_DDL(pipe)) &
-               ~((DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK) << DDL_SPRITE_SHIFT(sprite));
+       struct vlv_wm_values wm = dev_priv->wm.vlv;
 
        if (enabled)
-               sprite_dl |= vlv_compute_drain_latency(crtc, pixel_size) << DDL_SPRITE_SHIFT(sprite);
+               wm.ddl[pipe].sprite[sprite] =
+                       vlv_compute_drain_latency(crtc, pixel_size);
+       else
+               wm.ddl[pipe].sprite[sprite] = 0;
 
-       I915_WRITE(VLV_DDL(pipe), sprite_dl);
+       vlv_write_wm_values(intel_crtc, &wm);
 }
 
 static void g4x_update_wm(struct drm_crtc *crtc)