2010-10-13 17:30:56 +05:30
/*
* Copyright 2009 - 2010 Freescale Semiconductor , Inc .
*
* QorIQ ( P1 / P2 ) L2 controller init for Cache - SRAM instantiation
*
* Author : Vivek Mahajan < vivek . mahajan @ freescale . com >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/kernel.h>
# include <linux/of_platform.h>
# include <asm/io.h>
# include "fsl_85xx_cache_ctlr.h"
static char * sram_size ;
static char * sram_offset ;
struct mpc85xx_l2ctlr __iomem * l2ctlr ;
static long get_cache_sram_size ( void )
{
unsigned long val ;
if ( ! sram_size | | ( strict_strtoul ( sram_size , 0 , & val ) < 0 ) )
return - EINVAL ;
return val ;
}
static long get_cache_sram_offset ( void )
{
unsigned long val ;
if ( ! sram_offset | | ( strict_strtoul ( sram_offset , 0 , & val ) < 0 ) )
return - EINVAL ;
return val ;
}
static int __init get_size_from_cmdline ( char * str )
{
if ( ! str )
return 0 ;
sram_size = str ;
return 1 ;
}
static int __init get_offset_from_cmdline ( char * str )
{
if ( ! str )
return 0 ;
sram_offset = str ;
return 1 ;
}
__setup ( " cache-sram-size= " , get_size_from_cmdline ) ;
__setup ( " cache-sram-offset= " , get_offset_from_cmdline ) ;
2011-02-22 19:59:54 -07:00
static int __devinit mpc85xx_l2ctlr_of_probe ( struct platform_device * dev )
2010-10-13 17:30:56 +05:30
{
long rval ;
unsigned int rem ;
unsigned char ways ;
const unsigned int * prop ;
unsigned int l2cache_size ;
struct sram_parameters sram_params ;
if ( ! dev - > dev . of_node ) {
dev_err ( & dev - > dev , " Device's OF-node is NULL \n " ) ;
return - EINVAL ;
}
prop = of_get_property ( dev - > dev . of_node , " cache-size " , NULL ) ;
if ( ! prop ) {
dev_err ( & dev - > dev , " Missing L2 cache-size \n " ) ;
return - EINVAL ;
}
l2cache_size = * prop ;
sram_params . sram_size = get_cache_sram_size ( ) ;
2010-10-17 18:51:41 +04:00
if ( ( int ) sram_params . sram_size < = 0 ) {
2010-10-13 17:30:56 +05:30
dev_err ( & dev - > dev ,
" Entire L2 as cache, Aborting Cache-SRAM stuff \n " ) ;
return - EINVAL ;
}
sram_params . sram_offset = get_cache_sram_offset ( ) ;
2010-10-17 18:51:41 +04:00
if ( ( int64_t ) sram_params . sram_offset < = 0 ) {
2010-10-13 17:30:56 +05:30
dev_err ( & dev - > dev ,
" Entire L2 as cache, provide a valid sram offset \n " ) ;
return - EINVAL ;
}
rem = l2cache_size % sram_params . sram_size ;
ways = LOCK_WAYS_FULL * sram_params . sram_size / l2cache_size ;
if ( rem | | ( ways & ( ways - 1 ) ) ) {
dev_err ( & dev - > dev , " Illegal cache-sram-size in command line \n " ) ;
return - EINVAL ;
}
l2ctlr = of_iomap ( dev - > dev . of_node , 0 ) ;
if ( ! l2ctlr ) {
dev_err ( & dev - > dev , " Can't map L2 controller \n " ) ;
return - EINVAL ;
}
/*
* Write bits [ 0 - 17 ] to srbar0
*/
out_be32 ( & l2ctlr - > srbar0 ,
sram_params . sram_offset & L2SRAM_BAR_MSK_LO18 ) ;
/*
* Write bits [ 18 - 21 ] to srbare0
*/
# ifdef CONFIG_PHYS_64BIT
out_be32 ( & l2ctlr - > srbarea0 ,
( sram_params . sram_offset > > 32 ) & L2SRAM_BARE_MSK_HI4 ) ;
# endif
clrsetbits_be32 ( & l2ctlr - > ctl , L2CR_L2E , L2CR_L2FI ) ;
switch ( ways ) {
case LOCK_WAYS_EIGHTH :
setbits32 ( & l2ctlr - > ctl ,
L2CR_L2E | L2CR_L2FI | L2CR_SRAM_EIGHTH ) ;
break ;
case LOCK_WAYS_TWO_EIGHTH :
setbits32 ( & l2ctlr - > ctl ,
L2CR_L2E | L2CR_L2FI | L2CR_SRAM_QUART ) ;
break ;
case LOCK_WAYS_HALF :
setbits32 ( & l2ctlr - > ctl ,
L2CR_L2E | L2CR_L2FI | L2CR_SRAM_HALF ) ;
break ;
case LOCK_WAYS_FULL :
default :
setbits32 ( & l2ctlr - > ctl ,
L2CR_L2E | L2CR_L2FI | L2CR_SRAM_FULL ) ;
break ;
}
eieio ( ) ;
rval = instantiate_cache_sram ( dev , sram_params ) ;
if ( rval < 0 ) {
dev_err ( & dev - > dev , " Can't instantiate Cache-SRAM \n " ) ;
iounmap ( l2ctlr ) ;
return - EINVAL ;
}
return 0 ;
}
static int __devexit mpc85xx_l2ctlr_of_remove ( struct platform_device * dev )
{
BUG_ON ( ! l2ctlr ) ;
iounmap ( l2ctlr ) ;
remove_cache_sram ( dev ) ;
dev_info ( & dev - > dev , " MPC85xx L2 controller unloaded \n " ) ;
return 0 ;
}
static struct of_device_id mpc85xx_l2ctlr_of_match [ ] = {
{
. compatible = " fsl,p2020-l2-cache-controller " ,
} ,
{
. compatible = " fsl,p2010-l2-cache-controller " ,
} ,
{
. compatible = " fsl,p1020-l2-cache-controller " ,
} ,
{
. compatible = " fsl,p1011-l2-cache-controller " ,
} ,
{
. compatible = " fsl,p1013-l2-cache-controller " ,
} ,
{
. compatible = " fsl,p1022-l2-cache-controller " ,
} ,
{ } ,
} ;
2011-02-22 19:59:54 -07:00
static struct platform_driver mpc85xx_l2ctlr_of_platform_driver = {
2010-10-13 17:30:56 +05:30
. driver = {
. name = " fsl-l2ctlr " ,
. owner = THIS_MODULE ,
. of_match_table = mpc85xx_l2ctlr_of_match ,
} ,
. probe = mpc85xx_l2ctlr_of_probe ,
. remove = __devexit_p ( mpc85xx_l2ctlr_of_remove ) ,
} ;
static __init int mpc85xx_l2ctlr_of_init ( void )
{
2011-02-22 19:59:54 -07:00
return platform_driver_register ( & mpc85xx_l2ctlr_of_platform_driver ) ;
2010-10-13 17:30:56 +05:30
}
static void __exit mpc85xx_l2ctlr_of_exit ( void )
{
2011-02-22 19:59:54 -07:00
platform_driver_unregister ( & mpc85xx_l2ctlr_of_platform_driver ) ;
2010-10-13 17:30:56 +05:30
}
subsys_initcall ( mpc85xx_l2ctlr_of_init ) ;
module_exit ( mpc85xx_l2ctlr_of_exit ) ;
MODULE_DESCRIPTION ( " Freescale MPC85xx L2 controller init " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;