blob: 743fc2836f7aaa8877349cd47fe98669351e11d2 [file] [log] [blame]
Tony Lindgren92105bb2005-09-07 17:20:26 +01001/*
2 * linux/arch/arm/plat-omap/sram.c
3 *
4 * OMAP SRAM detection and management
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Written by Tony Lindgren <tony@atomide.com>
8 *
R Sricharan05e152c2012-06-05 16:21:32 +05309 * Copyright (C) 2009-2012 Texas Instruments
10 * Added OMAP4/5 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
Santosh Shilimkar44169072009-05-28 14:16:04 -070011 *
Tony Lindgren92105bb2005-09-07 17:20:26 +010012 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
Tony Lindgrenc2d43e32008-07-03 12:24:38 +030016#undef DEBUG
Tony Lindgren92105bb2005-09-07 17:20:26 +010017
Tony Lindgren92105bb2005-09-07 17:20:26 +010018#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
Russell Kingfced80c2008-09-06 12:10:45 +010021#include <linux/io.h>
Tony Lindgren92105bb2005-09-07 17:20:26 +010022
Tony Lindgrenbf027ca2012-10-29 13:54:06 -070023#include <asm/fncpy.h>
Tony Lindgren53d9cc72006-02-08 22:06:45 +000024#include <asm/tlb.h>
Tony Lindgren92105bb2005-09-07 17:20:26 +010025#include <asm/cacheflush.h>
26
Tony Lindgren670c1042006-04-02 17:46:25 +010027#include <asm/mach/map.h>
28
Tony Lindgren670c1042006-04-02 17:46:25 +010029#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
Tony Lindgren92105bb2005-09-07 17:20:26 +010030
Tony Lindgrena66cb342011-10-04 13:52:57 -070031static void __iomem *omap_sram_base;
Aaro Koskinenb2856732012-08-29 18:24:31 +030032static unsigned long omap_sram_skip;
Tony Lindgren92105bb2005-09-07 17:20:26 +010033static unsigned long omap_sram_size;
Tony Lindgrena66cb342011-10-04 13:52:57 -070034static void __iomem *omap_sram_ceil;
Tony Lindgren92105bb2005-09-07 17:20:26 +010035
Imre Deakb7cc6d42007-03-06 03:16:36 -080036/*
Jean Pihetb6338bd2011-02-02 16:38:06 +010037 * Memory allocator for SRAM: calculates the new ceiling address
38 * for pushing a function using the fncpy API.
39 *
40 * Note that fncpy requires the returned address to be aligned
41 * to an 8-byte boundary.
42 */
43void *omap_sram_push_address(unsigned long size)
Tony Lindgren92105bb2005-09-07 17:20:26 +010044{
Tony Lindgrena66cb342011-10-04 13:52:57 -070045 unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
46
Aaro Koskinenb2856732012-08-29 18:24:31 +030047 available = omap_sram_ceil - (omap_sram_base + omap_sram_skip);
Tony Lindgrena66cb342011-10-04 13:52:57 -070048
49 if (size > available) {
Santosh Shilimkar26a510b2011-04-04 14:20:08 +053050 pr_err("Not enough space in SRAM\n");
Tony Lindgren92105bb2005-09-07 17:20:26 +010051 return NULL;
52 }
Tony Lindgren670c1042006-04-02 17:46:25 +010053
Tony Lindgrena66cb342011-10-04 13:52:57 -070054 new_ceil -= size;
55 new_ceil = ROUND_DOWN(new_ceil, FNCPY_ALIGN);
56 omap_sram_ceil = IOMEM(new_ceil);
Tony Lindgren92105bb2005-09-07 17:20:26 +010057
58 return (void *)omap_sram_ceil;
59}
60
Tony Lindgrend8cfd6c2012-10-29 14:36:25 -070061/*
62 * The SRAM context is lost during off-idle and stack
63 * needs to be reset.
64 */
65void omap_sram_reset(void)
66{
67 omap_sram_ceil = omap_sram_base + omap_sram_size;
68}
69
70/*
71 * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
72 */
73void __init omap_map_sram(unsigned long start, unsigned long size,
74 unsigned long skip, int cached)
75{
76 if (size == 0)
77 return;
78
79 start = ROUND_DOWN(start, PAGE_SIZE);
80 omap_sram_size = size;
81 omap_sram_skip = skip;
82 omap_sram_base = __arm_ioremap_exec(start, size, cached);
83 if (!omap_sram_base) {
84 pr_err("SRAM: Could not map\n");
85 return;
86 }
87
88 omap_sram_reset();
89
90 /*
91 * Looks like we need to preserve some bootloader code at the
92 * beginning of SRAM for jumping to flash for reboot to work...
93 */
94 memset_io(omap_sram_base + omap_sram_skip, 0,
95 omap_sram_size - omap_sram_skip);
96}