From patchwork Thu May 3 06:37:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10377219 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 272036037D for ; Thu, 3 May 2018 06:40:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 174B628E71 for ; Thu, 3 May 2018 06:40:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0BD7A28EAF; Thu, 3 May 2018 06:40:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 421C228E71 for ; Thu, 3 May 2018 06:40:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2D7256E6E7; Thu, 3 May 2018 06:40:04 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (mail.fireflyinternet.com [109.228.58.192]) by gabe.freedesktop.org (Postfix) with ESMTPS id 30D566E6D4 for ; Thu, 3 May 2018 06:40:01 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 11578310-1500050 for multiple; Thu, 03 May 2018 07:39:55 +0100 Received: by haswell.alporthouse.com (sSMTP sendmail emulation); Thu, 03 May 2018 07:39:54 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Thu, 3 May 2018 07:37:37 +0100 Message-Id: <20180503063757.22238-51-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180503063757.22238-1-chris@chris-wilson.co.uk> References: <20180503063757.22238-1-chris@chris-wilson.co.uk> X-Originating-IP: 78.156.65.138 X-Country: code=GB country="United Kingdom" ip=78.156.65.138 Subject: [Intel-gfx] [PATCH 51/71] drm/i915: Pull IPS into GT power management X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP IPS was the precursor to RPS on Ironlake. It serves the same function, and so should be pulled under the intel_gt_pm umbrella. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 27 ---------- drivers/gpu/drm/i915/i915_irq.c | 21 ++++---- drivers/gpu/drm/i915/intel_gt_pm.c | 83 +++++++++++++++++------------- drivers/gpu/drm/i915/intel_gt_pm.h | 27 ++++++++++ drivers/gpu/drm/i915/intel_pm.c | 8 +-- 5 files changed, 88 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 21f56684028f..544ef802bc56 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -730,28 +730,6 @@ struct vlv_s0ix_state { u32 clock_gate_dis2; }; -/* defined intel_pm.c */ -extern spinlock_t mchdev_lock; - -struct intel_ilk_power_mgmt { - u8 cur_delay; - u8 min_delay; - u8 max_delay; - u8 fmax; - u8 fstart; - - u64 last_count1; - unsigned long last_time1; - unsigned long chipset_power; - u64 last_count2; - u64 last_time2; - unsigned long gfx_power; - u8 corr; - - int c_m; - int r_t; -}; - struct drm_i915_private; struct i915_power_well; @@ -1715,13 +1693,8 @@ struct drm_i915_private { /* Cannot be determined by PCIID. You must always read a register. */ u32 edram_cap; - /* gen6+ GT PM state */ struct intel_gt_pm gt_pm; - /* ilk-only ips/rps state. Everything in here is protected by the global - * mchdev_lock in intel_pm.c */ - struct intel_ilk_power_mgmt ips; - struct i915_power_domains power_domains; struct i915_psr psr; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 155de01ea756..c3ddba3418b3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -887,6 +887,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) { + struct intel_ips *ips = &dev_priv->gt_pm.ips; u32 busy_up, busy_down, max_avg, min_avg; u8 new_delay; @@ -894,7 +895,7 @@ static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); - new_delay = dev_priv->ips.cur_delay; + new_delay = ips->cur_delay; I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG); busy_up = I915_READ(RCPREVBSYTUPAVG); @@ -904,19 +905,19 @@ static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) /* Handle RCS change request from hw */ if (busy_up > max_avg) { - if (dev_priv->ips.cur_delay != dev_priv->ips.max_delay) - new_delay = dev_priv->ips.cur_delay - 1; - if (new_delay < dev_priv->ips.max_delay) - new_delay = dev_priv->ips.max_delay; + if (ips->cur_delay != ips->max_delay) + new_delay = ips->cur_delay - 1; + if (new_delay < ips->max_delay) + new_delay = ips->max_delay; } else if (busy_down < min_avg) { - if (dev_priv->ips.cur_delay != dev_priv->ips.min_delay) - new_delay = dev_priv->ips.cur_delay + 1; - if (new_delay > dev_priv->ips.min_delay) - new_delay = dev_priv->ips.min_delay; + if (ips->cur_delay != ips->min_delay) + new_delay = ips->cur_delay + 1; + if (new_delay > ips->min_delay) + new_delay = ips->min_delay; } if (ironlake_set_drps(dev_priv, new_delay)) - dev_priv->ips.cur_delay = new_delay; + ips->cur_delay = new_delay; spin_unlock(&mchdev_lock); diff --git a/drivers/gpu/drm/i915/intel_gt_pm.c b/drivers/gpu/drm/i915/intel_gt_pm.c index f71c39e528cc..f15342889ed4 100644 --- a/drivers/gpu/drm/i915/intel_gt_pm.c +++ b/drivers/gpu/drm/i915/intel_gt_pm.c @@ -66,6 +66,7 @@ bool ironlake_set_drps(struct drm_i915_private *dev_priv, u8 val) static void ironlake_enable_drps(struct drm_i915_private *dev_priv) { + struct intel_ips *ips = &dev_priv->gt_pm.ips; u32 rgvmodectl; u8 fmax, fmin, fstart, vstart; @@ -96,12 +97,12 @@ static void ironlake_enable_drps(struct drm_i915_private *dev_priv) vstart = (I915_READ(PXVFREQ(fstart)) & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT; - dev_priv->ips.fmax = fmax; /* IPS callback will increase this */ - dev_priv->ips.fstart = fstart; + ips->fmax = fmax; /* IPS callback will increase this */ + ips->fstart = fstart; - dev_priv->ips.max_delay = fstart; - dev_priv->ips.min_delay = fmin; - dev_priv->ips.cur_delay = fstart; + ips->max_delay = fstart; + ips->min_delay = fmin; + ips->cur_delay = fstart; DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin, fstart); @@ -124,11 +125,11 @@ static void ironlake_enable_drps(struct drm_i915_private *dev_priv) ironlake_set_drps(dev_priv, fstart); - dev_priv->ips.last_count1 = I915_READ(DMIEC) + - I915_READ(DDREC) + I915_READ(CSIEC); - dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies); - dev_priv->ips.last_count2 = I915_READ(GFXEC); - dev_priv->ips.last_time2 = ktime_get_raw_ns(); + ips->last_count1 = + I915_READ(DMIEC) + I915_READ(DDREC) + I915_READ(CSIEC); + ips->last_time1 = jiffies_to_msecs(jiffies); + ips->last_count2 = I915_READ(GFXEC); + ips->last_time2 = ktime_get_raw_ns(); spin_unlock_irq(&mchdev_lock); } @@ -149,7 +150,7 @@ static void ironlake_disable_drps(struct drm_i915_private *dev_priv) I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); /* Go back to the starting frequency */ - ironlake_set_drps(dev_priv, dev_priv->ips.fstart); + ironlake_set_drps(dev_priv, dev_priv->gt_pm.ips.fstart); mdelay(1); rgvswctl |= MEMCTL_CMD_STS; I915_WRITE(MEMSWCTL, rgvswctl); @@ -1873,6 +1874,7 @@ static const struct cparams { static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv) { + struct intel_ips *ips = &dev_priv->gt_pm.ips; u64 total_count, diff, ret; u32 count1, count2, count3, m = 0, c = 0; unsigned long now = jiffies_to_msecs(jiffies), diff1; @@ -1880,7 +1882,7 @@ static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv) lockdep_assert_held(&mchdev_lock); - diff1 = now - dev_priv->ips.last_time1; + diff1 = now - ips->last_time1; /* * Prevent division-by-zero if we are asking too fast. @@ -1889,7 +1891,7 @@ static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv) * in such cases. */ if (diff1 <= 10) - return dev_priv->ips.chipset_power; + return ips->chipset_power; count1 = I915_READ(DMIEC); count2 = I915_READ(DDREC); @@ -1898,16 +1900,15 @@ static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv) total_count = count1 + count2 + count3; /* FIXME: handle per-counter overflow */ - if (total_count < dev_priv->ips.last_count1) { - diff = ~0UL - dev_priv->ips.last_count1; + if (total_count < ips->last_count1) { + diff = ~0UL - ips->last_count1; diff += total_count; } else { - diff = total_count - dev_priv->ips.last_count1; + diff = total_count - ips->last_count1; } for (i = 0; i < ARRAY_SIZE(cparams); i++) { - if (cparams[i].i == dev_priv->ips.c_m && - cparams[i].t == dev_priv->ips.r_t) { + if (cparams[i].i == ips->c_m && cparams[i].t == ips->r_t) { m = cparams[i].m; c = cparams[i].c; break; @@ -1918,10 +1919,10 @@ static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv) ret = ((m * diff) + c); ret = div_u64(ret, 10); - dev_priv->ips.last_count1 = total_count; - dev_priv->ips.last_time1 = now; + ips->last_count1 = total_count; + ips->last_time1 = now; - dev_priv->ips.chipset_power = ret; + ips->chipset_power = ret; return ret; } @@ -1983,13 +1984,14 @@ static u32 pvid_to_extvid(struct drm_i915_private *i915, u8 pxvid) static void __i915_update_gfx_val(struct drm_i915_private *dev_priv) { + struct intel_ips *ips = &dev_priv->gt_pm.ips; u64 now, diff, diffms; u32 count; lockdep_assert_held(&mchdev_lock); now = ktime_get_raw_ns(); - diffms = now - dev_priv->ips.last_time2; + diffms = now - ips->last_time2; do_div(diffms, NSEC_PER_MSEC); /* Don't divide by 0 */ @@ -1998,20 +2000,20 @@ static void __i915_update_gfx_val(struct drm_i915_private *dev_priv) count = I915_READ(GFXEC); - if (count < dev_priv->ips.last_count2) { - diff = ~0UL - dev_priv->ips.last_count2; + if (count < ips->last_count2) { + diff = ~0UL - ips->last_count2; diff += count; } else { - diff = count - dev_priv->ips.last_count2; + diff = count - ips->last_count2; } - dev_priv->ips.last_count2 = count; - dev_priv->ips.last_time2 = now; + ips->last_count2 = count; + ips->last_time2 = now; /* More magic constants... */ diff = diff * 1181; diff = div_u64(diff, diffms * 10); - dev_priv->ips.gfx_power = diff; + ips->gfx_power = diff; } void i915_update_gfx_val(struct drm_i915_private *i915) @@ -2030,6 +2032,7 @@ void i915_update_gfx_val(struct drm_i915_private *i915) static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv) { + struct intel_ips *ips = &dev_priv->gt_pm.ips; unsigned long t, corr, state1, corr2, state2; u32 pxvid, ext_v; @@ -2055,14 +2058,14 @@ static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv) corr = corr * ((150142 * state1) / 10000 - 78642); corr /= 100000; - corr2 = (corr * dev_priv->ips.corr); + corr2 = (corr * ips->corr); state2 = (corr2 * state1) / 10000; state2 /= 100; /* convert to mW */ __i915_update_gfx_val(dev_priv); - return dev_priv->ips.gfx_power + state2; + return ips->gfx_power + state2; } unsigned long i915_gfx_val(struct drm_i915_private *i915) @@ -2133,14 +2136,17 @@ EXPORT_SYMBOL_GPL(i915_read_mch_val); bool i915_gpu_raise(void) { struct drm_i915_private *i915; + struct intel_ips *ips; i915 = mchdev_get(); if (!i915) return false; + ips = &i915->gt_pm.ips; + spin_lock_irq(&mchdev_lock); - if (i915->ips.max_delay > i915->ips.fmax) - i915->ips.max_delay--; + if (ips->max_delay > ips->fmax) + ips->max_delay--; spin_unlock_irq(&mchdev_lock); drm_dev_put(&i915->drm); @@ -2157,14 +2163,17 @@ EXPORT_SYMBOL_GPL(i915_gpu_raise); bool i915_gpu_lower(void) { struct drm_i915_private *i915; + struct intel_ips *ips; i915 = mchdev_get(); if (!i915) return false; + ips = &i915->gt_pm.ips; + spin_lock_irq(&mchdev_lock); - if (i915->ips.max_delay < i915->ips.min_delay) - i915->ips.max_delay++; + if (ips->max_delay < ips->min_delay) + ips->max_delay++; spin_unlock_irq(&mchdev_lock); drm_dev_put(&i915->drm); @@ -2209,8 +2218,8 @@ bool i915_gpu_turbo_disable(void) return false; spin_lock_irq(&mchdev_lock); - i915->ips.max_delay = i915->ips.fstart; - ret = ironlake_set_drps(i915, i915->ips.fstart); + i915->gt_pm.ips.max_delay = i915->gt_pm.ips.fstart; + ret = ironlake_set_drps(i915, i915->gt_pm.ips.fstart); spin_unlock_irq(&mchdev_lock); drm_dev_put(&i915->drm); @@ -2322,7 +2331,7 @@ static void intel_init_emon(struct drm_i915_private *dev_priv) lcfuse = I915_READ(LCFUSE02); - dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK); + dev_priv->gt_pm.ips.corr = (lcfuse & LCFUSE_HIV_MASK); } void intel_gt_pm_sanitize(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/intel_gt_pm.h b/drivers/gpu/drm/i915/intel_gt_pm.h index db67d81ae51a..23436bb213dd 100644 --- a/drivers/gpu/drm/i915/intel_gt_pm.h +++ b/drivers/gpu/drm/i915/intel_gt_pm.h @@ -72,6 +72,28 @@ struct intel_rps { struct intel_rps_ei ei; }; +/* defined intel_gt_pm.c */ +extern spinlock_t mchdev_lock; + +struct intel_ips { + u8 cur_delay; + u8 min_delay; + u8 max_delay; + u8 fmax; + u8 fstart; + + u64 last_count1; + unsigned long last_time1; + unsigned long chipset_power; + u64 last_count2; + u64 last_time2; + unsigned long gfx_power; + u8 corr; + + int c_m; + int r_t; +}; + struct intel_rc6 { u64 prev_hw_residency[4]; u64 cur_residency[4]; @@ -80,6 +102,11 @@ struct intel_rc6 { struct intel_gt_pm { struct intel_rc6 rc6; struct intel_rps rps; + /* + * ilk-only ips/rps state. Everything in here is protected by the + * global mchdev_lock in intel_gt_pm.c + */ + struct intel_ips ips; u32 imr; u32 ier; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b1f33c9c5f57..1cc9e312b1d0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -186,7 +186,7 @@ static void i915_ironlake_get_mem_freq(struct drm_i915_private *dev_priv) break; } - dev_priv->ips.r_t = dev_priv->mem_freq; + dev_priv->gt_pm.ips.r_t = dev_priv->mem_freq; switch (csipll & 0x3ff) { case 0x00c: @@ -218,11 +218,11 @@ static void i915_ironlake_get_mem_freq(struct drm_i915_private *dev_priv) } if (dev_priv->fsb_freq == 3200) { - dev_priv->ips.c_m = 0; + dev_priv->gt_pm.ips.c_m = 0; } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) { - dev_priv->ips.c_m = 1; + dev_priv->gt_pm.ips.c_m = 1; } else { - dev_priv->ips.c_m = 2; + dev_priv->gt_pm.ips.c_m = 2; } }