From patchwork Wed Dec 3 14:20:21 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 5431171 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: patchwork-linux-sh@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 3EB919F319 for ; Wed, 3 Dec 2014 14:20:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 04ED52035D for ; Wed, 3 Dec 2014 14:20:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C101720303 for ; Wed, 3 Dec 2014 14:20:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752846AbaLCOU2 (ORCPT ); Wed, 3 Dec 2014 09:20:28 -0500 Received: from michel.telenet-ops.be ([195.130.137.88]:59294 "EHLO michel.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752508AbaLCOUY (ORCPT ); Wed, 3 Dec 2014 09:20:24 -0500 Received: from ayla.of.borg ([84.193.93.87]) by michel.telenet-ops.be with bizsmtp id P2LN1p01F1t5w8s062LNFH; Wed, 03 Dec 2014 15:20:22 +0100 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1XwAn0-0002uM-MO; Wed, 03 Dec 2014 15:20:22 +0100 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1XwAn0-0001oz-Uj; Wed, 03 Dec 2014 15:20:22 +0100 From: Geert Uytterhoeven To: Simon Horman , Magnus Damm Cc: linux-sh@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH v2] ARM: shmobile: sh73a0 legacy: Add PM domain support Date: Wed, 3 Dec 2014 15:20:21 +0100 Message-Id: <1417616421-6968-1-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 Add all hierarchical PM domains that exist on SH-Mobile AG5 (sh730a), and register all platform devices to the appropriate PM domains. Special handling is required for the following PM domains: - A4BC0 and A4BC1 contain the SDRAM Bus State Controllers, and thus should not be turned off, - A3SP contains the serial console, and should not be turned off if no_console_suspend is set, - A2SL contains the CPU core, and should not be turned off if the CPU is in use. Note that PM domain D4 can be powered down without ill effects on s2ram behavior, just like on SH-Mobile AP4 (sh7372), but unlike on R-Mobile A1 (r8a7740). Signed-off-by: Geert Uytterhoeven --- v2: - The smsc911x is not located in A4S (the Bus State Controller it is connected to is, but we don't cover that device in legacy code), - Move domain_devices[] next to tables with platform devices. --- arch/arm/mach-shmobile/board-kzm9g.c | 14 ++++ arch/arm/mach-shmobile/pm-sh73a0.c | 131 ++++++++++++++++++++++++++++++++++ arch/arm/mach-shmobile/setup-sh73a0.c | 31 ++++++++ arch/arm/mach-shmobile/sh73a0.h | 7 ++ 4 files changed, 183 insertions(+) diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 7c9b63bdde9fa458..a4fbd02f1ddbdbc6 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -48,6 +48,7 @@ #include "common.h" #include "intc.h" #include "irqs.h" +#include "pm-rmobile.h" #include "sh73a0.h" /* @@ -798,6 +799,16 @@ static struct platform_device *kzm_devices[] __initdata = { &fsi_ak4648_device, }; +static struct pm_domain_device kzm_domain_devices[] __initdata = { + { "A4LC0", &lcdc_device }, + { "A4MP", &fsi_device }, + { "A4S", &usb_host_device }, + { "A3SP", &usbhs_device }, + { "A3SP", &mmc_device }, + { "A3SP", &sdhi0_device }, + { "A3SP", &sdhi2_device }, +}; + static unsigned long pin_pullup_conf[] = { PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 0), }; @@ -888,6 +899,9 @@ static void __init kzm_init(void) sh73a0_add_standard_devices(); platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices)); + rmobile_add_devices_to_domains(kzm_domain_devices, + ARRAY_SIZE(kzm_domain_devices)); + sh73a0_pm_init(); } diff --git a/arch/arm/mach-shmobile/pm-sh73a0.c b/arch/arm/mach-shmobile/pm-sh73a0.c index a7e466817965e3b8..06d2d98a355a0b70 100644 --- a/arch/arm/mach-shmobile/pm-sh73a0.c +++ b/arch/arm/mach-shmobile/pm-sh73a0.c @@ -2,14 +2,145 @@ * sh73a0 Power management support * * Copyright (C) 2012 Bastian Hecht + * Copyright (C) 2014 Glider bvba * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#include +#include #include + #include "common.h" +#include "pm-rmobile.h" + +#define SYSC_BASE IOMEM(0xe6180000) + +#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM) +static int sh73a0_pd_a4bc_suspend(void) +{ + /* + * The A4BC0 and A4BC1 domains contain the SDRAM Bus State Controllers + * (SBSC1 and SBSC2) and therefore they should only be turned off if + * SDRAM is not in use. + */ + return -EBUSY; +} + +static int sh73a0_pd_a3sp_suspend(void) +{ + /* + * Serial consoles make use of SCIF hardware located in A3SP, + * keep such power domain on if "no_console_suspend" is set. + */ + return console_suspend_enabled ? 0 : -EBUSY; +} + +static int sh73a0_pd_a2sl_suspend(void) +{ + /* + * The A2SL domain contains the CPU core and therefore it should + * only be turned off if the CPU is not in use. + */ + return -EBUSY; +} + +static struct rmobile_pm_domain sh73a0_pm_domains[] = { + { + .genpd.name = "C4", + .base = SYSC_BASE, + .bit_shift = 0, + }, { + .genpd.name = "D4", + .base = SYSC_BASE, + .bit_shift = 1, + }, { + .genpd.name = "A4BC0", + .base = SYSC_BASE, + .bit_shift = 4, + .gov = &pm_domain_always_on_gov, + .suspend = sh73a0_pd_a4bc_suspend, + }, { + .genpd.name = "A4BC1", + .base = SYSC_BASE, + .bit_shift = 5, + .gov = &pm_domain_always_on_gov, + .suspend = sh73a0_pd_a4bc_suspend, + }, { + .genpd.name = "A4LC0", + .base = SYSC_BASE, + .bit_shift = 6, + }, { + .genpd.name = "A4LC1", + .base = SYSC_BASE, + .bit_shift = 7, + }, { + .genpd.name = "A4MP", + .base = SYSC_BASE, + .bit_shift = 8, + }, { + .genpd.name = "A3MP", + .base = SYSC_BASE, + .bit_shift = 9, + }, { + .genpd.name = "A3VC", + .base = SYSC_BASE, + .bit_shift = 10, + }, { + .genpd.name = "A4RM", + .base = SYSC_BASE, + .bit_shift = 12, + }, { + .genpd.name = "A3R", + .base = SYSC_BASE, + .bit_shift = 13, + }, { + .genpd.name = "A2RV", + .base = SYSC_BASE, + .bit_shift = 14, + }, { + .genpd.name = "A4S", + .base = SYSC_BASE, + .bit_shift = 16, + }, { + .genpd.name = "A3SP", + .base = SYSC_BASE, + .bit_shift = 17, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = sh73a0_pd_a3sp_suspend, + }, { + .genpd.name = "A3SG", + .base = SYSC_BASE, + .bit_shift = 18, + }, { + .genpd.name = "A3SM", + .base = SYSC_BASE, + .bit_shift = 19, + }, { + .genpd.name = "A2SL", + .base = SYSC_BASE, + .bit_shift = 20, + .gov = &pm_domain_always_on_gov, + .suspend = sh73a0_pd_a2sl_suspend, + } +}; + +void __init sh73a0_init_pm_domains(void) +{ + rmobile_init_domains(sh73a0_pm_domains, ARRAY_SIZE(sh73a0_pm_domains)); + pm_genpd_add_subdomain_names("A4MP", "A3MP"); + pm_genpd_add_subdomain_names("A4MP", "A3VC"); + pm_genpd_add_subdomain_names("A4RM", "A3R"); + pm_genpd_add_subdomain_names("A3R", "A2RV"); + pm_genpd_add_subdomain_names("A4S", "A3SP"); + pm_genpd_add_subdomain_names("A4S", "A3SG"); + pm_genpd_add_subdomain_names("A4S", "A3SM"); + pm_genpd_add_subdomain_names("A3SM", "A2SL"); +} +#endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */ #ifdef CONFIG_SUSPEND static int sh73a0_enter_suspend(suspend_state_t suspend_state) diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 93ebe3430bfe707a..2ec702c51dd25050 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -39,6 +39,7 @@ #include "dma-register.h" #include "intc.h" #include "irqs.h" +#include "pm-rmobile.h" #include "sh73a0.h" static struct map_desc sh73a0_io_desc[] __initdata = { @@ -744,6 +745,30 @@ static struct platform_device *sh73a0_late_devices[] __initdata = { &irqpin3_device, }; +static struct pm_domain_device sh73a0_domain_devices[] __initdata = { + { "A4MP", &mpdma0_device }, + { "A3R", &tmu0_device }, + { "A4S", &irqpin0_device }, + { "A4S", &irqpin1_device }, + { "A4S", &irqpin2_device }, + { "A4S", &irqpin3_device }, + { "A3SP", &dma0_device }, + { "A3SP", &i2c0_device }, + { "A3SP", &i2c1_device }, + { "A3SP", &i2c2_device }, + { "A3SP", &i2c3_device }, + { "A3SP", &ipmmu_device }, + { "A3SP", &scif0_device }, + { "A3SP", &scif1_device }, + { "A3SP", &scif2_device }, + { "A3SP", &scif3_device }, + { "A3SP", &scif4_device }, + { "A3SP", &scif5_device }, + { "A3SP", &scif6_device }, + { "A3SP", &scif7_device }, + { "A3SP", &scif8_device }, +}; + #define SRCR2 IOMEM(0xe61580b0) void __init sh73a0_add_standard_devices(void) @@ -751,10 +776,16 @@ void __init sh73a0_add_standard_devices(void) /* Clear software reset bit on SY-DMAC module */ __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2); + sh73a0_init_pm_domains(); + platform_add_devices(sh73a0_early_devices, ARRAY_SIZE(sh73a0_early_devices)); platform_add_devices(sh73a0_late_devices, ARRAY_SIZE(sh73a0_late_devices)); + + /* add devices to PM domain */ + rmobile_add_devices_to_domains(sh73a0_domain_devices, + ARRAY_SIZE(sh73a0_domain_devices)); } /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ diff --git a/arch/arm/mach-shmobile/sh73a0.h b/arch/arm/mach-shmobile/sh73a0.h index f037c64b14fc0767..1a68a132bd516e00 100644 --- a/arch/arm/mach-shmobile/sh73a0.h +++ b/arch/arm/mach-shmobile/sh73a0.h @@ -81,6 +81,13 @@ extern void sh73a0_add_standard_devices_dt(void); extern void sh73a0_clock_init(void); extern void sh73a0_pinmux_init(void); extern void sh73a0_pm_init(void); + +#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM) +extern void sh73a0_init_pm_domains(void); +#else +static inline void sh73a0_init_pm_domains(void) {} +#endif + extern struct clk sh73a0_extal1_clk; extern struct clk sh73a0_extal2_clk; extern struct clk sh73a0_extcki_clk;