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(); | 
