From patchwork Tue Sep 15 12:41:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephane Viau X-Patchwork-Id: 7184351 Return-Path: X-Original-To: patchwork-linux-arm-msm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2C273BEEC1 for ; Tue, 15 Sep 2015 12:45:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 894722069D for ; Tue, 15 Sep 2015 12:45:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8033820688 for ; Tue, 15 Sep 2015 12:45:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752629AbbIOMnl (ORCPT ); Tue, 15 Sep 2015 08:43:41 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:48978 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752592AbbIOMnk (ORCPT ); Tue, 15 Sep 2015 08:43:40 -0400 Received: from smtp.codeaurora.org (localhost [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id 8912E14013A; Tue, 15 Sep 2015 12:43:39 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 486) id 79C08140140; Tue, 15 Sep 2015 12:43:39 +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 286CA14013B; Tue, 15 Sep 2015 12:43:38 +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 05/10] drm/msm/mdp5: Vote for SMMU power when performing translations Date: Tue, 15 Sep 2015 08:41:48 -0400 Message-Id: <1442320913-3248-6-git-send-email-sviau@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1442320913-3248-1-git-send-email-sviau@codeaurora.org> References: <1442320913-3248-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 On most recent chipsets, clients need to vote for SMMU power (regulator and clock) themselves for as long as they want the SMMU to be on, performing translations. This change enables (disables) the SMMU power just before attaching (after detaching) MDP5 device to the SMMU. Signed-off-by: Stephane Viau --- Documentation/devicetree/bindings/drm/msm/mdp.txt | 3 ++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 65 +++++++++++++++++++++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 3 ++ 3 files changed, 71 insertions(+) diff --git a/Documentation/devicetree/bindings/drm/msm/mdp.txt b/Documentation/devicetree/bindings/drm/msm/mdp.txt index 0833eda..99ba764 100644 --- a/Documentation/devicetree/bindings/drm/msm/mdp.txt +++ b/Documentation/devicetree/bindings/drm/msm/mdp.txt @@ -19,6 +19,9 @@ Optional properties: - gpus: phandle for gpu device - clock-names: the following clocks are optional: * "lut_clk" + * "iommu_clk" + * "mmagic_clk" +- mmagic-supply: phandle for mmagic GDSC regulator used during IOMMU translation Example: diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 61fcb41..983bd53 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -129,6 +129,54 @@ static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file) mdp5_crtc_cancel_pending_flip(priv->crtcs[i], file); } +static int mdp5_translation_ctrl_pwr(struct mdp5_kms *mdp5_kms, bool on) +{ + struct device *dev = mdp5_kms->dev->dev; + int ret; + + if (on) { + if (mdp5_kms->mmagic) { + ret = regulator_enable(mdp5_kms->mmagic); + if (ret) { + dev_err(dev, "failed to enable mmagic GDSC: %d\n", ret); + return ret; + } + } + if (mdp5_kms->mmagic_clk) { + clk_prepare_enable(mdp5_kms->mmagic_clk); + if (ret) { + dev_err(dev, "failed to enable mmagic_clk\n"); + goto undo_gdsc; + } + } + if (mdp5_kms->iommu_clk) { + ret = clk_prepare_enable(mdp5_kms->iommu_clk); + if (ret) { + dev_err(dev, "failed to enable iommu_clk\n"); + goto undo_mmagic_clk; + } + } + } else { + if (mdp5_kms->iommu_clk) + clk_disable_unprepare(mdp5_kms->iommu_clk); + if (mdp5_kms->mmagic_clk) + clk_disable_unprepare(mdp5_kms->mmagic_clk); + if (mdp5_kms->mmagic) + regulator_disable(mdp5_kms->mmagic); + } + + return 0; + +undo_mmagic_clk: + if (mdp5_kms->mmagic_clk) + clk_disable_unprepare(mdp5_kms->mmagic_clk); +undo_gdsc: + if (mdp5_kms->mmagic) + regulator_disable(mdp5_kms->mmagic); + + return ret; +} + static void mdp5_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); @@ -138,6 +186,7 @@ static void mdp5_destroy(struct msm_kms *kms) if (mmu) { mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); + mdp5_translation_ctrl_pwr(mdp5_kms, false); mmu->funcs->destroy(mmu); } @@ -520,6 +569,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) goto fail; } + mdp5_kms->mmagic = devm_regulator_get_optional(&pdev->dev, "mmagic"); + if (IS_ERR(mdp5_kms->mmagic)) { + ret = PTR_ERR(mdp5_kms->mmagic); + DBG("failed to get mmagic GDSC regulator: %d\n", ret); + mdp5_kms->mmagic = NULL; + } + /* mandatory clocks: */ ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk", true); if (ret) @@ -539,6 +595,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) /* optional clocks: */ get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk", false); + get_clk(pdev, &mdp5_kms->mmagic_clk, "mmagic_clk", false); + get_clk(pdev, &mdp5_kms->iommu_clk, "iommu_clk", false); /* we need to set a default rate before enabling. Set a safe * rate first, then figure out hw revision, and then set a @@ -612,6 +670,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) DBG("coherent hardware translation table walks is off"); } + ret = mdp5_translation_ctrl_pwr(mdp5_kms, true); + if (ret) { + dev_err(dev->dev, "failed to power iommu: %d\n", ret); + mmu->funcs->destroy(mmu); + goto fail; + } + ret = mmu->funcs->attach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); if (ret) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 1e1a6b0..ab19d52a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -44,12 +44,15 @@ struct mdp5_kms { void __iomem *mmio, *vbif; struct regulator *vdd; + struct regulator *mmagic; struct clk *axi_clk; struct clk *ahb_clk; struct clk *src_clk; struct clk *core_clk; struct clk *lut_clk; + struct clk *mmagic_clk; + struct clk *iommu_clk; struct clk *vsync_clk; /*