From patchwork Tue Nov 26 16:51:21 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: bradley.d.volkin@intel.com X-Patchwork-Id: 3239671 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7F16F9F3A0 for ; Tue, 26 Nov 2013 16:52:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9FB6B203F3 for ; Tue, 26 Nov 2013 16:52:35 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 6FF77203ED for ; Tue, 26 Nov 2013 16:52:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E5A86FB852; Tue, 26 Nov 2013 08:52:26 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 4377AF9DBB for ; Tue, 26 Nov 2013 08:52:24 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 26 Nov 2013 08:52:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.93,775,1378882800"; d="scan'208";a="415344860" Received: from bdvolkin-desk1.amr.corp.intel.com (HELO localhost.localdomain) ([10.10.34.110]) by orsmga001.jf.intel.com with ESMTP; 26 Nov 2013 08:52:22 -0800 From: bradley.d.volkin@intel.com To: intel-gfx@lists.freedesktop.org Date: Tue, 26 Nov 2013 08:51:21 -0800 Message-Id: <1385484699-51596-5-git-send-email-bradley.d.volkin@intel.com> X-Mailer: git-send-email 1.8.4.4 In-Reply-To: <1385484699-51596-1-git-send-email-bradley.d.volkin@intel.com> References: <1385484699-51596-1-git-send-email-bradley.d.volkin@intel.com> Subject: [Intel-gfx] [RFC 04/22] drm/i915: Add per-ring command length decode functions X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org 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 From: Brad Volkin For commands that aren't in the parser's tables, we get the length based on standard per-ring command encodings for specific opcode ranges. These functions just return the bitmask and the parser will extract the actual length value. OTC-Tracker: AXIA-4631 Change-Id: I2729d4483931cb4aea9403fd43710c4d4e8e5e89 Signed-off-by: Brad Volkin --- drivers/gpu/drm/i915/i915_cmd_parser.c | 62 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 12 +++++++ 2 files changed, 74 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 014e661..247d530 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -137,6 +137,62 @@ static const struct drm_i915_cmd_table gen7_blt_cmds[] = { { blt_cmds, ARRAY_SIZE(blt_cmds) }, }; +#define CLIENT_MASK 0xE0000000 +#define SUBCLIENT_MASK 0x18000000 +#define MI_CLIENT 0x00000000 +#define RC_CLIENT 0x60000000 +#define BC_CLIENT 0x40000000 +#define MEDIA_SUBCLIENT 0x10000000 + +static u32 gen7_render_get_cmd_length_mask(u32 cmd_header) +{ + u32 client = cmd_header & CLIENT_MASK; + u32 subclient = cmd_header & SUBCLIENT_MASK; + + if (client == MI_CLIENT) + return 0x3F; + else if (client == RC_CLIENT) { + if (subclient == MEDIA_SUBCLIENT) + return 0xFFFF; + else + return 0xFF; + } + + DRM_DEBUG_DRIVER("CMD: Abnormal rcs cmd length! 0x%08X\n", cmd_header); + return 0; +} + +static u32 gen7_bsd_get_cmd_length_mask(u32 cmd_header) +{ + u32 client = cmd_header & CLIENT_MASK; + u32 subclient = cmd_header & SUBCLIENT_MASK; + + if (client == MI_CLIENT) + return 0x3F; + else if (client == RC_CLIENT) { + if (subclient == MEDIA_SUBCLIENT) + return 0xFFF; + else + return 0xFF; + } + + DRM_DEBUG_DRIVER("CMD: Abnormal bsd cmd length! 0x%08X\n", cmd_header); + return 0; +} + +static u32 gen7_blt_get_cmd_length_mask(u32 cmd_header) +{ + u32 client = cmd_header & CLIENT_MASK; + + if (client == MI_CLIENT) + return 0x3F; + else if (client == BC_CLIENT) + return 0xFF; + + DRM_DEBUG_DRIVER("CMD: Abnormal blt cmd length! 0x%08X\n", cmd_header); + return 0; +} + void i915_cmd_parser_init_ring(struct intel_ring_buffer *ring) { if (!IS_GEN7(ring->dev)) @@ -152,18 +208,24 @@ void i915_cmd_parser_init_ring(struct intel_ring_buffer *ring) ring->cmd_tables = gen7_render_cmds; ring->cmd_table_count = ARRAY_SIZE(gen7_render_cmds); } + + ring->get_cmd_length_mask = gen7_render_get_cmd_length_mask; break; case VCS: ring->cmd_tables = gen7_video_cmds; ring->cmd_table_count = ARRAY_SIZE(gen7_video_cmds); + ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask; break; case BCS: ring->cmd_tables = gen7_blt_cmds; ring->cmd_table_count = ARRAY_SIZE(gen7_blt_cmds); + ring->get_cmd_length_mask = gen7_blt_get_cmd_length_mask; break; case VECS: ring->cmd_tables = hsw_vebox_cmds; ring->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; break; default: DRM_DEBUG("CMD: cmd_parser_init with unknown ring: %d\n", diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 67305d3..8e71b59 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -169,6 +169,18 @@ struct intel_ring_buffer { */ const struct drm_i915_cmd_table *cmd_tables; int cmd_table_count; + + /** + * Returns the bitmask for the length field of the specified command. + * Return 0 for an unrecognized/invalid command. + * + * If the command parser finds an entry for a command in the ring's + * cmd_tables, it gets the command's length based on the table entry. + * If not, it calls this function to determine the per-ring length field + * encoding for the command (i.e. certain opcode ranges use certain bits + * to encode the command length in the header). + */ + u32 (*get_cmd_length_mask)(u32 cmd_header); }; static inline bool