From patchwork Tue Dec 7 22:29:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 521624 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp16703imb; Tue, 7 Dec 2021 14:29:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJzd66SsePsAhh/t5UHzPHrJsIpn1u8h5gLaxNU/VfkK+1jjFWbWGgiD6mZuG6xKkn5Yplif X-Received: by 2002:a17:90b:314d:: with SMTP id ip13mr2322660pjb.228.1638916165068; Tue, 07 Dec 2021 14:29:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1638916165; cv=none; d=google.com; s=arc-20160816; b=axEfKbl2N7xllv9fyatLqQUrqgKxaY6l2Vr8J96EoHYMPn/GXPxeOccyhTpha8l3jP /MOwIRcy8ZHMxfZICVYjrObWhjAS9W+u72wF1l0kKm7hCVnv7/Shxfj1aSbP3jLkSGfx SCaFHkiMuFXu3LNSKnfAY7CJtJsf2NOqyUQQIsEzKv7jXD/MMD6LPQtYRZXwqH4lA1xa 3/anxUJMW4KX9qruj1shROM5EB0qHcuFuLa+TOcwjRutOQGLgm88ZzUf5KsTkAYHbYym BfCLyhf4iT4l8oEdRQX/+Vo0ozlIOwSIS3fbGqDtRuUiW/cODf5SW9pDc09vlRbGghsa gjHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to; bh=KQyhi8Tuxu4/knDgfSprik7qylpNwng9tPAXIuAarNU=; b=IjOG4gBieKMmrYpnpjwgMKJm3jXQ70aj5fJSgPxnl7qu6LA9gxkdMBmPcuQ0be/GsJ b2MhUW/5JURuT5cqU5DAkbXsbqiUGFjxy+0flzuv72atRBTPmhcyKz1K+3I02cCGDVQH 3hxuCZQO82v5V+CCNOaTTOUwxT/NdDa313AWbjHy5fMAUYjsk0gHwMCGlzXNJZEFhoTC YK7DrXc9rIm8gxElCGHRfjzat4MArdercclCRgqez3ISOeoGxR0xmYAJ9CrMJ4S5WzwC OORTxvVWPWD6st3mtnMtp9jmgSw3R38cDZfg1ywoq/+/LV6Ha1lPhg+hRQ6hTHRRgVw0 onyA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="k/AvE5IQ"; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id v29si1252416pga.804.2021.12.07.14.29.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Dec 2021 14:29:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="k/AvE5IQ"; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 08A4C6E5AE; Tue, 7 Dec 2021 22:29:16 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lj1-x231.google.com (mail-lj1-x231.google.com [IPv6:2a00:1450:4864:20::231]) by gabe.freedesktop.org (Postfix) with ESMTPS id 898B36E0F6 for ; Tue, 7 Dec 2021 22:29:14 +0000 (UTC) Received: by mail-lj1-x231.google.com with SMTP id u22so783561lju.7 for ; Tue, 07 Dec 2021 14:29:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KQyhi8Tuxu4/knDgfSprik7qylpNwng9tPAXIuAarNU=; b=k/AvE5IQ4Q/PFTfvJMJ0uSLl5kcm6XNcaI9lVQ45leWD0miLV5lZHTzOeEpb+pLhNQ +D0v7qQ8+l8B7LPLkr99/0D7TAgq6FVa6URdy0Oeb3qVg5g5KDlckKPR3JAbRQxKpeCg Kkrb2tytTbO7EmZiQHMGCiReqcoQYWGDKPMtg89Q45EF8gE0j1P11v/LKWuP2tv1Kgr6 PwjVlQtyds1IMXskORj8WGpCRNMb/fivMQ7a84WjJMo7pmFTW1SjALjeL2sIc8RAt+U9 DSq2+XQ5xC/PfBIbnZRKM9AzkaVdNnq2UhdDKgilj+0PjYh73M0SGZXO1w43bnvynu27 K1CA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KQyhi8Tuxu4/knDgfSprik7qylpNwng9tPAXIuAarNU=; b=5Zl7UYzYJEn5oizPsdU3ExHLd5ZaQ12htxZHuhNZcDB0OW/+5R0aGOjr39a82uXJ87 JjIdeiM64+V2LNnCs5kcZA7lyOvEe0LpO3NcPM8WXS5e+JtNYf/58xlRDp6U1PuwdpZK kH2U9oWqa49hEegGCXrrjDkS5jwZ1X0tKyhGi95WiiH4QZck/WmdZP2pCm6g5RFd2qkU g7FHCkk249+l1VE+d3J5tFrA7iYF5GgoJUamPfBlyLtvWfOmlxS0/crcnKuj/PUN/b38 puYY+rmqIvDYcax7mvi84LBxbs+IjOb6GP14jRrUQzfm4+R/ld3bb8YJqwVTai/VPTNe 16Qg== X-Gm-Message-State: AOAM531T7AZX1dd08NNqBEB7RR12FWPLl7aH7bqL5x7bXaZNQsF3OeDZ IKcSIedkatjavp2bzsjqy4RZyw== X-Received: by 2002:a2e:a54d:: with SMTP id e13mr43939891ljn.319.1638916152710; Tue, 07 Dec 2021 14:29:12 -0800 (PST) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id p22sm79423lfe.257.2021.12.07.14.29.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Dec 2021 14:29:12 -0800 (PST) From: Dmitry Baryshkov To: Bjorn Andersson , Rob Clark , Sean Paul , Abhinav Kumar Subject: [PATCH 1/2] drm/msm/dsi: move DSI host powerup to modeset time Date: Wed, 8 Dec 2021 01:29:00 +0300 Message-Id: <20211207222901.988484-2-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211207222901.988484-1-dmitry.baryshkov@linaro.org> References: <20211207222901.988484-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The DSI subsystem does not fully fall into the pre-enable/enable system of callbacks, since typically DSI device bridge drivers expect to be able to communicate with DSI devices at the pre-enable() callback. The reason is that for some DSI hosts enabling the video stream would prevent other drivers from sending DSI commands. For example see the panel-bridge driver, which does drm_panel_prepare() from the pre_enable() callback (which would be called before our pre_enable() callback, resulting in panel preparation failures as the link is not yet ready). Therewere several attempts to solve this issue, but currently the best approach is to power up the DSI link from the mode_set() callback, allowing next bridge/panel to use DSI transfers in the pre_enable() time. Follow this approach. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/dsi_manager.c | 43 +++++++++++++++++++-------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 681ca74fe410..497719efb9e9 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -336,13 +336,12 @@ dsi_mgr_connector_best_encoder(struct drm_connector *connector) return msm_dsi_get_encoder(msm_dsi); } -static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) +static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge) { int id = dsi_mgr_bridge_get_id(bridge); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); struct mipi_dsi_host *host = msm_dsi->host; - struct drm_panel *panel = msm_dsi->panel; struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX]; bool is_bonded_dsi = IS_BONDED_DSI(); int ret; @@ -383,6 +382,34 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (is_bonded_dsi && msm_dsi1) msm_dsi_host_enable_irq(msm_dsi1->host); + return; + +host1_on_fail: + msm_dsi_host_power_off(host); +host_on_fail: + dsi_mgr_phy_disable(id); +phy_en_fail: + return; +} + +static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) +{ + int id = dsi_mgr_bridge_get_id(bridge); + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); + struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); + struct mipi_dsi_host *host = msm_dsi->host; + struct drm_panel *panel = msm_dsi->panel; + bool is_bonded_dsi = IS_BONDED_DSI(); + int ret; + + DBG("id=%d", id); + if (!msm_dsi_device_connected(msm_dsi)) + return; + + /* Do nothing with the host if it is slave-DSI in case of bonded DSI */ + if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) + return; + /* Always call panel functions once, because even for dual panels, * there is only one drm_panel instance. */ @@ -417,17 +444,7 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (panel) drm_panel_unprepare(panel); panel_prep_fail: - msm_dsi_host_disable_irq(host); - if (is_bonded_dsi && msm_dsi1) - msm_dsi_host_disable_irq(msm_dsi1->host); - if (is_bonded_dsi && msm_dsi1) - msm_dsi_host_power_off(msm_dsi1->host); -host1_on_fail: - msm_dsi_host_power_off(host); -host_on_fail: - dsi_mgr_phy_disable(id); -phy_en_fail: return; } @@ -573,6 +590,8 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, msm_dsi_host_set_display_mode(host, adjusted_mode); if (is_bonded_dsi && other_dsi) msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode); + + dsi_mgr_bridge_power_on(bridge); } static const struct drm_connector_funcs dsi_mgr_connector_funcs = { From patchwork Tue Dec 7 22:29:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 521625 Delivered-To: patch@linaro.org Received: by 2002:a05:6e04:2287:0:0:0:0 with SMTP id bl7csp16747imb; Tue, 7 Dec 2021 14:29:27 -0800 (PST) X-Google-Smtp-Source: ABdhPJwXLeAHzjPWSl74Vp46vnZvrGRTwpiatzi3p1YR/aBnWib+NzlRKtAtK2oihB/jELKTlplM X-Received: by 2002:a17:90b:3d3:: with SMTP id go19mr2378174pjb.23.1638916167669; Tue, 07 Dec 2021 14:29:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1638916167; cv=none; d=google.com; s=arc-20160816; b=n1YA8RzVmseOnRlqlqDO1jCLZZxwrGM9XUsnrBD2biYltnSEPhFOUfmyo9YpoYPrZJ IyYw+0IWvvAercpTOSxEbbhnKaJktnpaZY54Jh9nrBDeSJYR/e6Y9I+bAJuKgBufW83d ovegJBpaZ2j/oz3wmg6Ky+qurdDFL4FLGR9W0lDY5rPeA+RKhwBeZefE0SLaEaH7HuWZ w5E4pwY7BbMDa14yaJGcRt2O8s4gmnPiAXQxZK1JzYz0eFUWGsCDvSjPBJQcuwc8TFpp 5c2dVWEny20teQdhkWMjNgaG+mugYpDE8OO/0aGlODuyPEqK9rjPS4fEq414X0ZkE7yq rwVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to; bh=QGI7yjBtbjFxqDbQX5fTzHk3zAVKVZlyuX4+mjpHTmM=; b=SRuY5BylB3fuC/xEJuydrCuxr8kDM4+Mu8pC5T7JOHtXoIkivr77eAVKwJ73rZvsQe maswB49rgSoLPIbW7WVWL7wFmxebnm38p3OSgIl5K8LonyXOGDFo5hUUzigR5uTmb/8Y 45fusAvxijFx7zzF2dXI6ZurolJYsIdWWz0bZu62RkopX0PQgJpK6f07J3whWSvIl++R CVt5+8TDJ2w78KvTj/BKlg5VN8A7yYLMAcp3UDHe0Wm8q39cylKfXIp943ApbxckbLHE ndGEeuRI69UJOFjp3EXR458MM/603qcKD88MfiXwQ2nx9LU70ebNB88x+jeVa1x32JJ5 UpjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=TUz50RGy; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id u63si1102544pgd.225.2021.12.07.14.29.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Dec 2021 14:29:27 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=TUz50RGy; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 336256E82D; Tue, 7 Dec 2021 22:29:20 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lj1-x234.google.com (mail-lj1-x234.google.com [IPv6:2a00:1450:4864:20::234]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4D1166E0FF for ; Tue, 7 Dec 2021 22:29:15 +0000 (UTC) Received: by mail-lj1-x234.google.com with SMTP id 207so756535ljf.10 for ; Tue, 07 Dec 2021 14:29:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QGI7yjBtbjFxqDbQX5fTzHk3zAVKVZlyuX4+mjpHTmM=; b=TUz50RGycRYp1Pu41CnvLHCuse+rMzopujXXA33lN0n14pQAJbzrcX8FmWGkM0J3Fi 1pqiGd+yghH/i48VJtGwmliArkNScmrYOHUrdUXQmzoIFDsPDVhtVCkFu/BT/RG2XD7z EOVtpJCWjbR8CVCTXVX36XUY4kHYshMylZU4729P5N698V2qrvJU+whq05jFCG3/Q2lU 0EpmnKlVPzW2OIlcQw1SB4yoSoNL4xNmOIvVrWTLhT/4xGXQAPs0JENV1/91o0+NC8Gy Ejh7SNF8SY962aSuykIjAsTiaZJML8mq9QC5AMoFjxtLIjJV49Yb8jnCA1heo2SIYwsY mcLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QGI7yjBtbjFxqDbQX5fTzHk3zAVKVZlyuX4+mjpHTmM=; b=1/sqxzrP8E5GzBvRw9meZ7ogN7DspHWnuS0Yzub2fdNrHs3axFthFK7TKN9FonrhH9 BGBEIbZTCOx+RmeuRw+IkMGu+8KEXAQRL0wlcK/VnIzprc8PfON5RMdXTwXogMhTINHy UqoHJOXPrL1DG3EBvd5GMY28WebYwjjp7n0nbplX2iXPGlnL8ZM98N7U3IzmGn+eSrqg RG6HsYOvDP3YpJjNKd4OeEMQZ6dlBMw+pvAsaHu0Pwd+jhe+gIIpHu9RC5iuDtxsL2QF wr9lmuENwppmZhuUDNKEvL7oE67m9nf09oonFqtRR9ApfHCXR9vwmkh1qCEAtfEGavQt mKrg== X-Gm-Message-State: AOAM531ma+mWrRvNX8VYmeigvb+gSRN9HOqIu0iVZa2fyvSDcDVuhTjk LaDfxvdpRNYCO73M9UMLLzJueg== X-Received: by 2002:a05:651c:4ca:: with SMTP id e10mr44240418lji.101.1638916153485; Tue, 07 Dec 2021 14:29:13 -0800 (PST) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id p22sm79423lfe.257.2021.12.07.14.29.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Dec 2021 14:29:13 -0800 (PST) From: Dmitry Baryshkov To: Bjorn Andersson , Rob Clark , Sean Paul , Abhinav Kumar Subject: [PATCH 2/2] drm/msm/dsi: switch to DRM_PANEL_BRIDGE Date: Wed, 8 Dec 2021 01:29:01 +0300 Message-Id: <20211207222901.988484-3-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211207222901.988484-1-dmitry.baryshkov@linaro.org> References: <20211207222901.988484-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Currently the DSI driver has two separate paths: one if the next device in a chain is a bridge and another one if the panel is connected directly to the DSI host. Simplify the code path by using panel-bridge driver (already selected in Kconfig) and dropping support for handling the panel directly. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/dsi.c | 32 +--- drivers/gpu/drm/msm/dsi/dsi.h | 10 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 20 +- drivers/gpu/drm/msm/dsi/dsi_manager.c | 257 +++----------------------- 4 files changed, 32 insertions(+), 287 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 9670e548b3e9..b61f451a282e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -208,7 +208,7 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, struct drm_encoder *encoder) { struct msm_drm_private *priv; - struct drm_bridge *ext_bridge; + struct drm_connector *connector; int ret; if (WARN_ON(!encoder) || WARN_ON(!msm_dsi) || WARN_ON(!dev)) @@ -238,31 +238,17 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, goto fail; } - /* - * check if the dsi encoder output is connected to a panel or an - * external bridge. We create a connector only if we're connected to a - * drm_panel device. When we're connected to an external bridge, we - * assume that the drm_bridge driver will create the connector itself. - */ - ext_bridge = msm_dsi_host_get_bridge(msm_dsi->host); - - if (ext_bridge) - msm_dsi->connector = - msm_dsi_manager_ext_bridge_init(msm_dsi->id); - else - msm_dsi->connector = - msm_dsi_manager_connector_init(msm_dsi->id); - - if (IS_ERR(msm_dsi->connector)) { - ret = PTR_ERR(msm_dsi->connector); + connector = msm_dsi_manager_ext_bridge_init(msm_dsi->id); + + if (IS_ERR(connector)) { + ret = PTR_ERR(connector); DRM_DEV_ERROR(dev->dev, "failed to create dsi connector: %d\n", ret); - msm_dsi->connector = NULL; goto fail; } priv->bridges[priv->num_bridges++] = msm_dsi->bridge; - priv->connectors[priv->num_connectors++] = msm_dsi->connector; + priv->connectors[priv->num_connectors++] = connector; return 0; fail: @@ -272,12 +258,6 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, msm_dsi->bridge = NULL; } - /* don't destroy connector if we didn't make it */ - if (msm_dsi->connector && !msm_dsi->external_bridge) - msm_dsi->connector->funcs->destroy(msm_dsi->connector); - - msm_dsi->connector = NULL; - return ret; } diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index f46df52c6985..7eb778070a8c 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -49,8 +49,6 @@ struct msm_dsi { struct drm_device *dev; struct platform_device *pdev; - /* connector managed by us when we're connected to a drm_panel */ - struct drm_connector *connector; /* internal dsi bridge attached to MDP interface */ struct drm_bridge *bridge; @@ -58,10 +56,8 @@ struct msm_dsi { struct msm_dsi_phy *phy; /* - * panel/external_bridge connected to dsi bridge output, only one of the - * two can be valid at a time + * external_bridge connected to dsi bridge output */ - struct drm_panel *panel; struct drm_bridge *external_bridge; struct device *phy_dev; @@ -76,7 +72,6 @@ struct msm_dsi { /* dsi manager */ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id); void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge); -struct drm_connector *msm_dsi_manager_connector_init(u8 id); struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id); int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg); bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len); @@ -88,7 +83,7 @@ void msm_dsi_manager_tpg_enable(void); /* msm dsi */ static inline bool msm_dsi_device_connected(struct msm_dsi *msm_dsi) { - return msm_dsi->panel || msm_dsi->external_bridge; + return msm_dsi->external_bridge; } struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi); @@ -115,7 +110,6 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, int msm_dsi_host_power_off(struct mipi_dsi_host *host); int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, const struct drm_display_mode *mode); -struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host); unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host); int msm_dsi_host_register(struct mipi_dsi_host *host); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 5b4bb722f750..58bd48d4ec03 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -159,7 +159,6 @@ struct msm_dsi_host { struct drm_display_mode *mode; /* connected device info */ - struct device_node *device_node; unsigned int channel; unsigned int lanes; enum mipi_dsi_pixel_format format; @@ -1604,8 +1603,6 @@ static int dsi_host_detach(struct mipi_dsi_host *host, dsi_dev_detach(msm_host->pdev); - msm_host->device_node = NULL; - DBG("id=%d", msm_host->id); if (msm_host->dev) queue_work(msm_host->workqueue, &msm_host->hpd_work); @@ -1745,16 +1742,6 @@ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) goto err; } - /* Get panel node from the output port's endpoint data */ - device_node = of_graph_get_remote_node(np, 1, 0); - if (!device_node) { - DRM_DEV_DEBUG(dev, "%s: no valid device\n", __func__); - ret = -ENODEV; - goto err; - } - - msm_host->device_node = device_node; - if (of_property_read_bool(np, "syscon-sfpb")) { msm_host->sfpb = syscon_regmap_lookup_by_phandle(np, "syscon-sfpb"); @@ -2405,11 +2392,6 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, return 0; } -struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host) -{ - return of_drm_find_panel(to_msm_dsi_host(host)->device_node); -} - unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host) { return to_msm_dsi_host(host)->mode_flags; @@ -2419,7 +2401,7 @@ struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); - return of_drm_find_bridge(msm_host->device_node); + return devm_drm_of_get_bridge(&msm_host->pdev->dev, msm_host->pdev->dev.of_node, 1, 0); } void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_host *host) diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 497719efb9e9..43b8a1268c4b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -188,39 +188,26 @@ static void dsi_mgr_phy_disable(int id) } } -struct dsi_connector { - struct drm_connector base; - int id; -}; - struct dsi_bridge { struct drm_bridge base; int id; }; -#define to_dsi_connector(x) container_of(x, struct dsi_connector, base) #define to_dsi_bridge(x) container_of(x, struct dsi_bridge, base) -static inline int dsi_mgr_connector_get_id(struct drm_connector *connector) -{ - struct dsi_connector *dsi_connector = to_dsi_connector(connector); - return dsi_connector->id; -} - static int dsi_mgr_bridge_get_id(struct drm_bridge *bridge) { struct dsi_bridge *dsi_bridge = to_dsi_bridge(bridge); return dsi_bridge->id; } -static int msm_dsi_manager_panel_init(struct drm_connector *conn, u8 id) +static void msm_dsi_manager_set_split_display(u8 id) { - struct msm_drm_private *priv = conn->dev->dev_private; - struct msm_kms *kms = priv->kms; struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id); + struct msm_drm_private *priv = msm_dsi->dev->dev_private; + struct msm_kms *kms = priv->kms; struct msm_dsi *master_dsi, *slave_dsi; - struct drm_panel *panel; if (IS_BONDED_DSI() && !IS_MASTER_DSI_LINK(id)) { master_dsi = other_dsi; @@ -230,88 +217,29 @@ static int msm_dsi_manager_panel_init(struct drm_connector *conn, u8 id) slave_dsi = other_dsi; } - /* - * There is only 1 panel in the global panel list for bonded DSI mode. - * Therefore slave dsi should get the drm_panel instance from master - * dsi. - */ - panel = msm_dsi_host_get_panel(master_dsi->host); - if (IS_ERR(panel)) { - DRM_ERROR("Could not find panel for %u (%ld)\n", msm_dsi->id, - PTR_ERR(panel)); - return PTR_ERR(panel); - } - - if (!panel || !IS_BONDED_DSI()) - goto out; - - drm_object_attach_property(&conn->base, - conn->dev->mode_config.tile_property, 0); + if (!msm_dsi->external_bridge || !IS_BONDED_DSI()) + return; /* * Set split display info to kms once bonded DSI panel is connected to * both hosts. */ - if (other_dsi && other_dsi->panel && kms->funcs->set_split_display) { + if (other_dsi && other_dsi->external_bridge && kms->funcs->set_split_display) { kms->funcs->set_split_display(kms, master_dsi->encoder, slave_dsi->encoder, msm_dsi_is_cmd_mode(msm_dsi)); } - -out: - msm_dsi->panel = panel; - return 0; -} - -static enum drm_connector_status dsi_mgr_connector_detect( - struct drm_connector *connector, bool force) -{ - int id = dsi_mgr_connector_get_id(connector); - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); - - return msm_dsi->panel ? connector_status_connected : - connector_status_disconnected; -} - -static void dsi_mgr_connector_destroy(struct drm_connector *connector) -{ - struct dsi_connector *dsi_connector = to_dsi_connector(connector); - - DBG(""); - - drm_connector_cleanup(connector); - - kfree(dsi_connector); -} - -static int dsi_mgr_connector_get_modes(struct drm_connector *connector) -{ - int id = dsi_mgr_connector_get_id(connector); - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); - struct drm_panel *panel = msm_dsi->panel; - int num; - - if (!panel) - return 0; - - /* - * In bonded DSI mode, we have one connector that can be - * attached to the drm_panel. - */ - num = drm_panel_get_modes(panel, connector); - if (!num) - return 0; - - return num; } -static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, + const struct drm_display_mode *mode) { - int id = dsi_mgr_connector_get_id(connector); + int id = dsi_mgr_bridge_get_id(bridge); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi); - struct msm_drm_private *priv = connector->dev->dev_private; + struct drm_device *dev = msm_dsi->dev; + struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; long actual, requested; @@ -326,16 +254,6 @@ static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *c return MODE_OK; } -static struct drm_encoder * -dsi_mgr_connector_best_encoder(struct drm_connector *connector) -{ - int id = dsi_mgr_connector_get_id(connector); - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); - - DBG(""); - return msm_dsi_get_encoder(msm_dsi); -} - static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge) { int id = dsi_mgr_bridge_get_id(bridge); @@ -398,7 +316,6 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); struct mipi_dsi_host *host = msm_dsi->host; - struct drm_panel *panel = msm_dsi->panel; bool is_bonded_dsi = IS_BONDED_DSI(); int ret; @@ -410,18 +327,6 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) return; - /* Always call panel functions once, because even for dual panels, - * there is only one drm_panel instance. - */ - if (panel) { - ret = drm_panel_prepare(panel); - if (ret) { - pr_err("%s: prepare panel %d failed, %d\n", __func__, - id, ret); - goto panel_prep_fail; - } - } - ret = msm_dsi_host_enable(host); if (ret) { pr_err("%s: enable host %d failed, %d\n", __func__, id, ret); @@ -441,9 +346,6 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) host1_en_fail: msm_dsi_host_disable(host); host_en_fail: - if (panel) - drm_panel_unprepare(panel); -panel_prep_fail: return; } @@ -461,62 +363,12 @@ void msm_dsi_manager_tpg_enable(void) } } -static void dsi_mgr_bridge_enable(struct drm_bridge *bridge) -{ - int id = dsi_mgr_bridge_get_id(bridge); - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); - struct drm_panel *panel = msm_dsi->panel; - bool is_bonded_dsi = IS_BONDED_DSI(); - int ret; - - DBG("id=%d", id); - if (!msm_dsi_device_connected(msm_dsi)) - return; - - /* Do nothing with the host if it is slave-DSI in case of bonded DSI */ - if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) - return; - - if (panel) { - ret = drm_panel_enable(panel); - if (ret) { - pr_err("%s: enable panel %d failed, %d\n", __func__, id, - ret); - } - } -} - -static void dsi_mgr_bridge_disable(struct drm_bridge *bridge) -{ - int id = dsi_mgr_bridge_get_id(bridge); - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); - struct drm_panel *panel = msm_dsi->panel; - bool is_bonded_dsi = IS_BONDED_DSI(); - int ret; - - DBG("id=%d", id); - if (!msm_dsi_device_connected(msm_dsi)) - return; - - /* Do nothing with the host if it is slave-DSI in case of bonded DSI */ - if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) - return; - - if (panel) { - ret = drm_panel_disable(panel); - if (ret) - pr_err("%s: Panel %d OFF failed, %d\n", __func__, id, - ret); - } -} - static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) { int id = dsi_mgr_bridge_get_id(bridge); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); struct mipi_dsi_host *host = msm_dsi->host; - struct drm_panel *panel = msm_dsi->panel; bool is_bonded_dsi = IS_BONDED_DSI(); int ret; @@ -543,13 +395,6 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) pr_err("%s: host1 disable failed, %d\n", __func__, ret); } - if (panel) { - ret = drm_panel_unprepare(panel); - if (ret) - pr_err("%s: Panel %d unprepare failed,%d\n", __func__, - id, ret); - } - msm_dsi_host_disable_irq(host); if (is_bonded_dsi && msm_dsi1) msm_dsi_host_disable_irq(msm_dsi1->host); @@ -594,76 +439,13 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, dsi_mgr_bridge_power_on(bridge); } -static const struct drm_connector_funcs dsi_mgr_connector_funcs = { - .detect = dsi_mgr_connector_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = dsi_mgr_connector_destroy, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static const struct drm_connector_helper_funcs dsi_mgr_conn_helper_funcs = { - .get_modes = dsi_mgr_connector_get_modes, - .mode_valid = dsi_mgr_connector_mode_valid, - .best_encoder = dsi_mgr_connector_best_encoder, -}; - static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = { .pre_enable = dsi_mgr_bridge_pre_enable, - .enable = dsi_mgr_bridge_enable, - .disable = dsi_mgr_bridge_disable, .post_disable = dsi_mgr_bridge_post_disable, .mode_set = dsi_mgr_bridge_mode_set, + .mode_valid = dsi_mgr_bridge_mode_valid, }; -/* initialize connector when we're connected to a drm_panel */ -struct drm_connector *msm_dsi_manager_connector_init(u8 id) -{ - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); - struct drm_connector *connector = NULL; - struct dsi_connector *dsi_connector; - int ret; - - dsi_connector = kzalloc(sizeof(*dsi_connector), GFP_KERNEL); - if (!dsi_connector) - return ERR_PTR(-ENOMEM); - - dsi_connector->id = id; - - connector = &dsi_connector->base; - - ret = drm_connector_init(msm_dsi->dev, connector, - &dsi_mgr_connector_funcs, DRM_MODE_CONNECTOR_DSI); - if (ret) - return ERR_PTR(ret); - - drm_connector_helper_add(connector, &dsi_mgr_conn_helper_funcs); - - /* Enable HPD to let hpd event is handled - * when panel is attached to the host. - */ - connector->polled = DRM_CONNECTOR_POLL_HPD; - - /* Display driver doesn't support interlace now. */ - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - drm_connector_attach_encoder(connector, msm_dsi->encoder); - - ret = msm_dsi_manager_panel_init(connector, id); - if (ret) { - DRM_DEV_ERROR(msm_dsi->dev->dev, "init panel failed %d\n", ret); - goto fail; - } - - return connector; - -fail: - connector->funcs->destroy(msm_dsi->connector); - return ERR_PTR(ret); -} - bool msm_dsi_manager_validate_current_config(u8 id) { bool is_bonded_dsi = IS_BONDED_DSI(); @@ -727,8 +509,11 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id) int ret; int_bridge = msm_dsi->bridge; - ext_bridge = msm_dsi->external_bridge = - msm_dsi_host_get_bridge(msm_dsi->host); + ext_bridge = msm_dsi_host_get_bridge(msm_dsi->host); + if (IS_ERR(ext_bridge)) + return ERR_PTR(PTR_ERR(ext_bridge)); + + msm_dsi->external_bridge = ext_bridge; encoder = msm_dsi->encoder; @@ -755,7 +540,7 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id) list_for_each_entry(connector, connector_list, head) { if (drm_connector_has_possible_encoder(connector, encoder)) - return connector; + goto out; } return ERR_PTR(-ENODEV); @@ -769,6 +554,10 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id) drm_connector_attach_encoder(connector, encoder); +out: + /* The pipeline is ready, ping encoders if necessary */ + msm_dsi_manager_set_split_display(id); + return connector; }