From 8b5d27b911d741054c65fb57f0d794a283308577 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 20 Jul 2017 19:57:53 +0200 Subject: [PATCH] drm/i915: Remove intel_flip_work infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This gets rid of all the interactions between the legacy flip code and the modeset code. Yay! This highlights an ommission in the atomic paths, where we fail to apply a boost to the pending rendering when we miss the target vblank. But the existing code is still dead and can be removed. v2: Note that the boosting doesn't work in atomic (Chris). Cc: Maarten Lankhorst Cc: Ville Syrjälä Reviewed-by: Maarten Lankhorst Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20170720175754.30751-7-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/i915_debugfs.c | 70 ---------------- drivers/gpu/drm/i915/i915_drv.c | 1 - drivers/gpu/drm/i915/i915_drv.h | 4 - drivers/gpu/drm/i915/i915_gem.c | 2 - drivers/gpu/drm/i915/intel_display.c | 117 +-------------------------- drivers/gpu/drm/i915/intel_drv.h | 21 +---- drivers/gpu/drm/i915/intel_sprite.c | 8 +- 7 files changed, 3 insertions(+), 220 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 2ef75c1a6119..c25f42c60d61 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -543,75 +543,6 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) return 0; } -static int i915_gem_pageflip_info(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct drm_device *dev = &dev_priv->drm; - struct intel_crtc *crtc; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - for_each_intel_crtc(dev, crtc) { - const char pipe = pipe_name(crtc->pipe); - const char plane = plane_name(crtc->plane); - struct intel_flip_work *work; - - spin_lock_irq(&dev->event_lock); - work = crtc->flip_work; - if (work == NULL) { - seq_printf(m, "No flip due on pipe %c (plane %c)\n", - pipe, plane); - } else { - u32 pending; - u32 addr; - - pending = atomic_read(&work->pending); - if (pending) { - seq_printf(m, "Flip ioctl preparing on pipe %c (plane %c)\n", - pipe, plane); - } else { - seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n", - pipe, plane); - } - if (work->flip_queued_req) { - struct intel_engine_cs *engine = work->flip_queued_req->engine; - - seq_printf(m, "Flip queued on %s at seqno %x, last submitted seqno %x [current breadcrumb %x], completed? %d\n", - engine->name, - work->flip_queued_req->global_seqno, - intel_engine_last_submit(engine), - intel_engine_get_seqno(engine), - i915_gem_request_completed(work->flip_queued_req)); - } else - seq_printf(m, "Flip not associated with any ring\n"); - seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n", - work->flip_queued_vblank, - work->flip_ready_vblank, - intel_crtc_get_vblank_counter(crtc)); - seq_printf(m, "%d prepares\n", atomic_read(&work->pending)); - - if (INTEL_GEN(dev_priv) >= 4) - addr = I915_HI_DISPBASE(I915_READ(DSPSURF(crtc->plane))); - else - addr = I915_READ(DSPADDR(crtc->plane)); - seq_printf(m, "Current scanout address 0x%08x\n", addr); - - if (work->pending_flip_obj) { - seq_printf(m, "New framebuffer address 0x%08lx\n", (long)work->gtt_offset); - seq_printf(m, "MMIO update completed? %d\n", addr == work->gtt_offset); - } - } - spin_unlock_irq(&dev->event_lock); - } - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - static int i915_gem_batch_pool_info(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -4854,7 +4785,6 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_gem_gtt", i915_gem_gtt_info, 0}, {"i915_gem_pin_display", i915_gem_gtt_info, 0, (void *)1}, {"i915_gem_stolen", i915_gem_stolen_list_info }, - {"i915_gem_pageflip", i915_gem_pageflip_info, 0}, {"i915_gem_request", i915_gem_request_info, 0}, {"i915_gem_seqno", i915_gem_seqno_info, 0}, {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f406aec8a499..5a21a6fcc90d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -876,7 +876,6 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, spin_lock_init(&dev_priv->uncore.lock); spin_lock_init(&dev_priv->mm.object_stat_lock); - spin_lock_init(&dev_priv->mmio_flip_lock); mutex_init(&dev_priv->sb_lock); mutex_init(&dev_priv->modeset_restore_lock); mutex_init(&dev_priv->av_mutex); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fea04182362d..0e84346115dd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2143,9 +2143,6 @@ struct drm_i915_private { /* protects the irq masks */ spinlock_t irq_lock; - /* protects the mmio flip data */ - spinlock_t mmio_flip_lock; - bool display_irqs_enabled; /* To control wakeup latency, e.g. for irq-driven dp aux transfers. */ @@ -2250,7 +2247,6 @@ struct drm_i915_private { struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES]; struct intel_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES]; - wait_queue_head_t pending_flip_queue; #ifdef CONFIG_DEBUG_FS struct intel_pipe_crc pipe_crc[I915_MAX_PIPES]; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1b2dfa8bdeef..59715e9f2cc4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4935,8 +4935,6 @@ i915_gem_load_init(struct drm_i915_private *dev_priv) init_waitqueue_head(&dev_priv->gpu_error.wait_queue); init_waitqueue_head(&dev_priv->gpu_error.reset_queue); - init_waitqueue_head(&dev_priv->pending_flip_queue); - atomic_set(&dev_priv->mm.bsd_engine_dispatch_index, 0); spin_lock_init(&dev_priv->fb_tracking.lock); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e144e6fec76e..56bf9009ea15 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -49,11 +49,6 @@ #include #include -static bool is_mmio_work(struct intel_flip_work *work) -{ - return work->mmio_work.func; -} - /* Primary plane formats for gen <= 3 */ static const uint32_t i8xx_primary_formats[] = { DRM_FORMAT_C8, @@ -3551,35 +3546,6 @@ unlock: mutex_unlock(&dev->mode_config.mutex); } -static bool abort_flip_on_reset(struct intel_crtc *crtc) -{ - struct i915_gpu_error *error = &to_i915(crtc->base.dev)->gpu_error; - - if (i915_reset_backoff(error)) - return true; - - if (crtc->reset_count != i915_reset_count(error)) - return true; - - return false; -} - -static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - bool pending; - - if (abort_flip_on_reset(intel_crtc)) - return false; - - spin_lock_irq(&dev->event_lock); - pending = to_intel_crtc(crtc)->flip_work != NULL; - spin_unlock_irq(&dev->event_lock); - - return pending; -} - static void intel_update_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *old_crtc_state) { @@ -4157,57 +4123,6 @@ bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv) return false; } -static void page_flip_completed(struct intel_crtc *intel_crtc) -{ - struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); - struct intel_flip_work *work = intel_crtc->flip_work; - - intel_crtc->flip_work = NULL; - - if (work->event) - drm_crtc_send_vblank_event(&intel_crtc->base, work->event); - - drm_crtc_vblank_put(&intel_crtc->base); - - wake_up_all(&dev_priv->pending_flip_queue); - trace_i915_flip_complete(intel_crtc->plane, - work->pending_flip_obj); - - queue_work(dev_priv->wq, &work->unpin_work); -} - -static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = to_i915(dev); - long ret; - - WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue)); - - ret = wait_event_interruptible_timeout( - dev_priv->pending_flip_queue, - !intel_crtc_has_pending_flip(crtc), - 60*HZ); - - if (ret < 0) - return ret; - - if (ret == 0) { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_flip_work *work; - - spin_lock_irq(&dev->event_lock); - work = intel_crtc->flip_work; - if (work && !is_mmio_work(work)) { - WARN_ONCE(1, "Removing stuck page flip\n"); - page_flip_completed(intel_crtc); - } - spin_unlock_irq(&dev->event_lock); - } - - return 0; -} - void lpt_disable_iclkip(struct drm_i915_private *dev_priv) { u32 temp; @@ -5814,8 +5729,6 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc, return; if (crtc->primary->state->visible) { - WARN_ON(intel_crtc->flip_work); - intel_pre_disable_primary_noatomic(crtc); intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary)); @@ -10088,35 +10001,11 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, static void intel_crtc_destroy(struct drm_crtc *crtc) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct intel_flip_work *work; - - spin_lock_irq(&dev->event_lock); - work = intel_crtc->flip_work; - intel_crtc->flip_work = NULL; - spin_unlock_irq(&dev->event_lock); - - if (work) { - cancel_work_sync(&work->mmio_work); - cancel_work_sync(&work->unpin_work); - kfree(work); - } drm_crtc_cleanup(crtc); - kfree(intel_crtc); } -static inline void intel_mark_page_flip_active(struct intel_crtc *crtc, - struct intel_flip_work *work) -{ - work->flip_queued_vblank = intel_crtc_get_vblank_counter(crtc); - - /* Ensure that the work item is consistent when activating it ... */ - smp_mb__before_atomic(); - atomic_set(&work->pending, 1); -} - /** * intel_wm_need_update - Check whether watermarks need updating * @plane: drm plane @@ -11935,10 +11824,6 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, if (state->legacy_cursor_update) continue; - ret = intel_crtc_wait_for_pending_flips(crtc); - if (ret) - return ret; - if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2) flush_workqueue(dev_priv->wq); } @@ -12712,7 +12597,7 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc, { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - intel_pipe_update_end(intel_crtc, NULL); + intel_pipe_update_end(intel_crtc); } /** diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4b7766efae7b..79009b759056 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -797,7 +797,6 @@ struct intel_crtc { u8 plane_ids_mask; unsigned long long enabled_power_domains; struct intel_overlay *overlay; - struct intel_flip_work *flip_work; atomic_t unpin_work_count; @@ -1132,24 +1131,6 @@ intel_get_crtc_for_plane(struct drm_i915_private *dev_priv, enum plane plane) return dev_priv->plane_to_crtc_mapping[plane]; } -struct intel_flip_work { - struct work_struct unpin_work; - struct work_struct mmio_work; - - struct drm_crtc *crtc; - struct i915_vma *old_vma; - struct drm_framebuffer *old_fb; - struct drm_i915_gem_object *pending_flip_obj; - struct drm_pending_vblank_event *event; - atomic_t pending; - u32 flip_count; - u32 gtt_offset; - struct drm_i915_gem_request *flip_queued_req; - u32 flip_queued_vblank; - u32 flip_ready_vblank; - unsigned int rotation; -}; - struct intel_load_detect_pipe { struct drm_atomic_state *restore_state; }; @@ -1903,7 +1884,7 @@ struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv); void intel_pipe_update_start(struct intel_crtc *crtc); -void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work); +void intel_pipe_update_end(struct intel_crtc *crtc); /* intel_tv.c */ void intel_tv_init(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 94f9a1332dbf..8e25694a1508 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -176,7 +176,7 @@ void intel_pipe_update_start(struct intel_crtc *crtc) * re-enables interrupts and verifies the update was actually completed * before a vblank using the value of @start_vbl_count. */ -void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work) +void intel_pipe_update_end(struct intel_crtc *crtc) { enum pipe pipe = crtc->pipe; int scanline_end = intel_get_crtc_scanline(crtc); @@ -184,12 +184,6 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work ktime_t end_vbl_time = ktime_get(); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - if (work) { - work->flip_queued_vblank = end_vbl_count; - smp_mb__before_atomic(); - atomic_set(&work->pending, 1); - } - trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end); /* We're still in the vblank-evade critical section, this can't race. -- 2.30.2