Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fffb6751 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-2016-04-25' of git://anongit.freedesktop.org/drm-intel into drm-next

- more userptr cornercase fixes from Chris
- clean up and tune forcewake handling (Tvrtko)
- more underrun fixes from Ville, mostly for ilk to appeas CI
- fix unclaimed register warnings on vlv/chv and enable the debug code to catch
  them by default (Ville)
- skl gpu hang fixes for gt3/4 (Mika Kuoppala)
- edram improvements for gen9+ (Mika again)
- clean up gpu reset corner cases (Chris)
- fix ctx/ring machine deaths on snb/ilk (Chris)
- MOCS programming for all engines (Peter Antoine)
- robustify/clean up vlv/chv irq handler (Ville)
- split gen8+ irq handlers into ack/handle phase (Ville)
- tons of bxt rpm fixes (mostly around firmware interactions), from Imre
- hook up panel fitting for dsi panels (Ville)
- more runtime PM fixes all over from Imre
- shrinker polish (Chris)
- more guc fixes from Alex Dai and Dave Gordon
- tons of bugfixes and small polish all over (but with a big focus on bxt)

* tag 'drm-intel-next-2016-04-25' of git://anongit.freedesktop.org/drm-intel: (142 commits)
  drm/i915: Update DRIVER_DATE to 20160425
  drm/i915/bxt: Explicitly clear the Turbo control register
  drm/i915: Correct the i915_frequency_info debugfs output
  drm/i915: Macros to convert PM time interval values to microseconds
  drm/i915: Make RPS EI/thresholds multiple of 25 on SNB-BDW
  drm/i915: Fake HDMI live status
  drm/i915/bxt: Force reprogramming a PHY with invalid HW state
  drm/i915/bxt: Wait for PHY1 GRC done if PHY0 was already enabled
  drm/i915/bxt: Use PHY0 GRC value for HW state verification
  drm/i915: use dev_priv directly in gen8_ppgtt_notify_vgt
  drm/i915/bxt: Enable DC5 during runtime resume
  drm/i915/bxt: Sanitize DC state tracking during system resume
  drm/i915/bxt: Don't uninit/init display core twice during system suspend/resume
  drm/i915: Inline intel_suspend_complete
  drm/i915/kbl: Don't WARN for expected secondary MISC IO power well request
  drm/i915: Fix eDP low vswing for Broadwell
  drm/i915: check for ERR_PTR from i915_gem_object_pin_map()
  drm/i915/guc: local optimisations and updating comments
  drm/i915/guc: drop cached copy of 'wq_head'
  drm/i915/guc: keep GuC doorbell & process descriptor mapped in kernel
  ...
parents b89359bd 5b4fd5b1
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
config DRM_I915_WERROR
        bool "Force GCC to throw an error instead of a warning when compiling"
        # As this may inadvertently break the build, only allow the user
        # to shoot oneself in the foot iff they aim really hard
        depends on EXPERT
        # We use the dependency on !COMPILE_TEST to not be enabled in
        # allmodconfig or allyesconfig configurations
        depends on !COMPILE_TEST
        default n
        help
          Add -Werror to the build flags for (and only for) i915.ko.
          Do not enable this unless you are writing code for the i915.ko module.

          Recommended for driver developers only.

          If in doubt, say "N".

config DRM_I915_DEBUG
        bool "Enable additional driver debugging"
        depends on DRM_I915
@@ -10,3 +27,15 @@ config DRM_I915_DEBUG

          If in doubt, say "N".

config DRM_I915_DEBUG_GEM
        bool "Insert extra checks into the GEM internals"
        default n
        depends on DRM_I915_WERROR
        help
          Enable extra sanity checks (including BUGs) along the GEM driver
          paths that may slow the system down and if hit hang the machine.

          Recommended for driver developers only.

          If in doubt, say "N".
+2 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
# Makefile for the drm device driver.  This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.

subdir-ccflags-$(CONFIG_DRM_I915_WERROR) := -Werror

# Please keep these build lists sorted!

# core driver code
+67 −37
Original line number Diff line number Diff line
@@ -89,27 +89,34 @@ static int i915_capabilities(struct seq_file *m, void *data)
	return 0;
}

static const char *get_pin_flag(struct drm_i915_gem_object *obj)
static const char get_active_flag(struct drm_i915_gem_object *obj)
{
	if (obj->pin_display)
		return "p";
	else
		return " ";
	return obj->active ? '*' : ' ';
}

