aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cc8131ff319f..68dcf36e2793 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2970,11 +2970,13 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock,
2970 if (srwm < 0) 2970 if (srwm < 0)
2971 srwm = 1; 2971 srwm = 1;
2972 srwm &= 0x3f; 2972 srwm &= 0x3f;
2973 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); 2973 if (IS_I965GM(dev))
2974 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
2974 } else { 2975 } else {
2975 /* Turn off self refresh if both pipes are enabled */ 2976 /* Turn off self refresh if both pipes are enabled */
2976 I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) 2977 if (IS_I965GM(dev))
2977 & ~FW_BLC_SELF_EN); 2978 I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
2979 & ~FW_BLC_SELF_EN);
2978 } 2980 }
2979 2981
2980 DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", 2982 DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
@@ -4483,6 +4485,7 @@ static void intel_idle_update(struct work_struct *work)
4483 struct drm_device *dev = dev_priv->dev; 4485 struct drm_device *dev = dev_priv->dev;
4484 struct drm_crtc *crtc; 4486 struct drm_crtc *crtc;
4485 struct intel_crtc *intel_crtc; 4487 struct intel_crtc *intel_crtc;
4488 int enabled = 0;
4486 4489
4487 if (!i915_powersave) 4490 if (!i915_powersave)
4488 return; 4491 return;
@@ -4491,21 +4494,22 @@ static void intel_idle_update(struct work_struct *work)
4491 4494
4492 i915_update_gfx_val(dev_priv); 4495 i915_update_gfx_val(dev_priv);
4493 4496
4494 if (IS_I945G(dev) || IS_I945GM(dev)) {
4495 DRM_DEBUG_DRIVER("enable memory self refresh on 945\n");
4496 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
4497 }
4498
4499 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 4497 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
4500 /* Skip inactive CRTCs */ 4498 /* Skip inactive CRTCs */
4501 if (!crtc->fb) 4499 if (!crtc->fb)
4502 continue; 4500 continue;
4503 4501
4502 enabled++;
4504 intel_crtc = to_intel_crtc(crtc); 4503 intel_crtc = to_intel_crtc(crtc);
4505 if (!intel_crtc->busy) 4504 if (!intel_crtc->busy)
4506 intel_decrease_pllclock(crtc); 4505 intel_decrease_pllclock(crtc);
4507 } 4506 }
4508 4507
4508 if ((enabled == 1) && (IS_I945G(dev) || IS_I945GM(dev))) {
4509 DRM_DEBUG_DRIVER("enable memory self refresh on 945\n");
4510 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
4511 }
4512
4509 mutex_unlock(&dev->struct_mutex); 4513 mutex_unlock(&dev->struct_mutex);
4510} 4514}
4511 4515
@@ -4601,10 +4605,10 @@ static void intel_unpin_work_fn(struct work_struct *__work)
4601 kfree(work); 4605 kfree(work);
4602} 4606}
4603 4607
4604void intel_finish_page_flip(struct drm_device *dev, int pipe) 4608static void do_intel_finish_page_flip(struct drm_device *dev,
4609 struct drm_crtc *crtc)
4605{ 4610{
4606 drm_i915_private_t *dev_priv = dev->dev_private; 4611 drm_i915_private_t *dev_priv = dev->dev_private;
4607 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
4608 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 4612 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4609 struct intel_unpin_work *work; 4613 struct intel_unpin_work *work;
4610 struct drm_i915_gem_object *obj_priv; 4614 struct drm_i915_gem_object *obj_priv;
@@ -4648,6 +4652,22 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
4648 schedule_work(&work->work); 4652 schedule_work(&work->work);
4649} 4653}
4650 4654
4655void intel_finish_page_flip(struct drm_device *dev, int pipe)
4656{
4657 drm_i915_private_t *dev_priv = dev->dev_private;
4658 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
4659
4660 do_intel_finish_page_flip(dev, crtc);
4661}
4662
4663void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
4664{
4665 drm_i915_private_t *dev_priv = dev->dev_private;
4666 struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
4667
4668 do_intel_finish_page_flip(dev, crtc);
4669}
4670
4651void intel_prepare_page_flip(struct drm_device *dev, int plane) 4671void intel_prepare_page_flip(struct drm_device *dev, int plane)
4652{ 4672{
4653 drm_i915_private_t *dev_priv = dev->dev_private; 4673 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -4678,6 +4698,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4678 unsigned long flags; 4698 unsigned long flags;
4679 int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; 4699 int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
4680 int ret, pipesrc; 4700 int ret, pipesrc;
4701 u32 flip_mask;
4681 4702
4682 work = kzalloc(sizeof *work, GFP_KERNEL); 4703 work = kzalloc(sizeof *work, GFP_KERNEL);
4683 if (work == NULL) 4704 if (work == NULL)
@@ -4731,15 +4752,28 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4731 atomic_inc(&obj_priv->pending_flip); 4752 atomic_inc(&obj_priv->pending_flip);
4732 work->pending_flip_obj = obj; 4753 work->pending_flip_obj = obj;
4733 4754
4755 if (intel_crtc->plane)
4756 flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
4757 else
4758 flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
4759
4760 /* Wait for any previous flip to finish */
4761 if (IS_GEN3(dev))
4762 while (I915_READ(ISR) & flip_mask)
4763 ;
4764
4734 BEGIN_LP_RING(4); 4765 BEGIN_LP_RING(4);
4735 OUT_RING(MI_DISPLAY_FLIP |
4736 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4737 OUT_RING(fb->pitch);
4738 if (IS_I965G(dev)) { 4766 if (IS_I965G(dev)) {
4767 OUT_RING(MI_DISPLAY_FLIP |
4768 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4769 OUT_RING(fb->pitch);
4739 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); 4770 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
4740 pipesrc = I915_READ(pipesrc_reg); 4771 pipesrc = I915_READ(pipesrc_reg);
4741 OUT_RING(pipesrc & 0x0fff0fff); 4772 OUT_RING(pipesrc & 0x0fff0fff);
4742 } else { 4773 } else {
4774 OUT_RING(MI_DISPLAY_FLIP_I915 |
4775 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4776 OUT_RING(fb->pitch);
4743 OUT_RING(obj_priv->gtt_offset); 4777 OUT_RING(obj_priv->gtt_offset);
4744 OUT_RING(MI_NOOP); 4778 OUT_RING(MI_NOOP);
4745 } 4779 }