sleep.S 2.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * SA11x0 Assembler Sleep/WakeUp Management Routines
 *
 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License.
 *
 * History:
 *
 * 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>
21
#include <mach/hardware.h>
L
Linus Torvalds 已提交
22 23 24

		.text
/*
25
 * sa1100_finish_suspend()
L
Linus Torvalds 已提交
26 27 28
 *
 * Causes sa11x0 to enter sleep state
 *
R
Russell King 已提交
29
 * Must be aligned to a cacheline.
L
Linus Torvalds 已提交
30
 */
R
Russell King 已提交
31
	.balign	32
32
ENTRY(sa1100_finish_suspend)
L
Linus Torvalds 已提交
33 34 35
	@ disable clock switching
	mcr	p15, 0, r1, c15, c2, 2

R
Russell King 已提交
36 37 38 39 40
	ldr	r6, =MDREFR
	ldr	r4, [r6]
	orr     r4, r4, #MDREFR_K1DB2
	ldr	r5, =PPCR

41
	@ Pre-load __loop_udelay into the I-cache
R
Russell King 已提交
42
	mov	r0, #1
43
	bl	__loop_udelay
R
Russell King 已提交
44 45 46 47 48 49 50 51
	mov	r0, r0

	@ The following must all exist in a single cache line to
	@ avoid accessing memory until this sequence is complete,
	@ otherwise we occasionally hang.

	@ Adjust memory timing before lowering CPU clock
	str     r4, [r6]
L
Linus Torvalds 已提交
52 53 54 55

	@ delay 90us and set CPU PLL to lowest speed
	@ fixes resume problem on high speed SA1110
	mov	r0, #90
56
	bl	__loop_udelay
L
Linus Torvalds 已提交
57
	mov	r1, #0
R
Russell King 已提交
58
	str	r1, [r5]
L
Linus Torvalds 已提交
59
	mov	r0, #90
60
	bl	__loop_udelay
L
Linus Torvalds 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

	/*
	 * 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
	ldr	r2, =MSC2

85 86 87
	ldr	r3, [r0]
	bic	r3, r3, #FMsk(MSC_RT)
	bic	r3, r3, #FMsk(MSC_RT)<<16
L
Linus Torvalds 已提交
88

89 90 91
	ldr	r4, [r1]
	bic	r4, r4, #FMsk(MSC_RT)
	bic	r4, r4, #FMsk(MSC_RT)<<16
L
Linus Torvalds 已提交
92

93 94 95
	ldr	r5, [r2]
	bic	r5, r5, #FMsk(MSC_RT)
	bic	r5, r5, #FMsk(MSC_RT)<<16
L
Linus Torvalds 已提交
96

97
	ldr	r7, [r6]
R
Russell King 已提交
98 99 100
	bic	r7, r7, #0x0000FF00
	bic	r7, r7, #0x000000F0
	orr	r8, r7, #MDREFR_SLFRSH
L
Linus Torvalds 已提交
101

102 103 104 105
	ldr	r9, =MDCNFG
	ldr	r10, [r9]
	bic	r10, r10, #(MDCNFG_DE0+MDCNFG_DE1)
	bic	r10, r10, #(MDCNFG_DE2+MDCNFG_DE3)
L
Linus Torvalds 已提交
106

107 108
	bic	r11, r8, #MDREFR_SLFRSH
	bic	r11, r11, #MDREFR_E1PIN
L
Linus Torvalds 已提交
109

110
	ldr	r12, =PMCR
L
Linus Torvalds 已提交
111

112
	mov	r13, #PMCR_SF
L
Linus Torvalds 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143

	b	sa1110_sdram_controller_fix

	.align 5
sa1110_sdram_controller_fix:

	@ Step 1 clear RT field of all MSCx registers
	str 	r3, [r0]
	str	r4, [r1]
	str	r5, [r2]

	@ Step 2 clear DRI field in MDREFR
	str	r7, [r6]

	@ Step 3 set SLFRSH bit in MDREFR
	str	r8, [r6]

	@ Step 4 clear DE bis in MDCNFG
	str	r10, [r9]

	@ Step 5 clear DRAM refresh control register
	str	r11, [r6]

	@ Wow, now the hardware suspend request pins can be used, that makes them functional for
	@ about 7 ns out of the	entire time that the CPU is running!

	@ Step 6 set force sleep bit in PMCR

	str	r13, [r12]

20:	b	20b			@ loop waiting for sleep