2019-05-27 08:55:00 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2010-06-19 04:08:12 +00:00
/*
* Copyright ( C ) 2009 - 2010 , Lars - Peter Clausen < lars @ metafoo . de >
2011-05-02 11:47:00 +02:00
* Copyright ( C ) 2011 , Maarten ter Huurne < maarten @ treewalker . org >
2010-06-19 04:08:12 +00:00
* JZ4740 setup code
*/
2020-04-13 17:26:33 +02:00
# include <linux/clocksource.h>
2010-06-19 04:08:12 +00:00
# include <linux/init.h>
2011-05-02 11:47:00 +02:00
# include <linux/io.h>
2015-05-24 16:11:19 +01:00
# include <linux/irqchip.h>
2010-06-19 04:08:12 +00:00
# include <linux/kernel.h>
2015-05-24 16:11:42 +01:00
# include <linux/libfdt.h>
2020-05-06 11:04:52 +02:00
# include <linux/of_clk.h>
2015-05-24 16:11:15 +01:00
# include <linux/of_fdt.h>
2020-04-13 17:26:33 +02:00
# include <linux/pm.h>
2020-07-30 18:12:33 +02:00
# include <linux/sizes.h>
2020-04-13 17:26:33 +02:00
# include <linux/suspend.h>
2010-06-19 04:08:12 +00:00
2011-05-02 11:47:00 +02:00
# include <asm/bootinfo.h>
2020-04-13 17:26:33 +02:00
# include <asm/fw/fw.h>
2015-05-24 16:11:15 +01:00
# include <asm/prom.h>
2020-04-13 17:26:33 +02:00
# include <asm/reboot.h>
2020-05-19 23:22:30 +02:00
# include <asm/time.h>
2010-06-19 04:08:12 +00:00
2018-01-16 16:48:00 +01:00
static unsigned long __init get_board_mach_type ( const void * fdt )
{
2020-07-22 13:21:19 +08:00
if ( ! fdt_node_check_compatible ( fdt , 0 , " ingenic,x2000 " ) )
return MACH_INGENIC_X2000 ;
2019-12-09 13:10:25 +08:00
if ( ! fdt_node_check_compatible ( fdt , 0 , " ingenic,x1830 " ) )
return MACH_INGENIC_X1830 ;
2019-07-30 19:30:11 +08:00
if ( ! fdt_node_check_compatible ( fdt , 0 , " ingenic,x1000 " ) )
return MACH_INGENIC_X1000 ;
2018-01-16 16:48:00 +01:00
if ( ! fdt_node_check_compatible ( fdt , 0 , " ingenic,jz4780 " ) )
return MACH_INGENIC_JZ4780 ;
if ( ! fdt_node_check_compatible ( fdt , 0 , " ingenic,jz4770 " ) )
return MACH_INGENIC_JZ4770 ;
2020-06-23 20:24:30 +02:00
if ( ! fdt_node_check_compatible ( fdt , 0 , " ingenic,jz4725b " ) )
return MACH_INGENIC_JZ4725B ;
2018-01-16 16:48:00 +01:00
return MACH_INGENIC_JZ4740 ;
}
2010-06-19 04:08:12 +00:00
void __init plat_mem_setup ( void )
{
2020-07-30 18:12:31 +02:00
void * dtb = ( void * ) fw_passed_dtb ;
2019-02-21 19:43:10 -03:00
__dt_setup_arch ( dtb ) ;
2020-07-30 18:12:33 +02:00
/*
* Old devicetree files for the qi , lb60 board did not have a / memory
* node . Hardcode the memory info here .
*/
if ( ! fdt_node_check_compatible ( dtb , 0 , " qi,lb60 " ) & &
fdt_path_offset ( dtb , " /memory " ) < 0 )
early_init_dt_add_memory_arch ( 0 , SZ_32M ) ;
2018-01-16 16:48:00 +01:00
2019-02-21 19:43:10 -03:00
mips_machtype = get_board_mach_type ( dtb ) ;
2010-06-19 04:08:12 +00:00
}
2015-05-24 16:11:15 +01:00
void __init device_tree_init ( void )
{
if ( ! initial_boot_params )
return ;
unflatten_and_copy_device_tree ( ) ;
}
2010-06-19 04:08:12 +00:00
const char * get_system_type ( void )
{
2018-01-16 16:48:00 +01:00
switch ( mips_machtype ) {
2020-07-22 13:21:19 +08:00
case MACH_INGENIC_X2000 :
return " X2000 " ;
2019-12-09 13:10:25 +08:00
case MACH_INGENIC_X1830 :
return " X1830 " ;
2019-07-30 19:30:11 +08:00
case MACH_INGENIC_X1000 :
return " X1000 " ;
2018-01-16 16:48:00 +01:00
case MACH_INGENIC_JZ4780 :
2015-05-24 16:11:46 +01:00
return " JZ4780 " ;
2018-01-16 16:48:00 +01:00
case MACH_INGENIC_JZ4770 :
return " JZ4770 " ;
2020-06-23 20:24:30 +02:00
case MACH_INGENIC_JZ4725B :
return " JZ4725B " ;
2018-01-16 16:48:00 +01:00
default :
return " JZ4740 " ;
}
2010-06-19 04:08:12 +00:00
}
2015-05-24 16:11:19 +01:00
void __init arch_init_irq ( void )
{
irqchip_init ( ) ;
}
2020-04-13 17:26:33 +02:00
void __init plat_time_init ( void )
{
of_clk_init ( NULL ) ;
timer_probe ( ) ;
}
void __init prom_init ( void )
{
fw_init_cmdline ( ) ;
}
void __init prom_free_prom_memory ( void )
{
}
static void jz4740_wait_instr ( void )
{
__asm__ ( " .set push; \n "
" .set mips3; \n "
" wait; \n "
" .set pop; \n "
) ;
}
static void jz4740_halt ( void )
{
for ( ; ; )
jz4740_wait_instr ( ) ;
}
static int __maybe_unused jz4740_pm_enter ( suspend_state_t state )
{
jz4740_wait_instr ( ) ;
return 0 ;
}
static const struct platform_suspend_ops jz4740_pm_ops __maybe_unused = {
. valid = suspend_valid_only_mem ,
. enter = jz4740_pm_enter ,
} ;
static int __init jz4740_pm_init ( void )
{
if ( IS_ENABLED ( CONFIG_PM_SLEEP ) )
suspend_set_ops ( & jz4740_pm_ops ) ;
_machine_halt = jz4740_halt ;
return 0 ;
}
late_initcall ( jz4740_pm_init ) ;