2015-03-16 08:48:43 +03:00
/*
* R - Car Generation 2 Power management support
*
* Copyright ( C ) 2013 - 2015 Renesas Electronics Corporation
* Copyright ( C ) 2011 Renesas Solutions Corp .
* Copyright ( C ) 2011 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*/
# include <linux/kernel.h>
# include <linux/of.h>
# include <linux/smp.h>
2016-04-20 15:02:36 +03:00
# include <linux/soc/renesas/rcar-sysc.h>
2015-03-16 08:48:43 +03:00
# include <asm/io.h>
# include "common.h"
# include "rcar-gen2.h"
/* RST */
# define RST 0xe6160000
2017-01-25 12:02:13 +03:00
# define CA15BAR 0x0020 /* CA15 Boot Address Register */
# define CA7BAR 0x0030 /* CA7 Boot Address Register */
# define CA15RESCNT 0x0040 /* CA15 Reset Control Register */
# define CA7RESCNT 0x0044 /* CA7 Reset Control Register */
/* SYS Boot Address Register */
# define SBAR_BAREN BIT(4) /* SBAR is valid */
/* Reset Control Registers */
# define CA15RESCNT_CODE 0xa5a50000
# define CA15RESCNT_CPUS 0xf /* CPU0-3 */
# define CA7RESCNT_CODE 0x5a5a0000
# define CA7RESCNT_CPUS 0xf /* CPU0-3 */
2015-03-16 08:48:43 +03:00
/* On-chip RAM */
2016-05-17 18:15:33 +03:00
# define ICRAM1 0xe63c0000 /* Inter Connect RAM1 (4 KiB) */
2015-03-16 08:48:43 +03:00
2017-01-25 12:02:13 +03:00
static inline u32 phys_to_sbar ( phys_addr_t addr )
{
return ( addr > > 8 ) & 0xfffffc00 ;
}
2015-03-16 08:48:43 +03:00
/* SYSC */
# define SYSCIER 0x0c
# define SYSCIMR 0x10
# if defined(CONFIG_SMP)
static void __init rcar_gen2_sysc_init ( u32 syscier )
{
soc: renesas: rcar-sysc: Move SYSC interrupt config to rcar-sysc driver
On R-Car H1 and Gen2, the SYSC interrupt registers are always configured
using hardcoded values in platform code. For R-Car Gen2, values are
provided for H2 and M2-W only, other SoCs are not yet supported, and
never will be.
Move this configuration from SoC-specific platform code to the
rcar_sysc_init() wrapper, so it can be skipped if the SYSC is configured
from DT. This would be the case not only for H1, H2, and M2-W using a
modern DTS, but also for other R-Car Gen2 SoCs not supported by the
platform code, relying purely on DT.
There is no longer a need to return the mapped register block, hence
make the function return void.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
2016-06-28 17:10:33 +03:00
rcar_sysc_init ( 0xe6180000 , syscier ) ;
2015-03-16 08:48:43 +03:00
}
# else /* CONFIG_SMP */
static inline void rcar_gen2_sysc_init ( u32 syscier ) { }
# endif /* CONFIG_SMP */
void __init rcar_gen2_pm_init ( void )
{
void __iomem * p ;
u32 bar ;
static int once ;
struct device_node * np , * cpus ;
bool has_a7 = false ;
bool has_a15 = false ;
2016-05-17 18:15:33 +03:00
phys_addr_t boot_vector_addr = ICRAM1 ;
2015-03-16 08:48:43 +03:00
u32 syscier = 0 ;
if ( once + + )
return ;
cpus = of_find_node_by_path ( " /cpus " ) ;
if ( ! cpus )
return ;
for_each_child_of_node ( cpus , np ) {
if ( of_device_is_compatible ( np , " arm,cortex-a15 " ) )
has_a15 = true ;
else if ( of_device_is_compatible ( np , " arm,cortex-a7 " ) )
has_a7 = true ;
}
2016-05-17 18:15:33 +03:00
if ( of_machine_is_compatible ( " renesas,r8a7790 " ) )
2015-03-16 08:48:43 +03:00
syscier = 0x013111ef ;
2016-05-17 18:15:33 +03:00
else if ( of_machine_is_compatible ( " renesas,r8a7791 " ) )
2015-03-16 08:48:43 +03:00
syscier = 0x00111003 ;
/* RAM for jump stub, because BAR requires 256KB aligned address */
p = ioremap_nocache ( boot_vector_addr , shmobile_boot_size ) ;
memcpy_toio ( p , shmobile_boot_vector , shmobile_boot_size ) ;
iounmap ( p ) ;
/* setup reset vectors */
p = ioremap_nocache ( RST , 0x63 ) ;
2017-01-25 12:02:13 +03:00
bar = phys_to_sbar ( boot_vector_addr ) ;
2015-03-16 08:48:43 +03:00
if ( has_a15 ) {
writel_relaxed ( bar , p + CA15BAR ) ;
2017-01-25 12:02:13 +03:00
writel_relaxed ( bar | SBAR_BAREN , p + CA15BAR ) ;
2015-03-16 08:48:43 +03:00
/* de-assert reset for CA15 CPUs */
2017-01-25 12:02:13 +03:00
writel_relaxed ( ( readl_relaxed ( p + CA15RESCNT ) &
~ CA15RESCNT_CPUS ) | CA15RESCNT_CODE ,
p + CA15RESCNT ) ;
2015-03-16 08:48:43 +03:00
}
if ( has_a7 ) {
writel_relaxed ( bar , p + CA7BAR ) ;
2017-01-25 12:02:13 +03:00
writel_relaxed ( bar | SBAR_BAREN , p + CA7BAR ) ;
2015-03-16 08:48:43 +03:00
/* de-assert reset for CA7 CPUs */
2017-01-25 12:02:13 +03:00
writel_relaxed ( ( readl_relaxed ( p + CA7RESCNT ) &
~ CA7RESCNT_CPUS ) | CA7RESCNT_CODE ,
p + CA7RESCNT ) ;
2015-03-16 08:48:43 +03:00
}
iounmap ( p ) ;
rcar_gen2_sysc_init ( syscier ) ;
shmobile_smp_apmu_suspend_init ( ) ;
}