diff options
author | Ben Widawsky <benjamin.widawsky@intel.com> | 2013-11-03 00:07:52 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-11-08 12:10:02 -0500 |
commit | 6edee7f3e7daab105b33148b49c74a8f881d172e (patch) | |
tree | c299ac3895eaf17185c9c7901fd289de881a27db | |
parent | e3c3357863db7cb8e847b3adff5b6be94cecde82 (diff) |
drm/i915/bdw: Create a separate BDW rps enable
This is mostly what we have for HSW with the exceptions of:
no writes:
GEN6_RC1_WAKE_RATE_LIMIT
GEN6_RC6pp_WAKE_RATE_LIMIT
GEN6_RC1e_THRESHOLD
GEN6_RC6p_THRESHOLD
GEN6_RC6pp_THRESHOLD
GEN6_RP_DOWN_TIMEOUT - use 1s instead of 1.28s
Don't try to overclock, or program ring/IA frequency tables since we
don't quite have sufficient docs yet.
NOTE: These values do not reflect the changes made recently by Chris.
Since we have no evidence yet what the proper way to tweak for this
platform is, I think it is good to go, and can be optimized by Chris, or
whomever, later.
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
[danvet: Drop spurious hunk and drop TODO - having per-platform rps
register frobbing code is in my opinion preferred, now that all the
infrastructure functions are extracted.]
Reviewed-by: Jesse Barnes <jbarnes@virtuosugeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 99658468cd9e..a35ebcf04fa6 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3762,6 +3762,78 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) | |||
3762 | I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs); | 3762 | I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs); |
3763 | } | 3763 | } |
3764 | 3764 | ||
3765 | static void gen8_enable_rps(struct drm_device *dev) | ||
3766 | { | ||
3767 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3768 | struct intel_ring_buffer *ring; | ||
3769 | uint32_t rc6_mask = 0, rp_state_cap; | ||
3770 | int unused; | ||
3771 | |||
3772 | /* 1a: Software RC state - RC0 */ | ||
3773 | I915_WRITE(GEN6_RC_STATE, 0); | ||
3774 | |||
3775 | /* 1c & 1d: Get forcewake during program sequence. Although the driver | ||
3776 | * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ | ||
3777 | gen6_gt_force_wake_get(dev_priv); | ||
3778 | |||
3779 | /* 2a: Disable RC states. */ | ||
3780 | I915_WRITE(GEN6_RC_CONTROL, 0); | ||
3781 | |||
3782 | rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | ||
3783 | |||
3784 | /* 2b: Program RC6 thresholds.*/ | ||
3785 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); | ||
3786 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ | ||
3787 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ | ||
3788 | for_each_ring(ring, dev_priv, unused) | ||
3789 | I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); | ||
3790 | I915_WRITE(GEN6_RC_SLEEP, 0); | ||
3791 | I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */ | ||
3792 | |||
3793 | /* 3: Enable RC6 */ | ||
3794 | if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) | ||
3795 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE; | ||
3796 | DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off"); | ||
3797 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | | ||
3798 | GEN6_RC_CTL_EI_MODE(1) | | ||
3799 | rc6_mask); | ||
3800 | |||
3801 | /* 4 Program defaults and thresholds for RPS*/ | ||
3802 | I915_WRITE(GEN6_RPNSWREQ, HSW_FREQUENCY(10)); /* Request 500 MHz */ | ||
3803 | I915_WRITE(GEN6_RC_VIDEO_FREQ, HSW_FREQUENCY(12)); /* Request 600 MHz */ | ||
3804 | /* NB: Docs say 1s, and 1000000 - which aren't equivalent */ | ||
3805 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */ | ||
3806 | |||
3807 | /* Docs recommend 900MHz, and 300 MHz respectively */ | ||
3808 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | ||
3809 | dev_priv->rps.max_delay << 24 | | ||
3810 | dev_priv->rps.min_delay << 16); | ||
3811 | |||
3812 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */ | ||
3813 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/ | ||
3814 | I915_WRITE(GEN6_RP_UP_EI, 66000); /* 84.48ms, XXX: random? */ | ||
3815 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); /* 448ms, XXX: random? */ | ||
3816 | |||
3817 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | ||
3818 | |||
3819 | /* 5: Enable RPS */ | ||
3820 | I915_WRITE(GEN6_RP_CONTROL, | ||
3821 | GEN6_RP_MEDIA_TURBO | | ||
3822 | GEN6_RP_MEDIA_HW_NORMAL_MODE | | ||
3823 | GEN6_RP_MEDIA_IS_GFX | | ||
3824 | GEN6_RP_ENABLE | | ||
3825 | GEN6_RP_UP_BUSY_AVG | | ||
3826 | GEN6_RP_DOWN_IDLE_AVG); | ||
3827 | |||
3828 | /* 6: Ring frequency + overclocking (our driver does this later */ | ||
3829 | |||
3830 | gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8); | ||
3831 | |||
3832 | gen6_enable_rps_interrupts(dev); | ||
3833 | |||
3834 | gen6_gt_force_wake_put(dev_priv); | ||
3835 | } | ||
3836 | |||
3765 | static void gen6_enable_rps(struct drm_device *dev) | 3837 | static void gen6_enable_rps(struct drm_device *dev) |
3766 | { | 3838 | { |
3767 | struct drm_i915_private *dev_priv = dev->dev_private; | 3839 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -4891,6 +4963,9 @@ static void intel_gen6_powersave_work(struct work_struct *work) | |||
4891 | 4963 | ||
4892 | if (IS_VALLEYVIEW(dev)) { | 4964 | if (IS_VALLEYVIEW(dev)) { |
4893 | valleyview_enable_rps(dev); | 4965 | valleyview_enable_rps(dev); |
4966 | } else if (IS_BROADWELL(dev)) { | ||
4967 | gen8_enable_rps(dev); | ||
4968 | gen6_update_ring_freq(dev); | ||
4894 | } else { | 4969 | } else { |
4895 | gen6_enable_rps(dev); | 4970 | gen6_enable_rps(dev); |
4896 | gen6_update_ring_freq(dev); | 4971 | gen6_update_ring_freq(dev); |