root/arch/unicore32/kernel/sleep.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * linux/arch/unicore32/kernel/sleep.S
   4  *
   5  * Code specific to PKUnity SoC and UniCore ISA
   6  *
   7  *      Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
   8  *      Copyright (C) 2001-2010 Guan Xuetao
   9  */
  10 
  11 #include <linux/linkage.h>
  12 #include <asm/assembler.h>
  13 #include <mach/hardware.h>
  14 
  15                 .text
  16 
  17 pkunity_cpu_save_cp:
  18 
  19         @ get coprocessor registers
  20 
  21         movc    r3, p0.c7, #0                   @ PID
  22         movc    r4, p0.c2, #0                   @ translation table base addr
  23         movc    r5, p0.c1, #0                   @ control reg
  24 
  25 
  26         @ store them plus current virtual stack ptr on stack
  27         mov     r6, sp
  28         stm.w   (r3 - r6), [sp-]
  29 
  30         mov     pc, lr
  31 
  32 pkunity_cpu_save_sp:
  33         @ preserve phys address of stack
  34         mov     r0, sp
  35         stw.w   lr, [sp+], #-4
  36         b.l     sleep_phys_sp
  37         ldw     r1, =sleep_save_sp
  38         stw     r0, [r1]
  39         ldw.w   pc, [sp]+, #4
  40 
  41 /*
  42  * puv3_cpu_suspend()
  43  *
  44  * Forces CPU into sleep state.
  45  *
  46  * r0 = value for PWRMODE M field for desired sleep state
  47  */
  48 
  49 ENTRY(puv3_cpu_suspend)
  50         stm.w   (r16 - r27, lr), [sp-]          @ save registers on stack
  51         stm.w   (r4 - r15), [sp-]               @ save registers on stack
  52 
  53 #ifdef  CONFIG_UNICORE_FPU_F64
  54         sfm.w   (f0  - f7 ), [sp-]
  55         sfm.w   (f8  - f15), [sp-]
  56         sfm.w   (f16 - f23), [sp-]
  57         sfm.w   (f24 - f31), [sp-]
  58         cff     r4, s31
  59         stm.w   (r4), [sp-]
  60 #endif
  61         b.l     pkunity_cpu_save_cp
  62 
  63         b.l     pkunity_cpu_save_sp
  64 
  65         @ clean data cache
  66         mov     r1, #0
  67         movc    p0.c5, r1, #14
  68         nop
  69         nop
  70         nop
  71         nop
  72 
  73 
  74 
  75         @ DDR2 BaseAddr
  76         ldw     r0, =(PKUNITY_DDR2CTRL_BASE)
  77 
  78         @ PM BaseAddr
  79         ldw     r1, =(PKUNITY_PM_BASE)
  80 
  81         @ set PLL_SYS_CFG reg, 275
  82         movl    r6, #0x00002401
  83         stw     r6, [r1+], #0x18
  84         @ set PLL_DDR_CFG reg, 66MHz
  85         movl    r6, #0x00100c00
  86         stw     r6, [r1+], #0x1c
  87 
  88         @ set wake up source
  89         movl    r8, #0x800001ff         @ epip4d
  90         stw     r8, [r1+], #0xc
  91 
  92         @ set PGSR
  93         movl    r5, #0x40000
  94         stw     r5, [r1+], #0x10
  95 
  96         @ prepare DDR2 refresh settings
  97         ldw     r5, [r0+], #0x24
  98         or      r5, r5, #0x00000001
  99 
 100         @ prepare PMCR for PLL changing
 101         movl    r6, #0xc
 102 
 103         @ prepare for closing PLL
 104         movl    r7, #0x1
 105 
 106         @ prepare sleep mode
 107         mov     r8, #0x1
 108 
 109 @       movl    r0, 0x11111111
 110 @       put_word_ocd r0
 111         b       pkunity_cpu_do_suspend
 112 
 113         .ltorg
 114         .align  5
 115 pkunity_cpu_do_suspend:
 116         b       101f
 117         @ put DDR2 into self-refresh
 118 100:    stw     r5, [r0+], #0x24
 119         @ change PLL
 120         stw     r6, [r1]
 121         b       1f
 122 
 123         .ltorg
 124         .align  5
 125 101:    b       102f
 126         @ wait for PLL changing complete
 127 1:      ldw     r6, [r1+], #0x44
 128         csub.a  r6, #0x1
 129         bne     1b
 130         b       2f
 131 
 132         .ltorg
 133         .align  5
 134 102:    b       100b
 135         @ close PLL
 136 2:      stw     r7, [r1+], #0x4
 137         @ enter sleep mode
 138         stw     r8, [r1]
 139 3:      b       3b
 140 
 141 
 142 
 143 
 144 /*
 145  * puv3_cpu_resume()
 146  *
 147  * entry point from bootloader into kernel during resume
 148  *
 149  * Note: Yes, part of the following code is located into the .data section.
 150  *       This is to allow sleep_save_sp to be accessed with a relative load
 151  *       while we can't rely on any MMU translation.  We could have put
 152  *       sleep_save_sp in the .text section as well, but some setups might
 153  *       insist on it to be truly read-only.
 154  */
 155 
 156         .data
 157         .align 5
 158 ENTRY(puv3_cpu_resume)
 159 @       movl    r0, 0x20202020
 160 @       put_word_ocd r0
 161 
 162         ldw     r0, sleep_save_sp               @ stack phys addr
 163         ldw     r2, =resume_after_mmu           @ its absolute virtual address
 164         ldm     (r3 - r6), [r0]+                @ CP regs + virt stack ptr
 165         mov     sp, r6                          @ CP regs + virt stack ptr
 166 
 167         mov     r1, #0
 168         movc    p0.c6, r1, #6                   @ invalidate I & D TLBs
 169         movc    p0.c5, r1, #28                  @ invalidate I & D caches, BTB
 170 
 171         movc    p0.c7, r3, #0                   @ PID
 172         movc    p0.c2, r4, #0                   @ translation table base addr
 173         movc    p0.c1, r5, #0                   @ control reg, turn on mmu
 174         nop
 175         jump    r2
 176         nop
 177         nop
 178         nop
 179         nop
 180         nop
 181 
 182 sleep_save_sp:
 183         .word   0                               @ preserve stack phys ptr here
 184 
 185         .text
 186 resume_after_mmu:
 187 @       movl    r0, 0x30303030
 188 @       put_word_ocd r0
 189 
 190 #ifdef  CONFIG_UNICORE_FPU_F64
 191         lfm.w   (f0  - f7 ), [sp]+
 192         lfm.w   (f8  - f15), [sp]+
 193         lfm.w   (f16 - f23), [sp]+
 194         lfm.w   (f24 - f31), [sp]+
 195         ldm.w   (r4), [sp]+
 196         ctf     r4, s31
 197 #endif
 198         ldm.w   (r4 - r15), [sp]+               @ restore registers from stack
 199         ldm.w   (r16 - r27, pc), [sp]+          @ return to caller

/* [<][>][^][v][top][bottom][index][help] */