1/* 2 * arch/sh/kernel/cpu/sh4a/sleep-sh_mobile.S 3 * 4 * Sleep mode and Standby modes support for SuperH Mobile 5 * 6 * Copyright (C) 2009 Magnus Damm 7 * 8 * This file is subject to the terms and conditions of the GNU General Public 9 * License. See the file "COPYING" in the main directory of this archive 10 * for more details. 11 */ 12 13#include <linux/sys.h> 14#include <linux/errno.h> 15#include <linux/linkage.h> 16#include <asm/asm-offsets.h> 17#include <asm/suspend.h> 18 19/* manage self-refresh and enter standby mode. 20 * this code will be copied to on-chip memory and executed from there. 21 */ 22 23 .balign 4096,0,4096 24ENTRY(sh_mobile_standby) 25 mov r4, r0 26 27 tst #SUSP_SH_SF, r0 28 bt skip_set_sf 29#ifdef CONFIG_CPU_SUBTYPE_SH7724 30 /* DBSC: put memory in self-refresh mode */ 31 32 mov.l dben_reg, r4 33 mov.l dben_data0, r1 34 mov.l r1, @r4 35 36 mov.l dbrfpdn0_reg, r4 37 mov.l dbrfpdn0_data0, r1 38 mov.l r1, @r4 39 40 mov.l dbcmdcnt_reg, r4 41 mov.l dbcmdcnt_data0, r1 42 mov.l r1, @r4 43 44 mov.l dbcmdcnt_reg, r4 45 mov.l dbcmdcnt_data1, r1 46 mov.l r1, @r4 47 48 mov.l dbrfpdn0_reg, r4 49 mov.l dbrfpdn0_data1, r1 50 mov.l r1, @r4 51#else 52 /* SBSC: disable power down and put in self-refresh mode */ 53 mov.l 1f, r4 54 mov.l 2f, r1 55 mov.l @r4, r2 56 or r1, r2 57 mov.l 3f, r3 58 and r3, r2 59 mov.l r2, @r4 60#endif 61 62skip_set_sf: 63 tst #SUSP_SH_SLEEP, r0 64 bt test_standby 65 66 /* set mode to "sleep mode" */ 67 bra do_sleep 68 mov #0x00, r1 69 70test_standby: 71 tst #SUSP_SH_STANDBY, r0 72 bt test_rstandby 73 74 /* set mode to "software standby mode" */ 75 bra do_sleep 76 mov #0x80, r1 77 78test_rstandby: 79 tst #SUSP_SH_RSTANDBY, r0 80 bt test_ustandby 81 82 /* set mode to "r-standby mode" */ 83 bra do_sleep 84 mov #0x20, r1 85 86test_ustandby: 87 tst #SUSP_SH_USTANDBY, r0 88 bt done_sleep 89 90 /* set mode to "u-standby mode" */ 91 mov #0x10, r1 92 93 /* fall-through */ 94 95do_sleep: 96 /* setup and enter selected standby mode */ 97 mov.l 5f, r4 98 mov.l r1, @r4 99 sleep 100 101done_sleep: 102 /* reset standby mode to sleep mode */ 103 mov.l 5f, r4 104 mov #0x00, r1 105 mov.l r1, @r4 106 107 tst #SUSP_SH_SF, r0 108 bt skip_restore_sf 109 110#ifdef CONFIG_CPU_SUBTYPE_SH7724 111 /* DBSC: put memory in auto-refresh mode */ 112 113 mov.l dbrfpdn0_reg, r4 114 mov.l dbrfpdn0_data0, r1 115 mov.l r1, @r4 116 117 /* sleep 140 ns */ 118 nop 119 nop 120 nop 121 nop 122 123 mov.l dbcmdcnt_reg, r4 124 mov.l dbcmdcnt_data0, r1 125 mov.l r1, @r4 126 127 mov.l dbcmdcnt_reg, r4 128 mov.l dbcmdcnt_data1, r1 129 mov.l r1, @r4 130 131 mov.l dben_reg, r4 132 mov.l dben_data1, r1 133 mov.l r1, @r4 134 135 mov.l dbrfpdn0_reg, r4 136 mov.l dbrfpdn0_data2, r1 137 mov.l r1, @r4 138#else 139 /* SBSC: set auto-refresh mode */ 140 mov.l 1f, r4 141 mov.l @r4, r2 142 mov.l 4f, r3 143 and r3, r2 144 mov.l r2, @r4 145 mov.l 6f, r4 146 mov.l 7f, r1 147 mov.l 8f, r2 148 mov.l @r4, r3 149 mov #-1, r4 150 add r4, r3 151 or r2, r3 152 mov.l r3, @r1 153#endif 154skip_restore_sf: 155 rts 156 nop 157 158 .balign 4 159#ifdef CONFIG_CPU_SUBTYPE_SH7724 160dben_reg: .long 0xfd000010 /* DBEN */ 161dben_data0: .long 0 162dben_data1: .long 1 163dbrfpdn0_reg: .long 0xfd000040 /* DBRFPDN0 */ 164dbrfpdn0_data0: .long 0 165dbrfpdn0_data1: .long 1 166dbrfpdn0_data2: .long 0x00010000 167dbcmdcnt_reg: .long 0xfd000014 /* DBCMDCNT */ 168dbcmdcnt_data0: .long 2 169dbcmdcnt_data1: .long 4 170#else 1711: .long 0xfe400008 /* SDCR0 */ 1722: .long 0x00000400 1733: .long 0xffff7fff 1744: .long 0xfffffbff 175#endif 1765: .long 0xa4150020 /* STBCR */ 1776: .long 0xfe40001c /* RTCOR */ 1787: .long 0xfe400018 /* RTCNT */ 1798: .long 0xa55a0000 180 181/* interrupt vector @ 0x600 */ 182 .balign 0x400,0,0x400 183 .long 0xdeadbeef 184 .balign 0x200,0,0x200 185 /* sh7722 will end up here in sleep mode */ 186 rte 187 nop 188sh_mobile_standby_end: 189 190ENTRY(sh_mobile_standby_size) 191 .long sh_mobile_standby_end - sh_mobile_standby 192