From patchwork Wed Nov 6 16:58:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Gerhold X-Patchwork-Id: 11230751 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BA0F0112B for ; Wed, 6 Nov 2019 17:01:25 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A269E21D7E for ; Wed, 6 Nov 2019 17:01:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A269E21D7E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gerhold.net Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 710706EDF3; Wed, 6 Nov 2019 17:01:14 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mo6-p02-ob.smtp.rzone.de (mo6-p02-ob.smtp.rzone.de [IPv6:2a01:238:20a:202:5302::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id D5D2C6E277 for ; Wed, 6 Nov 2019 17:01:11 +0000 (UTC) X-RZG-AUTH: ":P3gBZUipdd93FF5ZZvYFPugejmSTVR2nRPhVORvLd4SsytBXQrEOHTIXs8PvtBNfIQ==" X-RZG-CLASS-ID: mo00 Received: from localhost.localdomain by smtp.strato.de (RZmta 44.29.0 AUTH) with ESMTPSA id e07688vA6H15hLw (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 6 Nov 2019 18:01:05 +0100 (CET) From: Stephan Gerhold To: Linus Walleij Subject: [PATCH 6/7] drm/mcde: dsi: Enable clocks in pre_enable() instead of mode_set() Date: Wed, 6 Nov 2019 17:58:34 +0100 Message-Id: <20191106165835.2863-7-stephan@gerhold.net> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191106165835.2863-1-stephan@gerhold.net> References: <20191106165835.2863-1-stephan@gerhold.net> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1573059670; s=strato-dkim-0002; d=gerhold.net; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=sZdoB36F5UBdckaG8aj1GzQtE3+0zrTPGHer5Xs7ohg=; b=K2wR+BJqUik78z4mrqeIkEmFrRGUpyFgC7E1DbeIc11+E0jSZS+yeYReCUcjDVUATV ybTB5Ifd2wKfuc0j34eiMJKa4pT3NZ/NbY3aU/diWWllbrOzHA4CUy90bO5mU+w1B4ZP gEH7L7qxgiyvUdeNs9zRrV+Sfa/9/29a7Fqdr5XzYMMoBUf9FsOFkzI3GrV8qGHSUrwk F/VNMmiv97hpUN8zoCW6E26FeC0uUauOkQGIvP7yClVv0O5/dvgXQSz/mvHaRcai+AxV CKZIzT/f6kR6Gs33Z6T51Sknrxxr9NzvDkIThzaGH6RIWXXqQYWYEO3TPEtzHPAaqjwa wg4g== 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: David Airlie , Stephan Gerhold , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The DSI initialization sequence incorrectly assumes that the mode_set() function of the DRM bridge is always called when (re-)enabling the display. This is not necessarily the case. Keeping the device idle in the framebuffer console for a while results in the display being turned off using the disable() function. However, as soon as any key is pressed only (pre_)enable() are called. mode_set() is skipped because the mode has not been changed. In this case, the DSI HS/LP clocks are never turned back on, preventing the display from working. Fix this by moving a part of the initialization sequence from mode_set() to pre_enable(). Keep most of the video mode setup in mode_set() since most of the registers are only dependent on the mode that is set for the panel - there is no need to write them again each time we re-enable the display. Signed-off-by: Stephan Gerhold --- drivers/gpu/drm/mcde/mcde_dsi.c | 67 ++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index df963e078c35..03896a1f339a 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -562,21 +562,6 @@ static void mcde_dsi_setup_video_mode(struct mcde_dsi *d, DSI_VID_VCA_SETTING2_EXACT_BURST_LIMIT_SHIFT; writel(val, d->regs + DSI_VID_VCA_SETTING2); - /* Put IF1 into video mode */ - val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL); - val |= DSI_MCTL_MAIN_DATA_CTL_IF1_MODE; - writel(val, d->regs + DSI_MCTL_MAIN_DATA_CTL); - - /* Disable command mode on IF1 */ - val = readl(d->regs + DSI_CMD_MODE_CTL); - val &= ~DSI_CMD_MODE_CTL_IF1_LP_EN; - writel(val, d->regs + DSI_CMD_MODE_CTL); - - /* Enable some error interrupts */ - val = readl(d->regs + DSI_VID_MODE_STS_CTL); - val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC; - val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA; - writel(val, d->regs + DSI_VID_MODE_STS_CTL); } static void mcde_dsi_start(struct mcde_dsi *d) @@ -700,26 +685,13 @@ static void mcde_dsi_bridge_enable(struct drm_bridge *bridge) dev_info(d->dev, "enable DSI master\n"); }; -static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - const struct drm_display_mode *adj) +static void mcde_dsi_bridge_pre_enable(struct drm_bridge *bridge) { struct mcde_dsi *d = bridge_to_mcde_dsi(bridge); - unsigned long pixel_clock_hz = mode->clock * 1000; unsigned long hs_freq, lp_freq; u32 val; int ret; - if (!d->mdsi) { - dev_err(d->dev, "no DSI device attached to encoder!\n"); - return; - } - - dev_info(d->dev, "set DSI master to %dx%d %lu Hz %s mode\n", - mode->hdisplay, mode->vdisplay, pixel_clock_hz, - (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? "VIDEO" : "CMD" - ); - /* Copy maximum clock frequencies */ if (d->mdsi->lp_rate) lp_freq = d->mdsi->lp_rate; @@ -758,7 +730,21 @@ static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge, d->hs_freq); if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) { - mcde_dsi_setup_video_mode(d, mode); + /* Put IF1 into video mode */ + val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL); + val |= DSI_MCTL_MAIN_DATA_CTL_IF1_MODE; + writel(val, d->regs + DSI_MCTL_MAIN_DATA_CTL); + + /* Disable command mode on IF1 */ + val = readl(d->regs + DSI_CMD_MODE_CTL); + val &= ~DSI_CMD_MODE_CTL_IF1_LP_EN; + writel(val, d->regs + DSI_CMD_MODE_CTL); + + /* Enable some error interrupts */ + val = readl(d->regs + DSI_VID_MODE_STS_CTL); + val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC; + val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA; + writel(val, d->regs + DSI_VID_MODE_STS_CTL); } else { /* Command mode, clear IF1 ID */ val = readl(d->regs + DSI_CMD_MODE_CTL); @@ -772,6 +758,26 @@ static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge, } } +static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adj) +{ + struct mcde_dsi *d = bridge_to_mcde_dsi(bridge); + + if (!d->mdsi) { + dev_err(d->dev, "no DSI device attached to encoder!\n"); + return; + } + + dev_info(d->dev, "set DSI master to %dx%d %u Hz %s mode\n", + mode->hdisplay, mode->vdisplay, mode->clock * 1000, + (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? "VIDEO" : "CMD" + ); + + if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) + mcde_dsi_setup_video_mode(d, mode); +} + static void mcde_dsi_wait_for_command_mode_stop(struct mcde_dsi *d) { u32 val; @@ -863,6 +869,7 @@ static const struct drm_bridge_funcs mcde_dsi_bridge_funcs = { .mode_set = mcde_dsi_bridge_mode_set, .disable = mcde_dsi_bridge_disable, .enable = mcde_dsi_bridge_enable, + .pre_enable = mcde_dsi_bridge_pre_enable, }; static int mcde_dsi_bind(struct device *dev, struct device *master,