1/* 2 * linux/arch/arm/mach-pnx4008/sleep.S 3 * 4 * PNX4008 support for STOP mode and SDRAM self-refresh 5 * 6 * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com> 7 * 8 * 2005 (c) MontaVista Software, Inc. This file is licensed under 9 * the terms of the GNU General Public License version 2. This program 10 * is licensed "as is" without any warranty of any kind, whether express 11 * or implied. 12 */ 13 14#include <linux/linkage.h> 15#include <asm/assembler.h> 16#include <mach/hardware.h> 17 18#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE) 19#define PWR_CTRL_REG_OFFS 0x44 20 21#define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE) 22#define MPMC_STATUS_REG_OFFS 0x4 23 24 .text 25 26ENTRY(pnx4008_cpu_suspend) 27 @this function should be entered in Direct run mode. 28 29 @ save registers on stack 30 stmfd sp!, {r0 - r6, lr} 31 32 @ setup Power Manager base address in r4 33 @ and put it's value in r5 34 mov r4, #(PWRMAN_VA_BASE & 0xff000000) 35 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000) 36 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00) 37 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff) 38 ldr r5, [r4, #PWR_CTRL_REG_OFFS] 39 40 @ setup SDRAM controller base address in r2 41 @ and put it's value in r3 42 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000) 43 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000) 44 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00) 45 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff) 46 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround 47 48 @ clear SDRAM self-refresh bit latch 49 and r5, r5, #(~(1 << 8)) 50 @ clear SDRAM self-refresh bit 51 and r5, r5, #(~(1 << 9)) 52 str r5, [r4, #PWR_CTRL_REG_OFFS] 53 54 @ do save current bit settings in r1 55 mov r1, r5 56 57 @ set SDRAM self-refresh bit 58 orr r5, r5, #(1 << 9) 59 str r5, [r4, #PWR_CTRL_REG_OFFS] 60 61 @ set SDRAM self-refresh bit latch 62 orr r5, r5, #(1 << 8) 63 str r5, [r4, #PWR_CTRL_REG_OFFS] 64 65 @ clear SDRAM self-refresh bit latch 66 and r5, r5, #(~(1 << 8)) 67 str r5, [r4, #PWR_CTRL_REG_OFFS] 68 69 @ clear SDRAM self-refresh bit 70 and r5, r5, #(~(1 << 9)) 71 str r5, [r4, #PWR_CTRL_REG_OFFS] 72 73 @ wait for SDRAM to get into self-refresh mode 742: ldr r3, [r2, #MPMC_STATUS_REG_OFFS] 75 tst r3, #(1 << 2) 76 beq 2b 77 78 @ to prepare SDRAM to get out of self-refresh mode after wakeup 79 orr r5, r5, #(1 << 7) 80 str r5, [r4, #PWR_CTRL_REG_OFFS] 81 82 @ do enter stop mode 83 orr r5, r5, #(1 << 0) 84 str r5, [r4, #PWR_CTRL_REG_OFFS] 85 nop 86 nop 87 nop 88 nop 89 nop 90 nop 91 nop 92 nop 93 nop 94 95 @ sleeping now... 96 97 @ coming out of STOP mode into Direct Run mode 98 @ clear STOP mode and SDRAM self-refresh bits 99 str r1, [r4, #PWR_CTRL_REG_OFFS] 100 101 @ wait for SDRAM to get out self-refresh mode 1023: ldr r3, [r2, #MPMC_STATUS_REG_OFFS] 103 tst r3, #5 104 bne 3b 105 106 @ restore regs and return 107 ldmfd sp!, {r0 - r6, pc} 108 109ENTRY(pnx4008_cpu_suspend_sz) 110 .word . - pnx4008_cpu_suspend 111 112ENTRY(pnx4008_cpu_standby) 113 @ save registers on stack 114 stmfd sp!, {r0 - r6, lr} 115 116 @ setup Power Manager base address in r4 117 @ and put it's value in r5 118 mov r4, #(PWRMAN_VA_BASE & 0xff000000) 119 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000) 120 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00) 121 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff) 122 ldr r5, [r4, #PWR_CTRL_REG_OFFS] 123 124 @ setup SDRAM controller base address in r2 125 @ and put it's value in r3 126 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000) 127 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000) 128 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00) 129 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff) 130 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround 131 132 @ clear SDRAM self-refresh bit latch 133 and r5, r5, #(~(1 << 8)) 134 @ clear SDRAM self-refresh bit 135 and r5, r5, #(~(1 << 9)) 136 str r5, [r4, #PWR_CTRL_REG_OFFS] 137 138 @ do save current bit settings in r1 139 mov r1, r5 140 141 @ set SDRAM self-refresh bit 142 orr r5, r5, #(1 << 9) 143 str r5, [r4, #PWR_CTRL_REG_OFFS] 144 145 @ set SDRAM self-refresh bit latch 146 orr r5, r5, #(1 << 8) 147 str r5, [r4, #PWR_CTRL_REG_OFFS] 148 149 @ clear SDRAM self-refresh bit latch 150 and r5, r5, #(~(1 << 8)) 151 str r5, [r4, #PWR_CTRL_REG_OFFS] 152 153 @ clear SDRAM self-refresh bit 154 and r5, r5, #(~(1 << 9)) 155 str r5, [r4, #PWR_CTRL_REG_OFFS] 156 157 @ wait for SDRAM to get into self-refresh mode 1582: ldr r3, [r2, #MPMC_STATUS_REG_OFFS] 159 tst r3, #(1 << 2) 160 beq 2b 161 162 @ set 'get out of self-refresh mode after wakeup' bit 163 orr r5, r5, #(1 << 7) 164 str r5, [r4, #PWR_CTRL_REG_OFFS] 165 166 mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now... 167 168 @ set SDRAM self-refresh bit latch 169 orr r5, r5, #(1 << 8) 170 str r5, [r4, #PWR_CTRL_REG_OFFS] 171 172 @ clear SDRAM self-refresh bit latch 173 and r5, r5, #(~(1 << 8)) 174 str r5, [r4, #PWR_CTRL_REG_OFFS] 175 176 @ wait for SDRAM to get out self-refresh mode 1773: ldr r3, [r2, #MPMC_STATUS_REG_OFFS] 178 tst r3, #5 179 bne 3b 180 181 @ restore regs and return 182 ldmfd sp!, {r0 - r6, pc} 183 184ENTRY(pnx4008_cpu_standby_sz) 185 .word . - pnx4008_cpu_standby 186 187ENTRY(pnx4008_cache_clean_invalidate) 188 stmfd sp!, {r0 - r6, lr} 189#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 190 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache 191#else 1921: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate 193 bne 1b 194#endif 195 ldmfd sp!, {r0 - r6, pc} 196