diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-12-11 12:01:42 +0000 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-12-17 12:36:46 +0100 | 
| commit | c43d0188d7be6e45eb52a27ed9df714ca2e04e0a (patch) | |
| tree | 2e3ef699cb25ed6266a2467661751c21411a3b08 /drivers/gpu/drm/i915/intel_pm.c | |
| parent | 20652097dadd9a7fb4d652f25466299974bc78f9 (diff) | |
| download | olio-linux-3.10-c43d0188d7be6e45eb52a27ed9df714ca2e04e0a.tar.xz olio-linux-3.10-c43d0188d7be6e45eb52a27ed9df714ca2e04e0a.zip  | |
drm/i915: Fixup cursor latency used for IVB lp3 watermarks
It operates at twice the declared latency, so adjust the computation to
avoid potential flicker at low power.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50248
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
CC: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 117 | 
1 files changed, 112 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 42839fc7349..9f1ee07ec4a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1811,8 +1811,110 @@ static void sandybridge_update_wm(struct drm_device *dev)  		enabled |= 2;  	} -	if ((dev_priv->num_pipe == 3) && -	    g4x_compute_wm0(dev, 2, +	/* +	 * Calculate and update the self-refresh watermark only when one +	 * display plane is used. +	 * +	 * SNB support 3 levels of watermark. +	 * +	 * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, +	 * and disabled in the descending order +	 * +	 */ +	I915_WRITE(WM3_LP_ILK, 0); +	I915_WRITE(WM2_LP_ILK, 0); +	I915_WRITE(WM1_LP_ILK, 0); + +	if (!single_plane_enabled(enabled) || +	    dev_priv->sprite_scaling_enabled) +		return; +	enabled = ffs(enabled) - 1; + +	/* WM1 */ +	if (!ironlake_compute_srwm(dev, 1, enabled, +				   SNB_READ_WM1_LATENCY() * 500, +				   &sandybridge_display_srwm_info, +				   &sandybridge_cursor_srwm_info, +				   &fbc_wm, &plane_wm, &cursor_wm)) +		return; + +	I915_WRITE(WM1_LP_ILK, +		   WM1_LP_SR_EN | +		   (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | +		   (fbc_wm << WM1_LP_FBC_SHIFT) | +		   (plane_wm << WM1_LP_SR_SHIFT) | +		   cursor_wm); + +	/* WM2 */ +	if (!ironlake_compute_srwm(dev, 2, enabled, +				   SNB_READ_WM2_LATENCY() * 500, +				   &sandybridge_display_srwm_info, +				   &sandybridge_cursor_srwm_info, +				   &fbc_wm, &plane_wm, &cursor_wm)) +		return; + +	I915_WRITE(WM2_LP_ILK, +		   WM2_LP_EN | +		   (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | +		   (fbc_wm << WM1_LP_FBC_SHIFT) | +		   (plane_wm << WM1_LP_SR_SHIFT) | +		   cursor_wm); + +	/* WM3 */ +	if (!ironlake_compute_srwm(dev, 3, enabled, +				   SNB_READ_WM3_LATENCY() * 500, +				   &sandybridge_display_srwm_info, +				   &sandybridge_cursor_srwm_info, +				   &fbc_wm, &plane_wm, &cursor_wm)) +		return; + +	I915_WRITE(WM3_LP_ILK, +		   WM3_LP_EN | +		   (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | +		   (fbc_wm << WM1_LP_FBC_SHIFT) | +		   (plane_wm << WM1_LP_SR_SHIFT) | +		   cursor_wm); +} + +static void ivybridge_update_wm(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	int latency = SNB_READ_WM0_LATENCY() * 100;	/* In unit 0.1us */ +	u32 val; +	int fbc_wm, plane_wm, cursor_wm; +	int ignore_fbc_wm, ignore_plane_wm, ignore_cursor_wm; +	unsigned int enabled; + +	enabled = 0; +	if (g4x_compute_wm0(dev, 0, +			    &sandybridge_display_wm_info, latency, +			    &sandybridge_cursor_wm_info, latency, +			    &plane_wm, &cursor_wm)) { +		val = I915_READ(WM0_PIPEA_ILK); +		val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); +		I915_WRITE(WM0_PIPEA_ILK, val | +			   ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); +		DRM_DEBUG_KMS("FIFO watermarks For pipe A -" +			      " plane %d, " "cursor: %d\n", +			      plane_wm, cursor_wm); +		enabled |= 1; +	} + +	if (g4x_compute_wm0(dev, 1, +			    &sandybridge_display_wm_info, latency, +			    &sandybridge_cursor_wm_info, latency, +			    &plane_wm, &cursor_wm)) { +		val = I915_READ(WM0_PIPEB_ILK); +		val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); +		I915_WRITE(WM0_PIPEB_ILK, val | +			   ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); +		DRM_DEBUG_KMS("FIFO watermarks For pipe B -" +			      " plane %d, cursor: %d\n", +			      plane_wm, cursor_wm); +		enabled |= 2; +	} + +	if (g4x_compute_wm0(dev, 2,  			    &sandybridge_display_wm_info, latency,  			    &sandybridge_cursor_wm_info, latency,  			    &plane_wm, &cursor_wm)) { @@ -1875,12 +1977,17 @@ static void sandybridge_update_wm(struct drm_device *dev)  		   (plane_wm << WM1_LP_SR_SHIFT) |  		   cursor_wm); -	/* WM3 */ +	/* WM3, note we have to correct the cursor latency */  	if (!ironlake_compute_srwm(dev, 3, enabled,  				   SNB_READ_WM3_LATENCY() * 500,  				   &sandybridge_display_srwm_info,  				   &sandybridge_cursor_srwm_info, -				   &fbc_wm, &plane_wm, &cursor_wm)) +				   &fbc_wm, &plane_wm, &ignore_cursor_wm) || +	    !ironlake_compute_srwm(dev, 3, enabled, +				   2 * SNB_READ_WM3_LATENCY() * 500, +				   &sandybridge_display_srwm_info, +				   &sandybridge_cursor_srwm_info, +				   &ignore_fbc_wm, &ignore_plane_wm, &cursor_wm))  		return;  	I915_WRITE(WM3_LP_ILK, @@ -4005,7 +4112,7 @@ void intel_init_pm(struct drm_device *dev)  		} else if (IS_IVYBRIDGE(dev)) {  			/* FIXME: detect B0+ stepping and use auto training */  			if (SNB_READ_WM0_LATENCY()) { -				dev_priv->display.update_wm = sandybridge_update_wm; +				dev_priv->display.update_wm = ivybridge_update_wm;  				dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm;  			} else {  				DRM_DEBUG_KMS("Failed to read display plane latency. "  |