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

Commit 85bd5ac3 authored by Dave Airlie's avatar Dave Airlie
Browse files

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

- VBT code refactor for a clean split between parsing&using of firmware
  information (Jani)
- untangle the pll computation code, and splitting up the monster
  i9xx_crtc_compute_clocks (Ander)
- dsi support for bxt (Jani, Shashank Sharma and others)
- color manager (i.e. de-gamma, color conversion matrix & gamma support) from
  Lionel Landwerlin
- Vulkan hsw support in the command parser (Jordan Justen)
- large-scale renaming of intel_engine_cs variables/parameters to avoid the epic
  ring vs. engine confusion introduced in gen8 (Tvrtko Ursulin)
- few atomic patches from Maarten&Matt, big one is two-stage wm programming on ilk-bdw
- refactor driver load and add infrastructure to inject load failures for
  testing, from Imre
- various small things all over

* tag 'drm-intel-next-2016-03-30' of git://anongit.freedesktop.org/drm-intel: (179 commits)
  drm/i915: Update DRIVER_DATE to 20160330
  drm/i915: Call intel_dp_mst_resume() before resuming displays
  drm/i915: Fix races on fbdev
  drm/i915: remove unused dev_priv->render_reclock_avail
  drm/i915: move sdvo mappings to vbt data
  drm/i915: move edp low vswing config to vbt data
  drm/i915: use a substruct in vbt data for edp
  drm/i915: replace for_each_engine()
  drm/i915: introduce for_each_engine_id()
  drm/i915/bxt: Fix DSI HW state readout
  drm/i915: Remove vblank wait from hsw_enable_ips, v2.
  drm/i915: Tidy aliasing_gtt_bind_vma()
  drm/i915: Split PNV version of crtc_compute_clock()
  drm/i915: Split g4x_crtc_compute_clock()
  drm/i915: Split i8xx_crtc_compute_clock()
  drm/i915: Split CHV and VLV specific crtc_compute_clock() hooks
  drm/i915: Merge ironlake_compute_clocks() and ironlake_crtc_compute_clock()
  drm/i915: Move fp divisor calculation into ironlake_compute_dpll()
  drm/i915: Pass crtc_state->dpll directly to ->find_dpll()
  drm/i915: Simplify ironlake_crtc_compute_clock() CPU eDP case
  ...
parents e7c8e544 68d4aee9
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -2153,7 +2153,11 @@ void intel_crt_init(struct drm_device *dev)
	<td valign="top" >ENUM</td>
	<td valign="top" >{ "Automatic", "Full", "Limited 16:235" }</td>
	<td valign="top" >Connector</td>
	<td valign="top" >TBD</td>
	<td valign="top" >When this property is set to Limited 16:235
		and CTM is set, the hardware will be programmed with the
		result of the multiplication of CTM by the limited range
		matrix to ensure the pixels normaly in the range 0..1.0 are
		remapped to the range 16/255..235/255.</td>
	</tr>
	<tr>
	<td valign="top" >“audio”</td>
@@ -3334,7 +3338,7 @@ int num_ioctls;</synopsis>
	<title>Video BIOS Table (VBT)</title>
!Pdrivers/gpu/drm/i915/intel_bios.c Video BIOS Table (VBT)
!Idrivers/gpu/drm/i915/intel_bios.c
!Idrivers/gpu/drm/i915/intel_bios.h
!Idrivers/gpu/drm/i915/intel_vbt_defs.h
      </sect2>
    </sect1>

+6 −0
Original line number Diff line number Diff line
@@ -56,3 +56,9 @@ config DRM_I915_USERPTR
	  selected to enabled full userptr support.

	  If in doubt, say "Y".

menu "drm/i915 Debugging"
depends on DRM_I915
depends on EXPERT
source drivers/gpu/drm/i915/Kconfig.debug
endmenu
+12 −0
Original line number Diff line number Diff line
config DRM_I915_DEBUG
        bool "Enable additional driver debugging"
        depends on DRM_I915
        default n
        help
          Choose this option to turn on extra driver debugging that may affect
          performance but will catch some internal issues.

          Recommended for driver developers only.

          If in doubt, say "N".
