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

Commit 361b027b authored by Jordan Justen's avatar Jordan Justen Committed by Daniel Vetter
Browse files

drm/i915: Use an array of register tables in command parser



For Haswell, we will want another table of registers while retaining
the large common table of whitelisted registers shared by all gen7
devices.

Signed-off-by: default avatarJordan Justen <jordan.l.justen@intel.com>
Reviewed-by: default avatarFrancisco Jerez <currojerez@riseup.net>
[danvet: Pipe patch through sed -e 's/\<ring\>/engine/g' to make it
apply.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent a6573e1f
Loading
Loading
Loading
Loading
+72 −29
Original line number Original line Diff line number Diff line
@@ -501,6 +501,32 @@ static const struct drm_i915_reg_descriptor hsw_master_regs[] = {
#undef REG64
#undef REG64
#undef REG32
#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_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)
static u32 gen7_render_get_cmd_length_mask(u32 cmd_header)
{
{
	u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
	u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
@@ -614,9 +640,16 @@ static bool check_sorted(int ring_id,


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

	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 {
struct cmd_node {
@@ -711,15 +744,12 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
			cmd_table_count = ARRAY_SIZE(gen7_render_cmds);
			cmd_table_count = ARRAY_SIZE(gen7_render_cmds);
		}
		}


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

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


		engine->get_cmd_length_mask = gen7_render_get_cmd_length_mask;
		engine->get_cmd_length_mask = gen7_render_get_cmd_length_mask;
@@ -738,15 +768,12 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
			cmd_table_count = ARRAY_SIZE(gen7_blt_cmds);
			cmd_table_count = ARRAY_SIZE(gen7_blt_cmds);
		}
		}


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

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


		engine->get_cmd_length_mask = gen7_blt_get_cmd_length_mask;
		engine->get_cmd_length_mask = gen7_blt_get_cmd_length_mask;
@@ -849,13 +876,32 @@ static const struct drm_i915_reg_descriptor *
find_reg(const struct drm_i915_reg_descriptor *table,
find_reg(const struct drm_i915_reg_descriptor *table,
	 int count, u32 addr)
	 int count, u32 addr)
{
{
	if (table) {
	int i;
	int i;


	for (i = 0; i < count; i++) {
	for (i = 0; i < count; i++) {
		if (i915_mmio_reg_offset(table[i].addr) == addr)
		if (i915_mmio_reg_offset(table[i].addr) == addr)
			return &table[i];
			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;
	return NULL;
@@ -1005,12 +1051,9 @@ static bool check_cmd(const struct intel_engine_cs *engine,
		     offset += step) {
		     offset += step) {
			const u32 reg_addr = cmd[offset] & desc->reg.mask;
			const u32 reg_addr = cmd[offset] & desc->reg.mask;
			const struct drm_i915_reg_descriptor *reg =
			const struct drm_i915_reg_descriptor *reg =
				find_reg(engine->reg_table, engine->reg_count,
				find_reg_in_tables(engine->reg_tables,
					 reg_addr);
						   engine->reg_table_count,

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


			if (!reg) {
			if (!reg) {
+3 −10
Original line number Original line Diff line number Diff line
@@ -123,7 +123,7 @@ struct intel_ringbuffer {
};
};


struct	intel_context;
struct	intel_context;
struct drm_i915_reg_descriptor;
struct drm_i915_reg_table;


/*
/*
 * we use a single page to load ctx workarounds so all of these
 * we use a single page to load ctx workarounds so all of these
@@ -331,15 +331,8 @@ struct intel_engine_cs {
	/*
	/*
	 * Table of registers allowed in commands that read/write registers.
	 * Table of registers allowed in commands that read/write registers.
	 */
	 */
	const struct drm_i915_reg_descriptor *reg_table;
	const struct drm_i915_reg_table *reg_tables;
	int reg_count;
	int reg_table_count;

	/*
	 * Table of registers allowed in commands that read/write registers, but
	 * only from the DRM master.
	 */
	const struct drm_i915_reg_descriptor *master_reg_table;
	int master_reg_count;


	/*
	/*
	 * Returns the bitmask for the length field of the specified command.
	 * Returns the bitmask for the length field of the specified command.