aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c4
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c16
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c29
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
6 files changed, 46 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 84ce95602f00..4d59710c717e 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1408,6 +1408,10 @@ static int i915_load_modeset_init(struct drm_device *dev,
1408 if (ret) 1408 if (ret)
1409 goto destroy_ringbuffer; 1409 goto destroy_ringbuffer;
1410 1410
1411 /* IIR "flip pending" bit means done if this bit is set */
1412 if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE))
1413 dev_priv->flip_pending_is_done = true;
1414
1411 intel_modeset_init(dev); 1415 intel_modeset_init(dev);
1412 1416
1413 ret = drm_irq_install(dev); 1417 ret = drm_irq_install(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f3f681fca76a..21e217dd48ef 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -595,6 +595,7 @@ typedef struct drm_i915_private {
595 struct drm_crtc *plane_to_crtc_mapping[2]; 595 struct drm_crtc *plane_to_crtc_mapping[2];
596 struct drm_crtc *pipe_to_crtc_mapping[2]; 596 struct drm_crtc *pipe_to_crtc_mapping[2];
597 wait_queue_head_t pending_flip_queue; 597 wait_queue_head_t pending_flip_queue;
598 bool flip_pending_is_done;
598 599
599 /* Reclocking support */ 600 /* Reclocking support */
600 bool render_reclock_avail; 601 bool render_reclock_avail;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e9710a7005d4..70e1e4b66744 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -940,22 +940,30 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
940 if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) 940 if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT))
941 DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); 941 DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
942 942
943 if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) 943 if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) {
944 intel_prepare_page_flip(dev, 0); 944 intel_prepare_page_flip(dev, 0);
945 if (dev_priv->flip_pending_is_done)
946 intel_finish_page_flip_plane(dev, 0);
947 }
945 948
946 if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) 949 if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) {
950 if (dev_priv->flip_pending_is_done)
951 intel_finish_page_flip_plane(dev, 1);
947 intel_prepare_page_flip(dev, 1); 952 intel_prepare_page_flip(dev, 1);
953 }
948 954
949 if (pipea_stats & vblank_status) { 955 if (pipea_stats & vblank_status) {
950 vblank++; 956 vblank++;
951 drm_handle_vblank(dev, 0); 957 drm_handle_vblank(dev, 0);
952 intel_finish_page_flip(dev, 0); 958 if (!dev_priv->flip_pending_is_done)
959 intel_finish_page_flip(dev, 0);
953 } 960 }
954 961
955 if (pipeb_stats & vblank_status) { 962 if (pipeb_stats & vblank_status) {
956 vblank++; 963 vblank++;
957 drm_handle_vblank(dev, 1); 964 drm_handle_vblank(dev, 1);
958 intel_finish_page_flip(dev, 1); 965 if (!dev_priv->flip_pending_is_done)
966 intel_finish_page_flip(dev, 1);
959 } 967 }
960 968
961 if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || 969 if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 64b0a3afd92b..2cae38a57247 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -178,6 +178,7 @@
178#define MI_OVERLAY_OFF (0x2<<21) 178#define MI_OVERLAY_OFF (0x2<<21)
179#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) 179#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
180#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) 180#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
181#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1)
181#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) 182#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
182#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) 183#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
183#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ 184#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
@@ -368,6 +369,9 @@
368#define CM0_RC_OP_FLUSH_DISABLE (1<<0) 369#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
369#define BB_ADDR 0x02140 /* 8 bytes */ 370#define BB_ADDR 0x02140 /* 8 bytes */
370#define GFX_FLSH_CNTL 0x02170 /* 915+ only */ 371#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
372#define ECOSKPD 0x021d0
373#define ECO_GATING_CX_ONLY (1<<3)
374#define ECO_FLIP_DONE (1<<0)
371 375
372/* GEN6 interrupt control */ 376/* GEN6 interrupt control */
373#define GEN6_RENDER_HWSTAM 0x2098 377#define GEN6_RENDER_HWSTAM 0x2098
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index dc65a1de5f02..6db778a75e42 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4603,10 +4603,10 @@ static void intel_unpin_work_fn(struct work_struct *__work)
4603 kfree(work); 4603 kfree(work);
4604} 4604}
4605 4605
4606void intel_finish_page_flip(struct drm_device *dev, int pipe) 4606static void do_intel_finish_page_flip(struct drm_device *dev,
4607 struct drm_crtc *crtc)
4607{ 4608{
4608 drm_i915_private_t *dev_priv = dev->dev_private; 4609 drm_i915_private_t *dev_priv = dev->dev_private;
4609 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
4610 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 4610 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4611 struct intel_unpin_work *work; 4611 struct intel_unpin_work *work;
4612 struct drm_i915_gem_object *obj_priv; 4612 struct drm_i915_gem_object *obj_priv;
@@ -4650,6 +4650,22 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
4650 schedule_work(&work->work); 4650 schedule_work(&work->work);
4651} 4651}
4652 4652
4653void intel_finish_page_flip(struct drm_device *dev, int pipe)
4654{
4655 drm_i915_private_t *dev_priv = dev->dev_private;
4656 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
4657
4658 do_intel_finish_page_flip(dev, crtc);
4659}
4660
4661void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
4662{
4663 drm_i915_private_t *dev_priv = dev->dev_private;
4664 struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
4665
4666 do_intel_finish_page_flip(dev, crtc);
4667}
4668
4653void intel_prepare_page_flip(struct drm_device *dev, int plane) 4669void intel_prepare_page_flip(struct drm_device *dev, int plane)
4654{ 4670{
4655 drm_i915_private_t *dev_priv = dev->dev_private; 4671 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -4745,14 +4761,17 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4745 ; 4761 ;
4746 4762
4747 BEGIN_LP_RING(4); 4763 BEGIN_LP_RING(4);
4748 OUT_RING(MI_DISPLAY_FLIP |
4749 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4750 OUT_RING(fb->pitch);
4751 if (IS_I965G(dev)) { 4764 if (IS_I965G(dev)) {
4765 OUT_RING(MI_DISPLAY_FLIP |
4766 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4767 OUT_RING(fb->pitch);
4752 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); 4768 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
4753 pipesrc = I915_READ(pipesrc_reg); 4769 pipesrc = I915_READ(pipesrc_reg);
4754 OUT_RING(pipesrc & 0x0fff0fff); 4770 OUT_RING(pipesrc & 0x0fff0fff);
4755 } else { 4771 } else {
4772 OUT_RING(MI_DISPLAY_FLIP_I915 |
4773 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4774 OUT_RING(fb->pitch);
4756 OUT_RING(obj_priv->gtt_offset); 4775 OUT_RING(obj_priv->gtt_offset);
4757 OUT_RING(MI_NOOP); 4776 OUT_RING(MI_NOOP);
4758 } 4777 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index df931f787665..72206f37c4fb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -224,6 +224,7 @@ extern void intel_fbdev_fini(struct drm_device *dev);
224 224
225extern void intel_prepare_page_flip(struct drm_device *dev, int plane); 225extern void intel_prepare_page_flip(struct drm_device *dev, int plane);
226extern void intel_finish_page_flip(struct drm_device *dev, int pipe); 226extern void intel_finish_page_flip(struct drm_device *dev, int pipe);
227extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
227 228
228extern void intel_setup_overlay(struct drm_device *dev); 229extern void intel_setup_overlay(struct drm_device *dev);
229extern void intel_cleanup_overlay(struct drm_device *dev); 230extern void intel_cleanup_overlay(struct drm_device *dev);