123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /*
- * 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
- ldw r0, =(PKUNITY_DDR2CTRL_BASE)
- @ PM BaseAddr
- ldw r1, =(PKUNITY_PM_BASE)
- @ 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
|