Merge tag 'mfd-for-linus-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
[pandora-kernel.git] / arch / arm / mach-exynos / sleep.S
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3  *              http://www.samsung.com
4  *
5  * Exynos low-level resume code
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <linux/linkage.h>
19 #include <asm/asm-offsets.h>
20 #include <asm/hardware/cache-l2x0.h>
21 #include "smc.h"
22
23 #define CPU_MASK        0xff0ffff0
24 #define CPU_CORTEX_A9   0x410fc090
25
26         /*
27          * The following code is located into the .data section. This is to
28          * allow l2x0_regs_phys to be accessed with a relative load while we
29          * can't rely on any MMU translation. We could have put l2x0_regs_phys
30          * in the .text section as well, but some setups might insist on it to
31          * be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
32          */
33         .data
34         .align
35
36         /*
37          * sleep magic, to allow the bootloader to check for an valid
38          * image to resume to. Must be the first word before the
39          * exynos_cpu_resume entry.
40          */
41
42         .word   0x2bedf00d
43
44         /*
45          * exynos_cpu_resume
46          *
47          * resume code entry for bootloader to call
48          */
49
50 ENTRY(exynos_cpu_resume)
51 #ifdef CONFIG_CACHE_L2X0
52         mrc     p15, 0, r0, c0, c0, 0
53         ldr     r1, =CPU_MASK
54         and     r0, r0, r1
55         ldr     r1, =CPU_CORTEX_A9
56         cmp     r0, r1
57         bleq    l2c310_early_resume
58 #endif
59         b       cpu_resume
60 ENDPROC(exynos_cpu_resume)
61
62         .align
63
64 ENTRY(exynos_cpu_resume_ns)
65         mrc     p15, 0, r0, c0, c0, 0
66         ldr     r1, =CPU_MASK
67         and     r0, r0, r1
68         ldr     r1, =CPU_CORTEX_A9
69         cmp     r0, r1
70         bne     skip_cp15
71
72         adr     r0, cp15_save_power
73         ldr     r1, [r0]
74         adr     r0, cp15_save_diag
75         ldr     r2, [r0]
76         mov     r0, #SMC_CMD_C15RESUME
77         dsb
78         smc     #0
79 #ifdef CONFIG_CACHE_L2X0
80         adr     r0, 1f
81         ldr     r2, [r0]
82         add     r0, r2, r0
83
84         /* Check that the address has been initialised. */
85         ldr     r1, [r0, #L2X0_R_PHY_BASE]
86         teq     r1, #0
87         beq     skip_l2x0
88
89         /* Check if controller has been enabled. */
90         ldr     r2, [r1, #L2X0_CTRL]
91         tst     r2, #0x1
92         bne     skip_l2x0
93
94         ldr     r1, [r0, #L2X0_R_TAG_LATENCY]
95         ldr     r2, [r0, #L2X0_R_DATA_LATENCY]
96         ldr     r3, [r0, #L2X0_R_PREFETCH_CTRL]
97         mov     r0, #SMC_CMD_L2X0SETUP1
98         smc     #0
99
100         /* Reload saved regs pointer because smc corrupts registers. */
101         adr     r0, 1f
102         ldr     r2, [r0]
103         add     r0, r2, r0
104
105         ldr     r1, [r0, #L2X0_R_PWR_CTRL]
106         ldr     r2, [r0, #L2X0_R_AUX_CTRL]
107         mov     r0, #SMC_CMD_L2X0SETUP2
108         smc     #0
109
110         mov     r0, #SMC_CMD_L2X0INVALL
111         smc     #0
112
113         mov     r1, #1
114         mov     r0, #SMC_CMD_L2X0CTRL
115         smc     #0
116 skip_l2x0:
117 #endif /* CONFIG_CACHE_L2X0 */
118 skip_cp15:
119         b       cpu_resume
120 ENDPROC(exynos_cpu_resume_ns)
121         .globl cp15_save_diag
122 cp15_save_diag:
123         .long   0       @ cp15 diagnostic
124         .globl cp15_save_power
125 cp15_save_power:
126         .long   0       @ cp15 power control
127
128 #ifdef CONFIG_CACHE_L2X0
129         .align
130 1:      .long   l2x0_saved_regs - .
131 #endif /* CONFIG_CACHE_L2X0 */