diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 60 |
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 | ||
| 4604 | void intel_finish_page_flip(struct drm_device *dev, int pipe) | 4608 | static 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 | ||
| 4655 | void 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 | |||
| 4663 | void 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 | |||
| 4651 | void intel_prepare_page_flip(struct drm_device *dev, int plane) | 4671 | void 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 | } |
