From patchwork Mon Dec 12 15:46:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: thomas.abraham@linaro.org X-Patchwork-Id: 5606 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 91A4523E01 for ; Mon, 12 Dec 2011 15:45:24 +0000 (UTC) Received: from mail-bw0-f52.google.com (mail-bw0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id 7F789A18535 for ; Mon, 12 Dec 2011 15:45:24 +0000 (UTC) Received: by mail-bw0-f52.google.com with SMTP id 17so7498074bke.11 for ; Mon, 12 Dec 2011 07:45:24 -0800 (PST) Received: by 10.204.133.213 with SMTP id g21mr6558524bkt.126.1323704724312; Mon, 12 Dec 2011 07:45:24 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.129.2 with SMTP id hg2cs51046bkc; Mon, 12 Dec 2011 07:45:24 -0800 (PST) Received: by 10.236.92.168 with SMTP id j28mr26237600yhf.59.1323704722387; Mon, 12 Dec 2011 07:45:22 -0800 (PST) Received: from mailout4.samsung.com (mailout4.samsung.com. [203.254.224.34]) by mx.google.com with ESMTP id i14si7337561ybf.85.2011.12.12.07.45.21; Mon, 12 Dec 2011 07:45:22 -0800 (PST) Received-SPF: neutral (google.com: 203.254.224.34 is neither permitted nor denied by best guess record for domain of thomas.abraham@linaro.org) client-ip=203.254.224.34; Authentication-Results: mx.google.com; spf=neutral (google.com: 203.254.224.34 is neither permitted nor denied by best guess record for domain of thomas.abraham@linaro.org) smtp.mail=thomas.abraham@linaro.org Received: from epcpsbgm1.samsung.com (mailout4.samsung.com [203.254.224.34]) by mailout4.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTP id <0LW300DOKL3BID30@mailout4.samsung.com> for patches@linaro.org; Tue, 13 Dec 2011 00:45:20 +0900 (KST) X-AuditID: cbfee61a-b7b89ae000001a15-f1-4ee6218fb41f Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (MMPCPMTA) with SMTP id 8D.82.06677.F8126EE4; Tue, 13 Dec 2011 00:45:20 +0900 (KST) Received: from localhost.localdomain ([107.108.73.37]) by mmp2.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTPA id <0LW300JBXL35FY00@mmp2.samsung.com> for patches@linaro.org; Tue, 13 Dec 2011 00:45:19 +0900 (KST) From: Thomas Abraham To: linux-samsung-soc@vger.kernel.org, linux-pm@vger.kernel.org Cc: rjw@sisk.pl, linux-arm-kernel@lists.infradead.org, devicetree-discuss@lists.ozlabs.org, rob.herring@calxeda.com, grant.likely@secretlab.ca, kgene.kim@samsung.com, broonie@opensource.wolfsonmicro.com, patches@linaro.org Subject: [PATCH 2/2] ARM: Exynos: Hook up power domains to generic power domain infrastructure Date: Mon, 12 Dec 2011 21:16:29 +0530 Message-id: <1323704789-23923-3-git-send-email-thomas.abraham@linaro.org> X-Mailer: git-send-email 1.6.6.rc2 In-reply-to: <1323704789-23923-2-git-send-email-thomas.abraham@linaro.org> References: <1323704789-23923-1-git-send-email-thomas.abraham@linaro.org> <1323704789-23923-2-git-send-email-thomas.abraham@linaro.org> X-Brightmail-Tracker: AAAAAA== The generic power domain infrastructure is used to control the power domains available on Exynos4. For non-dt platforms, the power domains are statically instantiated. For dt platforms, the power domain nodes found in the device tree are instantiated. Cc: Kukjin Kim Cc: Rob Herring Cc: Grant Likely Signed-off-by: Thomas Abraham --- This patch is mainly derived from Mark Brown's work on generic power domain support for s3c64xx platforms. The existing exynos4 power domain implementation is not removed in this patch. The devices are not yet registered with the power domains for non-dt platforms. arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/pm.c | 179 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 0afcc3b..c1f77c7 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -29,6 +29,7 @@ config CPU_EXYNOS4210 default y depends on ARCH_EXYNOS4 select SAMSUNG_DMADEV + select PM_GENERIC_DOMAINS select ARM_CPU_SUSPEND if PM select S5P_PM if PM select S5P_SLEEP if PM diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 4093fea..a471ea6 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -20,6 +20,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -37,6 +41,13 @@ #include #include +struct exynos4_pm_domain { + void __iomem *base; + char const *name; + bool is_off; + struct generic_pm_domain pd; +}; + static struct sleep_save exynos4_set_clksrc[] = { { .reg = S5P_CLKSRC_MASK_TOP , .val = 0x00000001, }, { .reg = S5P_CLKSRC_MASK_CAM , .val = 0x11111111, }, @@ -285,12 +296,172 @@ static struct sysdev_driver exynos4_pm_driver = { .add = exynos4_pm_add, }; +static int exynos4_pd_power_on(struct generic_pm_domain *domain) +{ + struct exynos4_pm_domain *pd; + void __iomem *base; + u32 timeout; + + pd = container_of(domain, struct exynos4_pm_domain, pd); + base = pd->base; + + __raw_writel(S5P_INT_LOCAL_PWR_EN, base); + + /* Wait max 1ms */ + timeout = 10; + while ((__raw_readl(base + 0x4) & S5P_INT_LOCAL_PWR_EN) + != S5P_INT_LOCAL_PWR_EN) { + if (!timeout) { + pr_err("Power domain %s enable failed\n", domain->name); + return -ETIMEDOUT; + } + timeout--; + udelay(100); + } + return 0; +} + +static int exynos4_pd_power_off(struct generic_pm_domain *domain) +{ + struct exynos4_pm_domain *pd; + void __iomem *base; + u32 timeout; + + pd = container_of(domain, struct exynos4_pm_domain, pd); + base = pd->base; + + __raw_writel(0, base); + + /* Wait max 1ms */ + timeout = 10; + while (__raw_readl(base + 0x4) & S5P_INT_LOCAL_PWR_EN) { + if (!timeout) { + pr_err("Power domain %s disable failed\n", domain->name); + return -ETIMEDOUT; + } + timeout--; + udelay(100); + } + return 0; +} + +static struct exynos4_pm_domain exynos4_pd_mfc = { + .base = (void __iomem *)S5P_PMU_MFC_CONF, + .name = "pd-mfc", + .pd = { + .power_off = exynos4_pd_power_off, + .power_on = exynos4_pd_power_on, + }, +}; + +static struct exynos4_pm_domain exynos4_pd_g3d = { + .base = (void __iomem *)S5P_PMU_G3D_CONF, + .name = "pd-g3d", + .pd = { + .power_off = exynos4_pd_power_off, + .power_on = exynos4_pd_power_on, + }, +}; + +static struct exynos4_pm_domain exynos4_pd_lcd0 = { + .base = (void __iomem *)S5P_PMU_LCD0_CONF, + .name = "pd-lcd0", + .pd = { + .power_off = exynos4_pd_power_off, + .power_on = exynos4_pd_power_on, + }, +}; + +static struct exynos4_pm_domain exynos4_pd_lcd1 = { + .base = (void __iomem *)S5P_PMU_LCD1_CONF, + .name = "pd-lcd1", + .pd = { + .power_off = exynos4_pd_power_off, + .power_on = exynos4_pd_power_on, + }, +}; + +static struct exynos4_pm_domain exynos4_pd_tv = { + .base = (void __iomem *)S5P_PMU_TV_CONF, + .name = "pd-tv", + .pd = { + .power_off = exynos4_pd_power_off, + .power_on = exynos4_pd_power_on, + }, +}; + +static struct exynos4_pm_domain exynos4_pd_cam = { + .base = (void __iomem *)S5P_PMU_CAM_CONF, + .name = "pd-cam", + .pd = { + .power_off = exynos4_pd_power_off, + .power_on = exynos4_pd_power_on, + }, +}; + +static struct exynos4_pm_domain exynos4_pd_gps = { + .base = (void __iomem *)S5P_PMU_GPS_CONF, + .name = "pd-gps", + .pd = { + .power_off = exynos4_pd_power_off, + .power_on = exynos4_pd_power_on, + }, +}; + +static struct exynos4_pm_domain *exynos4_pm_domains[] = { + &exynos4_pd_mfc, + &exynos4_pd_g3d, + &exynos4_pd_lcd0, + &exynos4_pd_lcd1, + &exynos4_pd_tv, + &exynos4_pd_cam, + &exynos4_pd_gps, +}; + +static __init void exynos4_pm_init_power_domain(void) +{ + int idx; + struct device_node *np; + +#ifdef CONFIG_OF + if (!of_have_populated_dt()) + goto no_dt; + + for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { + struct exynos4_pm_domain *pd; + + pd = kzalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) { + pr_err("exynos4_pm_init_power_domain: memalloc " + "failed\n"); + return; + } + + if (of_get_property(np, "samsung,exynos4210-pd-off", NULL)) + pd->is_off = true; + pd->name = np->name; + pd->base = of_iomap(np, 0); + pd->pd.power_off = exynos4_pd_power_off; + pd->pd.power_on = exynos4_pd_power_on; + pd->pd.of_node = np; + pm_genpd_init(&pd->pd, NULL, false); + } + return; +#endif /* CONFIG_OF */ + +no_dt: + for (idx = 0; idx < ARRAY_SIZE(exynos4_pm_domains); idx++) + pm_genpd_init(&exynos4_pm_domains[idx]->pd, NULL, + exynos4_pm_domains[idx]->is_off); +} + static __init int exynos4_pm_drvinit(void) { struct clk *pll_base; unsigned int tmp; s3c_pm_init(); + exynos4_pm_init_power_domain(); /* All wakeup disable */ @@ -406,3 +577,11 @@ static __init int exynos4_pm_syscore_init(void) return 0; } arch_initcall(exynos4_pm_syscore_init); + + +static __init int exynos4_pm_late_initcall(void) +{ + pm_genpd_poweroff_unused(); + return 0; +} +late_initcall(exynos4_pm_late_initcall);