Re: [Intel-gfx] [PATCH 16/26] drm/i915: turbo RC6 support for VLV
-Original Message- From: intel-gfx-bounces+rohit.jain=intel@lists.freedesktop.org [mailto:intel-gfx-bounces+rohit.jain=intel@lists.freedesktop.org] On Behalf Of Jesse Barnes Sent: Friday, March 08, 2013 3:58 AM To: Rohit Jain Cc: intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH 16/26] drm/i915: turbo RC6 support for VLV On Wed, 6 Mar 2013 16:21:03 +0530 (IST) Rohit Jain ro...@intel.com wrote: On Sat, 2 Mar 2013, Jesse Barnes wrote: From: Ben Widawsky b...@bwidawsk.net Uses slightly different interfaces than other platforms. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_pm.c | 148 +-- 1 file changed, 144 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e3947cb..d16f4f40 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2477,6 +2477,47 @@ void gen6_set_rps(struct drm_device *dev, u8 val) trace_intel_gpu_freq_change(val * 50); } +void valleyview_set_rps(struct drm_device *dev, u8 val) { + struct drm_i915_private *dev_priv = dev-dev_private; + unsigned long timeout = jiffies + msecs_to_jiffies(100); + u32 limits = gen6_rps_limits(dev_priv, val); + u32 pval; + + WARN_ON(!mutex_is_locked(dev_priv-rps.hw_lock)); + WARN_ON(val dev_priv-rps.max_delay); + WARN_ON(val dev_priv-rps.min_delay); + + if (val == dev_priv-rps.cur_delay) + return; + + valleyview_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + + do { + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, pval); + if (time_after(jiffies, timeout)) { + DRM_DEBUG_DRIVER(timed out waiting for Punit\n); + break; + } + udelay(10); + } while (pval 1); + + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, pval); + if ((pval 8) != val) + DRM_DEBUG_DRIVER(punit overrode freq: %d requested, but got %d\n, + val, pval 8); + + /* Make sure we continue to get interrupts + * until we hit the minimum or maximum frequencies. + */ + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); + + dev_priv-rps.cur_delay = val; Shouldn't we store pval 8 instead of val in cur_delay in order to reclaim the rps state? If we store val here, the requested frequency will eventually exceed max_delay if punit overrides with a lower frequency. Yeah we should track the current freq here instead. But we clamp to max_delay in the caller right? And yeah I missed the update to i915_irq.c, I fixed that too. Cool! On my board, max_delay gets set to 255 while the punit refuses to go above 222 in practice. In this case, before we can clamp to max_delay, cur_delay overflows and gets set to min_delay instead :) Fixing it like this solves this problem neatly. Cheers, Rohit ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 16/26] drm/i915: turbo RC6 support for VLV
On Wed, 6 Mar 2013 16:21:03 +0530 (IST) Rohit Jain ro...@intel.com wrote: On Sat, 2 Mar 2013, Jesse Barnes wrote: From: Ben Widawsky b...@bwidawsk.net Uses slightly different interfaces than other platforms. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_pm.c | 148 +-- 1 file changed, 144 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e3947cb..d16f4f40 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2477,6 +2477,47 @@ void gen6_set_rps(struct drm_device *dev, u8 val) trace_intel_gpu_freq_change(val * 50); } +void valleyview_set_rps(struct drm_device *dev, u8 val) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + unsigned long timeout = jiffies + msecs_to_jiffies(100); + u32 limits = gen6_rps_limits(dev_priv, val); + u32 pval; + + WARN_ON(!mutex_is_locked(dev_priv-rps.hw_lock)); + WARN_ON(val dev_priv-rps.max_delay); + WARN_ON(val dev_priv-rps.min_delay); + + if (val == dev_priv-rps.cur_delay) + return; + + valleyview_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + + do { + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, pval); + if (time_after(jiffies, timeout)) { + DRM_DEBUG_DRIVER(timed out waiting for Punit\n); + break; + } + udelay(10); + } while (pval 1); + + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, pval); + if ((pval 8) != val) + DRM_DEBUG_DRIVER(punit overrode freq: %d requested, but got %d\n, + val, pval 8); + + /* Make sure we continue to get interrupts +* until we hit the minimum or maximum frequencies. +*/ + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); + + dev_priv-rps.cur_delay = val; Shouldn't we store pval 8 instead of val in cur_delay in order to reclaim the rps state? If we store val here, the requested frequency will eventually exceed max_delay if punit overrides with a lower frequency. Yeah we should track the current freq here instead. But we clamp to max_delay in the caller right? And yeah I missed the update to i915_irq.c, I fixed that too. -- Jesse Barnes, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 16/26] drm/i915: turbo RC6 support for VLV
On Sat, 2 Mar 2013, Jesse Barnes wrote: From: Ben Widawsky b...@bwidawsk.net Uses slightly different interfaces than other platforms. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_pm.c | 148 +-- 1 file changed, 144 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e3947cb..d16f4f40 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2477,6 +2477,47 @@ void gen6_set_rps(struct drm_device *dev, u8 val) trace_intel_gpu_freq_change(val * 50); } +void valleyview_set_rps(struct drm_device *dev, u8 val) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + unsigned long timeout = jiffies + msecs_to_jiffies(100); + u32 limits = gen6_rps_limits(dev_priv, val); + u32 pval; + + WARN_ON(!mutex_is_locked(dev_priv-rps.hw_lock)); + WARN_ON(val dev_priv-rps.max_delay); + WARN_ON(val dev_priv-rps.min_delay); + + if (val == dev_priv-rps.cur_delay) + return; + + valleyview_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + + do { + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, pval); + if (time_after(jiffies, timeout)) { + DRM_DEBUG_DRIVER(timed out waiting for Punit\n); + break; + } + udelay(10); + } while (pval 1); + + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, pval); + if ((pval 8) != val) + DRM_DEBUG_DRIVER(punit overrode freq: %d requested, but got %d\n, + val, pval 8); + + /* Make sure we continue to get interrupts +* until we hit the minimum or maximum frequencies. +*/ + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); + + dev_priv-rps.cur_delay = val; Shouldn't we store pval 8 instead of val in cur_delay in order to reclaim the rps state? If we store val here, the requested frequency will eventually exceed max_delay if punit overrides with a lower frequency. + + trace_intel_gpu_freq_change(val * 50); +} + + static void gen6_disable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; @@ -2714,6 +2755,100 @@ static void gen6_update_ring_freq(struct drm_device *dev) } } +static void valleyview_enable_rps(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_ring_buffer *ring; + u32 gtfifodbg, val; + int i; + + WARN_ON(!mutex_is_locked(dev_priv-rps.hw_lock)); + + if ((gtfifodbg = I915_READ(GTFIFODBG))) { + DRM_ERROR(GT fifo had a previous error %x\n, gtfifodbg); + I915_WRITE(GTFIFODBG, gtfifodbg); + } + + gen6_gt_force_wake_get(dev_priv); + + I915_WRITE(GEN6_RC_SLEEP, 0); + + I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x0028); + I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); + I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 0x19); + + for_each_ring(ring, dev_priv, i) + I915_WRITE(RING_MAX_IDLE(ring-mmio_base), 10); + + I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); + I915_WRITE(GEN6_RC6_THRESHOLD, 0xc350); + + I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); + I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); + I915_WRITE(GEN6_RP_UP_EI, 66000); + I915_WRITE(GEN6_RP_DOWN_EI, 35); + + I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); + + I915_WRITE(GEN6_RP_CONTROL, + GEN6_RP_MEDIA_TURBO | + GEN6_RP_MEDIA_HW_NORMAL_MODE | + GEN6_RP_MEDIA_IS_GFX | + GEN6_RP_ENABLE | + GEN6_RP_UP_BUSY_AVG | + GEN6_RP_DOWN_IDLE_CONT); + + /* allows RC6 residency counter to work */ + I915_WRITE(0x138104, 0x00ff); + I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE); + + valleyview_punit_read(dev_priv, PUNIT_FUSE_BUS1, val); + DRM_DEBUG_DRIVER(max GPU freq: %d\n, val); + dev_priv-rps.max_delay = val; + + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_LFM, val); + DRM_DEBUG_DRIVER(min GPU freq: %d\n, val); + dev_priv-rps.min_delay = val; + + valleyview_punit_read(dev_priv, PUNIT_FUSE_BUS2, val); + DRM_DEBUG_DRIVER(max GPLL freq: %d\n, val); + + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, val); + DRM_DEBUG_DRIVER(DDR speed: ); + if (((val 6) 3) == 0) { + dev_priv-mem_freq = 800; + printk(800 MHz\n); + } else if (((val 6) 3) == 1) { + printk(1066 MHz\n); + dev_priv-mem_freq = 1066; + } else if (((val 6) 3) == 2) { + printk(1333 MHz\n); + dev_priv-mem_freq = 1333; + } else if (((val 6) 3) == 3) + printk(invalid\n); +