^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Low-level PXA250/210 sleep/wakeUp support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Initial SA1110 code:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Adapted for PXA by Nicolas Pitre:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2002 Monta Vista Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * modify it under the terms of the GNU General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/assembler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <mach/hardware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <mach/smemc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <mach/pxa2xx-regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define MDREFR_KDIV 0x200a4000 // all banks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #ifdef CONFIG_PXA3xx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * pxa3xx_finish_suspend() - forces CPU into sleep state (S2D3C4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ENTRY(pxa3xx_finish_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) mov r0, #0x06 @ S2D3C4 mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) mcr p14, 0, r0, c7, c0, 0 @ enter sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 20: b 20b @ waiting for sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #endif /* CONFIG_PXA3xx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #ifdef CONFIG_PXA27x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * pxa27x_finish_suspend()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Forces CPU into sleep state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * r0 = value for PWRMODE M field for desired sleep state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ENTRY(pxa27x_finish_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) @ Put the processor to sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) @ (also workaround for sighting 28071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) @ prepare value for sleep mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mov r1, r0 @ sleep mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) @ prepare pointer to physical address 0 (virtual mapping in generic.c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) mov r2, #UNCACHED_PHYS_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) @ prepare SDRAM refresh settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ldr r4, =MDREFR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ldr r5, [r4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) @ enable SDRAM self-refresh mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) orr r5, r5, #MDREFR_SLFRSH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ldr r6, =MDREFR_KDIV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) orr r5, r5, r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) @ Intel PXA270 Specification Update notes problems sleeping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) @ with core operating above 91 MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) @ (see Errata 50, ...processor does not exit from sleep...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ldr r6, =CCCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ldr r8, [r6] @ keep original value for resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ldr r7, =CCCR_SLEEP @ prepare CCCR sleep value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) mov r0, #0x2 @ prepare value for CLKCFG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) @ align execution to a cache line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) b pxa_cpu_do_suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #ifdef CONFIG_PXA25x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * pxa25x_finish_suspend()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * Forces CPU into sleep state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * r0 = value for PWRMODE M field for desired sleep state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ENTRY(pxa25x_finish_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) @ prepare value for sleep mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mov r1, r0 @ sleep mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) @ prepare pointer to physical address 0 (virtual mapping in generic.c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) mov r2, #UNCACHED_PHYS_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) @ prepare SDRAM refresh settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ldr r4, =MDREFR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ldr r5, [r4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) @ enable SDRAM self-refresh mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) orr r5, r5, #MDREFR_SLFRSH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) @ Intel PXA255 Specification Update notes problems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) @ about suspending with PXBus operating above 133MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) @ (see Errata 31, GPIO output signals, ... unpredictable in sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) @
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) @ We keep the change-down close to the actual suspend on SDRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) @ as possible to eliminate messing about with the refresh clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) @ as the system will restore with the original speed settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) @
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) @ Ben Dooks, 13-Sep-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ldr r6, =CCCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ldr r8, [r6] @ keep original value for resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) @ ensure x1 for run and turbo mode with memory clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) bic r7, r8, #CCCR_M_MASK | CCCR_N_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) orr r7, r7, #(1<<5) | (2<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) @ check that the memory frequency is within limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) and r14, r7, #CCCR_L_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) teq r14, #1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) bicne r7, r7, #CCCR_L_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) orrne r7, r7, #1 @@ 99.53MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) @ get ready for the change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) @ note, turbo is not preserved over sleep so there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) @ point in preserving it here. we save it on the stack with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) @ other CP registers instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) mcr p14, 0, r0, c6, c0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) orr r0, r0, #2 @ initiate change bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) b pxa_cpu_do_suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .ltorg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) pxa_cpu_do_suspend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) @ All needed values are now in registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) @ These last instructions should be in cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) @ initiate the frequency change...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) str r7, [r6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) mcr p14, 0, r0, c6, c0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) @ restore the original cpu speed value for resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) str r8, [r6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) @ need 6 13-MHz cycles before changing PWRMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) @ just set frequency to 91-MHz... 6*91/13 = 42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) mov r0, #42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 10: subs r0, r0, #1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) bne 10b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) @ Do not reorder...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) @ Intel PXA270 Specification Update notes problems performing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) @ external accesses after SDRAM is put in self-refresh mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) @ (see Errata 38 ...hangs when entering self-refresh mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) @ force address lines low by reading at physical address 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ldr r3, [r2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) @ put SDRAM into self-refresh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) str r5, [r4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) @ enter sleep mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) mcr p14, 0, r1, c7, c0, 0 @ PWRMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 20: b 20b @ loop waiting for sleep