|
@@ -4609,25 +4609,45 @@ int intel_enable_rc6(const struct drm_device *dev)
|
|
|
return i915.enable_rc6;
|
|
|
}
|
|
|
|
|
|
-static void parse_rp_state_cap(struct drm_i915_private *dev_priv, u32 rp_state_cap)
|
|
|
+static void gen6_init_rps_frequencies(struct drm_device *dev)
|
|
|
{
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ uint32_t rp_state_cap;
|
|
|
+ u32 ddcc_status = 0;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
|
|
/* All of these values are in units of 50MHz */
|
|
|
dev_priv->rps.cur_freq = 0;
|
|
|
- /* static values from HW: RP0 < RPe < RP1 < RPn (min_freq) */
|
|
|
- dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff;
|
|
|
+ /* static values from HW: RP0 > RP1 > RPn (min_freq) */
|
|
|
dev_priv->rps.rp0_freq = (rp_state_cap >> 0) & 0xff;
|
|
|
+ dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff;
|
|
|
dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff;
|
|
|
- /* XXX: only BYT has a special efficient freq */
|
|
|
- dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
|
|
|
/* hw_max = RP0 until we check for overclocking */
|
|
|
dev_priv->rps.max_freq = dev_priv->rps.rp0_freq;
|
|
|
|
|
|
+ dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
|
|
|
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
|
|
|
+ ret = sandybridge_pcode_read(dev_priv,
|
|
|
+ HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL,
|
|
|
+ &ddcc_status);
|
|
|
+ if (0 == ret)
|
|
|
+ dev_priv->rps.efficient_freq =
|
|
|
+ (ddcc_status >> 8) & 0xff;
|
|
|
+ }
|
|
|
+
|
|
|
/* Preserve min/max settings in case of re-init */
|
|
|
if (dev_priv->rps.max_freq_softlimit == 0)
|
|
|
dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
|
|
|
|
|
|
- if (dev_priv->rps.min_freq_softlimit == 0)
|
|
|
- dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq;
|
|
|
+ if (dev_priv->rps.min_freq_softlimit == 0) {
|
|
|
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev))
|
|
|
+ dev_priv->rps.min_freq_softlimit =
|
|
|
+ dev_priv->rps.efficient_freq;
|
|
|
+ else
|
|
|
+ dev_priv->rps.min_freq_softlimit =
|
|
|
+ dev_priv->rps.min_freq;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void gen9_enable_rps(struct drm_device *dev)
|
|
@@ -4673,7 +4693,7 @@ static void gen8_enable_rps(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
struct intel_engine_cs *ring;
|
|
|
- uint32_t rc6_mask = 0, rp_state_cap;
|
|
|
+ uint32_t rc6_mask = 0;
|
|
|
int unused;
|
|
|
|
|
|
/* 1a: Software RC state - RC0 */
|
|
@@ -4686,8 +4706,8 @@ static void gen8_enable_rps(struct drm_device *dev)
|
|
|
/* 2a: Disable RC states. */
|
|
|
I915_WRITE(GEN6_RC_CONTROL, 0);
|
|
|
|
|
|
- rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
|
|
- parse_rp_state_cap(dev_priv, rp_state_cap);
|
|
|
+ /* Initialize rps frequencies */
|
|
|
+ gen6_init_rps_frequencies(dev);
|
|
|
|
|
|
/* 2b: Program RC6 thresholds.*/
|
|
|
I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
|
|
@@ -4754,7 +4774,6 @@ static void gen6_enable_rps(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
struct intel_engine_cs *ring;
|
|
|
- u32 rp_state_cap;
|
|
|
u32 rc6vids, pcu_mbox = 0, rc6_mask = 0;
|
|
|
u32 gtfifodbg;
|
|
|
int rc6_mode;
|
|
@@ -4778,9 +4797,8 @@ static void gen6_enable_rps(struct drm_device *dev)
|
|
|
|
|
|
gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
|
|
|
|
|
|
- rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
|
|
-
|
|
|
- parse_rp_state_cap(dev_priv, rp_state_cap);
|
|
|
+ /* Initialize rps frequencies */
|
|
|
+ gen6_init_rps_frequencies(dev);
|
|
|
|
|
|
/* disable the counters and set deterministic thresholds */
|
|
|
I915_WRITE(GEN6_RC_CONTROL, 0);
|