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

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

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

- refactor ddi buffer programming a bit (Ville)
- large-scale renaming to untangle naming in the gem code (Chris)
- rework vma/active tracking for accurately reaping idle mappings of shared
  objects (Chris)
- misc dp sst/mst probing corner case fixes (Ville)
- tons of cleanup&tunings all around in gem
- lockless (rcu-protected) request lookup, plus use it everywhere for
  non(b)locking waits (Chris)
- pipe crc debugfs fixes (Rodrigo)
- random fixes all over

* tag 'drm-intel-next-2016-08-08' of git://anongit.freedesktop.org/drm-intel: (222 commits)
  drm/i915: Update DRIVER_DATE to 20160808
  drm/i915: fix aliasing_ppgtt leak
  drm/i915: Update comment before i915_spin_request
  drm/i915: Use drm official vblank_no_hw_counter callback.
  drm/i915: Fix copy_to_user usage for pipe_crc
  Revert "drm/i915: Track active streams also for DP SST"
  drm/i915: fix WaInsertDummyPushConstPs
  drm/i915: Assert that the request hasn't been retired
  drm/i915: Repack fence tiling mode and stride into a single integer
  drm/i915: Document and reject invalid tiling modes
  drm/i915: Remove locking for get_tiling
  drm/i915: Remove pinned check from madvise ioctl
  drm/i915: Reduce locking inside swfinish ioctl
  drm/i915: Remove (struct_mutex) locking for busy-ioctl
  drm/i915: Remove (struct_mutex) locking for wait-ioctl
  drm/i915: Do a nonblocking wait first in pread/pwrite
  drm/i915: Remove unused no-shrinker-steal
  drm/i915: Tidy generation of the GTT mmap offset
  drm/i915/shrinker: Wait before acquiring struct_mutex under oom
  drm/i915: Simplify do_idling() (Ironlake vt-d w/a)
  ...
parents f8725ad1 c5b7e97b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -70,6 +70,9 @@ Frontbuffer Tracking
.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c
   :doc: frontbuffer tracking

.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.h
   :internal:

.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c
   :internal:

+2 −1
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o
i915-y += i915_cmd_parser.o \
	  i915_gem_batch_pool.o \
	  i915_gem_context.o \
	  i915_gem_debug.o \
	  i915_gem_dmabuf.o \
	  i915_gem_evict.o \
	  i915_gem_execbuffer.o \
@@ -33,6 +32,7 @@ i915-y += i915_cmd_parser.o \
	  i915_gem_gtt.o \
	  i915_gem.o \
	  i915_gem_render_state.o \
	  i915_gem_request.o \
	  i915_gem_shrinker.o \
	  i915_gem_stolen.o \
	  i915_gem_tiling.o \
@@ -40,6 +40,7 @@ i915-y += i915_cmd_parser.o \
	  i915_gpu_error.o \
	  i915_trace_points.o \
	  intel_breadcrumbs.o \
	  intel_engine_cs.o \
	  intel_lrc.o \
	  intel_mocs.o \
	  intel_ringbuffer.o \
+39 −35
Original line number Diff line number Diff line
@@ -62,23 +62,23 @@
 * The parser always rejects such commands.
 *
 * The majority of the problematic commands fall in the MI_* range, with only a
 * few specific commands on each ring (e.g. PIPE_CONTROL and MI_FLUSH_DW).
 * few specific commands on each engine (e.g. PIPE_CONTROL and MI_FLUSH_DW).
 *
 * Implementation:
 * Each ring maintains tables of commands and registers which the parser uses in
 * scanning batch buffers submitted to that ring.
 * Each engine maintains tables of commands and registers which the parser
 * uses in scanning batch buffers submitted to that engine.
 *
 * Since the set of commands that the parser must check for is significantly
 * smaller than the number of commands supported, the parser tables contain only
 * those commands required by the parser. This generally works because command
 * opcode ranges have standard command length encodings. So for commands that
 * the parser does not need to check, it can easily skip them. This is
 * implemented via a per-ring length decoding vfunc.
 * implemented via a per-engine length decoding vfunc.
 *
 * Unfortunately, there are a number of commands that do not follow the standard
 * length encoding for their opcode range, primarily amongst the MI_* commands.
 * To handle this, the parser provides a way to define explicit "skip" entries
 * in the per-ring command tables.
 * in the per-engine command tables.
 *
 * Other command table entries map fairly directly to high level categories
 * mentioned above: rejected, master-only, register whitelist. The parser
