Path: blob/master/arch/powerpc/platforms/cell/pervasive.c
10818 views
/*1* CBE Pervasive Monitor and Debug2*3* (C) Copyright IBM Corporation 20054*5* Authors: Maximino Aguilar ([email protected])6* Michael N. Day ([email protected])7*8* This program is free software; you can redistribute it and/or modify9* it under the terms of the GNU General Public License as published by10* the Free Software Foundation; either version 2, or (at your option)11* any later version.12*13* This program is distributed in the hope that it will be useful,14* but WITHOUT ANY WARRANTY; without even the implied warranty of15* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16* GNU General Public License for more details.17*18* You should have received a copy of the GNU General Public License19* along with this program; if not, write to the Free Software20* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.21*/2223#undef DEBUG2425#include <linux/interrupt.h>26#include <linux/irq.h>27#include <linux/percpu.h>28#include <linux/types.h>29#include <linux/kallsyms.h>3031#include <asm/io.h>32#include <asm/machdep.h>33#include <asm/prom.h>34#include <asm/pgtable.h>35#include <asm/reg.h>36#include <asm/cell-regs.h>3738#include "pervasive.h"3940static void cbe_power_save(void)41{42unsigned long ctrl, thread_switch_control;4344/*45* We need to hard disable interrupts, the local_irq_enable() done by46* our caller upon return will hard re-enable.47*/48hard_irq_disable();4950ctrl = mfspr(SPRN_CTRLF);5152/* Enable DEC and EE interrupt request */53thread_switch_control = mfspr(SPRN_TSC_CELL);54thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST;5556switch (ctrl & CTRL_CT) {57case CTRL_CT0:58thread_switch_control |= TSC_CELL_DEC_ENABLE_0;59break;60case CTRL_CT1:61thread_switch_control |= TSC_CELL_DEC_ENABLE_1;62break;63default:64printk(KERN_WARNING "%s: unknown configuration\n",65__func__);66break;67}68mtspr(SPRN_TSC_CELL, thread_switch_control);6970/*71* go into low thread priority, medium priority will be72* restored for us after wake-up.73*/74HMT_low();7576/*77* atomically disable thread execution and runlatch.78* External and Decrementer exceptions are still handled when the79* thread is disabled but now enter in cbe_system_reset_exception()80*/81ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);82mtspr(SPRN_CTRLT, ctrl);83}8485static int cbe_system_reset_exception(struct pt_regs *regs)86{87switch (regs->msr & SRR1_WAKEMASK) {88case SRR1_WAKEEE:89do_IRQ(regs);90break;91case SRR1_WAKEDEC:92timer_interrupt(regs);93break;94case SRR1_WAKEMT:95return cbe_sysreset_hack();96#ifdef CONFIG_CBE_RAS97case SRR1_WAKESYSERR:98cbe_system_error_exception(regs);99break;100case SRR1_WAKETHERM:101cbe_thermal_exception(regs);102break;103#endif /* CONFIG_CBE_RAS */104default:105/* do system reset */106return 0;107}108/* everything handled */109return 1;110}111112void __init cbe_pervasive_init(void)113{114int cpu;115116if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))117return;118119for_each_possible_cpu(cpu) {120struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);121if (!regs)122continue;123124/* Enable Pause(0) control bit */125out_be64(®s->pmcr, in_be64(®s->pmcr) |126CBE_PMD_PAUSE_ZERO_CONTROL);127}128129ppc_md.power_save = cbe_power_save;130ppc_md.system_reset_exception = cbe_system_reset_exception;131}132133134