diff options
Diffstat (limited to 'drivers/gpu/drm/i915/gt/intel_rps.c')
-rw-r--r-- | drivers/gpu/drm/i915/gt/intel_rps.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index c1c9cc0ad3b9..b629eeb14002 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -390,6 +390,16 @@ static void gen5_rps_update(struct intel_rps *rps) spin_unlock_irq(&mchdev_lock); } +static unsigned int gen5_invert_freq(struct intel_rps *rps, + unsigned int val) +{ + /* Invert the frequency bin into an ips delay */ + val = rps->max_freq - val; + val = rps->min_freq + val; + + return val; +} + static bool gen5_rps_set(struct intel_rps *rps, u8 val) { struct intel_uncore *uncore = rps_to_uncore(rps); @@ -404,8 +414,7 @@ static bool gen5_rps_set(struct intel_rps *rps, u8 val) } /* Invert the frequency bin into an ips delay */ - val = rps->max_freq - val; - val = rps->min_freq + val; + val = gen5_invert_freq(rps, val); rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | @@ -500,6 +509,7 @@ static unsigned int init_emon(struct intel_uncore *uncore) static bool gen5_rps_enable(struct intel_rps *rps) { + struct drm_i915_private *i915 = rps_to_i915(rps); struct intel_uncore *uncore = rps_to_uncore(rps); u8 fstart, vstart; u32 rgvmodectl; @@ -557,6 +567,10 @@ static bool gen5_rps_enable(struct intel_rps *rps) rps->ips.last_count2 = intel_uncore_read(uncore, GFXEC); rps->ips.last_time2 = ktime_get_raw_ns(); + spin_lock(&i915->irq_lock); + ilk_enable_display_irq(i915, DE_PCU_EVENT); + spin_unlock(&i915->irq_lock); + spin_unlock_irq(&mchdev_lock); rps->ips.corr = init_emon(uncore); @@ -566,11 +580,16 @@ static bool gen5_rps_enable(struct intel_rps *rps) static void gen5_rps_disable(struct intel_rps *rps) { + struct drm_i915_private *i915 = rps_to_i915(rps); struct intel_uncore *uncore = rps_to_uncore(rps); u16 rgvswctl; spin_lock_irq(&mchdev_lock); + spin_lock(&i915->irq_lock); + ilk_disable_display_irq(i915, DE_PCU_EVENT); + spin_unlock(&i915->irq_lock); + rgvswctl = intel_uncore_read16(uncore, MEMSWCTL); /* Ack interrupts, disable EFC interrupt */ @@ -578,11 +597,6 @@ static void gen5_rps_disable(struct intel_rps *rps) intel_uncore_read(uncore, MEMINTREN) & ~MEMINT_EVAL_CHG_EN); intel_uncore_write(uncore, MEMINTRSTS, MEMINT_EVAL_CHG); - intel_uncore_write(uncore, DEIER, - intel_uncore_read(uncore, DEIER) & ~DE_PCU_EVENT); - intel_uncore_write(uncore, DEIIR, DE_PCU_EVENT); - intel_uncore_write(uncore, DEIMR, - intel_uncore_read(uncore, DEIMR) | DE_PCU_EVENT); /* Go back to the starting frequency */ gen5_rps_set(rps, rps->idle_freq); @@ -1276,8 +1290,9 @@ static unsigned long __ips_gfx_val(struct intel_ips *ips) { struct intel_rps *rps = container_of(ips, typeof(*rps), ips); struct intel_uncore *uncore = rps_to_uncore(rps); - unsigned long t, corr, state1, corr2, state2; + unsigned int t, state1, state2; u32 pxvid, ext_v; + u64 corr, corr2; lockdep_assert_held(&mchdev_lock); @@ -1298,11 +1313,10 @@ static unsigned long __ips_gfx_val(struct intel_ips *ips) else /* < 50 */ corr = t * 301 + 1004; - corr = corr * 150142 * state1 / 10000 - 78642; - corr /= 100000; - corr2 = corr * ips->corr; + corr = div_u64(corr * 150142 * state1, 10000) - 78642; + corr2 = div_u64(corr, 100000) * ips->corr; - state2 = corr2 * state1 / 10000; + state2 = div_u64(corr2 * state1, 10000); state2 /= 100; /* convert to mW */ __gen5_ips_update(ips); @@ -1436,8 +1450,10 @@ int intel_gpu_freq(struct intel_rps *rps, int val) return chv_gpu_freq(rps, val); else if (IS_VALLEYVIEW(i915)) return byt_gpu_freq(rps, val); - else + else if (INTEL_GEN(i915) >= 6) return val * GT_FREQUENCY_MULTIPLIER; + else + return val; } int intel_freq_opcode(struct intel_rps *rps, int val) @@ -1451,8 +1467,10 @@ int intel_freq_opcode(struct intel_rps *rps, int val) return chv_freq_opcode(rps, val); else if (IS_VALLEYVIEW(i915)) return byt_freq_opcode(rps, val); - else + else if (INTEL_GEN(i915) >= 6) return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER); + else + return val; } static void vlv_init_gpll_ref_freq(struct intel_rps *rps) @@ -1868,8 +1886,11 @@ u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat) cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT; else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT; - else + else if (INTEL_GEN(i915) >= 6) cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT; + else + cagf = gen5_invert_freq(rps, (rpstat & MEMSTAT_PSTATE_MASK) >> + MEMSTAT_PSTATE_SHIFT); return cagf; } @@ -1877,14 +1898,17 @@ u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat) static u32 read_cagf(struct intel_rps *rps) { struct drm_i915_private *i915 = rps_to_i915(rps); + struct intel_uncore *uncore = rps_to_uncore(rps); u32 freq; if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { vlv_punit_get(i915); freq = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS); vlv_punit_put(i915); + } else if (INTEL_GEN(i915) >= 6) { + freq = intel_uncore_read(uncore, GEN6_RPSTAT1); } else { - freq = intel_uncore_read(rps_to_uncore(rps), GEN6_RPSTAT1); + freq = intel_uncore_read(uncore, MEMSTAT_ILK); } return intel_rps_get_cagf(rps, freq); @@ -1953,7 +1977,7 @@ static struct drm_i915_private *mchdev_get(void) rcu_read_lock(); i915 = rcu_dereference(ips_mchdev); - if (!kref_get_unless_zero(&i915->drm.ref)) + if (i915 && !kref_get_unless_zero(&i915->drm.ref)) i915 = NULL; rcu_read_unlock(); |