| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | /* | 
					
						
							|  |  |  |  * linux/arch/unicore32/kernel/sleep.S | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Code specific to PKUnity SoC and UniCore ISA | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
 | 
					
						
							|  |  |  |  *	Copyright (C) 2001-2010 Guan Xuetao | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify
 | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License version 2 as | 
					
						
							|  |  |  |  * published by the Free Software Foundation. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/linkage.h> | 
					
						
							|  |  |  | #include <asm/assembler.h> | 
					
						
							|  |  |  | #include <mach/hardware.h> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		.text | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pkunity_cpu_save_cp: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ get coprocessor registers
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	movc	r3, p0.c7, #0			@ PID
 | 
					
						
							|  |  |  | 	movc	r4, p0.c2, #0			@ translation table base addr
 | 
					
						
							|  |  |  | 	movc	r5, p0.c1, #0			@ control reg
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ store them plus current virtual stack ptr on stack
 | 
					
						
							|  |  |  | 	mov	r6, sp | 
					
						
							|  |  |  | 	stm.w	(r3 - r6), [sp-] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mov	pc, lr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pkunity_cpu_save_sp: | 
					
						
							|  |  |  | 	@ preserve phys address of stack
 | 
					
						
							|  |  |  | 	mov	r0, sp | 
					
						
							|  |  |  | 	stw.w	lr, [sp+], #-4 | 
					
						
							|  |  |  | 	b.l	sleep_phys_sp | 
					
						
							|  |  |  | 	ldw	r1, =sleep_save_sp | 
					
						
							|  |  |  | 	stw	r0, [r1] | 
					
						
							|  |  |  | 	ldw.w	pc, [sp]+, #4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * puv3_cpu_suspend() | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Forces CPU into sleep state. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * r0 = value for PWRMODE M field for desired sleep state | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ENTRY(puv3_cpu_suspend) | 
					
						
							|  |  |  | 	stm.w	(r16 - r27, lr), [sp-]		@ save registers on stack
 | 
					
						
							|  |  |  | 	stm.w	(r4 - r15), [sp-]		@ save registers on stack
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef	CONFIG_UNICORE_FPU_F64 | 
					
						
							|  |  |  | 	sfm.w	(f0  - f7 ), [sp-] | 
					
						
							|  |  |  | 	sfm.w	(f8  - f15), [sp-] | 
					
						
							|  |  |  | 	sfm.w	(f16 - f23), [sp-] | 
					
						
							|  |  |  | 	sfm.w	(f24 - f31), [sp-] | 
					
						
							|  |  |  | 	cff	r4, s31 | 
					
						
							|  |  |  | 	stm.w	(r4), [sp-] | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 	b.l	pkunity_cpu_save_cp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	b.l	pkunity_cpu_save_sp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ clean data cache
 | 
					
						
							|  |  |  | 	mov	r1, #0 | 
					
						
							|  |  |  | 	movc	p0.c5, r1, #14 | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ DDR2 BaseAddr
 | 
					
						
							| 
									
										
										
										
											2011-03-04 18:07:48 +08:00
										 |  |  | 	ldw	r0, =(PKUNITY_DDR2CTRL_BASE) | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	@ PM BaseAddr
 | 
					
						
							| 
									
										
										
										
											2011-03-04 18:07:48 +08:00
										 |  |  | 	ldw	r1, =(PKUNITY_PM_BASE) | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	@ set PLL_SYS_CFG reg, 275
 | 
					
						
							|  |  |  | 	movl	r6, #0x00002401 | 
					
						
							|  |  |  | 	stw	r6, [r1+], #0x18 | 
					
						
							|  |  |  | 	@ set PLL_DDR_CFG reg, 66MHz
 | 
					
						
							|  |  |  | 	movl	r6, #0x00100c00 | 
					
						
							|  |  |  | 	stw	r6, [r1+], #0x1c | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ set wake up source
 | 
					
						
							|  |  |  | 	movl	r8, #0x800001ff		@ epip4d
 | 
					
						
							|  |  |  | 	stw	r8, [r1+], #0xc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ set PGSR
 | 
					
						
							|  |  |  | 	movl	r5, #0x40000 | 
					
						
							|  |  |  | 	stw	r5, [r1+], #0x10 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ prepare DDR2 refresh settings
 | 
					
						
							|  |  |  | 	ldw	r5, [r0+], #0x24 | 
					
						
							|  |  |  | 	or	r5, r5, #0x00000001 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ prepare PMCR for PLL changing
 | 
					
						
							|  |  |  | 	movl	r6, #0xc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ prepare for closing PLL
 | 
					
						
							|  |  |  | 	movl	r7, #0x1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@ prepare sleep mode
 | 
					
						
							|  |  |  | 	mov	r8, #0x1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @	movl	r0, 0x11111111
 | 
					
						
							|  |  |  | @	put_word_ocd r0
 | 
					
						
							|  |  |  | 	b	pkunity_cpu_do_suspend | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.ltorg | 
					
						
							|  |  |  | 	.align	5
 | 
					
						
							|  |  |  | pkunity_cpu_do_suspend: | 
					
						
							|  |  |  | 	b	101f | 
					
						
							|  |  |  | 	@ put DDR2 into self-refresh
 | 
					
						
							|  |  |  | 100:	stw	r5, [r0+], #0x24 | 
					
						
							|  |  |  | 	@ change PLL
 | 
					
						
							|  |  |  | 	stw	r6, [r1] | 
					
						
							|  |  |  | 	b	1f | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.ltorg | 
					
						
							|  |  |  | 	.align	5
 | 
					
						
							|  |  |  | 101:	b	102f | 
					
						
							|  |  |  | 	@ wait for PLL changing complete
 | 
					
						
							|  |  |  | 1:	ldw	r6, [r1+], #0x44 | 
					
						
							|  |  |  | 	csub.a	r6, #0x1 | 
					
						
							|  |  |  | 	bne	1b | 
					
						
							|  |  |  | 	b	2f | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.ltorg | 
					
						
							|  |  |  | 	.align	5
 | 
					
						
							|  |  |  | 102:	b	100b | 
					
						
							|  |  |  | 	@ close PLL
 | 
					
						
							|  |  |  | 2:	stw	r7, [r1+], #0x4 | 
					
						
							|  |  |  | 	@ enter sleep mode
 | 
					
						
							|  |  |  | 	stw	r8, [r1] | 
					
						
							|  |  |  | 3:	b	3b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * puv3_cpu_resume() | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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 it to be truly read-only. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.data | 
					
						
							|  |  |  | 	.align 5
 | 
					
						
							|  |  |  | ENTRY(puv3_cpu_resume) | 
					
						
							|  |  |  | @	movl	r0, 0x20202020
 | 
					
						
							|  |  |  | @	put_word_ocd r0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ldw	r0, sleep_save_sp		@ stack phys addr
 | 
					
						
							|  |  |  | 	ldw	r2, =resume_after_mmu		@ its absolute virtual address
 | 
					
						
							|  |  |  | 	ldm	(r3 - r6), [r0]+		@ CP regs + virt stack ptr
 | 
					
						
							|  |  |  | 	mov	sp, r6				@ CP regs + virt stack ptr
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mov	r1, #0 | 
					
						
							|  |  |  | 	movc	p0.c6, r1, #6			@ invalidate I & D TLBs
 | 
					
						
							|  |  |  | 	movc	p0.c5, r1, #28			@ invalidate I & D caches, BTB
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	movc	p0.c7, r3, #0			@ PID
 | 
					
						
							|  |  |  | 	movc	p0.c2, r4, #0			@ translation table base addr
 | 
					
						
							|  |  |  | 	movc	p0.c1, r5, #0			@ control reg, turn on mmu
 | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 	jump	r2 | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sleep_save_sp: | 
					
						
							|  |  |  | 	.word	0				@ preserve stack phys ptr here
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.text | 
					
						
							|  |  |  | resume_after_mmu: | 
					
						
							|  |  |  | @	movl	r0, 0x30303030
 | 
					
						
							|  |  |  | @	put_word_ocd r0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef	CONFIG_UNICORE_FPU_F64 | 
					
						
							|  |  |  | 	lfm.w	(f0  - f7 ), [sp]+ | 
					
						
							|  |  |  | 	lfm.w	(f8  - f15), [sp]+ | 
					
						
							|  |  |  | 	lfm.w	(f16 - f23), [sp]+ | 
					
						
							|  |  |  | 	lfm.w	(f24 - f31), [sp]+ | 
					
						
							|  |  |  | 	ldm.w	(r4), [sp]+ | 
					
						
							|  |  |  | 	ctf	r4, s31 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 	ldm.w	(r4 - r15), [sp]+		@ restore registers from stack
 | 
					
						
							|  |  |  | 	ldm.w	(r16 - r27, pc), [sp]+		@ return to caller
 |