2011-09-06 10:39:44 +04:00
/*
* Copyright 2011 Freescale Semiconductor , Inc .
* Copyright 2011 Linaro Ltd .
*
* The code contained herein is licensed under the GNU General Public
* License . You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations :
*
* http : //www.opensource.org/licenses/gpl-license.html
* http : //www.gnu.org/copyleft/gpl.html
*/
# include <linux/init.h>
# include <linux/io.h>
# include <linux/of.h>
# include <linux/of_address.h>
2011-08-09 15:24:07 +04:00
# include <linux/smp.h>
2012-01-20 15:01:12 +04:00
# include <asm/smp_plat.h>
2011-09-06 10:39:44 +04:00
# define SRC_SCR 0x000
# define SRC_GPR1 0x020
2011-12-09 03:51:26 +04:00
# define BP_SRC_SCR_WARM_RESET_ENABLE 0
2011-09-06 10:39:44 +04:00
# define BP_SRC_SCR_CORE1_RST 14
# define BP_SRC_SCR_CORE1_ENABLE 22
static void __iomem * src_base ;
void imx_enable_cpu ( int cpu , bool enable )
{
u32 mask , val ;
2011-08-09 15:24:07 +04:00
cpu = cpu_logical_map ( cpu ) ;
2011-09-06 10:39:44 +04:00
mask = 1 < < ( BP_SRC_SCR_CORE1_ENABLE + cpu - 1 ) ;
val = readl_relaxed ( src_base + SRC_SCR ) ;
val = enable ? val | mask : val & ~ mask ;
writel_relaxed ( val , src_base + SRC_SCR ) ;
}
void imx_set_cpu_jump ( int cpu , void * jump_addr )
{
2011-08-09 15:24:07 +04:00
cpu = cpu_logical_map ( cpu ) ;
2012-01-10 01:41:40 +04:00
writel_relaxed ( virt_to_phys ( jump_addr ) ,
2011-09-06 10:39:44 +04:00
src_base + SRC_GPR1 + cpu * 8 ) ;
}
2011-12-09 03:51:26 +04:00
void imx_src_prepare_restart ( void )
{
u32 val ;
/* clear enable bits of secondary cores */
val = readl_relaxed ( src_base + SRC_SCR ) ;
val & = ~ ( 0x7 < < BP_SRC_SCR_CORE1_ENABLE ) ;
writel_relaxed ( val , src_base + SRC_SCR ) ;
/* clear persistent entry register of primary core */
writel_relaxed ( 0 , src_base + SRC_GPR1 ) ;
}
2011-09-06 10:39:44 +04:00
void __init imx_src_init ( void )
{
struct device_node * np ;
2011-12-09 03:51:26 +04:00
u32 val ;
2011-09-06 10:39:44 +04:00
np = of_find_compatible_node ( NULL , NULL , " fsl,imx6q-src " ) ;
src_base = of_iomap ( np , 0 ) ;
WARN_ON ( ! src_base ) ;
2011-12-09 03:51:26 +04:00
/*
* force warm reset sources to generate cold reset
* for a more reliable restart
*/
val = readl_relaxed ( src_base + SRC_SCR ) ;
val & = ~ ( 1 < < BP_SRC_SCR_WARM_RESET_ENABLE ) ;
writel_relaxed ( val , src_base + SRC_SCR ) ;
2011-09-06 10:39:44 +04:00
}