From patchwork Thu Jan 25 13:37:26 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: 10185315 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 1B68F60383 for ; Fri, 26 Jan 2018 08:39:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 076DA29101 for ; Fri, 26 Jan 2018 08:39:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF1A029103; Fri, 26 Jan 2018 08:39:44 +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 817E129101 for ; Fri, 26 Jan 2018 08:39:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9B0176E34E; 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-x242.google.com (mail-wm0-x242.google.com [IPv6:2a00:1450:400c:c09::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 86C7C6E0A4; Thu, 25 Jan 2018 13:37:33 +0000 (UTC) Received: by mail-wm0-x242.google.com with SMTP id v71so15012105wmv.2; Thu, 25 Jan 2018 05:37:33 -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=/rx7bNW3uatUwZWU5xxNfFzaxP+Sexkv66sYp0OhmmU=; b=ilDL7lBT/rhiHruInjP1mlQr5Oxem/XChXcNXGFDyHwiO9JVoZv1PXlFEe8q2fKoWC 0yEFZcGq51rTWclvFslyjipKrRU6b6V0A9Vs6VMI0jbfGggR1m56Qt39/2LVn1diRWzH iw+Z8ahKxpNe7dZR0lEId0yfi5RZiPr5qdw91XbpgT+Kn2iCK8Q4U2yn+NwGMiyNsriQ j+ph4ofqAcZ05m7x3jrJWdIjNNYw5IkRH8wbBGIpNhuN2ymYHHPgmI0ay2jC/RkhSecp It9K4fwmSKn/LTVYKAMsukB2a4SudaGt6ewNgoGHogVexlLHmoM4Ch8srk/1lmqPBz81 630w== 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=/rx7bNW3uatUwZWU5xxNfFzaxP+Sexkv66sYp0OhmmU=; b=TjEPljtHp07wXUIXLwdPlRN/9gJIBa+vAXqTe/CoXaxCsBxILxSOU9h1X1FN2LUpyM kzCEs876LaS2/ChTY6bnt6szMHYyjvqTdqkBsyExzgqlGNif1CWCHnCgHHhQfwtKiPTA JINQeajZR8djzLTfr56PNZWwF+G3jrmjG9oXtOmHpr+nhsQMYiji/sy1go+5Or2OG5z7 SOT+7vL3R9fjgi4RWALMrq9vEQaFzqR1RWpdQbGBKg6bhBe/Nr3uqzc0gailT7g+S5Na MCbmeQ8Xh1pFbkBKyy39y0lVa7e9xvRGvgzwmvaikCUvnNQlMTaNcD772iHe4vCz5atH D4og== X-Gm-Message-State: AKwxytfmqQfJIxhV2pm1P7bczJhZVrtlqUoWa4hx5zoSAbkyhhoj5XL1 0JQR1MTINWzwZGkAEO3+XLQ= X-Google-Smtp-Source: AH8x2278Hw87UleemsmlJBgeNX1Z8RPtGUGeuyclVKp9IGV33sSp8kP+NhIQJmxFI8OOStBW/j5RzA== X-Received: by 10.80.137.164 with SMTP id g33mr29267561edg.261.1516887451968; Thu, 25 Jan 2018 05:37:31 -0800 (PST) Received: from shalem.localdomain (546A5441.cm-12-3b.dynamic.ziggo.nl. [84.106.84.65]) by smtp.gmail.com with ESMTPSA id y5sm1316253ede.71.2018.01.25.05.37.30 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 25 Jan 2018 05:37:30 -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 Date: Thu, 25 Jan 2018 14:37:26 +0100 Message-Id: <20180125133726.7325-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 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 making mipi_exec_send_packet() call intel_dsi_device_ready() if not done already, so that we can call the INIT_OTP sequence earlier on affected devices. Note that this only changes the init-sequence on devices for which intel_dsi_use_init_otp_as_deassert() returns true, on other devices intel_dsi->device_ready will be set to true before calling any MIPI sequences which may send packets, so the check added to mipi_exec_send_packet() is a nop there. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=82880 Related: https://bugs.freedesktop.org/show_bug.cgi?id=101205 Reported-by: Jan-Michael Brummer Tested-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/gpu/drm/i915/intel_dsi.c | 53 ++++++++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_dsi.h | 4 +++ drivers/gpu/drm/i915/intel_dsi_vbt.c | 6 ++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index f67d321376e4..3d82811a38f3 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -539,9 +539,14 @@ static void vlv_dsi_device_ready(struct intel_encoder *encoder) } } -static void intel_dsi_device_ready(struct intel_encoder *encoder) +void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + + /* Already done? */ + if (intel_dsi->device_ready) + return; if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) vlv_dsi_device_ready(encoder); @@ -549,6 +554,8 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) bxt_dsi_device_ready(encoder); else if (IS_GEMINILAKE(dev_priv)) glk_dsi_device_ready(encoder); + + intel_dsi->device_ready = true; } static void glk_dsi_enter_low_power_mode(struct intel_encoder *encoder) @@ -786,6 +793,36 @@ static void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) * - wait t4 - wait t4 */ +/* + * Some v1 VBT MIPI sequences do the deassert in the init OTP sequence. + * The deassert must be done before calling intel_dsi_device_ready, while + * intel_dsi_device_ready() must be called before any send packet ops inside + * the init OTP sequence. mipi_exec_send_packet() deals with calling + * intel_dsi_device_ready() if necessary. This function checks if we need + * to call init OTP at deassert time. + */ +static bool intel_dsi_use_init_otp_as_deassert(struct intel_dsi *intel_dsi) +{ + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + + /* Limit this to VLV for now. */ + if (!IS_VALLEYVIEW(dev_priv)) + return false; + + /* Limit this to v1 vid-mode sequences */ + if (!is_vid_mode(intel_dsi) || dev_priv->vbt.dsi.seq_version != 1) + return false; + + /* If there is an assert-reset seq and no deassert one, use init OTP */ + if (dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET] != 0 && + dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET] == 0) { + DRM_DEBUG_KMS("Using init OTP to deassert reset\n"); + return true; + } + + return false; +} + static void intel_dsi_pre_enable(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) @@ -840,7 +877,10 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); /* Deassert reset */ - intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); + if (intel_dsi_use_init_otp_as_deassert(intel_dsi)) + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); + else + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); if (IS_GEMINILAKE(dev_priv)) { glk_cold_boot = glk_dsi_enable_io(encoder); @@ -858,7 +898,8 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, intel_dsi_prepare(encoder, pipe_config); /* Send initialization commands in LP mode */ - intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); + if (!intel_dsi_use_init_otp_as_deassert(intel_dsi)) + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); /* Enable port in pre-enable phase itself because as per hw team * recommendation, port should be enabled befor plane & pipe */ @@ -925,12 +966,15 @@ static void intel_dsi_disable(struct intel_encoder *encoder, static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) || IS_BROXTON(dev_priv)) vlv_dsi_clear_device_ready(encoder); else if (IS_GEMINILAKE(dev_priv)) glk_dsi_clear_device_ready(encoder); + + intel_dsi->device_ready = false; } static void intel_dsi_post_disable(struct intel_encoder *encoder, @@ -944,6 +988,9 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder, DRM_DEBUG_KMS("\n"); + /* in case the dsi panel is on when the i915 driver gets loaded */ + intel_dsi->device_ready = true; + if (is_vid_mode(intel_dsi)) { for_each_dsi_port(port, intel_dsi->ports) wait_for_dsi_fifo_empty(intel_dsi, port); diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 7afeb9580f41..d501cbcc97d0 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -46,6 +46,9 @@ struct intel_dsi { struct intel_connector *attached_connector; + /* Have we put the device in ready state (LP-11) ? */ + bool device_ready; + /* bit mask of ports being driven */ u16 ports; @@ -132,6 +135,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) /* intel_dsi.c */ void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port); enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt); +void intel_dsi_device_ready(struct intel_encoder *encoder); /* intel_dsi_pll.c */ bool intel_dsi_pll_is_enabled(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index 91c07b0c8db9..cf4e9e2a8df1 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -118,6 +118,12 @@ static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, DRM_DEBUG_KMS("\n"); + /* Make sure the device is in ready state (LP-11) */ + if (!intel_dsi->device_ready) { + intel_dsi_device_ready(&intel_dsi->base); + usleep_range(10000, 20000); + } + flags = *data++; type = *data++;