summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortkasivajhula <tkasivajhula@nvidia.com>2010-06-16 15:23:26 -0700
committerGary King <gking@nvidia.com>2010-06-16 20:21:11 -0700
commite47496ef32afa204cdb50b159f816f624554470e (patch)
tree21a4260684bf0c8728715a724514c4a299080eab
parent448326c5f143854eda9401a05006f7c9670a9e63 (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.c3
-rw-r--r--arch/arm/mach-tegra/tegra2_save.S44
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