patch-2.4.22 linux-2.4.22/arch/arm/mach-sa1100/sleep.S

Next file: linux-2.4.22/arch/arm/mach-sa1100/sleep.h
Previous file: linux-2.4.22/arch/arm/mach-sa1100/simputer.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/arch/arm/mach-sa1100/sleep.S linux-2.4.22/arch/arm/mach-sa1100/sleep.S
@@ -11,12 +11,17 @@
  * 2001-02-06: Cliff Brake         Initial code
  *
  * 2001-08-29:	Nicolas Pitre	Simplified.
+ *
+ * 2002-05-27:	Nicolas Pitre	Revisited, more cleanup and simplification.
+ *				Storage is on the stack now.
  */
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/hardware.h>
-#include "sleep.h"
+
+
+		.text
 
 /*
  * sa1100_cpu_suspend()
@@ -25,35 +30,25 @@
  *
  */
 
-	.text
-
-ENTRY(sleep_save)	.word	0		@ virtual address of parameter array
-ENTRY(sleep_save_p)	.word	0		@ physical address of parameter array
-
 ENTRY(sa1100_cpu_suspend)
 
-	@ save registers on stack
-	stmfd	sp!, {r4 - r12, lr}
-
-	@ load virtual address for sleep_save array
-	ldr	r4, sleep_save
+	stmfd	sp!, {r4 - r12, lr}		@ save registers on stack
 
-	@ save stack pointer
-	str	sp, [r4, #(SLEEP_SAVE_SP*4)]
-
-	@ save coprocessor registers
-	mrc 	p15, 0, r1, c1, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R1*4)]
-	mrc 	p15, 0, r1, c2, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R2*4)]
-	mrc 	p15, 0, r1, c3, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R3*4)]
-	mrc 	p15, 0, r1, c5, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R5*4)]
-	mrc 	p15, 0, r1, c6, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R6*4)]
-	mrc 	p15, 0, r1, c13, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R13*4)]
+	@ get coprocessor registers
+	mrc 	p15, 0, r4, c3, c0, 0		@ domain ID
+	mrc 	p15, 0, r5, c2, c0, 0		@ translation table base addr
+	mrc	p15, 0, r6, c13, c0, 0		@ PID
+	mrc 	p15, 0, r7, c1, c0, 0		@ control reg
+
+	@ store them plus current virtual stack ptr on stack
+	mov	r8, sp
+	stmfd	sp!, {r4 - r8}
+
+	@ preserve phys address of stack
+	mov	r0, sp
+	bl	sleep_phys_sp
+	ldr	r1, =sleep_save_sp
+	str	r0, [r1]
 
 	@ clean data cache and invalidate WB
 	bl	cpu_sa1100_cache_clean_invalidate_all
@@ -72,32 +67,31 @@
 	@ delay 90us and set CPU PLL to lowest speed
 	@ fixes resume problem on high speed SA1110
 	mov	r0, #90
-	bl	SYMBOL_NAME(udelay)
+	bl	SYMBOL_NAME(__udelay)
 	ldr	r0, =PPCR
 	mov	r1, #0
 	str	r1, [r0]
 	mov	r0, #90
-	bl	SYMBOL_NAME(udelay)
+	bl	SYMBOL_NAME(__udelay)
 
-
-/* setup up register contents for jump to page containing SA1110 SDRAM controller bug fix suspend code
- *
- * r0 points to MSC0 register
- * r1 points to MSC1 register
- * r2 points to MSC2 register
- * r3 is MSC0 value
- * r4 is MSC1 value
- * r5 is MSC2 value
- * r6 points to MDREFR register
- * r7 is first MDREFR value
- * r8 is second MDREFR value
- * r9 is pointer to MDCNFG register
- * r10 is MDCNFG value
- * r11 is third MDREFR value
- * r12 is pointer to PMCR register
- * r13 is PMCR value (1)
- *
- */
+	/*
+	 * SA1110 SDRAM controller workaround.  register values:
+	 *
+	 * r0  = &MSC0
+	 * r1  = &MSC1
+	 * r2  = &MSC2
+	 * r3  = MSC0 value
+	 * r4  = MSC1 value
+	 * r5  = MSC2 value
+	 * r6  = &MDREFR
+	 * r7  = first MDREFR value
+	 * r8  = second MDREFR value
+	 * r9  = &MDCNFG
+	 * r10 = MDCNFG value
+	 * r11 = third MDREFR value
+	 * r12 = &PMCR
+	 * r13 = PMCR value (1)
+	 */
 
 	ldr	r0, =MSC0
 	ldr	r1, =MSC1
