diff options
author | Prashant Gaikwad <pgaikwad@nvidia.com> | 2011-07-20 17:20:25 +0530 |
---|---|---|
committer | Manish Tuteja <mtuteja@nvidia.com> | 2011-07-21 04:16:36 -0700 |
commit | 9a3993d39599d1637d7c04218e6a634f914e9f91 (patch) | |
tree | 2f9da34a6bf012a360d035574f4353ae7f4d8586 | |
parent | 4f147689e4f369add2f4adf9ad2badde8b6dd381 (diff) |
arm: tegra: pm: Relocate lp0 vectortegra-10.11.12
LP0 vector is allocated by BL and address is shared to kernel.
For platform with memory less than 1GB it was allocated in
the overlapping region of carveout memory. Because of it
during AVP operation it gets corrupted, which prevents resume.
Relocate AVP vector to some other location where overlapping will
not occur.
Bug 827199
Change-Id: I8ec066d8c38c34b0bd9314abe20b2e01b4a3a293
Reviewed-on: http://git-master/r/42113
Reviewed-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Tested-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Reviewed-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/common.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-tegra/suspend.c | 31 |
2 files changed, 31 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 0eee187abe38..4091b6de2bcc 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -438,12 +438,6 @@ out: void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size, unsigned long fb2_size) { - if (tegra_lp0_vec_size) - if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) - pr_err("Failed to reserve lp0_vec %08lx@%08lx\n", - tegra_lp0_vec_size, tegra_lp0_vec_start); - - tegra_carveout_start = memblock_end_of_DRAM() - carveout_size; if (memblock_remove(tegra_carveout_start, carveout_size)) pr_err("Failed to remove carveout %08lx@%08lx from memory " diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c index f05acc6cb65f..6920d87c8982 100644 --- a/arch/arm/mach-tegra/suspend.c +++ b/arch/arm/mach-tegra/suspend.c @@ -852,6 +852,37 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat) (void)mode; if (plat->suspend_mode == TEGRA_SUSPEND_LP0 && tegra_lp0_vec_size) { + unsigned char *reloc_lp0; + unsigned long tmp; + void __iomem *orig; + reloc_lp0 = kmalloc(tegra_lp0_vec_size + L1_CACHE_BYTES - 1, + GFP_KERNEL); + WARN_ON(!reloc_lp0); + if (!reloc_lp0) { + pr_err("%s: Failed to allocate reloc_lp0\n", + __func__); + goto out; + } + + orig = ioremap(tegra_lp0_vec_start, tegra_lp0_vec_size); + WARN_ON(!orig); + if (!orig) { + pr_err("%s: Failed to map tegra_lp0_vec_start %08lx\n", + __func__, tegra_lp0_vec_start); + kfree(reloc_lp0); + goto out; + } + + tmp = (unsigned long) reloc_lp0; + tmp = (tmp + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1); + reloc_lp0 = (unsigned char *)tmp; + memcpy(reloc_lp0, orig, tegra_lp0_vec_size); + iounmap(orig); + tegra_lp0_vec_start = virt_to_phys(reloc_lp0); + } + +out: + if (plat->suspend_mode == TEGRA_SUSPEND_LP0 && tegra_lp0_vec_size) { wb0_restore = tegra_lp0_vec_start; } else { pr_warning("Suspend mode LP0 requested, but missing lp0_vec\n"); |