2007-02-02 10:47:17 +03:00
/*
* Celleb setup code
*
* ( C ) Copyright 2006 - 2007 TOSHIBA CORPORATION
*
* This code is based on arch / powerpc / platforms / cell / setup . c :
* Copyright ( C ) 1995 Linus Torvalds
* Adapted from ' alpha ' version by Gary Thomas
* Modified by Cort Dougan ( cort @ cs . nmt . edu )
* Modified by PPC64 Team , IBM Corp
* Modified by Cell Team , IBM Deutschland Entwicklung GmbH
*
* 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 . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
# undef DEBUG
# include <linux/cpu.h>
# include <linux/sched.h>
# include <linux/kernel.h>
# include <linux/mm.h>
# include <linux/stddef.h>
# include <linux/unistd.h>
# include <linux/reboot.h>
# include <linux/init.h>
# include <linux/delay.h>
# include <linux/irq.h>
# include <linux/seq_file.h>
# include <linux/root_dev.h>
# include <linux/console.h>
2007-11-13 20:10:58 +03:00
# include <linux/of_platform.h>
2007-02-02 10:47:17 +03:00
# include <asm/mmu.h>
# include <asm/processor.h>
# include <asm/io.h>
# include <asm/kexec.h>
# include <asm/prom.h>
# include <asm/machdep.h>
# include <asm/cputable.h>
# include <asm/irq.h>
2007-10-30 06:55:04 +03:00
# include <asm/time.h>
2007-02-02 10:47:17 +03:00
# include <asm/spu_priv1.h>
# include <asm/firmware.h>
2007-12-04 11:38:24 +03:00
# include <asm/rtas.h>
# include <asm/cell-regs.h>
2007-02-02 10:47:17 +03:00
2008-04-24 13:25:16 +04:00
# include "../celleb/interrupt.h"
# include "../celleb/beat_wrapper.h"
# include "../celleb/beat.h"
# include "celleb_pci.h"
2007-02-02 10:47:17 +03:00
# include "interrupt.h"
2008-04-24 13:25:16 +04:00
# include "pervasive.h"
# include "ras.h"
2007-02-02 10:47:17 +03:00
static char celleb_machine_type [ 128 ] = " Celleb " ;
static void celleb_show_cpuinfo ( struct seq_file * m )
{
struct device_node * root ;
const char * model = " " ;
root = of_find_node_by_path ( " / " ) ;
if ( root )
2007-04-03 16:26:41 +04:00
model = of_get_property ( root , " model " , NULL ) ;
2007-02-02 10:47:17 +03:00
/* using "CHRP" is to trick anaconda into installing FCx into Celleb */
seq_printf ( m , " machine \t \t : %s %s \n " , celleb_machine_type , model ) ;
of_node_put ( root ) ;
}
2007-07-26 14:02:27 +04:00
static int __init celleb_machine_type_hack ( char * ptr )
2007-02-02 10:47:17 +03:00
{
strncpy ( celleb_machine_type , ptr , sizeof ( celleb_machine_type ) ) ;
celleb_machine_type [ sizeof ( celleb_machine_type ) - 1 ] = 0 ;
return 0 ;
}
2007-05-09 11:38:03 +04:00
__setup ( " celleb_machine_type_hack= " , celleb_machine_type_hack ) ;
2007-02-02 10:47:17 +03:00
static void celleb_progress ( char * s , unsigned short hex )
{
printk ( " *** %04x : %s \n " , hex , s ? s : " " ) ;
}
2007-12-13 13:13:14 +03:00
static void __init celleb_setup_arch_common ( void )
2007-12-04 11:38:24 +03:00
{
2007-12-13 13:13:14 +03:00
/* init to some ~sane value until calibrate_delay() runs */
loops_per_jiffy = 50000000 ;
# ifdef CONFIG_DUMMY_CONSOLE
conswitchp = & dummy_con ;
# endif
2007-12-04 11:38:24 +03:00
}
2007-12-13 13:13:14 +03:00
static struct of_device_id celleb_bus_ids [ ] __initdata = {
{ . type = " scc " , } ,
{ . type = " ioif " , } , /* old style */
{ } ,
} ;
static int __init celleb_publish_devices ( void )
2007-02-02 10:47:17 +03:00
{
2007-12-13 13:13:14 +03:00
/* Publish OF platform devices for southbridge IOs */
of_platform_bus_probe ( NULL , celleb_bus_ids , NULL ) ;
return 0 ;
}
2008-01-02 22:14:36 +03:00
machine_device_initcall ( celleb_beat , celleb_publish_devices ) ;
machine_device_initcall ( celleb_native , celleb_publish_devices ) ;
2007-12-13 13:13:14 +03:00
/*
* functions for Celleb - Beat
*/
static void __init celleb_setup_arch_beat ( void )
{
2007-02-02 10:47:17 +03:00
# ifdef CONFIG_SPU_BASE
2007-12-04 11:38:24 +03:00
spu_priv1_ops = & spu_priv1_beat_ops ;
spu_management_ops = & spu_management_of_ops ;
2007-02-02 10:47:17 +03:00
# endif
# ifdef CONFIG_SMP
smp_init_celleb ( ) ;
# endif
2007-12-13 13:13:14 +03:00
celleb_setup_arch_common ( ) ;
2007-12-04 11:38:24 +03:00
}
2007-12-13 13:13:14 +03:00
static int __init celleb_probe_beat ( void )
2007-12-04 11:38:24 +03:00
{
2007-12-13 13:13:14 +03:00
unsigned long root = of_get_flat_dt_root ( ) ;
2007-12-04 11:38:24 +03:00
2007-12-13 13:13:14 +03:00
if ( ! of_flat_dt_is_compatible ( root , " Beat " ) )
return 0 ;
powerpc_firmware_features | = FW_FEATURE_CELLEB_ALWAYS
| FW_FEATURE_BEAT | FW_FEATURE_LPAR ;
hpte_init_beat_v3 ( ) ;
return 1 ;
}
/*
* functions for Celleb - native
*/
static void __init celleb_init_IRQ_native ( void )
{
iic_init_IRQ ( ) ;
spider_init_IRQ ( ) ;
}
static void __init celleb_setup_arch_native ( void )
{
2007-12-04 11:38:24 +03:00
# ifdef CONFIG_SPU_BASE
spu_priv1_ops = & spu_priv1_mmio_ops ;
spu_management_ops = & spu_management_of_ops ;
# endif
cbe_regs_init ( ) ;
# ifdef CONFIG_CBE_RAS
cbe_ras_init ( ) ;
# endif
# ifdef CONFIG_SMP
smp_init_cell ( ) ;
# endif
cbe_pervasive_init ( ) ;
2007-12-13 13:13:14 +03:00
/* XXX: nvram initialization should be added */
2007-02-02 10:47:17 +03:00
2007-12-13 13:13:14 +03:00
celleb_setup_arch_common ( ) ;
2007-02-02 10:47:17 +03:00
}
2007-12-13 13:13:14 +03:00
static int __init celleb_probe_native ( void )
2007-02-02 10:47:17 +03:00
{
unsigned long root = of_get_flat_dt_root ( ) ;
2007-12-13 13:13:14 +03:00
if ( of_flat_dt_is_compatible ( root , " Beat " ) | |
! of_flat_dt_is_compatible ( root , " TOSHIBA,Celleb " ) )
2007-02-02 10:47:17 +03:00
return 0 ;
2007-12-13 13:13:14 +03:00
powerpc_firmware_features | = FW_FEATURE_CELLEB_ALWAYS ;
hpte_init_native ( ) ;
2007-10-02 12:26:53 +04:00
2007-12-13 13:13:14 +03:00
return 1 ;
2007-02-02 10:47:17 +03:00
}
2007-12-13 13:13:14 +03:00
/*
* machine definitions
*/
define_machine ( celleb_beat ) {
. name = " Cell Reference Set (Beat) " ,
. probe = celleb_probe_beat ,
. setup_arch = celleb_setup_arch_beat ,
. show_cpuinfo = celleb_show_cpuinfo ,
. restart = beat_restart ,
. power_off = beat_power_off ,
. halt = beat_halt ,
. get_rtc_time = beat_get_rtc_time ,
. set_rtc_time = beat_set_rtc_time ,
. calibrate_decr = generic_calibrate_decr ,
. progress = celleb_progress ,
. power_save = beat_power_save ,
. nvram_size = beat_nvram_get_size ,
. nvram_read = beat_nvram_read ,
. nvram_write = beat_nvram_write ,
. set_dabr = beat_set_xdabr ,
. init_IRQ = beatic_init_IRQ ,
. get_irq = beatic_get_irq ,
. pci_probe_mode = celleb_pci_probe_mode ,
. pci_setup_phb = celleb_setup_phb ,
# ifdef CONFIG_KEXEC
. kexec_cpu_down = beat_kexec_cpu_down ,
. machine_kexec = default_machine_kexec ,
. machine_kexec_prepare = default_machine_kexec_prepare ,
. machine_crash_shutdown = default_machine_crash_shutdown ,
# endif
} ;
define_machine ( celleb_native ) {
. name = " Cell Reference Set (native) " ,
. probe = celleb_probe_native ,
. setup_arch = celleb_setup_arch_native ,
2007-02-02 10:47:17 +03:00
. show_cpuinfo = celleb_show_cpuinfo ,
2007-12-13 13:13:14 +03:00
. restart = rtas_restart ,
. power_off = rtas_power_off ,
. halt = rtas_halt ,
. get_boot_time = rtas_get_boot_time ,
. get_rtc_time = rtas_get_rtc_time ,
. set_rtc_time = rtas_set_rtc_time ,
2007-02-02 10:47:17 +03:00
. calibrate_decr = generic_calibrate_decr ,
. progress = celleb_progress ,
. pci_probe_mode = celleb_pci_probe_mode ,
. pci_setup_phb = celleb_setup_phb ,
2007-12-13 13:13:14 +03:00
. init_IRQ = celleb_init_IRQ_native ,
2007-02-02 10:47:17 +03:00
# ifdef CONFIG_KEXEC
. machine_kexec = default_machine_kexec ,
. machine_kexec_prepare = default_machine_kexec_prepare ,
. machine_crash_shutdown = default_machine_crash_shutdown ,
# endif
} ;