diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 50 | 
1 files changed, 50 insertions, 0 deletions
| diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 5874716774a7..d93dcf683e8c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1545,6 +1545,16 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)  	DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); +	if (IS_I915GM(dev) && enabled) { +		struct intel_framebuffer *fb; + +		fb = to_intel_framebuffer(enabled->primary->fb); + +		/* self-refresh seems busted with untiled */ +		if (fb->obj->tiling_mode == I915_TILING_NONE) +			enabled = NULL; +	} +  	/*  	 * Overlay gets an aggressive default since video jitter is bad.  	 */ @@ -2085,6 +2095,43 @@ static void intel_print_wm_latency(struct drm_device *dev,  	}  } +static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, +				    uint16_t wm[5], uint16_t min) +{ +	int level, max_level = ilk_wm_max_level(dev_priv->dev); + +	if (wm[0] >= min) +		return false; + +	wm[0] = max(wm[0], min); +	for (level = 1; level <= max_level; level++) +		wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5)); + +	return true; +} + +static void snb_wm_latency_quirk(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	bool changed; + +	/* +	 * The BIOS provided WM memory latency values are often +	 * inadequate for high resolution displays. Adjust them. +	 */ +	changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) | +		ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) | +		ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12); + +	if (!changed) +		return; + +	DRM_DEBUG_KMS("WM latency values increased to avoid potential underruns\n"); +	intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency); +	intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency); +	intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); +} +  static void ilk_setup_wm_latency(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private; @@ -2102,6 +2149,9 @@ static void ilk_setup_wm_latency(struct drm_device *dev)  	intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency);  	intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency);  	intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); + +	if (IS_GEN6(dev)) +		snb_wm_latency_quirk(dev);  }  static void ilk_compute_wm_parameters(struct drm_crtc *crtc, | 

