summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_cmd_parser.c
diff options
context:
space:
mode:
authorJordan Justen <jordan.l.justen@intel.com>2016-03-06 23:30:27 -0800
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-03-21 10:02:01 +0100
commit361b027bc6ae8501756829043ac98e42e40494f8 (patch)
treee2e87a23db286f7abef512f69777e4f51e6afc56 /drivers/gpu/drm/i915/i915_cmd_parser.c
parenta6573e1f54b713f837ac08d87961f610c63246ba (diff)
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: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: Francisco Jerez <currojerez@riseup.net> [danvet: Pipe patch through sed -e 's/\<ring\>/engine/g' to make it apply.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_cmd_parser.c')
-rw-r--r--drivers/gpu/drm/i915/i915_cmd_parser.c101
1 files changed, 72 insertions, 29 deletions
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index a5ebe9a13a11..ce753d3a817f 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -501,6 +501,32 @@ 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_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;
@@ -614,9 +640,16 @@ static bool check_sorted(int ring_id,
static bool validate_regs_sorted(struct intel_engine_cs *engine)
{
- return check_sorted(engine->id, engine->reg_table, engine->reg_count) &&
- check_sorted(engine->id, engine->master_reg_table,
- engine->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 {
@@ -711,15 +744,12 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
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)) {
- engine->master_reg_table = hsw_master_regs;
- engine->master_reg_count = ARRAY_SIZE(hsw_master_regs);
+ engine->reg_tables = hsw_render_reg_tables;
+ engine->reg_table_count = ARRAY_SIZE(hsw_render_reg_tables);
} else {
- engine->master_reg_table = ivb_master_regs;
- engine->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);
}
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);
}
- engine->reg_table = gen7_blt_regs;
- engine->reg_count = ARRAY_SIZE(gen7_blt_regs);
-
if (IS_HASWELL(engine->dev)) {
- engine->master_reg_table = hsw_master_regs;
- engine->master_reg_count = ARRAY_SIZE(hsw_master_regs);
+ engine->reg_tables = hsw_blt_reg_tables;
+ engine->reg_table_count = ARRAY_SIZE(hsw_blt_reg_tables);
} else {
- engine->master_reg_table = ivb_master_regs;
- engine->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);
}
engine->get_cmd_length_mask = gen7_blt_get_cmd_length_mask;
@@ -849,12 +876,31 @@ static const struct drm_i915_reg_descriptor *
find_reg(const struct drm_i915_reg_descriptor *table,
int count, u32 addr)
{
- if (table) {
- int i;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if (i915_mmio_reg_offset(table[i].addr) == addr)
+ return &table[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;
}
}
@@ -1005,13 +1051,10 @@ static bool check_cmd(const struct intel_engine_cs *engine,
offset += step) {
const u32 reg_addr = cmd[offset] & desc->reg.mask;
const struct drm_i915_reg_descriptor *reg =
- find_reg(engine->reg_table, engine->reg_count,
- reg_addr);
-
- if (!reg && is_master)
- reg = find_reg(engine->master_reg_table,
- engine->master_reg_count,
- reg_addr);
+ 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",