static const char *get_tiling_flag(struct drm_i915_gem_object *obj)
static const char get_pin_flag(struct drm_i915_gem_object *obj)
{
	return obj->pin_display ? 'p' : ' ';
}

static const char get_tiling_flag(struct drm_i915_gem_object *obj)
{
	switch (obj->tiling_mode) {
	default:
	case I915_TILING_NONE: return " ";
	case I915_TILING_X: return "X";
	case I915_TILING_Y: return "Y";
	case I915_TILING_NONE: return ' ';
	case I915_TILING_X: return 'X';
	case I915_TILING_Y: return 'Y';
	}
}

static inline const char get_global_flag(struct drm_i915_gem_object *obj)
{
	return i915_gem_obj_to_ggtt(obj) ? 'g' : ' ';
}

static inline const char *get_global_flag(struct drm_i915_gem_object *obj)
static inline const char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
{
	return i915_gem_obj_to_ggtt(obj) ? "g" : " ";
	return obj->mapping ? 'M' : ' ';
}

static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
@@ -136,12 +143,13 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)

	lockdep_assert_held(&obj->base.dev->struct_mutex);

	seq_printf(m, "%pK: %s%s%s%s %8zdKiB %02x %02x [ ",
	seq_printf(m, "%pK: %c%c%c%c%c %8zdKiB %02x %02x [ ",
		   &obj->base,
		   obj->active ? "*" : " ",
		   get_active_flag(obj),
		   get_pin_flag(obj),
		   get_tiling_flag(obj),
		   get_global_flag(obj),
		   get_pin_mapped_flag(obj),
		   obj->base.size / 1024,
		   obj->base.read_domains,
		   obj->base.write_domain);
@@ -435,6 +443,8 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
	struct i915_ggtt *ggtt = &dev_priv->ggtt;
	u32 count, mappable_count, purgeable_count;
	u64 size, mappable_size, purgeable_size;
	unsigned long pin_mapped_count = 0, pin_mapped_purgeable_count = 0;
	u64 pin_mapped_size = 0, pin_mapped_purgeable_size = 0;
	struct drm_i915_gem_object *obj;
	struct drm_file *file;
	struct i915_vma *vma;
@@ -468,6 +478,14 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
		size += obj->base.size, ++count;
		if (obj->madv == I915_MADV_DONTNEED)
			purgeable_size += obj->base.size, ++purgeable_count;
		if (obj->mapping) {
			pin_mapped_count++;
			pin_mapped_size += obj->base.size;
			if (obj->pages_pin_count == 0) {
				pin_mapped_purgeable_count++;
				pin_mapped_purgeable_size += obj->base.size;
			}
		}
	}
	seq_printf(m, "%u unbound objects, %llu bytes\n", count, size);

@@ -485,6 +503,14 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
			purgeable_size += obj->base.size;
			++purgeable_count;
		}
		if (obj->mapping) {
			pin_mapped_count++;
			pin_mapped_size += obj->base.size;
			if (obj->pages_pin_count == 0) {
				pin_mapped_purgeable_count++;
				pin_mapped_purgeable_size += obj->base.size;
			}
		}
	}
	seq_printf(m, "%u purgeable objects, %llu bytes\n",
		   purgeable_count, purgeable_size);
@@ -492,6 +518,10 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
		   mappable_count, mappable_size);
	seq_printf(m, "%u fault mappable objects, %llu bytes\n",
		   count, size);
	seq_printf(m,
		   "%lu [%lu] pin mapped objects, %llu [%llu] bytes [purgeable]\n",
		   pin_mapped_count, pin_mapped_purgeable_count,
		   pin_mapped_size, pin_mapped_purgeable_size);

	seq_printf(m, "%llu [%llu] gtt total\n",
		   ggtt->base.total, ggtt->mappable_end - ggtt->base.start);
