2018-09-07 02:04:19 +00:00
// SPDX-License-Identifier: GPL-2.0
2016-05-27 11:56:53 +02:00
/*
* R - Car Gen1 RESET / WDT , R - Car Gen2 , Gen3 , and RZ / G RST Driver
*
* Copyright ( C ) 2016 Glider bvba
*/
# include <linux/err.h>
# include <linux/io.h>
# include <linux/of_address.h>
# include <linux/soc/renesas/rcar-rst.h>
2018-02-13 13:02:44 +00:00
# define WDTRSTCR_RESET 0xA55A0002
# define WDTRSTCR 0x0054
static int rcar_rst_enable_wdt_reset ( void __iomem * base )
{
iowrite32 ( WDTRSTCR_RESET , base + WDTRSTCR ) ;
return 0 ;
}
2016-05-27 11:56:53 +02:00
struct rst_config {
2018-02-13 13:02:44 +00:00
unsigned int modemr ; /* Mode Monitoring Register Offset */
int ( * configure ) ( void * base ) ; /* Platform specific configuration */
2016-05-27 11:56:53 +02:00
} ;
static const struct rst_config rcar_rst_gen1 __initconst = {
. modemr = 0x20 ,
} ;
static const struct rst_config rcar_rst_gen2 __initconst = {
. modemr = 0x60 ,
2018-02-13 13:02:44 +00:00
. configure = rcar_rst_enable_wdt_reset ,
} ;
static const struct rst_config rcar_rst_gen3 __initconst = {
. modemr = 0x60 ,
2016-05-27 11:56:53 +02:00
} ;
static const struct of_device_id rcar_rst_matches [ ] __initconst = {
2018-08-02 15:55:04 +01:00
/* RZ/G1 is handled like R-Car Gen2 */
2016-05-27 11:56:53 +02:00
{ . compatible = " renesas,r8a7743-rst " , . data = & rcar_rst_gen2 } ,
2018-09-11 11:12:46 +01:00
{ . compatible = " renesas,r8a7744-rst " , . data = & rcar_rst_gen2 } ,
2016-05-27 11:56:53 +02:00
{ . compatible = " renesas,r8a7745-rst " , . data = & rcar_rst_gen2 } ,
2018-03-27 15:37:14 +01:00
{ . compatible = " renesas,r8a77470-rst " , . data = & rcar_rst_gen2 } ,
2018-08-02 15:55:04 +01:00
/* RZ/G2 is handled like R-Car Gen3 */
{ . compatible = " renesas,r8a774a1-rst " , . data = & rcar_rst_gen3 } ,
2018-09-10 16:09:41 +01:00
{ . compatible = " renesas,r8a774c0-rst " , . data = & rcar_rst_gen3 } ,
2016-05-27 11:56:53 +02:00
/* R-Car Gen1 */
{ . compatible = " renesas,r8a7778-reset-wdt " , . data = & rcar_rst_gen1 } ,
{ . compatible = " renesas,r8a7779-reset-wdt " , . data = & rcar_rst_gen1 } ,
/* R-Car Gen2 */
{ . compatible = " renesas,r8a7790-rst " , . data = & rcar_rst_gen2 } ,
{ . compatible = " renesas,r8a7791-rst " , . data = & rcar_rst_gen2 } ,
{ . compatible = " renesas,r8a7792-rst " , . data = & rcar_rst_gen2 } ,
{ . compatible = " renesas,r8a7793-rst " , . data = & rcar_rst_gen2 } ,
{ . compatible = " renesas,r8a7794-rst " , . data = & rcar_rst_gen2 } ,
2018-02-13 13:02:44 +00:00
/* R-Car Gen3 */
{ . compatible = " renesas,r8a7795-rst " , . data = & rcar_rst_gen3 } ,
{ . compatible = " renesas,r8a7796-rst " , . data = & rcar_rst_gen3 } ,
2018-02-20 16:12:04 +01:00
{ . compatible = " renesas,r8a77965-rst " , . data = & rcar_rst_gen3 } ,
2018-02-13 13:02:44 +00:00
{ . compatible = " renesas,r8a77970-rst " , . data = & rcar_rst_gen3 } ,
{ . compatible = " renesas,r8a77980-rst " , . data = & rcar_rst_gen3 } ,
2018-04-11 18:36:26 +09:00
{ . compatible = " renesas,r8a77990-rst " , . data = & rcar_rst_gen3 } ,
2018-02-13 13:02:44 +00:00
{ . compatible = " renesas,r8a77995-rst " , . data = & rcar_rst_gen3 } ,
2016-05-27 11:56:53 +02:00
{ /* sentinel */ }
} ;
static void __iomem * rcar_rst_base __initdata ;
static u32 saved_mode __initdata ;
static int __init rcar_rst_init ( void )
{
const struct of_device_id * match ;
const struct rst_config * cfg ;
struct device_node * np ;
void __iomem * base ;
int error = 0 ;
np = of_find_matching_node_and_match ( NULL , rcar_rst_matches , & match ) ;
if ( ! np )
return - ENODEV ;
base = of_iomap ( np , 0 ) ;
if ( ! base ) {
2017-07-18 16:43:29 -05:00
pr_warn ( " %pOF: Cannot map regs \n " , np ) ;
2016-05-27 11:56:53 +02:00
error = - ENOMEM ;
goto out_put ;
}
rcar_rst_base = base ;
cfg = match - > data ;
saved_mode = ioread32 ( base + cfg - > modemr ) ;
2018-02-13 13:02:44 +00:00
if ( cfg - > configure ) {
error = cfg - > configure ( base ) ;
if ( error ) {
pr_warn ( " %pOF: Cannot run SoC specific configuration \n " ,
np ) ;
goto out_put ;
}
}
2016-05-27 11:56:53 +02:00
2017-07-18 16:43:29 -05:00
pr_debug ( " %pOF: MODE = 0x%08x \n " , np , saved_mode ) ;
2016-05-27 11:56:53 +02:00
out_put :
of_node_put ( np ) ;
return error ;
}
int __init rcar_rst_read_mode_pins ( u32 * mode )
{
int error ;
if ( ! rcar_rst_base ) {
error = rcar_rst_init ( ) ;
if ( error )
return error ;
}
* mode = saved_mode ;
return 0 ;
}