]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/i915/intel_uncore.c
drm/i915: Fix forcewake active domain tracking
[linux.git] / drivers / gpu / drm / i915 / intel_uncore.c
index 0bffd3f0c15d796627d5d89a5775e5da7a0bf572..f1c0da06f8a2fab1f87669dbab55e3959bdde82c 100644 (file)
@@ -119,6 +119,8 @@ fw_domains_get(struct drm_i915_private *dev_priv, enum forcewake_domains fw_doma
 
        for_each_fw_domain_masked(d, fw_domains, dev_priv)
                fw_domain_wait_ack(d);
+
+       dev_priv->uncore.fw_domains_active |= fw_domains;
 }
 
 static void
@@ -130,6 +132,15 @@ fw_domains_put(struct drm_i915_private *dev_priv, enum forcewake_domains fw_doma
                fw_domain_put(d);
                fw_domain_posting_read(d);
        }
+
+       dev_priv->uncore.fw_domains_active &= ~fw_domains;
+}
+
+static void
+vgpu_fw_domains_nop(struct drm_i915_private *dev_priv,
+                   enum forcewake_domains fw_domains)
+{
+       /* Guest driver doesn't need to takes care forcewake. */
 }
 
 static void
@@ -240,10 +251,8 @@ intel_uncore_fw_release_timer(struct hrtimer *timer)
        if (WARN_ON(domain->wake_count == 0))
                domain->wake_count++;
 
-       if (--domain->wake_count == 0) {
+       if (--domain->wake_count == 0)
                dev_priv->uncore.funcs.force_wake_put(dev_priv, domain->mask);
-               dev_priv->uncore.fw_domains_active &= ~domain->mask;
-       }
 
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 
@@ -421,8 +430,7 @@ static void __intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
                                   GT_FIFO_CTL_RC6_POLICY_STALL);
        }
 
-       /* Enable Decoupled MMIO only on BXT C stepping onwards */
-       if (!IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
+       if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST))
                info->has_decoupled_mmio = false;
 
        intel_uncore_forcewake_reset(dev_priv, restore_forcewake);
@@ -455,10 +463,8 @@ static void __intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
                        fw_domains &= ~domain->mask;
        }
 
-       if (fw_domains) {
+       if (fw_domains)
                dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
-               dev_priv->uncore.fw_domains_active |= fw_domains;
-       }
 }
 
 /**
@@ -500,7 +506,7 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
 void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
                                        enum forcewake_domains fw_domains)
 {
-       assert_spin_locked(&dev_priv->uncore.lock);
+       lockdep_assert_held(&dev_priv->uncore.lock);
 
        if (!dev_priv->uncore.funcs.force_wake_get)
                return;
@@ -558,7 +564,7 @@ void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
 void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
                                        enum forcewake_domains fw_domains)
 {
-       assert_spin_locked(&dev_priv->uncore.lock);
+       lockdep_assert_held(&dev_priv->uncore.lock);
 
        if (!dev_priv->uncore.funcs.force_wake_put)
                return;
@@ -626,34 +632,14 @@ find_fw_domain(struct drm_i915_private *dev_priv, u32 offset)
                        dev_priv->uncore.fw_domains_table_entries,
                        fw_range_cmp);
 
-       return entry ? entry->domains : 0;
-}
-
-static void
-intel_fw_table_check(struct drm_i915_private *dev_priv)
-{
-       const struct intel_forcewake_range *ranges;
-       unsigned int num_ranges;
-       s32 prev;
-       unsigned int i;
-
-       if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG))
-               return;
-
-       ranges = dev_priv->uncore.fw_domains_table;
-       if (!ranges)
-               return;
+       if (!entry)
+               return 0;
 
-       num_ranges = dev_priv->uncore.fw_domains_table_entries;
+       WARN(entry->domains & ~dev_priv->uncore.fw_domains,
+            "Uninitialized forcewake domain(s) 0x%x accessed at 0x%x\n",
+            entry->domains & ~dev_priv->uncore.fw_domains, offset);
 
-       for (i = 0, prev = -1; i < num_ranges; i++, ranges++) {
-               WARN_ON_ONCE(IS_GEN9(dev_priv) &&
-                            (prev + 1) != (s32)ranges->start);
-               WARN_ON_ONCE(prev >= (s32)ranges->start);
-               prev = ranges->start;
-               WARN_ON_ONCE(prev >= (s32)ranges->end);
-               prev = ranges->end;
-       }
+       return entry->domains;
 }
 
 #define GEN_FW_RANGE(s, e, d) \
@@ -694,23 +680,6 @@ static const i915_reg_t gen8_shadowed_regs[] = {
        /* TODO: Other registers are not yet used */
 };
 
