0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #undef DEBUG
0012
0013 #include <linux/interrupt.h>
0014 #include <linux/irq.h>
0015 #include <linux/percpu.h>
0016 #include <linux/types.h>
0017 #include <linux/kallsyms.h>
0018 #include <linux/pgtable.h>
0019
0020 #include <asm/io.h>
0021 #include <asm/machdep.h>
0022 #include <asm/reg.h>
0023 #include <asm/cell-regs.h>
0024 #include <asm/cpu_has_feature.h>
0025
0026 #include "pervasive.h"
0027 #include "ras.h"
0028
0029 static void cbe_power_save(void)
0030 {
0031 unsigned long ctrl, thread_switch_control;
0032
0033
0034 if (!prep_irq_for_idle())
0035 return;
0036
0037 ctrl = mfspr(SPRN_CTRLF);
0038
0039
0040 thread_switch_control = mfspr(SPRN_TSC_CELL);
0041 thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST;
0042
0043 switch (ctrl & CTRL_CT) {
0044 case CTRL_CT0:
0045 thread_switch_control |= TSC_CELL_DEC_ENABLE_0;
0046 break;
0047 case CTRL_CT1:
0048 thread_switch_control |= TSC_CELL_DEC_ENABLE_1;
0049 break;
0050 default:
0051 printk(KERN_WARNING "%s: unknown configuration\n",
0052 __func__);
0053 break;
0054 }
0055 mtspr(SPRN_TSC_CELL, thread_switch_control);
0056
0057
0058
0059
0060
0061 HMT_low();
0062
0063
0064
0065
0066
0067
0068 ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);
0069 mtspr(SPRN_CTRLT, ctrl);
0070
0071
0072 __hard_irq_enable();
0073 }
0074
0075 static int cbe_system_reset_exception(struct pt_regs *regs)
0076 {
0077 switch (regs->msr & SRR1_WAKEMASK) {
0078 case SRR1_WAKEDEC:
0079 set_dec(1);
0080 break;
0081 case SRR1_WAKEEE:
0082
0083
0084
0085
0086
0087 break;
0088 case SRR1_WAKEMT:
0089 return cbe_sysreset_hack();
0090 #ifdef CONFIG_CBE_RAS
0091 case SRR1_WAKESYSERR:
0092 cbe_system_error_exception(regs);
0093 break;
0094 case SRR1_WAKETHERM:
0095 cbe_thermal_exception(regs);
0096 break;
0097 #endif
0098 default:
0099
0100 return 0;
0101 }
0102
0103 return 1;
0104 }
0105
0106 void __init cbe_pervasive_init(void)
0107 {
0108 int cpu;
0109
0110 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
0111 return;
0112
0113 for_each_possible_cpu(cpu) {
0114 struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);
0115 if (!regs)
0116 continue;
0117
0118
0119 out_be64(®s->pmcr, in_be64(®s->pmcr) |
0120 CBE_PMD_PAUSE_ZERO_CONTROL);
0121 }
0122
0123 ppc_md.power_save = cbe_power_save;
0124 ppc_md.system_reset_exception = cbe_system_reset_exception;
0125 }