From patchwork Wed Oct 31 09:41:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Lo X-Patchwork-Id: 195795 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 06DCB2C0199 for ; Wed, 31 Oct 2012 20:41:58 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751623Ab2JaJlw (ORCPT ); Wed, 31 Oct 2012 05:41:52 -0400 Received: from hqemgate03.nvidia.com ([216.228.121.140]:9207 "EHLO hqemgate03.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933580Ab2JaJlq (ORCPT ); Wed, 31 Oct 2012 05:41:46 -0400 Received: from hqnvupgp06.nvidia.com (Not Verified[216.228.121.13]) by hqemgate03.nvidia.com id ; Wed, 31 Oct 2012 02:44:19 -0700 Received: from hqemhub03.nvidia.com ([172.17.108.22]) by hqnvupgp06.nvidia.com (PGP Universal service); Wed, 31 Oct 2012 02:41:45 -0700 X-PGP-Universal: processed; by hqnvupgp06.nvidia.com on Wed, 31 Oct 2012 02:41:45 -0700 Received: from localhost.localdomain (172.20.144.16) by hqemhub03.nvidia.com (172.20.150.15) with Microsoft SMTP Server (TLS) id 8.3.279.1; Wed, 31 Oct 2012 02:41:45 -0700 From: Joseph Lo To: Stephen Warren CC: , , Joseph Lo Subject: [PATCH V4 6/7] ARM: tegra30: flowctrl: add cpu_suspend_exter/exit function Date: Wed, 31 Oct 2012 17:41:20 +0800 Message-ID: <1351676481-28425-7-git-send-email-josephl@nvidia.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1351676481-28425-1-git-send-email-josephl@nvidia.com> References: <1351676481-28425-1-git-send-email-josephl@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org The flow controller can help CPU to go into suspend mode (powered-down state). When CPU go into powered-down state, it needs some careful settings before getting into and after leaving. The enter and exit functions do that by configuring appropriate mode for flow controller. Signed-off-by: Joseph Lo --- V4: * rebased on next-20121031 V3: * update the commit message V2: * no change --- arch/arm/mach-tegra/flowctrl.c | 47 ++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-tegra/flowctrl.h | 8 ++++++ 2 files changed, 55 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c index ffaa286..a2250dd 100644 --- a/arch/arm/mach-tegra/flowctrl.c +++ b/arch/arm/mach-tegra/flowctrl.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "flowctrl.h" #include "iomap.h" @@ -50,6 +51,14 @@ static void flowctrl_update(u8 offset, u32 value) readl_relaxed(addr); } +u32 flowctrl_read_cpu_csr(unsigned int cpuid) +{ + u8 offset = flowctrl_offset_cpu_csr[cpuid]; + void __iomem *addr = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + offset; + + return readl(addr); +} + void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value) { return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value); @@ -59,3 +68,41 @@ void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value) { return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value); } + +void flowctrl_cpu_suspend_enter(unsigned int cpuid) +{ + unsigned int reg; + int i; + + reg = flowctrl_read_cpu_csr(cpuid); + reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfe bitmap */ + reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; /* clear wfi bitmap */ + reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */ + reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event flag */ + reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid; /* pwr gating on wfi */ + reg |= FLOW_CTRL_CSR_ENABLE; /* pwr gating */ + flowctrl_write_cpu_csr(cpuid, reg); + + for (i = 0; i < num_possible_cpus(); i++) { + if (i == cpuid) + continue; + reg = flowctrl_read_cpu_csr(i); + reg |= FLOW_CTRL_CSR_EVENT_FLAG; + reg |= FLOW_CTRL_CSR_INTR_FLAG; + flowctrl_write_cpu_csr(i, reg); + } +} + +void flowctrl_cpu_suspend_exit(unsigned int cpuid) +{ + unsigned int reg; + + /* Disable powergating via flow controller for CPU0 */ + reg = flowctrl_read_cpu_csr(cpuid); + reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfe bitmap */ + reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; /* clear wfi bitmap */ + reg &= ~FLOW_CTRL_CSR_ENABLE; /* clear enable */ + reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr */ + reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event */ + flowctrl_write_cpu_csr(cpuid, reg); +} diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h index 1942817..0798dec 100644 --- a/arch/arm/mach-tegra/flowctrl.h +++ b/arch/arm/mach-tegra/flowctrl.h @@ -34,9 +34,17 @@ #define FLOW_CTRL_HALT_CPU1_EVENTS 0x14 #define FLOW_CTRL_CPU1_CSR 0x18 +#define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 (1 << 8) +#define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4) +#define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8) + #ifndef __ASSEMBLY__ +u32 flowctrl_read_cpu_csr(unsigned int cpuid); void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value); void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value); + +void flowctrl_cpu_suspend_enter(unsigned int cpuid); +void flowctrl_cpu_suspend_exit(unsigned int cpuid); #endif #endif