Merge tag 'samsung-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux...
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_uncore.c
index d0c7577..4f6fef7 100644 (file)
@@ -255,8 +255,7 @@ static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
 
 }
 
-void vlv_force_wake_get(struct drm_i915_private *dev_priv,
-                                               int fw_engine)
+static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 {
        unsigned long irqflags;
 
@@ -275,8 +274,7 @@ void vlv_force_wake_get(struct drm_i915_private *dev_priv,
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
-void vlv_force_wake_put(struct drm_i915_private *dev_priv,
-                                               int fw_engine)
+static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 {
        unsigned long irqflags;
 
@@ -322,7 +320,8 @@ static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
-       del_timer_sync(&dev_priv->uncore.force_wake_timer);
+       if (del_timer_sync(&dev_priv->uncore.force_wake_timer))
+               gen6_force_wake_timer((unsigned long)dev_priv);
 
        /* Hold uncore.lock across reset to prevent any register access
         * with forcewake not set correctly
@@ -374,7 +373,7 @@ void intel_uncore_early_sanitize(struct drm_device *dev)
        if (HAS_FPGA_DBG_UNCLAIMED(dev))
                __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
 
-       if (IS_HASWELL(dev) &&
+       if ((IS_HASWELL(dev) || IS_BROADWELL(dev)) &&
            (__raw_i915_read32(dev_priv, HSW_EDRAM_PRESENT) == 1)) {
                /* The docs do not explain exactly how the calculation can be
                 * made. It is somewhat guessable, but for now, it's always
@@ -395,26 +394,8 @@ void intel_uncore_early_sanitize(struct drm_device *dev)
 
 void intel_uncore_sanitize(struct drm_device *dev)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 reg_val;
-
        /* BIOS often leaves RC6 enabled, but disable it for hw init */
        intel_disable_gt_powersave(dev);
-
-       /* Turn off power gate, require especially for the BIOS less system */
-       if (IS_VALLEYVIEW(dev)) {
-
-               mutex_lock(&dev_priv->rps.hw_lock);
-               reg_val = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS);
-
-               if (reg_val & (PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_RENDER) |
-                              PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_MEDIA) |
-                              PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_DISP2D)))
-                       vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, 0x0);
-
-               mutex_unlock(&dev_priv->rps.hw_lock);
-
-       }
 }
 
 /*
@@ -488,6 +469,17 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
 #define NEEDS_FORCE_WAKE(dev_priv, reg) \
         ((reg) < 0x40000 && (reg) != FORCEWAKE)
 
+#define FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg) \
+       (((reg) >= 0x2000 && (reg) < 0x4000) ||\
+       ((reg) >= 0x5000 && (reg) < 0x8000) ||\
+       ((reg) >= 0xB000 && (reg) < 0x12000) ||\
+       ((reg) >= 0x2E000 && (reg) < 0x30000))
+
+#define FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)\
+       (((reg) >= 0x12000 && (reg) < 0x14000) ||\
+       ((reg) >= 0x22000 && (reg) < 0x24000) ||\
+       ((reg) >= 0x30000 && (reg) < 0x40000))
+
 static void
 ilk_dummy_write(struct drm_i915_private *dev_priv)
 {
@@ -854,12 +846,15 @@ void intel_uncore_fini(struct drm_device *dev)
        intel_uncore_forcewake_reset(dev, false);
 }
 
+#define GEN_RANGE(l, h) GENMASK(h, l)
+
 static const struct register_whitelist {
        uint64_t offset;
        uint32_t size;
-       uint32_t gen_bitmask; /* support gens, 0x10 for 4, 0x30 for 4 and 5, etc. */
+       /* supported gens, 0x10 for 4, 0x30 for 4 and 5, etc. */
+       uint32_t gen_bitmask;
 } whitelist[] = {
-       { RING_TIMESTAMP(RENDER_RING_BASE), 8, 0x1F0 },
+       { RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 8) },
 };
 
 int i915_reg_read_ioctl(struct drm_device *dev,
@@ -911,7 +906,7 @@ int i915_get_reset_stats_ioctl(struct drm_device *dev,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_reset_stats *args = data;
        struct i915_ctx_hang_stats *hs;
-       struct i915_hw_context *ctx;
+       struct intel_context *ctx;
        int ret;
 
        if (args->flags || args->pad)
@@ -955,6 +950,9 @@ static int i965_do_reset(struct drm_device *dev)
 {
        int ret;
 
+       /* FIXME: i965g/gm need a display save/restore for gpu reset. */
+       return -ENODEV;
+
        /*
         * Set the domains we want to reset (GRDOM/bits 2 and 3) as
         * well as the reset bit (GR/bit 0).  Setting the GR bit
@@ -966,7 +964,6 @@ static int i965_do_reset(struct drm_device *dev)
        if (ret)
                return ret;
 
-       /* We can't reset render&media without also resetting display ... */
        pci_write_config_byte(dev->pdev, I965_GDRST,
                              GRDOM_MEDIA | GRDOM_RESET_ENABLE);
 
@@ -979,26 +976,58 @@ static int i965_do_reset(struct drm_device *dev)
        return 0;
 }
 
+static int g4x_do_reset(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int ret;
+
+       pci_write_config_byte(dev->pdev, I965_GDRST,
+                             GRDOM_RENDER | GRDOM_RESET_ENABLE);
+       ret =  wait_for(i965_reset_complete(dev), 500);
+       if (ret)
+               return ret;
+
+       /* WaVcpClkGateDisableForMediaReset:ctg,elk */
+       I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE);
+       POSTING_READ(VDECCLK_GATE_D);
+
+       pci_write_config_byte(dev->pdev, I965_GDRST,
+                             GRDOM_MEDIA | GRDOM_RESET_ENABLE);
+       ret =  wait_for(i965_reset_complete(dev), 500);
+       if (ret)
+               return ret;
+
+       /* WaVcpClkGateDisableForMediaReset:ctg,elk */
+       I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE);
+       POSTING_READ(VDECCLK_GATE_D);
+
+       pci_write_config_byte(dev->pdev, I965_GDRST, 0);
+
+       return 0;
+}
+
 static int ironlake_do_reset(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 gdrst;
        int ret;
 
-       gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
-       gdrst &= ~GRDOM_MASK;
        I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
-                  gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE);
-       ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
+                  ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE);
+       ret = wait_for((I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) &
+                       ILK_GRDOM_RESET_ENABLE) == 0, 500);
        if (ret)
                return ret;
 
-       /* We can't reset render&media without also resetting display ... */
-       gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
-       gdrst &= ~GRDOM_MASK;
        I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
-                  gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE);
-       return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
+                  ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE);
+       ret = wait_for((I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) &
+                       ILK_GRDOM_RESET_ENABLE) == 0, 500);
+       if (ret)
+               return ret;
+
+       I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, 0);
+
+       return 0;
 }
 
 static int gen6_do_reset(struct drm_device *dev)
@@ -1029,7 +1058,11 @@ int intel_gpu_reset(struct drm_device *dev)
        case 7:
        case 6: return gen6_do_reset(dev);
        case 5: return ironlake_do_reset(dev);
-       case 4: return i965_do_reset(dev);
+       case 4:
+               if (IS_G4X(dev))
+                       return g4x_do_reset(dev);
+               else
+                       return i965_do_reset(dev);
        default: return -ENODEV;
        }
 }