@@ -603,7 +603,7 @@ static u32 gen7_blt_get_cmd_length_mask(u32 cmd_header)
	return 0;
}

static bool validate_cmds_sorted(struct intel_engine_cs *engine,
static bool validate_cmds_sorted(const struct intel_engine_cs *engine,
				 const struct drm_i915_cmd_table *cmd_tables,
				 int cmd_table_count)
{
@@ -624,8 +624,10 @@ static bool validate_cmds_sorted(struct intel_engine_cs *engine,
			u32 curr = desc->cmd.value & desc->cmd.mask;

			if (curr < previous) {
				DRM_ERROR("CMD: table not sorted ring=%d table=%d entry=%d cmd=0x%08X prev=0x%08X\n",
					  engine->id, i, j, curr, previous);
				DRM_ERROR("CMD: %s [%d] command table not sorted: "
					  "table=%d entry=%d cmd=0x%08X prev=0x%08X\n",
					  engine->name, engine->id,
					  i, j, curr, previous);
				ret = false;
			}

@@ -636,7 +638,7 @@ static bool validate_cmds_sorted(struct intel_engine_cs *engine,
	return ret;
}

static bool check_sorted(int ring_id,
static bool check_sorted(const struct intel_engine_cs *engine,
			 const struct drm_i915_reg_descriptor *reg_table,
			 int reg_count)
{
@@ -648,8 +650,10 @@ static bool check_sorted(int ring_id,
		u32 curr = i915_mmio_reg_offset(reg_table[i].addr);

		if (curr < previous) {
			DRM_ERROR("CMD: table not sorted ring=%d entry=%d reg=0x%08X prev=0x%08X\n",
				  ring_id, i, curr, previous);
			DRM_ERROR("CMD: %s [%d] register table not sorted: "
				  "entry=%d reg=0x%08X prev=0x%08X\n",
				  engine->name, engine->id,
				  i, curr, previous);
			ret = false;
		}

@@ -666,7 +670,7 @@ static bool validate_regs_sorted(struct intel_engine_cs *engine)

	for (i = 0; i < engine->reg_table_count; i++) {
		table = &engine->reg_tables[i];
		if (!check_sorted(engine->id, table->regs, table->num_regs))
		if (!check_sorted(engine, table->regs, table->num_regs))
			return false;
	}

@@ -736,7 +740,7 @@ static void fini_hash_table(struct intel_engine_cs *engine)
}

/**
 * i915_cmd_parser_init_ring() - set cmd parser related fields for a ringbuffer
 * intel_engine_init_cmd_parser() - set cmd parser related fields for an engine
 * @engine: the engine to initialize
 *
 * Optionally initializes fields related to batch buffer command parsing in the
@@ -745,7 +749,7 @@ static void fini_hash_table(struct intel_engine_cs *engine)
 *
 * Return: non-zero if initialization fails
 */
int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
int intel_engine_init_cmd_parser(struct intel_engine_cs *engine)
{
	const struct drm_i915_cmd_table *cmd_tables;
	int cmd_table_count;
@@ -806,8 +810,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
		engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
		break;
	default:
		DRM_ERROR("CMD: cmd_parser_init with unknown ring: %d\n",
			  engine->id);
		MISSING_CASE(engine->id);
		BUG();
	}

@@ -829,13 +832,13 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
}

/**
 * i915_cmd_parser_fini_ring() - clean up cmd parser related fields
 * intel_engine_cleanup_cmd_parser() - clean up cmd parser related fields
 * @engine: the engine to clean up
 *
 * Releases any resources related to command parsing that may have been
 * initialized for the specified ring.
 * initialized for the specified engine.
 */
void i915_cmd_parser_fini_ring(struct intel_engine_cs *engine)
void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine)
{
	if (!engine->needs_cmd_parser)
		return;
@@ -866,9 +869,9 @@ find_cmd_in_table(struct intel_engine_cs *engine,
 * Returns a pointer to a descriptor for the command specified by cmd_header.
 *
 * The caller must supply space for a default descriptor via the default_desc
 * parameter. If no descriptor for the specified command exists in the ring's
 * parameter. If no descriptor for the specified command exists in the engine's
 * command parser tables, this function fills in default_desc based on the
 * ring's default length encoding and returns default_desc.
 * engine's default length encoding and returns default_desc.
 */
static const struct drm_i915_cmd_descriptor*
find_cmd(struct intel_engine_cs *engine,
@@ -1023,15 +1026,16 @@ static u32 *copy_batch(struct drm_i915_gem_object *dest_obj,
}

/**
 * i915_needs_cmd_parser() - should a given ring use software command parsing?
 * intel_engine_needs_cmd_parser() - should a given engine use software
 *                                   command parsing?
 * @engine: the engine in question
 *
 * Only certain platforms require software batch buffer command parsing, and
 * only when enabled via module parameter.
 *
 * Return: true if the ring requires software command parsing
 * Return: true if the engine requires software command parsing
 */
bool i915_needs_cmd_parser(struct intel_engine_cs *engine)
bool intel_engine_needs_cmd_parser(struct intel_engine_cs *engine)
{
	if (!engine->needs_cmd_parser)
		return false;
@@ -1078,8 +1082,8 @@ static bool check_cmd(const struct intel_engine_cs *engine,
						   reg_addr);

			if (!reg) {
				DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n",
						 reg_addr, *cmd, engine->id);
				DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (exec_id=%d)\n",
						 reg_addr, *cmd, engine->exec_id);
				return false;
			}

@@ -1159,11 +1163,11 @@ static bool check_cmd(const struct intel_engine_cs *engine,
				desc->bits[i].mask;

			if (dword != desc->bits[i].expected) {
				DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X for bitmask 0x%08X (exp=0x%08X act=0x%08X) (ring=%d)\n",
				DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X for bitmask 0x%08X (exp=0x%08X act=0x%08X) (exec_id=%d)\n",
						 *cmd,
						 desc->bits[i].mask,
						 desc->bits[i].expected,
						 dword, engine->id);
						 dword, engine->exec_id);
				return false;
			}
		}
@@ -1189,7 +1193,7 @@ static bool check_cmd(const struct intel_engine_cs *engine,
 * Return: non-zero if the parser finds violations or otherwise fails; -EACCES
 * if the batch appears legal but should use hardware parsing
 */
int i915_parse_cmds(struct intel_engine_cs *engine,
int intel_engine_cmd_parser(struct intel_engine_cs *engine,
			    struct drm_i915_gem_object *batch_obj,
			    struct drm_i915_gem_object *shadow_batch_obj,
			    u32 batch_start_offset,
@@ -1295,7 +1299,7 @@ int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv)

	/* If the command parser is not enabled, report 0 - unsupported */
	for_each_engine(engine, dev_priv) {
		if (i915_needs_cmd_parser(engine)) {
		if (intel_engine_needs_cmd_parser(engine)) {
			active = true;
			break;
		}
+87 −100
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ static int i915_capabilities(struct seq_file *m, void *data)

static char get_active_flag(struct drm_i915_gem_object *obj)
{
	return obj->active ? '*' : ' ';
	return i915_gem_object_is_active(obj) ? '*' : ' ';
}

static char get_pin_flag(struct drm_i915_gem_object *obj)
@@ -101,7 +101,7 @@ static char get_pin_flag(struct drm_i915_gem_object *obj)

static char get_tiling_flag(struct drm_i915_gem_object *obj)
{
	switch (obj->tiling_mode) {
	switch (i915_gem_object_get_tiling(obj)) {
	default:
	case I915_TILING_NONE: return ' ';
	case I915_TILING_X: return 'X';
@@ -125,7 +125,7 @@ static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
	struct i915_vma *vma;

	list_for_each_entry(vma, &obj->vma_list, obj_link) {
		if (vma->is_ggtt && drm_mm_node_allocated(&vma->node))
		if (i915_vma_is_ggtt(vma) && drm_mm_node_allocated(&vma->node))
			size += vma->node.size;
	}

@@ -138,6 +138,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
	struct intel_engine_cs *engine;
	struct i915_vma *vma;
	unsigned int frontbuffer_bits;
	int pin_count = 0;
	enum intel_engine_id id;

@@ -155,17 +156,20 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
		   obj->base.write_domain);
	for_each_engine_id(engine, dev_priv, id)
		seq_printf(m, "%x ",
				i915_gem_request_get_seqno(obj->last_read_req[id]));
			   i915_gem_active_get_seqno(&obj->last_read[id],
						     &obj->base.dev->struct_mutex));
	seq_printf(m, "] %x %x%s%s%s",
		   i915_gem_request_get_seqno(obj->last_write_req),
		   i915_gem_request_get_seqno(obj->last_fenced_req),
		   i915_gem_active_get_seqno(&obj->last_write,
					     &obj->base.dev->struct_mutex),
		   i915_gem_active_get_seqno(&obj->last_fence,
					     &obj->base.dev->struct_mutex),
		   i915_cache_level_str(to_i915(obj->base.dev), obj->cache_level),
		   obj->dirty ? " dirty" : "",
		   obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
	if (obj->base.name)
		seq_printf(m, " (name: %d)", obj->base.name);
	list_for_each_entry(vma, &obj->vma_list, obj_link) {
		if (vma->pin_count > 0)
		if (i915_vma_is_pinned(vma))
			pin_count++;
	}
	seq_printf(m, " (pinned x %d)", pin_count);
@@ -174,10 +178,13 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
	if (obj->fence_reg != I915_FENCE_REG_NONE)
		seq_printf(m, " (fence: %d)", obj->fence_reg);
	list_for_each_entry(vma, &obj->vma_list, obj_link) {
		if (!drm_mm_node_allocated(&vma->node))
			continue;

		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx",
			   vma->is_ggtt ? "g" : "pp",
			   i915_vma_is_ggtt(vma) ? "g" : "pp",
			   vma->node.start, vma->node.size);
		if (vma->is_ggtt)
		if (i915_vma_is_ggtt(vma))
			seq_printf(m, ", type: %u", vma->ggtt_view.type);
		seq_puts(m, ")");
	}
@@ -192,11 +199,15 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
		*t = '\0';
		seq_printf(m, " (%s mappable)", s);
	}
	if (obj->last_write_req != NULL)
		seq_printf(m, " (%s)",
			   i915_gem_request_get_engine(obj->last_write_req)->name);
	if (obj->frontbuffer_bits)
		seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits);

	engine = i915_gem_active_get_engine(&obj->last_write,
					    &obj->base.dev->struct_mutex);
	if (engine)
		seq_printf(m, " (%s)", engine->name);

	frontbuffer_bits = atomic_read(&obj->frontbuffer_bits);
	if (frontbuffer_bits)
		seq_printf(m, " (frontbuffer: 0x%03x)", frontbuffer_bits);
}

static int i915_gem_object_list_info(struct seq_file *m, void *data)
@@ -338,47 +349,30 @@ static int per_file_stats(int id, void *ptr, void *data)

	stats->count++;
	stats->total += obj->base.size;

	if (!obj->bind_count)
		stats->unbound += obj->base.size;
	if (obj->base.name || obj->base.dma_buf)
		stats->shared += obj->base.size;

	if (USES_FULL_PPGTT(obj->base.dev)) {
	list_for_each_entry(vma, &obj->vma_list, obj_link) {
			struct i915_hw_ppgtt *ppgtt;

		if (!drm_mm_node_allocated(&vma->node))
			continue;

			if (vma->is_ggtt) {
				stats->global += obj->base.size;
				continue;
			}
		if (i915_vma_is_ggtt(vma)) {
			stats->global += vma->node.size;
		} else {
			struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vma->vm);

			ppgtt = container_of(vma->vm, struct i915_hw_ppgtt, base);
			if (ppgtt->file_priv != stats->file_priv)
			if (ppgtt->base.file != stats->file_priv)
				continue;

			if (obj->active) /* XXX per-vma statistic */
				stats->active += obj->base.size;
			else
				stats->inactive += obj->base.size;

			return 0;
		}
	} else {
		if (i915_gem_obj_ggtt_bound(obj)) {
			stats->global += obj->base.size;
			if (obj->active)
				stats->active += obj->base.size;

		if (i915_vma_is_active(vma))
			stats->active += vma->node.size;
		else
				stats->inactive += obj->base.size;
			return 0;
		}
			stats->inactive += vma->node.size;
	}

	if (!list_empty(&obj->global_list))
		stats->unbound += obj->base.size;

	return 0;
}

@@ -425,8 +419,8 @@ static int per_file_ctx_stats(int id, void *ptr, void *data)
	for (n = 0; n < ARRAY_SIZE(ctx->engine); n++) {
		if (ctx->engine[n].state)
			per_file_stats(0, ctx->engine[n].state, data);
		if (ctx->engine[n].ringbuf)
			per_file_stats(0, ctx->engine[n].ringbuf->obj, data);
		if (ctx->engine[n].ring)
			per_file_stats(0, ctx->engine[n].ring->obj, data);
	}

	return 0;
@@ -754,13 +748,13 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
		int count;

		count = 0;
		list_for_each_entry(req, &engine->request_list, list)
		list_for_each_entry(req, &engine->request_list, link)
			count++;
		if (count == 0)
			continue;

		seq_printf(m, "%s requests: %d\n", engine->name, count);
		list_for_each_entry(req, &engine->request_list, list) {
		list_for_each_entry(req, &engine->request_list, link) {
			struct task_struct *task;

			rcu_read_lock();
@@ -768,7 +762,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
			if (req->pid)
				task = pid_task(req->pid, PIDTYPE_PID);
			seq_printf(m, "    %x @ %d: %s [%d]\n",
				   req->seqno,
				   req->fence.seqno,
				   (int) (jiffies - req->emitted_jiffies),
				   task ? task->comm : "<unknown>",
				   task ? task->pid : -1);
@@ -1205,8 +1199,6 @@ static int i915_frequency_info(struct seq_file *m, void *unused)

	intel_runtime_pm_get(dev_priv);

	flush_delayed_work(&dev_priv->rps.delayed_resume_work);

	if (IS_GEN5(dev)) {
		u16 rgvswctl = I915_READ16(MEMSWCTL);
		u16 rgvstat = I915_READ16(MEMSTAT_ILK);
@@ -1381,6 +1373,8 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
			   intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq));
		seq_printf(m, "Min freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq));
		seq_printf(m, "Boost freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq));
		seq_printf(m, "Max freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
		seq_printf(m,
@@ -1419,7 +1413,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
	intel_runtime_pm_get(dev_priv);

	for_each_engine_id(engine, dev_priv, id) {
		acthd[id] = intel_ring_get_active_head(engine);
		acthd[id] = intel_engine_get_active_head(engine);
		seqno[id] = intel_engine_get_seqno(engine);
	}

@@ -1602,6 +1596,7 @@ static int gen6_drpc_info(struct seq_file *m)
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = to_i915(dev);
	u32 rpmodectl1, gt_core_status, rcctl1, rc6vids = 0;
	u32 gen9_powergate_enable = 0, gen9_powergate_status = 0;
	unsigned forcewake_count;
	int count = 0, ret;

@@ -1629,6 +1624,10 @@ static int gen6_drpc_info(struct seq_file *m)

	rpmodectl1 = I915_READ(GEN6_RP_CONTROL);
	rcctl1 = I915_READ(GEN6_RC_CONTROL);
	if (INTEL_INFO(dev)->gen >= 9) {
		gen9_powergate_enable = I915_READ(GEN9_PG_ENABLE);
		gen9_powergate_status = I915_READ(GEN9_PWRGT_DOMAIN_STATUS);
	}
	mutex_unlock(&dev->struct_mutex);
	mutex_lock(&dev_priv->rps.hw_lock);
	sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
@@ -1647,6 +1646,12 @@ static int gen6_drpc_info(struct seq_file *m)
		   yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
	seq_printf(m, "RC6 Enabled: %s\n",
		   yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE));
	if (INTEL_INFO(dev)->gen >= 9) {
		seq_printf(m, "Render Well Gating Enabled: %s\n",
			yesno(gen9_powergate_enable & GEN9_RENDER_PG_ENABLE));
		seq_printf(m, "Media Well Gating Enabled: %s\n",
			yesno(gen9_powergate_enable & GEN9_MEDIA_PG_ENABLE));
	}
	seq_printf(m, "Deep RC6 Enabled: %s\n",
		   yesno(rcctl1 & GEN6_RC_CTL_RC6p_ENABLE));
	seq_printf(m, "Deepest RC6 Enabled: %s\n",
@@ -1675,6 +1680,14 @@ static int gen6_drpc_info(struct seq_file *m)

	seq_printf(m, "Core Power Down: %s\n",
		   yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK));
	if (INTEL_INFO(dev)->gen >= 9) {
		seq_printf(m, "Render Power Well: %s\n",
			(gen9_powergate_status &
			 GEN9_PWRGT_RENDER_STATUS_MASK) ? "Up" : "Down");
		seq_printf(m, "Media Power Well: %s\n",
			(gen9_powergate_status &
			 GEN9_PWRGT_MEDIA_STATUS_MASK) ? "Up" : "Down");
	}

	/* Not exactly sure what this is */
	seq_printf(m, "RC6 \"Locked to RPn\" residency since boot: %u\n",
@@ -1692,7 +1705,7 @@ static int gen6_drpc_info(struct seq_file *m)
		   GEN6_DECODE_RC6_VID(((rc6vids >> 8) & 0xff)));
	seq_printf(m, "RC6++ voltage: %dmV\n",
		   GEN6_DECODE_RC6_VID(((rc6vids >> 16) & 0xff)));
	return 0;
	return i915_forcewake_domains(m, NULL);
}

static int i915_drpc_info(struct seq_file *m, void *unused)
@@ -1896,8 +1909,6 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)

	intel_runtime_pm_get(dev_priv);

	flush_delayed_work(&dev_priv->rps.delayed_resume_work);

	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	if (ret)
		goto out;
@@ -2019,12 +2030,11 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
	return 0;
}

static void describe_ctx_ringbuf(struct seq_file *m,
				 struct intel_ringbuffer *ringbuf)
static void describe_ctx_ring(struct seq_file *m, struct intel_ring *ring)
{
	seq_printf(m, " (ringbuffer, space: %d, head: %u, tail: %u, last head: %d)",
		   ringbuf->space, ringbuf->head, ringbuf->tail,
		   ringbuf->last_retired_head);
		   ring->space, ring->head, ring->tail,
		   ring->last_retired_head);
}

static int i915_context_status(struct seq_file *m, void *unused)
@@ -2068,8 +2078,8 @@ static int i915_context_status(struct seq_file *m, void *unused)
			seq_putc(m, ce->initialised ? 'I' : 'i');
			if (ce->state)
				describe_obj(m, ce->state);
			if (ce->ringbuf)
				describe_ctx_ringbuf(m, ce->ringbuf);
			if (ce->ring)
				describe_ctx_ring(m, ce->ring);
			seq_putc(m, '\n');
		}

@@ -2467,13 +2477,7 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
			   list_empty(&file_priv->rps.link) ? "" : ", active");
		rcu_read_unlock();
	}
	seq_printf(m, "Semaphore boosts: %d%s\n",
		   dev_priv->rps.semaphores.boosts,
		   list_empty(&dev_priv->rps.semaphores.link) ? "" : ", active");
	seq_printf(m, "MMIO flip boosts: %d%s\n",
		   dev_priv->rps.mmioflips.boosts,
		   list_empty(&dev_priv->rps.mmioflips.link) ? "" : ", active");
	seq_printf(m, "Kernel boosts: %d\n", dev_priv->rps.boosts);
	seq_printf(m, "Kernel (anonymous) boosts: %d\n", dev_priv->rps.boosts);
	spin_unlock(&dev_priv->rps.client_lock);
	mutex_unlock(&dev->filelist_mutex);

@@ -3228,7 +3232,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
	enum intel_engine_id id;
	int j, ret;

	if (!i915_semaphore_is_enabled(dev_priv)) {
	if (!i915.semaphores) {
		seq_puts(m, "Semaphores are disabled\n");
		return 0;
	}
@@ -3621,7 +3625,6 @@ i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count,
	while (n_entries > 0) {
		struct intel_pipe_crc_entry *entry =
			&pipe_crc->entries[pipe_crc->tail];
		int ret;

		if (CIRC_CNT(pipe_crc->head, pipe_crc->tail,
			     INTEL_PIPE_CRC_ENTRIES_NR) < 1)
@@ -3638,8 +3641,7 @@ i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count,

		spin_unlock_irq(&pipe_crc->lock);

		ret = copy_to_user(user_buf, buf, PIPE_CRC_LINE_LEN);
		if (ret == PIPE_CRC_LINE_LEN)
		if (copy_to_user(user_buf, buf, PIPE_CRC_LINE_LEN))
			return -EFAULT;

		user_buf += PIPE_CRC_LINE_LEN;
@@ -4921,7 +4923,7 @@ i915_drop_caches_set(void *data, u64 val)
		return ret;

	if (val & DROP_ACTIVE) {
		ret = i915_gem_wait_for_idle(dev_priv);
		ret = i915_gem_wait_for_idle(dev_priv, true);
		if (ret)
			goto unlock;
	}
@@ -4950,20 +4952,11 @@ i915_max_freq_get(void *data, u64 *val)
{
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = to_i915(dev);
	int ret;

	if (INTEL_INFO(dev)->gen < 6)
		return -ENODEV;

	flush_delayed_work(&dev_priv->rps.delayed_resume_work);

	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	if (ret)
		return ret;

	*val = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit);
	mutex_unlock(&dev_priv->rps.hw_lock);

	return 0;
}

@@ -4978,8 +4971,6 @@ i915_max_freq_set(void *data, u64 val)
	if (INTEL_INFO(dev)->gen < 6)
		return -ENODEV;

	flush_delayed_work(&dev_priv->rps.delayed_resume_work);

	DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);

	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
@@ -5017,20 +5008,11 @@ i915_min_freq_get(void *data, u64 *val)
{
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = to_i915(dev);
	int ret;

	if (INTEL_INFO(dev)->gen < 6)
	if (INTEL_GEN(dev_priv) < 6)
		return -ENODEV;

	flush_delayed_work(&dev_priv->rps.delayed_resume_work);

	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	if (ret)
		return ret;

	*val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit);
	mutex_unlock(&dev_priv->rps.hw_lock);

	return 0;
}

