diff options
author | tkasivajhula <tkasivajhula@nvidia.com> | 2010-06-16 15:23:26 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-06-16 20:21:11 -0700 |
commit | e47496ef32afa204cdb50b159f816f624554470e (patch) | |
tree | 21a4260684bf0c8728715a724514c4a299080eab | |
parent | 448326c5f143854eda9401a05006f7c9670a9e63 (diff) |
[ARM/tegra]: Turn off MMU in LP2tegra-9.12.14
With the MMU on, the instruction prefetcher
can potentially fetch instructions from memory
as the CPU is losing power. This can cause SDRAM to hang.
Change-Id: Iee4a40cc65f25a5969c443710c3a446befd07f41
Reviewed-on: http://git-master/r/2789
Reviewed-by: Trivikram Kasivajhula <tkasivajhula@nvidia.com>
Tested-by: Trivikram Kasivajhula <tkasivajhula@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/platsmp.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_save.S | 44 |
2 files changed, 32 insertions, 15 deletions
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 3190a7112066..547b2a3bf557 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -43,6 +43,7 @@ extern void tegra_secondary_startup(void); static DEFINE_SPINLOCK(boot_lock); static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); extern void __cortex_a9_restore(void); +extern void __shut_off_mmu(void); #ifdef CONFIG_HOTPLUG_CPU static DEFINE_PER_CPU(struct completion, cpu_killed); @@ -172,6 +173,7 @@ static int create_suspend_pgtable(void) (unsigned long)tegra_context_area, (unsigned long)virt_to_phys(tegra_hotplug_startup), (unsigned long)__cortex_a9_restore, + (unsigned long)virt_to_phys(__shut_off_mmu), }; unsigned long addr_p[] = { PHYS_OFFSET, @@ -179,6 +181,7 @@ static int create_suspend_pgtable(void) (unsigned long)virt_to_phys(tegra_context_area), (unsigned long)virt_to_phys(tegra_hotplug_startup), (unsigned long)virt_to_phys(__cortex_a9_restore), + (unsigned long)virt_to_phys(__shut_off_mmu), }; unsigned int flags = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_WBWA | PMD_SECT_S; diff --git a/arch/arm/mach-tegra/tegra2_save.S b/arch/arm/mach-tegra/tegra2_save.S index 6c80e8e28b79..e5256d34fa1b 100644 --- a/arch/arm/mach-tegra/tegra2_save.S +++ b/arch/arm/mach-tegra/tegra2_save.S @@ -28,6 +28,7 @@ #include <asm/ptrace.h> #include <asm/cache.h> #include <asm/vfpmacros.h> +#include <asm/memory.h> #include <asm/hardware/cache-l2x0.h> #include <mach/iomap.h> @@ -531,19 +532,13 @@ __l2_clean_done: * memory access due to page table walks */ mov32 r0, (IO_APB_VIRT-IO_APB_PHYS) mov32 r4, TEGRA_PMC_BASE - addeq r4, r4, r0 mov32 r0, (IO_PPSB_VIRT-IO_PPSB_PHYS) mov32 r5, TEGRA_CLK_RESET_BASE mov32 r6, TEGRA_FLOW_CTRL_BASE mov32 r7, TEGRA_TMRUS_BASE - addeq r5, r5, r0 - addeq r6, r6, r0 - addeq r7, r7, r0 - - beq __tear_down_master_pll_cpu /* change page table pointer to tegra_pgd_phys, so that IRAM - * will be mapped virtual == physical */ + * and MMU shut-off will be mapped virtual == physical */ adr r3, __tear_down_master_data ldr r3, [r3] @ &tegra_pgd_phys ldr r3, [r3] @@ -553,18 +548,43 @@ __l2_clean_done: isb mcr p15, 0, r3, c2, c0, 0 @ TTB 0 isb + + /* Obtain LP1 information. + * R10 = LP1 branch target */ mov32 r2, __tegra_lp1_reset mov32 r3, __tear_down_master_sdram sub r2, r3, r2 mov32 r3, (TEGRA_IRAM_CODE_AREA) - add r3, r2, r3 - movne pc, r3 + add r10, r2, r3 + + mov32 r3, __shut_off_mmu + + /* R9 = LP2 branch target */ + mov32 r9, __tear_down_master_pll_cpu + + /* Convert the branch targets + * to physical addresses */ + sub r3, r3, #(PAGE_OFFSET - PHYS_OFFSET) + sub r9, r9, #(PAGE_OFFSET - PHYS_OFFSET) + movne r9, r10 + mov pc, r3 ENDPROC(__tear_down_master) .type __tear_down_master_data, %object __tear_down_master_data: .long tegra_pgd_phys .size __tear_down_master_data, . - __tear_down_master_data + .align L1_CACHE_SHIFT +ENTRY(__shut_off_mmu) + mrc p15, 0, r3, c1, c0, 0 + movw r2, #(1<<12) | (1<<11) | (1<<2) | (1<<0) + bic r3, r3, r2 + dsb + mcr p15, 0, r3, c1, c0, 0 + isb + mov pc, r9 +ENDPROC(__shut_off_mmu) + /* START OF ROUTINES COPIED TO IRAM */ /* * __tegra_lp1_reset @@ -660,12 +680,6 @@ ENDPROC(__tegra_lp1_reset) */ .align L1_CACHE_SHIFT __tear_down_master_sdram: - mrc p15, 0, r3, c1, c0, 0 - bic r3, r3, #((1<<0) | (1<<2)) @ disable MMU and data-cache - mcr p15, 0, r3, c1, c0, 0 @ to avoid page faults & races - dsb - isb - mov32 r1, TEGRA_EMC_BASE mov r2, #3 str r2, [r1, #EMC_REQ_CTRL] @ stall incoming DRAM requests |