2005-09-07 20:20:26 +04:00
/*
* linux / arch / arm / plat - omap / sram . c
*
* OMAP SRAM detection and management
*
* Copyright ( C ) 2005 Nokia Corporation
* Written by Tony Lindgren < tony @ atomide . com >
*
2012-06-05 14:51:32 +04:00
* Copyright ( C ) 2009 - 2012 Texas Instruments
* Added OMAP4 / 5 support - Santosh Shilimkar < santosh . shilimkar @ ti . com >
2009-05-29 01:16:04 +04:00
*
2005-09-07 20:20:26 +04:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
2008-07-03 13:24:38 +04:00
# undef DEBUG
2005-09-07 20:20:26 +04:00
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
2008-09-06 15:10:45 +04:00
# include <linux/io.h>
2005-09-07 20:20:26 +04:00
2012-10-30 00:54:06 +04:00
# include <asm/fncpy.h>
2006-02-09 01:06:45 +03:00
# include <asm/tlb.h>
2005-09-07 20:20:26 +04:00
# include <asm/cacheflush.h>
2006-04-02 20:46:25 +04:00
# include <asm/mach/map.h>
2012-12-28 13:09:15 +04:00
# include <plat/sram.h>
2006-04-02 20:46:25 +04:00
# define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
2005-09-07 20:20:26 +04:00
2011-10-05 00:52:57 +04:00
static void __iomem * omap_sram_base ;
2012-08-29 19:24:31 +04:00
static unsigned long omap_sram_skip ;
2005-09-07 20:20:26 +04:00
static unsigned long omap_sram_size ;
2011-10-05 00:52:57 +04:00
static void __iomem * omap_sram_ceil ;
2005-09-07 20:20:26 +04:00
2011-02-02 18:38:06 +03:00
/*
* Memory allocator for SRAM : calculates the new ceiling address
* for pushing a function using the fncpy API .
*
* Note that fncpy requires the returned address to be aligned
* to an 8 - byte boundary .
*/
void * omap_sram_push_address ( unsigned long size )
2005-09-07 20:20:26 +04:00
{
2011-10-05 00:52:57 +04:00
unsigned long available , new_ceil = ( unsigned long ) omap_sram_ceil ;
2012-08-29 19:24:31 +04:00
available = omap_sram_ceil - ( omap_sram_base + omap_sram_skip ) ;
2011-10-05 00:52:57 +04:00
if ( size > available ) {
2011-04-04 12:50:08 +04:00
pr_err ( " Not enough space in SRAM \n " ) ;
2005-09-07 20:20:26 +04:00
return NULL ;
}
2006-04-02 20:46:25 +04:00
2011-10-05 00:52:57 +04:00
new_ceil - = size ;
new_ceil = ROUND_DOWN ( new_ceil , FNCPY_ALIGN ) ;
omap_sram_ceil = IOMEM ( new_ceil ) ;
2005-09-07 20:20:26 +04:00
return ( void * ) omap_sram_ceil ;
}
2012-10-30 01:36:25 +04:00
/*
* The SRAM context is lost during off - idle and stack
* needs to be reset .
*/
void omap_sram_reset ( void )
{
omap_sram_ceil = omap_sram_base + omap_sram_size ;
}
/*
* Note that we cannot use ioremap for SRAM , as clock init needs SRAM early .
*/
void __init omap_map_sram ( unsigned long start , unsigned long size ,
unsigned long skip , int cached )
{
if ( size = = 0 )
return ;
start = ROUND_DOWN ( start , PAGE_SIZE ) ;
omap_sram_size = size ;
omap_sram_skip = skip ;
omap_sram_base = __arm_ioremap_exec ( start , size , cached ) ;
if ( ! omap_sram_base ) {
pr_err ( " SRAM: Could not map \n " ) ;
return ;
}
omap_sram_reset ( ) ;
/*
* Looks like we need to preserve some bootloader code at the
* beginning of SRAM for jumping to flash for reboot to work . . .
*/
memset_io ( omap_sram_base + omap_sram_skip , 0 ,
omap_sram_size - omap_sram_skip ) ;
}