@@ -5042,11 +5024,9 @@ i915_min_freq_set(void *data, u64 val)
	u32 hw_max, hw_min;
	int ret;

	if (INTEL_INFO(dev)->gen < 6)
	if (INTEL_GEN(dev_priv) < 6)
		return -ENODEV;

	flush_delayed_work(&dev_priv->rps.delayed_resume_work);

	DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);

	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
@@ -5268,7 +5248,8 @@ static void broadwell_sseu_device_status(struct drm_device *dev,
static int i915_sseu_status(struct seq_file *m, void *unused)
{
	struct drm_info_node *node = (struct drm_info_node *) m->private;
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = to_i915(node->minor->dev);
	struct drm_device *dev = &dev_priv->drm;
	struct sseu_dev_status stat;

	if (INTEL_INFO(dev)->gen < 8)
@@ -5298,6 +5279,9 @@ static int i915_sseu_status(struct seq_file *m, void *unused)

	seq_puts(m, "SSEU Device Status\n");
	memset(&stat, 0, sizeof(stat));

	intel_runtime_pm_get(dev_priv);

	if (IS_CHERRYVIEW(dev)) {
		cherryview_sseu_device_status(dev, &stat);
	} else if (IS_BROADWELL(dev)) {
@@ -5305,6 +5289,9 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
	} else if (INTEL_INFO(dev)->gen >= 9) {
		gen9_sseu_device_status(dev, &stat);
	}

	intel_runtime_pm_put(dev_priv);

	seq_printf(m, "  Enabled Slice Total: %u\n",
		   stat.slice_total);
	seq_printf(m, "  Enabled Subslice Total: %u\n",
+23 −62
Original line number Diff line number Diff line
@@ -228,27 +228,6 @@ static void intel_detect_pch(struct drm_device *dev)
	pci_dev_put(pch);
}

bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv)
{
	if (INTEL_GEN(dev_priv) < 6)
		return false;

	if (i915.semaphores >= 0)
		return i915.semaphores;

	/* TODO: make semaphores and Execlists play nicely together */
	if (i915.enable_execlists)
		return false;

#ifdef CONFIG_INTEL_IOMMU
	/* Enable semaphores on SNB when IO remapping is off */
	if (IS_GEN6(dev_priv) && intel_iommu_gfx_mapped)
		return false;
#endif

	return true;
}

static int i915_getparam(struct drm_device *dev, void *data,
			 struct drm_file *file_priv)
{
@@ -324,7 +303,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
		value = 1;
		break;
	case I915_PARAM_HAS_SEMAPHORES:
		value = i915_semaphore_is_enabled(dev_priv);
		value = i915.semaphores;
		break;
	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
		value = 1;
@@ -999,6 +978,9 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv)
	i915.enable_ppgtt =
		intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt);
	DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt);

	i915.semaphores = intel_sanitize_semaphores(dev_priv, i915.semaphores);
	DRM_DEBUG_DRIVER("use GPU sempahores? %s\n", yesno(i915.semaphores));
}

