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