-static void intel_shadow_table_check(void)
-{
-       const i915_reg_t *reg = gen8_shadowed_regs;
-       s32 prev;
-       u32 offset;
-       unsigned int i;
-
-       if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG))
-               return;
-
-       for (i = 0, prev = -1; i < ARRAY_SIZE(gen8_shadowed_regs); i++, reg++) {
-               offset = i915_mmio_reg_offset(*reg);
-               WARN_ON_ONCE(prev >= (s32)offset);
-               prev = offset;
-       }
-}
-
 static int mmio_reg_cmp(u32 key, const i915_reg_t *reg)
 {
        u32 offset = i915_mmio_reg_offset(*reg);
@@ -962,7 +931,6 @@ static noinline void ___force_wake_auto(struct drm_i915_private *dev_priv,
                fw_domain_arm_timer(domain);
 
        dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
-       dev_priv->uncore.fw_domains_active |= fw_domains;
 }
 
 static inline void __force_wake_auto(struct drm_i915_private *dev_priv,
@@ -979,29 +947,19 @@ static inline void __force_wake_auto(struct drm_i915_private *dev_priv,
                ___force_wake_auto(dev_priv, fw_domains);
 }
 
-#define __gen6_read(x) \
-static u##x \
-gen6_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
-       enum forcewake_domains fw_engine; \
-       GEN6_READ_HEADER(x); \
-       fw_engine = __gen6_reg_read_fw_domains(offset); \
-       if (fw_engine) \
-               __force_wake_auto(dev_priv, fw_engine); \
-       val = __raw_i915_read##x(dev_priv, reg); \
-       GEN6_READ_FOOTER; \
-}
-
-#define __fwtable_read(x) \
+#define __gen_read(func, x) \
 static u##x \
-fwtable_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
+func##_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
        enum forcewake_domains fw_engine; \
        GEN6_READ_HEADER(x); \
-       fw_engine = __fwtable_reg_read_fw_domains(offset); \
+       fw_engine = __##func##_reg_read_fw_domains(offset); \
        if (fw_engine) \
                __force_wake_auto(dev_priv, fw_engine); \
        val = __raw_i915_read##x(dev_priv, reg); \
        GEN6_READ_FOOTER; \
 }
+#define __gen6_read(x) __gen_read(gen6, x)
+#define __fwtable_read(x) __gen_read(fwtable, x)
 
 #define __gen9_decoupled_read(x) \
 static u##x \
@@ -1039,34 +997,6 @@ __gen6_read(64)
 #undef GEN6_READ_FOOTER
 #undef GEN6_READ_HEADER
 
-#define VGPU_READ_HEADER(x) \
-       unsigned long irqflags; \
-       u##x val = 0; \
-       assert_rpm_device_not_suspended(dev_priv); \
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
-
-#define VGPU_READ_FOOTER \
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
-       trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
-       return val
-
-#define __vgpu_read(x) \
-static u##x \
-vgpu_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
-       VGPU_READ_HEADER(x); \
-       val = __raw_i915_read##x(dev_priv, reg); \
-       VGPU_READ_FOOTER; \
-}
-
-__vgpu_read(8)
-__vgpu_read(16)
-__vgpu_read(32)
-__vgpu_read(64)
-
-#undef __vgpu_read
-#undef VGPU_READ_FOOTER
-#undef VGPU_READ_HEADER
-
 #define GEN2_WRITE_HEADER \
        trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
        assert_rpm_wakelock_held(dev_priv); \
@@ -1130,29 +1060,19 @@ gen6_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool
        GEN6_WRITE_FOOTER; \
 }
 