/**
@@ -1011,8 +993,6 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv)
static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = &dev_priv->drm;
	struct i915_ggtt *ggtt = &dev_priv->ggtt;
	uint32_t aperture_size;
	int ret;

	if (i915_inject_load_failure())
@@ -1022,16 +1002,10 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)

	intel_sanitize_options(dev_priv);

	ret = i915_ggtt_init_hw(dev);
	ret = i915_ggtt_probe_hw(dev_priv);
	if (ret)
		return ret;

	ret = i915_ggtt_enable_hw(dev);
	if (ret) {
		DRM_ERROR("failed to enable GGTT\n");
		goto out_ggtt;
	}

	/* WARNING: Apparently we must kick fbdev drivers before vgacon,
	 * otherwise the vga fbdev driver falls over. */
	ret = i915_kick_out_firmware_fb(dev_priv);
@@ -1046,6 +1020,16 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
		goto out_ggtt;
	}

	ret = i915_ggtt_init_hw(dev_priv);
	if (ret)
		return ret;

	ret = i915_ggtt_enable_hw(dev_priv);
	if (ret) {
		DRM_ERROR("failed to enable GGTT\n");
		goto out_ggtt;
	}

	pci_set_master(dev->pdev);

	/* overlay on gen2 is broken and can't address above 1G */
