From patchwork Mon Dec 21 13:10:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jani Nikula X-Patchwork-Id: 7895721 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 08C61BEEE5 for ; Mon, 21 Dec 2015 13:11:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 23D712055B for ; Mon, 21 Dec 2015 13:11:23 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 47B0F20553 for ; Mon, 21 Dec 2015 13:11:22 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B789D6E410; Mon, 21 Dec 2015 05:11:21 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTP id 48E806E410 for ; Mon, 21 Dec 2015 05:11:20 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 21 Dec 2015 05:11:20 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,459,1444719600"; d="scan'208";a="878205065" Received: from jnikula-mobl.fi.intel.com (HELO localhost) ([10.237.72.67]) by fmsmga002.fm.intel.com with ESMTP; 21 Dec 2015 05:11:18 -0800 From: Jani Nikula To: intel-gfx@lists.freedesktop.org Date: Mon, 21 Dec 2015 15:10:56 +0200 Message-Id: X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo Cc: jani.nikula@intel.com, Deepak M Subject: [Intel-gfx] [PATCH 05/15] drm/i915/bios: abstract finding the panel sequence block 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 Make the whole thing easier to read. Signed-off-by: Jani Nikula Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_bios.c | 76 +++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 7393596df37d..9511a5341562 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -697,7 +697,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time; } -static u8 *goto_next_sequence(u8 *data, int *size) +static u8 *goto_next_sequence(u8 *data, u16 *size) { u16 len; int tmp = *size; @@ -818,15 +818,52 @@ parse_mipi_config(struct drm_i915_private *dev_priv, dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; } +/* Find the sequence block and size for the given panel. */ +static const u8 * +find_panel_sequence_block(const struct bdb_mipi_sequence *sequence, + u16 panel_id, u16 *seq_size) +{ + u32 total = get_blocksize(sequence); + const u8 *data = &sequence->data[0]; + u8 current_id; + u16 current_size; + int index = 0; + int i; + + for (i = 0; i < MAX_MIPI_CONFIGURATIONS && index + 3 < total; i++) { + current_id = *(data + index); + index++; + + current_size = *((const u16 *)(data + index)); + index += 2; + + if (index + current_size > total) { + DRM_ERROR("Invalid sequence block\n"); + return NULL; + } + + if (current_id == panel_id) { + *seq_size = current_size; + return data + index; + } + + index += current_size; + } + + DRM_ERROR("Sequence block detected but no valid configuration\n"); + + return NULL; +} + static void parse_mipi_sequence(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) { const struct bdb_mipi_sequence *sequence; const u8 *seq_data; + u16 seq_size; u8 *data; u16 block_size; - int i, panel_id, seq_size; /* Only our generic panel driver uses the sequence block. */ if (dev_priv->vbt.dsi.panel_id != MIPI_DSI_GENERIC_PANEL_ID) @@ -853,40 +890,11 @@ parse_mipi_sequence(struct drm_i915_private *dev_priv, */ dev_priv->vbt.dsi.seq_version = sequence->version; - seq_data = &sequence->data[0]; - - /* - * sequence block is variable length and hence we need to parse and - * get the sequence data for specific panel id - */ - for (i = 0; i < MAX_MIPI_CONFIGURATIONS; i++) { - panel_id = *seq_data; - seq_size = *((u16 *) (seq_data + 1)); - if (panel_id == panel_type) - break; - - /* skip the sequence including seq header of 3 bytes */ - seq_data = seq_data + 3 + seq_size; - if ((seq_data - &sequence->data[0]) > block_size) { - DRM_ERROR("Sequence start is beyond sequence block size, corrupted sequence block\n"); - return; - } - } - - if (i == MAX_MIPI_CONFIGURATIONS) { - DRM_ERROR("Sequence block detected but no valid configuration\n"); + seq_data = find_panel_sequence_block(sequence, panel_type, &seq_size); + if (!seq_data) return; - } - - /* check if found sequence is completely within the sequence block - * just being paranoid */ - if (seq_size > block_size) { - DRM_ERROR("Corrupted sequence/size, bailing out\n"); - return; - } - /* skip the panel id(1 byte) and seq size(2 bytes) */ - dev_priv->vbt.dsi.data = kmemdup(seq_data + 3, seq_size, GFP_KERNEL); + dev_priv->vbt.dsi.data = kmemdup(seq_data, seq_size, GFP_KERNEL); if (!dev_priv->vbt.dsi.data) return;