{
struct drm_i915_private *dev_priv = dev->dev_private;
int pipestat_reg = PIPESTAT(pipe);
+ struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+ int timeout = crtc->hwmode.vrefresh ?
+ DIV_ROUND_UP(1000, crtc->hwmode.vrefresh) : 50;
/* Clear existing vblank status. Note this will clear any other
* sticky status fields as well.
/* Wait for vblank interrupt bit to set */
if (wait_for(I915_READ(pipestat_reg) &
PIPE_VBLANK_INTERRUPT_STATUS,
- 50))
+ timeout))
DRM_DEBUG_KMS("vblank wait timed out\n");
}
dspcntr |= DISPPLANE_SEL_PIPE_B;
if (pipe == 0 && INTEL_INFO(dev)->gen < 4) {
- /* Enable pixel doubling when the dot clock is > 90% of the (display)
+ /* Enable pixel doubling when the dot clock is > 85% of the (display)
* core speed.
*
* XXX: No double-wide on 915GM pipe B. Is that the only reason for the
* pipe == 0 check?
*/
if (mode->clock >
- dev_priv->display.get_display_clock_speed(dev) * 9 / 10)
+ dev_priv->display.get_display_clock_speed(dev) * 17 / 20)
pipeconf |= PIPECONF_DOUBLE_WIDE;
else
pipeconf &= ~PIPECONF_DOUBLE_WIDE;
goto cleanup_pending;
intel_disable_fbc(dev);
+ intel_mark_busy(dev, intel_fb->obj);
mutex_unlock(&dev->struct_mutex);
trace_i915_flip_request(intel_crtc->plane, obj);
static int intel_enable_rc6(struct drm_device *dev)
{
- /*
- * Disable rc6 on ivybridge
- * until all our HW/BIOS combinations work.
- */
- if (INTEL_INFO(dev)->gen == 7)
- return 0;
-
/*
* Respect the kernel parameter if it is set
*/
u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
u32 pcu_mbox, rc6_mask = 0;
u32 gtfifodbg;
- int cur_freq, min_freq, max_freq;
+ u8 cur_delay, min_delay, max_delay;
int rc6_mode;
int i;
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_RC6p_THRESHOLD, 150000);
I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
rc6_mode = intel_enable_rc6(dev_priv->dev);
GEN6_RC_CTL_EI_MODE(1) |
GEN6_RC_CTL_HW_ENABLE);
- I915_WRITE(GEN6_RPNSWREQ,
- 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, 10000);
- I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000);
+ /*
+ * These thresholds found through experimentation. Making them
+ * symmetric will prevent holding the clock high when the workload is
+ * light. This allows us to improve our power usage, and lower thermals.
+ */
+ I915_WRITE(GEN6_RP_UP_THRESHOLD, 0x4000);
+ I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 0x4000);
+
I915_WRITE(GEN6_RP_UP_EI, 100000);
I915_WRITE(GEN6_RP_DOWN_EI, 5000000);
I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
500))
DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
- min_freq = (rp_state_cap & 0xff0000) >> 16;
- max_freq = rp_state_cap & 0xff;
- cur_freq = (gt_perf_status & 0xff00) >> 8;
+ min_delay = (rp_state_cap & 0xff0000) >> 16;
+ max_delay = rp_state_cap & 0xff;
+ cur_delay = (gt_perf_status & 0xff00) >> 8;
/* Check for overclock support */
if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
500))
DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
if (pcu_mbox & (1<<31)) { /* OC supported */
- max_freq = pcu_mbox & 0xff;
+ max_delay = pcu_mbox & 0xff;
DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50);
}
/* In units of 100MHz */
- dev_priv->max_delay = max_freq;
- dev_priv->min_delay = min_freq;
- dev_priv->cur_delay = cur_freq;
+ dev_priv->min_delay = max(min_delay, dev_priv->min_delay);
+ dev_priv->max_delay = max_delay;
+ dev_priv->cur_delay = max(dev_priv->min_delay, (u8)10);
+
+ I915_WRITE(GEN6_RPNSWREQ,
+ GEN6_FREQUENCY(dev_priv->cur_delay) |
+ GEN6_OFFSET(0) |
+ GEN6_AGGRESSIVE_TURBO);
+ I915_WRITE(GEN6_RC_VIDEO_FREQ,
+ GEN6_FREQUENCY(12));
/* requires MSI enabled */
I915_WRITE(GEN6_PMIER,
/* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
* This implements the WaDisableRCZUnitClockGating workaround.
*/
- I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
+ I915_WRITE(GEN6_UCGCTL2,
+ GEN6_RCZUNIT_CLOCK_GATE_DISABLE |
+ GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);