void __init tegra_map_common_io(void);
void __init tegra_init_irq(void);
void __init tegra_init_clock(void);
+void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
+ unsigned long fb2_size);
+
+extern unsigned long tegra_bootloader_fb_start;
+extern unsigned long tegra_bootloader_fb_size;
+extern unsigned long tegra_fb_start;
+extern unsigned long tegra_fb_size;
+extern unsigned long tegra_fb2_start;
+extern unsigned long tegra_fb2_size;
+extern unsigned long tegra_carveout_start;
+extern unsigned long tegra_carveout_size;
+extern unsigned long tegra_lp0_vec_start;
+extern unsigned long tegra_lp0_vec_size;
extern struct sys_timer tegra_timer;
#endif
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/memblock.h>
#include <asm/hardware/cache-l2x0.h>
#include "clock.h"
#include "fuse.h"
+unsigned long tegra_bootloader_fb_start;
+unsigned long tegra_bootloader_fb_size;
+unsigned long tegra_fb_start;
+unsigned long tegra_fb_size;
+unsigned long tegra_fb2_start;
+unsigned long tegra_fb2_size;
+unsigned long tegra_carveout_start;
+unsigned long tegra_carveout_size;
+unsigned long tegra_lp0_vec_start;
+unsigned long tegra_lp0_vec_size;
+
void (*tegra_reset)(char mode, const char *cmd);
static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
tegra_dma_init();
#endif
}
+
+static int __init tegra_bootloader_fb_arg(char *options)
+{
+ char *p = options;
+
+ tegra_bootloader_fb_size = memparse(p, &p);
+ if (*p == '@')
+ tegra_bootloader_fb_start = memparse(p+1, &p);
+
+ pr_info("Found tegra_fbmem: %08lx@%08lx\n",
+ tegra_bootloader_fb_size, tegra_bootloader_fb_start);
+
+ return 0;
+}
+early_param("tegra_fbmem", tegra_bootloader_fb_arg);
+
+static int __init tegra_lp0_vec_arg(char *options)
+{
+ char *p = options;
+
+ tegra_lp0_vec_size = memparse(p, &p);
+ if (*p == '@')
+ tegra_lp0_vec_start = memparse(p+1, &p);
+
+ return 0;
+}
+early_param("lp0_vec", tegra_lp0_vec_arg);
+
+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 "
+ "map\n",
+ tegra_carveout_start, carveout_size);
+ else
+ tegra_carveout_size = carveout_size;
+
+ tegra_fb2_start = memblock_end_of_DRAM() - fb2_size;
+ if (memblock_remove(tegra_fb2_start, fb2_size))
+ pr_err("Failed to remove second framebuffer %08lx@%08lx from "
+ "memory map\n",
+ tegra_fb2_start, fb2_size);
+ else
+ tegra_fb2_size = fb2_size;
+
+ tegra_fb_start = memblock_end_of_DRAM() - fb_size;
+ if (memblock_remove(tegra_fb_start, fb_size))
+ pr_err("Failed to remove framebuffer %08lx@%08lx from memory "
+ "map\n",
+ tegra_fb_start, fb_size);
+ else
+ tegra_fb_size = fb_size;
+
+ /*
+ * TODO: We should copy the bootloader's framebuffer to the framebuffer
+ * allocated above, and then free this one.
+ */
+ if (tegra_bootloader_fb_size)
+ if (memblock_reserve(tegra_bootloader_fb_start,
+ tegra_bootloader_fb_size))
+ pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
+ tegra_lp0_vec_size, tegra_lp0_vec_start);
+
+ pr_info("Tegra reserved memory:\n"
+ "LP0: %08lx - %08lx\n"
+ "Bootloader framebuffer: %08lx - %08lx\n"
+ "Framebuffer: %08lx - %08lx\n"
+ "2nd Framebuffer: %08lx - %08lx\n"
+ "Carveout: %08lx - %08lx\n",
+ tegra_lp0_vec_start,
+ tegra_lp0_vec_start + tegra_lp0_vec_size - 1,
+ tegra_bootloader_fb_start,
+ tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1,
+ tegra_fb_start,
+ tegra_fb_start + tegra_fb_size - 1,
+ tegra_fb2_start,
+ tegra_fb2_start + tegra_fb2_size - 1,
+ tegra_carveout_start,
+ tegra_carveout_start + tegra_carveout_size - 1);
+}
#include <mach/legacy_irq.h>
#include <mach/suspend.h>
+#include "board.h"
#include "power.h"
/* NOTE: only add elements to the end of this structure, since the assembly
};
#endif
-static unsigned long lp0_vec_orig_start = 0;
-static unsigned long lp0_vec_orig_size = 0;
-
-static int __init tegra_lp0_vec_arg(char *options)
-{
- char *p = options;
-
- lp0_vec_orig_size = memparse(p, &p);
- if (*p == '@')
- lp0_vec_orig_start = memparse(p+1, &p);
-
- return 0;
-}
-__setup("lp0_vec=", tegra_lp0_vec_arg);
-
void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
{
u32 reg, mode;
(void)reg;
(void)mode;
- if (plat->suspend_mode == TEGRA_SUSPEND_LP0 &&
- lp0_vec_orig_size && lp0_vec_orig_start) {
- unsigned char *reloc_lp0;
- unsigned long tmp;
- void __iomem *orig;
- reloc_lp0 = kmalloc(lp0_vec_orig_size+L1_CACHE_BYTES-1,
- GFP_KERNEL);
- WARN_ON(!reloc_lp0);
- if (!reloc_lp0)
- goto out;
-
- orig = ioremap(lp0_vec_orig_start, lp0_vec_orig_size);
- WARN_ON(!orig);
- if (!orig) {
- 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, lp0_vec_orig_size);
- iounmap(orig);
- wb0_restore = virt_to_phys(reloc_lp0);
- }
-out:
- if (plat->suspend_mode == TEGRA_SUSPEND_LP0 && !wb0_restore) {
+ 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");
pr_warning("Disabling LP0\n");
plat->suspend_mode = TEGRA_SUSPEND_LP1;