|
@@ -5842,6 +5842,91 @@ void intel_init_emon(struct drm_device *dev)
|
|
|
dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
|
|
|
}
|
|
|
|
|
|
+static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* Here begins a magic sequence of register writes to enable
|
|
|
+ * auto-downclocking.
|
|
|
+ *
|
|
|
+ * Perhaps there might be some value in exposing these to
|
|
|
+ * userspace...
|
|
|
+ */
|
|
|
+ I915_WRITE(GEN6_RC_STATE, 0);
|
|
|
+ __gen6_force_wake_get(dev_priv);
|
|
|
+
|
|
|
+ /* disable the counters and set determistic thresholds */
|
|
|
+ I915_WRITE(GEN6_RC_CONTROL, 0);
|
|
|
+
|
|
|
+ I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16);
|
|
|
+ I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30);
|
|
|
+ I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30);
|
|
|
+ I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
|
|
|
+ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
|
|
|
+
|
|
|
+ for (i = 0; i < I915_NUM_RINGS; i++)
|
|
|
+ I915_WRITE(RING_MAX_IDLE(dev_priv->ring[i].mmio_base), 10);
|
|
|
+
|
|
|
+ I915_WRITE(GEN6_RC_SLEEP, 0);
|
|
|
+ I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
|
|
|
+ I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
|
|
|
+ I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
|
|
|
+ I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
|
|
|
+
|
|
|
+ I915_WRITE(GEN6_RC_CONTROL,
|
|
|
+ GEN6_RC_CTL_RC6p_ENABLE |
|
|
|
+ GEN6_RC_CTL_RC6_ENABLE |
|
|
|
+ GEN6_RC_CTL_HW_ENABLE);
|
|
|
+
|
|
|
+ I915_WRITE(GEN6_RC_NORMAL_FREQ,
|
|
|
+ GEN6_FREQUENCY(10) |
|
|
|
+ GEN6_OFFSET(0) |
|
|
|
+ GEN6_AGGRESSIVE_TURBO);
|
|
|
+ I915_WRITE(GEN6_RC_VIDEO_FREQ,
|
|
|
+ GEN6_FREQUENCY(12));
|
|
|
+
|
|
|
+ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
|
|
|
+ I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
|
|
|
+ 18 << 24 |
|
|
|
+ 6 << 16);
|
|
|
+ I915_WRITE(GEN6_RP_UP_THRESHOLD, 90000);
|
|
|
+ I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 100000);
|
|
|
+ I915_WRITE(GEN6_RP_UP_EI, 100000);
|
|
|
+ I915_WRITE(GEN6_RP_DOWN_EI, 300000);
|
|
|
+ I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
|
|
|
+ I915_WRITE(GEN6_RP_CONTROL,
|
|
|
+ GEN6_RP_MEDIA_TURBO |
|
|
|
+ GEN6_RP_USE_NORMAL_FREQ |
|
|
|
+ GEN6_RP_MEDIA_IS_GFX |
|
|
|
+ GEN6_RP_ENABLE |
|
|
|
+ GEN6_RP_UP_BUSY_MAX |
|
|
|
+ GEN6_RP_DOWN_BUSY_MIN);
|
|
|
+
|
|
|
+ if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
|
|
|
+ 500))
|
|
|
+ DRM_ERROR("timeout waiting for pcode mailbox to become idle\n");
|
|
|
+
|
|
|
+ I915_WRITE(GEN6_PCODE_DATA, 0);
|
|
|
+ I915_WRITE(GEN6_PCODE_MAILBOX,
|
|
|
+ GEN6_PCODE_READY |
|
|
|
+ GEN6_PCODE_WRITE_MIN_FREQ_TABLE);
|
|
|
+ if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
|
|
|
+ 500))
|
|
|
+ DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
|
|
|
+
|
|
|
+ /* requires MSI enabled */
|
|
|
+ I915_WRITE(GEN6_PMIER,
|
|
|
+ GEN6_PM_MBOX_EVENT |
|
|
|
+ GEN6_PM_THERMAL_EVENT |
|
|
|
+ GEN6_PM_RP_DOWN_TIMEOUT |
|
|
|
+ GEN6_PM_RP_UP_THRESHOLD |
|
|
|
+ GEN6_PM_RP_DOWN_THRESHOLD |
|
|
|
+ GEN6_PM_RP_UP_EI_EXPIRED |
|
|
|
+ GEN6_PM_RP_DOWN_EI_EXPIRED);
|
|
|
+
|
|
|
+ __gen6_force_wake_put(dev_priv);
|
|
|
+}
|
|
|
+
|
|
|
void intel_enable_clock_gating(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
@@ -5924,6 +6009,7 @@ void intel_enable_clock_gating(struct drm_device *dev)
|
|
|
_3D_CHICKEN2_WM_READ_PIPELINED << 16 |
|
|
|
_3D_CHICKEN2_WM_READ_PIPELINED);
|
|
|
}
|
|
|
+
|
|
|
} else if (IS_G4X(dev)) {
|
|
|
uint32_t dspclk_gate;
|
|
|
I915_WRITE(RENCLK_GATE_D1, 0);
|
|
@@ -5997,6 +6083,9 @@ void intel_enable_clock_gating(struct drm_device *dev)
|
|
|
I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (IS_GEN6(dev))
|
|
|
+ gen6_enable_rc6(dev_priv);
|
|
|
}
|
|
|
|
|
|
void intel_disable_clock_gating(struct drm_device *dev)
|