sleep.S 9.6 KB

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