@@ -1216,12 +1246,12 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
		rpdeclimit = I915_READ(GEN6_RP_DOWN_THRESHOLD);

		rpstat = I915_READ(GEN6_RPSTAT1);
		rpupei = I915_READ(GEN6_RP_CUR_UP_EI);
		rpcurup = I915_READ(GEN6_RP_CUR_UP);
		rpprevup = I915_READ(GEN6_RP_PREV_UP);
		rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI);
		rpcurdown = I915_READ(GEN6_RP_CUR_DOWN);
		rpprevdown = I915_READ(GEN6_RP_PREV_DOWN);
		rpupei = I915_READ(GEN6_RP_CUR_UP_EI) & GEN6_CURICONT_MASK;
		rpcurup = I915_READ(GEN6_RP_CUR_UP) & GEN6_CURBSYTAVG_MASK;
		rpprevup = I915_READ(GEN6_RP_PREV_UP) & GEN6_CURBSYTAVG_MASK;
		rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI) & GEN6_CURIAVG_MASK;
		rpcurdown = I915_READ(GEN6_RP_CUR_DOWN) & GEN6_CURBSYTAVG_MASK;
		rpprevdown = I915_READ(GEN6_RP_PREV_DOWN) & GEN6_CURBSYTAVG_MASK;
		if (IS_GEN9(dev))
			cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
		else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
@@ -1261,21 +1291,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
		seq_printf(m, "RPDECLIMIT: 0x%08x\n", rpdeclimit);
		seq_printf(m, "RPNSWREQ: %dMHz\n", reqf);
		seq_printf(m, "CAGF: %dMHz\n", cagf);
		seq_printf(m, "RP CUR UP EI: %dus\n", rpupei &
			   GEN6_CURICONT_MASK);
		seq_printf(m, "RP CUR UP: %dus\n", rpcurup &
			   GEN6_CURBSYTAVG_MASK);
		seq_printf(m, "RP PREV UP: %dus\n", rpprevup &
			   GEN6_CURBSYTAVG_MASK);
		seq_printf(m, "RP CUR UP EI: %d (%dus)\n",
			   rpupei, GT_PM_INTERVAL_TO_US(dev_priv, rpupei));
		seq_printf(m, "RP CUR UP: %d (%dus)\n",
			   rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup));
		seq_printf(m, "RP PREV UP: %d (%dus)\n",
			   rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup));
		seq_printf(m, "Up threshold: %d%%\n",
			   dev_priv->rps.up_threshold);

		seq_printf(m, "RP CUR DOWN EI: %dus\n", rpdownei &
			   GEN6_CURIAVG_MASK);
		seq_printf(m, "RP CUR DOWN: %dus\n", rpcurdown &
			   GEN6_CURBSYTAVG_MASK);
		seq_printf(m, "RP PREV DOWN: %dus\n", rpprevdown &
			   GEN6_CURBSYTAVG_MASK);
		seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n",
			   rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei));
		seq_printf(m, "RP CUR DOWN: %d (%dus)\n",
			   rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown));
		seq_printf(m, "RP PREV DOWN: %d (%dus)\n",
			   rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown));
		seq_printf(m, "Down threshold: %d%%\n",
			   dev_priv->rps.down_threshold);

@@ -1469,12 +1499,11 @@ static int i915_forcewake_domains(struct seq_file *m, void *data)
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_uncore_forcewake_domain *fw_domain;
	int i;

	spin_lock_irq(&dev_priv->uncore.lock);
	for_each_fw_domain(fw_domain, dev_priv, i) {
	for_each_fw_domain(fw_domain, dev_priv) {
		seq_printf(m, "%s.wake_count = %u\n",
			   intel_uncore_forcewake_domain_to_str(i),
			   intel_uncore_forcewake_domain_to_str(fw_domain->id),
			   fw_domain->wake_count);
	}
	spin_unlock_irq(&dev_priv->uncore.lock);
@@ -2405,10 +2434,11 @@ static int i915_llc(struct seq_file *m, void *data)
	struct drm_info_node *node = m->private;
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	const bool edram = INTEL_GEN(dev_priv) > 8;

	/* Size calculation for LLC is a bit of a pain. Ignore for now. */
	seq_printf(m, "LLC: %s\n", yesno(HAS_LLC(dev)));
	seq_printf(m, "eLLC: %zuMB\n", dev_priv->ellc_size);
	seq_printf(m, "%s: %lluMB\n", edram ? "eDRAM" : "eLLC",
		   intel_uncore_edram_size(dev_priv)/1024/1024);

	return 0;
}
@@ -4723,7 +4753,7 @@ i915_wedged_get(void *data, u64 *val)
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;

	*val = atomic_read(&dev_priv->gpu_error.reset_counter);
	*val = i915_terminally_wedged(&dev_priv->gpu_error);

	return 0;
}
+16 −16
Original line number Diff line number Diff line
@@ -257,13 +257,6 @@ static int i915_get_bridge_dev(struct drm_device *dev)
	return 0;
}

#define MCHBAR_I915 0x44
#define MCHBAR_I965 0x48
#define MCHBAR_SIZE (4*4096)

#define DEVEN_REG 0x54
#define   DEVEN_MCHBAR_EN (1 << 28)

/* Allocate space for the MCH regs if needed, return nonzero on error */
static int
intel_alloc_mchbar_resource(struct drm_device *dev)
@@ -325,7 +318,7 @@ intel_setup_mchbar(struct drm_device *dev)
	dev_priv->mchbar_need_disable = false;

	if (IS_I915G(dev) || IS_I915GM(dev)) {
		pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
		pci_read_config_dword(dev_priv->bridge_dev, DEVEN, &temp);
		enabled = !!(temp & DEVEN_MCHBAR_EN);
	} else {
		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
@@ -343,7 +336,7 @@ intel_setup_mchbar(struct drm_device *dev)

	/* Space is allocated or reserved, so enable it. */
	if (IS_I915G(dev) || IS_I915GM(dev)) {
		pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG,
		pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
				       temp | DEVEN_MCHBAR_EN);
	} else {
		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
@@ -356,17 +349,24 @@ intel_teardown_mchbar(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
	u32 temp;

	if (dev_priv->mchbar_need_disable) {
		if (IS_I915G(dev) || IS_I915GM(dev)) {
			pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
			temp &= ~DEVEN_MCHBAR_EN;
			pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp);
			u32 deven_val;

			pci_read_config_dword(dev_priv->bridge_dev, DEVEN,
					      &deven_val);
			deven_val &= ~DEVEN_MCHBAR_EN;
			pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
					       deven_val);
		} else {
			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
			temp &= ~1;
			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp);
			u32 mchbar_val;

			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg,
					      &mchbar_val);
			mchbar_val &= ~1;
			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg,
					       mchbar_val);
		}
	}

+100 −93
Original line number Diff line number Diff line
@@ -567,10 +567,9 @@ static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
	drm_modeset_unlock_all(dev);
}

static int intel_suspend_complete(struct drm_i915_private *dev_priv);
static int vlv_resume_prepare(struct drm_i915_private *dev_priv,
			      bool rpm_resume);
static int bxt_resume_prepare(struct drm_i915_private *dev_priv);
static int vlv_suspend_complete(struct drm_i915_private *dev_priv);

static bool suspend_to_idle(struct drm_i915_private *dev_priv)
{
@@ -640,8 +639,7 @@ static int i915_drm_suspend(struct drm_device *dev)

	intel_display_set_init_power(dev_priv, false);

	if (HAS_CSR(dev_priv))
		flush_work(&dev_priv->csr.work);
	intel_csr_ucode_suspend(dev_priv);

out:
	enable_rpm_wakeref_asserts(dev_priv);
@@ -657,7 +655,8 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)

	disable_rpm_wakeref_asserts(dev_priv);

	fw_csr = suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
	fw_csr = !IS_BROXTON(dev_priv) &&
		suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
	/*
	 * In case of firmware assisted context save/restore don't manually
	 * deinit the power domains. This also means the CSR/DMC firmware will
@@ -668,7 +667,13 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
	if (!fw_csr)
		intel_power_domains_suspend(dev_priv);

	ret = intel_suspend_complete(dev_priv);
	ret = 0;
	if (IS_BROXTON(dev_priv))
		bxt_enable_dc9(dev_priv);
	else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
		hsw_enable_pc8(dev_priv);
	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
		ret = vlv_suspend_complete(dev_priv);

	if (ret) {
		DRM_ERROR("Suspend complete failed: %d\n", ret);
@@ -732,6 +737,8 @@ static int i915_drm_resume(struct drm_device *dev)

	disable_rpm_wakeref_asserts(dev_priv);

	intel_csr_ucode_resume(dev_priv);

	mutex_lock(&dev->struct_mutex);
	i915_gem_restore_gtt_mappings(dev);
	mutex_unlock(&dev->struct_mutex);
@@ -802,7 +809,7 @@ static int i915_drm_resume(struct drm_device *dev)
static int i915_drm_resume_early(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	int ret = 0;
	int ret;

	/*
	 * We have a resume ordering issue with the snd-hda driver also
@@ -813,6 +820,36 @@ static int i915_drm_resume_early(struct drm_device *dev)
	 * FIXME: This should be solved with a special hdmi sink device or
	 * similar so that power domains can be employed.
	 */

	/*
	 * Note that we need to set the power state explicitly, since we
	 * powered off the device during freeze and the PCI core won't power
	 * it back up for us during thaw. Powering off the device during
	 * freeze is not a hard requirement though, and during the
	 * suspend/resume phases the PCI core makes sure we get here with the
	 * device powered on. So in case we change our freeze logic and keep
	 * the device powered we can also remove the following set power state
	 * call.
	 */
	ret = pci_set_power_state(dev->pdev, PCI_D0);
	if (ret) {
		DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret);
		goto out;
	}

	/*
	 * Note that pci_enable_device() first enables any parent bridge
	 * device and only then sets the power state for this device. The
	 * bridge enabling is a nop though, since bridge devices are resumed
	 * first. The order of enabling power and enabling the device is
	 * imposed by the PCI core as described above, so here we preserve the
	 * same order for the freeze/thaw phases.
	 *
	 * TODO: eventually we should remove pci_disable_device() /
	 * pci_enable_enable_device() from suspend/resume. Due to how they
	 * depend on the device enable refcount we can't anyway depend on them
	 * disabling/enabling the device.
	 */
	if (pci_enable_device(dev->pdev)) {
		ret = -EIO;
		goto out;
@@ -830,21 +867,25 @@ static int i915_drm_resume_early(struct drm_device *dev)

	intel_uncore_early_sanitize(dev, true);

	if (IS_BROXTON(dev))
		ret = bxt_resume_prepare(dev_priv);
	else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
	if (IS_BROXTON(dev)) {
		if (!dev_priv->suspended_to_idle)
			gen9_sanitize_dc_state(dev_priv);
		bxt_disable_dc9(dev_priv);
	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
		hsw_disable_pc8(dev_priv);
	}

	intel_uncore_sanitize(dev);

	if (!(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload))
	if (IS_BROXTON(dev_priv) ||
	    !(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload))
		intel_power_domains_init_hw(dev_priv, true);

	enable_rpm_wakeref_asserts(dev_priv);

out:
	dev_priv->suspended_to_idle = false;

	enable_rpm_wakeref_asserts(dev_priv);

	return ret;
}

@@ -880,23 +921,32 @@ int i915_resume_switcheroo(struct drm_device *dev)
int i915_reset(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	bool simulated;
	struct i915_gpu_error *error = &dev_priv->gpu_error;
	unsigned reset_counter;
	int ret;

	intel_reset_gt_powersave(dev);

	mutex_lock(&dev->struct_mutex);

	i915_gem_reset(dev);
	/* Clear any previous failed attempts at recovery. Time to try again. */
	atomic_andnot(I915_WEDGED, &error->reset_counter);

	/* Clear the reset-in-progress flag and increment the reset epoch. */
	reset_counter = atomic_inc_return(&error->reset_counter);
	if (WARN_ON(__i915_reset_in_progress(reset_counter))) {
		ret = -EIO;
		goto error;
	}

	simulated = dev_priv->gpu_error.stop_rings != 0;
	i915_gem_reset(dev);

	ret = intel_gpu_reset(dev, ALL_ENGINES);

	/* Also reset the gpu hangman. */
	if (simulated) {
	if (error->stop_rings != 0) {
		DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
		dev_priv->gpu_error.stop_rings = 0;
		error->stop_rings = 0;
		if (ret == -ENODEV) {
			DRM_INFO("Reset not implemented, but ignoring "
				 "error for simulated gpu hangs\n");
@@ -908,9 +958,11 @@ int i915_reset(struct drm_device *dev)
		pr_notice("drm/i915: Resetting chip after gpu hang\n");

	if (ret) {
		if (ret != -ENODEV)
			DRM_ERROR("Failed to reset chip: %i\n", ret);
		mutex_unlock(&dev->struct_mutex);
		return ret;
		else
			DRM_DEBUG_DRIVER("GPU reset disabled\n");
		goto error;
	}

	intel_overlay_reset(dev_priv);
@@ -929,20 +981,14 @@ int i915_reset(struct drm_device *dev)
	 * was running at the time of the reset (i.e. we weren't VT
	 * switched away).
	 */

	/* Used to prevent gem_check_wedged returning -EAGAIN during gpu reset */
	dev_priv->gpu_error.reload_in_reset = true;

	ret = i915_gem_init_hw(dev);

	dev_priv->gpu_error.reload_in_reset = false;

	mutex_unlock(&dev->struct_mutex);
	if (ret) {
		DRM_ERROR("Failed hw init on reset %d\n", ret);
		return ret;
		goto error;
	}

	mutex_unlock(&dev->struct_mutex);

	/*
	 * rps/rc6 re-init is necessary to restore state lost after the
	 * reset and the re-install of gt irqs. Skip for ironlake per
@@ -953,6 +999,11 @@ int i915_reset(struct drm_device *dev)
		intel_enable_gt_powersave(dev);

	return 0;

error:
	atomic_or(I915_WEDGED, &error->reset_counter);
	mutex_unlock(&dev->struct_mutex);
	return ret;
}

static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1059,44 +1110,6 @@ static int i915_pm_resume(struct device *dev)
	return i915_drm_resume(drm_dev);
}

static int hsw_suspend_complete(struct drm_i915_private *dev_priv)
{
	hsw_enable_pc8(dev_priv);

	return 0;
}

static int bxt_suspend_complete(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = dev_priv->dev;

	/* TODO: when DC5 support is added disable DC5 here. */

	broxton_ddi_phy_uninit(dev);
	broxton_uninit_cdclk(dev);
	bxt_enable_dc9(dev_priv);

	return 0;
}

static int bxt_resume_prepare(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = dev_priv->dev;

	/* TODO: when CSR FW support is added make sure the FW is loaded */

	bxt_disable_dc9(dev_priv);

	/*
	 * TODO: when DC5 support is added enable DC5 here if the CSR FW
	 * is available.
	 */
	broxton_init_cdclk(dev);
	broxton_ddi_phy_init(dev);

	return 0;
}

/*
 * Save all Gunit registers that may be lost after a D3 and a subsequent
 * S0i[R123] transition. The list of registers needing a save/restore is
@@ -1502,7 +1515,16 @@ static int intel_runtime_suspend(struct device *device)
	intel_suspend_gt_powersave(dev);
	intel_runtime_pm_disable_interrupts(dev_priv);

	ret = intel_suspend_complete(dev_priv);
	ret = 0;
	if (IS_BROXTON(dev_priv)) {
		bxt_display_core_uninit(dev_priv);
		bxt_enable_dc9(dev_priv);
	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
		hsw_enable_pc8(dev_priv);
	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
		ret = vlv_suspend_complete(dev_priv);
	}

	if (ret) {
		DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret);
		intel_runtime_pm_enable_interrupts(dev_priv);
@@ -1576,12 +1598,17 @@ static int intel_runtime_resume(struct device *device)
	if (IS_GEN6(dev_priv))
		intel_init_pch_refclk(dev);

	if (IS_BROXTON(dev))
		ret = bxt_resume_prepare(dev_priv);
	else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
	if (IS_BROXTON(dev)) {
		bxt_disable_dc9(dev_priv);
		bxt_display_core_init(dev_priv, true);
		if (dev_priv->csr.dmc_payload &&
		    (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5))
			gen9_enable_dc5(dev_priv);
	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
		hsw_disable_pc8(dev_priv);
	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
		ret = vlv_resume_prepare(dev_priv, true);
	}

	/*
	 * No point of rolling back things in case of an error, as the best
@@ -1612,26 +1639,6 @@ static int intel_runtime_resume(struct device *device)
	return ret;
}

/*
 * This function implements common functionality of runtime and system
 * suspend sequence.
 */
static int intel_suspend_complete(struct drm_i915_private *dev_priv)
{
	int ret;

	if (IS_BROXTON(dev_priv))
		ret = bxt_suspend_complete(dev_priv);
	else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
		ret = hsw_suspend_complete(dev_priv);
	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
		ret = vlv_suspend_complete(dev_priv);
	else
		ret = 0;

	return ret;
}

static const struct dev_pm_ops i915_pm_ops = {
	/*
	 * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND,
Loading