diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 281 |
1 files changed, 217 insertions, 64 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f469a84cacfd..88a1ab7c05ce 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1029,19 +1029,28 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1029 | void i8xx_disable_fbc(struct drm_device *dev) | 1029 | void i8xx_disable_fbc(struct drm_device *dev) |
1030 | { | 1030 | { |
1031 | struct drm_i915_private *dev_priv = dev->dev_private; | 1031 | struct drm_i915_private *dev_priv = dev->dev_private; |
1032 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
1032 | u32 fbc_ctl; | 1033 | u32 fbc_ctl; |
1033 | 1034 | ||
1034 | if (!I915_HAS_FBC(dev)) | 1035 | if (!I915_HAS_FBC(dev)) |
1035 | return; | 1036 | return; |
1036 | 1037 | ||
1038 | if (!(I915_READ(FBC_CONTROL) & FBC_CTL_EN)) | ||
1039 | return; /* Already off, just return */ | ||
1040 | |||
1037 | /* Disable compression */ | 1041 | /* Disable compression */ |
1038 | fbc_ctl = I915_READ(FBC_CONTROL); | 1042 | fbc_ctl = I915_READ(FBC_CONTROL); |
1039 | fbc_ctl &= ~FBC_CTL_EN; | 1043 | fbc_ctl &= ~FBC_CTL_EN; |
1040 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1044 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
1041 | 1045 | ||
1042 | /* Wait for compressing bit to clear */ | 1046 | /* Wait for compressing bit to clear */ |
1043 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) | 1047 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { |
1044 | ; /* nothing */ | 1048 | if (time_after(jiffies, timeout)) { |
1049 | DRM_DEBUG_DRIVER("FBC idle timed out\n"); | ||
1050 | break; | ||
1051 | } | ||
1052 | ; /* do nothing */ | ||
1053 | } | ||
1045 | 1054 | ||
1046 | intel_wait_for_vblank(dev); | 1055 | intel_wait_for_vblank(dev); |
1047 | 1056 | ||
@@ -1239,10 +1248,11 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1239 | return; | 1248 | return; |
1240 | 1249 | ||
1241 | out_disable: | 1250 | out_disable: |
1242 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | ||
1243 | /* Multiple disables should be harmless */ | 1251 | /* Multiple disables should be harmless */ |
1244 | if (intel_fbc_enabled(dev)) | 1252 | if (intel_fbc_enabled(dev)) { |
1253 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | ||
1245 | intel_disable_fbc(dev); | 1254 | intel_disable_fbc(dev); |
1255 | } | ||
1246 | } | 1256 | } |
1247 | 1257 | ||
1248 | static int | 1258 | static int |
@@ -1386,7 +1396,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1386 | Start = obj_priv->gtt_offset; | 1396 | Start = obj_priv->gtt_offset; |
1387 | Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); | 1397 | Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); |
1388 | 1398 | ||
1389 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); | 1399 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
1400 | Start, Offset, x, y, crtc->fb->pitch); | ||
1390 | I915_WRITE(dspstride, crtc->fb->pitch); | 1401 | I915_WRITE(dspstride, crtc->fb->pitch); |
1391 | if (IS_I965G(dev)) { | 1402 | if (IS_I965G(dev)) { |
1392 | I915_WRITE(dspbase, Offset); | 1403 | I915_WRITE(dspbase, Offset); |
@@ -2345,6 +2356,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | |||
2345 | if (mode->clock * 3 > 27000 * 4) | 2356 | if (mode->clock * 3 > 27000 * 4) |
2346 | return MODE_CLOCK_HIGH; | 2357 | return MODE_CLOCK_HIGH; |
2347 | } | 2358 | } |
2359 | |||
2360 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
2348 | return true; | 2361 | return true; |
2349 | } | 2362 | } |
2350 | 2363 | ||
@@ -2629,6 +2642,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
2629 | 2642 | ||
2630 | struct cxsr_latency { | 2643 | struct cxsr_latency { |
2631 | int is_desktop; | 2644 | int is_desktop; |
2645 | int is_ddr3; | ||
2632 | unsigned long fsb_freq; | 2646 | unsigned long fsb_freq; |
2633 | unsigned long mem_freq; | 2647 | unsigned long mem_freq; |
2634 | unsigned long display_sr; | 2648 | unsigned long display_sr; |
@@ -2638,33 +2652,45 @@ struct cxsr_latency { | |||
2638 | }; | 2652 | }; |
2639 | 2653 | ||
2640 | static struct cxsr_latency cxsr_latency_table[] = { | 2654 | static struct cxsr_latency cxsr_latency_table[] = { |
2641 | {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | 2655 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ |
2642 | {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | 2656 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ |
2643 | {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | 2657 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ |
2644 | 2658 | {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */ | |
2645 | {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | 2659 | {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */ |
2646 | {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | 2660 | |
2647 | {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | 2661 | {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ |
2648 | 2662 | {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | |
2649 | {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | 2663 | {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ |
2650 | {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | 2664 | {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */ |
2651 | {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | 2665 | {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */ |
2652 | 2666 | ||
2653 | {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | 2667 | {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ |
2654 | {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | 2668 | {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ |
2655 | {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | 2669 | {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ |
2656 | 2670 | {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */ | |
2657 | {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | 2671 | {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */ |
2658 | {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | 2672 | |
2659 | {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | 2673 | {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ |
2660 | 2674 | {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | |
2661 | {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | 2675 | {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ |
2662 | {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | 2676 | {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */ |
2663 | {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | 2677 | {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */ |
2678 | |||
2679 | {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
2680 | {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
2681 | {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
2682 | {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */ | ||
2683 | {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */ | ||
2684 | |||
2685 | {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
2686 | {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
2687 | {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
2688 | {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */ | ||
2689 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | ||
2664 | }; | 2690 | }; |
2665 | 2691 | ||
2666 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | 2692 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, |
2667 | int mem) | 2693 | int fsb, int mem) |
2668 | { | 2694 | { |
2669 | int i; | 2695 | int i; |
2670 | struct cxsr_latency *latency; | 2696 | struct cxsr_latency *latency; |
@@ -2675,6 +2701,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | |||
2675 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | 2701 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { |
2676 | latency = &cxsr_latency_table[i]; | 2702 | latency = &cxsr_latency_table[i]; |
2677 | if (is_desktop == latency->is_desktop && | 2703 | if (is_desktop == latency->is_desktop && |
2704 | is_ddr3 == latency->is_ddr3 && | ||
2678 | fsb == latency->fsb_freq && mem == latency->mem_freq) | 2705 | fsb == latency->fsb_freq && mem == latency->mem_freq) |
2679 | return latency; | 2706 | return latency; |
2680 | } | 2707 | } |
@@ -2789,8 +2816,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
2789 | struct cxsr_latency *latency; | 2816 | struct cxsr_latency *latency; |
2790 | int sr_clock; | 2817 | int sr_clock; |
2791 | 2818 | ||
2792 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq, | 2819 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
2793 | dev_priv->mem_freq); | 2820 | dev_priv->fsb_freq, dev_priv->mem_freq); |
2794 | if (!latency) { | 2821 | if (!latency) { |
2795 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | 2822 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
2796 | pineview_disable_cxsr(dev); | 2823 | pineview_disable_cxsr(dev); |
@@ -3772,6 +3799,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3772 | } | 3799 | } |
3773 | } | 3800 | } |
3774 | 3801 | ||
3802 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { | ||
3803 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; | ||
3804 | /* the chip adds 2 halflines automatically */ | ||
3805 | adjusted_mode->crtc_vdisplay -= 1; | ||
3806 | adjusted_mode->crtc_vtotal -= 1; | ||
3807 | adjusted_mode->crtc_vblank_start -= 1; | ||
3808 | adjusted_mode->crtc_vblank_end -= 1; | ||
3809 | adjusted_mode->crtc_vsync_end -= 1; | ||
3810 | adjusted_mode->crtc_vsync_start -= 1; | ||
3811 | } else | ||
3812 | pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ | ||
3813 | |||
3775 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 3814 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
3776 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 3815 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
3777 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | | 3816 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | |
@@ -4436,6 +4475,8 @@ static void intel_idle_update(struct work_struct *work) | |||
4436 | 4475 | ||
4437 | mutex_lock(&dev->struct_mutex); | 4476 | mutex_lock(&dev->struct_mutex); |
4438 | 4477 | ||
4478 | i915_update_gfx_val(dev_priv); | ||
4479 | |||
4439 | if (IS_I945G(dev) || IS_I945GM(dev)) { | 4480 | if (IS_I945G(dev) || IS_I945GM(dev)) { |
4440 | DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); | 4481 | DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); |
4441 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); | 4482 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); |
@@ -4564,12 +4605,6 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) | |||
4564 | spin_lock_irqsave(&dev->event_lock, flags); | 4605 | spin_lock_irqsave(&dev->event_lock, flags); |
4565 | work = intel_crtc->unpin_work; | 4606 | work = intel_crtc->unpin_work; |
4566 | if (work == NULL || !work->pending) { | 4607 | if (work == NULL || !work->pending) { |
4567 | if (work && !work->pending) { | ||
4568 | obj_priv = to_intel_bo(work->pending_flip_obj); | ||
4569 | DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", | ||
4570 | obj_priv, | ||
4571 | atomic_read(&obj_priv->pending_flip)); | ||
4572 | } | ||
4573 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4608 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4574 | return; | 4609 | return; |
4575 | } | 4610 | } |
@@ -4629,14 +4664,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4629 | unsigned long flags; | 4664 | unsigned long flags; |
4630 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; | 4665 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; |
4631 | int ret, pipesrc; | 4666 | int ret, pipesrc; |
4632 | RING_LOCALS; | ||
4633 | 4667 | ||
4634 | work = kzalloc(sizeof *work, GFP_KERNEL); | 4668 | work = kzalloc(sizeof *work, GFP_KERNEL); |
4635 | if (work == NULL) | 4669 | if (work == NULL) |
4636 | return -ENOMEM; | 4670 | return -ENOMEM; |
4637 | 4671 | ||
4638 | mutex_lock(&dev->struct_mutex); | ||
4639 | |||
4640 | work->event = event; | 4672 | work->event = event; |
4641 | work->dev = crtc->dev; | 4673 | work->dev = crtc->dev; |
4642 | intel_fb = to_intel_framebuffer(crtc->fb); | 4674 | intel_fb = to_intel_framebuffer(crtc->fb); |
@@ -4646,10 +4678,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4646 | /* We borrow the event spin lock for protecting unpin_work */ | 4678 | /* We borrow the event spin lock for protecting unpin_work */ |
4647 | spin_lock_irqsave(&dev->event_lock, flags); | 4679 | spin_lock_irqsave(&dev->event_lock, flags); |
4648 | if (intel_crtc->unpin_work) { | 4680 | if (intel_crtc->unpin_work) { |
4649 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
4650 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4681 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4651 | kfree(work); | 4682 | kfree(work); |
4652 | mutex_unlock(&dev->struct_mutex); | 4683 | |
4684 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
4653 | return -EBUSY; | 4685 | return -EBUSY; |
4654 | } | 4686 | } |
4655 | intel_crtc->unpin_work = work; | 4687 | intel_crtc->unpin_work = work; |
@@ -4658,13 +4690,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4658 | intel_fb = to_intel_framebuffer(fb); | 4690 | intel_fb = to_intel_framebuffer(fb); |
4659 | obj = intel_fb->obj; | 4691 | obj = intel_fb->obj; |
4660 | 4692 | ||
4693 | mutex_lock(&dev->struct_mutex); | ||
4661 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 4694 | ret = intel_pin_and_fence_fb_obj(dev, obj); |
4662 | if (ret != 0) { | 4695 | if (ret != 0) { |
4663 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | ||
4664 | to_intel_bo(obj)); | ||
4665 | kfree(work); | ||
4666 | intel_crtc->unpin_work = NULL; | ||
4667 | mutex_unlock(&dev->struct_mutex); | 4696 | mutex_unlock(&dev->struct_mutex); |
4697 | |||
4698 | spin_lock_irqsave(&dev->event_lock, flags); | ||
4699 | intel_crtc->unpin_work = NULL; | ||
4700 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
4701 | |||
4702 | kfree(work); | ||
4703 | |||
4704 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | ||
4705 | to_intel_bo(obj)); | ||
4668 | return ret; | 4706 | return ret; |
4669 | } | 4707 | } |
4670 | 4708 | ||
@@ -5023,10 +5061,32 @@ err_unref: | |||
5023 | return NULL; | 5061 | return NULL; |
5024 | } | 5062 | } |
5025 | 5063 | ||
5064 | bool ironlake_set_drps(struct drm_device *dev, u8 val) | ||
5065 | { | ||
5066 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5067 | u16 rgvswctl; | ||
5068 | |||
5069 | rgvswctl = I915_READ16(MEMSWCTL); | ||
5070 | if (rgvswctl & MEMCTL_CMD_STS) { | ||
5071 | DRM_DEBUG("gpu busy, RCS change rejected\n"); | ||
5072 | return false; /* still busy with another command */ | ||
5073 | } | ||
5074 | |||
5075 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | ||
5076 | (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
5077 | I915_WRITE16(MEMSWCTL, rgvswctl); | ||
5078 | POSTING_READ16(MEMSWCTL); | ||
5079 | |||
5080 | rgvswctl |= MEMCTL_CMD_STS; | ||
5081 | I915_WRITE16(MEMSWCTL, rgvswctl); | ||
5082 | |||
5083 | return true; | ||
5084 | } | ||
5085 | |||
5026 | void ironlake_enable_drps(struct drm_device *dev) | 5086 | void ironlake_enable_drps(struct drm_device *dev) |
5027 | { | 5087 | { |
5028 | struct drm_i915_private *dev_priv = dev->dev_private; | 5088 | struct drm_i915_private *dev_priv = dev->dev_private; |
5029 | u32 rgvmodectl = I915_READ(MEMMODECTL), rgvswctl; | 5089 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
5030 | u8 fmax, fmin, fstart, vstart; | 5090 | u8 fmax, fmin, fstart, vstart; |
5031 | int i = 0; | 5091 | int i = 0; |
5032 | 5092 | ||
@@ -5045,13 +5105,21 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5045 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); | 5105 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); |
5046 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> | 5106 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> |
5047 | MEMMODE_FSTART_SHIFT; | 5107 | MEMMODE_FSTART_SHIFT; |
5108 | fstart = fmax; | ||
5109 | |||
5048 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> | 5110 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> |
5049 | PXVFREQ_PX_SHIFT; | 5111 | PXVFREQ_PX_SHIFT; |
5050 | 5112 | ||
5051 | dev_priv->max_delay = fstart; /* can't go to fmax w/o IPS */ | 5113 | dev_priv->fmax = fstart; /* IPS callback will increase this */ |
5114 | dev_priv->fstart = fstart; | ||
5115 | |||
5116 | dev_priv->max_delay = fmax; | ||
5052 | dev_priv->min_delay = fmin; | 5117 | dev_priv->min_delay = fmin; |
5053 | dev_priv->cur_delay = fstart; | 5118 | dev_priv->cur_delay = fstart; |
5054 | 5119 | ||
5120 | DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin, | ||
5121 | fstart); | ||
5122 | |||
5055 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); | 5123 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); |
5056 | 5124 | ||
5057 | /* | 5125 | /* |
@@ -5073,20 +5141,19 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5073 | } | 5141 | } |
5074 | msleep(1); | 5142 | msleep(1); |
5075 | 5143 | ||
5076 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | 5144 | ironlake_set_drps(dev, fstart); |
5077 | (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
5078 | I915_WRITE(MEMSWCTL, rgvswctl); | ||
5079 | POSTING_READ(MEMSWCTL); | ||
5080 | 5145 | ||
5081 | rgvswctl |= MEMCTL_CMD_STS; | 5146 | dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + |
5082 | I915_WRITE(MEMSWCTL, rgvswctl); | 5147 | I915_READ(0x112e0); |
5148 | dev_priv->last_time1 = jiffies_to_msecs(jiffies); | ||
5149 | dev_priv->last_count2 = I915_READ(0x112f4); | ||
5150 | getrawmonotonic(&dev_priv->last_time2); | ||
5083 | } | 5151 | } |
5084 | 5152 | ||
5085 | void ironlake_disable_drps(struct drm_device *dev) | 5153 | void ironlake_disable_drps(struct drm_device *dev) |
5086 | { | 5154 | { |
5087 | struct drm_i915_private *dev_priv = dev->dev_private; | 5155 | struct drm_i915_private *dev_priv = dev->dev_private; |
5088 | u32 rgvswctl; | 5156 | u16 rgvswctl = I915_READ16(MEMSWCTL); |
5089 | u8 fstart; | ||
5090 | 5157 | ||
5091 | /* Ack interrupts, disable EFC interrupt */ | 5158 | /* Ack interrupts, disable EFC interrupt */ |
5092 | I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); | 5159 | I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); |
@@ -5096,11 +5163,7 @@ void ironlake_disable_drps(struct drm_device *dev) | |||
5096 | I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); | 5163 | I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); |
5097 | 5164 | ||
5098 | /* Go back to the starting frequency */ | 5165 | /* Go back to the starting frequency */ |
5099 | fstart = (I915_READ(MEMMODECTL) & MEMMODE_FSTART_MASK) >> | 5166 | ironlake_set_drps(dev, dev_priv->fstart); |
5100 | MEMMODE_FSTART_SHIFT; | ||
5101 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | ||
5102 | (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
5103 | I915_WRITE(MEMSWCTL, rgvswctl); | ||
5104 | msleep(1); | 5167 | msleep(1); |
5105 | rgvswctl |= MEMCTL_CMD_STS; | 5168 | rgvswctl |= MEMCTL_CMD_STS; |
5106 | I915_WRITE(MEMSWCTL, rgvswctl); | 5169 | I915_WRITE(MEMSWCTL, rgvswctl); |
@@ -5108,6 +5171,92 @@ void ironlake_disable_drps(struct drm_device *dev) | |||
5108 | 5171 | ||
5109 | } | 5172 | } |
5110 | 5173 | ||
5174 | static unsigned long intel_pxfreq(u32 vidfreq) | ||
5175 | { | ||
5176 | unsigned long freq; | ||
5177 | int div = (vidfreq & 0x3f0000) >> 16; | ||
5178 | int post = (vidfreq & 0x3000) >> 12; | ||
5179 | int pre = (vidfreq & 0x7); | ||
5180 | |||
5181 | if (!pre) | ||
5182 | return 0; | ||
5183 | |||
5184 | freq = ((div * 133333) / ((1<<post) * pre)); | ||
5185 | |||
5186 | return freq; | ||
5187 | } | ||
5188 | |||
5189 | void intel_init_emon(struct drm_device *dev) | ||
5190 | { | ||
5191 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5192 | u32 lcfuse; | ||
5193 | u8 pxw[16]; | ||
5194 | int i; | ||
5195 | |||
5196 | /* Disable to program */ | ||
5197 | I915_WRITE(ECR, 0); | ||
5198 | POSTING_READ(ECR); | ||
5199 | |||
5200 | /* Program energy weights for various events */ | ||
5201 | I915_WRITE(SDEW, 0x15040d00); | ||
5202 | I915_WRITE(CSIEW0, 0x007f0000); | ||
5203 | I915_WRITE(CSIEW1, 0x1e220004); | ||
5204 | I915_WRITE(CSIEW2, 0x04000004); | ||
5205 | |||
5206 | for (i = 0; i < 5; i++) | ||
5207 | I915_WRITE(PEW + (i * 4), 0); | ||
5208 | for (i = 0; i < 3; i++) | ||
5209 | I915_WRITE(DEW + (i * 4), 0); | ||
5210 | |||
5211 | /* Program P-state weights to account for frequency power adjustment */ | ||
5212 | for (i = 0; i < 16; i++) { | ||
5213 | u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); | ||
5214 | unsigned long freq = intel_pxfreq(pxvidfreq); | ||
5215 | unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> | ||
5216 | PXVFREQ_PX_SHIFT; | ||
5217 | unsigned long val; | ||
5218 | |||
5219 | val = vid * vid; | ||
5220 | val *= (freq / 1000); | ||
5221 | val *= 255; | ||
5222 | val /= (127*127*900); | ||
5223 | if (val > 0xff) | ||
5224 | DRM_ERROR("bad pxval: %ld\n", val); | ||
5225 | pxw[i] = val; | ||
5226 | } | ||
5227 | /* Render standby states get 0 weight */ | ||
5228 | pxw[14] = 0; | ||
5229 | pxw[15] = 0; | ||
5230 | |||
5231 | for (i = 0; i < 4; i++) { | ||
5232 | u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | | ||
5233 | (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); | ||
5234 | I915_WRITE(PXW + (i * 4), val); | ||
5235 | } | ||
5236 | |||
5237 | /* Adjust magic regs to magic values (more experimental results) */ | ||
5238 | I915_WRITE(OGW0, 0); | ||
5239 | I915_WRITE(OGW1, 0); | ||
5240 | I915_WRITE(EG0, 0x00007f00); | ||
5241 | I915_WRITE(EG1, 0x0000000e); | ||
5242 | I915_WRITE(EG2, 0x000e0000); | ||
5243 | I915_WRITE(EG3, 0x68000300); | ||
5244 | I915_WRITE(EG4, 0x42000000); | ||
5245 | I915_WRITE(EG5, 0x00140031); | ||
5246 | I915_WRITE(EG6, 0); | ||
5247 | I915_WRITE(EG7, 0); | ||
5248 | |||
5249 | for (i = 0; i < 8; i++) | ||
5250 | I915_WRITE(PXWL + (i * 4), 0); | ||
5251 | |||
5252 | /* Enable PMON + select events */ | ||
5253 | I915_WRITE(ECR, 0x80000019); | ||
5254 | |||
5255 | lcfuse = I915_READ(LCFUSE02); | ||
5256 | |||
5257 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); | ||
5258 | } | ||
5259 | |||
5111 | void intel_init_clock_gating(struct drm_device *dev) | 5260 | void intel_init_clock_gating(struct drm_device *dev) |
5112 | { | 5261 | { |
5113 | struct drm_i915_private *dev_priv = dev->dev_private; | 5262 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -5277,11 +5426,13 @@ static void intel_init_display(struct drm_device *dev) | |||
5277 | dev_priv->display.update_wm = NULL; | 5426 | dev_priv->display.update_wm = NULL; |
5278 | } else if (IS_PINEVIEW(dev)) { | 5427 | } else if (IS_PINEVIEW(dev)) { |
5279 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), | 5428 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), |
5429 | dev_priv->is_ddr3, | ||
5280 | dev_priv->fsb_freq, | 5430 | dev_priv->fsb_freq, |
5281 | dev_priv->mem_freq)) { | 5431 | dev_priv->mem_freq)) { |
5282 | DRM_INFO("failed to find known CxSR latency " | 5432 | DRM_INFO("failed to find known CxSR latency " |
5283 | "(found fsb freq %d, mem freq %d), " | 5433 | "(found ddr%s fsb freq %d, mem freq %d), " |
5284 | "disabling CxSR\n", | 5434 | "disabling CxSR\n", |
5435 | (dev_priv->is_ddr3 == 1) ? "3": "2", | ||
5285 | dev_priv->fsb_freq, dev_priv->mem_freq); | 5436 | dev_priv->fsb_freq, dev_priv->mem_freq); |
5286 | /* Disable CxSR and never update its watermark again */ | 5437 | /* Disable CxSR and never update its watermark again */ |
5287 | pineview_disable_cxsr(dev); | 5438 | pineview_disable_cxsr(dev); |
@@ -5354,8 +5505,10 @@ void intel_modeset_init(struct drm_device *dev) | |||
5354 | 5505 | ||
5355 | intel_init_clock_gating(dev); | 5506 | intel_init_clock_gating(dev); |
5356 | 5507 | ||
5357 | if (IS_IRONLAKE_M(dev)) | 5508 | if (IS_IRONLAKE_M(dev)) { |
5358 | ironlake_enable_drps(dev); | 5509 | ironlake_enable_drps(dev); |
5510 | intel_init_emon(dev); | ||
5511 | } | ||
5359 | 5512 | ||
5360 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | 5513 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
5361 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | 5514 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |