diff options
author | Scott Williams <scwilliams@nvidia.com> | 2010-05-03 18:43:08 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-05-04 17:31:12 -0700 |
commit | fc5f671424da0d58aad8378294dfdc0432ec5997 (patch) | |
tree | c15069252569d0ffbbc98b641860aafb7d81effe /arch | |
parent | 7e8d0d8ed579ba9d9e78c078202b3d7ecd78874e (diff) |
tegra: Clean up low-level power code
- Moved power header and partitioned in to SOC-specific and
SOC-independent parts.
- Eliminated assembly literals in favor of MOV32.
- Fixed low-power state enumerators.
- Cleaned up assembly statement whitespaces.
Change-Id: Ie157f8840eb238f9bf5602c74a974e00408b8ddc
Reviewed-on: http://git-master/r/1275
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Tested-by: Scott Williams <scwilliams@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/idle-t2.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/power-t2.h (renamed from arch/arm/mach-tegra/power.h) | 201 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/power.h | 150 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-context-t2.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-lp.S | 2282 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-t2.c | 126 |
6 files changed, 1370 insertions, 1403 deletions
diff --git a/arch/arm/mach-tegra/idle-t2.c b/arch/arm/mach-tegra/idle-t2.c index c9aeb8b6c7a7..d9d66b6989db 100644 --- a/arch/arm/mach-tegra/idle-t2.c +++ b/arch/arm/mach-tegra/idle-t2.c @@ -25,7 +25,7 @@ #include "ap20/arflow_ctlr.h" #include "nvbootargs.h" #include "nvrm_memmgr.h" -#include "power.h" +#include "mach/power.h" #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/wakelock.h> @@ -87,7 +87,7 @@ void __init NvAp20InitFlowController(void) NvRmModuleGetBaseAddress(s_hRmGlobal, NVRM_MODULE_ID(NvRmModuleID_FlowCtrl, 0), &pa, &len); - + if (NvRmPhysicalMemMap(pa, len, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void**)&pTempFc)!=NvSuccess) { @@ -280,12 +280,12 @@ void cpu_ap20_do_idle(void) { unsigned int tmp = 0; volatile uint32_t *addr = 0; - + dsb(); if (likely(s_pFlowCtrl)) { - /* + /* * Trigger the "stats monitor" to count the CPU idle cycles. */ if (smp_processor_id()) @@ -296,7 +296,7 @@ void cpu_ap20_do_idle(void) addr = (volatile uint32_t*)(s_pFlowCtrl + FLOW_CTLR_HALT_CPU_EVENTS_0); } - tmp = NV_DRF_DEF(FLOW_CTLR, HALT_CPU1_EVENTS, MODE, FLOW_MODE_WAITEVENT) + tmp = NV_DRF_DEF(FLOW_CTLR, HALT_CPU1_EVENTS, MODE, FLOW_MODE_WAITEVENT) | NV_DRF_NUM(FLOW_CTLR, HALT_CPU1_EVENTS, JTAG, 1); NV_WRITE32(addr, tmp); @@ -311,7 +311,7 @@ void cpu_ap20_do_idle(void) /* * Signal "stats monitor" to stop counting the idle cycles. */ - tmp = NV_DRF_DEF(FLOW_CTLR, HALT_CPU1_EVENTS, MODE, FLOW_MODE_NONE); + tmp = NV_DRF_DEF(FLOW_CTLR, HALT_CPU1_EVENTS, MODE, FLOW_MODE_NONE); NV_WRITE32(addr, tmp); tmp = NV_READ32(addr); } diff --git a/arch/arm/mach-tegra/power.h b/arch/arm/mach-tegra/include/mach/power-t2.h index ddca6fa3ce49..266c8f6fed71 100644 --- a/arch/arm/mach-tegra/power.h +++ b/arch/arm/mach-tegra/include/mach/power-t2.h @@ -1,30 +1,43 @@ /* - * arch/arm/mach-tegra/power.h + * arch/arm/mach-tegra/include/mach/power-t2.h * - * Header for tegra power + * Header for tegra 2 power * - * Copyright (c) 2010, NVIDIA Corporation. + * Copyright (c) 2010 NVIDIA Corporation. + * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NVIDIA Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "nvos.h" -#include "nvrm_init.h" -#include "nvrm_drf.h" +#ifndef _MACH_TEGRA_POWER_T2_H_ +#define _MACH_TEGRA_POWER_T2_H_ + #include "ap20/arapbpm.h" -#include "nvrm_module.h" #include "ap20/arflow_ctlr.h" #include "ap20/arclk_rst.h" #include "ap20/arapb_misc.h" @@ -35,78 +48,22 @@ #include "ap20/aremc.h" #include "ap15/arictlr.h" #include "ap15/argpio.h" -#include "nvrm_hardware_access.h" -#include "nvrm_interrupt.h" -#include "nvrm_power.h" -#include "nvrm_power_private.h" -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> #include "ap20/nvboot_pmc_scratch_map.h" -extern NvRmDeviceHandle s_hRmGlobal; - -#define NUM_LOCAL_TIMER_REGISTERS 3 -#define WAKE_PAD_MIN_LATCH_TIME_US 130 -#define WAKE_PAD_MIN_SAMPLE_TIME_US 70 +#define AVP_CONTEXT_SAVE_AREA_SIZE 4096 +#define NUM_LOCAL_TIMER_REGISTERS 3 +#define WAKE_PAD_MIN_LATCH_TIME_US 130 +#define WAKE_PAD_MIN_SAMPLE_TIME_US 70 //Workaround for spurious KBC wake event #define NV_KBC_INTERRUPT_WORKAROUND 1 -#define NV_CAR_REGR(pBase, reg)\ - NV_READ32( (((NvUPtr)(pBase)) + CLK_RST_CONTROLLER_##reg##_0)) -#define NV_CAR_REGW(pBase, reg, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + CLK_RST_CONTROLLER_##reg##_0), (val)) -#define NV_CAR_REGR_OFFSET(pBase, off)\ - NV_READ32( (((NvUPtr)(pBase)) + off)) -#define NV_CAR_REGW_OFFSET(pBase, off, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + off), (val)) - -#define NV_ICTLR_REGR(pBase, reg)\ - NV_READ32( (((NvUPtr)(pBase)) + ICTLR_##reg##_0)) -#define NV_ICTLR_REGW(pBase, reg, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + ICTLR_##reg##_0), (val)) - -#define NV_MISC_REGR(pBase, reg)\ - NV_READ32( (((NvUPtr)(pBase)) + APB_MISC_##reg##_0)) -#define NV_MISC_REGW(pBase, reg, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + APB_MISC_##reg##_0), (val)) - -#define NV_GPIO_REGR(pBase, reg)\ - NV_READ32( (((NvUPtr)(pBase)) + GPIO_##reg)) -#define NV_GPIO_REGW(pBase, reg, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + GPIO_##reg), (val)) - -#define NV_APBDMA_REGR(pBase, reg)\ - NV_READ32( (((NvUPtr)(pBase)) + APBDMA_##reg##_0)) -#define NV_APBDMA_REGW(pBase, reg, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + APBDMA_##reg##_0), (val)) - -#define NV_APBDMACH_REGR(pBase, reg)\ - NV_READ32( (((NvUPtr)(pBase)) + APBDMACHAN_CHANNEL_0_##reg##_0)) -#define NV_APBDMACH_REGW(pBase, reg, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + APBDMACHAN_CHANNEL_0_##reg##_0),(val)) - -#define NV_MC_REGR(pBase, reg)\ - NV_READ32( (((NvUPtr)(pBase)) + MC_##reg##_0)) -#define NV_MC_REGW(pBase, reg, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + MC_##reg##_0), (val)) - -#define NV_PMC_REGR(pBase, reg)\ - NV_READ32( (((NvUPtr)(pBase)) + APBDEV_PMC_##reg##_0)) -#define NV_PMC_REGW(pBase, reg, val)\ - NV_WRITE32( (((NvUPtr)(pBase)) + APBDEV_PMC_##reg##_0), (val)) - #define CAR_CLK_SOURCES_OFFSET_START CLK_RST_CONTROLLER_CLK_SOURCE_I2S1_0 -#define CAR_CLK_SOURCES_OFFSET_END CLK_RST_CONTROLLER_CLK_SOURCE_OSC_0 -#define CAR_CLK_SOURCES_REGISTER_COUNT\ +#define CAR_CLK_SOURCES_OFFSET_END CLK_RST_CONTROLLER_CLK_SOURCE_OSC_0 +#define CAR_CLK_SOURCES_REGISTER_COUNT \ ((CAR_CLK_SOURCES_OFFSET_END - CAR_CLK_SOURCES_OFFSET_START +\ sizeof(NvU32)) / sizeof(NvU32)) -#define NV_DR_REGR(d,r)\ - NV_READ32( ((NvUPtr)(g_p##d)) + d##_##r##_0) - - //------------------------------------------------------------------------------ // Boot ROM PMC scratch map name remapping to fix broken names (see bug 542815). //------------------------------------------------------------------------------ @@ -414,87 +371,5 @@ extern NvRmDeviceHandle s_hRmGlobal; REG(SCRATCH40, APB_MISC, GP_XM2CFGDPADCTRL2, CFG2TMC_XM2CFGD_RX_FT_REC_EN) \ /* End-of-List */ -#define GPIO_PORT(x) ((x) - 'a') -#define GPIO_PORTS_PER_INSTANCE (4) -#define GPIO_BITS_PER_PORT (8) - -#define aa ('z'+1) // GPIO port AA -#define ab ('z'+2) // GPIO port AB - -#define AVP_CONTEXT_SAVE_AREA_SIZE 4096 - -//------------------------------------------------------------------------------ -// Wakeup source table macros -//------------------------------------------------------------------------------ - -/** WAKEUP_INTERNAL(m,i,x) - Internal wakeup module interrupt sources - - @param m Module id - @param i Module instance - @param x Module interrupt index - */ -#define WAKEUP_INTERNAL(m,i,x) { NVRM_MODULE_ID((m), (i)), (x) } - -/** WAKEUP_EXTERNAL(p, b) - External wakeup module interrupt sources - - @param p GPIO port (e.g., 'a', 'b', etc.) - @param b GPIO port bit - */ -#define WAKEUP_EXTERNAL(p,b)\ - {NVRM_MODULE_ID(NvRmPrivModuleID_Gpio,GPIO_PORT(p)/GPIO_PORTS_PER_INSTANCE),\ - (((GPIO_PORT(p) % GPIO_PORTS_PER_INSTANCE)*GPIO_BITS_PER_PORT) + (b)) } -typedef struct -{ - NvU32 *pBase; - NvU32 *pContext; -} power_module_context; - -struct power_context -{ - NvU32 context_size_words; - NvU32 *first_context_location; - power_module_context interrupt; - power_module_context misc; - power_module_context clock_reset; - power_module_context apb_dma; - power_module_context apb_dma_chan; - power_module_context gpio; - power_module_context vde; - power_module_context mc; -}; - -struct wakeup_source -{ - NvU32 Module; - NvU32 Index; -}; - -typedef enum -{ - PowerModuleContext_Init, - PowerModuleContext_Save, - PowerModuleContext_Restore, - PowerModuleContext_DisableInterrupt, - PowerModuleContext_SaveLP1, - PowerModuleContext_RestoreLP1, - PowerModuleContext_Force32 = 0x7fffffff -} PowerModuleContext; - -typedef enum -{ - PowerPllM = 0x1, // Memory - PowerPllC = 0x2, // CPU - PowerPllP = 0x4, // Peripherals - PowerPllA = 0x8, // Audio - PowerPllX = 0x10, // CPU Complex - PowerPll_Force32 = 0x7fffffff -} PowerPll; - -typedef enum -{ - POWER_STATE_LP2, - POWER_STATE_LP1, - POWER_STATE_LP0, -} PowerState; +#endif /* _MACH_TEGRA_POWER_T2_H_ */ -typedef NvU16 NvIrqNumber; diff --git a/arch/arm/mach-tegra/include/mach/power.h b/arch/arm/mach-tegra/include/mach/power.h new file mode 100644 index 000000000000..501116d84ec6 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/power.h @@ -0,0 +1,150 @@ +/* + * arch/arm/mach-tegra/power.h + * + * Header for tegra power + * + * Copyright (c) 2010, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MACH_TEGRA_POWER_H_ +#define _MACH_TEGRA_POWER_H_ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include "nvos.h" +#include "nvrm_init.h" +#include "nvrm_drf.h" +#include "nvrm_module.h" +#include "nvrm_hardware_access.h" +#include "nvrm_interrupt.h" +#include "nvrm_power.h" +#include "nvrm_power_private.h" + +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) +#include "power-t2.h" +#else +#error "Unsupported Tegra SOC architecture" +#endif + +extern NvRmDeviceHandle s_hRmGlobal; + +#define NV_CAR_REGR(pBase, reg)\ + NV_READ32( (((NvUPtr)(pBase)) + CLK_RST_CONTROLLER_##reg##_0)) +#define NV_CAR_REGW(pBase, reg, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + CLK_RST_CONTROLLER_##reg##_0), (val)) +#define NV_CAR_REGR_OFFSET(pBase, off)\ + NV_READ32( (((NvUPtr)(pBase)) + off)) +#define NV_CAR_REGW_OFFSET(pBase, off, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + off), (val)) + +#define NV_ICTLR_REGR(pBase, reg)\ + NV_READ32( (((NvUPtr)(pBase)) + ICTLR_##reg##_0)) +#define NV_ICTLR_REGW(pBase, reg, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + ICTLR_##reg##_0), (val)) + +#define NV_MISC_REGR(pBase, reg)\ + NV_READ32( (((NvUPtr)(pBase)) + APB_MISC_##reg##_0)) +#define NV_MISC_REGW(pBase, reg, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + APB_MISC_##reg##_0), (val)) + +#define NV_GPIO_REGR(pBase, reg)\ + NV_READ32( (((NvUPtr)(pBase)) + GPIO_##reg)) +#define NV_GPIO_REGW(pBase, reg, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + GPIO_##reg), (val)) + +#define NV_APBDMA_REGR(pBase, reg)\ + NV_READ32( (((NvUPtr)(pBase)) + APBDMA_##reg##_0)) +#define NV_APBDMA_REGW(pBase, reg, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + APBDMA_##reg##_0), (val)) + +#define NV_APBDMACH_REGR(pBase, reg)\ + NV_READ32( (((NvUPtr)(pBase)) + APBDMACHAN_CHANNEL_0_##reg##_0)) +#define NV_APBDMACH_REGW(pBase, reg, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + APBDMACHAN_CHANNEL_0_##reg##_0),(val)) + +#define NV_MC_REGR(pBase, reg)\ + NV_READ32( (((NvUPtr)(pBase)) + MC_##reg##_0)) +#define NV_MC_REGW(pBase, reg, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + MC_##reg##_0), (val)) + +#define NV_PMC_REGR(pBase, reg)\ + NV_READ32( (((NvUPtr)(pBase)) + APBDEV_PMC_##reg##_0)) +#define NV_PMC_REGW(pBase, reg, val)\ + NV_WRITE32( (((NvUPtr)(pBase)) + APBDEV_PMC_##reg##_0), (val)) + +#define NV_DR_REGR(d,r)\ + NV_READ32( ((NvUPtr)(g_p##d)) + d##_##r##_0) + +typedef struct +{ + NvU32 *pBase; + NvU32 *pContext; +} power_module_context; + +struct power_context +{ + NvU32 context_size_words; + NvU32 *first_context_location; + power_module_context interrupt; + power_module_context misc; + power_module_context clock_reset; + power_module_context apb_dma; + power_module_context apb_dma_chan; + power_module_context gpio; + power_module_context vde; + power_module_context mc; +}; + +struct wakeup_source +{ + NvU32 Module; + NvU32 Index; +}; + +typedef enum +{ + PowerModuleContext_Init, + PowerModuleContext_Save, + PowerModuleContext_Restore, + PowerModuleContext_DisableInterrupt, + PowerModuleContext_SaveLP1, + PowerModuleContext_RestoreLP1, + PowerModuleContext_Force32 = 0x7fffffff +} PowerModuleContext; + +typedef enum +{ + PowerPllM = 0x1, // Memory + PowerPllC = 0x2, // CPU + PowerPllP = 0x4, // Peripherals + PowerPllA = 0x8, // Audio + PowerPllX = 0x10, // CPU Complex + PowerPll_Force32 = 0x7fffffff +} PowerPll; + +typedef enum +{ + POWER_STATE_LP0, + POWER_STATE_LP1, + POWER_STATE_LP2, +} PowerState; + +typedef NvU16 NvIrqNumber; + +#endif /* _MACH_TEGRA_POWER_H_ */ + diff --git a/arch/arm/mach-tegra/power-context-t2.c b/arch/arm/mach-tegra/power-context-t2.c index a67044ded963..41b3b9c5603f 100644 --- a/arch/arm/mach-tegra/power-context-t2.c +++ b/arch/arm/mach-tegra/power-context-t2.c @@ -20,7 +20,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "power.h" +#include "mach/power.h" extern NvRmDeviceHandle s_hRmGlobal; extern uintptr_t g_resume, g_contextSavePA; diff --git a/arch/arm/mach-tegra/power-lp.S b/arch/arm/mach-tegra/power-lp.S index 8b6ecf79ce32..c10eadbdee6f 100644 --- a/arch/arm/mach-tegra/power-lp.S +++ b/arch/arm/mach-tegra/power-lp.S @@ -18,11 +18,35 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Portions of this file + * Copyright (C) 2007-2009 ARM Limited + * + * This software is provided 'as-is', without any express or implied + * warranties including the implied warranties of satisfactory quality, + * fitness for purpose or non infringement. In no event will ARM be + * liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use, copy and modify this software for + * any purpose, and to redistribute the software, subject to the following + * restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. */ #include <linux/linkage.h> #include <linux/init.h> #include <asm/vfpmacros.h> +#include "nvrm_drf.h" +#include "nvmacro.h" + +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) #include "ap20/arflow_ctlr.h" #include "ap20/arclk_rst.h" #include "ap20/arevp.h" @@ -30,199 +54,184 @@ #include "ap20/aremc.h" #include "ap20/arapb_misc.h" #include "ap20/arpl310.h" -#include "nvrm_drf.h" -#if defined(CONFIG_ARCH_TEGRA_2x_SOC) -#define EMC_PA_BASE 0x7000f400 -#define PMC_PA_BASE 0x7000e400 -#define FLOW_PA_BASE 0x60007000 -#define TIMERUS_PA_BASE 0x60005010 -#define CLK_RST_PA_BASE 0x60006000 -#define EVP_PA_BASE 0x6000f000 -#define CSITE_PA_BASE 0x70040000 -#define APB_MISC_BASE 0x70000000 -#define RTC_PA_BASE 0x7000e000 -#define TEMP_RESET_VECTOR 8 -#define TEMP_SCLK_BURST_POLICY 16 -#define TEMP_CCLK_BURST_POLICY 20 -#define TEMP_PLLX_BASE 12 -#define CSITE_CPUDBG0_LAR_0 0x10fb0 -#define CSITE_CPUDBG1_LAR_0 0x12fb0 -#define TEMP_AREA_SIZE 32 -#define DEBUG_FORCE_RTC_WAKEUP_SEC 0 +#define TEMP_RESET_VECTOR 8 +#define TEMP_PLLX_BASE 12 +#define TEMP_SCLK_BURST_POLICY 16 +#define TEMP_CCLK_BURST_POLICY 20 +#define TEMP_AREA_SIZE 32 +#define CSITE_CPUDBG0_LAR_0 0x10fb0 +#define CSITE_CPUDBG1_LAR_0 0x12fb0 #else #error "Unrecognized Tegra SoC Family" #endif +#define DEBUG_FORCE_RTC_WAKEUP_SEC 0 + +#define EMC_PA_BASE 0x7000f400 +#define PMC_PA_BASE 0x7000e400 +#define FLOW_PA_BASE 0x60007000 +#define TIMERUS_PA_BASE 0x60005010 +#define CLK_RST_PA_BASE 0x60006000 +#define EVP_PA_BASE 0x6000f000 +#define CSITE_PA_BASE 0x70040000 +#define APB_MISC_BASE 0x70000000 +#define RTC_PA_BASE 0x7000e000 + //r0 - Power state //r1 - proc_id ENTRY(enter_power_state) //We should be in SVC mode //with IRQs turned off - mrs r2, CPSR + mrs r2, CPSR stmfd sp!, {r0-r12, lr} stmfd sp!, {r0} - cmp r1, #0 - bne save_arm_state + cmp r1, #0 + bne save_arm_state //Wait for everyone else to spin down wait_for_other_cores: stmfd sp!, {r1} - bl check_for_cpu1_reset + bl check_for_cpu1_reset ldmfd sp!, {r1} - cmp r0, #0 - beq finish_power_state + cmp r0, #0 + beq finish_power_state //Save the local timers stmfd sp!, {r1} - bl save_local_timers + bl save_local_timers ldmfd sp!, {r1} - //Ok we can save state for core0 now -save_arm_state: + //Ok we can save state for core0 now +save_arm_state: //Get the context save pointer for the core - ldr r0, =g_contextSaveVA - ldr r0, [r0] - mov r2, #0x800 - //r0 = r0 + r1 * r2 - smlabb r0, r1, r2, r0 + ldr r0, =g_contextSaveVA + ldr r0, [r0] + mov r2, #0x800 + smlabb r0, r1, r2, r0 // r0 = r0 + r1 * r2 - ldr r1, =g_ArmPerif - ldr r1, [r1] + ldr r1, =g_ArmPerif + ldr r1, [r1] //We need r0 = virtual context save //We need R1 = SCU VA - b ArmCortexA9Save + b ArmCortexA9Save ArmCortexA9Saved: //All cores but core 0 must be reset - mrc p15, 0, r2, c0, c0, 5 - ands r2, r2, #0x3 - bne reset_slave + mrc p15, 0, r2, c0, c0, 5 + ands r2, r2, #0x3 + bne reset_slave //Check which power state we want to enter ldmfd sp!, {r0} //Is it LP2? - cmp r0, #0 + cmp r0, #2 ldreq r2, =g_enterLP2PA ldreq r2, [r2] - beq transition_to_state + beq transition_to_state - ldr r4, =g_pIRAM - ldr r4, [r4] + ldr r4, =g_pIRAM + ldr r4, [r4] //Is it LP1? - cmp r0, #1 + cmp r0, #1 ldreq r5, =exit_lp1_end ldreq r6, =enter_lp1 - beq copy_to_iram + beq copy_to_iram - //Is it LP0? - cmp r0, #2 - ldr r5, =enter_lp0_end - ldr r6, =enter_lp0 + //It is LP0. + ldr r5, =enter_lp0_end + ldr r6, =enter_lp0 //For LP0, the AVP stores its continuation address at the first //location in IRAM. Before we overwrite IRAM with the LP0 entry //code, copy the AVP continuation and store it in the scratch //register dedicated for this purposed. - //R1 = *g_pIRAM - ldr r1, [r4] - //R3 = &(g_pPMC) - ldr r3, =g_pPMC - //R3 = g_pPMC - ldr r3, [r3] - //Store in scratch39 - str r1, [r3, #APBDEV_PMC_SCRATCH39_0] + ldr r1, [r4] //R1 = *g_pIRAM + ldr r3, =g_pPMC //R3 = &(g_pPMC) + ldr r3, [r3] //R3 = g_pPMC + str r1, [r3, #APBDEV_PMC_SCRATCH39_0] //Flush L2 rams for LP0 - ldr r1, =g_pPL310 - ldr r1, [r1] + ldr r1, =g_pPL310 + ldr r1, [r1] - ldr r2, [r1, #PL310_CONTROL_0] + ldr r2, [r1, #PL310_CONTROL_0] ands r2, r2, #0x1 - beq copy_to_iram + beq copy_to_iram //Clear L2 restoration ptr - ldr r3, =g_contextSaveVA - ldr r3, [r3] + ldr r3, =g_contextSaveVA + ldr r3, [r3] - mov r2, #0 - str r2, [r3, #0x30] + mov r2, #0 + str r2, [r3, #0x30] dsb //Lock all ways - add r10, r1, #PL310_DATA_LOCKDOWN0_0 - //16 lockdown registers => 64 bytes register space - add r2, r10, #64 - //r3 = 0xff = ALL_WAYS - mov r3, #0xff + add r10, r1, #PL310_DATA_LOCKDOWN0_0 + add r2, r10, #64 //16 lockdown registers => 64 bytes register space + mov r3, #0xff //r3 = 0xff = ALL_WAYS lock_all_ways: - str r3, [r10] + str r3, [r10] add r10, r10, #4 - cmp r10, r2 - bne lock_all_ways + cmp r10, r2 + bne lock_all_ways //Clean all ways - mov r2, #0xff - str r2, [r1, #PL310_CLEAN_BY_WAY_0] + mov r2, #0xff + str r2, [r1, #PL310_CLEAN_BY_WAY_0] wait_for_l2_flush: - ldr r2, [r1, #PL310_CLEAN_BY_WAY_0] - cmp r2, #0 - bne wait_for_l2_flush + ldr r2, [r1, #PL310_CLEAN_BY_WAY_0] + cmp r2, #0 + bne wait_for_l2_flush //Issue a cache sync - mov r2, #0 - str r2, [r1, #PL310_CACHE_SYNC_0] + mov r2, #0 + str r2, [r1, #PL310_CACHE_SYNC_0] dsb //Unlock all ways - add r10, r1, #PL310_DATA_LOCKDOWN0_0 - //16 lockdown registers => 64 bytes register space - add r2, r10, #64 - //r3 = 0 = BITMAP_NO_WAYS - mov r3, #0 + add r10, r1, #PL310_DATA_LOCKDOWN0_0 + add r2, r10, #64 //16 lockdown registers => 64 bytes register space + mov r3, #0 //r3 = 0 = BITMAP_NO_WAYS unlock_all_ways: - str r3, [r10] - add r10, r10, #4 + str r3, [r10] + add r10, r10, #4 - cmp r10, r2 - bne unlock_all_ways + cmp r10, r2 + bne unlock_all_ways copy_to_iram: - //Copy the enter_lp0 function to IRAM using 8x4 block moves. + //Copy the low power core to IRAM using 8x4 block moves. //It doesn't matter if we copy a few extra words. //IRAM has already been safely saved by the AVP at this point //R4 = destination address to copy code to //R5 = size of code to copy in bytes //R6 = source address to copy code from - //r2 is the source address - cpy r2, r6 - //r3 is the size to copy - sub r3, r5, r6 + cpy r2, r6 //r2 is the source address + sub r3, r5, r6 //r3 is the size to copy copy_code: - //Load source - ldmia r2!, {r5-r12} - //Store at destination - stmia r4!, {r5-r12} - //Decrement count - subs r3, r3, #32 - bgt copy_code + ldmia r2!, {r5-r12} //Load source + stmia r4!, {r5-r12} //Store at destination + subs r3, r3, #32 //Decrement count + bgt copy_code //Get the physical address of IRAM //This is where we will jump to start LP0 - ldr r2, =g_IramPA - ldr r2, [r2] + ldr r2, =g_IramPA + ldr r2, [r2] //We are the master. We should //turn of MMUs and caches. @@ -230,145 +239,132 @@ copy_code: transition_to_state: //Turn off caches and MMU - mrc p15, 0, r3, c1, c0, 0 - bic r3, r3, #(1<<12) //I-Cache - bic r3, r3, #(1<<11) //Branch-pred - bic r3, r3, #(1<<2) //D-Cache - bic r3, r3, #(1<<0) //MMU - - ldr r0, =g_modifiedPlls - ldr r0, [r0] - ldr r1, =g_wakeupCcbp - ldr r1, [r1] - - mov r10, #0 - mcr p15, 0, r10, c8, c7, 0 // invalidate TLB + mrc p15, 0, r3, c1, c0, 0 + bic r3, r3, #(1<<12) //I-Cache + bic r3, r3, #(1<<11) //Branch-pred + bic r3, r3, #(1<<2) //D-Cache + bic r3, r3, #(1<<0) //MMU + + ldr r0, =g_modifiedPlls + ldr r0, [r0] + ldr r1, =g_wakeupCcbp + ldr r1, [r1] + + mov r10, #0 + mcr p15, 0, r10, c8, c7, 0 // invalidate TLB dsb .align 5 + //The following two instructions MUST be in the same cache line //Disable L1 caches and MMU - mcr p15, 0, r3, c1, c0, 0 + mcr p15, 0, r3, c1, c0, 0 //Jump to the appropriate LPx function - //bl enter_lp2 - bx r2 + bx r2 reset_slave: //Reset the slave cores - mov r0, #1 - mov r1, #1 - bl reset_cpu - b . + mov r0, #1 + mov r1, #1 + bl reset_cpu + b . finish_power_state: ldmfd sp!, {r0} ldmfd sp!, {r0-r12, lr} - bx lr -.ltorg + bx lr + .ltorg ENDPROC(EnterPowerState) ENTRY(enter_lp2) - ldr r5, =PMC_PA_BASE //R5 = PMC PA base address - ldr r6, =FLOW_PA_BASE //R6 = FLOW PA base address - ldr r7, =TIMERUS_PA_BASE //R7 = TIMERUS PA base address - ldr r8, =CLK_RST_PA_BASE //R8 = CLK PA base address - ldr r9, =EVP_PA_BASE //R9 = EVP PA base address + MOV32 r5, PMC_PA_BASE //R5 = PMC PA base address + MOV32 r6, FLOW_PA_BASE //R6 = FLOW PA base address + MOV32 r7, TIMERUS_PA_BASE //R7 = TIMERUS PA base address + MOV32 r8, CLK_RST_PA_BASE //R8 = CLK PA base address + MOV32 r9, EVP_PA_BASE //R9 = EVP PA base address //This funny little instruction obtains a piece of memory //that is relative to the PC. We can't use literals - //as the MMU has been turned off. - add r12, pc, #TempStoreArea-(.+8) + //as the MMU has been turned off. + add r12, pc, #TempStoreArea-(.+8) //Save the input paramters in temp region stmia r12, {r0-r1} //Save old reset vector - ldr r2, [r9, #EVP_CPU_RESET_VECTOR_0] - str r2, [r12, #TEMP_RESET_VECTOR] + ldr r2, [r9, #EVP_CPU_RESET_VECTOR_0] + str r2, [r12, #TEMP_RESET_VECTOR] //Save pllx base - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] - str r2, [r12, #TEMP_PLLX_BASE] + ldr r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] + str r2, [r12, #TEMP_PLLX_BASE] //Store WB2 entry point in reset - add r2, pc, #exit_lp2-(.+8) - str r2, [r9, #EVP_CPU_RESET_VECTOR_0] + add r2, pc, #exit_lp2-(.+8) + str r2, [r9, #EVP_CPU_RESET_VECTOR_0] //Make sure SIDE_EFFECT_LP0 is not set - ldr r2, [r5, #APBDEV_PMC_CNTRL_0] - //Unset the SIDE_EFFECT bit - bic r2, r2, #(1<<14) - str r2, [r5, #APBDEV_PMC_CNTRL_0] + ldr r2, [r5, #APBDEV_PMC_CNTRL_0] + bic r2, r2, #(1<<14) //Unset the SIDE_EFFECT bit + str r2, [r5, #APBDEV_PMC_CNTRL_0] //Powergate the cpu by setting the ENABLE bit - ldr r2, [r6, #FLOW_CTLR_CPU_CSR_0] - orr r2, r2, #(1<<0) - str r2, [r6, #FLOW_CTLR_CPU_CSR_0] + ldr r2, [r6, #FLOW_CTLR_CPU_CSR_0] + orr r2, r2, #(1<<0) + str r2, [r6, #FLOW_CTLR_CPU_CSR_0] //Put the CPU on the desired clock source for wakeup, // wait 2us for switch to complete, and disable PLLX - str r1, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] - ldr r11, [r7] + str r1, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] + ldr r11, [r7] cclk_delay: - ldr r2, [r7] - sub r2, r2, r11 - cmp r2, #2 - ble cclk_delay - - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] - bic r2, r2, #(1<<30) //Clear PllX ENABLE - str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] + ldr r2, [r7] + sub r2, r2, r11 + cmp r2, #2 + ble cclk_delay + + ldr r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] + bic r2, r2, #(1<<30) //Clear PllX ENABLE + str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] dmb //Get the microsecond count before LP2 - ldr r2, [r7] - str r2, [r5, #APBDEV_PMC_SCRATCH38_0] + ldr r2, [r7] + str r2, [r5, #APBDEV_PMC_SCRATCH38_0] //Finally, halt the CPU - mov r2, #0 - orr r2, r2, #(4<<29) //STOP_UNTIL_IRQ - orr r2, r2, #(1<<10) //IRQ_0 event - orr r2, r2, #(1<<8) //FIQ_0 event - str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] + mov r2, #0 + orr r2, r2, #(4<<29) //STOP_UNTIL_IRQ + orr r2, r2, #(1<<10) //IRQ_0 event + orr r2, r2, #(1<<8) //FIQ_0 event + str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] DoWFI: - dsb + dsb wfi - b DoWFI + b DoWFI ENDPROC(enter_lp2) ENTRY(exit_lp2) - //R5 = PMC PA base address - add r5, pc, #lp_literals-(.+4) - ldr r5, [r5] - //R6 = FLOW PA base address - add r6, pc, #lp_literals-(.+0) - ldr r6, [r6] - //R7 = TIMERUS PA base address - add r7, pc, #lp_literals-(.-4) - ldr r7, [r7] - //R8 = CLK PA base address - add r8, pc, #lp_literals-(.-8) - ldr r8, [r8] - //R9 = EVP PA base address - add r9, pc, #lp_literals-(.-12) - ldr r9, [r9] - //R10 = CSITE PA base address - add r10, pc, #lp_literals-(.-12) - ldr r10, [r10] + MOV32 r5, PMC_PA_BASE //R5 = PMC PA base address + MOV32 r6, FLOW_PA_BASE //R6 = FLOW PA base address + MOV32 r7, TIMERUS_PA_BASE //R7 = TIMERUS PA base address + MOV32 r8, CLK_RST_PA_BASE //R8 = CLK PA base address + MOV32 r9, EVP_PA_BASE //R9 = EVP PA base address + MOV32 r10, CSITE_PA_BASE //R10 = CSITE PA base address //Check which core we are by checking the MPIDR - mrc p15, 0, r2, c0, c0, 5 + mrc p15, 0, r2, c0, c0, 5 ands r2, r2, #0x3 - bne skip_cpu0_restore + bne skip_cpu0_restore //This funny little instruction obtains a piece of memory //that is relative to the PC. We can't use literals //as the MMU has been turned off. - add r12, pc, #TempStoreArea-(.+8) + add r12, pc, #TempStoreArea-(.+8) //Get the current microsecond count - ldr r11, [r7, #0] + ldr r11, [r7, #0] //NOTE: Any low-power state that cuts power to the CPU power island //but not to the island containing the APB bus on which @@ -387,382 +383,347 @@ ENTRY(exit_lp2) //functional until after CPU state restoration. //Assert CoreSight reset. - ldr r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] - orr r0, r0, #(1<<9) - str r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] + ldr r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] + orr r0, r0, #(1<<9) + str r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] //Hold CoreSight reset for 2us. - add r1, r11, #2 + add r1, r11, #2 reset_poll: - ldr r2, [r7, #0] - cmp r2, r1 - ble reset_poll + ldr r2, [r7, #0] + cmp r2, r1 + ble reset_poll //De-assert CoreSight reset. - bic r0, r0, #(1<<9) - str r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] - - //Unlock debugger access by writing special "CSACCESS" - add r0, pc, #lp_literals-(.-20) - ldr r0, [r0] - add r1, pc, #lp_literals-(.-24) //R1 = CPU0 lock offset - ldr r1, [r1] - add r2, pc, #lp_literals-(.-28) //R2 = CPU1 lock offset - ldr r2, [r2] - str r0, [r10, r1] //Unlock CPU0 - str r0, [r10, r2] //Unlock CPU1 + bic r0, r0, #(1<<9) + str r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] + + //Unlock debugger access by writing special "C5ACCE55" unlock code + MOV32 r0, 0xC5ACCE55 + MOV32 r1, CSITE_CPUDBG0_LAR_0 + MOV32 r2, CSITE_CPUDBG1_LAR_0 + str r0, [r10, r1] //Unlock CPU0 + str r0, [r10, r2] //Unlock CPU1 //Make sure we no longer powergate the CPU island when halting. - ldr r1, [r6, #FLOW_CTLR_CPU_CSR_0] - bic r1, r1, #(1<<0) - str r1, [r6, #FLOW_CTLR_CPU_CSR_0] + ldr r1, [r6, #FLOW_CTLR_CPU_CSR_0] + bic r1, r1, #(1<<0) + str r1, [r6, #FLOW_CTLR_CPU_CSR_0] //Restore the input parameters passed to enter_lp2 - ldm r12, {r0-r1} + ldm r12, {r0-r1} //Put the CPU on the desired clock source for wakeup - str r1, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] + str r1, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] //Enable PLL-X and restore the values - ldr r2, [r12, #TEMP_PLLX_BASE] - mov r3, #(1<<30) //PllX ENABLE - orr r2, r2, r3 - str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] + ldr r2, [r12, #TEMP_PLLX_BASE] + mov r3, #(1<<30) //PllX ENABLE + orr r2, r2, r3 + str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] //Restore the reset vector target. - ldr r1, [r12, #TEMP_RESET_VECTOR] - str r1, [r9, #EVP_CPU_RESET_VECTOR_0] + ldr r1, [r12, #TEMP_RESET_VECTOR] + str r1, [r9, #EVP_CPU_RESET_VECTOR_0] skip_cpu0_restore: - mrc p15, 0, r2, c0, c0, 5 + mrc p15, 0, r2, c0, c0, 5 ands r2, r2, #0x3 //Write to reset vector to allow platsmp to continue - str r2, [r9, #EVP_CPU_RESET_VECTOR_0] + str r2, [r9, #EVP_CPU_RESET_VECTOR_0] //Only get the timer for CPU0 - bne skip_lp2_time + bne skip_lp2_time //Get the microsecond count after LP2 - str r11, [r5, #APBDEV_PMC_SCRATCH39_0] + str r11, [r5, #APBDEV_PMC_SCRATCH39_0] skip_lp2_time: //Set lr to the resume function - ldr lr, [r5, #APBDEV_PMC_SCRATCH1_0] - bx lr + ldr lr, [r5, #APBDEV_PMC_SCRATCH1_0] + bx lr TempStoreArea: //Create some empty space. We can't use literals //after the MMU has been turned off, so we need //some PC relative scratch space - .space TEMP_AREA_SIZE + .space TEMP_AREA_SIZE ENDPROC(exit_lp2) ENTRY(enter_lp1) - add r4, pc, #lp_literals-(.+8) - ldr r4, [r4] - add r5, pc, #lp_literals-(.+4) - ldr r5, [r5] - add r6, pc, #lp_literals-(.+0) - ldr r6, [r6] - add r7, pc, #lp_literals-(.-4) - ldr r7, [r7] - add r8, pc, #lp_literals-(.-8) - ldr r8, [r8] - add r9, pc, #lp_literals-(.-12) - ldr r9, [r9] - - add r12, pc, #TemporaryStore-(.+8) + MOV32 r4, EMC_PA_BASE //R4 = EMC PA base address + MOV32 r5, PMC_PA_BASE //R5 = PMC PA base address + MOV32 r6, FLOW_PA_BASE //R6 = FLOW PA base address + MOV32 r7, TIMERUS_PA_BASE //R7 = TIMERUS PA base address + MOV32 r8, CLK_RST_PA_BASE //R8 = CLK PA base address + MOV32 r9, EVP_PA_BASE //R9 = EVP PA base address + + add r12, pc, #TemporaryStore-(.+8) stmia r12!, {r0, r1} - ldr r0, [r9, #EVP_CPU_RESET_VECTOR_0] - ldr r1, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] - ldr r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] - ldr r3, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] + ldr r0, [r9, #EVP_CPU_RESET_VECTOR_0] + ldr r1, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] + ldr r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] + ldr r3, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] stmia r12, {r0 - r3} - sub r12, r12, #8 + sub r12, r12, #8 - add r2, pc, #exit_lp1-(.+8) - str r2, [r9, #EVP_CPU_RESET_VECTOR_0] + add r2, pc, #exit_lp1-(.+8) + str r2, [r9, #EVP_CPU_RESET_VECTOR_0] dmb //Stall incoming EMC read/write transactions - mov r2, #3 - str r2, [r4, #0x2B0] + mov r2, #3 + str r2, [r4, #0x2B0] //Poll till EMC is idle is_idle1: - ldr r2, [r4, #0x2B4] - tst r2, #4 - beq is_idle1 + ldr r2, [r4, #0x2B4] + tst r2, #4 + beq is_idle1 //Put SDRAM into self refresh - mov r2, #1 - str r2, [r4, #0xE0] - ldr r2, [r4, #0x10] + mov r2, #1 + str r2, [r4, #0xE0] + ldr r2, [r4, #0x10] ands r2, r2, #0x3000000 moveq r0, #0x100 movne r0, #0x300 //Poll until all devices are in self refresh is_self1: - ldr r2, [r4, #0x2B4] - and r2, r2, r0 - teq r0, r2 - bne is_self1 + ldr r2, [r4, #0x2B4] + and r2, r2, r0 + teq r0, r2 + bne is_self1 // Save SDRAM pad configuration, replace it with min power settings // (every lp1 entry loads settings, hence we can overwrite them) - add r0, pc, #lp1_ddrpad_addr-(.+8) - add r1, pc, #lp1_ddrpad_setting-(.+8) + add r0, pc, #lp1_ddrpad_addr-(.+8) + add r1, pc, #lp1_ddrpad_setting-(.+8) pad_susp_next: - ldr r3, [r0], #4 - cmp r3, #0 - beq pad_susp_end - ldr r11, [r3] - ldr r2, [r1] - str r2, [r3] - str r11, [r1], #4 - b pad_susp_next + ldr r3, [r0], #4 + cmp r3, #0 + beq pad_susp_end + ldr r11, [r3] + ldr r2, [r1] + str r2, [r3] + str r11, [r1], #4 + b pad_susp_next pad_susp_end: //Make sure SIDE_EFFECT_LP0 is not set - ldr r2, [r5, #APBDEV_PMC_CNTRL_0] + ldr r2, [r5, #APBDEV_PMC_CNTRL_0] //Unset the SIDE_EFFECT bit - bic r2, r2, #(1<<14) - str r2, [r5, #APBDEV_PMC_CNTRL_0] + bic r2, r2, #(1<<14) + str r2, [r5, #APBDEV_PMC_CNTRL_0] //Switch CPU clocks to CLKM - mov r2, #0 - orr r2, r2, #(1<<28) - str r2, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] + mov r2, #0 + orr r2, r2, #(1<<28) + str r2, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] //Switch the system clock to CLKM - mov r2, #0 - orr r2, r2, #(1<<28) - str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] + mov r2, #0 + orr r2, r2, #(1<<28) + str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] //2 uSec delay for System Clock Switching - mov r2, #0x2 - orr r2, r2, #(1<<25) //STOP_UNTIL_Event - str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] + mov r2, #0x2 + orr r2, r2, #(1<<25) //STOP_UNTIL_Event + str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] clk_delay: - ldr r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] - tst r2, #0xFF - bne clk_delay + ldr r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] + tst r2, #0xFF + bne clk_delay //Powergate the cpu by setting the ENABLE bit - ldr r2, [r6, #FLOW_CTLR_CPU_CSR_0] - orr r2, r2, #(1<<0) - str r2, [r6, #FLOW_CTLR_CPU_CSR_0] + ldr r2, [r6, #FLOW_CTLR_CPU_CSR_0] + orr r2, r2, #(1<<0) + str r2, [r6, #FLOW_CTLR_CPU_CSR_0] //Switch system clocks to 32Khz - mov r2, #6 - orr r2, r2, #(1<<28) - mov r3, #0 - str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] - str r3, [r8, #CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER_0] + mov r2, #6 + orr r2, r2, #(1<<28) + mov r3, #0 + str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] + str r3, [r8, #CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER_0] //Turn off pll-m - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] - bic r2, r2, #1, 2 - str r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] + ldr r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] + bic r2, r2, #1, 2 + str r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] //Turn off pll-p - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] - bic r2, r2, #1, 2 - str r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] + ldr r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] + bic r2, r2, #1, 2 + str r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] //Get the microsecond count before LP1 - ldr r2, [r7] - str r2, [r5, #APBDEV_PMC_SCRATCH38_0] + ldr r2, [r7] + str r2, [r5, #APBDEV_PMC_SCRATCH38_0] //Finally, halt the CPU - mov r2, #0 - orr r2, r2, #(4<<29) //STOP_UNTIL_IRQ - orr r2, r2, #(1<<10) //IRQ_0 event - orr r2, r2, #(1<<8) //FIQ_0 event - str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] + mov r2, #0 + orr r2, r2, #(4<<29) //STOP_UNTIL_IRQ + orr r2, r2, #(1<<10) //IRQ_0 event + orr r2, r2, #(1<<8) //FIQ_0 event + str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] do_wfi1: dsb wfi - b do_wfi1 + b do_wfi1 enter_lp1_end: .ltorg ENDPROC(enter_lp1) ENTRY(exit_lp1) - //R4 = EMC_PA_BASE - add r4, pc, #lp_literals-(.+8) - ldr r4, [r4] - //R5 = PMC_PA_BASE - add r5, pc, #lp_literals-(.+4) - ldr r5, [r5] - //R6 = FLOW_PA_BASE - add r6, pc, #lp_literals-(.+0) - ldr r6, [r6] - //R7 = TIMERUS_PA_BASE - add r7, pc, #lp_literals-(.-4) - ldr r7, [r7] - //R8 = CLK_RST_PA_BASE - add r8, pc, #lp_literals-(.-8) - ldr r8, [r8] - //R9 = EVP_PA_BASE - add r9, pc, #lp_literals-(.-12) - ldr r9, [r9] - //R10 = CSITE_PA_BASE - add r10, pc, #lp_literals-(.-16) - ldr r10, [r10] + MOV32 r4, EMC_PA_BASE //R4 = EMC PA base address + MOV32 r5, PMC_PA_BASE //R5 = PMC PA base address + MOV32 r6, FLOW_PA_BASE //R6 = FLOW PA base address + MOV32 r7, TIMERUS_PA_BASE //R7 = TIMERUS PA base address + MOV32 r8, CLK_RST_PA_BASE //R8 = CLK PA base address + MOV32 r9, EVP_PA_BASE //R9 = EVP PA base address + MOV32 r10, CSITE_PA_BASE //R10 = CSITE PA base address //R12 = Temporary iram store - add r12, pc, #TemporaryStore-(.+8) + add r12, pc, #TemporaryStore-(.+8) //Read the microsecond counter - ldr r11, [r7] + ldr r11, [r7] //Assert CoreSight reset. - ldr r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] - orr r0, r0, #(1<<9) - str r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] + ldr r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] + orr r0, r0, #(1<<9) + str r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] //Hold CoreSight reset for 2us. - add r1, r11, #2 + add r1, r11, #2 reset_poll1: - ldr r2, [r7, #0] - cmp r2, r1 - ble reset_poll1 + ldr r2, [r7, #0] + cmp r2, r1 + ble reset_poll1 //De-assert CoreSight reset. - bic r0, r0, #(1<<9) - str r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] - - //Unlock debugger access by writing special "CSACCESS" - add r0, pc, #lp_literals-(.-20) - ldr r0, [r0] - add r1, pc, #lp_literals-(.-24) //R1 = CPU0 lock offset - ldr r1, [r1] - add r2, pc, #lp_literals-(.-28) //R2 = CPU1 lock offset - ldr r2, [r2] - str r0, [r10, r1] //Unlock CPU0 - str r0, [r10, r2] //Unlock CPU1 + bic r0, r0, #(1<<9) + str r0, [r8, #CLK_RST_CONTROLLER_RST_DEVICES_U_0] + + //Unlock debugger access by writing special "C5ACCE55" unlock code + MOV32 r0, 0xC5ACCE55 + MOV32 r1, CSITE_CPUDBG0_LAR_0 + MOV32 r2, CSITE_CPUDBG1_LAR_0 + str r0, [r10, r1] //Unlock CPU0 + str r0, [r10, r2] //Unlock CPU1 //Switch the system to CLKM - mov r2, #0 - orr r2, r2, #(1<<28) - str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] + mov r2, #0 + orr r2, r2, #(1<<28) + str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] //Enable PLL-M - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] - mov r3, #(1<<30) //PllM ENABLE - tst r2, r3 + ldr r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] + mov r3, #(1<<30) //PllM ENABLE + tst r2, r3 orreq r2, r2, r3 streq r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] //Enable PLL-P - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] - mov r3, #(1<<30) //PllP ENABLE - tst r2, r3 + ldr r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] + mov r3, #(1<<30) //PllP ENABLE + tst r2, r3 orreq r2, r2, r3 streq r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] //Enable PLL-X with restored values - ldr r2, [r12, #TEMP_PLLX_BASE] - mov r3, #(1<<30) //PllX ENABLE - orr r2, r2, r3 - str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] + ldr r2, [r12, #TEMP_PLLX_BASE] + mov r3, #(1<<30) //PllX ENABLE + orr r2, r2, r3 + str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] //Configure CPU island to not be power gated - ldr r2, [r6, #8] - bic r2, r2, #1 - str r2, [r6, #8] + ldr r2, [r6, #8] + bic r2, r2, #1 + str r2, [r6, #8] //Restore the reset vector target - ldr r2, [r12, #TEMP_RESET_VECTOR] - str r2, [r9, #EVP_CPU_RESET_VECTOR_0] + ldr r2, [r12, #TEMP_RESET_VECTOR] + str r2, [r9, #EVP_CPU_RESET_VECTOR_0] // Restore SDRAM pad configuration - add r0, pc, #lp1_ddrpad_addr-(.+8) - add r1, pc, #lp1_ddrpad_setting-(.+8) + add r0, pc, #lp1_ddrpad_addr-(.+8) + add r1, pc, #lp1_ddrpad_setting-(.+8) pad_wake_next: - ldr r3, [r0], #4 - cmp r3, #0 - beq pad_wake_end - ldr r2, [r1], #4 - str r2, [r3] - b pad_wake_next -pad_wake_end: // 4us delay after restoration - covered by PLL delay + ldr r3, [r0], #4 + cmp r3, #0 + beq pad_wake_end + ldr r2, [r1], #4 + str r2, [r3] + b pad_wake_next +pad_wake_end: // 4us delay after restoration - covered by PLL delay //Explicit delay of 255 uSec for pll stabilization - mov r2, #0xFF - orr r2, r2, #(1<<25) //STOP_UNTIL_Event - str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] + mov r2, #0xFF + orr r2, r2, #(1<<25) //STOP_UNTIL_Event + str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] pll_delay: - ldr r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] - tst r2, #0xFF - bne pll_delay + ldr r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] + tst r2, #0xFF + bne pll_delay //Restore the system and CPU burst, csite, clksrc registers - ldr r1, [r12, #TEMP_SCLK_BURST_POLICY] - ldr r2, [r12, #TEMP_CCLK_BURST_POLICY] - str r1, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] - str r2, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] + ldr r1, [r12, #TEMP_SCLK_BURST_POLICY] + ldr r2, [r12, #TEMP_CCLK_BURST_POLICY] + str r1, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] + str r2, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] //Take the SDRAM out of self-refresh //Make sure that the sdram is not gated - ldr r1, [r4, #EMC_CFG_0] - bic r1, r1, #2, 2 - str r1, [r4, #EMC_CFG_0] + ldr r1, [r4, #EMC_CFG_0] + bic r1, r1, #2, 2 + str r1, [r4, #EMC_CFG_0] //Take the sdram out of self refresh - mov r1, #0 - str r1, [r4, #EMC_SELF_REF_0] + mov r1, #0 + str r1, [r4, #EMC_SELF_REF_0] //Issue a couple of nops - mov r1, #1 - str r1, [r4, #EMC_NOP_0] - str r1, [r4, #EMC_NOP_0] + mov r1, #1 + str r1, [r4, #EMC_NOP_0] + str r1, [r4, #EMC_NOP_0] //Issue a refresh command - mov r1, #1 - str r1, [r4, #EMC_REF_0] + mov r1, #1 + str r1, [r4, #EMC_REF_0] //Confirm that all chips have exited self-refresh - ldr r1, [r4, #EMC_ADR_CFG_0] + ldr r1, [r4, #EMC_ADR_CFG_0] ands r1, r1, #3, 8 moveq r0, #1, 24 movne r0, #3, 24 //Poll until all chips have exited self-refresh is_auto: - ldr r1, [r4, #EMC_EMC_STATUS_0] - and r2, r1, r0 - cmp r2, #0 - bne is_auto + ldr r1, [r4, #EMC_EMC_STATUS_0] + and r2, r1, r0 + cmp r2, #0 + bne is_auto //Un-stall incoming reads/writes - mov r1, #0 - str r1, [r4, #EMC_REQ_CTRL_0] + mov r1, #0 + str r1, [r4, #EMC_REQ_CTRL_0] //Store the LP1 exit time and restore return addr - ldr lr, [r5, #APBDEV_PMC_SCRATCH1_0] - str r11, [r5, #APBDEV_PMC_SCRATCH39_0] - bx lr -lp_literals: - .word EMC_PA_BASE - .word PMC_PA_BASE - .word FLOW_PA_BASE - .word TIMERUS_PA_BASE - .word CLK_RST_PA_BASE - .word EVP_PA_BASE - .word CSITE_PA_BASE - .word 0xC5ACCE55 - .word CSITE_CPUDBG0_LAR_0 - .word CSITE_CPUDBG1_LAR_0 + ldr lr, [r5, #APBDEV_PMC_SCRATCH1_0] + str r11, [r5, #APBDEV_PMC_SCRATCH39_0] + bx lr + TemporaryStore: //Create some empty space. We can't use literals //after the MMU has been turned off, so we need //some PC relative scratch space .space TEMP_AREA_SIZE + lp1_ddrpad_addr: .word ((APB_MISC_BASE)+(APB_MISC_GP_XM2CFGCPADCTRL_0)) .word ((APB_MISC_BASE)+(APB_MISC_GP_XM2CFGDPADCTRL_0)) @@ -784,104 +745,87 @@ exit_lp1_end: ENDPROC(exit_lp1) ENTRY(enter_lp0) - //R4 = EMC_PA_BASE - add r4, pc, #lp0_literals-(.+8) //EMC base - ldr r4, [r4] - //R5 = PMC_PA_BASE - add r5, pc, #lp0_literals-(.+4) //PMC base - ldr r5, [r5] - //R6 = FLOW_PA_BASE - add r6, pc, #lp0_literals-(.+0) //FLOW base - ldr r6, [r6] - //R7 = TIMERUS_PA_BASE - add r7, pc, #lp0_literals-(.-4) //TIMERUS base - ldr r7, [r7] - //R8 = RTC_PA_BASE - add r8, pc, #lp0_literals-(.-8) //RTC base - ldr r8, [r8] + MOV32 r4, EMC_PA_BASE //R4 = EMC PA base address + MOV32 r5, PMC_PA_BASE //R5 = PMC PA base address + MOV32 r6, FLOW_PA_BASE //R6 = FLOW PA base address + MOV32 r7, TIMERUS_PA_BASE //R7 = TIMERUS PA base address //Flush the write buffer dmb //Stall incoming EMC read/write transactions - mov r2, #3 - str r2, [r4, #0x2B0] + mov r2, #3 + str r2, [r4, #0x2B0] //Poll till EMC is idle is_idle: - ldr r2, [r4, #0x2B4] - tst r2, #4 - beq is_idle + ldr r2, [r4, #0x2B4] + tst r2, #4 + beq is_idle //Put SDRAM into self refresh - mov r2, #1 - str r2, [r4, #0xE0] - ldr r2, [r4, #0x10] + mov r2, #1 + str r2, [r4, #0xE0] + ldr r2, [r4, #0x10] ands r2, r2, #0x3000000 moveq r0, #0x100 movne r0, #0x300 //Poll until all devices are in self refresh is_self: - ldr r2, [r4, #0x2B4] - and r2, r2, r0 - teq r0, r2 - bne is_self - mov r2, #1 - str r2, [r5, #0x20] + ldr r2, [r4, #0x2B4] + and r2, r2, r0 + teq r0, r2 + bne is_self + mov r2, #1 + str r2, [r5, #0x20] //Set SIDE_EFFECT_LP0 - ldr r2, [r5, #APBDEV_PMC_CNTRL_0] - orr r2, r2, #0x4000 - str r2, [r5, #APBDEV_PMC_CNTRL_0] + ldr r2, [r5, #APBDEV_PMC_CNTRL_0] + orr r2, r2, #0x4000 + str r2, [r5, #APBDEV_PMC_CNTRL_0] //Set CPU island to power gate when halted - ldr r2, [r6, #FLOW_CTLR_CPU_CSR_0] - orr r2, r2, #1 - str r2, [r6, #FLOW_CTLR_CPU_CSR_0] + ldr r2, [r6, #FLOW_CTLR_CPU_CSR_0] + orr r2, r2, #1 + str r2, [r6, #FLOW_CTLR_CPU_CSR_0] #if DEBUG_FORCE_RTC_WAKEUP_SEC //r0 = RTC_BASE - mov r0, r8 + MOV32 r0, RTC_PA_BASE //R0 = RTC PA base address //setup rtc wake - ldr r2, [r0, #0x10] //milli - ldr r2, [r0, #0x8] //shadow + ldr r2, [r0, #0x10] //milli + ldr r2, [r0, #0x8] //shadow - add r2, r2, #DEBUG_FORCE_RTC_WAKEUP_SEC + add r2, r2, #DEBUG_FORCE_RTC_WAKEUP_SEC rtc_idle1: - ldr r1, [r0, #0x4] - tst r1, #0x1 - bne rtc_idle1 - str r2, [r0, #0x14] + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle1 + str r2, [r0, #0x14] rtc_idle2: - ldr r1, [r0, #0x4] - tst r1, #0x1 - bne rtc_idle2 + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle2 //intr mask alarm0 - mov r2, #1 - str r2, [r0, #0x28] + mov r2, #1 + str r2, [r0, #0x28] rtc_idle3: - ldr r1, [r0, #0x4] - tst r1, #0x1 - bne rtc_idle3 + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle3 #endif //Save the microsecond count before LP0 in SCRATCH38 - ldr r2, [r7] - str r2, [r5, #APBDEV_PMC_SCRATCH38_0] + ldr r2, [r7] + str r2, [r5, #APBDEV_PMC_SCRATCH38_0] //Halt the CPU without any wakeup events - mov r2, #1, 2 - str r2, [r6] + mov r2, #1, 2 + str r2, [r6] do_wfi: dsb wfe - b do_wfi -lp0_literals: - .word EMC_PA_BASE - .word PMC_PA_BASE - .word FLOW_PA_BASE - .word TIMERUS_PA_BASE - .word RTC_PA_BASE + b do_wfi enter_lp0_end: ENDPROC(enter_lp0) @@ -889,31 +833,29 @@ ENTRY(exit_power_state) //Switch to SVC state cpsid if, #0x13 - add r5, pc, #lp0_literals-(.+4) //PMC base - ldr r5, [r5] + MOV32 r5, PMC_PA_BASE //R5 = PMC PA base address //Check which core we are by checking the MPIDR - mrc p15, 0, r2, c0, c0, 5 + mrc p15, 0, r2, c0, c0, 5 ands r2, r2, #0x3 - bne restore_slave + bne restore_slave //Disable DPD sample - mov r3, #0 - str r3, [r5, #APBDEV_PMC_DPD_SAMPLE_0] + mov r3, #0 + str r3, [r5, #APBDEV_PMC_DPD_SAMPLE_0] - //Disable DPD enable - str r3, [r5, #APBDEV_PMC_DPD_ENABLE_0] + //Disable DPD enable + str r3, [r5, #APBDEV_PMC_DPD_ENABLE_0] restore_slave: //Get the physical pointer to cpu context save area - ldr r0, [r5, #APBDEV_PMC_SCRATCH37_0] - mov r3, #0x800 - //r0 = r0 + r2 * r3 - smlabb r0, r2, r3, r0 + ldr r0, [r5, #APBDEV_PMC_SCRATCH37_0] + mov r3, #0x800 + smlabb r0, r2, r3, r0 //r0 = r0 + r2 * r3 - //Perform ARM restore (r0 = context save ptr) - b ArmCortexA9PhysicalRestore + //Perform ARM restore (r0 = context save ptr) + b ArmCortexA9PhysicalRestore ArmCortexA9PhysicalRestored: @@ -922,64 +864,64 @@ ArmCortexA9PhysicalRestored: //r11 = pointer to CPU-specific context save area VA //Check if power state is POWER_STATE_LP0 - cmp r0, #2 - bne skip_pll - ldr r0, =g_pPMC - ldr r0, [r0] - ldr r1, =g_pTimerus - ldr r1, [r1] + cmp r0, #0 + bne skip_pll + ldr r0, =g_pPMC + ldr r0, [r0] + ldr r1, =g_pTimerus + ldr r1, [r1] //Read from LP0 exit time from SCRATCH1 //The warmboot code filled this value in - ldr r2, [r0, #APBDEV_PMC_SCRATCH1_0] - add r2, r2, #300 + ldr r2, [r0, #APBDEV_PMC_SCRATCH1_0] + add r2, r2, #300 pll_wait: - ldr r3, [r1] - cmp r3, r2 - blt pll_wait + ldr r3, [r1] + cmp r3, r2 + blt pll_wait - //Put CPU clock source on PLLX - ldr r0, =g_pCLK_RST_CONTROLLER - ldr r0, [r0] - ldr r1, =0x20008888 - str r1, [r0, #0x20] + //Put CPsource on PLLX + ldr r0, =g_pCLK_RST_CONTROLLER + ldr r0, [r0] + MOV32 r1, 0x20008888 + str r1, [r0, #0x20] #if DEBUG_FORCE_RTC_WAKEUP_SEC //Clear the pending rtc interrupt - ldr r0, =g_pRtc - ldr r0, [r0] + ldr r0, =g_pRtc + ldr r0, [r0] rtc_idle4: - ldr r1, [r0, #0x4] - tst r1, #0x1 - bne rtc_idle4 - mov r2, #0 - str r2, [r0, #0x28] + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle4 + mov r2, #0 + str r2, [r0, #0x28] rtc_idle5: - ldr r1, [r0, #0x4] - tst r1, #0x1 - bne rtc_idle5 + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle5 //clear interrupt - mov r2, #1 - str r2, [r0, #0x2c] + mov r2, #1 + str r2, [r0, #0x2c] rtc_idle6: - ldr r1, [r0, #0x4] - tst r1, #0x1 - bne rtc_idle6 + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle6 #endif skip_pll: //Restore the cpu virtual context - b ArmCortexA9VirtualRestore + b ArmCortexA9VirtualRestore ArmCortexA9VirtualRestored: //Everything should be restored now //Check which core we are by checking the MPIDR - mrc p15, 0, r2, c0, c0, 5 + mrc p15, 0, r2, c0, c0, 5 ands r2, r2, #0x3 - bne skip_local_timer_restore + bne skip_local_timer_restore //Restore the local timers - bl restore_local_timers + bl restore_local_timers skip_local_timer_restore: //Restore the stack registers @@ -987,886 +929,886 @@ skip_local_timer_restore: ldmfd sp!, {r0-r12, lr} //Restore the CPSR stored in r2 - msr CPSR_fsxc, r2 - mov r0, #1 - bx lr + msr CPSR_fsxc, r2 + mov r0, #1 + bx lr ENDPROC(exit_power_state) ENTRY(ArmCortexA9Save) - add r0, r0, #0x44 - str sp, [r0], #4 + add r0, r0, #0x44 + str sp, [r0], #4 stmia r0!, {r1 - r12, lr} - sub r11, r0, #0x7C - mrs r4, cpsr - mrs r5, spsr + sub r11, r0, #0x7C + mrs r4, cpsr + mrs r5, spsr stmia r0!, {r4, r5} movs r4, #0x44 movs r5, #0 movs r6, #0 loop: - str r5, [r11, r6] - add r6, r6, #4 - cmp r6, r4 - bne loop - str r11, [r11, #0x34] - str r1, [r11, #0x38] - mov r4, r1 - mrc p15, 0, r5, c1, c0, 0 - tst r5, #1 - beq MmuOffDMsave - mov r6, #0x1000 - sub r6, r6, #1 - bic r5, r4, r6 + str r5, [r11, r6] + add r6, r6, #4 + cmp r6, r4 + bne loop + str r11, [r11, #0x34] + str r1, [r11, #0x38] + mov r4, r1 + mrc p15, 0, r5, c1, c0, 0 + tst r5, #1 + beq MmuOffDMsave + mov r6, #0x1000 + sub r6, r6, #1 + bic r5, r4, r6 //VA to PA translation register in r5 - mcr p15, 0, r5, c7, c8, 1 + mcr p15, 0, r5, c7, c8, 1 isb //r5 = PA register - mrc p15, 0, r5, c7, c4, 0 - tst r5, #1 + mrc p15, 0, r5, c7, c4, 0 + tst r5, #1 //Translation failed! - bne . - bic r5, r5, r6 - and r4, r4, r6 - orr r4, r4, r5 + bne . + bic r5, r5, r6 + and r4, r4, r6 + orr r4, r4, r5 MmuOffDMsave: - str r4, [r11, #0x3C] - str r0, [r11, #0x18] - mrc p15, 0, r8, c9, c12, 0 - bic r1, r8, #1 - mcr p15, 0, r1, c9, c12, 0 + str r4, [r11, #0x3C] + str r0, [r11, #0x18] + mrc p15, 0, r8, c9, c12, 0 + bic r1, r8, #1 + mcr p15, 0, r1, c9, c12, 0 isb - mrc p15, 0, r9, c9, c12, 3 - mrc p15, 0, r10, c9, c12, 5 + mrc p15, 0, r9, c9, c12, 3 + mrc p15, 0, r10, c9, c12, 5 stmia r0!, {r8 - r10} ubfx r9, r8, #11, #5 - tst r9, r9 - beq PMonsavecontinue + tst r9, r9 + beq PMonsavecontinue PMonsaveloop: subs r9, r9, #1 - mcr p15, 0, r9, c9, c12, 5 + mcr p15, 0, r9, c9, c12, 5 isb - mrc p15, 0, r3, c9, c13, 1 - mrc p15, 0, r4, c9, c13, 2 + mrc p15, 0, r3, c9, c13, 1 + mrc p15, 0, r4, c9, c13, 2 stmia r0!, {r3, r4} - bne PMonsaveloop + bne PMonsaveloop PMonsavecontinue: - mrc p15, 0, r1, c9, c13, 0 - mrc p15, 0, r2, c9, c14, 0 - mrc p15, 0, r3, c9, c14, 1 - mrc p15, 0, r4, c9, c12, 1 + mrc p15, 0, r1, c9, c13, 0 + mrc p15, 0, r2, c9, c14, 0 + mrc p15, 0, r3, c9, c14, 1 + mrc p15, 0, r4, c9, c12, 1 stmia r0!, {r1 - r4} - str r0, [r11, #0x10] - cps 0x1f //sys - str sp, [r0], #4 - str lr, [r0], #4 - cps 0x17 //abt - str sp, [r0], #4 - mrs r4, spsr + str r0, [r11, #0x10] + cps 0x1f //sys + str sp, [r0], #4 + str lr, [r0], #4 + cps 0x17 //abt + str sp, [r0], #4 + mrs r4, spsr stmia r0!, {r4, lr} - cps 0x1b //und - str sp, [r0], #4 - mrs r4, spsr + cps 0x1b //und + str sp, [r0], #4 + mrs r4, spsr stmia r0!, {r4, lr} - cps 0x12 //irq - str sp, [r0], #4 - mrs r4, spsr + cps 0x12 //irq + str sp, [r0], #4 + mrs r4, spsr stmia r0!, {r4, lr} - cps 0x11 //fiq - str sp, [r0], #4 - mrs r4, spsr + cps 0x11 //fiq + str sp, [r0], #4 + mrs r4, spsr stmia r0!, {r4, r8 - r12, lr} - cps 0x13 //svc - mrc p15, 2, r3, c0, c0, 0 - str r3, [r0], #4 - mrc p15, 0, r4, c1, c0, 1 - mrc p15, 0, r5, c1, c0, 0 - mrc p15, 0, r6, c1, c0, 2 - str r4, [r11, #4] - str r5, [r11, #8] - str r6, [r11, #0xC] //VFPSave - str r0, [r11, #0x1C] - mrc p15, 0, r9, c1, c0, 2 - orr r2, r9, #0xf00000 - mcr p15, 0, r2, c1, c0, 2 + cps 0x13 //svc + mrc p15, 2, r3, c0, c0, 0 + str r3, [r0], #4 + mrc p15, 0, r4, c1, c0, 1 + mrc p15, 0, r5, c1, c0, 0 + mrc p15, 0, r6, c1, c0, 2 + str r4, [r11, #4] + str r5, [r11, #8] + str r6, [r11, #0xC] //VFPSave + str r0, [r11, #0x1C] + mrc p15, 0, r9, c1, c0, 2 + orr r2, r9, #0xf00000 + mcr p15, 0, r2, c1, c0, 2 isb - mrc p15, 0, r2, c1, c0, 2 - and r2, r2, #0xf00000 - cmp r2, #0xf00000 - beq do_fpu_saveVFPsave + mrc p15, 0, r2, c1, c0, 2 + and r2, r2, #0xf00000 + cmp r2, #0xf00000 + beq do_fpu_saveVFPsave movs r2, #0 - str r2, [r11, #0x1C] - b exit_fpu_saveVFPsave + str r2, [r11, #0x1C] + b exit_fpu_saveVFPsave do_fpu_saveVFPsave: VFPFMRX r10,FPEXC - str r10, [r0], #4 - ldr r2, =0x40000000 + str r10, [r0], #4 + mov r2, #0x40000000 VFPFMXR FPEXC,r2 VFPFMRX r2,FPSCR - str r2, [r0], #4 + str r2, [r0], #4 VFPFSTMIA r0, r1 @ fstmiad r0!, {d0-d15}. clobbers r1 VFPFMRX r2, MVFR0 - and r2, r2, #0xF - cmp r2, #2 - blt exit_fpu_saveVFPsave + and r2, r2, #0xF + cmp r2, #2 + blt exit_fpu_saveVFPsave //fstmiad r0!, {d16-d31} //?? VFPFMXR FPEXC,r10 exit_fpu_saveVFPsave: - mcr p15, 0, r9, c1, c0, 2 - str r0, [r11, #0x28] - ldr r1, [r11, #0x38] - mov r6, #1, 24 - add r1, r1, r6 - ldr r2, [r1, #4] - ldr r3, [r1, #8] - ldr r4, [r1] + mcr p15, 0, r9, c1, c0, 2 + str r0, [r11, #0x28] + ldr r1, [r11, #0x38] + mov r6, #1, 24 + add r1, r1, r6 + ldr r2, [r1, #4] + ldr r3, [r1, #8] + ldr r4, [r1] stmia r0!, {r2 - r4} - mov r2, #0 - str r2, [r1, #4] - mrc p15, 0, r7, c0, c0, 5 + mov r2, #0 + str r2, [r1, #4] + mrc p15, 0, r7, c0, c0, 5 ubfx r7, r7, #0, #2 - ldr r1, [r11, #0x38] - mov r6, #0x1000 - add r1, r1, r6 - cmp r7, #0 + ldr r1, [r11, #0x38] + mov r6, #0x1000 + add r1, r1, r6 + cmp r7, #0 movne r2, #1 - bne next1CA9GICsave - ldr r2, [r1, #4] + bne next1CA9GICsave + ldr r2, [r1, #4] ubfx r2, r2, #0, #5 - add r2, r2, #1 + add r2, r2, #1 next1CA9GICsave: - mov r3, r2 + mov r3, r2 loop1CA9GICsave: - ldr r5, [r1, #0x100] - str r5, [r0], #4 - add r1, r1, #4 + ldr r5, [r1, #0x100] + str r5, [r0], #4 + add r1, r1, #4 subs r3, r3, #1 - bne loop1CA9GICsave - ldr r1, [r11, #0x38] - mov r6, #0x1000 // - add r1, r1, r6 - mov r3, r2, lsl #3 + bne loop1CA9GICsave + ldr r1, [r11, #0x38] + mov r6, #0x1000 + add r1, r1, r6 + mov r3, r2, lsl #3 loop2CA9GICsave: - ldr r4, [r1, #0x400] - ldr r5, [r1, #0x800] + ldr r4, [r1, #0x400] + ldr r5, [r1, #0x800] stmia r0!, {r4, r5} - add r1, r1, #4 + add r1, r1, #4 subs r3, r3, #1 - bne loop2CA9GICsave - ldr r1, [r11, #0x38] - mov r6, #0x1000 // - add r1, r1, r6 - mov r3, r2, lsl #1 + bne loop2CA9GICsave + ldr r1, [r11, #0x38] + mov r6, #0x1000 + add r1, r1, r6 + mov r3, r2, lsl #1 loop3CA9GICsave: - ldr r4, [r1, #0xC00] - str r4, [r0], #4 - add r1, r1, #4 + ldr r4, [r1, #0xC00] + str r4, [r0], #4 + add r1, r1, #4 subs r3, r3, #1 - bne loop3CA9GICsave - cmp r7, #0 - bne continueCA9GICsave - ldr r1, [r11, #0x38] - mov r6, #0x1000 - add r1, r1, r6 - ldr r2, [r1] //distributor control - str r2, [r0], #4 + bne loop3CA9GICsave + cmp r7, #0 + bne continueCA9GICsave + ldr r1, [r11, #0x38] + mov r6, #0x1000 + add r1, r1, r6 + ldr r2, [r1] //distributor control + str r2, [r0], #4 continueCA9GICsave: - mov r4, r0 - mrc p15, 0, r5, c1, c0, 0 - tst r5, #1 - beq MmuOffDMmmu - mov r6, #0x1000 - sub r6, r6, #1 - bic r5, r4, r6 - mcr p15, 0, r5, c7, c8, 1 + mov r4, r0 + mrc p15, 0, r5, c1, c0, 0 + tst r5, #1 + beq MmuOffDMmmu + mov r6, #0x1000 + sub r6, r6, #1 + bic r5, r4, r6 + mcr p15, 0, r5, c7, c8, 1 isb - mrc p15, 0, r5, c7, c4, 0 - tst r5, #1 - bne . - bic r5, r5, r6 - and r4, r4, r6 - orr r4, r4, r5 + mrc p15, 0, r5, c7, c4, 0 + tst r5, #1 + bne . + bic r5, r5, r6 + and r4, r4, r6 + orr r4, r4, r5 MmuOffDMmmu: - str r4, [r11, #0x20] - mrc p15, 0, r5, c2, c0, 0 - mrc p15, 0, r6, c2, c0, 1 - mrc p15, 0, r7, c2, c0, 2 + str r4, [r11, #0x20] + mrc p15, 0, r5, c2, c0, 0 + mrc p15, 0, r6, c2, c0, 1 + mrc p15, 0, r7, c2, c0, 2 stmia r0!, {r5 - r7} - mrc p15, 0, r4, c3, c0, 0 - mrc p15, 0, r5, c7, c4, 0 - mrc p15, 0, r6, c10, c2, 0 - mrc p15, 0, r7, c10, c2, 1 + mrc p15, 0, r4, c3, c0, 0 + mrc p15, 0, r5, c7, c4, 0 + mrc p15, 0, r6, c10, c2, 0 + mrc p15, 0, r7, c10, c2, 1 stmia r0!, {r4 - r7} - mrc p15, 0, r4, c12, c0, 0 - str r4, [r0], #4 - mrc p15, 0, r4, c13, c0, 1 - mrc p15, 0, r5, c13, c0, 2 - mrc p15, 0, r6, c13, c0, 3 - mrc p15, 0, r7, c13, c0, 4 + mrc p15, 0, r4, c12, c0, 0 + str r4, [r0], #4 + mrc p15, 0, r4, c13, c0, 1 + mrc p15, 0, r5, c13, c0, 2 + mrc p15, 0, r6, c13, c0, 3 + mrc p15, 0, r7, c13, c0, 4 stmia r0!, {r4 - r7} //Disable the D-Cache - mrc p15, 0, r4, c1, c0, 0 - bic r4, r4, #4 - mcr p15, 0, r4, c1, c0, 0 + mrc p15, 0, r4, c1, c0, 0 + bic r4, r4, #4 + mcr p15, 0, r4, c1, c0, 0 isb - mov r1, #0 - mcr p15, 2, r1, c0, c0, 0 + mov r1, #0 + mcr p15, 2, r1, c0, c0, 0 isb - mrc p15, 1, r7, c0, c0, 0 + mrc p15, 1, r7, c0, c0, 0 ubfx r3, r7, #0, #3 - add r3, r3, #4 + add r3, r3, #4 ubfx r4, r7, #13, #15 ubfx r5, r7, #3, #10 - cmp r5, #3 + cmp r5, #3 cmpeq r3, #5 - bne PWRDNcleangeneric - mov r1, r4, lsl #5 - add r2, r1, #0x40000000 - add r3, r1, #0x80000000 - add r4, r1, #0xc0000000 + bne PWRDNcleangeneric + mov r1, r4, lsl #5 + add r2, r1, #0x40000000 + add r3, r1, #0x80000000 + add r4, r1, #0xc0000000 PWRDNcleanoptloop: - mcr p15, 0, r1, c7, c14, 2 - mcr p15, 0, r2, c7, c14, 2 - mcr p15, 0, r3, c7, c14, 2 - mcr p15, 0, r4, c7, c14, 2 + mcr p15, 0, r1, c7, c14, 2 + mcr p15, 0, r2, c7, c14, 2 + mcr p15, 0, r3, c7, c14, 2 + mcr p15, 0, r4, c7, c14, 2 subs r1, r1, #0x20 - sub r2, r2, #0x20 - sub r3, r3, #0x20 - sub r4, r4, #0x20 - bpl PWRDNcleanoptloop - b PWRDNcleanend + sub r2, r2, #0x20 + sub r3, r3, #0x20 + sub r4, r4, #0x20 + bpl PWRDNcleanoptloop + b PWRDNcleanend PWRDNcleangeneric: - clz r6, r5 + clz r6, r5 PWRDNcleanloopl: - mov r2, r5 + mov r2, r5 PWRDNcleanloop2: - mov r7, r2, lsl r6 - mov r1, r4, lsl r3 - orr r7, r7, r1 - mcr p15, 0, r7, c7, c14, 2 + mov r7, r2, lsl r6 + mov r1, r4, lsl r3 + orr r7, r7, r1 + mcr p15, 0, r7, c7, c14, 2 subs r2, r2, #1 - bge PWRDNcleanloop2 + bge PWRDNcleanloop2 subs r4, r4, #1 - bge PWRDNcleanloopl + bge PWRDNcleanloopl PWRDNcleanend: dsb - mrc p15, 0, r4, c1, c0, 1 - bic r4, r4, #0x40 - mcr p15, 0, r4, c1, c0, 1 + mrc p15, 0, r4, c1, c0, 1 + bic r4, r4, #0x40 + mcr p15, 0, r4, c1, c0, 1 isb - mrc p15, 0, r7, c0, c0, 5 + mrc p15, 0, r7, c0, c0, 5 ubfx r7, r7, #0, #2 - cmp r7, #0 - bne NotCPU0save - mov r4, r0 - mrc p15, 0, r5, c1, c0, 0 - tst r5, #1 - beq MmuOffDMscu - mov r6, #0x1000 - sub r6, r6, #1 - bic r5, r4, r6 - mcr p15, 0, r5, c7, c8, 1 + cmp r7, #0 + bne NotCPU0save + mov r4, r0 + mrc p15, 0, r5, c1, c0, 0 + tst r5, #1 + beq MmuOffDMscu + mov r6, #0x1000 + sub r6, r6, #1 + bic r5, r4, r6 + mcr p15, 0, r5, c7, c8, 1 isb - mrc p15, 0, r5, c7, c4, 0 - tst r5, #1 - bne . - bic r5, r5, r6 - and r4, r4, r6 - orr r4, r4, r5 + mrc p15, 0, r5, c7, c4, 0 + tst r5, #1 + bne . + bic r5, r5, r6 + and r4, r4, r6 + orr r4, r4, r5 MmuOffDMscu: - str r4, [r11, #0x24] - ldr r1, [r11, #0x38] - ldr r2, [r1, #0x40] - ldr r3, [r1, #0x44] - ldr r4, [r1, #0x50] - ldr r5, [r1, #0x54] - ldr r6, [r1] + str r4, [r11, #0x24] + ldr r1, [r11, #0x38] + ldr r2, [r1, #0x40] + ldr r3, [r1, #0x44] + ldr r4, [r1, #0x50] + ldr r5, [r1, #0x54] + ldr r6, [r1] stmia r0!, {r2 - r6} NotCPU0save: - mov r4, r0 + mov r4, r0 DMpl310: - mrc p15, 0, r5, c1, c0, 0 - tst r5, #1 - beq MmuOff - mov r6, #0x1000 - sub r6, r6, #1 - bic r5, r4, r6 - mcr p15, 0, r5, c7, c8, 1 + mrc p15, 0, r5, c1, c0, 0 + tst r5, #1 + beq MmuOff + mov r6, #0x1000 + sub r6, r6, #1 + bic r5, r4, r6 + mcr p15, 0, r5, c7, c8, 1 isb - mrc p15, 0, r5, c7, c4, 0 - tst r5, #1 - bne . - bic r5, r5, r6 - and r4, r4, r6 - orr r4, r4, r5 + mrc p15, 0, r5, c7, c4, 0 + tst r5, #1 + bne . + bic r5, r5, r6 + and r4, r4, r6 + orr r4, r4, r5 MmuOff: - str r4, [r11, #0x30] - ldr r1, [r11, #0x38] - mov r2, #0x3200 // - add r1, r1, r2 - ldr r2, [r1] - ldr r3, [r1, #4] - ldr r4, [r1, #8] - ldr r5, [r1, #0xC] - ldr r6, [r1, #0x10] - ldr r7, [r1, #0x14] + str r4, [r11, #0x30] + ldr r1, [r11, #0x38] + mov r2, #0x3200 + add r1, r1, r2 + ldr r2, [r1] + ldr r3, [r1, #4] + ldr r4, [r1, #8] + ldr r5, [r1, #0xC] + ldr r6, [r1, #0x10] + ldr r7, [r1, #0x14] stmia r0!, {r2 - r7} - add r1, r1, #0x700 - ldr r2, [r1], #4 - ldr r3, [r1], #4 - ldr r4, [r1], #4 - ldr r5, [r1], #4 + add r1, r1, #0x700 + ldr r2, [r1], #4 + ldr r3, [r1], #4 + ldr r4, [r1], #4 + ldr r5, [r1], #4 stmia r0!, {r2 - r5} - ldr r2, [r1], #4 - ldr r3, [r1], #4 - ldr r4, [r1], #4 - ldr r5, [r1], #4 + ldr r2, [r1], #4 + ldr r3, [r1], #4 + ldr r4, [r1], #4 + ldr r5, [r1], #4 stmia r0!, {r2 - r5} - ldr r2, [r1], #4 - ldr r3, [r1], #4 - ldr r4, [r1], #4 - ldr r5, [r1], #4 + ldr r2, [r1], #4 + ldr r3, [r1], #4 + ldr r4, [r1], #4 + ldr r5, [r1], #4 stmia r0!, {r2 - r5} - ldr r2, [r1], #4 - ldr r3, [r1], #4 - ldr r4, [r1], #4 - ldr r5, [r1], #4 + ldr r2, [r1], #4 + ldr r3, [r1], #4 + ldr r4, [r1], #4 + ldr r5, [r1], #4 stmia r0!, {r2 - r5} - add r1, r1, #0x10 - ldr r2, [r1] - ldr r3, [r1, #4] + add r1, r1, #0x10 + ldr r2, [r1] + ldr r3, [r1, #4] stmia r0!, {r2, r3} - add r1, r1, #0x2b0 - ldr r2, [r1] - ldr r3, [r1, #4] + add r1, r1, #0x2b0 + ldr r2, [r1] + ldr r3, [r1, #4] stmia r0!, {r2, r3} - ldr r2, [r1, #0x340] - str r2, [r0], #4 - sub r1, r1, #0xB00 - ldr r2, [r1] - ldr r3, [r1, #4] - ldr r4, [r1, #8] - ldr r5, [r1, #0xC] + ldr r2, [r1, #0x340] + str r2, [r0], #4 + sub r1, r1, #0xB00 + ldr r2, [r1] + ldr r3, [r1, #4] + ldr r4, [r1, #8] + ldr r5, [r1, #0xC] stmia r0!, {r2 - r5} CheckWayOperationsSYSCACHEsave: - ldr r2, [r1, #0x6FC] - cmp r2, #0 - bne CheckWayOperationsSYSCACHEsave + ldr r2, [r1, #0x6FC] + cmp r2, #0 + bne CheckWayOperationsSYSCACHEsave CheckUnlockOperationSYSCACHEsave: - ldr r2, [r1, #0x854] - cmp r2, #0 - bne CheckUnlockOperationSYSCACHEsave - ldr r4, [r11, #0x20] - mov r2, #0x1F - bic r4, r4, r2 - ldr r1, [r11, #0x38] - mov r2, #0x3700 - add r1, r1, r2 - mov r3, r0 - mrc p15, 0, r5, c1, c0, 0 - tst r5, #1 - beq MmuOffDMsyscache1 - mov r6, #0x1000 - sub r6, r6, #1 - bic r5, r3, r6 - mcr p15, 0, r5, c7, c8, 1 + ldr r2, [r1, #0x854] + cmp r2, #0 + bne CheckUnlockOperationSYSCACHEsave + ldr r4, [r11, #0x20] + mov r2, #0x1F + bic r4, r4, r2 + ldr r1, [r11, #0x38] + mov r2, #0x3700 + add r1, r1, r2 + mov r3, r0 + mrc p15, 0, r5, c1, c0, 0 + tst r5, #1 + beq MmuOffDMsyscache1 + mov r6, #0x1000 + sub r6, r6, #1 + bic r5, r3, r6 + mcr p15, 0, r5, c7, c8, 1 isb - mrc p15, 0, r5, c7, c4, 0 - tst r5, #1 - bne . - bic r5, r5, r6 - and r3, r3, r6 - orr r3, r3, r5 + mrc p15, 0, r5, c7, c4, 0 + tst r5, #1 + bne . + bic r5, r5, r6 + and r3, r3, r6 + orr r3, r3, r5 MmuOffDMsyscache1: - str r4, [r1, #0xB0] - add r4, r4, #0x20 - cmp r4, r3 - blt MmuOffDMsyscache1 - mov r4, r11 - mrc p15, 0, r5, c1, c0, 0 - tst r5, #1 - beq MmuOffDMsyscache2 - mov r6, #0x1000 - sub r6, r6, #1 - bic r5, r4, r6 - mcr p15, 0, r5, c7, c8, 1 + str r4, [r1, #0xB0] + add r4, r4, #0x20 + cmp r4, r3 + blt MmuOffDMsyscache1 + mov r4, r11 + mrc p15, 0, r5, c1, c0, 0 + tst r5, #1 + beq MmuOffDMsyscache2 + mov r6, #0x1000 + sub r6, r6, #1 + bic r5, r4, r6 + mcr p15, 0, r5, c7, c8, 1 isb - mrc p15, 0, r5, c7, c4, 0 - tst r5, #1 - bne . - bic r5, r5, r6 - and r4, r4, r6 - orr r4, r4, r5 + mrc p15, 0, r5, c7, c4, 0 + tst r5, #1 + bne . + bic r5, r5, r6 + and r4, r4, r6 + orr r4, r4, r5 MmuOffDMsyscache2: - mov r2, #0x44 - add r2, r2, r4 + mov r2, #0x44 + add r2, r2, r4 SYSCACHEclean2: - str r4, [r1, #0xB0] - add r4, r4, #0x20 - cmp r4, r2 - blt SYSCACHEclean2 + str r4, [r1, #0xB0] + add r4, r4, #0x20 + cmp r4, r2 + blt SYSCACHEclean2 NotCPU0savex: - str r0, [r11, #0x14] + str r0, [r11, #0x14] _lc010_006156_: - mrc p14, 0, r1, c0, c1, 0 - str r1, [r0], #4 - mrc p14, 0, r1, c0, c6, 0 - mrc p14, 0, r2, c0, c7, 0 - mrc p14, 0, r3, c7, c9, 6 + mrc p14, 0, r1, c0, c1, 0 + str r1, [r0], #4 + mrc p14, 0, r1, c0, c6, 0 + mrc p14, 0, r2, c0, c7, 0 + mrc p14, 0, r3, c7, c9, 6 stmia r0!, {r1 - r3} - mrc p14, 0, r2, c0, c0, 4 - mrc p14, 0, r3, c0, c0, 5 + mrc p14, 0, r2, c0, c0, 4 + mrc p14, 0, r3, c0, c0, 5 stmia r0!, {r2, r3} - mrc p14, 0, r2, c0, c1, 4 - mrc p14, 0, r3, c0, c1, 5 + mrc p14, 0, r2, c0, c1, 4 + mrc p14, 0, r3, c0, c1, 5 stmia r0!, {r2, r3} - mrc p14, 0, r2, c0, c2, 4 - mrc p14, 0, r3, c0, c2, 5 + mrc p14, 0, r2, c0, c2, 4 + mrc p14, 0, r3, c0, c2, 5 stmia r0!, {r2, r3} - mrc p14, 0, r2, c0, c3, 4 - mrc p14, 0, r3, c0, c3, 5 + mrc p14, 0, r2, c0, c3, 4 + mrc p14, 0, r3, c0, c3, 5 stmia r0!, {r2, r3} - mrc p14, 0, r2, c0, c4, 4 - mrc p14, 0, r3, c0, c4, 5 + mrc p14, 0, r2, c0, c4, 4 + mrc p14, 0, r3, c0, c4, 5 stmia r0!, {r2, r3} - mrc p14, 0, r2, c0, c5, 4 - mrc p14, 0, r3, c0, c5, 5 + mrc p14, 0, r2, c0, c5, 4 + mrc p14, 0, r3, c0, c5, 5 stmia r0!, {r2, r3} _lc025_006469_: - mrc p14, 0, r2, c0, c0, 6 - mrc p14, 0, r3, c0, c0, 7 + mrc p14, 0, r2, c0, c0, 6 + mrc p14, 0, r3, c0, c0, 7 stmia r0!, {r2, r3} - mrc p14, 0, r2, c0, c1, 6 - mrc p14, 0, r3, c0, c1, 7 + mrc p14, 0, r2, c0, c1, 6 + mrc p14, 0, r3, c0, c1, 7 stmia r0!, {r2, r3} - mrc p14, 0, r2, c0, c2, 6 - mrc p14, 0, r3, c0, c2, 7 + mrc p14, 0, r2, c0, c2, 6 + mrc p14, 0, r3, c0, c2, 7 stmia r0!, {r2, r3} - mrc p14, 0, r2, c0, c3, 6 - mrc p14, 0, r3, c0, c3, 7 + mrc p14, 0, r2, c0, c3, 6 + mrc p14, 0, r3, c0, c3, 7 stmia r0!, {r2, r3} _lc099_006768_: - mov r0, r11 - b ArmCortexA9Saved + mov r0, r11 + b ArmCortexA9Saved ENDPROC(ArmCortexA9Save) ENTRY(ArmCortexA9PhysicalRestore) cpsid aif, #0x13 // - mov r11, r0 - mcr p15, 0, r0, c7, c5, 0 - mcr p15, 0, r0, c7, c5, 6 - mov r1, #0x1800 // - mcr p15, 0, r1, c1, c0, 0 + mov r11, r0 + mcr p15, 0, r0, c7, c5, 0 + mcr p15, 0, r0, c7, c5, 6 + mov r1, #0x1800 // + mcr p15, 0, r1, c1, c0, 0 isb - mov r1, #0 - mcr p15, 2, r1, c0, c0, 0 + mov r1, #0 + mcr p15, 2, r1, c0, c0, 0 isb - mrc p15, 1, r7, c0, c0, 0 + mrc p15, 1, r7, c0, c0, 0 ubfx r3, r7, #0, #3 - add r3, r3, #4 + add r3, r3, #4 ubfx r4, r7, #13, #15 ubfx r5, r7, #3, #10 - cmp r5, #3 - cmpeq r3, #5 - bne PWRUPinvgeneric - mov r1, r4, lsl #5 - add r2, r1, #0x40000000 - add r3, r1, #0x80000000 - add r4, r1, #0xc0000000 + cmp r5, #3 + cmpeq r3, #5 + bne PWRUPinvgeneric + mov r1, r4, lsl #5 + add r2, r1, #0x40000000 + add r3, r1, #0x80000000 + add r4, r1, #0xc0000000 PWRUPinvoptloop: - mcr p15, 0, r1, c7, c6, 2 - mcr p15, 0, r2, c7, c6, 2 - mcr p15, 0, r3, c7, c6, 2 - mcr p15, 0, r4, c7, c6, 2 + mcr p15, 0, r1, c7, c6, 2 + mcr p15, 0, r2, c7, c6, 2 + mcr p15, 0, r3, c7, c6, 2 + mcr p15, 0, r4, c7, c6, 2 subs r1, r1, #0x20 - sub r2, r2, #0x20 - sub r3, r3, #0x20 - sub r4, r4, #0x20 - bpl PWRUPinvoptloop - b PWRUPinvend + sub r2, r2, #0x20 + sub r3, r3, #0x20 + sub r4, r4, #0x20 + bpl PWRUPinvoptloop + b PWRUPinvend PWRUPinvgeneric: - clz r6, r5 + clz r6, r5 PWRUPinvloopl: - mov r2, r5 + mov r2, r5 PWRUPinvloop2: - mov r7, r2, lsl r6 - mov r1, r4, lsl r3 - orr r7, r7, r1 - mcr p15, 0, r7, c7, c6, 2 + mov r7, r2, lsl r6 + mov r1, r4, lsl r3 + orr r7, r7, r1 + mcr p15, 0, r7, c7, c6, 2 subs r2, r2, #1 - bge PWRUPinvloop2 + bge PWRUPinvloop2 subs r4, r4, #1 - bge PWRUPinvloopl + bge PWRUPinvloopl PWRUPinvend: dsb - mrc p15, 0, r7, c0, c0, 5 + mrc p15, 0, r7, c0, c0, 5 ubfx r7, r7, #0, #2 - cmp r7, #0 - bne NotCPU0restore + cmp r7, #0 + bne NotCPU0restore CPU0restore: - ldr r0, [r11, #0x24] - cmp r0, #0 - beq CA9SCUrestorecontinue - ldr r1, [r11, #0x3C] + ldr r0, [r11, #0x24] + cmp r0, #0 + beq CA9SCUrestorecontinue + ldr r1, [r11, #0x3C] ldmia r0!, {r2 - r6} - str r2, [r1, #0x40] - str r3, [r1, #0x44] - str r4, [r1, #0x50] - str r5, [r1, #0x54] - mov r7, #0x10000 - sub r7, r7, #1 - str r7, [r1, #0xC] - str r6, [r1] + str r2, [r1, #0x40] + str r3, [r1, #0x44] + str r4, [r1, #0x50] + str r5, [r1, #0x54] + mov r7, #0x10000 + sub r7, r7, #1 + str r7, [r1, #0xC] + str r6, [r1] CA9SCUrestorecontinue: - ldr r0, [r11, #0x30] - cmp r0, #0 - beq SYSCACHErestorecontinue - ldr r1, [r11, #0x3C] - mov r2, #0x3100 - add r1, r1, r2 + ldr r0, [r11, #0x30] + cmp r0, #0 + beq SYSCACHErestorecontinue + ldr r1, [r11, #0x3C] + mov r2, #0x3100 + add r1, r1, r2 movs r2, #0 SYSCACHErestorel2_cache_disable_loop: - ldr r3, [r1] - and r3, r3, #1 - cmp r3, #0 - beq SYSCACHErestorel2_cache_disable_skip - str r2, [r1] + ldr r3, [r1] + and r3, r3, #1 + cmp r3, #0 + beq SYSCACHErestorel2_cache_disable_skip + str r2, [r1] dsb - b SYSCACHErestorel2_cache_disable_loop + b SYSCACHErestorel2_cache_disable_loop SYSCACHErestorel2_cache_disable_skip: - ldr r0, [r11, #0x30] + ldr r0, [r11, #0x30] ldmia r0!, {r2 - r7} - add r1, r1, #0x100 - str r2, [r1] - str r3, [r1, #4] - str r4, [r1, #8] - str r5, [r1, #0xC] - str r6, [r1, #0x10] - str r7, [r1, #0x14] - add r1, r1, #0x700 + add r1, r1, #0x100 + str r2, [r1] + str r3, [r1, #4] + str r4, [r1, #8] + str r5, [r1, #0xC] + str r6, [r1, #0x10] + str r7, [r1, #0x14] + add r1, r1, #0x700 ldmia r0!, {r2 - r5} - str r2, [r1], #4 - str r3, [r1], #4 - str r4, [r1], #4 - str r5, [r1], #4 + str r2, [r1], #4 + str r3, [r1], #4 + str r4, [r1], #4 + str r5, [r1], #4 ldmia r0!, {r2 - r5} - str r2, [r1], #4 - str r3, [r1], #4 - str r4, [r1], #4 - str r5, [r1], #4 + str r2, [r1], #4 + str r3, [r1], #4 + str r4, [r1], #4 + str r5, [r1], #4 ldmia r0!, {r2 - r5} - str r2, [r1], #4 - str r3, [r1], #4 - str r4, [r1], #4 - str r5, [r1], #4 + str r2, [r1], #4 + str r3, [r1], #4 + str r4, [r1], #4 + str r5, [r1], #4 ldmia r0!, {r2 - r5} - str r2, [r1], #4 - str r3, [r1], #4 - str r4, [r1], #4 - str r5, [r1], #4 - add r1, r1, #0x10 + str r2, [r1], #4 + str r3, [r1], #4 + str r4, [r1], #4 + str r5, [r1], #4 + add r1, r1, #0x10 ldmia r0!, {r2, r3} - str r2, [r1] - str r3, [r1, #4] - add r1, r1, #0x2B0 + str r2, [r1] + str r3, [r1, #4] + add r1, r1, #0x2B0 ldmia r0!, {r2, r3} - str r2, [r1] - str r3, [r1, #4] - ldr r2, [r0], #4 - str r2, [r1, #0x340] - sub r1, r1, #0xB00 + str r2, [r1] + str r3, [r1, #4] + ldr r2, [r0], #4 + str r2, [r1, #0x340] + sub r1, r1, #0xB00 ldmia r0!, {r2 - r5} - str r3, [r1, #4] - str r4, [r1, #8] - str r5, [r1, #0xC] - str r2, [r1] + str r3, [r1, #4] + str r4, [r1, #8] + str r5, [r1, #0xC] + str r2, [r1] dsb -SYSCACHErestorecontinue: +SYSCACHErestorecontinue: NotCPU0restore: - ldr r0, [r11, #0x20] + ldr r0, [r11, #0x20] ldmia r0!, {r5 - r7} - mcr p15, 0, r5, c2, c0, 0 - mcr p15, 0, r6, c2, c0, 1 - mcr p15, 0, r7, c2, c0, 2 + mcr p15, 0, r5, c2, c0, 0 + mcr p15, 0, r6, c2, c0, 1 + mcr p15, 0, r7, c2, c0, 2 ldmia r0!, {r4 - r7} - mcr p15, 0, r4, c3, c0, 0 - mcr p15, 0, r5, c7, c4, 0 - mcr p15, 0, r6, c10, c2, 0 - mcr p15, 0, r7, c10, c2, 1 - ldr r4, [r0], #4 - mcr p15, 0, r4, c12, c0, 0 + mcr p15, 0, r4, c3, c0, 0 + mcr p15, 0, r5, c7, c4, 0 + mcr p15, 0, r6, c10, c2, 0 + mcr p15, 0, r7, c10, c2, 1 + ldr r4, [r0], #4 + mcr p15, 0, r4, c12, c0, 0 ldmia r0!, {r4 - r7} - mcr p15, 0, r4, c13, c0, 1 - mcr p15, 0, r5, c13, c0, 2 - mcr p15, 0, r6, c13, c0, 3 - mcr p15, 0, r7, c13, c0, 4 - ldr r11, [r11, #0x34] - ldr lr, =VirtualRestore - mov r1, #0 - mcr p15, 0, r1, c8, c7, 0 + mcr p15, 0, r4, c13, c0, 1 + mcr p15, 0, r5, c13, c0, 2 + mcr p15, 0, r6, c13, c0, 3 + mcr p15, 0, r7, c13, c0, 4 + ldr r11, [r11, #0x34] + MOV32 lr, VirtualRestore + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 isb - mov r2, #0 - orr r2, #(1<<11) //Z bit on - orr r2, #(1<<12) //I cache on - orr r2, #(1<<28) //Enable Tex Remap - orr r2, #(1<<0) //MMU on + mov r2, #0 + orr r2, #(1<<11) //Z bit on + orr r2, #(1<<12) //I cache on + orr r2, #(1<<28) //Enable Tex Remap + orr r2, #(1<<0) //MMU on andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 andeq r0, r0, r0 -.align 5 - mcr p15, 0, r2, c1, c0, 0 - bx lr - mov r0, r0 - mov r0, r0 - mov r0, r0 - mov r0, r0 + .align 5 + mcr p15, 0, r2, c1, c0, 0 + bx lr + mov r0, r0 + mov r0, r0 + mov r0, r0 + mov r0, r0 VirtualRestore: - mcr p15, 0, r1, c8, c7, 0 + mcr p15, 0, r1, c8, c7, 0 dsb isb - add r0, r11, #0x44 - ldr r0, [r0] - ldr r0, [r0] - b ArmCortexA9PhysicalRestored + add r0, r11, #0x44 + ldr r0, [r0] + ldr r0, [r0] + b ArmCortexA9PhysicalRestored andeq r1, r0, r1, lsl #16 andeq r0, r0, r0 .ltorg - + ENDPROC(ArmCortexA9PhysicalRestore) - -ENTRY(ArmCortexA9VirtualRestore) - mrc p15, 0, r7, c0, c0, 5 - tst r7, r7 - bpl CA9GICrestorecontinue + +ENTRY(ArmCortexA9VirtualRestore) + mrc p15, 0, r7, c0, c0, 5 + tst r7, r7 + bpl CA9GICrestorecontinue ubfx r7, r7, #0, #2 - ldr r0, [r11, #0x28] - cmp r0, #0 - beq CA9GICrestorecontinue - ldr r1, [r11, #0x38] - mov r6, #1, 24 - add r1, r1, r6 + ldr r0, [r11, #0x28] + cmp r0, #0 + beq CA9GICrestorecontinue + ldr r1, [r11, #0x38] + mov r6, #1, 24 + add r1, r1, r6 ldmia r0!, {r2 - r4} - str r2, [r1, #4] - str r3, [r1, #8] - str r4, [r1] - ldr r1, [r11, #0x38] - mov r6, #0x1000 - add r1, r1, r6 - cmp r7, #0 + str r2, [r1, #4] + str r3, [r1, #8] + str r4, [r1] + ldr r1, [r11, #0x38] + mov r6, #0x1000 + add r1, r1, r6 + cmp r7, #0 movne r2, #1 - bne next1CA9GICrestore - ldr r2, [r1, #4] + bne next1CA9GICrestore + ldr r2, [r1, #4] ubfx r2, r2, #0, #5 - add r2, r2, #1 + add r2, r2, #1 next1CA9GICrestore: - mov r3, r2 + mov r3, r2 loop1CA9GICrestore: - ldr r5, [r0], #4 - str r5, [r1, #0x100] - add r1, r1, #4 + ldr r5, [r0], #4 + str r5, [r1, #0x100] + add r1, r1, #4 subs r3, r3, #1 - bne loop1CA9GICrestore - ldr r1, [r11, #0x38] - mov r6, #0x1000 - add r1, r1, r6 - mov r3, r2, lsl #3 + bne loop1CA9GICrestore + ldr r1, [r11, #0x38] + mov r6, #0x1000 + add r1, r1, r6 + mov r3, r2, lsl #3 loop2CA9GICrestore: ldmia r0!, {r4, r5} - str r4, [r1, #0x400] - str r5, [r1, #0x800] - add r1, r1, #4 + str r4, [r1, #0x400] + str r5, [r1, #0x800] + add r1, r1, #4 subs r3, r3, #1 - bne loop2CA9GICrestore - ldr r1, [r11, #0x38] - mov r6, #0x1000 - add r1, r1, r6 - mov r3, r2, lsl #1 + bne loop2CA9GICrestore + ldr r1, [r11, #0x38] + mov r6, #0x1000 + add r1, r1, r6 + mov r3, r2, lsl #1 loop3CA9GICrestore: - ldr r4, [r0], #4 - str r4, [r1, #0xC00] - add r1, r1, #4 + ldr r4, [r0], #4 + str r4, [r1, #0xC00] + add r1, r1, #4 subs r3, r3, #1 - bne loop3CA9GICrestore - cmp r7, #0 - bne CA9GICrestorecontinue - ldr r1, [r11, #0x38] - mov r6, #1, 20 - add r1, r1, r6 - ldr r2, [r0], #4 - str r2, [r1] + bne loop3CA9GICrestore + cmp r7, #0 + bne CA9GICrestorecontinue + ldr r1, [r11, #0x38] + mov r6, #1, 20 + add r1, r1, r6 + ldr r2, [r0], #4 + str r2, [r1] CA9GICrestorecontinue: - ldr r0, [r11, #0x1C] - cmp r0, #0 - beq exit_fpu_restoreVFPrestore - mrc p15, 0, r2, c1, c0, 2 - orr r2, r2, #0x00F00000 - mcr p15, 0, r2, c1, c0, 2 - ldr r2, =0x40000000 + ldr r0, [r11, #0x1C] + cmp r0, #0 + beq exit_fpu_restoreVFPrestore + mrc p15, 0, r2, c1, c0, 2 + orr r2, r2, #0x00F00000 + mcr p15, 0, r2, c1, c0, 2 + mov r2, #0x40000000 VFPFMXR FPEXC,r2 ldmia r0!, {r9, r10} VFPFLDMIA r0, r4 @ r4 clobbered (immediately loaded in exit_fpu_re) VFPFMRX r2, MVFR0 - and r2, r2, #0xF - cmp r2, #2 - blt complete_fpu_restoreVFPrestore + and r2, r2, #0xF + cmp r2, #2 + blt complete_fpu_restoreVFPrestore //fldmiad r0!, {d16-d31} //?? complete_fpu_restoreVFPrestore: VFPFMXR FPSCR,r10 VFPFMXR FPEXC,r9 exit_fpu_restoreVFPrestore: - ldr r0, [r11, #0x10] - cps #0x1f //sys - ldr sp, [r0], #4 - ldr lr, [r0], #4 - cps #0x17 //abt - ldr sp, [r0], #4 + ldr r0, [r11, #0x10] + cps #0x1f //sys + ldr sp, [r0], #4 + ldr lr, [r0], #4 + cps #0x17 //abt + ldr sp, [r0], #4 ldmia r0!, {r4, lr} - msr spsr_cxsf, r4 - cps #0x1b //und - ldr sp, [r0], #4 + msr spsr_cxsf, r4 + cps #0x1b //und + ldr sp, [r0], #4 ldmia r0!, {r4, lr} - msr spsr_cxsf, r4 - cps #0x12 //irq - ldr sp, [r0], #4 + msr spsr_cxsf, r4 + cps #0x12 //irq + ldr sp, [r0], #4 ldmia r0!, {r4, lr} - msr spsr_cxsf, r4 - cps 0x11 //fiq - ldr sp, [r0], #4 + msr spsr_cxsf, r4 + cps 0x11 //fiq + ldr sp, [r0], #4 ldmia r0!, {r4, r8 - r12, lr} - msr spsr_cxsf, r4 - cps 0x13 //svc - ldr r3, [r0], #4 - mcr p15, 2, r3, c0, c0, 0 - ldr r4, [r11, #4] - ldr r5, [r11, #8] - mcr p15, 0, r4, c1, c0, 1 + msr spsr_cxsf, r4 + cps 0x13 //svc + ldr r3, [r0], #4 + mcr p15, 2, r3, c0, c0, 0 + ldr r4, [r11, #4] + ldr r5, [r11, #8] + mcr p15, 0, r4, c1, c0, 1 isb - mcr p15, 0, r5, c1, c0, 0 + mcr p15, 0, r5, c1, c0, 0 isb - ldr r6, [r11, #0xC] - mcr p15, 0, r6, c1, c0, 2 + ldr r6, [r11, #0xC] + mcr p15, 0, r6, c1, c0, 2 isb - ldr r0, [r11, #0x14] - cmp r0, #0 - beq SkipDbgRestore + ldr r0, [r11, #0x14] + cmp r0, #0 + beq SkipDbgRestore DBGrestore: - ldr r5, [r0], #4 + ldr r5, [r0], #4 ldmia r0!, {r1 - r3} - mcr p14, 0, r1, c0, c6, 0 - mcr p14, 0, r2, c0, c7, 0 - mcr p14, 0, r3, c7, c8, 6 + mcr p14, 0, r1, c0, c6, 0 + mcr p14, 0, r2, c0, c7, 0 + mcr p14, 0, r3, c7, c8, 6 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c0, 4 - mcr p14, 0, r3, c0, c0, 5 + mcr p14, 0, r2, c0, c0, 4 + mcr p14, 0, r3, c0, c0, 5 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c1, 4 - mcr p14, 0, r3, c0, c1, 5 + mcr p14, 0, r2, c0, c1, 4 + mcr p14, 0, r3, c0, c1, 5 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c2, 4 - mcr p14, 0, r3, c0, c2, 5 + mcr p14, 0, r2, c0, c2, 4 + mcr p14, 0, r3, c0, c2, 5 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c3, 4 - mcr p14, 0, r3, c0, c3, 5 + mcr p14, 0, r2, c0, c3, 4 + mcr p14, 0, r3, c0, c3, 5 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c4, 4 - mcr p14, 0, r3, c0, c4, 5 + mcr p14, 0, r2, c0, c4, 4 + mcr p14, 0, r3, c0, c4, 5 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c5, 4 - mcr p14, 0, r3, c0, c5, 5 + mcr p14, 0, r2, c0, c5, 4 + mcr p14, 0, r3, c0, c5, 5 _lc025_008056_: ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c0, 6 - mcr p14, 0, r3, c0, c0, 7 + mcr p14, 0, r2, c0, c0, 6 + mcr p14, 0, r3, c0, c0, 7 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c1, 6 - mcr p14, 0, r3, c0, c1, 7 + mcr p14, 0, r2, c0, c1, 6 + mcr p14, 0, r3, c0, c1, 7 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c2, 6 - mcr p14, 0, r3, c0, c2, 7 + mcr p14, 0, r2, c0, c2, 6 + mcr p14, 0, r3, c0, c2, 7 ldmia r0!, {r2, r3} - mcr p14, 0, r2, c0, c3, 6 - mcr p14, 0, r3, c0, c3, 7 + mcr p14, 0, r2, c0, c3, 6 + mcr p14, 0, r3, c0, c3, 7 _lc040_008312_: isb - mcr p14, 0, r5, c0, c2, 2 + mcr p14, 0, r5, c0, c2, 2 _lc099_008377_: isb SkipDbgRestore: - ldr r0, [r11, #0x18] + ldr r0, [r11, #0x18] ldmia r0!, {r8 - r10} - mov r1, #0 - mvn r2, #0 - mcr p15, 0, r2, c9, c14, 2 - mcr p15, 0, r2, c9, c12, 3 + mov r1, #0 + mvn r2, #0 + mcr p15, 0, r2, c9, c14, 2 + mcr p15, 0, r2, c9, c12, 3 isb ubfx r12, r8, #11, #5 - tst r12, r12 - beq PMonrestorecontinue - mov r3, r12 - mov r4, #1 - mov r4, r4, lsl r3 - sub r4, r4, #1 + tst r12, r12 + beq PMonrestorecontinue + mov r3, r12 + mov r4, #1 + mov r4, r4, lsl r3 + sub r4, r4, #1 PMonrestoreloop1: subs r3, r3, #1 - mcr p15, 0, r3, c9, c12, 5 + mcr p15, 0, r3, c9, c12, 5 isb - mrc p15, 0, r5, c9, c13, 1 - bfc r5, #0, #8 - mcr p15, 0, r5, c9, c13, 1 - mcr p15, 0, r2, c9, c13, 2 + mrc p15, 0, r5, c9, c13, 1 + bfc r5, #0, #8 + mcr p15, 0, r5, c9, c13, 1 + mcr p15, 0, r2, c9, c13, 2 isb - bne PMonrestoreloop1 - mov r3, #1 - bic r5, r9, #1<<31 - mcr p15, 0, r5, c9, c12, 1 - mcr p15, 0, r3, c9, c12, 0 + bne PMonrestoreloop1 + mov r3, #1 + bic r5, r9, #1<<31 + mcr p15, 0, r5, c9, c12, 1 + mcr p15, 0, r3, c9, c12, 0 isb - mcr p15, 0, r9, c9, c12, 4 + mcr p15, 0, r9, c9, c12, 4 isb - mcr p15, 0, r4, c9, c12, 2 + mcr p15, 0, r4, c9, c12, 2 PMonrestoreloop2: subs r12, r12, #1 - mcr p15, 0, r12, c9, c12, 5 + mcr p15, 0, r12, c9, c12, 5 isb ldmia r0!, {r3, r4} - mcr p15, 0, r3, c9, c13, 1 - mcr p15, 0, r4, c9, c13, 2 + mcr p15, 0, r3, c9, c13, 1 + mcr p15, 0, r4, c9, c13, 2 isb - bne PMonrestoreloop2 + bne PMonrestoreloop2 PMonrestorecontinue: - tst r9, #0x80000000 - beq PMonrestorecontinue2 - mcr p15, 0, r2, c9, c13, 0 + tst r9, #0x80000000 + beq PMonrestorecontinue2 + mcr p15, 0, r2, c9, c13, 0 isb - mov r3, #0x80000000 - mcr p15, 0, r3, c9, c12, 1 + mov r3, #0x80000000 + mcr p15, 0, r3, c9, c12, 1 isb PMonrestoreloop3: - mrc p15, 0, r4, c9, c12, 3 + mrc p15, 0, r4, c9, c12, 3 movs r4, r4 - bpl PMonrestoreloop3 - mcr p15, 0, r3, c9, c12, 2 + bpl PMonrestoreloop3 + mcr p15, 0, r3, c9, c12, 2 PMonrestorecontinue2: - mcr p15, 0, r1, c9, c12, 0 + mcr p15, 0, r1, c9, c12, 0 isb ldmia r0!, {r1 - r4} - mcr p15, 0, r1, c9, c13, 0 - mcr p15, 0, r2, c9, c14, 0 - mcr p15, 0, r3, c9, c14, 1 - mcr p15, 0, r4, c9, c12, 1 - mcr p15, 0, r10, c9, c12, 5 + mcr p15, 0, r1, c9, c13, 0 + mcr p15, 0, r2, c9, c14, 0 + mcr p15, 0, r3, c9, c14, 1 + mcr p15, 0, r4, c9, c12, 1 + mcr p15, 0, r10, c9, c12, 5 isb - mcr p15, 0, r8, c9, c12, 0 + mcr p15, 0, r8, c9, c12, 0 isb - add r0, r11, #0x7C + add r0, r11, #0x7C ldmia r0, {r1, r2} - msr cpsr_cxsf, r1 - msr spsr_cxsf, r2 - sub r0, r0, #0x38 - ldr sp, [r0], #4 + msr cpsr_cxsf, r1 + msr spsr_cxsf, r2 + sub r0, r0, #0x38 + ldr sp, [r0], #4 ldmia r0, {r1 - r12, lr} - sub r0, r0, #0x48 - b ArmCortexA9VirtualRestored -.ltorg + sub r0, r0, #0x48 + b ArmCortexA9VirtualRestored + .ltorg ENDPROC(ArmCortexA9VirtualRestore) diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c index a608ea1724b1..fbb0a49cfd76 100644 --- a/arch/arm/mach-tegra/power-t2.c +++ b/arch/arm/mach-tegra/power-t2.c @@ -20,7 +20,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "power.h" +#include "mach/power.h" #include "linux/interrupt.h" #include "nvassert.h" #include "ap20/arapbdev_kbc.h" @@ -229,7 +229,7 @@ void cpu_ap20_do_lp2(void) APBDEV_PMC_SCRATCH37_0, g_contextSavePA); //Only CPU0 must execute the actual suspend operations - //CPU1 must be in the reset state before we continue LP2 + //CPU1 must be in the reset state before we continue LP2 if (!proc_id) { //Disable the Statistics interrupt @@ -246,19 +246,19 @@ void cpu_ap20_do_lp2(void) //Do LP2 enter_power_state(POWER_STATE_LP2, proc_id); - + if (!proc_id) { //We're back enable_irq(INT_SYS_STATS_MON); //Delay if needed - - if (g_modifiedPlls & PowerPllC) + + if (g_modifiedPlls & PowerPllC) enable_pll(PowerPllC, NV_TRUE); - if (g_modifiedPlls & PowerPllM) + if (g_modifiedPlls & PowerPllM) enable_pll(PowerPllM, NV_TRUE); - if (g_modifiedPlls & PowerPllP) + if (g_modifiedPlls & PowerPllP) enable_pll(PowerPllP, NV_TRUE); NvOsWaitUS(300); @@ -268,11 +268,11 @@ void cpu_ap20_do_lp2(void) CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER_0, g_currentCcdiv); //Restore burst policy - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0, g_currentCcbp); - + //Restore the CoreSight clock source. - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0, g_coreSightClock); } } @@ -446,7 +446,7 @@ static NvU32 select_wakeup_pll(void) NvU32 Pll; // Wakeup PLL //Get the current CPU burst policy. - CurrentCcbp = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + CurrentCcbp = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0); Ccbp = CurrentCcbp; @@ -464,25 +464,25 @@ static NvU32 select_wakeup_pll(void) case CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0_CPU_STATE_IDLE: // Extract the 'idle' state clock source. - Reg = NV_DRF_VAL(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, + Reg = NV_DRF_VAL(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, CWAKEUP_IDLE_SOURCE, Ccbp); break; case CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0_CPU_STATE_RUN: // Extract the 'run' state clock source. - Reg = NV_DRF_VAL(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, + Reg = NV_DRF_VAL(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, CWAKEUP_RUN_SOURCE, Ccbp); break; case CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0_CPU_STATE_IRQ: // Extract the 'IRQ' state clock source. - Reg = NV_DRF_VAL(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, + Reg = NV_DRF_VAL(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, CWAKEUP_IRQ_SOURCE, Ccbp); break; case CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0_CPU_STATE_FIQ: // Extract the 'FIQ' state clock source. - Reg = NV_DRF_VAL(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, + Reg = NV_DRF_VAL(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, CWAKEUP_FIQ_SOURCE, Ccbp); break; default: @@ -521,7 +521,7 @@ static NvU32 select_wakeup_pll(void) if (PllMask & PowerPllM) { // Is it running now? - Reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + Reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLM_BASE_0); if (NV_DRF_VAL(CLK_RST_CONTROLLER, PLLM_BASE, PLLM_ENABLE, Reg)) { @@ -535,7 +535,7 @@ static NvU32 select_wakeup_pll(void) if (PllMask & PowerPllP) { // Is it running now? - Reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + Reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLP_BASE_0); if (NV_DRF_VAL(CLK_RST_CONTROLLER, PLLP_BASE, PLLP_ENABLE, Reg)) { @@ -564,25 +564,25 @@ SetWakeupSource: { case CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0_CPU_STATE_IDLE: // Extract the 'idle' state clock source. - Ccbp = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, + Ccbp = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, CWAKEUP_IDLE_SOURCE, Pll, Ccbp); break; case CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0_CPU_STATE_RUN: // Extract the 'run' state clock source. - Ccbp = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, + Ccbp = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, CWAKEUP_RUN_SOURCE, Pll, Ccbp); break; case CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0_CPU_STATE_IRQ: // Extract the 'IRQ' state clock source. - Ccbp = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, + Ccbp = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, CWAKEUP_IRQ_SOURCE, Pll, Ccbp); break; case CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0_CPU_STATE_FIQ: // Extract the 'FIQ' state clock source. - Ccbp = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, + Ccbp = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, CCLK_BURST_POLICY, CWAKEUP_FIQ_SOURCE, Pll, Ccbp); break; @@ -599,42 +599,42 @@ SetWakeupSource: void enable_pll(PowerPll pll, NvBool enable) { NvU32 reg; - + switch(pll) { case PowerPllM: - reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLM_BASE_0); - reg = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, PLLM_BASE, + reg = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, PLLM_BASE, PLLM_ENABLE, (enable ? 1 : 0), reg); - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLM_BASE_0, reg); break; case PowerPllC: - reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLC_BASE_0); - reg = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, PLLC_BASE, + reg = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, PLLC_BASE, PLLC_ENABLE, (enable ? 1 : 0), reg); - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLC_BASE_0, reg); break; case PowerPllP: - reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLP_BASE_0); - reg = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, PLLP_BASE, + reg = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, PLLP_BASE, PLLP_ENABLE, (enable ? 1 : 0), reg); - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLP_BASE_0, reg); break; case PowerPllA: - reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLA_BASE_0); - reg = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, PLLA_BASE, + reg = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, PLLA_BASE, PLLA_ENABLE, (enable ? 1 : 0), reg); - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_PLLA_BASE_0, reg); break; @@ -646,9 +646,9 @@ void enable_pll(PowerPll pll, NvBool enable) void enable_plls(NvBool enable) { NvU32 dfsPllFlags = NvRmPrivGetDfsFlags(s_hRmGlobal); - + g_modifiedPlls = 0; - + //DFS tells us which PLLs are safe to turn off if (dfsPllFlags & NvRmDfsStatusFlags_StopPllC0) { @@ -657,7 +657,7 @@ void enable_plls(NvBool enable) } //pllp - if ((dfsPllFlags & NvRmDfsStatusFlags_StopPllP0) && + if ((dfsPllFlags & NvRmDfsStatusFlags_StopPllP0) && (dfsPllFlags & NvRmDfsStatusFlags_StopPllA0)) { enable_pll(PowerPllP, NV_FALSE); @@ -675,18 +675,18 @@ void enable_plls(NvBool enable) void do_suspend_prep(void) { NvU32 reg; - + //Enable CPU power request output reg = NV_REGR(s_hRmGlobal, NvRmModuleID_Pmif, 0, APBDEV_PMC_CNTRL_0); reg = NV_FLD_SET_DRF_DEF(APBDEV_PMC, CNTRL, CPUPWRREQ_OE, ENABLE, reg); NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0, APBDEV_PMC_CNTRL_0, reg); - + //Save the CoreSight stuff - g_coreSightClock = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + g_coreSightClock = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0); - reg = NV_DRF_DEF(CLK_RST_CONTROLLER, CLK_SOURCE_CSITE, + reg = NV_DRF_DEF(CLK_RST_CONTROLLER, CLK_SOURCE_CSITE, CSITE_CLK_SRC, CLK_M); - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0, reg); //Turn off necessary PLLs enable_plls(NV_FALSE); @@ -698,50 +698,50 @@ void do_suspend_prep(void) void reset_cpu(unsigned int cpu, unsigned int reset) { NvU32 reg; - + if (reset) { reg = NV_DRF_DEF(FLOW_CTLR, HALT_CPU1_EVENTS, MODE, FLOW_MODE_WAITEVENT); - + if (cpu) - { - NV_REGW(s_hRmGlobal, NvRmModuleID_FlowCtrl, 0, + { + NV_REGW(s_hRmGlobal, NvRmModuleID_FlowCtrl, 0, FLOW_CTLR_HALT_CPU1_EVENTS_0, reg); } else { - NV_REGW(s_hRmGlobal, NvRmModuleID_FlowCtrl, 0, - FLOW_CTLR_HALT_CPU_EVENTS_0, reg); + NV_REGW(s_hRmGlobal, NvRmModuleID_FlowCtrl, 0, + FLOW_CTLR_HALT_CPU_EVENTS_0, reg); } // Place CPUn into reset. reg = NV_DRF_NUM(CLK_RST_CONTROLLER, RST_CPU_CMPLX_SET, SET_CPURESET0, 1) | NV_DRF_NUM(CLK_RST_CONTROLLER, RST_CPU_CMPLX_SET, SET_DBGRESET0, 1) | NV_DRF_NUM(CLK_RST_CONTROLLER, RST_CPU_CMPLX_SET, SET_DERESET0, 1); reg <<= cpu; - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, - CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET_0, reg); + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET_0, reg); } else { - reg = NV_DRF_DEF(FLOW_CTLR, HALT_CPU1_EVENTS, MODE, - FLOW_MODE_NONE); + reg = NV_DRF_DEF(FLOW_CTLR, HALT_CPU1_EVENTS, MODE, + FLOW_MODE_NONE); if (cpu) - { - NV_REGW(s_hRmGlobal, NvRmModuleID_FlowCtrl, 0, + { + NV_REGW(s_hRmGlobal, NvRmModuleID_FlowCtrl, 0, FLOW_CTLR_HALT_CPU1_EVENTS_0, reg); } else { - NV_REGW(s_hRmGlobal, NvRmModuleID_FlowCtrl, 0, - FLOW_CTLR_HALT_CPU_EVENTS_0, reg); - } + NV_REGW(s_hRmGlobal, NvRmModuleID_FlowCtrl, 0, + FLOW_CTLR_HALT_CPU_EVENTS_0, reg); + } // Take CPUn out of reset. reg = NV_DRF_NUM(CLK_RST_CONTROLLER, RST_CPU_CMPLX_CLR, CLR_CPURESET0, 1) | NV_DRF_NUM(CLK_RST_CONTROLLER, RST_CPU_CMPLX_CLR, CLR_DBGRESET0, 1) | NV_DRF_NUM(CLK_RST_CONTROLLER, RST_CPU_CMPLX_CLR, CLR_DERESET0, 1); reg <<= cpu; - NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR_0, reg); } } @@ -750,10 +750,10 @@ unsigned int check_for_cpu1_reset(void) { volatile NvU32 reg; - reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + reg = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET_0); - - reg = reg & 0x2; + + reg = reg & 0x2; return reg; } @@ -766,7 +766,7 @@ void save_local_timers(void) while (spin); g_localTimerLoadRegister = reg[0]; - g_localTimerCntrlRegister = reg[2]; + g_localTimerCntrlRegister = reg[2]; } void restore_local_timers(void) @@ -775,7 +775,7 @@ void restore_local_timers(void) volatile NvU32 spin = 0; while (spin); - + reg[0] = g_localTimerLoadRegister; reg[2] = g_localTimerCntrlRegister; } |