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

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

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

Final block of feature work for 4.11:

- gen8 pd cleanup from Matthew Auld
- more cleanups for view/vma (Chris)
- dmc support on glk (Anusha Srivatsa)
- use core crc api (Tomue)
- track wedged requests using fence.error (Chris)
- lots of psr fixes (Nagaraju, Vathsala)
- dp mst support, acked for merging through drm-intel by Takashi
  (Libin)
- huc loading support, including uapi for libva to use it (Anusha
  Srivatsa)

* tag 'drm-intel-next-2017-01-23' of git://anongit.freedesktop.org/git/drm-intel: (111 commits)
  drm/i915: Update DRIVER_DATE to 20170123
  drm/i915: reinstate call to trace_i915_vma_bind
  drm/i915: Assert that created vma has a whole number of pages
  drm/i915: Assert the drm_mm_node is allocated when on the VM lists
  drm/i915: Treat an error from i915_vma_instance() as unlikely
  drm/i915: Reject vma creation larger than address space
  drm/i915: Use common LRU inactive vma bumping for unpin_from_display
  drm/i915: Do an unlocked wait before set-cache-level ioctl
  drm/i915/huc: Assert that HuC vma is placed in GuC accessible range
  drm/i915/huc: Avoid attempting to authenticate non-existent fw
  drm/i915: Set adjustment to zero on Up/Down interrupts if freq is already max/min
  drm/i915: Remove the double handling of 'flags from intel_mode_from_pipe_config()
  drm/i915: Remove crtc->config usage from intel_modeset_readout_hw_state()
  drm/i915: Release temporary load-detect state upon switching
  drm/i915: Remove i915_gem_object_to_ggtt()
  drm/i915: Remove i915_vma_create from VMA API
  drm/i915: Add a check that the VMA instance we lookup matches the request
  drm/i915: Rename some warts in the VMA API
  drm/i915: Track pinned vma in intel_plane_state
  drm/i915/get_params: Add HuC status to getparams
  ...
parents c4d79c22 add6329c
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -19,6 +19,23 @@ PCM
===
To be added

Pin Initialization
==================
Each pin may have several device entries (virtual pins). On Intel platform,
the device entries number is dynamically changed. If DP MST hub is connected,
it is in DP MST mode, and the device entries number is 3. Otherwise, the
device entries number is 1.

To simplify the implementation, all the device entries will be initialized
when bootup no matter whether it is in DP MST mode or not.

Connection list
===============
DP MST reuses connection list code. The code can be reused because
device entries on the same pin have the same connection list.

This means DP MST gets the device entry connection list without the
device entry setting.

Jack
====
+2 −0
Original line number Diff line number Diff line
@@ -56,7 +56,9 @@ i915-y += i915_cmd_parser.o \

# general-purpose microcontroller (GuC) support
i915-y += intel_uc.o \
	  intel_guc_log.o \
	  intel_guc_loader.o \
	  intel_huc.o \
	  i915_guc_submission.o

# autogenerated null render state
+10 −23
Original line number Diff line number Diff line
@@ -41,47 +41,34 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
{
	struct intel_gvt *gvt = vgpu->gvt;
	struct drm_i915_private *dev_priv = gvt->dev_priv;
	u32 alloc_flag, search_flag;
	unsigned int flags;
	u64 start, end, size;
	struct drm_mm_node *node;
	int retried = 0;
	int ret;

	if (high_gm) {
		search_flag = DRM_MM_SEARCH_BELOW;
		alloc_flag = DRM_MM_CREATE_TOP;
		node = &vgpu->gm.high_gm_node;
		size = vgpu_hidden_sz(vgpu);
		start = gvt_hidden_gmadr_base(gvt);
		end = gvt_hidden_gmadr_end(gvt);
		flags = PIN_HIGH;
	} else {
		search_flag = DRM_MM_SEARCH_DEFAULT;
		alloc_flag = DRM_MM_CREATE_DEFAULT;
		node = &vgpu->gm.low_gm_node;
		size = vgpu_aperture_sz(vgpu);
		start = gvt_aperture_gmadr_base(gvt);
		end = gvt_aperture_gmadr_end(gvt);
		flags = PIN_MAPPABLE;
	}

	mutex_lock(&dev_priv->drm.struct_mutex);
search_again:
	ret = drm_mm_insert_node_in_range_generic(&dev_priv->ggtt.base.mm,
						  node, size, 4096,
						  I915_COLOR_UNEVICTABLE,
						  start, end, search_flag,
						  alloc_flag);
	if (ret) {
		ret = i915_gem_evict_something(&dev_priv->ggtt.base,
					       size, 4096,
					       I915_COLOR_UNEVICTABLE,
					       start, end, 0);
		if (ret == 0 && ++retried < 3)
			goto search_again;

		gvt_err("fail to alloc %s gm space from host, retried %d\n",
				high_gm ? "high" : "low", retried);
	}
	ret = i915_gem_gtt_insert(&dev_priv->ggtt.base, node,
				  size, 4096, I915_COLOR_UNEVICTABLE,
				  start, end, flags);
	mutex_unlock(&dev_priv->drm.struct_mutex);
	if (ret)
		gvt_err("fail to alloc %s gm space from host\n",
			high_gm ? "high" : "low");

	return ret;
}

