From patchwork Fri Mar 13 19:49:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephane Viau X-Patchwork-Id: 6009011 Return-Path: X-Original-To: patchwork-linux-arm-msm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id AD4BE9F318 for ; Fri, 13 Mar 2015 19:50:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A7CA320225 for ; Fri, 13 Mar 2015 19:50:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4F83C20256 for ; Fri, 13 Mar 2015 19:50:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751168AbbCMTuG (ORCPT ); Fri, 13 Mar 2015 15:50:06 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:60187 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756878AbbCMTtt (ORCPT ); Fri, 13 Mar 2015 15:49:49 -0400 Received: from smtp.codeaurora.org (localhost [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id 7C204142617; Fri, 13 Mar 2015 19:49:48 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 486) id 62D06142644; Fri, 13 Mar 2015 19:49:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from yyzubuntu31.qualcomm.com (rrcs-67-52-130-30.west.biz.rr.com [67.52.130.30]) (using TLSv1.1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: sviau@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 0F5FF142641; Fri, 13 Mar 2015 19:49:46 +0000 (UTC) From: Stephane Viau To: dri-devel@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, robdclark@gmail.com, Stephane Viau Subject: [PATCH v3 4/4] drm/msm/mdp5: Make the intf connection in config module Date: Fri, 13 Mar 2015 15:49:34 -0400 Message-Id: <1426276174-17010-5-git-send-email-sviau@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1426276174-17010-1-git-send-email-sviau@codeaurora.org> References: <1426276174-17010-1-git-send-email-sviau@codeaurora.org> X-Virus-Scanned: ClamAV using ClamSMTP 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 Up until now, we assume that eDP is tight to intf_0 and HDMI to intf_3. This information shall actually come from the mdp5_cfg module since it can change from one chip to another. v2: rename macro to mdp5_cfg_intf_is_virtual() [pointed by Archit] v3: add sanity check before writing in INTF_TIMING_ENGINE_EN registers Signed-off-by: Stephane Viau --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 8 +++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h | 4 ++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 112 ++++++++++++++++++-------------- 3 files changed, 75 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c index 72c075a..8bee023 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c @@ -62,6 +62,10 @@ const struct mdp5_cfg_hw msm8x74_config = { .count = 4, .base = { 0x12500, 0x12700, 0x12900, 0x12b00 }, }, + .intfs = { + [0] = INTF_eDP, + [3] = INTF_HDMI, + }, .max_clk = 200000000, }; @@ -111,6 +115,10 @@ const struct mdp5_cfg_hw apq8084_config = { .count = 5, .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 }, }, + .intfs = { + [0] = INTF_eDP, + [3] = INTF_HDMI, + }, .max_clk = 320000000, }; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h index 69e35ac..12224d7 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h @@ -56,6 +56,8 @@ struct mdp5_smp_block { int reserved[MAX_CLIENTS]; /* # of MMBs allocated per client */ }; +#define MDP5_INTF_NUM_MAX 5 + struct mdp5_cfg_hw { char *name; @@ -69,6 +71,8 @@ struct mdp5_cfg_hw { struct mdp5_sub_block ad; struct mdp5_sub_block intf; + u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */ + uint32_t max_clk; }; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 390d9d2..7e03af5 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -161,6 +161,44 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms) return 0; } +static int construct_encoder(struct mdp5_kms *mdp5_kms, + enum mdp5_intf_type intf_type, int intf_num) +{ + struct drm_device *dev = mdp5_kms->dev; + struct msm_drm_private *priv = dev->dev_private; + struct drm_encoder *encoder; + struct mdp5_interface intf = { + .num = intf_num, + .type = intf_type, + .mode = MDP5_INTF_MODE_NONE, + }; + int ret = 0; + + encoder = mdp5_encoder_init(dev, &intf); + if (IS_ERR(encoder)) { + ret = PTR_ERR(encoder); + dev_err(dev->dev, "failed to construct encoder: %d\n", ret); + return ret; + } + + encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; + priv->encoders[priv->num_encoders++] = encoder; + + if (intf_type == INTF_HDMI) { + ret = hdmi_modeset_init(priv->hdmi, dev, encoder); + if (ret) + dev_err(dev->dev, "failed to init HDMI: %d\n", ret); + + } else if (intf_type == INTF_eDP) { + /* Construct bridge/connector for eDP: */ + ret = msm_edp_modeset_init(priv->edp, dev, encoder); + if (ret) + dev_err(dev->dev, "failed to init eDP: %d\n", ret); + } + + return ret; +} + static int modeset_init(struct mdp5_kms *mdp5_kms) { static const enum mdp5_pipe crtcs[] = { @@ -171,7 +209,6 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) }; struct drm_device *dev = mdp5_kms->dev; struct msm_drm_private *priv = dev->dev_private; - struct drm_encoder *encoder; const struct mdp5_cfg_hw *hw_cfg; int i, ret; @@ -222,56 +259,29 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) } } - if (priv->hdmi) { - struct mdp5_interface intf = { - .num = 3, - .type = INTF_HDMI, - .mode = MDP5_INTF_MODE_NONE, - }; - - /* Construct encoder for HDMI: */ - encoder = mdp5_encoder_init(dev, &intf); - if (IS_ERR(encoder)) { - dev_err(dev->dev, "failed to construct encoder\n"); - ret = PTR_ERR(encoder); - goto fail; - } - - encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;; - priv->encoders[priv->num_encoders++] = encoder; - - ret = hdmi_modeset_init(priv->hdmi, dev, encoder); - if (ret) { - dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); - goto fail; - } - } - - if (priv->edp) { - struct mdp5_interface intf = { - .num = 0, - .type = INTF_eDP, - .mode = MDP5_INTF_MODE_NONE, - }; - - /* Construct encoder for eDP: */ - encoder = mdp5_encoder_init(dev, &intf); - if (IS_ERR(encoder)) { - dev_err(dev->dev, "failed to construct eDP encoder\n"); - ret = PTR_ERR(encoder); - goto fail; + /* Construct external display interfaces' encoders: */ + for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) { + enum mdp5_intf_type intf_type = hw_cfg->intfs[i]; + + switch (intf_type) { + case INTF_DISABLED: + break; + case INTF_eDP: + if (priv->edp) + ret = construct_encoder(mdp5_kms, INTF_eDP, i); + break; + case INTF_HDMI: + if (priv->hdmi) + ret = construct_encoder(mdp5_kms, INTF_HDMI, i); + break; + default: + dev_err(dev->dev, "unknown intf: %d\n", intf_type); + ret = -EINVAL; + break; } - encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; - priv->encoders[priv->num_encoders++] = encoder; - - /* Construct bridge/connector for eDP: */ - ret = msm_edp_modeset_init(priv->edp, dev, encoder); - if (ret) { - dev_err(dev->dev, "failed to initialize eDP: %d\n", - ret); + if (ret) goto fail; - } } return 0; @@ -415,8 +425,12 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) * we don't disable): */ mdp5_enable(mdp5_kms); - for (i = 0; i < config->hw->intf.count; i++) + for (i = 0; i < MDP5_INTF_NUM_MAX; i++) { + if (!config->hw->intf.base[i] || + mdp5_cfg_intf_is_virtual(config->hw->intfs[i])) + continue; mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0); + } mdp5_disable(mdp5_kms); mdelay(16);