@@ -170,69 +164,49 @@
  *
  * entry point from bootloader into kernel during resume
  *
+ * Note: Yes, part of the following code is located into the .data section.
+ *       This is to allow sleep_save_sp to be accessed with a relative load
+ *       while we can't rely on any MMU translation.  We could have put
+ *       sleep_save_sp in the .text section as well, but some setups might
+ *       insist on .text to be truely read-only.
  */
 
+	.data
 	.align 5
 ENTRY(sa1100_cpu_resume)
-
-	@ set SVC, irqs off
-	mov	r0, #I_BIT | MODE_SVC
+	mov	r0, #I_BIT | F_BIT | MODE_SVC	@ set SVC, irqs off
 	msr	cpsr_c, r0
 
-	@ load physical address of sleep_save
-	ldr	r4, sleep_save_p
-
-	@ restore cp15_r3, domain id
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R3*4)]
-	mcr 	p15, 0, r1, c3, c0 ,0
-
-	@ restore cp15_r2, translation table base address
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R2*4)]
-	mcr 	p15, 0, r1, c2, c0 ,0
+	ldr	r0, sleep_save_sp		@ stack phys addr
+	ldr	r2, =resume_after_mmu		@ its absolute virtual address
+	ldmfd	r0, {r4 - r7, sp}		@ CP regs + virt stack ptr
 
 	mov	r1, #0
 	mcr	p15, 0, r1, c8, c7, 0   	@ flush I+D TLBs
 	mcr	p15, 0, r1, c7, c7, 0		@ flush I&D cache
+	mcr	p15, 0, r1, c9, c0, 0		@ invalidate RB
+	mcr     p15, 0, r1, c9, c0, 5		@ allow user space to use RB
 
-	@ get saved cp15 r1 (control register)
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R1*4)]
-
-	@ get address to jump to after turning on MMU
-	ldr	r2, =resume_after_mmu
-
-	cmp	r2, #0
-
-	b	resume_turn_on_mmu
+	mcr 	p15, 0, r4, c3, c0, 0		@ domain ID
+	mcr 	p15, 0, r5, c2, c0, 0		@ translation table base addr
+	mcr	p15, 0, r6, c13, c0, 0		@ PID
+	b	resume_turn_on_mmu		@ cache align execution
 
 	.align 5
 resume_turn_on_mmu:
-
-	@ turn on mmu
-	mcr 	p15, 0, r1, c1, c0 ,0
-
-	@ jump to resume_after_mmu
-	mov	pc, r2
+	mcr 	p15, 0, r7, c1, c0, 0		@ turn on MMU, caches, etc.
+	nop
+	mov	pc, r2				@ jump to virtual addr
+	nop
 	nop
 	nop
 
-	.align 5
-resume_after_mmu:
-
-	@ load virtual address for sleep_save array
-	ldr	r4, sleep_save
-
-	@ restore the rest of CPU state
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R13*4)]
-	mcr	p15, 0, r1, c13, c0, 0
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R5*4)]
-	mcr 	p15, 0, r1, c5, c0 ,0
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R6*4)]
-	mcr 	p15, 0, r1, c6, c0 ,0
-
-	@ restore stack pointer
-	ldr	sp, [r4, #(SLEEP_SAVE_SP*4)]
+sleep_save_sp:
+	.word	0				@ preserve stack phys ptr here
 
-	@ return to caller
-	ldmfd	sp!, {r4 - r12, pc}
+	.text
+resume_after_mmu:
+	mcr     p15, 0, r1, c15, c1, 2		@ enable clock switching
+	ldmfd	sp!, {r4 - r12, pc}		@ return to caller
 
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)