From patchwork Fri Jan 26 07:52:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 10185313 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 833FA60383 for ; Fri, 26 Jan 2018 08:39:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 600EB29100 for ; Fri, 26 Jan 2018 08:39:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5287129102; Fri, 26 Jan 2018 08:39:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D350529100 for ; Fri, 26 Jan 2018 08:39:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5EF4D6E338; Fri, 26 Jan 2018 08:39:40 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x244.google.com (mail-wm0-x244.google.com [IPv6:2a00:1450:400c:c09::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 676C389E35; Fri, 26 Jan 2018 07:52:12 +0000 (UTC) Received: by mail-wm0-x244.google.com with SMTP id r78so19360495wme.0; Thu, 25 Jan 2018 23:52:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=ChOB709nKS7soIO1uJKYmtpuIZIbFro7wMIIeovVphg=; b=OqRtwok6B2Gg2RpQWYiuyuOxXa7sswoC9n72fBZlavAsrT9ORbhlOT10MJZshoZVBn 09FcxZSGL2tJhBQDMW/SiENZJfge1Ume+61YT8tZO8YqvW+caCtxgi2clZNTlR5NLg4d HzLi28anP84rXP/gFKZYLtIgeO3B/FlMbbeOeAWazVDcp+i/cN3j9E++raDXs8SV40Oy oMe9henig8pWxyrshdYfPsIb9Rw6DhcxtX0WhnmzQBtbb4JyW1nwyuhiiea+paziTwmg bRybzm9BY1RpzU0LI1jzVrVgvPeMH4K88SKi9eUXw4f/6vzGbYRzS7uQYWiqRJ4eqBDt Diag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ChOB709nKS7soIO1uJKYmtpuIZIbFro7wMIIeovVphg=; b=fu7U8G1QjMykt5vIYQSurqT+6iAQJiy4SuSMUu3RZT+D+xHzo1ftX1H+XMdDEdmdr1 tnMmdGb9w/ff7m9Ddq9Bv++XdYt+vXuXH2grGRRHUUqgzBvFtEj+5qdxOYp4bQR+deG1 2gCt5BaepxFef5vjx+ZFQ5/ThsmYyKLYAeXb9UD3VcI8Uk3jyDd3AfWzzmdFiLTT1oTy atiEMLH+KXUL9himkXzUYwZoSVudfcwQPLOZSM/OQaFwJGjbkEZxTBXDyKKdVZjzpwlD 4/utjj4lTVAPTkdsvVo6TnyKIuWu44MlBUUpYJho2nrT2mipznc6Yc3azbN/D9TsLJ4g qjCg== X-Gm-Message-State: AKwxytdXL79c9mfOTTlWnDSYQ7Tg1Lo1T8Hh+DOSPGt2sbXblKD77S+O 6EndAVCezdN90FvEvG7totQ= X-Google-Smtp-Source: AH8x225NZRgYwv7jHMoJ8rWgzm2ewRHr8NP7JUo7IRPFrCqeClxT8IGYUySvaJKgxDCgmyxYEsAyeg== X-Received: by 10.80.246.133 with SMTP id d5mr32230400edn.93.1516953130898; Thu, 25 Jan 2018 23:52:10 -0800 (PST) Received: from shalem.localdomain (546A5441.cm-12-3b.dynamic.ziggo.nl. [84.106.84.65]) by smtp.gmail.com with ESMTPSA id d20sm2032409ede.16.2018.01.25.23.52.09 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 25 Jan 2018 23:52:10 -0800 (PST) From: Hans de Goede X-Google-Original-From: Hans de Goede To: Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Subject: [PATCH] drm/i915: Fix DSI panels with v1 MIPI sequences without a DEASSERT sequence v2 Date: Fri, 26 Jan 2018 08:52:07 +0100 Message-Id: <20180126075207.311-1-hdegoede@redhat.com> X-Mailer: git-send-email 2.14.3 X-Mailman-Approved-At: Fri, 26 Jan 2018 08:39:39 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Hans de Goede , intel-gfx , dri-devel@lists.freedesktop.org, Jan-Michael Brummer MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP So far models of the Dell Venue 8 Pro, with a panel with MIPI panel index = 3, one of which has been kindly provided to me by Jan Brummer, where not working with the i915 driver, giving a black screen on the first modeset. The problem with at least these Dells is that their VBT defines a MIPI ASSERT sequence, but not a DEASSERT sequence. Instead they DEASSERT the reset in their INIT_OTP sequence, but the deassert must be done before calling intel_dsi_device_ready(), so that is too late. Simply doing the INIT_OTP sequence earlier is not enough to fix this, because the INIT_OTP sequence also sends various MIPI packets to the panel, which can only happen after calling intel_dsi_device_ready(). This commit fixes this by splitting the INIT_OTP sequence into everything before the first DSI packet and everything else, including the first DSI packet. The first part (everything before the first DSI packet) is then used as deassert sequence. Changed in v2: -Split the init OTP sequence into a deassert reset and the actual init OTP sequence, instead of calling it earlier and then having the first mipi_exec_send_packet() call call intel_dsi_device_ready(). BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=82880 Related: https://bugs.freedesktop.org/show_bug.cgi?id=101205 Cc: Jan-Michael Brummer Reported-by: Jan-Michael Brummer Tested-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/gpu/drm/i915/intel_dsi.c | 1 + drivers/gpu/drm/i915/intel_dsi.h | 2 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 82 ++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index f67d321376e4..b59ef34d25f6 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1642,6 +1642,7 @@ static void intel_dsi_encoder_destroy(struct drm_encoder *encoder) if (intel_dsi->gpio_panel) gpiod_put(intel_dsi->gpio_panel); + kfree(intel_dsi->deassert_seq); intel_encoder_destroy(encoder); } diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 7afeb9580f41..5895588144ad 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -46,6 +46,8 @@ struct intel_dsi { struct intel_connector *attached_connector; + u8 *deassert_seq; + /* bit mask of ports being driven */ u16 ports; diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index 91c07b0c8db9..84664f79cbef 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -499,6 +499,86 @@ int intel_dsi_vbt_get_modes(struct intel_dsi *intel_dsi) return 1; } +/* + * Get len of pre-fixed deassert from init OTP, skip all delay + gpio operands + * and stop at the first DSI packet op. + */ +static int intel_vbi_get_deassert_len(const u8 *data, int total) +{ + int index, len; + + /* index = 1 to skip sequence byte */ + for (index = 1; index < total; index += len) { + switch (data[index]) { + case MIPI_SEQ_ELEM_SEND_PKT: + return index; + case MIPI_SEQ_ELEM_DELAY: + len = 5; /* 1 byte for operand + uint32 */ + break; + case MIPI_SEQ_ELEM_GPIO: + len = 3; /* 1 byte for op, 1 for gpio_nr, 1 for value */ + break; + default: + return 0; + } + } + + return 0; +} + +/* + * Some v1 VBT MIPI sequences do the deassert in the init OTP sequence. + * The deassert must be done before calling intel_dsi_device_ready, so for + * these devices we split the init OTP sequence into a deassert sequence and + * the actual init OTP part. + */ +static void intel_dsi_fixup_dsi_sequences(struct intel_dsi *intel_dsi) +{ + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + int init_otp_index, len; + u8 *init_otp; + + /* Limit this to VLV for now. */ + if (!IS_VALLEYVIEW(dev_priv)) + return; + + /* Limit this to v1 vid-mode sequences */ + if (intel_dsi->operation_mode != INTEL_DSI_VIDEO_MODE || + dev_priv->vbt.dsi.seq_version != 1) + return; + + /* Only do this if there are otp and assert seqs and no deassert seq */ + if (!dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] || + !dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET] || + dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) + return; + + /* The deassert-sequence ends at the first DSI packet */ + init_otp_index = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] - + (const u8 *)dev_priv->vbt.dsi.data; + init_otp = dev_priv->vbt.dsi.data + init_otp_index; + len = dev_priv->vbt.dsi.size - init_otp_index; + len = intel_vbi_get_deassert_len(init_otp, len); + if (!len) + return; + + DRM_DEBUG_KMS("Using init OTP fragment to deassert reset\n"); + + /* Copy the fragment, update seq byte and terminate it */ + intel_dsi->deassert_seq = kmemdup(init_otp, len + 1, GFP_KERNEL); + if (!intel_dsi->deassert_seq) + return; + intel_dsi->deassert_seq[0] = MIPI_SEQ_DEASSERT_RESET; + intel_dsi->deassert_seq[len] = MIPI_SEQ_ELEM_END; + /* Use the copy for deassert */ + dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET] = + intel_dsi->deassert_seq; + /* Replace the last byte of the fragment with init OTP seq byte */ + init_otp[len - 1] = MIPI_SEQ_INIT_OTP; + /* And make MIPI_MIPI_SEQ_INIT_OTP point to it */ + dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] = init_otp + len - 1; +} + bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) { struct drm_device *dev = intel_dsi->base.base.dev; @@ -794,5 +874,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) mipi_dsi_attach(intel_dsi->dsi_hosts[port]->device); } + intel_dsi_fixup_dsi_sequences(intel_dsi); + return true; }