From patchwork Wed Jan 9 12:54:41 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prasanna Kumar X-Patchwork-Id: 1952611 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 076CBDF25A for ; Wed, 9 Jan 2013 12:56:20 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Tsv95-0004Gr-Oi; Wed, 09 Jan 2013 12:52:39 +0000 Received: from mailout3.samsung.com ([203.254.224.33]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Tsv8z-0004Ed-Gx for linux-arm-kernel@lists.infradead.org; Wed, 09 Jan 2013 12:52:35 +0000 Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MGC00D33ZRHUK20@mailout3.samsung.com> for linux-arm-kernel@lists.infradead.org; Wed, 09 Jan 2013 21:52:29 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.122]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 8A.8D.12699.D086DE05; Wed, 09 Jan 2013 21:52:29 +0900 (KST) X-AuditID: cbfee61b-b7f616d00000319b-46-50ed680d3026 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 0A.8D.12699.D086DE05; Wed, 09 Jan 2013 21:52:29 +0900 (KST) Received: from user-ubuntu.sisodomain.com ([107.108.83.235]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MGC00CPHZLNZ970@mmp2.samsung.com> for linux-arm-kernel@lists.infradead.org; Wed, 09 Jan 2013 21:52:29 +0900 (KST) From: Prasanna Kumar To: linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, kgene.kim@samsung.com, t.figa@samsung.com, jhbird.choi@samsung.com Subject: [PATCH 3/3] ARM: exynos5: Add clock save and restore Date: Wed, 09 Jan 2013 18:24:41 +0530 Message-id: <1357736081-19390-4-git-send-email-prasanna.ps@samsung.com> X-Mailer: git-send-email 1.7.5.4 In-reply-to: <1357736081-19390-1-git-send-email-prasanna.ps@samsung.com> References: <1357736081-19390-1-git-send-email-prasanna.ps@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrNLMWRmVeSWpSXmKPExsWyRsSkSpc3422AwfWvahabHl9jdWD02Lyk PoAxissmJTUnsyy1SN8ugSvjyrK5jAXLdComTbrK1sB4TrmLkYNDQsBE4uBEmS5GTiBTTOLC vfVsXYxcHEICSxklHqz6wQaRMJG4duIRM0RiOqPEutVzGCGcLUwSS3Z/YgSpYhPQk5g/Yzk7 SEJEYCKjxPdN/8ESzAI6Evufb2IHWScsYCtx54AiSJhFQFXiY1s/K4jNK+Au8edsDwvENgWJ X0dWgcU5BTwkum98ZgKxhYBqWnccZoXoFZD4NvkQC8QHshKbDoAdJyFwmU1izr3rTBBzJCUO rrjBMoFReAEjwypG0dSC5ILipPRcI73ixNzi0rx0veT83E2MwBA8/e+Z9A7GVQ0WhxgFOBiV eHgZPd8GCLEmlhVX5h5ilOBgVhLhDfYFCvGmJFZWpRblxxeV5qQWH2L0AbpkIrOUaHI+MD7y SuINjU3MTY1NLY2MzExNcQgrifMynnoSICSQnliSmp2aWpBaBDOOiYNTqoFxbfnmvcWK++Su 7/3TsuHdkpiVR1bO/yRTnO0lbv3nSvi3DfuiPU7nq+X8vnou8+cBKQ49g1MvLISY3GLltvpO aRD7pBC3wPzL+Y0XZ9byLH6necThZLvc05dpC0SvncqySFV9YTt9+zLmxpLZk5v9ZL7fkWJe /PN5D5+h7Y4t+vEndygLLVz6W4mlOCPRUIu5qDgRAC7LGC9uAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupmkeLIzCtJLcpLzFFi42I5/e+xoC5vxtsAg4MbhC02Pb7G6sDosXlJ fQBjVAOjTUZqYkpqkUJqXnJ+SmZeuq2Sd3C8c7ypmYGhrqGlhbmSQl5ibqqtkotPgK5bZg7Q VCWFssScUqBQQGJxsZK+HaYJoSFuuhYwjRG6viFBcD1GBmggYQ1jxpVlcxkLlulUTJp0la2B 8ZxyFyMnh4SAicS1E4+YIWwxiQv31rN1MXJxCAlMZ5RYt3oOI4SzhUliye5PjCBVbAJ6EvNn LGcHSYgITGSU+L7pP1iCWUBHYv/zTUAJDg5hAVuJOwcUQcIsAqoSH9v6WUFsXgF3iT9ne1gg tilI/DqyCizOKeAh0X3jMxOILQRU07rjMOsERt4FjAyrGEVTC5ILipPSc430ihNzi0vz0vWS 83M3MYJD/Jn0DsZVDRaHGAU4GJV4eBk93wYIsSaWFVfmHmKU4GBWEuEN9gUK8aYkVlalFuXH F5XmpBYfYvQBumois5Rocj4w/vJK4g2NTcxNjU0tTSxMzCxxCCuJ8zKeehIgJJCeWJKanZpa kFoEM46Jg1OqgbFi8qz5rmfSpfbfM9pc8DpKS+1ORp7V07vln/M2HDJimfTqunNLg/YkF6OS /JWPtIQcVm3Vlk+Wjl1ZOWudvtsTq5pVOZc6DIXrte67NHRqFF5OmnhyAj+zhVfmg/C+/iTe s/faxG9uK+iPaZF53h2TuODIeYm7et7ebVq3Zp5VmjS9p/hulxJLcUaioRZzUXEiAAl9TQGe AgAA X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130109_075234_146970_1C29E2D1 X-CRM114-Status: GOOD ( 17.58 ) X-Spam-Score: -7.6 (-------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-7.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [203.254.224.33 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Prasanna Kumar X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org After Suspend-Resume operation, it is observed that CLK_TOP_SRC3 register gets modified if the G-Scaler/MFC devices are power gated. The clock for G-Scaler gets set to XXTI which results in the device running very slow.This issue also seen for MFC. To solve above issue, the existing clock framework of exynos5 is used to save and restore clocks while power gating instead of accessing CLK_SRC_TOP3 register directly.The clock names are read from DT file. Please refer below URL to know the background of this issue. http://www.mail-archive.com/linux-samsung-soc@vger.kernel.org/msg14347.html. Signed-off-by: Prasanna Kumar --- arch/arm/mach-exynos/pm_domains.c | 125 +++++++++++++++++++++++++++++++++++++ 1 files changed, 125 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index 9f1351d..2f49de9 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -21,9 +21,14 @@ #include #include #include +#include +#include #include #include +#include +#include + /* * Exynos specific wrapper around the generic power domain @@ -33,7 +38,69 @@ struct exynos_pm_domain { char const *name; bool is_off; struct generic_pm_domain pd; + struct list_head list_pdclks; + struct list_head saved_list_pdclks; + int pd_clks; +}; + +struct exynos_pd_clk { + struct list_head node; + struct clk *clk; }; +static int exynos_pdclk_save(struct exynos_pm_domain *epd) +{ + struct exynos_pd_clk *pdclk; + struct exynos_pd_clk *saved_pdclk; + + list_for_each_entry(pdclk, &epd->list_pdclks, node) { + if (pdclk) { + saved_pdclk = kzalloc(sizeof(struct exynos_pd_clk), + GFP_KERNEL); + if (!saved_pdclk) { + pr_err("%s: failed to allocate memory\n", + __func__); + return -ENOMEM; + } + saved_pdclk->clk = clk_get_parent(pdclk->clk); + if (IS_ERR(saved_pdclk->clk)) { + pr_err(" Cannot get parent for %s\n", + pdclk->clk->name); + return PTR_ERR(saved_pdclk->clk); + } + list_add_tail(&saved_pdclk->node, + &epd->saved_list_pdclks); + } + } + return 0; +} + +static void exynos_pdclk_restore(struct exynos_pm_domain *epd) +{ + struct exynos_pd_clk *pdclk; + struct exynos_pd_clk *saved_pdclk; + struct list_head *p_clk; + struct list_head *p_saved_clk; + int ret; + + p_saved_clk = epd->saved_list_pdclks.next; + p_clk = epd->list_pdclks.next; + + for ( ; p_saved_clk != &epd->saved_list_pdclks && + p_clk != &epd->list_pdclks; + p_clk = p_clk->next, p_saved_clk = p_saved_clk->next) { + + saved_pdclk = list_entry(p_saved_clk, + struct exynos_pd_clk, node); + pdclk = list_entry(p_clk, struct exynos_pd_clk, node); + if (saved_pdclk && pdclk) { + ret = clk_set_parent(pdclk->clk, saved_pdclk->clk); + if (ret) + pr_err("Failed to set %s as parent of %s\n", + saved_pdclk->clk->name, pdclk->clk->name); + } + } + return; +} static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) { @@ -45,6 +112,13 @@ 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; + if (!power_on) { + if (pd->pd_clks > 0) + if (exynos_pdclk_save(pd)) + pr_err("Failed to save pdclks for %s\n", + domain->name); + } + pwr = power_on ? S5P_INT_LOCAL_PWR_EN : 0; __raw_writel(pwr, base); @@ -61,6 +135,11 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) cpu_relax(); usleep_range(80, 100); } + + if (!power_on) { + if (pd->pd_clks > 0) + exynos_pdclk_restore(pd); + } return 0; } @@ -157,10 +236,48 @@ static struct notifier_block platform_nb = { .notifier_call = exynos_pm_notifier_call, }; +static int exynos_read_pdclk_from_dt(struct device_node *dev_node, + struct exynos_pm_domain *pd) +{ + int i = 0; + const char *clk_name; + struct exynos_pd_clk *pd_clk; + int err = 0; + + INIT_LIST_HEAD(&pd->list_pdclks); + INIT_LIST_HEAD(&pd->saved_list_pdclks); + + for (i = 0; i < pd->pd_clks; i++) { + pd_clk = kzalloc(sizeof(struct exynos_pd_clk), + GFP_KERNEL); + if (!pd_clk) { + pr_err("%s: failed to allocate memory\n", + __func__); + return -ENOMEM; + } + err = of_property_read_string_index(dev_node, + "samsung,exynos-pd-clks", + i, + &clk_name); + if (err) { + pr_err("failed to read pd_clks\n"); + return err; + } + pd_clk->clk = clk_get(NULL, clk_name); + if (IS_ERR(pd_clk->clk)) { + pr_err("clk_get failed for %s\n", clk_name); + return PTR_ERR(pd_clk->clk); + } + list_add(&pd_clk->node, &pd->list_pdclks); + } + return 0; +} + static __init int exynos_pm_dt_parse_domains(void) { struct platform_device *pdev; struct device_node *np; + int err = 0; for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { struct exynos_pm_domain *pd; @@ -182,6 +299,14 @@ static __init int exynos_pm_dt_parse_domains(void) pd->pd.power_on = exynos_pd_power_on; pd->pd.of_node = np; + pd->pd_clks = of_property_count_strings(np, + "samsung,exynos-pd-clks"); + if (pd->pd_clks > 0) { + err = exynos_read_pdclk_from_dt(np, pd); + if (err) + return err; + } + platform_set_drvdata(pdev, pd); on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN;