Merge tag 'media/v4.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[deliverable/linux.git] / arch / frv / kernel / sleep.S
1 /* sleep.S: power saving mode entry
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Woodhouse (dwmw2@infradead.org)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13 #include <linux/sys.h>
14 #include <linux/linkage.h>
15 #include <asm/setup.h>
16 #include <asm/segment.h>
17 #include <asm/page.h>
18 #include <asm/ptrace.h>
19 #include <asm/errno.h>
20 #include <asm/cache.h>
21 #include <asm/spr-regs.h>
22
23 #define __addr_MASK 0xfeff9820 /* interrupt controller mask */
24
25 #define __addr_FR55X_DRCN 0xfeff0218 /* Address of DRCN register */
26 #define FR55X_DSTS_OFFSET -4 /* Offset from DRCN to DSTS */
27 #define FR55X_SDRAMC_DSTS_SSI 0x00000002 /* indicates that the SDRAM is in self-refresh mode */
28
29 #define __addr_FR4XX_DRCN 0xfe000430 /* Address of DRCN register */
30 #define FR4XX_DSTS_OFFSET -8 /* Offset from DRCN to DSTS */
31 #define FR4XX_SDRAMC_DSTS_SSI 0x00000001 /* indicates that the SDRAM is in self-refresh mode */
32
33 #define SDRAMC_DRCN_SR 0x00000001 /* transition SDRAM into self-refresh mode */
34
35 .section .bss
36 .balign 8
37 .globl __sleep_save_area
38 __sleep_save_area:
39 .space 16
40
41
42 .text
43 .balign 4
44
45 .macro li v r
46 sethi.p %hi(\v),\r
47 setlo %lo(\v),\r
48 .endm
49
50 #ifdef CONFIG_PM
51 ###############################################################################
52 #
53 # CPU suspension routine
54 # - void frv_cpu_suspend(unsigned long pdm_mode)
55 #
56 ###############################################################################
57 .globl frv_cpu_suspend
58 .type frv_cpu_suspend,@function
59 frv_cpu_suspend:
60
61 #----------------------------------------------------
62 # save hsr0, psr, isr, and lr for resume code
63 #----------------------------------------------------
64 li __sleep_save_area,gr11
65
66 movsg hsr0,gr4
67 movsg psr,gr5
68 movsg isr,gr6
69 movsg lr,gr7
70 stdi gr4,@(gr11,#0)
71 stdi gr6,@(gr11,#8)
72
73 # store the return address from sleep in GR14, and its complement in GR13 as a check
74 li __ramboot_resume,gr14
75 #ifdef CONFIG_MMU
76 # Resume via RAMBOOT# will turn MMU off, so bootloader needs a physical address.
77 sethi.p %hi(__page_offset),gr13
78 setlo %lo(__page_offset),gr13
79 sub gr14,gr13,gr14
80 #endif
81 not gr14,gr13
82
83 #----------------------------------------------------
84 # preload and lock into icache that code which may have to run
85 # when dram is in self-refresh state.
86 #----------------------------------------------------
87 movsg hsr0, gr3
88 li HSR0_ICE,gr4
89 or gr3,gr4,gr3
90 movgs gr3,hsr0
91 or gr3,gr8,gr7 // add the sleep bits for later
92
93 li #__icache_lock_start,gr3
94 li #__icache_lock_end,gr4
95 1: icpl gr3,gr0,#1
96 addi gr3,#L1_CACHE_BYTES,gr3
97 cmp gr4,gr3,icc0
98 bhi icc0,#0,1b
99
100 # disable exceptions
101 movsg psr,gr8
102 andi.p gr8,#~PSR_PIL,gr8
103 andi gr8,~PSR_ET,gr8
104 movgs gr8,psr
105 ori gr8,#PSR_ET,gr8
106
107 srli gr8,#28,gr4
108 subicc gr4,#3,gr0,icc0
109 beq icc0,#0,1f
110 # FR4xx
111 li __addr_FR4XX_DRCN,gr4
112 li FR4XX_SDRAMC_DSTS_SSI,gr5
113 li FR4XX_DSTS_OFFSET,gr6
114 bra __icache_lock_start
115 1:
116 # FR5xx
117 li __addr_FR55X_DRCN,gr4
118 li FR55X_SDRAMC_DSTS_SSI,gr5
119 li FR55X_DSTS_OFFSET,gr6
120 bra __icache_lock_start
121
122 .size frv_cpu_suspend, .-frv_cpu_suspend
123
124 #
125 # the final part of the sleep sequence...
126 # - we want it to be be cacheline aligned so we can lock it into the icache easily
127 # On entry: gr7 holds desired hsr0 sleep value
128 # gr8 holds desired psr sleep value
129 #
130 .balign L1_CACHE_BYTES
131 .type __icache_lock_start,@function
132 __icache_lock_start:
133
134 #----------------------------------------------------
135 # put SDRAM in self-refresh mode
136 #----------------------------------------------------
137
138 # Flush all data in the cache using the DCEF instruction.
139 dcef @(gr0,gr0),#1
140
141 # Stop DMAC transfer
142
143 # Execute dummy load from SDRAM
144 ldi @(gr11,#0),gr11
145
146 # put the SDRAM into self-refresh mode
147 ld @(gr4,gr0),gr11
148 ori gr11,#SDRAMC_DRCN_SR,gr11
149 st gr11,@(gr4,gr0)
150 membar
151
152 # wait for SDRAM to reach self-refresh mode
153 1: ld @(gr4,gr6),gr11
154 andcc gr11,gr5,gr11,icc0
155 beq icc0,#0,1b
156
157 # Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
158 # Set the clock mode (CLKC register) as required.
159 # - At this time, also set the CLKC register P0 bit.
160
161 # Set the HSR0 register PDM field.
162 movgs gr7,hsr0
163
164 # Execute NOP 32 times.
165 .rept 32
166 nop
167 .endr
168
169 #if 0 // Fujitsu recommend to skip this and will update docs.
170 # Release the interrupt mask setting of the MASK register of the
171 # interrupt controller if necessary.
172 sti gr10,@(gr9,#0)
173 membar
174 #endif
175
176 # Set the PSR register ET bit to 1 to enable interrupts.
177 movgs gr8,psr
178
179 ###################################################
180 # this is only reached if waking up via interrupt
181 ###################################################
182
183 # Execute NOP 32 times.
184 .rept 32
185 nop
186 .endr
187
188 #----------------------------------------------------
189 # wake SDRAM from self-refresh mode
190 #----------------------------------------------------
191 ld @(gr4,gr0),gr11
192 andi gr11,#~SDRAMC_DRCN_SR,gr11
193 st gr11,@(gr4,gr0)
194 membar
195 2:
196 ld @(gr4,gr6),gr11 // Wait for it to come back...
197 andcc gr11,gr5,gr0,icc0
198 bne icc0,0,2b
199
200 # wait for the SDRAM to stabilise
201 li 0x0100000,gr3
202 3: subicc gr3,#1,gr3,icc0
203 bne icc0,#0,3b
204
205 # now that DRAM is back, this is the end of the code which gets
206 # locked in icache.
207 __icache_lock_end:
208 .size __icache_lock_start, .-__icache_lock_start
209
210 # Fall-through to the RAMBOOT# wakeup path
211
212 ###############################################################################
213 #
214 # resume from suspend re-entry point reached via RAMBOOT# and bootloader
215 #
216 ###############################################################################
217 __ramboot_resume:
218
219 #----------------------------------------------------
220 # restore hsr0, psr, isr, and leave saved lr in gr7
221 #----------------------------------------------------
222 li __sleep_save_area,gr11
223 #ifdef CONFIG_MMU
224 movsg hsr0,gr4
225 sethi.p %hi(HSR0_EXMMU),gr3
226 setlo %lo(HSR0_EXMMU),gr3
227 andcc gr3,gr4,gr0,icc0
228 bne icc0,#0,2f
229
230 # need to use physical address
231 sethi.p %hi(__page_offset),gr3
232 setlo %lo(__page_offset),gr3
233 sub gr11,gr3,gr11
234
235 # flush all tlb entries
236 setlos #64,gr4
237 setlos.p #PAGE_SIZE,gr5
238 setlos #0,gr6
239 1:
240 tlbpr gr6,gr0,#6,#0
241 subicc.p gr4,#1,gr4,icc0
242 add gr6,gr5,gr6
243 bne icc0,#2,1b
244
245 # need a temporary mapping for the current physical address we are
246 # using between time MMU is enabled and jump to virtual address is
247 # made.
248 sethi.p %hi(0x00000000),gr4
249 setlo %lo(0x00000000),gr4 ; physical address
250 setlos #xAMPRx_L|xAMPRx_M|xAMPRx_SS_256Mb|xAMPRx_S_KERNEL|xAMPRx_V,gr5
251 or gr4,gr5,gr5
252
253 movsg cxnr,gr13
254 or gr4,gr13,gr4
255
256 movgs gr4,iamlr1 ; mapped from real address 0
257 movgs gr5,iampr1 ; cached kernel memory at 0x00000000
258 2:
259 #endif
260
261 lddi @(gr11,#0),gr4 ; hsr0, psr
262 lddi @(gr11,#8),gr6 ; isr, lr
263 movgs gr4,hsr0
264 bar
265
266 #ifdef CONFIG_MMU
267 sethi.p %hi(1f),gr11
268 setlo %lo(1f),gr11
269 jmpl @(gr11,gr0)
270 1:
271 movgs gr0,iampr1 ; get rid of temporary mapping
272 #endif
273 movgs gr5,psr
274 movgs gr6,isr
275
276 #----------------------------------------------------
277 # unlock the icache which was locked before going to sleep
278 #----------------------------------------------------
279 li __icache_lock_start,gr3
280 li __icache_lock_end,gr4
281 1: icul gr3
282 addi gr3,#L1_CACHE_BYTES,gr3
283 cmp gr4,gr3,icc0
284 bhi icc0,#0,1b
285
286 #----------------------------------------------------
287 # back to business as usual
288 #----------------------------------------------------
289 jmpl @(gr7,gr0) ;
290
291 #endif /* CONFIG_PM */
292
293 ###############################################################################
294 #
295 # CPU core sleep mode routine
296 #
297 ###############################################################################
298 .globl frv_cpu_core_sleep
299 .type frv_cpu_core_sleep,@function
300 frv_cpu_core_sleep:
301
302 # Preload into icache.
303 li #__core_sleep_icache_lock_start,gr3
304 li #__core_sleep_icache_lock_end,gr4
305
306 1: icpl gr3,gr0,#1
307 addi gr3,#L1_CACHE_BYTES,gr3
308 cmp gr4,gr3,icc0
309 bhi icc0,#0,1b
310
311 bra __core_sleep_icache_lock_start
312
313 .balign L1_CACHE_BYTES
314 __core_sleep_icache_lock_start:
315
316 # (1) Set the PSR register ET bit to 0 to disable interrupts.
317 movsg psr,gr8
318 andi.p gr8,#~(PSR_PIL),gr8
319 andi gr8,#~(PSR_ET),gr4
320 movgs gr4,psr
321
322 #if 0 // Fujitsu recommend to skip this and will update docs.
323 # (2) Set '1' to all bits in the MASK register of the interrupt
324 # controller and mask interrupts.
325 sethi.p %hi(__addr_MASK),gr9
326 setlo %lo(__addr_MASK),gr9
327 sethi.p %hi(0xffff0000),gr4
328 setlo %lo(0xffff0000),gr4
329 ldi @(gr9,#0),gr10
330 sti gr4,@(gr9,#0)
331 #endif
332 # (3) Flush all data in the cache using the DCEF instruction.
333 dcef @(gr0,gr0),#1
334
335 # (4) Execute the memory barrier instruction
336 membar
337
338 # (5) Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
339 # (6) Set the clock mode (CLKC register) as required.
340 # - At this time, also set the CLKC register P0 bit.
341 # (7) Set the HSR0 register PDM field to 001 .
342 movsg hsr0,gr4
343 ori gr4,HSR0_PDM_CORE_SLEEP,gr4
344 movgs gr4,hsr0
345
346 # (8) Execute NOP 32 times.
347 .rept 32
348 nop
349 .endr
350
351 #if 0 // Fujitsu recommend to skip this and will update docs.
352 # (9) Release the interrupt mask setting of the MASK register of the
353 # interrupt controller if necessary.
354 sti gr10,@(gr9,#0)
355 membar
356 #endif
357
358 # (10) Set the PSR register ET bit to 1 to enable interrupts.
359 movgs gr8,psr
360
361 __core_sleep_icache_lock_end:
362
363 # Unlock from icache
364 li __core_sleep_icache_lock_start,gr3
365 li __core_sleep_icache_lock_end,gr4
366 1: icul gr3
367 addi gr3,#L1_CACHE_BYTES,gr3
368 cmp gr4,gr3,icc0
369 bhi icc0,#0,1b
370
371 bralr
372
373 .size frv_cpu_core_sleep, .-frv_cpu_core_sleep
This page took 0.042409 seconds and 5 git commands to generate.