at v2.6.13 374 lines 9.9 kB view raw
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