summaryrefslogtreecommitdiffstats
path: root/kernel/arch/powerpc/platforms/52xx/mpc52xx_sleep.S
blob: 4dc170b0ae1803cccfdc4cb07125aa0823f9512f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
144
145
146
147
148
149
150
151
152
153
154
#include <asm/reg.h>
#include <asm/ppc_asm.h>
#include <asm/processor.h>


.text

_GLOBAL(mpc52xx_deep_sleep)
mpc52xx_deep_sleep: /* args r3-r6: SRAM, SDRAM regs, CDM regs, INTR regs */

	/* enable interrupts */
	mfmsr	r7
	ori	r7, r7, 0x8000 /* EE */
	mtmsr	r7
	sync; isync;

	li	r10, 0 /* flag that irq handler sets */

	/* enable tmr7 (or any other) interrupt */
	lwz	r8, 0x14(r6) /* intr->main_mask */
	ori	r8, r8, 0x1
	xori	r8, r8, 0x1
	stw	r8, 0x14(r6)
	sync

	/* emulate tmr7 interrupt */
	li	r8, 0x1
	stw	r8, 0x40(r6) /* intr->main_emulate */
	sync

	/* wait for it to happen */
1:
	cmpi	cr0, r10, 1
	bne	cr0, 1b

	/* lock icache */
	mfspr	r10, SPRN_HID0
	ori	r10, r10, 0x2000
	sync; isync;
	mtspr	SPRN_HID0, r10
	sync; isync;


	mflr	r9 /* save LR */

	/* jump to sram */
	mtlr	r3
	blrl

	mtlr	r9 /* restore LR */

	/* unlock icache */
	mfspr	r10, SPRN_HID0
	ori	r10, r10, 0x2000
	xori	r10, r10, 0x2000
	sync; isync;
	mtspr	SPRN_HID0, r10
	sync; isync;


	/* return to C code */
	blr


_GLOBAL(mpc52xx_ds_sram)
mpc52xx_ds_sram:
	/* put SDRAM into self-refresh */
	lwz	r8, 0x4(r4)	/* sdram->ctrl */

	oris	r8, r8, 0x8000 /* mode_en */
	stw	r8, 0x4(r4)
	sync

	ori	r8, r8, 0x0002 /* soft_pre */
	stw	r8, 0x4(r4)
	sync
	xori	r8, r8, 0x0002

	xoris	r8, r8, 0x8000 /* !mode_en */
	stw	r8, 0x4(r4)
	sync

	oris	r8, r8, 0x5000
	xoris	r8, r8, 0x4000 /* ref_en !cke */
	stw	r8, 0x4(r4)
	sync

	/* disable SDRAM clock */
	lwz	r8, 0x14(r5) /* cdm->clkenable */
	ori	r8, r8, 0x0008
	xori	r8, r8, 0x0008
	stw	r8, 0x14(r5)
	sync


	/* put mpc5200 to sleep */
	mfmsr	r10
	oris	r10, r10, 0x0004	/* POW = 1 */
	sync; isync;
	mtmsr	r10
	sync; isync;


	/* enable clock */
	lwz	r8, 0x14(r5)
	ori	r8, r8, 0x0008
	stw	r8, 0x14(r5)
	sync

	/* get ram out of self-refresh */
	lwz	r8, 0x4(r4)
	oris	r8, r8, 0x5000 /* cke ref_en */
	stw	r8, 0x4(r4)
	sync

	blr
_GLOBAL(mpc52xx_ds_sram_size)
mpc52xx_ds_sram_size:
	.long $-mpc52xx_ds_sram


/* ### interrupt handler for wakeup from deep-sleep ### */
_GLOBAL(mpc52xx_ds_cached)
mpc52xx_ds_cached:
	mtspr	SPRN_SPRG0, r7
	mtspr	SPRN_SPRG1, r8

	/* disable emulated interrupt */
	mfspr	r7, 311 /* MBAR */
	addi	r7, r7, 0x540	/* intr->main_emul */
	li	r8, 0
	stw	r8, 0(r7)
	sync
	dcbf	0, r7

	/* acknowledge wakeup, so CCS releases power pown */
	mfspr	r7, 311	/* MBAR */
	addi	r7, r7, 0x524	/* intr->enc_status */
	lwz	r8, 0(r7)
	ori	r8, r8, 0x0400
	stw	r8, 0(r7)
	sync
	dcbf	0, r7

	/* flag - we handled the interrupt */
	li	r10, 1

	mfspr	r8, SPRN_SPRG1
	mfspr	r7, SPRN_SPRG0

	rfi
_GLOBAL(mpc52xx_ds_cached_size)
mpc52xx_ds_cached_size:
	.long $-mpc52xx_ds_cached