summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/cps-vec.S
diff options
context:
space:
mode:
authorPaul Burton2014-04-14 12:00:56 +0200
committerPaul Burton2014-05-28 17:20:31 +0200
commit3179d37ee1ed602770a8b8ed975bd30faa85b4a3 (patch)
treea644d061f4153008b4821810b258b9afb93ef956 /arch/mips/kernel/cps-vec.S
parentMIPS: smp-cps: use CPC core-other locking (diff)
downloadkernel-qcow2-linux-3179d37ee1ed602770a8b8ed975bd30faa85b4a3.tar.gz
kernel-qcow2-linux-3179d37ee1ed602770a8b8ed975bd30faa85b4a3.tar.xz
kernel-qcow2-linux-3179d37ee1ed602770a8b8ed975bd30faa85b4a3.zip
MIPS: pm-cps: add PM state entry code for CPS systems
This patch adds code to generate entry & exit code for various low power states available on systems based around the MIPS Coherent Processing System architecture (ie. those with a Coherence Manager, Global Interrupt Controller & for >=CM2 a Cluster Power Controller). States supported are: - Non-coherent wait. This state first leaves the coherent domain and then executes a regular MIPS wait instruction. Power savings are found from the elimination of coherency interventions between the core and any other coherent requestors in the system. - Clock gated. This state leaves the coherent domain and then gates the clock input to the core. This removes all dynamic power from the core but leaves the core at the mercy of another to restart its clock. Register state is preserved, but the core can not service interrupts whilst its clock is gated. - Power gated. This deepest state removes all power input to the core. All register state is lost and the core will restart execution from its BEV when another core powers it back up. Because register state is lost this state requires cooperation with the CONFIG_MIPS_CPS SMP implementation in order for the core to exit the state successfully. The code will detect which states are available on the current system during boot & generate the entry/exit code for those states. This will be used by cpuidle & hotplug implementations. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Diffstat (limited to 'arch/mips/kernel/cps-vec.S')
-rw-r--r--arch/mips/kernel/cps-vec.S35
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index 57ec18c7d17f..1c865ae922a5 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -15,6 +15,7 @@
#include <asm/cacheops.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
+#include <asm/pm.h>
#define GCR_CL_COHERENCE_OFS 0x2008
#define GCR_CL_ID_OFS 0x2028
@@ -447,3 +448,37 @@ LEAF(mips_cps_boot_vpes)
jr ra
nop
END(mips_cps_boot_vpes)
+
+#if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)
+
+ /* Calculate a pointer to this CPUs struct mips_static_suspend_state */
+ .macro psstate dest
+ .set push
+ .set noat
+ lw $1, TI_CPU(gp)
+ sll $1, $1, LONGLOG
+ la \dest, __per_cpu_offset
+ addu $1, $1, \dest
+ lw $1, 0($1)
+ la \dest, cps_cpu_state
+ addu \dest, \dest, $1
+ .set pop
+ .endm
+
+LEAF(mips_cps_pm_save)
+ /* Save CPU state */
+ SUSPEND_SAVE_REGS
+ psstate t1
+ SUSPEND_SAVE_STATIC
+ jr v0
+ nop
+ END(mips_cps_pm_save)
+
+LEAF(mips_cps_pm_restore)
+ /* Restore CPU state */
+ psstate t1
+ RESUME_RESTORE_STATIC
+ RESUME_RESTORE_REGS_RETURN
+ END(mips_cps_pm_restore)
+
+#endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */