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

Commit 2d62c799 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-2017-07-17' of git://anongit.freedesktop.org/git/drm-intel into drm-next

2nd round of 4.14 features:

- prep for deferred fbdev setup
- refactor fixed 16.16 computations and skl+ wm code (Mahesh Kumar)
- more cnl paches (Rodrigo, Imre et al)
- tighten context cleanup and handling (Chris Wilson)
- fix interlaced handling on skl+ (Mahesh Kumar)
- small bits as usual

* tag 'drm-intel-next-2017-07-17' of git://anongit.freedesktop.org/git/drm-intel: (84 commits)
  drm/i915: Update DRIVER_DATE to 20170717
  drm/i915: Protect against deferred fbdev setup
  drm/i915/fbdev: Always forward hotplug events
  drm/i915/skl+: unify cpp value in WM calculation
  drm/i915/skl+: WM calculation don't require height
  drm/i915: Addition wrapper for fixed16.16 operation
  drm/i915: cleanup fixed-point wrappers naming
  drm/i915: Always perform internal fixed16 division in 64 bits
  drm/i915: take-out common clamping code of fixed16 wrappers
  drm/i915/cnl: Add missing type case.
  drm/i915/cnl: Add max allowed Cannonlake DC.
  drm/i915: Make DP-MST connector info work
  drm/i915/cnl: Get DDI clock based on PLLs.
  drm/i915/cnl: Inherit RPS stuff from previous platforms.
  drm/i915/cnl: Gen10 render context size.
  drm/i915/cnl: Don't trust VBT's alternate pin for port D for now.
  drm/i915: Fix the kernel panic when using aliasing ppgtt
  drm/i915/cnl: Cannonlake color init.
  drm/i915/cnl: Add force wake for gen10+.
  x86/gpu: CNL uses the same GMS values as SKL
  ...
parents 5771a8c0 58947144
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -527,6 +527,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
	INTEL_BXT_IDS(&gen9_early_ops),
	INTEL_KBL_IDS(&gen9_early_ops),
	INTEL_GLK_IDS(&gen9_early_ops),
	INTEL_CNL_IDS(&gen9_early_ops),
};

static void __init
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ config DRM_I915
	select ACPI_BUTTON if ACPI
	select SYNC_FILE
	select IOSF_MBI
	select CRC32
	help
	  Choose this option if you have a system that has "Intel Graphics
	  Media Accelerator" or "HD Graphics" integrated graphics,
+1 −1
Original line number Diff line number Diff line
@@ -616,7 +616,7 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)

void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu)
{
	i915_gem_context_put_unlocked(vgpu->shadow_ctx);
	i915_gem_context_put(vgpu->shadow_ctx);
}

int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
+74 −29
Original line number Diff line number Diff line
@@ -1159,7 +1159,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
		intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);

		reqf = I915_READ(GEN6_RPNSWREQ);
		if (IS_GEN9(dev_priv))
		if (INTEL_GEN(dev_priv) >= 9)
			reqf >>= 23;
		else {
			reqf &= ~GEN6_TURBO_DISABLE;
@@ -1181,7 +1181,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
		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_priv))
		if (INTEL_GEN(dev_priv) >= 9)
			cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
		else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
			cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
