]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/bf561/cpu.c
Blackfin: BF537-stamp: cleanup spi flash driver
[karo-tx-uboot.git] / cpu / bf561 / 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_INST_SRAM)
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         SSYNC();
104         asm(" .align 8; ");
105         *(unsigned int *)IMEM_CONTROL = IMC | ENICPLB;
106         SSYNC();
107 }
108
109 void icache_disable(void)
110 {
111         SSYNC();
112         asm(" .align 8; ");
113         *(unsigned int *)IMEM_CONTROL &= ~(IMC | ENICPLB);
114         SSYNC();
115 }
116
117 int icache_status(void)
118 {
119         unsigned int value;
120         value = *(unsigned int *)IMEM_CONTROL;
121
122         if (value & (IMC | ENICPLB))
123                 return CACHE_ON;
124         else
125                 return CACHE_OFF;
126 }
127
128 void dcache_enable(void)
129 {
130         unsigned int *I0, *I1;
131         unsigned int temp;
132         int i, j = 0;
133
134         /* Before enable dcache, disable it first */
135         dcache_disable();
136         I0 = (unsigned int *)DCPLB_ADDR0;
137         I1 = (unsigned int *)DCPLB_DATA0;
138
139         /* make sure the locked ones go in first */
140         for (i = 0; i < page_descriptor_table_size; i++) {
141                 if (CPLB_LOCK & dcplb_table[i][1]) {
142                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
143                               dcplb_table[i][0], dcplb_table[i][1]);
144                         *I0++ = dcplb_table[i][0];
145                         *I1++ = dcplb_table[i][1];
146                         j++;
147                 } else {
148                         debug("skip   %02i %02i 0x%08x 0x%08x\n", i, j,
149                               dcplb_table[i][0], dcplb_table[i][1]);
150                 }
151         }
152
153         for (i = 0; i < page_descriptor_table_size; i++) {
154                 if (!(CPLB_LOCK & dcplb_table[i][1])) {
155                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
156                               dcplb_table[i][0], dcplb_table[i][1]);
157                         *I0++ = dcplb_table[i][0];
158                         *I1++ = dcplb_table[i][1];
159                         j++;
160                         if (j == 16) {
161                                 break;
162                         }
163                 }
164         }
165
166         /* Fill the rest with invalid entry */
167         if (j <= 15) {
168                 for (; j < 16; j++) {
169                         debug("filling %i with 0", j);
170                         *I1++ = 0x0;
171                 }
172         }
173
174         temp = *(unsigned int *)DMEM_CONTROL;
175         SSYNC();
176         asm(" .align 8; ");
177         *(unsigned int *)DMEM_CONTROL =
178             ACACHE_BCACHE | ENDCPLB | PORT_PREF0 | temp;
179         SSYNC();
180 }
181
182 void dcache_disable(void)
183 {
184
185         unsigned int *I0, *I1;
186         int i;
187
188         SSYNC();
189         asm(" .align 8; ");
190         *(unsigned int *)DMEM_CONTROL &=
191             ~(ACACHE_BCACHE | ENDCPLB | PORT_PREF0);
192         SSYNC();
193
194         /* after disable dcache, clear it so we don't confuse the next application */
195         I0 = (unsigned int *)DCPLB_ADDR0;
196         I1 = (unsigned int *)DCPLB_DATA0;
197
198         for (i = 0; i < 16; i++) {
199                 *I0++ = 0x0;
200                 *I1++ = 0x0;
201         }
202 }
203
204 int dcache_status(void)
205 {
206         unsigned int value;
207         value = *(unsigned int *)DMEM_CONTROL;
208         if (value & (ENDCPLB))
209                 return CACHE_ON;
210         else
211                 return CACHE_OFF;
212 }