+95 −8
Original line number Diff line number Diff line
@@ -159,8 +159,35 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx",
			   i915_vma_is_ggtt(vma) ? "g" : "pp",
			   vma->node.start, vma->node.size);
		if (i915_vma_is_ggtt(vma))
			seq_printf(m, ", type: %u", vma->ggtt_view.type);
		if (i915_vma_is_ggtt(vma)) {
			switch (vma->ggtt_view.type) {
			case I915_GGTT_VIEW_NORMAL:
				seq_puts(m, ", normal");
				break;

			case I915_GGTT_VIEW_PARTIAL:
				seq_printf(m, ", partial [%08llx+%x]",
					   vma->ggtt_view.partial.offset << PAGE_SHIFT,
					   vma->ggtt_view.partial.size << PAGE_SHIFT);
				break;

			case I915_GGTT_VIEW_ROTATED:
				seq_printf(m, ", rotated [(%ux%u, stride=%u, offset=%u), (%ux%u, stride=%u, offset=%u)]",
					   vma->ggtt_view.rotated.plane[0].width,
					   vma->ggtt_view.rotated.plane[0].height,
					   vma->ggtt_view.rotated.plane[0].stride,
					   vma->ggtt_view.rotated.plane[0].offset,
					   vma->ggtt_view.rotated.plane[1].width,
					   vma->ggtt_view.rotated.plane[1].height,
					   vma->ggtt_view.rotated.plane[1].stride,
					   vma->ggtt_view.rotated.plane[1].offset);
				break;

			default:
				MISSING_CASE(vma->ggtt_view.type);
				break;
			}
		}
		if (vma->fence)
			seq_printf(m, " , fence: %d%s",
				   vma->fence->id,
@@ -2325,10 +2352,40 @@ static int i915_llc(struct seq_file *m, void *data)
	return 0;
}

static int i915_huc_load_status_info(struct seq_file *m, void *data)
{
	struct drm_i915_private *dev_priv = node_to_i915(m->private);
	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;

	if (!HAS_HUC_UCODE(dev_priv))
		return 0;

	seq_puts(m, "HuC firmware status:\n");
	seq_printf(m, "\tpath: %s\n", huc_fw->path);
	seq_printf(m, "\tfetch: %s\n",
		intel_uc_fw_status_repr(huc_fw->fetch_status));
	seq_printf(m, "\tload: %s\n",
		intel_uc_fw_status_repr(huc_fw->load_status));
	seq_printf(m, "\tversion wanted: %d.%d\n",
		huc_fw->major_ver_wanted, huc_fw->minor_ver_wanted);
	seq_printf(m, "\tversion found: %d.%d\n",
		huc_fw->major_ver_found, huc_fw->minor_ver_found);
	seq_printf(m, "\theader: offset is %d; size = %d\n",
		huc_fw->header_offset, huc_fw->header_size);
	seq_printf(m, "\tuCode: offset is %d; size = %d\n",
		huc_fw->ucode_offset, huc_fw->ucode_size);
	seq_printf(m, "\tRSA: offset is %d; size = %d\n",
		huc_fw->rsa_offset, huc_fw->rsa_size);

	seq_printf(m, "\nHuC status 0x%08x:\n", I915_READ(HUC_STATUS2));

	return 0;
}

