drm/i915: Split g4x+ sprite plane update into noarm+arm pair
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 18 Oct 2021 11:50:28 +0000 (14:50 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 4 Nov 2021 15:59:25 +0000 (17:59 +0200)
Chop g4x_sprite_update() into two halves. Fist half becomes
the _noarm() variant, second part the _arm() variant.

Fortunately I have already previously grouped the register
writes into roughtly the correct order, so the split looks
surprisingly clean.

Not much of a change in i915_update_info on these older
platforms that don't have so many planes or registers to
begin with. Here are the numbers from snb (totally unpatched
vs. both primary plane and sprite patched applied) running
kms_atomic_transition --r plane-all-transition --extended:
w/o patch                           w/ patch
Updates: 5404     Updates: 5405
       |         |
   1us |******        1us |******
       |*********         |*********
   4us |***********        4us |***********
       |**********         |**********
  16us |**       16us |**
       |         |
  66us |       66us |
       |         |
 262us |      262us |
       |         |
   1ms |        1ms |
       |         |
   4ms |        4ms |
       |         |
  17ms |       17ms |
       |         |
Min update: 1400ns     Min update: 1307ns
Max update: 19809ns     Max update: 20194ns
Average update: 6957ns     Average update: 6432ns
Overruns > 100us: 0     Overruns > 100us: 0

But there seems to be a slight improvement with
lockdep enabled:
w/o patch                           w/ patch
Updates: 17612     Updates: 16364
       |         |
   1us |        1us |
       |******         |******
   4us |**********        4us |**********
       |************         |*************
  16us |*************       16us |************
       |***         |*
  66us |       66us |
       |         |
 262us |      262us |
       |         |
   1ms |        1ms |
       |         |
   4ms |        4ms |
       |         |
  17ms |       17ms |
       |         |
Min update: 3141ns     Min update: 3562ns
Max update: 126450ns     Max update: 73354ns
Average update: 16373ns     Average update: 15153ns
Overruns > 250us: 0     Overruns > 250us: 0

Cc: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211018115030.3547-8-ville.syrjala@linux.intel.com
Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
drivers/gpu/drm/i915/display/intel_sprite.c

index fb24996..fe779b5 100644 (file)
@@ -1166,28 +1166,21 @@ static void ilk_sprite_update_gamma(const struct intel_plane_state *plane_state)
 }
 
 static void
-g4x_sprite_update_arm(struct intel_plane *plane,
-                     const struct intel_crtc_state *crtc_state,
-                     const struct intel_plane_state *plane_state)
+g4x_sprite_update_noarm(struct intel_plane *plane,
+                       const struct intel_crtc_state *crtc_state,
+                       const struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum pipe pipe = plane->pipe;
-       u32 dvssurf_offset = plane_state->view.color_plane[0].offset;
-       u32 linear_offset;
-       const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
        int crtc_x = plane_state->uapi.dst.x1;
        int crtc_y = plane_state->uapi.dst.y1;
        u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
        u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
-       u32 x = plane_state->view.color_plane[0].x;
-       u32 y = plane_state->view.color_plane[0].y;
        u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
        u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
-       u32 dvscntr, dvsscale = 0;
+       u32 dvsscale = 0;
        unsigned long irqflags;
 
-       dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
-
        /* Sizes are 0 based */
        src_w--;
        src_h--;
@@ -1197,8 +1190,6 @@ g4x_sprite_update_arm(struct intel_plane *plane,
        if (crtc_w != src_w || crtc_h != src_h)
                dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
 
-       linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
-
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
        intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
@@ -1207,6 +1198,29 @@ g4x_sprite_update_arm(struct intel_plane *plane,
        intel_de_write_fw(dev_priv, DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
        intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale);
 
+       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
+static void
+g4x_sprite_update_arm(struct intel_plane *plane,
+                     const struct intel_crtc_state *crtc_state,
+                     const struct intel_plane_state *plane_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+       enum pipe pipe = plane->pipe;
+       const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+       u32 dvssurf_offset = plane_state->view.color_plane[0].offset;
+       u32 x = plane_state->view.color_plane[0].x;
+       u32 y = plane_state->view.color_plane[0].y;
+       u32 dvscntr, linear_offset;
+       unsigned long irqflags;
+
+       dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
+
+       linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
+
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
        if (key->flags) {
                intel_de_write_fw(dev_priv, DVSKEYVAL(pipe), key->min_value);
                intel_de_write_fw(dev_priv, DVSKEYMSK(pipe),
@@ -1779,6 +1793,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
 
                plane_funcs = &snb_sprite_funcs;
        } else {
+               plane->update_noarm = g4x_sprite_update_noarm;
                plane->update_arm = g4x_sprite_update_arm;
                plane->disable_arm = g4x_sprite_disable_arm;
                plane->get_hw_state = g4x_sprite_get_hw_state;