diff mbox

[(sh-2.6.30.y),12/13] stm: pm: Add Hibernation core code

Message ID 1259938375-27499-12-git-send-email-francesco.virlinzi@st.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Francesco VIRLINZI Dec. 4, 2009, 2:52 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/sh/kernel/pm/stm_swsusp.S b/arch/sh/kernel/pm/stm_swsusp.S
new file mode 100644
index 0000000..217ff90
--- /dev/null
+++ b/arch/sh/kernel/pm/stm_swsusp.S
@@ -0,0 +1,169 @@ 
+/*
+ * -------------------------------------------------------------------------
+ * <linux_root>/arch/sh/kernel/pm/stm_swsusp.S
+ * -------------------------------------------------------------------------
+ * Copyright (C) 2009  STMicroelectronics
+ * Author: Francesco M. Virlinzi  <francesco.virlinzi@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License V.2 ONLY.  See linux/COPYING for more information.
+ *
+ * This may not use any stack, nor any variable that is not "NoSave"
+ * ------------------------------------------------------------------------- */
+
+#include <linux/linkage.h>
+
+#define OFF_R8		(0)
+#define OFF_R9		(4 + OFF_R8)
+#define OFF_R10		(4 + OFF_R9)
+#define OFF_R11		(4 + OFF_R10)
+#define OFF_R12		(4 + OFF_R11)
+#define OFF_R13		(4 + OFF_R12)
+#define OFF_R14		(4 + OFF_R13)
+#define OFF_R15		(4 + OFF_R14)
+#define OFF_PR		(4 + OFF_R15)
+#define OFF_SR		(4 + OFF_PR)
+#define OFF_R6_BK	(4 + OFF_SR)
+#define OFF_R7_BK	(4 + OFF_R6_BK)
+
+.text		;
+.balign 32 	;	! to be icache aligned
+
+ENTRY(swsusp_arch_suspend) ;
+/*
+ *	Here I have to save all the registers
+ */
+	mov.l 1f, r0
+	mov.l r8,  @(OFF_R8, r0)
+	mov.l r9,  @(OFF_R9, r0)
+	mov.l r10, @(OFF_R10, r0)
+	mov.l r11, @(OFF_R11, r0)
+	mov.l r12, @(OFF_R12, r0)
+	mov.l r13, @(OFF_R13, r0)
+	mov.l r14, @(OFF_R14, r0)
+	mov.l r15, @(OFF_R15, r0)
+	stc   r6_bank, r1
+	mov.l r1,  @(OFF_R6_BK, r0)
+	stc   r7_bank, r1
+	mov.l r1,  @(OFF_R7_BK, r0)
+
+	sts   pr, r1
+	mov.l r1,  @(OFF_PR, r0)
+	stc   sr, r1
+	mov.l r1,  @(OFF_SR, r0)
+
+	! Now call the swsusp_save
+	mov.l 2f, r0
+	jsr   @r0
+	 nop
+	! Now in r0 there is the returned value of swsusp_save
+	mov.l 1f, r4
+	! Reload the right pr
+	mov.l @(OFF_PR, r4), r1
+	lds   r1, pr
+	rts
+	 nop
+
+.balign 4;
+1:.long swsusp_arch_regs_cpu0;
+2:.long swsusp_save;
+
+#define JUMPER()	        bra 201f;	\
+				 nop;		\
+			200:	bra 200f;	\
+				 nop;	;	\
+			201:
+
+.balign 32 ;		! icache aligned
+ENTRY(swsusp_arch_resume)
+	bra 200f 		! start the jump sequence
+	 nop
+really_swsusp_arch_resume:
+	mov.l 10f, r6 	! load the restore_pblist
+	mov.l @r6, r6
+0:	tst r6, r6 	! check if there are other 'pages'(pbe)
+	bt/s  20f
+	mov #64, r7	! r7 = 64
+	shll r7 	! r7 = 128 dcache line(128 * 32) = 4096...
+
+	JUMPER()
+
+	mov.l @(0, r6), r5 	! the source address
+	mov.l @(4, r6), r4 	! the destination address
+	mov.l @(8, r6), r6 	! the next pbe address
+	mov r5, r3
+	add #32, r3		! the next icache line source address
+1:
+	mov.l @r5+, r0 		! 1.
+	pref  @r3 		! prefect the next icache line
+	movca.l r0, @r4
+	mov.l @r5+, r0		! 2.
+	mov.l r0,   @(4, r4)
+	mov.l @r5+, r0 		! 3.
+	JUMPER()
+
+	mov.l r0, @(8, r4)
+	mov.l @r5+, r0 		! 4.
+	mov.l r0, @(12, r4)
+	mov.l @r5+, r0 		! 5.
+	mov.l r0, @(16, r4)
+	mov.l @r5+, r0 		! 6
+	mov.l r0, @(20, r4)
+
+	JUMPER()
+
+	mov.l @r5 +, r0 	! 7
+	mov.l r0, @(24, r4)
+	mov.l @r5+,  r0 	! 8
+	mov.l r0, @(28, r4)
+	ocbp @r4
+	add  #32,	r4
+	add  #32,	r3
+	dt   r7
+	bf   1b 	! check if the page is complete
+
+	JUMPER()
+
+	bra 0b
+	 nop
+
+20:
+
+	!now restore the previous value...
+	mov.l 11f, r0
+	mov.l @(OFF_R8, r0), r8
+	mov.l @(OFF_R9, r0), r9
+	mov.l @(OFF_R10, r0), r10
+
+	JUMPER()
+
+	mov.l @(OFF_R11, r0), r11
+	mov.l @(OFF_R12, r0), r12
+	mov.l @(OFF_R13, r0), r13
+	mov.l @(OFF_R14, r0), r14
+	mov.l @(OFF_R15, r0), r15
+	mov.l @(OFF_R6_BK, r0), r1
+	ldc r1, r6_bank
+	mov.l @(OFF_R7_BK, r0), r1
+	ldc r1, r7_bank
+
+	JUMPER()
+
+	mov.l 12f, r1
+	jsr @r1
+	 nop
+	mov.l 11f, r0
+	mov.l @(OFF_PR, r0), r1
+	lds r1, pr
+	mov.l @(OFF_SR, r0), r1
+	ldc r1, sr
+	rts
+	 mov #0, r0
+
+200:	bra really_swsusp_arch_resume
+	 nop
+
+.balign 4			;
+10:.long restore_pblist		;
+11:.long swsusp_arch_regs_cpu0	;
+12:.long flush_cache_all	;