From patchwork Tue Jan 17 04:06:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archit Taneja X-Patchwork-Id: 9519883 X-Patchwork-Delegate: agross@codeaurora.org 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 D28EB60442 for ; Tue, 17 Jan 2017 04:06:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C4F6F28179 for ; Tue, 17 Jan 2017 04:06:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9A7E28452; Tue, 17 Jan 2017 04:06:54 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1C4B6281D2 for ; Tue, 17 Jan 2017 04:06:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750987AbdAQEGx (ORCPT ); Mon, 16 Jan 2017 23:06:53 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:55450 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750922AbdAQEGw (ORCPT ); Mon, 16 Jan 2017 23:06:52 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 50900607C2; Tue, 17 Jan 2017 04:06:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1484626012; bh=2Zylm9jItv2b+6HYfJow7VV0e7SG0KgByiqiGZe3rQk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F4V+x7ZCzbw6yRnBrBy9ZhlMOoIkD9+yGSqdCpnVNNaKq38Hzh7d8jQz8VohrojXY njRFtnPlsZJX1wTKjPcqjl5Fp7odbfHg4jRL9iZXoREvvx0FEPCf1Na77UQdQojLJh 6c4E4qQ5+FNiijaEJ5jT07SzkBRcoNl2LjjDkBKM= Received: from localhost (unknown [202.46.23.61]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: architt@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 17EB3607CD; Tue, 17 Jan 2017 04:06:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1484626011; bh=2Zylm9jItv2b+6HYfJow7VV0e7SG0KgByiqiGZe3rQk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NB6J9jD7g3E0xJybvaqOA25DiVWk0IhxLqojuuPMeqm+0fX3vqz6UxTy1p2LmeiOA k/F3dKIze+Ydlzmr8ZmyyQ1hIF24PYuwy+eP506o9yUZGmCJ9sLbcvWhe8nFnf4n6n SA/ZMi2JSl7+MQx9jFiGE44Wa4vYKj6HN9nHhl1Q= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 17EB3607CD Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=architt@codeaurora.org From: Archit Taneja To: robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, Archit Taneja Subject: [PATCH v2 2/6] drm/msm: Set encoder's mode of operation using a kms func Date: Tue, 17 Jan 2017 09:36:26 +0530 Message-Id: <20170117040630.5299-3-architt@codeaurora.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170117040630.5299-1-architt@codeaurora.org> References: <1482141850-23393-1-git-send-email-architt@codeaurora.org> <20170117040630.5299-1-architt@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The mdp5 kms driver currently sets up multiple encoders per interface (INTF), one for each kind of mode of operation it supports. We create 2 drm_encoders for DSI, one for Video Mode and the other for Command Mode operation. The reason behind this approach could have been that we aren't aware of the DSI device's mode of operation when we create the encoders. This makes things a bit complicated, since these encoders have to be further attached to the same DSI bridge. The easier way out is to create a single encoder, and make the DSI driver set its mode of operation when we know what the DSI device's mode flags are. Start with providing a way to set the mdp5_intf_mode using a kms func that sets the encoder's mode of operation. When constructing a DSI encoder, we set the mode of operation to Video Mode as default. When the DSI device is attached to the host, we probe the DSI mode flags and set the corresponding mode of operation. Signed-off-by: Archit Taneja --- drivers/gpu/drm/msm/dsi/dsi.h | 1 + drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 39 ++++++++++++++++++++++++++--- drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 17 +++++++++++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 8 ++++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 1 + drivers/gpu/drm/msm/msm_kms.h | 3 +++ 7 files changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index ddcda8cec9a7..81971b3caf3b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -90,6 +90,7 @@ int msm_dsi_manager_phy_enable(int id, void msm_dsi_manager_phy_disable(int 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); +void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags); int msm_dsi_manager_register(struct msm_dsi *msm_dsi); void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 3819fdefcae2..eb0903d37e5c 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1482,6 +1482,8 @@ static int dsi_host_attach(struct mipi_dsi_host *host, msm_host->format = dsi->format; msm_host->mode_flags = dsi->mode_flags; + msm_dsi_manager_attach_dsi_device(msm_host->id, dsi->mode_flags); + /* Some gpios defined in panel DT need to be controlled by host */ ret = dsi_host_init_panel_gpios(msm_host, &dsi->dev); if (ret) diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 19da23d8a0b1..643a6df9a32c 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -155,8 +155,16 @@ static enum drm_connector_status dsi_mgr_connector_detect( DBG("id=%d", id); if (!msm_dsi->panel) { + struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi); + bool cmd_mode; + msm_dsi->panel = msm_dsi_host_get_panel(msm_dsi->host, - &msm_dsi->device_flags); + &msm_dsi->device_flags); + + cmd_mode = !(msm_dsi->device_flags & MIPI_DSI_MODE_VIDEO); + + if (kms->funcs->set_encoder_mode) + kms->funcs->set_encoder_mode(kms, encoder, cmd_mode); /* There is only 1 panel in the global panel list * for dual DSI mode. Therefore slave dsi should get @@ -177,8 +185,6 @@ static enum drm_connector_status dsi_mgr_connector_detect( */ if (msm_dsi->panel && IS_DUAL_DSI() && other_dsi && other_dsi->panel) { - bool cmd_mode = !(msm_dsi->device_flags & - MIPI_DSI_MODE_VIDEO); struct drm_encoder *encoder = msm_dsi_get_encoder( dsi_mgr_get_dsi(DSI_ENCODER_MASTER)); struct drm_encoder *slave_enc = msm_dsi_get_encoder( @@ -773,6 +779,33 @@ bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len) return true; } +void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags) +{ + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); + struct drm_device *dev = msm_dsi->dev; + struct msm_drm_private *priv; + struct msm_kms *kms; + struct drm_encoder *encoder; + + /* + * drm_device pointer is assigned to msm_dsi only in the modeset_init + * path. If mipi_dsi_attach() happens in DSI driver's probe path + * (generally the case when we're connected to a drm_panel of the type + * mipi_dsi_device), this would be NULL. Try to set encoder mode in + * the DSI connector's detect() op. + */ + if (!dev) + return; + + priv = dev->dev_private; + kms = priv->kms; + encoder = msm_dsi_get_encoder(msm_dsi); + + if (encoder && kms->funcs->set_encoder_mode) + if (!(device_flags & MIPI_DSI_MODE_VIDEO)) + kms->funcs->set_encoder_mode(kms, encoder, true); +} + int msm_dsi_manager_register(struct msm_dsi *msm_dsi) { struct msm_dsi_manager *msm_dsim = &msm_dsim_glb; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c index fe0c22230883..1e7c99125fdd 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c @@ -342,6 +342,23 @@ int mdp5_encoder_set_split_display(struct drm_encoder *encoder, return 0; } +void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode) +{ + struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); + struct mdp5_interface *intf = &mdp5_encoder->intf; + + /* TODO: Expand this to set writeback modes too */ + if (cmd_mode) { + WARN_ON(intf->type != INTF_DSI); + intf->mode = MDP5_INTF_DSI_MODE_COMMAND; + } else { + if (intf->type == INTF_DSI) + intf->mode = MDP5_INTF_DSI_MODE_VIDEO; + else + intf->mode = MDP5_INTF_MODE_NONE; + } +} + /* initialize encoder */ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, struct mdp5_interface *intf, struct mdp5_ctl *ctl) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 5bad72c9e253..f73d46756912 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -151,6 +151,13 @@ static int mdp5_set_split_display(struct msm_kms *kms, return mdp5_encoder_set_split_display(encoder, slave_encoder); } +static void mdp5_set_encoder_mode(struct msm_kms *kms, + struct drm_encoder *encoder, + bool cmd_mode) +{ + mdp5_encoder_set_intf_mode(encoder, cmd_mode); +} + static void mdp5_kms_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); @@ -230,6 +237,7 @@ static const struct mdp_kms_funcs kms_funcs = { .get_format = mdp_get_format, .round_pixclk = mdp5_round_pixclk, .set_split_display = mdp5_set_split_display, + .set_encoder_mode = mdp5_set_encoder_mode, .destroy = mdp5_kms_destroy, #ifdef CONFIG_DEBUG_FS .debugfs_init = mdp5_kms_debugfs_init, diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index cdfc63d90c7b..3e0baed0a8a7 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -246,6 +246,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, struct mdp5_interface *intf, struct mdp5_ctl *ctl); int mdp5_encoder_set_split_display(struct drm_encoder *encoder, struct drm_encoder *slave_encoder); +void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode); int mdp5_encoder_get_linecount(struct drm_encoder *encoder); u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index e470f4cf8f76..117635d2b8c5 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -56,6 +56,9 @@ struct msm_kms_funcs { struct drm_encoder *encoder, struct drm_encoder *slave_encoder, bool is_cmd_mode); + void (*set_encoder_mode)(struct msm_kms *kms, + struct drm_encoder *encoder, + bool cmd_mode); /* cleanup: */ void (*destroy)(struct msm_kms *kms); #ifdef CONFIG_DEBUG_FS