From patchwork Mon Mar 7 07:30:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Justen X-Patchwork-Id: 8515881 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 145F79F38C for ; Mon, 7 Mar 2016 07:32:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1F61020121 for ; Mon, 7 Mar 2016 07:32:57 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 1013220142 for ; Mon, 7 Mar 2016 07:32:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 158AB6E11E; Mon, 7 Mar 2016 07:32:53 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 166176E0D7 for ; Mon, 7 Mar 2016 07:32:39 +0000 (UTC) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP; 06 Mar 2016 23:32:38 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,550,1449561600"; d="scan'208";a="665037041" Received: from llingapp-mobl5.amr.corp.intel.com (HELO localhost.localdomain) ([10.252.132.83]) by FMSMGA003.fm.intel.com with ESMTP; 06 Mar 2016 23:30:39 -0800 From: Jordan Justen To: intel-gfx@lists.freedesktop.org Date: Sun, 6 Mar 2016 23:30:27 -0800 Message-Id: <1457335830-30923-3-git-send-email-jordan.l.justen@intel.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1457335830-30923-1-git-send-email-jordan.l.justen@intel.com> References: <1457335830-30923-1-git-send-email-jordan.l.justen@intel.com> Subject: [Intel-gfx] [PATCH 2/5] drm/i915: Use an array of register tables in command parser X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Reviewed-by: Francisco Jerez --- drivers/gpu/drm/i915/i915_cmd_parser.c | 101 +++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_ringbuffer.h | 13 +--- 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 86d7cda..46ea40b 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 *ring) { - 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 < ring->reg_table_count; i++) { + table = &ring->reg_tables[i]; + if (!check_sorted(ring->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 *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); + ring->reg_tables = hsw_render_reg_tables; + ring->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); + ring->reg_tables = ivb_render_reg_tables; + ring->reg_table_count = ARRAY_SIZE(ivb_render_reg_tables); } ring->get_cmd_length_mask = gen7_render_get_cmd_length_mask; @@ -738,15 +768,12 @@ 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); + ring->reg_tables = hsw_blt_reg_tables; + ring->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); + ring->reg_tables = ivb_blt_reg_tables; + ring->reg_table_count = ARRAY_SIZE(ivb_blt_reg_tables); } ring->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 *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, - reg_addr); + find_reg_in_tables(ring->reg_tables, + ring->reg_table_count, + is_master, + reg_addr); if (!reg) { DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n", diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 566b0ae..5f89261 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -125,7 +125,7 @@ struct intel_ringbuffer { }; 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 @@ -332,15 +332,8 @@ struct intel_engine_cs { /* * Table of registers allowed in commands that read/write registers. */ - const struct drm_i915_reg_descriptor *reg_table; - int reg_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; + const struct drm_i915_reg_table *reg_tables; + int reg_table_count; /* * Returns the bitmask for the length field of the specified command.