PageRenderTime 22ms CodeModel.GetById 13ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/frv/kernel/sleep.S

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