On Tue, May 17, 2016 at 03:07:51PM +0200, Maarten Lankhorst wrote:
> With intel_pipe_update begin/end we ensure that the mmio updates
> don't run during vblank interrupt, using the hw counter we can
> be sure that when current vblank count != vblank count at the time
> of pipe_update_end the mmio update is complete.
> 
> This allows us to use mmio updates on all platforms, using the
> update_plane call.
> 
> With Chris Wilson's patch to skip waiting for vblanks for
> legacy_cursor_update this potentially leaves a small race
> condition, in which update_plane can be called with a freed
> crtc_state. Because of this commit acf4e84d61673
> ("drm/i915: Avoid stalling on pending flips for legacy cursor updates")
> is temporarily reverted.
> 
> Changes since v1:
> - Split out the flip_work rename.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankho...@linux.intel.com>

Reviewed-by: Patrik Jakobsson <patrik.jakobs...@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/intel_display.c | 99 
> +++---------------------------------
>  drivers/gpu/drm/i915/intel_drv.h     |  1 -
>  2 files changed, 7 insertions(+), 93 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 6526bb5a7afb..6d2af42a86c1 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11269,9 +11269,6 @@ static bool use_mmio_flip(struct intel_engine_cs 
> *engine,
>       if (engine == NULL)
>               return true;
>  
> -     if (INTEL_GEN(engine->i915) < 5)
> -             return false;
> -
>       if (i915.use_mmio_flip < 0)
>               return false;
>       else if (i915.use_mmio_flip > 0)
> @@ -11286,92 +11283,15 @@ static bool use_mmio_flip(struct intel_engine_cs 
> *engine,
>               return engine != 
> i915_gem_request_get_engine(obj->last_write_req);
>  }
>  
> -static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
> -                          unsigned int rotation,
> -                          struct intel_flip_work *work)
> -{
> -     struct drm_device *dev = intel_crtc->base.dev;
> -     struct drm_i915_private *dev_priv = dev->dev_private;
> -     struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
> -     const enum pipe pipe = intel_crtc->pipe;
> -     u32 ctl, stride, tile_height;
> -
> -     ctl = I915_READ(PLANE_CTL(pipe, 0));
> -     ctl &= ~PLANE_CTL_TILED_MASK;
> -     switch (fb->modifier[0]) {
> -     case DRM_FORMAT_MOD_NONE:
> -             break;
> -     case I915_FORMAT_MOD_X_TILED:
> -             ctl |= PLANE_CTL_TILED_X;
> -             break;
> -     case I915_FORMAT_MOD_Y_TILED:
> -             ctl |= PLANE_CTL_TILED_Y;
> -             break;
> -     case I915_FORMAT_MOD_Yf_TILED:
> -             ctl |= PLANE_CTL_TILED_YF;
> -             break;
> -     default:
> -             MISSING_CASE(fb->modifier[0]);
> -     }
> -
> -     /*
> -      * The stride is either expressed as a multiple of 64 bytes chunks for
> -      * linear buffers or in number of tiles for tiled buffers.
> -      */
> -     if (intel_rotation_90_or_270(rotation)) {
> -             /* stride = Surface height in tiles */
> -             tile_height = intel_tile_height(dev_priv, fb->modifier[0], 0);
> -             stride = DIV_ROUND_UP(fb->height, tile_height);
> -     } else {
> -             stride = fb->pitches[0] /
> -                     intel_fb_stride_alignment(dev_priv, fb->modifier[0],
> -                                               fb->pixel_format);
> -     }
> -
> -     /*
> -      * Both PLANE_CTL and PLANE_STRIDE are not updated on vblank but on
> -      * PLANE_SURF updates, the update is then guaranteed to be atomic.
> -      */
> -     I915_WRITE(PLANE_CTL(pipe, 0), ctl);
> -     I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> -
> -     I915_WRITE(PLANE_SURF(pipe, 0), work->gtt_offset);
> -     POSTING_READ(PLANE_SURF(pipe, 0));
> -}
> -
> -static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc,
> -                          struct intel_flip_work *work)
> -{
> -     struct drm_device *dev = intel_crtc->base.dev;
> -     struct drm_i915_private *dev_priv = dev->dev_private;
> -     struct intel_framebuffer *intel_fb =
> -             to_intel_framebuffer(intel_crtc->base.primary->fb);
> -     struct drm_i915_gem_object *obj = intel_fb->obj;
> -     i915_reg_t reg = DSPCNTR(intel_crtc->plane);
> -     u32 dspcntr;
> -
> -     dspcntr = I915_READ(reg);
> -
> -     if (obj->tiling_mode != I915_TILING_NONE)
> -             dspcntr |= DISPPLANE_TILED;
> -     else
> -             dspcntr &= ~DISPPLANE_TILED;
> -
> -     I915_WRITE(reg, dspcntr);
> -
> -     I915_WRITE(DSPSURF(intel_crtc->plane), work->gtt_offset);
> -     POSTING_READ(DSPSURF(intel_crtc->plane));
> -}
> -
>  static void intel_mmio_flip_work_func(struct work_struct *w)
>  {
>       struct intel_flip_work *work =
>               container_of(w, struct intel_flip_work, mmio_work);
>       struct intel_crtc *crtc = to_intel_crtc(work->crtc);
> -     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -     struct intel_framebuffer *intel_fb =
> -             to_intel_framebuffer(crtc->base.primary->fb);
> -     struct drm_i915_gem_object *obj = intel_fb->obj;
> +     struct drm_device *dev = crtc->base.dev;
> +     struct drm_i915_private *dev_priv = dev->dev_private;
> +     struct intel_plane *primary = to_intel_plane(crtc->base.primary);
> +     struct drm_i915_gem_object *obj = intel_fb_obj(primary->base.state->fb);
>  
>       if (work->flip_queued_req)
>               WARN_ON(__i915_wait_request(work->flip_queued_req,
> @@ -11385,13 +11305,9 @@ static void intel_mmio_flip_work_func(struct 
> work_struct *w)
>                                                           
> MAX_SCHEDULE_TIMEOUT) < 0);
>  
>       intel_pipe_update_start(crtc);
> -
> -     if (INTEL_GEN(dev_priv) >= 9)
> -             skl_do_mmio_flip(crtc, work->rotation, work);
> -     else
> -             /* use_mmio_flip() retricts MMIO flips to ilk+ */
> -             ilk_do_mmio_flip(crtc, work);
> -
> +     primary->update_plane(&primary->base,
> +                           crtc->config,
> +                           to_intel_plane_state(primary->base.state));
>       intel_pipe_update_end(crtc, work);
>  }
>  
> @@ -11616,7 +11532,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
>       work->gtt_offset = intel_plane_obj_offset(to_intel_plane(primary),
>                                                 obj, 0);
>       work->gtt_offset += intel_crtc->dspaddr_offset;
> -     work->rotation = crtc->primary->state->rotation;
>  
>       if (mmio_flip) {
>               INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index f9a09b0dc05e..b5235373b1ad 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -983,7 +983,6 @@ struct intel_flip_work {
>       struct drm_i915_gem_request *flip_queued_req;
>       u32 flip_queued_vblank;
>       u32 flip_ready_vblank;
> -     unsigned int rotation;
>  };
>  
>  struct intel_load_detect_pipe {
> -- 
> 2.5.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Intel Sweden AB Registered Office: Knarrarnasgatan 15, 164 40 Kista, Stockholm, 
Sweden Registration Number: 556189-6027 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to