@@ -1058,7 +1042,6 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
		}
	}


	/* 965GM sometimes incorrectly writes to hardware status page (HWS)
	 * using 32bit addressing, overwriting memory if HWS is located
	 * above 4GB.
@@ -1077,19 +1060,6 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
		}
	}

	aperture_size = ggtt->mappable_end;

	ggtt->mappable =
		io_mapping_create_wc(ggtt->mappable_base,
				     aperture_size);
	if (!ggtt->mappable) {
		ret = -EIO;
		goto out_ggtt;
	}

	ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base,
					      aperture_size);

	pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
			   PM_QOS_DEFAULT_VALUE);

@@ -1118,7 +1088,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
	return 0;

out_ggtt:
	i915_ggtt_cleanup_hw(dev);
	i915_ggtt_cleanup_hw(dev_priv);

	return ret;
}
@@ -1130,15 +1100,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = &dev_priv->drm;
	struct i915_ggtt *ggtt = &dev_priv->ggtt;

	if (dev->pdev->msi_enabled)
		pci_disable_msi(dev->pdev);

	pm_qos_remove_request(&dev_priv->pm_qos);
	arch_phys_wc_del(ggtt->mtrr);
	io_mapping_free(ggtt->mappable);
	i915_ggtt_cleanup_hw(dev);
	i915_ggtt_cleanup_hw(dev_priv);
}

/**
@@ -1343,7 +1310,7 @@ void i915_driver_unload(struct drm_device *dev)
	i915_destroy_error_state(dev);

	/* Flush any outstanding unpin_work. */
	flush_workqueue(dev_priv->wq);
	drain_workqueue(dev_priv->wq);

	intel_guc_fini(dev);
	i915_gem_fini(dev);
