[Intel-gfx] [PATCH] allow 945 to control self refresh automatically
Li Peng
peng.li at linux.intel.com
Fri Oct 8 10:05:34 CEST 2010
Hi, Alexander:
I think you are right that GEN3 hardware CXSR requires enabling low
power render writes.
This patch is OK for me, but DRM_DEBUG_KMS is better than printk.
Acked-by : Li Peng <peng.li at linux.intel.com>
On Mon, 2010-10-04 at 19:31 -0400, Alexander Lam wrote:
> Using 2.6.35.7 (this patch is against drm-intel-next 7dcd249, but untested),
> I changed 945's self refresh to work without the need for the driver to
> enable/disable self refresh manually based on the idle state of the gpu.
> This is much better than enabling/disabling self refresh for various
> reasons, including staying in a lower power state for more time and
> avoiding the need for cpu cycles.
>
> Something must have been fixed in the driver between the initial
> implementation of 945 self refresh and now.
> (maybe 944001201ca0196bcdb088129e5866a9f379d08c: drm/i915: enable low
> power render writes on GEN3 hardware?)
>
> This patch probably doesn't cover all cases concerning if SR should
> be enabled/disabled, not to mention doing things in the wrong order or
> in the wrong place.
>
> It only works with printk statements or replacing the printk's
> with DRM_DEBUG and turning drm debugging on (I don't understand what is
> going on there...).
> ---
> drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++-----------------------
> 1 files changed, 11 insertions(+), 26 deletions(-)
>
>
> differences between files attachment
> (0001-allow-945-to-control-self-refresh-automatically.patch)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 69c54c5..97f4d86 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3256,7 +3256,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
> int planea_wm, planeb_wm;
> struct intel_watermark_params planea_params, planeb_params;
> unsigned long line_time_us;
> - int sr_clock, sr_entries = 0;
> + int sr_clock, sr_entries = 0, sr_enabled = 0;
>
> /* Create copies of the base settings for each pipe */
> if (IS_CRESTLINE(dev) || IS_I945GM(dev))
> @@ -3303,8 +3303,11 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
> if (srwm < 0)
> srwm = 1;
>
> - if (IS_I945G(dev) || IS_I945GM(dev))
> + if (IS_I945G(dev) || IS_I945GM(dev)){
> I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_FIFO_MASK | (srwm & 0xff));
> + printk("enable memory self refresh on 945\n");
> + sr_enabled = 1;
> + }
> else if (IS_I915GM(dev)) {
> /* 915M has a smaller SRWM field */
> I915_WRITE(FW_BLC_SELF, srwm & 0x3f);
> @@ -3313,6 +3316,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
> } else {
> /* Turn off self refresh if both pipes are enabled */
> if (IS_I945G(dev) || IS_I945GM(dev)) {
> + printk("disable memory self refresh on 945\n");
> + sr_enabled = 0;
> I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
> & ~FW_BLC_SELF_EN);
> } else if (IS_I915GM(dev)) {
> @@ -3332,6 +3337,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
>
> I915_WRITE(FW_BLC, fwater_lo);
> I915_WRITE(FW_BLC2, fwater_hi);
> + if (sr_enabled)
> + I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
> }
>
> static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused,
> @@ -4828,7 +4835,6 @@ static void intel_idle_update(struct work_struct *work)
> struct drm_device *dev = dev_priv->dev;
> struct drm_crtc *crtc;
> struct intel_crtc *intel_crtc;
> - int enabled = 0;
>
> if (!i915_powersave)
> return;
> @@ -4842,16 +4848,11 @@ static void intel_idle_update(struct work_struct *work)
> if (!crtc->fb)
> continue;
>
> - enabled++;
> intel_crtc = to_intel_crtc(crtc);
> if (!intel_crtc->busy)
> intel_decrease_pllclock(crtc);
> }
>
> - if ((enabled == 1) && (IS_I945G(dev) || IS_I945GM(dev))) {
> - DRM_DEBUG_DRIVER("enable memory self refresh on 945\n");
> - I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
> - }
>
> mutex_unlock(&dev->struct_mutex);
> }
> @@ -4876,17 +4877,9 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj)
> if (!drm_core_check_feature(dev, DRIVER_MODESET))
> return;
>
> - if (!dev_priv->busy) {
> - if (IS_I945G(dev) || IS_I945GM(dev)) {
> - u32 fw_blc_self;
> -
> - DRM_DEBUG_DRIVER("disable memory self refresh on 945\n");
> - fw_blc_self = I915_READ(FW_BLC_SELF);
> - fw_blc_self &= ~FW_BLC_SELF_EN;
> - I915_WRITE(FW_BLC_SELF, fw_blc_self | FW_BLC_SELF_EN_MASK);
> - }
> + if (!dev_priv->busy)
> dev_priv->busy = true;
> - } else
> + else
> mod_timer(&dev_priv->idle_timer, jiffies +
> msecs_to_jiffies(GPU_IDLE_TIMEOUT));
>
> @@ -4898,14 +4891,6 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj)
> intel_fb = to_intel_framebuffer(crtc->fb);
> if (intel_fb->obj == obj) {
> if (!intel_crtc->busy) {
> - if (IS_I945G(dev) || IS_I945GM(dev)) {
> - u32 fw_blc_self;
> -
> - DRM_DEBUG_DRIVER("disable memory self refresh on 945\n");
> - fw_blc_self = I915_READ(FW_BLC_SELF);
> - fw_blc_self &= ~FW_BLC_SELF_EN;
> - I915_WRITE(FW_BLC_SELF, fw_blc_self | FW_BLC_SELF_EN_MASK);
> - }
> /* Non-busy -> busy, upclock */
> intel_increase_pllclock(crtc);
> intel_crtc->busy = true;
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20101008/e56b797b/attachment.html>
More information about the Intel-gfx
mailing list