Merge tag 'drm-next-2020-12-11' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / gt / intel_rps.c
index e6a00ee..b629eeb 100644 (file)
@@ -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);
@@ -883,6 +897,10 @@ void intel_rps_park(struct intel_rps *rps)
                adj = -2;
        rps->last_adj = adj;
        rps->cur_freq = max_t(int, rps->cur_freq + adj, rps->min_freq);
+       if (rps->cur_freq < rps->efficient_freq) {
+               rps->cur_freq = rps->efficient_freq;
+               rps->last_adj = 0;
+       }
 
        GT_TRACE(rps_to_gt(rps), "park:%x\n", rps->cur_freq);
 }
@@ -1272,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);
 
@@ -1294,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);
@@ -1432,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)
@@ -1447,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)
@@ -1864,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;
 }
@@ -1873,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);
@@ -1949,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();