2011-08-12 15:41:50 +04:00
/*
* Copyright ( C ) ST - Ericsson SA 2011
*
* License terms : GNU General Public License ( GPL ) version 2
*/
# include <linux/io.h>
2012-03-08 13:02:02 +04:00
# include <linux/of.h>
2011-08-12 15:41:50 +04:00
# include <asm/cacheflush.h>
# include <asm/hardware/cache-l2x0.h>
# include <mach/hardware.h>
# include <mach/id.h>
static void __iomem * l2x0_base ;
2011-10-08 23:47:06 +04:00
static int __init ux500_l2x0_unlock ( void )
{
int i ;
/*
* Unlock Data and Instruction Lock if locked . Ux500 U - Boot versions
* apparently locks both caches before jumping to the kernel . The
* l2x0 core will not touch the unlock registers if the l2x0 is
* already enabled , so we do it right here instead . The PL310 has
* 8 sets of registers , one per possible CPU .
*/
for ( i = 0 ; i < 8 ; i + + ) {
writel_relaxed ( 0x0 , l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
i * L2X0_LOCKDOWN_STRIDE ) ;
writel_relaxed ( 0x0 , l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
i * L2X0_LOCKDOWN_STRIDE ) ;
}
return 0 ;
}
static int __init ux500_l2x0_init ( void )
2011-08-12 15:41:50 +04:00
{
2012-01-23 14:54:44 +04:00
u32 aux_val = 0x3e000000 ;
2012-08-09 19:10:36 +04:00
if ( cpu_is_u8500_family ( ) | | cpu_is_ux540_family ( ) )
2011-08-12 15:41:50 +04:00
l2x0_base = __io_address ( U8500_L2CC_BASE ) ;
else
ux500_unknown_soc ( ) ;
2011-10-08 23:47:06 +04:00
/* Unlock before init */
ux500_l2x0_unlock ( ) ;
2012-01-23 14:54:44 +04:00
/* DB9540's L2 has 128KB way size */
if ( cpu_is_u9540 ( ) )
/* 128KB way size */
aux_val | = ( 0x4 < < L2X0_AUX_CTRL_WAY_SIZE_SHIFT ) ;
else
/* 64KB way size */
aux_val | = ( 0x3 < < L2X0_AUX_CTRL_WAY_SIZE_SHIFT ) ;
2011-08-12 15:41:50 +04:00
/* 64KB way size, 8 way associativity, force WA */
2012-03-08 13:02:02 +04:00
if ( of_have_populated_dt ( ) )
2012-01-23 14:54:44 +04:00
l2x0_of_init ( aux_val , 0xc0000fff ) ;
2012-03-08 13:02:02 +04:00
else
2012-01-23 14:54:44 +04:00
l2x0_init ( l2x0_base , aux_val , 0xc0000fff ) ;
2011-08-12 15:41:50 +04:00
2012-01-17 09:59:39 +04:00
/*
* We can ' t disable l2 as we are in non secure mode , currently
* this seems be called only during kexec path . So let ' s
* override outer . disable with nasty assignment until we have
* some SMI service available .
*/
outer_cache . disable = NULL ;
2011-08-12 15:41:50 +04:00
return 0 ;
}
early_initcall ( ux500_l2x0_init ) ;