@@ -1458,8 +1425,6 @@ static int i915_drm_suspend(struct drm_device *dev)

	intel_guc_suspend(dev);

	intel_suspend_gt_powersave(dev_priv);

	intel_display_suspend(dev);

	intel_dp_mst_suspend(dev);
@@ -1586,15 +1551,13 @@ static int i915_drm_resume(struct drm_device *dev)

	disable_rpm_wakeref_asserts(dev_priv);

	ret = i915_ggtt_enable_hw(dev);
	ret = i915_ggtt_enable_hw(dev_priv);
	if (ret)
		DRM_ERROR("failed to re-enable GGTT\n");

	intel_csr_ucode_resume(dev_priv);

	mutex_lock(&dev->struct_mutex);
	i915_gem_restore_gtt_mappings(dev);
	mutex_unlock(&dev->struct_mutex);
	i915_gem_resume(dev);

	i915_restore_state(dev);
	intel_opregion_setup(dev_priv);
@@ -1652,6 +1615,7 @@ static int i915_drm_resume(struct drm_device *dev)

	intel_opregion_notify_adapter(dev_priv, PCI_D0);

	intel_autoenable_gt_powersave(dev_priv);
	drm_kms_helper_poll_enable(dev);

	enable_rpm_wakeref_asserts(dev_priv);
