Merge with /home/stefan/git/u-boot/bamboo-nand
[platform/kernel/u-boot.git] / cpu / bf533 / cpu.c
1 /*
2  * U-boot - cpu.c CPU specific functions
3  *
4  * Copyright (c) 2005-2007 Analog Devices Inc.
5  *
6  * (C) Copyright 2000-2004
7  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
25  * MA 02110-1301 USA
26  */
27
28 #include <common.h>
29 #include <asm/blackfin.h>
30 #include <command.h>
31 #include <asm/entry.h>
32 #include <asm/cplb.h>
33 #include <asm/io.h>
34
35 #define CACHE_ON 1
36 #define CACHE_OFF 0
37
38 extern unsigned int icplb_table[page_descriptor_table_size][2];
39 extern unsigned int dcplb_table[page_descriptor_table_size][2];
40
41 int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
42 {
43         __asm__ __volatile__("cli r3;" "P0 = %0;" "JUMP (P0);"::"r"(L1_ISRAM)
44             );
45
46         return 0;
47 }
48
49 /* These functions are just used to satisfy the linker */
50 int cpu_init(void)
51 {
52         return 0;
53 }
54
55 int cleanup_before_linux(void)
56 {
57         return 0;
58 }
59
60 void icache_enable(void)
61 {
62         unsigned int *I0, *I1;
63         int i, j = 0;
64
65         /* Before enable icache, disable it first */
66         icache_disable();
67         I0 = (unsigned int *)ICPLB_ADDR0;
68         I1 = (unsigned int *)ICPLB_DATA0;
69
70         /* make sure the locked ones go in first */
71         for (i = 0; i < page_descriptor_table_size; i++) {
72                 if (CPLB_LOCK & icplb_table[i][1]) {
73                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
74                                  icplb_table[i][0], icplb_table[i][1]);
75                         *I0++ = icplb_table[i][0];
76                         *I1++ = icplb_table[i][1];
77                         j++;
78                 }
79         }
80
81         for (i = 0; i < page_descriptor_table_size; i++) {
82                 if (!(CPLB_LOCK & icplb_table[i][1])) {
83                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
84                                  icplb_table[i][0], icplb_table[i][1]);
85                         *I0++ = icplb_table[i][0];
86                         *I1++ = icplb_table[i][1];
87                         j++;
88                         if (j == 16) {
89                                 break;
90                         }
91                 }
92         }
93
94         /* Fill the rest with invalid entry */
95         if (j <= 15) {
96                 for (; j < 16; j++) {
97                         debug("filling %i with 0", j);
98                         *I1++ = 0x0;
99                 }
100
101         }
102
103         cli();
104         sync();
105         asm(" .align 8; ");
106         *(unsigned int *)IMEM_CONTROL = IMC | ENICPLB;
107         sync();
108         sti();
109 }
110
111 void icache_disable(void)
112 {
113         cli();
114         sync();
115         asm(" .align 8; ");
116         *(unsigned int *)IMEM_CONTROL &= ~(IMC | ENICPLB);
117         sync();
118         sti();
119 }
120
121 int icache_status(void)
122 {
123         unsigned int value;
124         value = *(unsigned int *)IMEM_CONTROL;
125
126         if (value & (IMC | ENICPLB))
127                 return CACHE_ON;
128         else
129                 return CACHE_OFF;
130 }
131
132 void dcache_enable(void)
133 {
134         unsigned int *I0, *I1;
135         unsigned int temp;
136         int i, j = 0;
137
138         /* Before enable dcache, disable it first */
139         dcache_disable();
140         I0 = (unsigned int *)DCPLB_ADDR0;
141         I1 = (unsigned int *)DCPLB_DATA0;
142
143         /* make sure the locked ones go in first */
144         for (i = 0; i < page_descriptor_table_size; i++) {
145                 if (CPLB_LOCK & dcplb_table[i][1]) {
146                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
147                                  dcplb_table[i][0], dcplb_table[i][1]);
148                         *I0++ = dcplb_table[i][0];
149                         *I1++ = dcplb_table[i][1];
150                         j++;
151                 } else {
152                         debug("skip   %02i %02i 0x%08x 0x%08x\n", i, j,
153                                  dcplb_table[i][0], dcplb_table[i][1]);
154                 }
155         }
156
157         for (i = 0; i < page_descriptor_table_size; i++) {
158                 if (!(CPLB_LOCK & dcplb_table[i][1])) {
159                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
160                                  dcplb_table[i][0], dcplb_table[i][1]);
161                         *I0++ = dcplb_table[i][0];
162                         *I1++ = dcplb_table[i][1];
163                         j++;
164                         if (j == 16) {
165                                 break;
166                         }
167                 }
168         }
169
170         /* Fill the rest with invalid entry */
171         if (j <= 15) {
172                 for (; j < 16; j++) {
173                         debug("filling %i with 0", j);
174                         *I1++ = 0x0;
175                 }
176         }
177
178         cli();
179         temp = *(unsigned int *)DMEM_CONTROL;
180         sync();
181         asm(" .align 8; ");
182         *(unsigned int *)DMEM_CONTROL =
183             ACACHE_BCACHE | ENDCPLB | PORT_PREF0 | temp;
184         sync();
185         sti();
186 }
187
188 void dcache_disable(void)
189 {
190         unsigned int *I0, *I1;
191         int i;
192
193         cli();
194         sync();
195         asm(" .align 8; ");
196         *(unsigned int *)DMEM_CONTROL &=
197             ~(ACACHE_BCACHE | ENDCPLB | PORT_PREF0);
198         sync();
199         sti();
200
201         /* after disable dcache,
202          * clear it so we don't confuse the next application
203          */
204         I0 = (unsigned int *)DCPLB_ADDR0;
205         I1 = (unsigned int *)DCPLB_DATA0;
206
207         for (i = 0; i < 16; i++) {
208                 *I0++ = 0x0;
209                 *I1++ = 0x0;
210         }
211 }
212
213 int dcache_status(void)
214 {
215         unsigned int value;
216         value = *(unsigned int *)DMEM_CONTROL;
217         if (value & (ENDCPLB))
218                 return CACHE_ON;
219         else
220                 return CACHE_OFF;
221 }