static int i915_guc_load_status_info(struct seq_file *m, void *data)
{
	struct drm_i915_private *dev_priv = node_to_i915(m->private);
	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
	u32 tmp, i;

	if (!HAS_GUC_UCODE(dev_priv))
@@ -2336,15 +2393,15 @@ static int i915_guc_load_status_info(struct seq_file *m, void *data)

	seq_printf(m, "GuC firmware status:\n");
	seq_printf(m, "\tpath: %s\n",
		guc_fw->guc_fw_path);
		guc_fw->path);
	seq_printf(m, "\tfetch: %s\n",
		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
		intel_uc_fw_status_repr(guc_fw->fetch_status));
	seq_printf(m, "\tload: %s\n",
		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
		intel_uc_fw_status_repr(guc_fw->load_status));
	seq_printf(m, "\tversion wanted: %d.%d\n",
		guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
		guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted);
	seq_printf(m, "\tversion found: %d.%d\n",
		guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
		guc_fw->major_ver_found, guc_fw->minor_ver_found);
	seq_printf(m, "\theader: offset is %d; size = %d\n",
		guc_fw->header_offset, guc_fw->header_size);
	seq_printf(m, "\tuCode: offset is %d; size = %d\n",
@@ -2532,6 +2589,29 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_guc_log_control_fops,
			i915_guc_log_control_get, i915_guc_log_control_set,
			"%lld\n");

static const char *psr2_live_status(u32 val)
{
	static const char * const live_status[] = {
		"IDLE",
		"CAPTURE",
		"CAPTURE_FS",
		"SLEEP",
		"BUFON_FW",
		"ML_UP",
		"SU_STANDBY",
		"FAST_SLEEP",
		"DEEP_SLEEP",
		"BUF_ON",
		"TG_ON"
	};

	val = (val & EDP_PSR2_STATUS_STATE_MASK) >> EDP_PSR2_STATUS_STATE_SHIFT;
	if (val < ARRAY_SIZE(live_status))
		return live_status[val];

	return "unknown";
}

static int i915_edp_psr_status(struct seq_file *m, void *data)
{
	struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -2606,6 +2686,12 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)

		seq_printf(m, "Performance_Counter: %u\n", psrperf);
	}
	if (dev_priv->psr.psr2_support) {
		u32 psr2 = I915_READ(EDP_PSR2_STATUS_CTL);

		seq_printf(m, "EDP_PSR2_STATUS_CTL: %x [%s]\n",
			   psr2, psr2_live_status(psr2));
	}
	mutex_unlock(&dev_priv->psr.lock);

	intel_runtime_pm_put(dev_priv);
@@ -4553,6 +4639,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
	{"i915_guc_info", i915_guc_info, 0},
	{"i915_guc_load_status", i915_guc_load_status_info, 0},
	{"i915_guc_log_dump", i915_guc_log_dump, 0},
	{"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_drpc_info", i915_drpc_info, 0},
+29 −31
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#include "i915_trace.h"
#include "i915_vgpu.h"
#include "intel_drv.h"
#include "intel_uc.h"

static struct drm_driver driver;