@@ -1210,7 +1210,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
			   dev_priv->rps.pm_intrmsk_mbz);
		seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
		seq_printf(m, "Render p-state ratio: %d\n",
			   (gt_perf_status & (IS_GEN9(dev_priv) ? 0x1ff00 : 0xff00)) >> 8);
			   (gt_perf_status & (INTEL_GEN(dev_priv) >= 9 ? 0x1ff00 : 0xff00)) >> 8);
		seq_printf(m, "Render p-state VID: %d\n",
			   gt_perf_status & 0xff);
		seq_printf(m, "Render p-state limit: %d\n",
@@ -1241,18 +1241,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused)

		max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 :
			    rp_state_cap >> 16) & 0xff;
		max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
		max_freq *= (IS_GEN9_BC(dev_priv) ||
			     IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
		seq_printf(m, "Lowest (RPN) frequency: %dMHz\n",
			   intel_gpu_freq(dev_priv, max_freq));

		max_freq = (rp_state_cap & 0xff00) >> 8;
		max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
		max_freq *= (IS_GEN9_BC(dev_priv) ||
			     IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
		seq_printf(m, "Nominal (RP1) frequency: %dMHz\n",
			   intel_gpu_freq(dev_priv, max_freq));

		max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 16 :
			    rp_state_cap >> 0) & 0xff;
		max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
		max_freq *= (IS_GEN9_BC(dev_priv) ||
			     IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
		seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
			   intel_gpu_freq(dev_priv, max_freq));
		seq_printf(m, "Max overclocked frequency: %dMHz\n",
@@ -1407,6 +1410,23 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
	return 0;
}

static int i915_reset_info(struct seq_file *m, void *unused)
{
	struct drm_i915_private *dev_priv = node_to_i915(m->private);
	struct i915_gpu_error *error = &dev_priv->gpu_error;
	struct intel_engine_cs *engine;
	enum intel_engine_id id;

	seq_printf(m, "full gpu reset = %u\n", i915_reset_count(error));

	for_each_engine(engine, dev_priv, id) {
		seq_printf(m, "%s = %u\n", engine->name,
			   i915_reset_engine_count(error, engine));
	}

	return 0;
}

static int ironlake_drpc_info(struct seq_file *m)
{
	struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -1838,7 +1858,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
	if (ret)
		goto out;

	if (IS_GEN9_BC(dev_priv)) {
	if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
		/* Convert GT frequency to 50 HZ units */
		min_gpu_freq =
			dev_priv->rps.min_freq_softlimit / GEN9_FREQ_SCALER;
@@ -1858,7 +1878,8 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
				       &ia_freq);
		seq_printf(m, "%d\t\t%d\t\t\t\t%d\n",
			   intel_gpu_freq(dev_priv, (gpu_freq *
						     (IS_GEN9_BC(dev_priv) ?
						     (IS_GEN9_BC(dev_priv) ||
						      IS_CANNONLAKE(dev_priv) ?
						      GEN9_FREQ_SCALER : 1))),
			   ((ia_freq >> 0) & 0xff) * 100,
			   ((ia_freq >> 8) & 0xff) * 100);
@@ -1914,7 +1935,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
		return ret;

#ifdef CONFIG_DRM_FBDEV_EMULATION
	if (dev_priv->fbdev) {
	if (dev_priv->fbdev && dev_priv->fbdev->helper.fb) {
		fbdev_fb = to_intel_framebuffer(dev_priv->fbdev->helper.fb);

		seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
@@ -1970,7 +1991,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
	if (ret)
		return ret;

	list_for_each_entry(ctx, &dev_priv->context_list, link) {
	list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
		seq_printf(m, "HW context %u ", ctx->hw_id);
		if (ctx->pid) {
			struct task_struct *task;
@@ -2076,7 +2097,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
	if (ret)
		return ret;

	list_for_each_entry(ctx, &dev_priv->context_list, link)
	list_for_each_entry(ctx, &dev_priv->contexts.list, link)
		for_each_engine(engine, dev_priv, id)
			i915_dump_lrc_obj(m, ctx, engine);

@@ -2310,6 +2331,8 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
	seq_printf(m, "GPU busy? %s [%d requests]\n",
		   yesno(dev_priv->gt.awake), dev_priv->gt.active_requests);
	seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
	seq_printf(m, "Boosts outstanding? %d\n",
		   atomic_read(&dev_priv->rps.num_waiters));
	seq_printf(m, "Frequency requested %d\n",
		   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
	seq_printf(m, "  min hard:%d, soft:%d; max soft:%d, hard:%d\n",
@@ -2323,22 +2346,20 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
		   intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq));

	mutex_lock(&dev->filelist_mutex);
	spin_lock(&dev_priv->rps.client_lock);
	list_for_each_entry_reverse(file, &dev->filelist, lhead) {
		struct drm_i915_file_private *file_priv = file->driver_priv;
		struct task_struct *task;

		rcu_read_lock();
		task = pid_task(file->pid, PIDTYPE_PID);
		seq_printf(m, "%s [%d]: %d boosts%s\n",
		seq_printf(m, "%s [%d]: %d boosts\n",
			   task ? task->comm : "<unknown>",
			   task ? task->pid : -1,
			   file_priv->rps.boosts,
			   list_empty(&file_priv->rps.link) ? "" : ", active");
			   atomic_read(&file_priv->rps.boosts));
		rcu_read_unlock();
	}
	seq_printf(m, "Kernel (anonymous) boosts: %d\n", dev_priv->rps.boosts);
	spin_unlock(&dev_priv->rps.client_lock);
	seq_printf(m, "Kernel (anonymous) boosts: %d\n",
		   atomic_read(&dev_priv->rps.boosts));
	mutex_unlock(&dev->filelist_mutex);

	if (INTEL_GEN(dev_priv) >= 6 &&
@@ -3289,6 +3310,7 @@ static int i915_display_info(struct seq_file *m, void *unused)
static int i915_engine_info(struct seq_file *m, void *unused)
{
	struct drm_i915_private *dev_priv = node_to_i915(m->private);
	struct i915_gpu_error *error = &dev_priv->gpu_error;
	struct intel_engine_cs *engine;
	enum intel_engine_id id;

@@ -3312,6 +3334,8 @@ static int i915_engine_info(struct seq_file *m, void *unused)
			   engine->hangcheck.seqno,
			   jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp),
			   engine->timeline->inflight_seqnos);
		seq_printf(m, "\tReset count: %d\n",
			   i915_reset_engine_count(error, engine));

		rcu_read_lock();

@@ -3758,13 +3782,18 @@ static ssize_t i915_displayport_test_active_write(struct file *file,

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		struct intel_encoder *encoder;

		if (connector->connector_type !=
		    DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected &&
		    connector->encoder != NULL) {
			intel_dp = enc_to_intel_dp(connector->encoder);
		encoder = to_intel_encoder(connector->encoder);
		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
			continue;

		if (encoder && connector->status == connector_status_connected) {
			intel_dp = enc_to_intel_dp(&encoder->base);
			status = kstrtoint(input_buffer, 10, &val);
			if (status < 0)
				break;
@@ -3796,13 +3825,18 @@ static int i915_displayport_test_active_show(struct seq_file *m, void *data)

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		struct intel_encoder *encoder;

		if (connector->connector_type !=
		    DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected &&
		    connector->encoder != NULL) {
			intel_dp = enc_to_intel_dp(connector->encoder);
		encoder = to_intel_encoder(connector->encoder);
		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
			continue;

		if (encoder && connector->status == connector_status_connected) {
			intel_dp = enc_to_intel_dp(&encoder->base);
			if (intel_dp->compliance.test_active)
				seq_puts(m, "1");
			else
@@ -3842,13 +3876,18 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data)

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		struct intel_encoder *encoder;

		if (connector->connector_type !=
		    DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected &&
		    connector->encoder != NULL) {
			intel_dp = enc_to_intel_dp(connector->encoder);
		encoder = to_intel_encoder(connector->encoder);
		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
			continue;

		if (encoder && connector->status == connector_status_connected) {
			intel_dp = enc_to_intel_dp(&encoder->base);
			if (intel_dp->compliance.test_type ==
			    DP_TEST_LINK_EDID_READ)
				seq_printf(m, "%lx",
@@ -3895,13 +3934,18 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data)

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		struct intel_encoder *encoder;

		if (connector->connector_type !=
		    DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected &&
		    connector->encoder != NULL) {
			intel_dp = enc_to_intel_dp(connector->encoder);
		encoder = to_intel_encoder(connector->encoder);
		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
			continue;

		if (encoder && connector->status == connector_status_connected) {
			intel_dp = enc_to_intel_dp(&encoder->base);
			seq_printf(m, "%02lx", intel_dp->compliance.test_type);
		} else
			seq_puts(m, "0");
@@ -4824,6 +4868,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
	{"i915_huc_load_status", i915_huc_load_status_info, 0},
	{"i915_frequency_info", i915_frequency_info, 0},
	{"i915_hangcheck_info", i915_hangcheck_info, 0},
	{"i915_reset_info", i915_reset_info, 0},
	{"i915_drpc_info", i915_drpc_info, 0},
	{"i915_emon_status", i915_emon_status, 0},
	{"i915_ring_freq_table", i915_ring_freq_table, 0},
+104 −27
Original line number Diff line number Diff line
@@ -132,9 +132,13 @@ static enum intel_pch intel_virt_detect_pch(struct drm_i915_private *dev_priv)
		DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n");
	} else if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
		ret = PCH_CPT;
		DRM_DEBUG_KMS("Assuming CouarPoint PCH\n");
		DRM_DEBUG_KMS("Assuming CougarPoint PCH\n");
	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
		ret = PCH_LPT;
		if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
			dev_priv->pch_id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
		else
			dev_priv->pch_id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
		DRM_DEBUG_KMS("Assuming LynxPoint PCH\n");
	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
		ret = PCH_SPT;
@@ -173,29 +177,25 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
	while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
			unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
			unsigned short id_ext = pch->device &
				INTEL_PCH_DEVICE_ID_MASK_EXT;

			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
			dev_priv->pch_id = id;

			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
				dev_priv->pch_type = PCH_IBX;
				DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
				WARN_ON(!IS_GEN5(dev_priv));
			} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
				dev_priv->pch_id = id;
				dev_priv->pch_type = PCH_CPT;
				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
				WARN_ON(!(IS_GEN6(dev_priv) ||
					IS_IVYBRIDGE(dev_priv)));
				WARN_ON(!IS_GEN6(dev_priv) &&
					!IS_IVYBRIDGE(dev_priv));
			} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
				/* PantherPoint is CPT compatible */
				dev_priv->pch_id = id;
				dev_priv->pch_type = PCH_CPT;
				DRM_DEBUG_KMS("Found PantherPoint PCH\n");
				WARN_ON(!(IS_GEN6(dev_priv) ||
					IS_IVYBRIDGE(dev_priv)));
				WARN_ON(!IS_GEN6(dev_priv) &&
					!IS_IVYBRIDGE(dev_priv));
			} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
				dev_priv->pch_id = id;
				dev_priv->pch_type = PCH_LPT;
				DRM_DEBUG_KMS("Found LynxPoint PCH\n");
				WARN_ON(!IS_HASWELL(dev_priv) &&
@@ -203,51 +203,60 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
				WARN_ON(IS_HSW_ULT(dev_priv) ||
					IS_BDW_ULT(dev_priv));
			} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
				dev_priv->pch_id = id;
				dev_priv->pch_type = PCH_LPT;
				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
				WARN_ON(!IS_HASWELL(dev_priv) &&
					!IS_BROADWELL(dev_priv));
				WARN_ON(!IS_HSW_ULT(dev_priv) &&
					!IS_BDW_ULT(dev_priv));
			} else if (id == INTEL_PCH_WPT_DEVICE_ID_TYPE) {
				/* WildcatPoint is LPT compatible */
				dev_priv->pch_type = PCH_LPT;
				DRM_DEBUG_KMS("Found WildcatPoint PCH\n");
				WARN_ON(!IS_HASWELL(dev_priv) &&
					!IS_BROADWELL(dev_priv));
				WARN_ON(IS_HSW_ULT(dev_priv) ||
					IS_BDW_ULT(dev_priv));
			} else if (id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE) {
				/* WildcatPoint is LPT compatible */
				dev_priv->pch_type = PCH_LPT;
				DRM_DEBUG_KMS("Found WildcatPoint LP PCH\n");
				WARN_ON(!IS_HASWELL(dev_priv) &&
					!IS_BROADWELL(dev_priv));
				WARN_ON(!IS_HSW_ULT(dev_priv) &&
					!IS_BDW_ULT(dev_priv));
			} else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
				dev_priv->pch_id = id;
				dev_priv->pch_type = PCH_SPT;
				DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
				WARN_ON(!IS_SKYLAKE(dev_priv) &&
					!IS_KABYLAKE(dev_priv));
			} else if (id_ext == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
				dev_priv->pch_id = id_ext;
			} else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
				dev_priv->pch_type = PCH_SPT;
				DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
				WARN_ON(!IS_SKYLAKE(dev_priv) &&
					!IS_KABYLAKE(dev_priv));
			} else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
				dev_priv->pch_id = id;
				dev_priv->pch_type = PCH_KBP;
				DRM_DEBUG_KMS("Found KabyPoint PCH\n");
				WARN_ON(!IS_SKYLAKE(dev_priv) &&
					!IS_KABYLAKE(dev_priv));
			} else if (id == INTEL_PCH_CNP_DEVICE_ID_TYPE) {
				dev_priv->pch_id = id;
				dev_priv->pch_type = PCH_CNP;
				DRM_DEBUG_KMS("Found CannonPoint PCH\n");
				WARN_ON(!IS_CANNONLAKE(dev_priv) &&
					!IS_COFFEELAKE(dev_priv));
			} else if (id_ext == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
				dev_priv->pch_id = id_ext;
			} else if (id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
				dev_priv->pch_type = PCH_CNP;
				DRM_DEBUG_KMS("Found CannonPoint LP PCH\n");
				WARN_ON(!IS_CANNONLAKE(dev_priv) &&
					!IS_COFFEELAKE(dev_priv));
			} else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
				   (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) ||
				   ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
			} else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
				   id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
				   (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
				    pch->subsystem_vendor ==
					    PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
				    pch->subsystem_device ==
					    PCI_SUBDEVICE_ID_QEMU)) {
				dev_priv->pch_id = id;
				dev_priv->pch_type =
					intel_virt_detect_pch(dev_priv);
			} else
@@ -331,6 +340,8 @@ static int i915_getparam(struct drm_device *dev, void *data,
		break;
	case I915_PARAM_HAS_GPU_RESET:
		value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv);
		if (value && intel_has_reset_engine(dev_priv))
			value = 2;
		break;
	case I915_PARAM_HAS_RESOURCE_STREAMER:
		value = HAS_RESOURCE_STREAMER(dev_priv);
@@ -585,16 +596,18 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {

static void i915_gem_fini(struct drm_i915_private *dev_priv)
{
	flush_workqueue(dev_priv->wq);

	mutex_lock(&dev_priv->drm.struct_mutex);
	intel_uc_fini_hw(dev_priv);
	i915_gem_cleanup_engines(dev_priv);
	i915_gem_context_fini(dev_priv);
	i915_gem_contexts_fini(dev_priv);
	i915_gem_cleanup_userptr(dev_priv);
	mutex_unlock(&dev_priv->drm.struct_mutex);

	i915_gem_drain_freed_objects(dev_priv);

	WARN_ON(!list_empty(&dev_priv->context_list));
	WARN_ON(!list_empty(&dev_priv->contexts.list));
}

static int i915_load_modeset_init(struct drm_device *dev)
@@ -1427,9 +1440,10 @@ static void i915_driver_release(struct drm_device *dev)

static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
{
	struct drm_i915_private *i915 = to_i915(dev);
	int ret;

	ret = i915_gem_open(dev, file);
	ret = i915_gem_open(i915, file);
	if (ret)
		return ret;

@@ -1459,7 +1473,7 @@ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
	struct drm_i915_file_private *file_priv = file->driver_priv;

	mutex_lock(&dev->struct_mutex);
	i915_gem_context_close(dev, file);
	i915_gem_context_close(file);
	i915_gem_release(dev, file);
	mutex_unlock(&dev->struct_mutex);

@@ -1911,9 +1925,72 @@ void i915_reset(struct drm_i915_private *dev_priv)

error:
	i915_gem_set_wedged(dev_priv);
	i915_gem_retire_requests(dev_priv);
	goto finish;
}

/**
 * i915_reset_engine - reset GPU engine to recover from a hang
 * @engine: engine to reset
 *
 * Reset a specific GPU engine. Useful if a hang is detected.
 * Returns zero on successful reset or otherwise an error code.
 *
 * Procedure is:
 *  - identifies the request that caused the hang and it is dropped
 *  - reset engine (which will force the engine to idle)
 *  - re-init/configure engine
 */
int i915_reset_engine(struct intel_engine_cs *engine)
{
	struct i915_gpu_error *error = &engine->i915->gpu_error;
	struct drm_i915_gem_request *active_request;
	int ret;

	GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));

	DRM_DEBUG_DRIVER("resetting %s\n", engine->name);

	active_request = i915_gem_reset_prepare_engine(engine);
	if (IS_ERR(active_request)) {
		DRM_DEBUG_DRIVER("Previous reset failed, promote to full reset\n");
		ret = PTR_ERR(active_request);
		goto out;
	}

	/*
	 * The request that caused the hang is stuck on elsp, we know the
	 * active request and can drop it, adjust head to skip the offending
	 * request to resume executing remaining requests in the queue.
	 */
	i915_gem_reset_engine(engine, active_request);

	/* Finally, reset just this engine. */
	ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine));

	i915_gem_reset_finish_engine(engine);

	if (ret) {
		/* If we fail here, we expect to fallback to a global reset */
		DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n",
				 engine->name, ret);
		goto out;
	}

	/*
	 * The engine and its registers (and workarounds in case of render)
	 * have been reset to their default values. Follow the init_ring
	 * process to program RING_MODE, HWSP and re-enable submission.
	 */
	ret = engine->init_hw(engine);
	if (ret)
		goto out;

	error->reset_engine_count[engine->id]++;
out:
	return ret;
}

static int i915_pm_suspend(struct device *kdev)
{
	struct pci_dev *pdev = to_pci_dev(kdev);
Loading