From patchwork Fri Jul 28 10:47:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archit Taneja X-Patchwork-Id: 9868455 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 D99196035E for ; Fri, 28 Jul 2017 10:48:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D7333288A0 for ; Fri, 28 Jul 2017 10:48:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CC0A1288B7; Fri, 28 Jul 2017 10:48:03 +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 14B0C288A0 for ; Fri, 28 Jul 2017 10:48:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751751AbdG1KsC (ORCPT ); Fri, 28 Jul 2017 06:48:02 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:47348 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751744AbdG1KsB (ORCPT ); Fri, 28 Jul 2017 06:48:01 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 3ADAF609C6; Fri, 28 Jul 2017 10:48:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1501238881; bh=Q76Rxj54DygkyI/SQFZhp2qOzp7yAr+qkyW2WgM+FLQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KohhTppTr7GVYdDhvf2eIVwa21KVjO4svhE9giYhND1tWev9Bg/M/pOlsbJRo/TkX Srg3t1yK5dV1bbFXS16l2BCrTwzYDOBRLFPiFFLzIvhwyxRvYcTgf/3sL64dqXNnNp X5vnLxPMclqQyx0K/RNq0w4VX4srdh9fH5MQ40BQ= Received: from localhost (blr-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.18.19]) (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 2FE3F60A18; Fri, 28 Jul 2017 10:47:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1501238879; bh=Q76Rxj54DygkyI/SQFZhp2qOzp7yAr+qkyW2WgM+FLQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H7RatH3FKSLhIx4FNHp48Z4h0+k68uWmsslTN1yy8udA1Xu/FwLpBk5JRj7mquU0M qUj6AI3OeZrB01aujBIEacF2yuWJtwqV6CnFqRL3VvCXX/GZVKwzxeRidFA/oMGNR+ 79z/rMnOI93vDu+ntnP2XRzzy2zoKbG/9TRmTKA4= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 2FE3F60A18 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: dri-devel@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, Archit Taneja Subject: [PATCH 09/10] drm/msm/mdp5: Set up runtime PM for MDSS Date: Fri, 28 Jul 2017 16:17:07 +0530 Message-Id: <20170728104708.20635-10-architt@codeaurora.org> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170728104708.20635-1-architt@codeaurora.org> References: <20170728104708.20635-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 MDSS represents the top level wrapper that contains MDP5, DSI, HDMI and other sub-blocks. W.r.t device heirarchy, it's the parent of all these devices. The power domain of this device is actually tied to the GDSC hw. When any sub-device enables its PD, MDSS's PD is also enabled. The suspend/resume ops enable the top level clocks that end at the MDSS boundary. For now, we're letting them all be optional, since the child devices anyway hold a ref to these clocks. Until now, we'd called a runtime_get() during probe, which ensured that the GDSC was always on. Now that we've set up runtime PM for the children devices, we can get rid of this hack. Note: that the MDSS device is the platform_device in msm_drv.c. The msm_runtime_suspend/resume ops call the funcs that enable/disable the top level MDSS clocks. This is different from MDP4, where the platform device created in msm_drv.c represents MDP4 itself. It would have been nicer to hide these differences by adding new kms funcs, but runtime PM needs to be enabled before kms is set up (i.e, msm_kms_init is called). Signed-off-by: Archit Taneja --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c | 63 ++++++++++++++++++++++++++++---- drivers/gpu/drm/msm/msm_drv.c | 29 +++++++++++++++ drivers/gpu/drm/msm/msm_kms.h | 2 + 3 files changed, 86 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c index 9c34d7824988..f2a0db7a8a03 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c @@ -31,6 +31,10 @@ struct msm_mdss { struct regulator *vdd; + struct clk *ahb_clk; + struct clk *axi_clk; + struct clk *vsync_clk; + struct { volatile unsigned long enabled_mask; struct irq_domain *domain; @@ -140,6 +144,51 @@ static int mdss_irq_domain_init(struct msm_mdss *mdss) return 0; } +int msm_mdss_enable(struct msm_mdss *mdss) +{ + DBG(""); + + clk_prepare_enable(mdss->ahb_clk); + if (mdss->axi_clk) + clk_prepare_enable(mdss->axi_clk); + if (mdss->vsync_clk) + clk_prepare_enable(mdss->vsync_clk); + + return 0; +} + +int msm_mdss_disable(struct msm_mdss *mdss) +{ + DBG(""); + + if (mdss->vsync_clk) + clk_disable_unprepare(mdss->vsync_clk); + if (mdss->axi_clk) + clk_disable_unprepare(mdss->axi_clk); + clk_disable_unprepare(mdss->ahb_clk); + + return 0; +} + +static int msm_mdss_get_clocks(struct msm_mdss *mdss) +{ + struct platform_device *pdev = to_platform_device(mdss->dev->dev); + + mdss->ahb_clk = msm_clk_get(pdev, "iface"); + if (IS_ERR(mdss->ahb_clk)) + mdss->ahb_clk = NULL; + + mdss->axi_clk = msm_clk_get(pdev, "bus"); + if (IS_ERR(mdss->axi_clk)) + mdss->axi_clk = NULL; + + mdss->vsync_clk = msm_clk_get(pdev, "vsync"); + if (IS_ERR(mdss->vsync_clk)) + mdss->vsync_clk = NULL; + + return 0; +} + void msm_mdss_destroy(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -153,8 +202,6 @@ void msm_mdss_destroy(struct drm_device *dev) regulator_disable(mdss->vdd); - pm_runtime_put_sync(dev->dev); - pm_runtime_disable(dev->dev); } @@ -190,6 +237,12 @@ int msm_mdss_init(struct drm_device *dev) goto fail; } + ret = msm_mdss_get_clocks(mdss); + if (ret) { + dev_err(dev->dev, "failed to get clocks: %d\n", ret); + goto fail; + } + /* Regulator to enable GDSCs in downstream kernels */ mdss->vdd = devm_regulator_get(dev->dev, "vdd"); if (IS_ERR(mdss->vdd)) { @@ -221,12 +274,6 @@ int msm_mdss_init(struct drm_device *dev) pm_runtime_enable(dev->dev); - /* - * TODO: This is needed as the MDSS GDSC is only tied to MDSS's power - * domain. Remove this once runtime PM is adapted for all the devices. - */ - pm_runtime_get_sync(dev->dev); - return 0; fail_irq: regulator_disable(mdss->vdd); diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index f49f6ac5585c..a19c393f7e45 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -879,8 +879,37 @@ static int msm_pm_resume(struct device *dev) } #endif +#ifdef CONFIG_PM +static int msm_runtime_suspend(struct device *dev) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct msm_drm_private *priv = ddev->dev_private; + + DBG(""); + + if (priv->mdss) + return msm_mdss_disable(priv->mdss); + + return 0; +} + +static int msm_runtime_resume(struct device *dev) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct msm_drm_private *priv = ddev->dev_private; + + DBG(""); + + if (priv->mdss) + return msm_mdss_enable(priv->mdss); + + return 0; +} +#endif + static const struct dev_pm_ops msm_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(msm_pm_suspend, msm_pm_resume) + SET_RUNTIME_PM_OPS(msm_runtime_suspend, msm_runtime_resume, NULL) }; /* diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index a8f2ba5e5f07..17d5824417ad 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -99,5 +99,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev); struct msm_kms *mdp5_kms_init(struct drm_device *dev); int msm_mdss_init(struct drm_device *dev); void msm_mdss_destroy(struct drm_device *dev); +int msm_mdss_enable(struct msm_mdss *mdss); +int msm_mdss_disable(struct msm_mdss *mdss); #endif /* __MSM_KMS_H__ */