From patchwork Mon May 26 11:56:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shaik Ameer Basha X-Patchwork-Id: 4241891 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A24249F1E7 for ; Mon, 26 May 2014 11:58:22 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AF66D2020A for ; Mon, 26 May 2014 11:58:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4DA44201FA for ; Mon, 26 May 2014 11:58:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751917AbaEZL6T (ORCPT ); Mon, 26 May 2014 07:58:19 -0400 Received: from mailout1.samsung.com ([203.254.224.24]:54469 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751549AbaEZL6S (ORCPT ); Mon, 26 May 2014 07:58:18 -0400 Received: from epcpsbgr1.samsung.com (u141.gpu120.samsung.co.kr [203.254.230.141]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N66003JFJX5TZC0@mailout1.samsung.com>; Mon, 26 May 2014 20:58:17 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.124]) by epcpsbgr1.samsung.com (EPCPMTA) with SMTP id A6.FB.24374.95C23835; Mon, 26 May 2014 20:58:17 +0900 (KST) X-AuditID: cbfee68d-b7fd46d000005f36-a9-53832c5952d3 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 88.8E.07139.85C23835; Mon, 26 May 2014 20:58:17 +0900 (KST) Received: from chromebld-server.sisodomain.com ([107.108.73.106]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N66006MLJW8Y690@mmp2.samsung.com>; Mon, 26 May 2014 20:58:16 +0900 (KST) From: Shaik Ameer Basha To: linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org Cc: kgene.kim@samsung.com, t.figa@samsung.com, tomasz.figa@gmail.com, mark.rutland@arm.com, pawel.moll@arm.com, swarren@wwwdotorg.org, prathyush.k@samsung.com, abrestic@chromium.org, arunkk.samsung@gmail.com, joshi@samsung.com, Arun Kumar K , Shaik Ameer Basha Subject: [PATCH v2 1/3] ARM: EXYNOS: Add support for clock handling in power domain Date: Mon, 26 May 2014 17:26:22 +0530 Message-id: <1401105384-8678-2-git-send-email-shaik.ameer@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1401105384-8678-1-git-send-email-shaik.ameer@samsung.com> References: <1401105384-8678-1-git-send-email-shaik.ameer@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprLIsWRmVeSWpSXmKPExsWyRsSkRjdSpznY4M81PouV7/8yWnw8dZvV 4sXGW+wW84+cY7X4vusLu0XvgqtsFjPO72OyWHr9IpPFhOlrWSwurNjIbnHk4W52i1cH21gs 1s94zWKxatcfRgc+jzXz1jB6zG64yOKxc9Zddo++LasYPT5vkvPYODc0gC2KyyYlNSezLLVI 3y6BK+Pgim6Wgm16FXMmfGVtYJyp2sXIwSEhYCJxvr2ki5ETyBSTuHBvPVsXIxeHkMBSRolv RyYyQiRMJCZNfsgCkZjOKLFvSjMThDOBSWLDxC52kCo2AUOJ7feusILYIgKOEjvm/AMrYhbY zSRxv/8EWJGwQKjE8b7VYDaLgKrExfM3wRp4BdwkNh6YygxxkoLEnEk2IGFOAXeJptvfwK4Q Air5tmgvO8hMCYFb7BL/JmxghpgjIPFt8iEWiF5ZiU0HmCGulpQ4uOIGywRG4QWMDKsYRVML kguKk9KLDPWKE3OLS/PS9ZLzczcxAqPm9L9nvTsYbx+wPsSYDDRuIrOUaHI+MOrySuINjc2M LExNTI2NzC3NSBNWEudNepgUJCSQnliSmp2aWpBaFF9UmpNafIiRiYNTqoHx1ORpM06ujJns 4Cf28XHbTzZz28kb2F6aSSvyK2fPnjF5btpTdpfQ9VVTknu6nm1dNX3ysbfzp3X3PN+4sVyn mEFY59bU+WuupHq+2PVgtUcRC8PauAmqOanzdReuF+DeE8OVzc97rz58m1f/XJHUolMLE5kz LAWWy/99qzzt9oOoj71+S3ifKbEUZyQaajEXFScCAHXw04CwAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrNIsWRmVeSWpSXmKPExsVy+t9jQd1IneZgg70PmCxWvv/LaPHx1G1W ixcbb7FbzD9yjtXi+64v7Ba9C66yWcw4v4/JYun1i0wWE6avZbG4sGIju8WRh7vZLV4dbGOx WD/jNYvFql1/GB34PNbMW8PoMbvhIovHzll32T36tqxi9Pi8Sc5j49zQALaoBkabjNTElNQi hdS85PyUzLx0WyXv4HjneFMzA0NdQ0sLcyWFvMTcVFslF58AXbfMHKBzlRTKEnNKgUIBicXF Svp2mCaEhrjpWsA0Ruj6hgTB9RgZoIGENYwZB1d0sxRs06uYM+ErawPjTNUuRk4OCQETiUmT H7JA2GISF+6tZ+ti5OIQEpjOKLFvSjMThDOBSWLDxC52kCo2AUOJ7feusILYIgKOEjvm/AMr YhbYzSRxv/8EWJGwQKjE8b7VYDaLgKrExfM3wRp4BdwkNh6YytzFyAG0TkFiziQbkDCngLtE 0+1vjCC2EFDJt0V72Scw8i5gZFjFKJpakFxQnJSea6RXnJhbXJqXrpecn7uJERyVz6R3MK5q sDjEKMDBqMTDe8C7KViINbGsuDL3EKMEB7OSCK8WZ3OwEG9KYmVValF+fFFpTmrxIcZkoKMm MkuJJucDE0ZeSbyhsYm5qbGppYmFiZklacJK4rwHW60DhQTSE0tSs1NTC1KLYLYwcXBKNTAm 2rpaF/3YLH5C+8L3wy3/ev//c+07Lew6baKx819XFs1Onmmf3jzUL+ffup7t0G+dCMvnWfN3 ++W7bi44tvWVVxzv8a1znMrb61ZEr353xv5u1Md11ZIBezO1Ul7s+MkctHFaQodzYf4CBbdv W4QZuR0yGZvY3rtG+u9ZvaH/i+gH/X9XbXuVWIozEg21mIuKEwG59KQpDgMAAA== DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Prathyush K While powering on/off a local powerdomain in exynos5 chipsets, the input clocks to each device gets modified. This behaviour is based on the SYSCLK_SYS_PWR_REG registers. E.g. SYSCLK_MFC_SYS_PWR_REG = 0x0, the parent of input clock to MFC (aclk333) gets modified to oscclk = 0x1, no change in clocks. The recommended value of SYSCLK_SYS_PWR_REG before power gating any domain is 0x0. So we must also restore the clocks while powering on a domain everytime. This patch adds the framework for getting the required mux and parent clocks through a power domain device node. With this patch, while powering off a domain, parent is set to oscclk and while powering back on, its re-set to the correct parent which is as per the recommended pd on/off sequence. Signed-off-by: Prathyush K Signed-off-by: Andrew Bresticker Signed-off-by: Arun Kumar K Signed-off-by: Shaik Ameer Basha Reviewed-by: Tomasz Figa --- .../bindings/arm/exynos/power_domain.txt | 20 +++++++ arch/arm/mach-exynos/pm_domains.c | 59 +++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt index 5216b41..8b4f7b7f 100644 --- a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt +++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt @@ -9,6 +9,18 @@ Required Properties: - reg: physical base address of the controller and length of memory mapped region. +Optional Properties: +- clocks: List of clock handles. The parent clocks of the input clocks to the + devices in this power domain are set to oscclk before power gating + and restored back after powering on a domain. This is required for + all domains which are powered on and off and not required for unused + domains. +- clock-names: The following clocks can be specified: + - oscclk: Oscillator clock. + - pclkN, clkN: Pairs of parent of input clock and input clock to the + devices in this power domain. Maximum of 4 pairs (N = 0 to 3) + are supported currently. + Node of a device using power domains must have a samsung,power-domain property defined with a phandle to respective power domain. @@ -19,6 +31,14 @@ Example: reg = <0x10023C00 0x10>; }; + mfc_pd: power-domain@10044060 { + compatible = "samsung,exynos4210-pd"; + reg = <0x10044060 0x20>; + clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK333>, + <&clock CLK_MOUT_USER_ACLK333>; + clock-names = "oscclk", "pclk0", "clk0"; + }; + Example of the node using power domain: node { diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index fe6570e..34d86b1 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,8 @@ #include "regs-pmu.h" +#define MAX_CLK_PER_DOMAIN 4 + /* * Exynos specific wrapper around the generic power domain */ @@ -32,6 +35,9 @@ struct exynos_pm_domain { char const *name; bool is_off; struct generic_pm_domain pd; + struct clk *oscclk; + struct clk *clk[MAX_CLK_PER_DOMAIN]; + struct clk *pclk[MAX_CLK_PER_DOMAIN]; }; static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) @@ -44,6 +50,18 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) pd = container_of(domain, struct exynos_pm_domain, pd); base = pd->base; + /* Set oscclk before powering off a domain*/ + if (!power_on) { + int i; + for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { + if (IS_ERR(pd->clk[i])) + break; + if (clk_set_parent(pd->clk[i], pd->oscclk)) + pr_err("%s: error setting oscclk as parent to clock %d\n", + pd->name, i); + } + } + pwr = power_on ? S5P_INT_LOCAL_PWR_EN : 0; __raw_writel(pwr, base); @@ -60,6 +78,19 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) cpu_relax(); usleep_range(80, 100); } + + /* Restore clocks after powering on a domain*/ + if (power_on) { + int i; + for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { + if (IS_ERR(pd->clk[i])) + break; + if (clk_set_parent(pd->clk[i], pd->pclk[i])) + pr_err("%s: error setting parent to clock%d\n", + pd->name, i); + } + } + return 0; } @@ -152,9 +183,11 @@ static __init int exynos4_pm_init_power_domain(void) for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { struct exynos_pm_domain *pd; - int on; + int on, i; + struct device *dev; pdev = of_find_device_by_node(np); + dev = &pdev->dev; pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) { @@ -170,6 +203,30 @@ static __init int exynos4_pm_init_power_domain(void) pd->pd.power_on = exynos_pd_power_on; pd->pd.of_node = np; + pd->oscclk = clk_get(dev, "oscclk"); + if (IS_ERR(pd->oscclk)) + goto no_clk; + + for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { + char clk_name[8]; + + snprintf(clk_name, sizeof(clk_name), "clk%d", i); + pd->clk[i] = clk_get(dev, clk_name); + if (IS_ERR(pd->clk[i])) + break; + snprintf(clk_name, sizeof(clk_name), "pclk%d", i); + pd->pclk[i] = clk_get(dev, clk_name); + if (IS_ERR(pd->pclk[i])) { + clk_put(pd->clk[i]); + pd->clk[i] = ERR_PTR(-EINVAL); + break; + } + } + + if (IS_ERR(pd->clk[0])) + clk_put(pd->oscclk); + +no_clk: platform_set_drvdata(pdev, pd); on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN;