summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrashant Gaikwad <pgaikwad@nvidia.com>2011-07-20 17:20:25 +0530
committerManish Tuteja <mtuteja@nvidia.com>2011-07-21 04:16:36 -0700
commit9a3993d39599d1637d7c04218e6a634f914e9f91 (patch)
tree2f9da34a6bf012a360d035574f4353ae7f4d8586
parent4f147689e4f369add2f4adf9ad2badde8b6dd381 (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.c6
-rw-r--r--arch/arm/mach-tegra/suspend.c31
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");