+2 −0
Original line number Diff line number Diff line
@@ -55,7 +55,9 @@ i915-y += intel_audio.o \
	  intel_atomic.o \
	  intel_atomic_plane.o \
	  intel_bios.o \
	  intel_color.o \
	  intel_display.o \
	  intel_dpll_mgr.o \
	  intel_fbc.o \
	  intel_fifo_underrun.o \
	  intel_frontbuffer.o \
+138 −73
Original line number Diff line number Diff line
@@ -444,6 +444,7 @@ static const struct drm_i915_reg_descriptor gen7_render_regs[] = {
	REG64(CL_PRIMITIVES_COUNT),
	REG64(PS_INVOCATION_COUNT),
	REG64(PS_DEPTH_COUNT),
	REG64_IDX(RING_TIMESTAMP, RENDER_RING_BASE),
	REG32(OACONTROL), /* Only allowed for LRI and SRM. See below. */
	REG64(MI_PREDICATE_SRC0),
	REG64(MI_PREDICATE_SRC1),
@@ -471,6 +472,25 @@ static const struct drm_i915_reg_descriptor gen7_render_regs[] = {
	REG32(GEN7_L3SQCREG1),
	REG32(GEN7_L3CNTLREG2),
	REG32(GEN7_L3CNTLREG3),
};

static const struct drm_i915_reg_descriptor hsw_render_regs[] = {
	REG64_IDX(HSW_CS_GPR, 0),
	REG64_IDX(HSW_CS_GPR, 1),
	REG64_IDX(HSW_CS_GPR, 2),
	REG64_IDX(HSW_CS_GPR, 3),
	REG64_IDX(HSW_CS_GPR, 4),
	REG64_IDX(HSW_CS_GPR, 5),
	REG64_IDX(HSW_CS_GPR, 6),
	REG64_IDX(HSW_CS_GPR, 7),
	REG64_IDX(HSW_CS_GPR, 8),
	REG64_IDX(HSW_CS_GPR, 9),
	REG64_IDX(HSW_CS_GPR, 10),
	REG64_IDX(HSW_CS_GPR, 11),
	REG64_IDX(HSW_CS_GPR, 12),
	REG64_IDX(HSW_CS_GPR, 13),
	REG64_IDX(HSW_CS_GPR, 14),
	REG64_IDX(HSW_CS_GPR, 15),
	REG32(HSW_SCRATCH1,
	      .mask = ~HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE,
	      .value = 0),
@@ -500,6 +520,33 @@ static const struct drm_i915_reg_descriptor hsw_master_regs[] = {
#undef REG64
#undef REG32

struct drm_i915_reg_table {
	const struct drm_i915_reg_descriptor *regs;
	int num_regs;
	bool master;
};

static const struct drm_i915_reg_table ivb_render_reg_tables[] = {
	{ gen7_render_regs, ARRAY_SIZE(gen7_render_regs), false },
	{ ivb_master_regs, ARRAY_SIZE(ivb_master_regs), true },
};

static const struct drm_i915_reg_table ivb_blt_reg_tables[] = {
	{ gen7_blt_regs, ARRAY_SIZE(gen7_blt_regs), false },
	{ ivb_master_regs, ARRAY_SIZE(ivb_master_regs), true },
};

static const struct drm_i915_reg_table hsw_render_reg_tables[] = {
	{ gen7_render_regs, ARRAY_SIZE(gen7_render_regs), false },
	{ hsw_render_regs, ARRAY_SIZE(hsw_render_regs), false },
	{ hsw_master_regs, ARRAY_SIZE(hsw_master_regs), true },
};

static const struct drm_i915_reg_table hsw_blt_reg_tables[] = {
	{ gen7_blt_regs, ARRAY_SIZE(gen7_blt_regs), false },
	{ hsw_master_regs, ARRAY_SIZE(hsw_master_regs), true },
};

static u32 gen7_render_get_cmd_length_mask(u32 cmd_header)
{
	u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
@@ -555,7 +602,7 @@ static u32 gen7_blt_get_cmd_length_mask(u32 cmd_header)
	return 0;
}

static bool validate_cmds_sorted(struct intel_engine_cs *ring,
static bool validate_cmds_sorted(struct intel_engine_cs *engine,
				 const struct drm_i915_cmd_table *cmd_tables,
				 int cmd_table_count)
{
@@ -577,7 +624,7 @@ static bool validate_cmds_sorted(struct intel_engine_cs *ring,

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

@@ -611,11 +658,18 @@ static bool check_sorted(int ring_id,
	return ret;
}

static bool validate_regs_sorted(struct intel_engine_cs *ring)
static bool validate_regs_sorted(struct intel_engine_cs *engine)
{
	return check_sorted(ring->id, ring->reg_table, ring->reg_count) &&
		check_sorted(ring->id, ring->master_reg_table,
			     ring->master_reg_count);
	int i;
	const struct drm_i915_reg_table *table;

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

	return true;
}

struct cmd_node {
@@ -639,13 +693,13 @@ struct cmd_node {
 */
#define CMD_HASH_MASK STD_MI_OPCODE_MASK

static int init_hash_table(struct intel_engine_cs *ring,
static int init_hash_table(struct intel_engine_cs *engine,
			   const struct drm_i915_cmd_table *cmd_tables,
			   int cmd_table_count)
{
	int i, j;

	hash_init(ring->cmd_hash);
	hash_init(engine->cmd_hash);

	for (i = 0; i < cmd_table_count; i++) {
		const struct drm_i915_cmd_table *table = &cmd_tables[i];
@@ -660,7 +714,7 @@ static int init_hash_table(struct intel_engine_cs *ring,
				return -ENOMEM;

			desc_node->desc = desc;
			hash_add(ring->cmd_hash, &desc_node->node,
			hash_add(engine->cmd_hash, &desc_node->node,
				 desc->cmd.value & CMD_HASH_MASK);
		}
	}
@@ -668,13 +722,13 @@ static int init_hash_table(struct intel_engine_cs *ring,
	return 0;
}

static void fini_hash_table(struct intel_engine_cs *ring)
static void fini_hash_table(struct intel_engine_cs *engine)
{
	struct hlist_node *tmp;
	struct cmd_node *desc_node;
	int i;

	hash_for_each_safe(ring->cmd_hash, i, tmp, desc_node, node) {
	hash_for_each_safe(engine->cmd_hash, i, tmp, desc_node, node) {
		hash_del(&desc_node->node);
		kfree(desc_node);
	}
@@ -690,18 +744,18 @@ static void fini_hash_table(struct intel_engine_cs *ring)
 *
 * Return: non-zero if initialization fails
 */
int i915_cmd_parser_init_ring(struct intel_engine_cs *ring)
int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
{
	const struct drm_i915_cmd_table *cmd_tables;
	int cmd_table_count;
	int ret;

	if (!IS_GEN7(ring->dev))
	if (!IS_GEN7(engine->dev))
		return 0;

	switch (ring->id) {
	switch (engine->id) {
	case RCS:
		if (IS_HASWELL(ring->dev)) {
		if (IS_HASWELL(engine->dev)) {
			cmd_tables = hsw_render_ring_cmds;
			cmd_table_count =
				ARRAY_SIZE(hsw_render_ring_cmds);
@@ -710,26 +764,23 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring)
			cmd_table_count = ARRAY_SIZE(gen7_render_cmds);
		}

		ring->reg_table = gen7_render_regs;
		ring->reg_count = ARRAY_SIZE(gen7_render_regs);

		if (IS_HASWELL(ring->dev)) {
			ring->master_reg_table = hsw_master_regs;
			ring->master_reg_count = ARRAY_SIZE(hsw_master_regs);
		if (IS_HASWELL(engine->dev)) {
			engine->reg_tables = hsw_render_reg_tables;
			engine->reg_table_count = ARRAY_SIZE(hsw_render_reg_tables);
		} else {
			ring->master_reg_table = ivb_master_regs;
			ring->master_reg_count = ARRAY_SIZE(ivb_master_regs);
			engine->reg_tables = ivb_render_reg_tables;
			engine->reg_table_count = ARRAY_SIZE(ivb_render_reg_tables);
		}

		ring->get_cmd_length_mask = gen7_render_get_cmd_length_mask;
		engine->get_cmd_length_mask = gen7_render_get_cmd_length_mask;
		break;
	case VCS:
		cmd_tables = gen7_video_cmds;
		cmd_table_count = ARRAY_SIZE(gen7_video_cmds);
		ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
		engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
		break;
	case BCS:
		if (IS_HASWELL(ring->dev)) {
		if (IS_HASWELL(engine->dev)) {
			cmd_tables = hsw_blt_ring_cmds;
			cmd_table_count = ARRAY_SIZE(hsw_blt_ring_cmds);
		} else {
@@ -737,44 +788,41 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring)
			cmd_table_count = ARRAY_SIZE(gen7_blt_cmds);
		}

		ring->reg_table = gen7_blt_regs;
		ring->reg_count = ARRAY_SIZE(gen7_blt_regs);

		if (IS_HASWELL(ring->dev)) {
			ring->master_reg_table = hsw_master_regs;
			ring->master_reg_count = ARRAY_SIZE(hsw_master_regs);
		if (IS_HASWELL(engine->dev)) {
			engine->reg_tables = hsw_blt_reg_tables;
			engine->reg_table_count = ARRAY_SIZE(hsw_blt_reg_tables);
		} else {
			ring->master_reg_table = ivb_master_regs;
			ring->master_reg_count = ARRAY_SIZE(ivb_master_regs);
			engine->reg_tables = ivb_blt_reg_tables;
			engine->reg_table_count = ARRAY_SIZE(ivb_blt_reg_tables);
		}

		ring->get_cmd_length_mask = gen7_blt_get_cmd_length_mask;
		engine->get_cmd_length_mask = gen7_blt_get_cmd_length_mask;
		break;
	case VECS:
		cmd_tables = hsw_vebox_cmds;
		cmd_table_count = ARRAY_SIZE(hsw_vebox_cmds);
		/* VECS can use the same length_mask function as VCS */
		ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
		engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
		break;
	default:
		DRM_ERROR("CMD: cmd_parser_init with unknown ring: %d\n",
			  ring->id);
			  engine->id);
		BUG();
	}

	BUG_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count));
	BUG_ON(!validate_regs_sorted(ring));
	BUG_ON(!validate_cmds_sorted(engine, cmd_tables, cmd_table_count));
	BUG_ON(!validate_regs_sorted(engine));

	WARN_ON(!hash_empty(ring->cmd_hash));
	WARN_ON(!hash_empty(engine->cmd_hash));

	ret = init_hash_table(ring, cmd_tables, cmd_table_count);
	ret = init_hash_table(engine, cmd_tables, cmd_table_count);
	if (ret) {
		DRM_ERROR("CMD: cmd_parser_init failed!\n");
		fini_hash_table(ring);
		fini_hash_table(engine);
		return ret;
	}

	ring->needs_cmd_parser = true;
	engine->needs_cmd_parser = true;

	return 0;
}
@@ -786,21 +834,21 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring)
 * Releases any resources related to command parsing that may have been
 * initialized for the specified ring.
 */
void i915_cmd_parser_fini_ring(struct intel_engine_cs *ring)
void i915_cmd_parser_fini_ring(struct intel_engine_cs *engine)
{
	if (!ring->needs_cmd_parser)
	if (!engine->needs_cmd_parser)
		return;

	fini_hash_table(ring);
	fini_hash_table(engine);
}

static const struct drm_i915_cmd_descriptor*
find_cmd_in_table(struct intel_engine_cs *ring,
find_cmd_in_table(struct intel_engine_cs *engine,
		  u32 cmd_header)
{
	struct cmd_node *desc_node;

	hash_for_each_possible(ring->cmd_hash, desc_node, node,
	hash_for_each_possible(engine->cmd_hash, desc_node, node,
			       cmd_header & CMD_HASH_MASK) {
		const struct drm_i915_cmd_descriptor *desc = desc_node->desc;
		u32 masked_cmd = desc->cmd.mask & cmd_header;
@@ -822,18 +870,18 @@ find_cmd_in_table(struct intel_engine_cs *ring,
 * ring's default length encoding and returns default_desc.
 */
static const struct drm_i915_cmd_descriptor*
find_cmd(struct intel_engine_cs *ring,
find_cmd(struct intel_engine_cs *engine,
	 u32 cmd_header,
	 struct drm_i915_cmd_descriptor *default_desc)
{
	const struct drm_i915_cmd_descriptor *desc;
	u32 mask;

	desc = find_cmd_in_table(ring, cmd_header);
	desc = find_cmd_in_table(engine, cmd_header);
	if (desc)
		return desc;

	mask = ring->get_cmd_length_mask(cmd_header);
	mask = engine->get_cmd_length_mask(cmd_header);
	if (!mask)
		return NULL;

@@ -848,13 +896,32 @@ static const struct drm_i915_reg_descriptor *
find_reg(const struct drm_i915_reg_descriptor *table,
	 int count, u32 addr)
{
	if (table) {
	int i;

	for (i = 0; i < count; i++) {
		if (i915_mmio_reg_offset(table[i].addr) == addr)
			return &table[i];
	}

	return NULL;
}

static const struct drm_i915_reg_descriptor *
find_reg_in_tables(const struct drm_i915_reg_table *tables,
		   int count, bool is_master, u32 addr)
{
	int i;
	const struct drm_i915_reg_table *table;
	const struct drm_i915_reg_descriptor *reg;

	for (i = 0; i < count; i++) {
		table = &tables[i];
		if (!table->master || is_master) {
			reg = find_reg(table->regs, table->num_regs,
				       addr);
			if (reg != NULL)
				return reg;
		}
	}

	return NULL;
@@ -963,18 +1030,18 @@ static u32 *copy_batch(struct drm_i915_gem_object *dest_obj,
 *
 * Return: true if the ring requires software command parsing
 */
bool i915_needs_cmd_parser(struct intel_engine_cs *ring)
bool i915_needs_cmd_parser(struct intel_engine_cs *engine)
{
	if (!ring->needs_cmd_parser)
	if (!engine->needs_cmd_parser)
		return false;

	if (!USES_PPGTT(ring->dev))
	if (!USES_PPGTT(engine->dev))
		return false;

	return (i915.enable_cmd_parser == 1);
}

static bool check_cmd(const struct intel_engine_cs *ring,
static bool check_cmd(const struct intel_engine_cs *engine,
		      const struct drm_i915_cmd_descriptor *desc,
		      const u32 *cmd, u32 length,
		      const bool is_master,
@@ -1004,17 +1071,14 @@ static bool check_cmd(const struct intel_engine_cs *ring,
		     offset += step) {
			const u32 reg_addr = cmd[offset] & desc->reg.mask;
			const struct drm_i915_reg_descriptor *reg =
				find_reg(ring->reg_table, ring->reg_count,
					 reg_addr);

			if (!reg && is_master)
				reg = find_reg(ring->master_reg_table,
					       ring->master_reg_count,
				find_reg_in_tables(engine->reg_tables,
						   engine->reg_table_count,
						   is_master,
						   reg_addr);

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

@@ -1087,7 +1151,7 @@ static bool check_cmd(const struct intel_engine_cs *ring,
						 *cmd,
						 desc->bits[i].mask,
						 desc->bits[i].expected,
						 dword, ring->id);
						 dword, engine->id);
				return false;
			}
		}
@@ -1113,7 +1177,7 @@ static bool check_cmd(const struct intel_engine_cs *ring,
 * 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 *ring,
int i915_parse_cmds(struct intel_engine_cs *engine,
		    struct drm_i915_gem_object *batch_obj,
		    struct drm_i915_gem_object *shadow_batch_obj,
		    u32 batch_start_offset,
@@ -1147,7 +1211,7 @@ int i915_parse_cmds(struct intel_engine_cs *ring,
		if (*cmd == MI_BATCH_BUFFER_END)
			break;

		desc = find_cmd(ring, *cmd, &default_desc);
		desc = find_cmd(engine, *cmd, &default_desc);
		if (!desc) {
			DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n",
					 *cmd);
@@ -1179,7 +1243,7 @@ int i915_parse_cmds(struct intel_engine_cs *ring,
			break;
		}

		if (!check_cmd(ring, desc, cmd, length, is_master,
		if (!check_cmd(engine, desc, cmd, length, is_master,
			       &oacontrol_set)) {
			ret = -EINVAL;
			break;
@@ -1223,6 +1287,7 @@ int i915_cmd_parser_get_version(void)
	 * 3. Allow access to the GPGPU_THREADS_DISPATCHED register.
	 * 4. L3 atomic chicken bits of HSW_SCRATCH1 and HSW_ROW_CHICKEN3.
	 * 5. GPGPU dispatch compute indirect registers.
	 * 6. TIMESTAMP register and Haswell CS GPR registers
	 */
	return 5;
	return 6;
}
Loading