-#define __gen8_write(x) \
+#define __gen_write(func, x) \
 static void \
-gen8_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
+func##_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
        enum forcewake_domains fw_engine; \
        GEN6_WRITE_HEADER; \
-       fw_engine = __gen8_reg_write_fw_domains(offset); \
-       if (fw_engine) \
-               __force_wake_auto(dev_priv, fw_engine); \
-       __raw_i915_write##x(dev_priv, reg, val); \
-       GEN6_WRITE_FOOTER; \
-}
-
-#define __fwtable_write(x) \
-static void \
-fwtable_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
-       enum forcewake_domains fw_engine; \
-       GEN6_WRITE_HEADER; \
-       fw_engine = __fwtable_reg_write_fw_domains(offset); \
+       fw_engine = __##func##_reg_write_fw_domains(offset); \
        if (fw_engine) \
                __force_wake_auto(dev_priv, fw_engine); \
        __raw_i915_write##x(dev_priv, reg, val); \
        GEN6_WRITE_FOOTER; \
 }
+#define __gen8_write(x) __gen_write(gen8, x)
+#define __fwtable_write(x) __gen_write(fwtable, x)
 
 #define __gen9_decoupled_write(x) \
 static void \
@@ -1189,31 +1109,6 @@ __gen6_write(32)
 #undef GEN6_WRITE_FOOTER
 #undef GEN6_WRITE_HEADER
 
-#define VGPU_WRITE_HEADER \
-       unsigned long irqflags; \
-       trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
-       assert_rpm_device_not_suspended(dev_priv); \
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
-
-#define VGPU_WRITE_FOOTER \
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
-
-#define __vgpu_write(x) \
-static void vgpu_write##x(struct drm_i915_private *dev_priv, \
-                         i915_reg_t reg, u##x val, bool trace) { \
-       VGPU_WRITE_HEADER; \
-       __raw_i915_write##x(dev_priv, reg, val); \
-       VGPU_WRITE_FOOTER; \
-}
-
-__vgpu_write(8)
-__vgpu_write(16)
-__vgpu_write(32)
-
-#undef __vgpu_write
-#undef VGPU_WRITE_FOOTER
-#undef VGPU_WRITE_HEADER
-
 #define ASSIGN_WRITE_MMIO_VFUNCS(x) \
 do { \
        dev_priv->uncore.funcs.mmio_writeb = x##_write8; \
@@ -1369,6 +1264,11 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv)
                               FORCEWAKE, FORCEWAKE_ACK);
        }
 
+       if (intel_vgpu_active(dev_priv)) {
+               dev_priv->uncore.funcs.force_wake_get = vgpu_fw_domains_nop;
+               dev_priv->uncore.funcs.force_wake_put = vgpu_fw_domains_nop;
+       }
+
        /* All future platforms are expected to require complex power gating */
        WARN_ON(dev_priv->uncore.fw_domains == 0);
 }
@@ -1439,15 +1339,6 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
                break;
        }
 
-       intel_fw_table_check(dev_priv);
-       if (INTEL_GEN(dev_priv) >= 8)
-               intel_shadow_table_check();
-
-       if (intel_vgpu_active(dev_priv)) {
-               ASSIGN_WRITE_MMIO_VFUNCS(vgpu);
-               ASSIGN_READ_MMIO_VFUNCS(vgpu);
-       }
-
        i915_check_and_clear_faults(dev_priv);
 }
 #undef ASSIGN_WRITE_MMIO_VFUNCS
@@ -1813,7 +1704,7 @@ static reset_func intel_get_gpu_reset(struct drm_i915_private *dev_priv)
                return ironlake_do_reset;
        else if (IS_G4X(dev_priv))
                return g4x_do_reset;
-       else if (IS_G33(dev_priv))
+       else if (IS_G33(dev_priv) || IS_PINEVIEW(dev_priv))
                return g33_do_reset;
        else if (INTEL_INFO(dev_priv)->gen >= 3)
                return i915_do_reset;
@@ -1965,3 +1856,7 @@ intel_uncore_forcewake_for_reg(struct drm_i915_private *dev_priv,
 
        return fw_domains;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/intel_uncore.c"
+#endif