@@ -1778,8 +1742,6 @@ int i915_reset(struct drm_i915_private *dev_priv)
	unsigned reset_counter;
	int ret;

	intel_reset_gt_powersave(dev_priv);

	mutex_lock(&dev->struct_mutex);

	/* Clear any previous failed attempts at recovery. Time to try again. */
@@ -1835,8 +1797,7 @@ int i915_reset(struct drm_i915_private *dev_priv)
	 * previous concerns that it doesn't respond well to some forms
	 * of re-init after reset.
	 */
	if (INTEL_INFO(dev)->gen > 5)
		intel_enable_gt_powersave(dev_priv);
	intel_autoenable_gt_powersave(dev_priv);

	return 0;

@@ -2462,7 +2423,6 @@ static int intel_runtime_resume(struct device *device)
	 * we can do is to hope that things will still work (and disable RPM).
	 */
	i915_gem_init_swizzling(dev);
	gen6_update_ring_freq(dev_priv);

	intel_runtime_pm_enable_interrupts(dev_priv);

@@ -2618,6 +2578,7 @@ static struct drm_driver driver = {
	.postclose = i915_driver_postclose,
	.set_busid = drm_pci_set_busid,

	.gem_close_object = i915_gem_close_object,
	.gem_free_object = i915_gem_free_object,
	.gem_vm_ops = &i915_gem_vm_ops,

Loading