@@ -315,6 +316,12 @@ static int i915_getparam(struct drm_device *dev, void *data,
	case I915_PARAM_MIN_EU_IN_POOL:
		value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
		break;
	case I915_PARAM_HUC_STATUS:
		/* The register is already force-woken. We dont need
		 * any rpm here
		 */
		value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
		break;
	case I915_PARAM_MMAP_GTT_VERSION:
		/* Though we've started our numbering from 1, and so class all
		 * earlier versions as 0, in effect their value is undefined as
@@ -599,6 +606,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
	if (ret)
		goto cleanup_irq;

	intel_huc_init(dev_priv);
	intel_guc_init(dev_priv);

	ret = i915_gem_init(dev_priv);
@@ -627,6 +635,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
	i915_gem_fini(dev_priv);
cleanup_irq:
	intel_guc_fini(dev_priv);
	intel_huc_fini(dev_priv);
	drm_irq_uninstall(dev);
	intel_teardown_gmbus(dev_priv);
cleanup_csr:
@@ -1114,7 +1123,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
	/* Reveal our presence to userspace */
	if (drm_dev_register(dev, 0) == 0) {
		i915_debugfs_register(dev_priv);
		i915_guc_register(dev_priv);
		i915_guc_log_register(dev_priv);
		i915_setup_sysfs(dev_priv);

		/* Depends on sysfs having been initialized */
@@ -1158,7 +1167,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
	i915_perf_unregister(dev_priv);

	i915_teardown_sysfs(dev_priv);
	i915_guc_unregister(dev_priv);
	i915_guc_log_unregister(dev_priv);
	i915_debugfs_unregister(dev_priv);
	drm_dev_unregister(&dev_priv->drm);

@@ -1314,6 +1323,7 @@ void i915_driver_unload(struct drm_device *dev)
	drain_workqueue(dev_priv->wq);

	intel_guc_fini(dev_priv);
	intel_huc_fini(dev_priv);
	i915_gem_fini(dev_priv);
	intel_fbc_cleanup_cfb(dev_priv);

@@ -1471,7 +1481,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)

	intel_display_set_init_power(dev_priv, false);

	fw_csr = !IS_BROXTON(dev_priv) &&
	fw_csr = !IS_GEN9_LP(dev_priv) &&
		suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
	/*
	 * In case of firmware assisted context save/restore don't manually
@@ -1484,7 +1494,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
		intel_power_domains_suspend(dev_priv);

	ret = 0;
	if (IS_BROXTON(dev_priv))
	if (IS_GEN9_LP(dev_priv))
		bxt_enable_dc9(dev_priv);
	else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
		hsw_enable_pc8(dev_priv);
@@ -1692,7 +1702,7 @@ static int i915_drm_resume_early(struct drm_device *dev)

	intel_uncore_early_sanitize(dev_priv, true);

	if (IS_BROXTON(dev_priv)) {
	if (IS_GEN9_LP(dev_priv)) {
		if (!dev_priv->suspended_to_idle)
			gen9_sanitize_dc_state(dev_priv);
		bxt_disable_dc9(dev_priv);
@@ -1702,7 +1712,7 @@ static int i915_drm_resume_early(struct drm_device *dev)

	intel_uncore_sanitize(dev_priv);

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

@@ -1728,25 +1738,9 @@ static int i915_resume_switcheroo(struct drm_device *dev)
	return i915_drm_resume(dev);
}

static void disable_engines_irq(struct drm_i915_private *dev_priv)
{
	struct intel_engine_cs *engine;
	enum intel_engine_id id;

	/* Ensure irq handler finishes, and not run again. */
	disable_irq(dev_priv->drm.irq);
	for_each_engine(engine, dev_priv, id)
		tasklet_kill(&engine->irq_tasklet);
}

static void enable_engines_irq(struct drm_i915_private *dev_priv)
{
	enable_irq(dev_priv->drm.irq);
}

/**
 * i915_reset - reset chip after a hang
 * @dev: drm device to reset
 * @dev_priv: device private to reset
 *
 * Reset the chip.  Useful if a hang is detected. Marks the device as wedged
 * on failure.
@@ -1776,12 +1770,15 @@ void i915_reset(struct drm_i915_private *dev_priv)
	error->reset_count++;

	pr_notice("drm/i915: Resetting chip after gpu hang\n");
	i915_gem_reset_prepare(dev_priv);
	disable_irq(dev_priv->drm.irq);
	ret = i915_gem_reset_prepare(dev_priv);
	if (ret) {
		DRM_ERROR("GPU recovery failed\n");
		intel_gpu_reset(dev_priv, ALL_ENGINES);
		goto error;
	}

	disable_engines_irq(dev_priv);
	ret = intel_gpu_reset(dev_priv, ALL_ENGINES);
	enable_engines_irq(dev_priv);

	if (ret) {
		if (ret != -ENODEV)
			DRM_ERROR("Failed to reset chip: %i\n", ret);
@@ -1816,6 +1813,7 @@ void i915_reset(struct drm_i915_private *dev_priv)
	i915_queue_hangcheck(dev_priv);

wakeup:
	enable_irq(dev_priv->drm.irq);
	wake_up_bit(&error->flags, I915_RESET_IN_PROGRESS);
	return;

@@ -2326,7 +2324,7 @@ static int intel_runtime_suspend(struct device *kdev)
	intel_runtime_pm_disable_interrupts(dev_priv);

	ret = 0;
	if (IS_BROXTON(dev_priv)) {
	if (IS_GEN9_LP(dev_priv)) {
		bxt_display_core_uninit(dev_priv);
		bxt_enable_dc9(dev_priv);
	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
@@ -2411,7 +2409,7 @@ static int intel_runtime_resume(struct device *kdev)
	if (IS_GEN6(dev_priv))
		intel_init_pch_refclk(dev_priv);

	if (IS_BROXTON(dev_priv)) {
	if (IS_GEN9_LP(dev_priv)) {
		bxt_disable_dc9(dev_priv);
		bxt_display_core_init(dev_priv, true);
		if (dev_priv->csr.dmc_payload &&
@@ -2549,8 +2547,8 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling_ioctl, DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
	DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
Loading