2006-01-04 19:55:53 +00:00
/*
* CBE Pervasive Monitor and Debug
*
* ( C ) Copyright IBM Corporation 2005
*
* Authors : Maximino Aguilar ( maguilar @ us . ibm . com )
* Michael N . Day ( mnday @ us . ibm . com )
*
* 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 , 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 . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# undef DEBUG
# include <linux/interrupt.h>
# include <linux/irq.h>
# include <linux/percpu.h>
# include <linux/types.h>
# include <linux/kallsyms.h>
# include <asm/io.h>
# include <asm/machdep.h>
# include <asm/prom.h>
# include <asm/pgtable.h>
# include <asm/reg.h>
2007-10-04 15:40:42 +10:00
# include <asm/cell-regs.h>
2006-01-04 19:55:53 +00:00
# include "pervasive.h"
2006-10-24 18:31:26 +02:00
static void cbe_power_save ( void )
2006-01-04 19:55:53 +00:00
{
2006-10-24 18:31:26 +02:00
unsigned long ctrl , thread_switch_control ;
2006-11-23 00:46:38 +01:00
2012-07-10 18:36:40 +10:00
/* Ensure our interrupt state is properly tracked */
if ( ! prep_irq_for_idle ( ) )
return ;
2006-11-23 00:46:38 +01:00
2006-10-24 18:31:26 +02:00
ctrl = mfspr ( SPRN_CTRLF ) ;
2006-01-04 19:55:53 +00:00
/* Enable DEC and EE interrupt request */
thread_switch_control = mfspr ( SPRN_TSC_CELL ) ;
thread_switch_control | = TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST ;
2006-10-24 18:31:26 +02:00
switch ( ctrl & CTRL_CT ) {
2006-01-04 19:55:53 +00:00
case CTRL_CT0 :
thread_switch_control | = TSC_CELL_DEC_ENABLE_0 ;
break ;
case CTRL_CT1 :
thread_switch_control | = TSC_CELL_DEC_ENABLE_1 ;
break ;
default :
printk ( KERN_WARNING " %s: unknown configuration \n " ,
2008-03-29 08:21:07 +11:00
__func__ ) ;
2006-01-04 19:55:53 +00:00
break ;
}
mtspr ( SPRN_TSC_CELL , thread_switch_control ) ;
2006-10-24 18:31:26 +02:00
/*
* go into low thread priority , medium priority will be
* restored for us after wake - up .
2006-06-19 20:33:16 +02:00
*/
2006-10-24 18:31:26 +02:00
HMT_low ( ) ;
2006-01-04 19:55:53 +00:00
2006-10-24 18:31:26 +02:00
/*
* atomically disable thread execution and runlatch .
* External and Decrementer exceptions are still handled when the
* thread is disabled but now enter in cbe_system_reset_exception ( )
*/
ctrl & = ~ ( CTRL_RUNLATCH | CTRL_TE ) ;
mtspr ( SPRN_CTRLT , ctrl ) ;
2012-07-10 18:36:40 +10:00
/* Re-enable interrupts in MSR */
__hard_irq_enable ( ) ;
2006-01-04 19:55:53 +00:00
}
2006-01-11 23:07:11 +00:00
static int cbe_system_reset_exception ( struct pt_regs * regs )
2006-01-04 19:55:53 +00:00
{
switch ( regs - > msr & SRR1_WAKEMASK ) {
case SRR1_WAKEEE :
do_IRQ ( regs ) ;
break ;
case SRR1_WAKEDEC :
timer_interrupt ( regs ) ;
break ;
case SRR1_WAKEMT :
2008-07-16 05:51:44 +10:00
return cbe_sysreset_hack ( ) ;
2006-06-19 20:33:16 +02:00
# ifdef CONFIG_CBE_RAS
case SRR1_WAKESYSERR :
cbe_system_error_exception ( regs ) ;
break ;
case SRR1_WAKETHERM :
cbe_thermal_exception ( regs ) ;
break ;
# endif /* CONFIG_CBE_RAS */
2006-01-04 19:55:53 +00:00
default :
/* do system reset */
return 0 ;
}
/* everything handled */
return 1 ;
}
2006-06-19 20:33:16 +02:00
void __init cbe_pervasive_init ( void )
2006-01-04 19:55:53 +00:00
{
2006-10-24 18:31:26 +02:00
int cpu ;
2007-08-23 03:01:26 +10:00
2006-01-04 19:55:53 +00:00
if ( ! cpu_has_feature ( CPU_FTR_PAUSE_ZERO ) )
return ;
2006-10-24 18:31:26 +02:00
for_each_possible_cpu ( cpu ) {
struct cbe_pmd_regs __iomem * regs = cbe_get_cpu_pmd_regs ( cpu ) ;
if ( ! regs )
continue ;
/* Enable Pause(0) control bit */
out_be64 ( & regs - > pmcr , in_be64 ( & regs - > pmcr ) |
CBE_PMD_PAUSE_ZERO_CONTROL ) ;
}
ppc_md . power_save = cbe_power_save ;
2006-01-04 19:55:53 +00:00
ppc_md . system_reset_exception = cbe_system_reset_exception ;
}