diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 29 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 1 |
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 | ||
| 4606 | void intel_finish_page_flip(struct drm_device *dev, int pipe) | 4606 | static 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 | ||
| 4653 | void 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 | |||
| 4661 | void 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 | |||
| 4653 | void intel_prepare_page_flip(struct drm_device *dev, int plane) | 4669 | void 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 | ||
| 225 | extern void intel_prepare_page_flip(struct drm_device *dev, int plane); | 225 | extern void intel_prepare_page_flip(struct drm_device *dev, int plane); |
| 226 | extern void intel_finish_page_flip(struct drm_device *dev, int pipe); | 226 | extern void intel_finish_page_flip(struct drm_device *dev, int pipe); |
| 227 | extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane); | ||
| 227 | 228 | ||
| 228 | extern void intel_setup_overlay(struct drm_device *dev); | 229 | extern void intel_setup_overlay(struct drm_device *dev); |
| 229 | extern void intel_cleanup_overlay(struct drm_device *dev); | 230 | extern void intel_cleanup_overlay(struct drm_device *dev); |
