lite5200_sleep.S 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #include <asm/reg.h>
  3. #include <asm/ppc_asm.h>
  4. #include <asm/processor.h>
  5. #include <asm/cache.h>
  6. #define SDRAM_CTRL 0x104
  7. #define SC_MODE_EN (1<<31)
  8. #define SC_CKE (1<<30)
  9. #define SC_REF_EN (1<<28)
  10. #define SC_SOFT_PRE (1<<1)
  11. #define GPIOW_GPIOE 0xc00
  12. #define GPIOW_DDR 0xc08
  13. #define GPIOW_DVO 0xc0c
  14. #define CDM_CE 0x214
  15. #define CDM_SDRAM (1<<3)
  16. /* helpers... beware: r10 and r4 are overwritten */
  17. #define SAVE_SPRN(reg, addr) \
  18. mfspr r10, SPRN_##reg; \
  19. stw r10, ((addr)*4)(r4);
  20. #define LOAD_SPRN(reg, addr) \
  21. lwz r10, ((addr)*4)(r4); \
  22. mtspr SPRN_##reg, r10; \
  23. sync; \
  24. isync;
  25. .data
  26. registers:
  27. .space 0x5c*4
  28. .text
  29. /* ---------------------------------------------------------------------- */
  30. /* low-power mode with help of M68HLC908QT1 */
  31. .globl lite5200_low_power
  32. lite5200_low_power:
  33. mr r7, r3 /* save SRAM va */
  34. mr r8, r4 /* save MBAR va */
  35. /* setup wakeup address for u-boot at physical location 0x0 */
  36. lis r3, CONFIG_KERNEL_START@h
  37. lis r4, lite5200_wakeup@h
  38. ori r4, r4, lite5200_wakeup@l
  39. sub r4, r4, r3
  40. stw r4, 0(r3)
  41. /*
  42. * save stuff BDI overwrites
  43. * 0xf0 (0xe0->0x100 gets overwritten when BDI connected;
  44. * even when CONFIG_BDI* is disabled and MMU XLAT commented; heisenbug?))
  45. * WARNING: self-refresh doesn't seem to work when BDI2000 is connected,
  46. * possibly because BDI sets SDRAM registers before wakeup code does
  47. */
  48. lis r4, registers@h
  49. ori r4, r4, registers@l
  50. lwz r10, 0xf0(r3)
  51. stw r10, (0x1d*4)(r4)
  52. /* save registers to r4 [destroys r10] */
  53. SAVE_SPRN(LR, 0x1c)
  54. bl save_regs
  55. /* flush caches [destroys r3, r4] */
  56. bl flush_data_cache
  57. /* copy code to sram */
  58. mr r4, r7
  59. li r3, (sram_code_end - sram_code)/4
  60. mtctr r3
  61. lis r3, sram_code@h
  62. ori r3, r3, sram_code@l
  63. 1:
  64. lwz r5, 0(r3)
  65. stw r5, 0(r4)
  66. addi r3, r3, 4
  67. addi r4, r4, 4
  68. bdnz 1b
  69. /* get tb_ticks_per_usec */
  70. lis r3, tb_ticks_per_usec@h
  71. lwz r11, tb_ticks_per_usec@l(r3)
  72. /* disable I and D caches */
  73. mfspr r3, SPRN_HID0
  74. ori r3, r3, HID0_ICE | HID0_DCE
  75. xori r3, r3, HID0_ICE | HID0_DCE
  76. sync; isync;
  77. mtspr SPRN_HID0, r3
  78. sync; isync;
  79. /* jump to sram */
  80. mtlr r7
  81. blrl
  82. /* doesn't return */
  83. sram_code:
  84. /* self refresh */
  85. lwz r4, SDRAM_CTRL(r8)
  86. /* send NOP (precharge) */
  87. oris r4, r4, SC_MODE_EN@h /* mode_en */
  88. stw r4, SDRAM_CTRL(r8)
  89. sync
  90. ori r4, r4, SC_SOFT_PRE /* soft_pre */
  91. stw r4, SDRAM_CTRL(r8)
  92. sync
  93. xori r4, r4, SC_SOFT_PRE
  94. xoris r4, r4, SC_MODE_EN@h /* !mode_en */
  95. stw r4, SDRAM_CTRL(r8)
  96. sync
  97. /* delay (for NOP to finish) */
  98. li r12, 1
  99. bl udelay
  100. /*
  101. * mode_en must not be set when enabling self-refresh
  102. * send AR with CKE low (self-refresh)
  103. */
  104. oris r4, r4, (SC_REF_EN | SC_CKE)@h
  105. xoris r4, r4, (SC_CKE)@h /* ref_en !cke */
  106. stw r4, SDRAM_CTRL(r8)
  107. sync
  108. /* delay (after !CKE there should be two cycles) */
  109. li r12, 1
  110. bl udelay
  111. /* disable clock */
  112. lwz r4, CDM_CE(r8)
  113. ori r4, r4, CDM_SDRAM
  114. xori r4, r4, CDM_SDRAM
  115. stw r4, CDM_CE(r8)
  116. sync
  117. /* delay a bit */
  118. li r12, 1
  119. bl udelay
  120. /* turn off with QT chip */
  121. li r4, 0x02
  122. stb r4, GPIOW_GPIOE(r8) /* enable gpio_wkup1 */
  123. sync
  124. stb r4, GPIOW_DVO(r8) /* "output" high */
  125. sync
  126. stb r4, GPIOW_DDR(r8) /* output */
  127. sync
  128. stb r4, GPIOW_DVO(r8) /* output high */
  129. sync
  130. /* 10uS delay */
  131. li r12, 10
  132. bl udelay
  133. /* turn off */
  134. li r4, 0
  135. stb r4, GPIOW_DVO(r8) /* output low */
  136. sync
  137. /* wait until we're offline */
  138. 1:
  139. b 1b
  140. /* local udelay in sram is needed */
  141. udelay: /* r11 - tb_ticks_per_usec, r12 - usecs, overwrites r13 */
  142. mullw r12, r12, r11
  143. mftb r13 /* start */
  144. addi r12, r13, r12 /* end */
  145. 1:
  146. mftb r13 /* current */
  147. cmp cr0, r13, r12
  148. blt 1b
  149. blr
  150. sram_code_end:
  151. /* uboot jumps here on resume */
  152. lite5200_wakeup:
  153. bl restore_regs
  154. /* HIDs, MSR */
  155. LOAD_SPRN(HID1, 0x19)
  156. LOAD_SPRN(HID2, 0x1a)
  157. /* address translation is tricky (see turn_on_mmu) */
  158. mfmsr r10
  159. ori r10, r10, MSR_DR | MSR_IR
  160. mtspr SPRN_SRR1, r10
  161. lis r10, mmu_on@h
  162. ori r10, r10, mmu_on@l
  163. mtspr SPRN_SRR0, r10
  164. sync
  165. rfi
  166. mmu_on:
  167. /* kernel offset (r4 is still set from restore_registers) */
  168. addis r4, r4, CONFIG_KERNEL_START@h
  169. /* restore MSR */
  170. lwz r10, (4*0x1b)(r4)
  171. mtmsr r10
  172. sync; isync;
  173. /* invalidate caches */
  174. mfspr r10, SPRN_HID0
  175. ori r5, r10, HID0_ICFI | HID0_DCI
  176. mtspr SPRN_HID0, r5 /* invalidate caches */
  177. sync; isync;
  178. mtspr SPRN_HID0, r10
  179. sync; isync;
  180. /* enable caches */
  181. lwz r10, (4*0x18)(r4)
  182. mtspr SPRN_HID0, r10 /* restore (enable caches, DPM) */
  183. /* ^ this has to be after address translation set in MSR */
  184. sync
  185. isync
  186. /* restore 0xf0 (BDI2000) */
  187. lis r3, CONFIG_KERNEL_START@h
  188. lwz r10, (0x1d*4)(r4)
  189. stw r10, 0xf0(r3)
  190. LOAD_SPRN(LR, 0x1c)
  191. blr
  192. /* ---------------------------------------------------------------------- */
  193. /* boring code: helpers */
  194. /* save registers */
  195. #define SAVE_BAT(n, addr) \
  196. SAVE_SPRN(DBAT##n##L, addr); \
  197. SAVE_SPRN(DBAT##n##U, addr+1); \
  198. SAVE_SPRN(IBAT##n##L, addr+2); \
  199. SAVE_SPRN(IBAT##n##U, addr+3);
  200. #define SAVE_SR(n, addr) \
  201. mfsr r10, n; \
  202. stw r10, ((addr)*4)(r4);
  203. #define SAVE_4SR(n, addr) \
  204. SAVE_SR(n, addr); \
  205. SAVE_SR(n+1, addr+1); \
  206. SAVE_SR(n+2, addr+2); \
  207. SAVE_SR(n+3, addr+3);
  208. save_regs:
  209. stw r0, 0(r4)
  210. stw r1, 0x4(r4)
  211. stw r2, 0x8(r4)
  212. stmw r11, 0xc(r4) /* 0xc -> 0x5f, (0x18*4-1) */
  213. SAVE_SPRN(HID0, 0x18)
  214. SAVE_SPRN(HID1, 0x19)
  215. SAVE_SPRN(HID2, 0x1a)
  216. mfmsr r10
  217. stw r10, (4*0x1b)(r4)
  218. /*SAVE_SPRN(LR, 0x1c) have to save it before the call */
  219. /* 0x1d reserved by 0xf0 */
  220. SAVE_SPRN(RPA, 0x1e)
  221. SAVE_SPRN(SDR1, 0x1f)
  222. /* save MMU regs */
  223. SAVE_BAT(0, 0x20)
  224. SAVE_BAT(1, 0x24)
  225. SAVE_BAT(2, 0x28)
  226. SAVE_BAT(3, 0x2c)
  227. SAVE_BAT(4, 0x30)
  228. SAVE_BAT(5, 0x34)
  229. SAVE_BAT(6, 0x38)
  230. SAVE_BAT(7, 0x3c)
  231. SAVE_4SR(0, 0x40)
  232. SAVE_4SR(4, 0x44)
  233. SAVE_4SR(8, 0x48)
  234. SAVE_4SR(12, 0x4c)
  235. SAVE_SPRN(SPRG0, 0x50)
  236. SAVE_SPRN(SPRG1, 0x51)
  237. SAVE_SPRN(SPRG2, 0x52)
  238. SAVE_SPRN(SPRG3, 0x53)
  239. SAVE_SPRN(SPRG4, 0x54)
  240. SAVE_SPRN(SPRG5, 0x55)
  241. SAVE_SPRN(SPRG6, 0x56)
  242. SAVE_SPRN(SPRG7, 0x57)
  243. SAVE_SPRN(IABR, 0x58)
  244. SAVE_SPRN(DABR, 0x59)
  245. SAVE_SPRN(TBRL, 0x5a)
  246. SAVE_SPRN(TBRU, 0x5b)
  247. blr
  248. /* restore registers */
  249. #define LOAD_BAT(n, addr) \
  250. LOAD_SPRN(DBAT##n##L, addr); \
  251. LOAD_SPRN(DBAT##n##U, addr+1); \
  252. LOAD_SPRN(IBAT##n##L, addr+2); \
  253. LOAD_SPRN(IBAT##n##U, addr+3);
  254. #define LOAD_SR(n, addr) \
  255. lwz r10, ((addr)*4)(r4); \
  256. mtsr n, r10;
  257. #define LOAD_4SR(n, addr) \
  258. LOAD_SR(n, addr); \
  259. LOAD_SR(n+1, addr+1); \
  260. LOAD_SR(n+2, addr+2); \
  261. LOAD_SR(n+3, addr+3);
  262. restore_regs:
  263. lis r4, registers@h
  264. ori r4, r4, registers@l
  265. /* MMU is not up yet */
  266. subis r4, r4, CONFIG_KERNEL_START@h
  267. lwz r0, 0(r4)
  268. lwz r1, 0x4(r4)
  269. lwz r2, 0x8(r4)
  270. lmw r11, 0xc(r4)
  271. /*
  272. * these are a bit tricky
  273. *
  274. * 0x18 - HID0
  275. * 0x19 - HID1
  276. * 0x1a - HID2
  277. * 0x1b - MSR
  278. * 0x1c - LR
  279. * 0x1d - reserved by 0xf0 (BDI2000)
  280. */
  281. LOAD_SPRN(RPA, 0x1e);
  282. LOAD_SPRN(SDR1, 0x1f);
  283. /* restore MMU regs */
  284. LOAD_BAT(0, 0x20)
  285. LOAD_BAT(1, 0x24)
  286. LOAD_BAT(2, 0x28)
  287. LOAD_BAT(3, 0x2c)
  288. LOAD_BAT(4, 0x30)
  289. LOAD_BAT(5, 0x34)
  290. LOAD_BAT(6, 0x38)
  291. LOAD_BAT(7, 0x3c)
  292. LOAD_4SR(0, 0x40)
  293. LOAD_4SR(4, 0x44)
  294. LOAD_4SR(8, 0x48)
  295. LOAD_4SR(12, 0x4c)
  296. /* rest of regs */
  297. LOAD_SPRN(SPRG0, 0x50);
  298. LOAD_SPRN(SPRG1, 0x51);
  299. LOAD_SPRN(SPRG2, 0x52);
  300. LOAD_SPRN(SPRG3, 0x53);
  301. LOAD_SPRN(SPRG4, 0x54);
  302. LOAD_SPRN(SPRG5, 0x55);
  303. LOAD_SPRN(SPRG6, 0x56);
  304. LOAD_SPRN(SPRG7, 0x57);
  305. LOAD_SPRN(IABR, 0x58);
  306. LOAD_SPRN(DABR, 0x59);
  307. LOAD_SPRN(TBWL, 0x5a); /* these two have separate R/W regs */
  308. LOAD_SPRN(TBWU, 0x5b);
  309. blr
  310. /* cache flushing code. copied from arch/ppc/boot/util.S */
  311. #define NUM_CACHE_LINES (128*8)
  312. /*
  313. * Flush data cache
  314. * Do this by just reading lots of stuff into the cache.
  315. */
  316. flush_data_cache:
  317. lis r3,CONFIG_KERNEL_START@h
  318. ori r3,r3,CONFIG_KERNEL_START@l
  319. li r4,NUM_CACHE_LINES
  320. mtctr r4
  321. 1:
  322. lwz r4,0(r3)
  323. addi r3,r3,L1_CACHE_BYTES /* Next line, please */
  324. bdnz 1b
  325. blr