]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/arm_cortexa8/cpu.c
506dbec173201da98b3fcfc8c63b76a159f17620
[karo-tx-uboot.git] / cpu / arm_cortexa8 / cpu.c
1 /*
2  * (C) Copyright 2008 Texas Insturments
3  *
4  * (C) Copyright 2002
5  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
6  * Marius Groeger <mgroeger@sysgo.de>
7  *
8  * (C) Copyright 2002
9  * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
10  *
11  * See file CREDITS for list of people who contributed to this
12  * project.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation; either version 2 of
17  * the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27  * MA 02111-1307 USA
28  */
29
30 /*
31  * CPU specific code
32  */
33
34 #include <common.h>
35 #include <command.h>
36 #include <asm/arch/sys_proto.h>
37 #include <asm/system.h>
38
39 #ifdef CONFIG_USE_IRQ
40 DECLARE_GLOBAL_DATA_PTR;
41 #endif
42
43 #ifndef CONFIG_L2_OFF
44 void l2cache_disable(void);
45 #endif
46
47 static void cache_flush(void);
48
49 static void cp_delay(void)
50 {
51         /* Many OMAP regs need at least 2 nops */
52         asm("nop");
53         asm("nop");
54 }
55
56 int cpu_init(void)
57 {
58         /*
59          * setup up stacks if necessary
60          */
61 #ifdef CONFIG_USE_IRQ
62         IRQ_STACK_START =
63             _armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4;
64         FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
65 #endif
66         return 0;
67 }
68
69 int cleanup_before_linux(void)
70 {
71         unsigned int i;
72
73         /*
74          * this function is called just before we call linux
75          * it prepares the processor for linux
76          *
77          * we turn off caches etc ...
78          */
79         disable_interrupts();
80
81         /* turn off I/D-cache */
82         icache_disable();
83         dcache_disable();
84
85         /* invalidate I-cache */
86         cache_flush();
87
88 #ifndef CONFIG_L2_OFF
89         /* turn off L2 cache */
90         l2cache_disable();
91         /* invalidate L2 cache also */
92         v7_flush_dcache_all(get_device_type());
93 #endif
94         i = 0;
95         /* mem barrier to sync up things */
96         asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
97
98 #ifndef CONFIG_L2_OFF
99         l2cache_enable();
100 #endif
101
102         return 0;
103 }
104
105 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
106 {
107         disable_interrupts();
108         reset_cpu(0);
109
110         /* NOTREACHED */
111         return 0;
112 }
113
114 void icache_enable(void)
115 {
116         ulong reg;
117
118         reg = get_cr(); /* get control reg. */
119         cp_delay();
120         set_cr(reg | CR_I);
121 }
122
123 void icache_disable(void)
124 {
125         ulong reg;
126
127         reg = get_cr();
128         cp_delay();
129         set_cr(reg & ~CR_I);
130 }
131
132 void dcache_disable (void)
133 {
134         ulong reg;
135
136         reg = get_cr ();
137         cp_delay ();
138         set_cr (reg & ~CR_C);
139 }
140
141 void l2cache_enable()
142 {
143         unsigned long i;
144         volatile unsigned int j;
145
146         /* ES2 onwards we can disable/enable L2 ourselves */
147         if (get_cpu_rev() == CPU_3430_ES2) {
148                 __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
149                 __asm__ __volatile__("orr %0, %0, #0x2":"=r"(i));
150                 __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
151         } else {
152                 /* Save r0, r12 and restore them after usage */
153                 __asm__ __volatile__("mov %0, r12":"=r"(j));
154                 __asm__ __volatile__("mov %0, r0":"=r"(i));
155
156                 /*
157                  * GP Device ROM code API usage here
158                  * r12 = AUXCR Write function and r0 value
159                  */
160                 __asm__ __volatile__("mov r12, #0x3");
161                 __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
162                 __asm__ __volatile__("orr r0, r0, #0x2");
163                 /* SMI instruction to call ROM Code API */
164                 __asm__ __volatile__(".word 0xE1600070");
165                 __asm__ __volatile__("mov r0, %0":"=r"(i));
166                 __asm__ __volatile__("mov r12, %0":"=r"(j));
167         }
168
169 }
170
171 void l2cache_disable()
172 {
173         unsigned long i;
174         volatile unsigned int j;
175
176         /* ES2 onwards we can disable/enable L2 ourselves */
177         if (get_cpu_rev() == CPU_3430_ES2) {
178                 __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
179                 __asm__ __volatile__("bic %0, %0, #0x2":"=r"(i));
180                 __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
181         } else {
182                 /* Save r0, r12 and restore them after usage */
183                 __asm__ __volatile__("mov %0, r12":"=r"(j));
184                 __asm__ __volatile__("mov %0, r0":"=r"(i));
185
186                 /*
187                  * GP Device ROM code API usage here
188                  * r12 = AUXCR Write function and r0 value
189                  */
190                 __asm__ __volatile__("mov r12, #0x3");
191                 __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
192                 __asm__ __volatile__("bic r0, r0, #0x2");
193                 /* SMI instruction to call ROM Code API */
194                 __asm__ __volatile__(".word 0xE1600070");
195                 __asm__ __volatile__("mov r0, %0":"=r"(i));
196                 __asm__ __volatile__("mov r12, %0":"=r"(j));
197         }
198 }
199
200 int icache_status(void)
201 {
202         return (get_cr() & CR_I) != 0;
203 }
204
205 static void cache_flush(void)
206 {
207         asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
208 }