aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom O'Rourke <Tom.O'Rourke@intel.com>2014-11-19 17:21:52 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-11-20 07:03:31 -0500
commit93ee29203f506582cca2bcec5f05041526d9ab0a (patch)
tree5e2dfc3d76b0ea69a8c6e363b6c300b652b946bb
parentf548c0e9d4200a660e607bb4d8824c21c6d0bd74 (diff)
drm/i915: Use efficient frequency for HSW/BDW
Added gen6_init_rps_frequencies() to initialize the rps frequency values. This function replaces parse_rp_state_cap(). In addition to reading RPn, RP0, and RP1 from RP_STATE_CAP register, the new function reads efficient frequency (aka RPe) from pcode for Haswell and Broadwell and sets the turbo softlimits. The turbo minimum frequency softlimit is set to RPe for Haswell and Broadwell and to RPn otherwise. For RPe, the efficiency is based on the frequency/power ratio (MHz/W); this is considering GT power and not package power. The efficent frequency is the highest frequency for which the frequency/power ratio is within some threshold of the highest frequency/power ratio. A fixed decrease in frequency results in smaller decrease in power at frequencies less than RPe than at frequencies above RPe. v2: Following suggestions from Chris Wilson and Daniel Vetter to extend and rename parse_rp_state_cap and to open-code a poorly named function. Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> [danvet: Remove unused variables.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c46
2 files changed, 33 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7a77cd5676c8..3a51c05ca552 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6038,6 +6038,7 @@ enum punit_power_well {
6038#define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) 6038#define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5)
6039#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245) 6039#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245)
6040#define DISPLAY_IPS_CONTROL 0x19 6040#define DISPLAY_IPS_CONTROL 0x19
6041#define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A
6041#define GEN6_PCODE_DATA 0x138128 6042#define GEN6_PCODE_DATA 0x138128
6042#define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 6043#define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8
6043#define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 6044#define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 417ba880c427..eb2a0a85e057 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4609,25 +4609,45 @@ int intel_enable_rc6(const struct drm_device *dev)
4609 return i915.enable_rc6; 4609 return i915.enable_rc6;
4610} 4610}
4611 4611
4612static void parse_rp_state_cap(struct drm_i915_private *dev_priv, u32 rp_state_cap) 4612static void gen6_init_rps_frequencies(struct drm_device *dev)
4613{ 4613{
4614 struct drm_i915_private *dev_priv = dev->dev_private;
4615 uint32_t rp_state_cap;
4616 u32 ddcc_status = 0;
4617 int ret;
4618
4619 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
4614 /* All of these values are in units of 50MHz */ 4620 /* All of these values are in units of 50MHz */
4615 dev_priv->rps.cur_freq = 0; 4621 dev_priv->rps.cur_freq = 0;
4616 /* static values from HW: RP0 < RPe < RP1 < RPn (min_freq) */ 4622 /* static values from HW: RP0 > RP1 > RPn (min_freq) */
4617 dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff;
4618 dev_priv->rps.rp0_freq = (rp_state_cap >> 0) & 0xff; 4623 dev_priv->rps.rp0_freq = (rp_state_cap >> 0) & 0xff;
4624 dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff;
4619 dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff; 4625 dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff;
4620 /* XXX: only BYT has a special efficient freq */
4621 dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
4622 /* hw_max = RP0 until we check for overclocking */ 4626 /* hw_max = RP0 until we check for overclocking */
4623 dev_priv->rps.max_freq = dev_priv->rps.rp0_freq; 4627 dev_priv->rps.max_freq = dev_priv->rps.rp0_freq;
4624 4628
4629 dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
4630 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
4631 ret = sandybridge_pcode_read(dev_priv,
4632 HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL,
4633 &ddcc_status);
4634 if (0 == ret)
4635 dev_priv->rps.efficient_freq =
4636 (ddcc_status >> 8) & 0xff;
4637 }
4638
4625 /* Preserve min/max settings in case of re-init */ 4639 /* Preserve min/max settings in case of re-init */
4626 if (dev_priv->rps.max_freq_softlimit == 0) 4640 if (dev_priv->rps.max_freq_softlimit == 0)
4627 dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; 4641 dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
4628 4642
4629 if (dev_priv->rps.min_freq_softlimit == 0) 4643 if (dev_priv->rps.min_freq_softlimit == 0) {
4630 dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; 4644 if (IS_HASWELL(dev) || IS_BROADWELL(dev))
4645 dev_priv->rps.min_freq_softlimit =
4646 dev_priv->rps.efficient_freq;
4647 else
4648 dev_priv->rps.min_freq_softlimit =
4649 dev_priv->rps.min_freq;
4650 }
4631} 4651}
4632 4652
4633static void gen9_enable_rps(struct drm_device *dev) 4653static void gen9_enable_rps(struct drm_device *dev)
@@ -4673,7 +4693,7 @@ static void gen8_enable_rps(struct drm_device *dev)
4673{ 4693{
4674 struct drm_i915_private *dev_priv = dev->dev_private; 4694 struct drm_i915_private *dev_priv = dev->dev_private;
4675 struct intel_engine_cs *ring; 4695 struct intel_engine_cs *ring;
4676 uint32_t rc6_mask = 0, rp_state_cap; 4696 uint32_t rc6_mask = 0;
4677 int unused; 4697 int unused;
4678 4698
4679 /* 1a: Software RC state - RC0 */ 4699 /* 1a: Software RC state - RC0 */
@@ -4686,8 +4706,8 @@ static void gen8_enable_rps(struct drm_device *dev)
4686 /* 2a: Disable RC states. */ 4706 /* 2a: Disable RC states. */
4687 I915_WRITE(GEN6_RC_CONTROL, 0); 4707 I915_WRITE(GEN6_RC_CONTROL, 0);
4688 4708
4689 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); 4709 /* Initialize rps frequencies */
4690 parse_rp_state_cap(dev_priv, rp_state_cap); 4710 gen6_init_rps_frequencies(dev);
4691 4711
4692 /* 2b: Program RC6 thresholds.*/ 4712 /* 2b: Program RC6 thresholds.*/
4693 I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); 4713 I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
@@ -4754,7 +4774,6 @@ static void gen6_enable_rps(struct drm_device *dev)
4754{ 4774{
4755 struct drm_i915_private *dev_priv = dev->dev_private; 4775 struct drm_i915_private *dev_priv = dev->dev_private;
4756 struct intel_engine_cs *ring; 4776 struct intel_engine_cs *ring;
4757 u32 rp_state_cap;
4758 u32 rc6vids, pcu_mbox = 0, rc6_mask = 0; 4777 u32 rc6vids, pcu_mbox = 0, rc6_mask = 0;
4759 u32 gtfifodbg; 4778 u32 gtfifodbg;
4760 int rc6_mode; 4779 int rc6_mode;
@@ -4778,9 +4797,8 @@ static void gen6_enable_rps(struct drm_device *dev)
4778 4797
4779 gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); 4798 gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
4780 4799
4781 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); 4800 /* Initialize rps frequencies */
4782 4801 gen6_init_rps_frequencies(dev);
4783 parse_rp_state_cap(dev_priv, rp_state_cap);
4784 4802
4785 /* disable the counters and set deterministic thresholds */ 4803 /* disable the counters and set deterministic thresholds */
4786 I915_WRITE(GEN6_RC_CONTROL, 0); 4804 I915_WRITE(GEN6_RC_CONTROL, 0);