]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/sunxi/psci.S
Merge branch 'zynq' of git://www.denx.de/git/u-boot-microblaze
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / sunxi / psci.S
1 /*
2  * Copyright (C) 2013 - ARM Ltd
3  * Author: Marc Zyngier <marc.zyngier@arm.com>
4  *
5  * Based on code by Carl van Schaik <carl@ok-labs.com>.
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 version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <asm/psci.h>
22 #include <asm/arch/cpu.h>
23
24 /*
25  * Memory layout:
26  *
27  * SECURE_RAM to text_end :
28  *      ._secure_text section
29  * text_end to ALIGN_PAGE(text_end):
30  *      nothing
31  * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000)
32  *      1kB of stack per CPU (4 CPUs max).
33  */
34
35         .pushsection ._secure.text, "ax"
36
37         .arch_extension sec
38
39 #define ONE_MS                  (CONFIG_SYS_CLK_FREQ / 1000)
40 #define TEN_MS                  (10 * ONE_MS)
41
42 .macro  timer_wait      reg, ticks
43         @ Program CNTP_TVAL
44         movw    \reg, #(\ticks & 0xffff)
45         movt    \reg, #(\ticks >> 16)
46         mcr     p15, 0, \reg, c14, c2, 0
47         isb
48         @ Enable physical timer, mask interrupt
49         mov     \reg, #3
50         mcr     p15, 0, \reg, c14, c2, 1
51         @ Poll physical timer until ISTATUS is on
52 1:      isb
53         mrc     p15, 0, \reg, c14, c2, 1
54         ands    \reg, \reg, #4
55         bne     1b
56         @ Disable timer
57         mov     \reg, #0
58         mcr     p15, 0, \reg, c14, c2, 1
59         isb
60 .endm
61
62 .globl  psci_arch_init
63 psci_arch_init:
64         mrc     p15, 0, r5, c1, c1, 0   @ Read SCR
65         bic     r5, r5, #1              @ Secure mode
66         mcr     p15, 0, r5, c1, c1, 0   @ Write SCR
67         isb
68
69         mrc     p15, 0, r4, c0, c0, 5   @ MPIDR
70         and     r4, r4, #3              @ cpu number in cluster
71         mov     r5, #400                @ 1kB of stack per CPU
72         mul     r4, r4, r5
73
74         adr     r5, text_end            @ end of text
75         add     r5, r5, #0x2000         @ Skip two pages
76         lsr     r5, r5, #12             @ Align to start of page
77         lsl     r5, r5, #12
78         sub     sp, r5, r4              @ here's our stack!
79
80         bx      lr
81
82         @ r1 = target CPU
83         @ r2 = target PC
84 .globl  psci_cpu_on
85 psci_cpu_on:
86         adr     r0, _target_pc
87         str     r2, [r0]
88         dsb
89
90         movw    r0, #(SUNXI_CPUCFG_BASE & 0xffff)
91         movt    r0, #(SUNXI_CPUCFG_BASE >> 16)
92
93         @ CPU mask
94         and     r1, r1, #3      @ only care about first cluster
95         mov     r4, #1
96         lsl     r4, r4, r1
97
98         adr     r6, _sunxi_cpu_entry
99         str     r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector)
100
101         @ Assert reset on target CPU
102         mov     r6, #0
103         lsl     r5, r1, #6      @ 64 bytes per CPU
104         add     r5, r5, #0x40   @ Offset from base
105         add     r5, r5, r0      @ CPU control block
106         str     r6, [r5]        @ Reset CPU
107
108         @ l1 invalidate
109         ldr     r6, [r0, #0x184]
110         bic     r6, r6, r4
111         str     r6, [r0, #0x184]
112
113         @ Lock CPU
114         ldr     r6, [r0, #0x1e4]
115         bic     r6, r6, r4
116         str     r6, [r0, #0x1e4]
117
118         @ Release power clamp
119         movw    r6, #0x1ff
120         movt    r6, #0
121 1:      lsrs    r6, r6, #1
122         str     r6, [r0, #0x1b0]
123         bne     1b
124
125         timer_wait r1, TEN_MS
126
127         @ Clear power gating
128         ldr     r6, [r0, #0x1b4]
129         bic     r6, r6, #1
130         str     r6, [r0, #0x1b4]
131
132         @ Deassert reset on target CPU
133         mov     r6, #3
134         str     r6, [r5]
135
136         @ Unlock CPU
137         ldr     r6, [r0, #0x1e4]
138         orr     r6, r6, r4
139         str     r6, [r0, #0x1e4]
140
141         mov     r0, #ARM_PSCI_RET_SUCCESS       @ Return PSCI_RET_SUCCESS
142         mov     pc, lr
143
144 _target_pc:
145         .word   0
146
147 _sunxi_cpu_entry:
148         @ Set SMP bit
149         mrc     p15, 0, r0, c1, c0, 1
150         orr     r0, r0, #0x40
151         mcr     p15, 0, r0, c1, c0, 1
152         isb
153
154         bl      _nonsec_init
155         bl      psci_arch_init
156
157         adr     r0, _target_pc
158         ldr     r0, [r0]
159         b       _do_nonsec_entry
160
161 text_end:
162         .popsection