From patchwork Tue Apr 19 07:52:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maarten Lankhorst X-Patchwork-Id: 8877551 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 65554BF4C7 for ; Tue, 19 Apr 2016 07:53:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 51F612026F for ; Tue, 19 Apr 2016 07:53:01 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id DD03D20145 for ; Tue, 19 Apr 2016 07:52:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D009C6E6C5; Tue, 19 Apr 2016 07:52:53 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mblankhorst.nl (mblankhorst.nl [IPv6:2a02:2308::216:3eff:fe92:dfa3]) by gabe.freedesktop.org (Postfix) with ESMTPS id 52C286E6C7 for ; Tue, 19 Apr 2016 07:52:49 +0000 (UTC) From: Maarten Lankhorst To: intel-gfx@lists.freedesktop.org Date: Tue, 19 Apr 2016 09:52:27 +0200 Message-Id: <1461052359-24154-8-git-send-email-maarten.lankhorst@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1461052359-24154-1-git-send-email-maarten.lankhorst@linux.intel.com> References: <1461052359-24154-1-git-send-email-maarten.lankhorst@linux.intel.com> Subject: [Intel-gfx] [PATCH 07/19] drm/i915: Allow mmio updates on all platforms, v2. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- drivers/gpu/drm/i915/intel_display.c | 105 ++++------------------------------- drivers/gpu/drm/i915/intel_drv.h | 1 - 2 files changed, 12 insertions(+), 94 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8b61a07c4c52..d1181089512a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11324,9 +11324,6 @@ static bool use_mmio_flip(struct intel_engine_cs *engine, if (engine == NULL) return true; - if (INTEL_INFO(engine->dev)->gen < 5) - return false; - if (i915.use_mmio_flip < 0) return false; else if (i915.use_mmio_flip > 0) @@ -11341,92 +11338,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, @@ -11440,13 +11360,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); } @@ -11479,6 +11395,10 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev, smp_mb__after_atomic(); vblank = intel_crtc_get_vblank_counter(intel_crtc); + if (is_mmio_work(work)) + /* MMIO work completes when vblank is different from flip_queued_vblank. */ + return vblank != work->flip_queued_vblank; + if (work->flip_ready_vblank == 0) { if (work->flip_queued_req && !i915_gem_request_completed(work->flip_queued_req, true)) @@ -11519,7 +11439,7 @@ void intel_check_page_flip(struct drm_device *dev, int pipe) spin_lock(&dev->event_lock); work = intel_crtc->flip_work; if (work != NULL && __intel_pageflip_stall_check(dev, crtc)) { - WARN_ONCE(1, + WARN_ONCE(!is_mmio_work(work), "Kicking stuck page flip: queued at %d, now %d\n", work->flip_queued_vblank, intel_crtc_get_vblank_counter(intel_crtc)); page_flip_completed(intel_crtc); @@ -11675,7 +11595,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 e10e6959fd43..bc310513adb8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -950,7 +950,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 {