drm/i915/frontbuffer: Pull frontbuffer_flush out of gem_obj_pin_to_display
authorDhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Wed, 7 Mar 2018 03:34:18 +0000 (19:34 -0800)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 13 Mar 2018 20:49:39 +0000 (13:49 -0700)
i915_gem_obj_pin_to_display() calls frontbuffer_flush with origin set to
DIRTYFB. The callers however are at a vantage point to decide if hardware
frontbuffer tracking can do the flush for us. For example, legacy cursor
updates, like flips, write to MMIO registers, which then triggers PSR flush
by the hardware. Moving frontbuffer_flush out will enable us to skip a
software initiated flush by setting origin to FLIP. Thanks to Chris for the
idea.

v2:
Rebased due to Ville adding intel_plane_pin_fb().
Minor code reordering as fb_obj_flush doesn't need struct_mutex (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180307033420.3086-1-dhinakaran.pandiyan@intel.com
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_overlay.c

index 05b0724b60dca7ca8af6add2ae6ce79a57c13065..58f8cf7d3b40ef6ad6e68aa05e029d4a82d2c778 100644 (file)
@@ -4094,9 +4094,10 @@ out:
 }
 
 /*
- * Prepare buffer for display plane (scanout, cursors, etc).
- * Can be called from an uninterruptible phase (modesetting) and allows
- * any flushes to be pipelined (for pageflips).
+ * Prepare buffer for display plane (scanout, cursors, etc). Can be called from
+ * an uninterruptible phase (modesetting) and allows any flushes to be pipelined
+ * (for pageflips). We only flush the caches while preparing the buffer for
+ * display, the callers are responsible for frontbuffer flush.
  */
 struct i915_vma *
 i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
@@ -4152,9 +4153,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
 
        vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
 
-       /* Treat this as an end-of-frame, like intel_user_framebuffer_dirty() */
        __i915_gem_object_flush_for_display(obj);
-       intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
 
        /* It should now be out of any other write domains, and we can update
         * the domain values for our changes.
index f424fff477f6d262d7267225b2af1da43c60ec2d..1b2a402e32fa869147d6627c02e0e1d8d7cac663 100644 (file)
@@ -2858,6 +2858,9 @@ valid_fb:
                return;
        }
 
+       obj = intel_fb_obj(fb);
+       intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
+
        plane_state->src_x = 0;
        plane_state->src_y = 0;
        plane_state->src_w = fb->width << 16;
@@ -2871,7 +2874,6 @@ valid_fb:
        intel_state->base.src = drm_plane_state_src(plane_state);
        intel_state->base.dst = drm_plane_state_dest(plane_state);
 
-       obj = intel_fb_obj(fb);
        if (i915_gem_object_is_tiled(obj))
                dev_priv->preserve_bios_swizzle = true;
 
@@ -12793,6 +12795,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
        if (ret)
                return ret;
 
+       intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
+
        if (!new_state->fence) { /* implicit fencing */
                struct dma_fence *fence;
 
@@ -13186,8 +13190,9 @@ intel_legacy_cursor_update(struct drm_plane *plane,
        if (ret)
                goto out_unlock;
 
-       old_fb = old_plane_state->fb;
+       intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_DIRTYFB);
 
+       old_fb = old_plane_state->fb;
        i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb),
                          intel_plane->frontbuffer_bit);
 
index 6f12adc063650c1ad4f696922dee1215a98398c0..65a3313723c916edb28d6927eaed59b9d9c979a4 100644 (file)
@@ -221,6 +221,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
                goto out_unlock;
        }
 
+       fb = &ifbdev->fb->base;
+       intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_DIRTYFB);
+
        info = drm_fb_helper_alloc_fbi(helper);
        if (IS_ERR(info)) {
                DRM_ERROR("Failed to allocate fb_info\n");
@@ -230,8 +233,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
 
        info->par = helper;
 
-       fb = &ifbdev->fb->base;
-
        ifbdev->helper.fb = fb;
 
        strcpy(info->fix.id, "inteldrmfb");
index 36671a937fa4ae88bf5495ae45af5b5f0ae87626..c2f10d8993296471833e4a5d8a0cd69463a992b4 100644 (file)
@@ -807,6 +807,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
                ret = PTR_ERR(vma);
                goto out_pin_section;
        }
+       intel_fb_obj_flush(new_bo, ORIGIN_DIRTYFB);
 
        ret = i915_vma_put_fence(vma);
        if (ret)