ARMV7: Add support for Samsung ORIGEN board
[platform/kernel/u-boot.git] / board / samsung / origen / lowlevel_init.S
1 /*
2  * Lowlevel setup for ORIGEN board based on S5PV310
3  *
4  * Copyright (C) 2011 Samsung Electronics
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <config.h>
26 #include <version.h>
27 #include <asm/arch/cpu.h>
28 #include "origen_setup.h"
29 /*
30  * Register usages:
31  *
32  * r5 has zero always
33  * r7 has GPIO part1 base 0x11400000
34  * r6 has GPIO part2 base 0x11000000
35  */
36
37 _TEXT_BASE:
38         .word   CONFIG_SYS_TEXT_BASE
39
40         .globl lowlevel_init
41 lowlevel_init:
42         push    {lr}
43
44         /* r5 has always zero */
45         mov     r5, #0
46         ldr     r7, =S5PC210_GPIO_PART1_BASE
47         ldr     r6, =S5PC210_GPIO_PART2_BASE
48
49         /* check reset status */
50         ldr     r0, =(S5PC210_POWER_BASE + INFORM1_OFFSET)
51         ldr     r1, [r0]
52
53         /* AFTR wakeup reset */
54         ldr     r2, =S5P_CHECK_DIDLE
55         cmp     r1, r2
56         beq     exit_wakeup
57
58         /* LPA wakeup reset */
59         ldr     r2, =S5P_CHECK_LPA
60         cmp     r1, r2
61         beq     exit_wakeup
62
63         /* Sleep wakeup reset */
64         ldr     r2, =S5P_CHECK_SLEEP
65         cmp     r1, r2
66         beq     wakeup_reset
67
68         /*
69          * If U-boot is already running in ram, no need to relocate U-Boot.
70          * Memory controller must be configured before relocating U-Boot
71          * in ram.
72          */
73         ldr     r0, =0x0ffffff          /* r0 <- Mask Bits*/
74         bic     r1, pc, r0              /* pc <- current addr of code */
75                                         /* r1 <- unmasked bits of pc */
76         ldr     r2, _TEXT_BASE          /* r2 <- original base addr in ram */
77         bic     r2, r2, r0              /* r2 <- unmasked bits of r2*/
78         cmp     r1, r2                  /* compare r1, r2 */
79         beq     1f                      /* r0 == r1 then skip sdram init */
80
81         /* init system clock */
82         bl system_clock_init
83
84         /* Memory initialize */
85         bl mem_ctrl_asm_init
86
87 1:
88         /* for UART */
89         bl uart_asm_init
90         bl tzpc_init
91         pop     {pc}
92
93 wakeup_reset:
94         bl system_clock_init
95         bl mem_ctrl_asm_init
96         bl tzpc_init
97
98 exit_wakeup:
99         /* Load return address and jump to kernel */
100         ldr     r0, =(S5PC210_POWER_BASE + INFORM0_OFFSET)
101
102         /* r1 = physical address of s5pc210_cpu_resume function */
103         ldr     r1, [r0]
104
105         /* Jump to kernel*/
106         mov     pc, r1
107         nop
108         nop
109
110 /*
111  * system_clock_init: Initialize core clock and bus clock.
112  * void system_clock_init(void)
113  */
114 system_clock_init:
115         push    {lr}
116         ldr     r0, =S5PC210_CLOCK_BASE
117
118         /* APLL(1), MPLL(1), CORE(0), HPM(0) */
119         ldr     r1, =CLK_SRC_CPU_VAL
120         ldr     r2, =CLK_SRC_CPU_OFFSET
121         str     r1, [r0, r2]
122
123         /* wait ?us */
124         mov     r1, #0x10000
125 2:      subs    r1, r1, #1
126         bne     2b
127
128         ldr     r1, =CLK_SRC_TOP0_VAL
129         ldr     r2, =CLK_SRC_TOP0_OFFSET
130         str     r1, [r0, r2]
131
132         ldr     r1, =CLK_SRC_TOP1_VAL
133         ldr     r2, =CLK_SRC_TOP1_OFFSET
134         str     r1, [r0, r2]
135
136         /* DMC */
137         ldr     r1, =CLK_SRC_DMC_VAL
138         ldr     r2, =CLK_SRC_DMC_OFFSET
139         str     r1, [r0, r2]
140
141         /*CLK_SRC_LEFTBUS */
142         ldr     r1, =CLK_SRC_LEFTBUS_VAL
143         ldr     r2, =CLK_SRC_LEFTBUS_OFFSET
144         str     r1, [r0, r2]
145
146         /*CLK_SRC_RIGHTBUS */
147         ldr     r1, =CLK_SRC_RIGHTBUS_VAL
148         ldr     r2, =CLK_SRC_RIGHTBUS_OFFSET
149         str     r1, [r0, r2]
150
151         /* SATA: SCLKMPLL(0), MMC[0:4]: SCLKMPLL(6) */
152         ldr     r1, =CLK_SRC_FSYS_VAL
153         ldr     r2, =CLK_SRC_FSYS_OFFSET
154         str     r1, [r0, r2]
155
156         /* UART[0:4] */
157         ldr     r1, =CLK_SRC_PERIL0_VAL
158         ldr     r2, =CLK_SRC_PERIL0_OFFSET
159         str     r1, [r0, r2]
160
161         /* wait ?us */
162         mov     r1, #0x10000
163 3:      subs    r1, r1, #1
164         bne     3b
165
166         /* CLK_DIV_CPU0 */
167         ldr     r1, =CLK_DIV_CPU0_VAL
168         ldr     r2, =CLK_DIV_CPU0_OFFSET
169         str     r1, [r0, r2]
170
171         /* CLK_DIV_CPU1 */
172         ldr     r1, =CLK_DIV_CPU1_VAL
173         ldr     r2, =CLK_DIV_CPU1_OFFSET
174         str     r1, [r0, r2]
175
176         /* CLK_DIV_DMC0 */
177         ldr     r1, =CLK_DIV_DMC0_VAL
178         ldr     r2, =CLK_DIV_DMC0_OFFSET
179         str     r1, [r0, r2]
180
181         /*CLK_DIV_DMC1 */
182         ldr     r1, =CLK_DIV_DMC1_VAL
183         ldr     r2, =CLK_DIV_DMC1_OFFSET
184         str     r1, [r0, r2]
185
186         /* CLK_DIV_LEFTBUS */
187         ldr     r1, =CLK_DIV_LEFTBUS_VAL
188         ldr     r2, =CLK_DIV_LEFTBUS_OFFSET
189         str     r1, [r0, r2]
190
191         /* CLK_DIV_RIGHTBUS */
192         ldr     r1, =CLK_DIV_RIGHTBUS_VAL
193         ldr     r2, =CLK_DIV_RIGHTBUS_OFFSET
194         str     r1, [r0, r2]
195
196         /* CLK_DIV_TOP */
197         ldr     r1, =CLK_DIV_TOP_VAL
198         ldr     r2, =CLK_DIV_TOP_OFFSET
199         str     r1, [r0, r2]
200
201         /* MMC[0:1] */
202         ldr     r1, =CLK_DIV_FSYS1_VAL          /* 800(MPLL) / (15 + 1) */
203         ldr     r2, =CLK_DIV_FSYS1_OFFSET
204         str     r1, [r0, r2]
205
206         /* MMC[2:3] */
207         ldr     r1, =CLK_DIV_FSYS2_VAL          /* 800(MPLL) / (15 + 1) */
208         ldr     r2, =CLK_DIV_FSYS2_OFFSET
209         str     r1, [r0, r2]
210
211         /* MMC4 */
212         ldr     r1, =CLK_DIV_FSYS3_VAL          /* 800(MPLL) / (15 + 1) */
213         ldr     r2, =CLK_DIV_FSYS3_OFFSET
214         str     r1, [r0, r2]
215
216         /* CLK_DIV_PERIL0: UART Clock Divisors */
217         ldr     r1, =CLK_DIV_PERIL0_VAL
218         ldr     r2, =CLK_DIV_PERIL0_OFFSET
219         str     r1, [r0, r2]
220
221         /* Set PLL locktime */
222         ldr     r1, =PLL_LOCKTIME
223         ldr     r2, =APLL_LOCK_OFFSET
224         str     r1, [r0, r2]
225
226         ldr     r1, =PLL_LOCKTIME
227         ldr     r2, =MPLL_LOCK_OFFSET
228         str     r1, [r0, r2]
229
230         ldr     r1, =PLL_LOCKTIME
231         ldr     r2, =EPLL_LOCK_OFFSET
232         str     r1, [r0, r2]
233
234         ldr     r1, =PLL_LOCKTIME
235         ldr     r2, =VPLL_LOCK_OFFSET
236         str     r1, [r0, r2]
237
238         /* APLL_CON1 */
239         ldr     r1, =APLL_CON1_VAL
240         ldr     r2, =APLL_CON1_OFFSET
241         str     r1, [r0, r2]
242
243         /* APLL_CON0 */
244         ldr     r1, =APLL_CON0_VAL
245         ldr     r2, =APLL_CON0_OFFSET
246         str     r1, [r0, r2]
247
248         /* MPLL_CON1 */
249         ldr     r1, =MPLL_CON1_VAL
250         ldr     r2, =MPLL_CON1_OFFSET
251         str     r1, [r0, r2]
252
253         /* MPLL_CON0 */
254         ldr     r1, =MPLL_CON0_VAL
255         ldr     r2, =MPLL_CON0_OFFSET
256         str     r1, [r0, r2]
257
258         /* EPLL */
259         ldr     r1, =EPLL_CON1_VAL
260         ldr     r2, =EPLL_CON1_OFFSET
261         str     r1, [r0, r2]
262
263         /* EPLL_CON0 */
264         ldr     r1, =EPLL_CON0_VAL
265         ldr     r2, =EPLL_CON0_OFFSET
266         str     r1, [r0, r2]
267
268         /* VPLL_CON1 */
269         ldr     r1, =VPLL_CON1_VAL
270         ldr     r2, =VPLL_CON1_OFFSET
271         str     r1, [r0, r2]
272
273         /* VPLL_CON0 */
274         ldr     r1, =VPLL_CON0_VAL
275         ldr     r2, =VPLL_CON0_OFFSET
276         str     r1, [r0, r2]
277
278         /* wait ?us */
279         mov     r1, #0x30000
280 4:      subs    r1, r1, #1
281         bne     4b
282
283         pop     {pc}
284 /*
285  * uart_asm_init: Initialize UART in asm mode, 115200bps fixed.
286  * void uart_asm_init(void)
287  */
288         .globl uart_asm_init
289 uart_asm_init:
290
291         /* setup UART0-UART3 GPIOs (part1) */
292         mov     r0, r7
293         ldr     r1, =S5PC210_GPIO_A0_CON_VAL
294         str     r1, [r0, #S5PC210_GPIO_A0_CON_OFFSET]
295         ldr     r1, =S5PC210_GPIO_A1_CON_VAL
296         str     r1, [r0, #S5PC210_GPIO_A1_CON_OFFSET]
297
298         ldr r0, =S5PC210_UART_BASE
299         add r0, r0, #S5PC210_DEFAULT_UART_OFFSET
300
301         ldr     r1, =ULCON_VAL
302         str     r1, [r0, #ULCON_OFFSET]
303         ldr     r1, =UCON_VAL
304         str     r1, [r0, #UCON_OFFSET]
305         ldr     r1, =UFCON_VAL
306         str     r1, [r0, #UFCON_OFFSET]
307         ldr     r1, =UBRDIV_VAL
308         str     r1, [r0, #UBRDIV_OFFSET]
309         ldr     r1, =UFRACVAL_VAL
310         str     r1, [r0, #UFRACVAL_OFFSET]
311         mov     pc, lr
312         nop
313         nop
314         nop
315
316 /* Setting TZPC[TrustZone Protection Controller] */
317 tzpc_init:
318         ldr     r0, =TZPC0_BASE
319         mov     r1, #R0SIZE
320         str     r1, [r0]
321         mov     r1, #DECPROTXSET
322         str     r1, [r0, #TZPC_DECPROT0SET_OFFSET]
323         str     r1, [r0, #TZPC_DECPROT1SET_OFFSET]
324         str     r1, [r0, #TZPC_DECPROT2SET_OFFSET]
325         str     r1, [r0, #TZPC_DECPROT3SET_OFFSET]
326
327         ldr     r0, =TZPC1_BASE
328         str     r1, [r0, #TZPC_DECPROT0SET_OFFSET]
329         str     r1, [r0, #TZPC_DECPROT1SET_OFFSET]
330         str     r1, [r0, #TZPC_DECPROT2SET_OFFSET]
331         str     r1, [r0, #TZPC_DECPROT3SET_OFFSET]
332
333         ldr     r0, =TZPC2_BASE
334         str     r1, [r0, #TZPC_DECPROT0SET_OFFSET]
335         str     r1, [r0, #TZPC_DECPROT1SET_OFFSET]
336         str     r1, [r0, #TZPC_DECPROT2SET_OFFSET]
337         str     r1, [r0, #TZPC_DECPROT3SET_OFFSET]
338
339         ldr     r0, =TZPC3_BASE
340         str     r1, [r0, #TZPC_DECPROT0SET_OFFSET]
341         str     r1, [r0, #TZPC_DECPROT1SET_OFFSET]
342         str     r1, [r0, #TZPC_DECPROT2SET_OFFSET]
343         str     r1, [r0, #TZPC_DECPROT3SET_OFFSET]
344
345         ldr     r0, =TZPC4_BASE
346         str     r1, [r0, #TZPC_DECPROT0SET_OFFSET]
347         str     r1, [r0, #TZPC_DECPROT1SET_OFFSET]
348         str     r1, [r0, #TZPC_DECPROT2SET_OFFSET]
349         str     r1, [r0, #TZPC_DECPROT3SET_OFFSET]
350
351         ldr     r0, =TZPC5_BASE
352         str     r1, [r0, #TZPC_DECPROT0SET_OFFSET]
353         str     r1, [r0, #TZPC_DECPROT1SET_OFFSET]
354         str     r1, [r0, #TZPC_DECPROT2SET_OFFSET]
355         str     r1, [r0, #TZPC_DECPROT3SET_OFFSET]
356
357         mov     pc, lr