aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2016-05-17 09:07:47 -0400
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2016-05-19 08:36:59 -0400
commit5251f04e0c91de058531c658068939e91a29e035 (patch)
treed187f5707757431c9918514aec9b7a1003b3daeb /drivers/gpu/drm/i915
parentef58319d3fcf90050ac417e918b0c1e6373863bd (diff)
drm/i915: Remove intel_prepare_page_flip, v3.
Instead of calling prepare_flip right before calling finish_page_flip do everything from prepare_page_flip in finish_page_flip. Putting prepare and finish page_flip in a single step removes the need for INTEL_FLIP_COMPLETE, so it can be removed. This simplifies the code slightly. Changes since v1: - Invert if case to simplify code. - Add missing barrier. - Reword commit message. Changes since v2: - intel_page_flip_plane is removed. - work->pending is turned into a bool. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1463490484-19540-5-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c5
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c18
-rw-r--r--drivers/gpu/drm/i915/intel_display.c72
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h4
4 files changed, 26 insertions, 73 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index f23b119a365d..6bff6b4daf99 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -619,12 +619,9 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
619 u32 addr; 619 u32 addr;
620 620
621 pending = atomic_read(&work->pending); 621 pending = atomic_read(&work->pending);
622 if (pending == INTEL_FLIP_INACTIVE) { 622 if (pending) {
623 seq_printf(m, "Flip ioctl preparing on pipe %c (plane %c)\n", 623 seq_printf(m, "Flip ioctl preparing on pipe %c (plane %c)\n",
624 pipe, plane); 624 pipe, plane);
625 } else if (pending >= INTEL_FLIP_COMPLETE) {
626 seq_printf(m, "Flip queued on pipe %c (plane %c)\n",
627 pipe, plane);
628 } else { 625 } else {
629 seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n", 626 seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n",
630 pipe, plane); 627 pipe, plane);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 920a5e4abb70..148741646fb0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1705,10 +1705,8 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
1705 intel_pipe_handle_vblank(dev_priv, pipe)) 1705 intel_pipe_handle_vblank(dev_priv, pipe))
1706 intel_check_page_flip(dev_priv, pipe); 1706 intel_check_page_flip(dev_priv, pipe);
1707 1707
1708 if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV) { 1708 if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV)
1709 intel_prepare_page_flip(dev_priv, pipe);
1710 intel_finish_page_flip(dev_priv, pipe); 1709 intel_finish_page_flip(dev_priv, pipe);
1711 }
1712 1710
1713 if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) 1711 if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
1714 i9xx_pipe_crc_irq_handler(dev_priv, pipe); 1712 i9xx_pipe_crc_irq_handler(dev_priv, pipe);
@@ -2162,10 +2160,8 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
2162 i9xx_pipe_crc_irq_handler(dev_priv, pipe); 2160 i9xx_pipe_crc_irq_handler(dev_priv, pipe);
2163 2161
2164 /* plane/pipes map 1:1 on ilk+ */ 2162 /* plane/pipes map 1:1 on ilk+ */
2165 if (de_iir & DE_PLANE_FLIP_DONE(pipe)) { 2163 if (de_iir & DE_PLANE_FLIP_DONE(pipe))
2166 intel_prepare_page_flip(dev_priv, pipe);
2167 intel_finish_page_flip(dev_priv, pipe); 2164 intel_finish_page_flip(dev_priv, pipe);
2168 }
2169 } 2165 }
2170 2166
2171 /* check event from PCH */ 2167 /* check event from PCH */
@@ -2209,10 +2205,8 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
2209 intel_check_page_flip(dev_priv, pipe); 2205 intel_check_page_flip(dev_priv, pipe);
2210 2206
2211 /* plane/pipes map 1:1 on ilk+ */ 2207 /* plane/pipes map 1:1 on ilk+ */
2212 if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe)) { 2208 if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe))
2213 intel_prepare_page_flip(dev_priv, pipe);
2214 intel_finish_page_flip(dev_priv, pipe); 2209 intel_finish_page_flip(dev_priv, pipe);
2215 }
2216 } 2210 }
2217 2211
2218 /* check event from PCH */ 2212 /* check event from PCH */
@@ -2417,10 +2411,8 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
2417 else 2411 else
2418 flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE; 2412 flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE;
2419 2413
2420 if (flip_done) { 2414 if (flip_done)
2421 intel_prepare_page_flip(dev_priv, pipe);
2422 intel_finish_page_flip(dev_priv, pipe); 2415 intel_finish_page_flip(dev_priv, pipe);
2423 }
2424 2416
2425 if (iir & GEN8_PIPE_CDCLK_CRC_DONE) 2417 if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
2426 hsw_pipe_crc_irq_handler(dev_priv, pipe); 2418 hsw_pipe_crc_irq_handler(dev_priv, pipe);
@@ -3998,7 +3990,6 @@ static bool i8xx_handle_vblank(struct drm_i915_private *dev_priv,
3998 if (I915_READ16(ISR) & flip_pending) 3990 if (I915_READ16(ISR) & flip_pending)
3999 goto check_page_flip; 3991 goto check_page_flip;
4000 3992
4001 intel_prepare_page_flip(dev_priv, plane);
4002 intel_finish_page_flip(dev_priv, pipe); 3993 intel_finish_page_flip(dev_priv, pipe);
4003 return true; 3994 return true;
4004 3995
@@ -4188,7 +4179,6 @@ static bool i915_handle_vblank(struct drm_i915_private *dev_priv,
4188 if (I915_READ(ISR) & flip_pending) 4179 if (I915_READ(ISR) & flip_pending)
4189 goto check_page_flip; 4180 goto check_page_flip;
4190 4181
4191 intel_prepare_page_flip(dev_priv, plane);
4192 intel_finish_page_flip(dev_priv, pipe); 4182 intel_finish_page_flip(dev_priv, pipe);
4193 return true; 4183 return true;
4194 4184
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a298b8d137bf..ca2f51be8ef9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3112,10 +3112,8 @@ static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
3112{ 3112{
3113 struct intel_crtc *crtc; 3113 struct intel_crtc *crtc;
3114 3114
3115 for_each_intel_crtc(dev_priv->dev, crtc) { 3115 for_each_intel_crtc(dev_priv->dev, crtc)
3116 intel_prepare_page_flip(dev_priv, crtc->plane);
3117 intel_finish_page_flip(dev_priv, crtc->pipe); 3116 intel_finish_page_flip(dev_priv, crtc->pipe);
3118 }
3119} 3117}
3120 3118
3121static void intel_update_primary_planes(struct drm_device *dev) 3119static void intel_update_primary_planes(struct drm_device *dev)
@@ -10866,42 +10864,6 @@ static void intel_unpin_work_fn(struct work_struct *__work)
10866 kfree(work); 10864 kfree(work);
10867} 10865}
10868 10866
10869static void do_intel_finish_page_flip(struct drm_i915_private *dev_priv,
10870 struct drm_crtc *crtc)
10871{
10872 struct drm_device *dev = dev_priv->dev;
10873 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
10874 struct intel_unpin_work *work;
10875 unsigned long flags;
10876
10877 /* Ignore early vblank irqs */
10878 if (intel_crtc == NULL)
10879 return;
10880
10881 /*
10882 * This is called both by irq handlers and the reset code (to complete
10883 * lost pageflips) so needs the full irqsave spinlocks.
10884 */
10885 spin_lock_irqsave(&dev->event_lock, flags);
10886 work = intel_crtc->unpin_work;
10887
10888 if (work && atomic_read(&work->pending) >= INTEL_FLIP_COMPLETE) {
10889 /* ensure that the unpin work is consistent wrt ->pending. */
10890 smp_rmb();
10891
10892 page_flip_completed(intel_crtc);
10893 }
10894
10895 spin_unlock_irqrestore(&dev->event_lock, flags);
10896}
10897
10898void intel_finish_page_flip(struct drm_i915_private *dev_priv, int pipe)
10899{
10900 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
10901
10902 do_intel_finish_page_flip(dev_priv, crtc);
10903}
10904
10905/* Is 'a' after or equal to 'b'? */ 10867/* Is 'a' after or equal to 'b'? */
10906static bool g4x_flip_count_after_eq(u32 a, u32 b) 10868static bool g4x_flip_count_after_eq(u32 a, u32 b)
10907{ 10869{
@@ -10914,6 +10876,9 @@ static bool page_flip_finished(struct intel_crtc *crtc)
10914 struct drm_i915_private *dev_priv = dev->dev_private; 10876 struct drm_i915_private *dev_priv = dev->dev_private;
10915 unsigned reset_counter; 10877 unsigned reset_counter;
10916 10878
10879 /* ensure that the unpin work is consistent wrt ->pending. */
10880 smp_rmb();
10881
10917 reset_counter = i915_reset_counter(&dev_priv->gpu_error); 10882 reset_counter = i915_reset_counter(&dev_priv->gpu_error);
10918 if (crtc->reset_counter != reset_counter) 10883 if (crtc->reset_counter != reset_counter)
10919 return true; 10884 return true;
@@ -10955,25 +10920,30 @@ static bool page_flip_finished(struct intel_crtc *crtc)
10955 crtc->unpin_work->flip_count); 10920 crtc->unpin_work->flip_count);
10956} 10921}
10957 10922
10958void intel_prepare_page_flip(struct drm_i915_private *dev_priv, int plane) 10923void intel_finish_page_flip(struct drm_i915_private *dev_priv, int pipe)
10959{ 10924{
10960 struct drm_device *dev = dev_priv->dev; 10925 struct drm_device *dev = dev_priv->dev;
10961 struct intel_crtc *intel_crtc = 10926 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
10962 to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]); 10927 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
10928 struct intel_unpin_work *work;
10963 unsigned long flags; 10929 unsigned long flags;
10964 10930
10931 /* Ignore early vblank irqs */
10932 if (!crtc)
10933 return;
10965 10934
10966 /* 10935 /*
10967 * This is called both by irq handlers and the reset code (to complete 10936 * This is called both by irq handlers and the reset code (to complete
10968 * lost pageflips) so needs the full irqsave spinlocks. 10937 * lost pageflips) so needs the full irqsave spinlocks.
10969 *
10970 * NB: An MMIO update of the plane base pointer will also
10971 * generate a page-flip completion irq, i.e. every modeset
10972 * is also accompanied by a spurious intel_prepare_page_flip().
10973 */ 10938 */
10974 spin_lock_irqsave(&dev->event_lock, flags); 10939 spin_lock_irqsave(&dev->event_lock, flags);
10975 if (intel_crtc->unpin_work && page_flip_finished(intel_crtc)) 10940 work = intel_crtc->unpin_work;
10976 atomic_inc_not_zero(&intel_crtc->unpin_work->pending); 10941
10942 if (work != NULL &&
10943 atomic_read(&work->pending) &&
10944 page_flip_finished(intel_crtc))
10945 page_flip_completed(intel_crtc);
10946
10977 spin_unlock_irqrestore(&dev->event_lock, flags); 10947 spin_unlock_irqrestore(&dev->event_lock, flags);
10978} 10948}
10979 10949
@@ -10981,7 +10951,7 @@ static inline void intel_mark_page_flip_active(struct intel_unpin_work *work)
10981{ 10951{
10982 /* Ensure that the work item is consistent when activating it ... */ 10952 /* Ensure that the work item is consistent when activating it ... */
10983 smp_mb__before_atomic(); 10953 smp_mb__before_atomic();
10984 atomic_set(&work->pending, INTEL_FLIP_PENDING); 10954 atomic_set(&work->pending, 1);
10985} 10955}
10986 10956
10987static int intel_gen2_queue_flip(struct drm_device *dev, 10957static int intel_gen2_queue_flip(struct drm_device *dev,
@@ -11421,8 +11391,8 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
11421 /* ensure that the unpin work is consistent wrt ->pending. */ 11391 /* ensure that the unpin work is consistent wrt ->pending. */
11422 smp_rmb(); 11392 smp_rmb();
11423 11393
11424 if (pending != INTEL_FLIP_PENDING) 11394 if (!pending)
11425 return pending == INTEL_FLIP_COMPLETE; 11395 return false;
11426 11396
11427 if (work->flip_ready_vblank == 0) { 11397 if (work->flip_ready_vblank == 0) {
11428 if (work->flip_queued_req && 11398 if (work->flip_queued_req &&
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ff268567cc0e..4541aa3f2943 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -984,9 +984,6 @@ struct intel_unpin_work {
984 struct drm_i915_gem_object *pending_flip_obj; 984 struct drm_i915_gem_object *pending_flip_obj;
985 struct drm_pending_vblank_event *event; 985 struct drm_pending_vblank_event *event;
986 atomic_t pending; 986 atomic_t pending;
987#define INTEL_FLIP_INACTIVE 0
988#define INTEL_FLIP_PENDING 1
989#define INTEL_FLIP_COMPLETE 2
990 u32 flip_count; 987 u32 flip_count;
991 u32 gtt_offset; 988 u32 gtt_offset;
992 struct drm_i915_gem_request *flip_queued_req; 989 struct drm_i915_gem_request *flip_queued_req;
@@ -1199,7 +1196,6 @@ struct drm_framebuffer *
1199__intel_framebuffer_create(struct drm_device *dev, 1196__intel_framebuffer_create(struct drm_device *dev,
1200 struct drm_mode_fb_cmd2 *mode_cmd, 1197 struct drm_mode_fb_cmd2 *mode_cmd,
1201 struct drm_i915_gem_object *obj); 1198 struct drm_i915_gem_object *obj);
1202void intel_prepare_page_flip(struct drm_i915_private *dev_priv, int plane);
1203void intel_finish_page_flip(struct drm_i915_private *dev_priv, int pipe); 1199void intel_finish_page_flip(struct drm_i915_private *dev_priv, int pipe);
1204void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe); 1200void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe);
1205int intel_prepare_plane_fb(struct drm_plane *plane, 1201int intel_prepare_plane_fb(struct drm_plane *plane,