Blackfin: BF537-stamp: cleanup spi flash driver
[oweals/u-boot.git] / cpu / bf537 / 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         if ((*pCHIPID >> 28) < 2)
66                 return;
67
68         /* Before enable icache, disable it first */
69         icache_disable();
70         I0 = (unsigned int *)ICPLB_ADDR0;
71         I1 = (unsigned int *)ICPLB_DATA0;
72
73         /* make sure the locked ones go in first */
74         for (i = 0; i < page_descriptor_table_size; i++) {
75                 if (CPLB_LOCK & icplb_table[i][1]) {
76                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
77                                  icplb_table[i][0], icplb_table[i][1]);
78                         *I0++ = icplb_table[i][0];
79                         *I1++ = icplb_table[i][1];
80                         j++;
81                 }
82         }
83
84         for (i = 0; i < page_descriptor_table_size; i++) {
85                 if (!(CPLB_LOCK & icplb_table[i][1])) {
86                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
87                                  icplb_table[i][0], icplb_table[i][1]);
88                         *I0++ = icplb_table[i][0];
89                         *I1++ = icplb_table[i][1];
90                         j++;
91                         if (j == 16) {
92                                 break;
93                         }
94                 }
95         }
96
97         /* Fill the rest with invalid entry */
98         if (j <= 15) {
99                 for (; j < 16; j++) {
100                         debug("filling %i with 0", j);
101                         *I1++ = 0x0;
102                 }
103
104         }
105
106         SSYNC();
107         asm(" .align 8; ");
108         *(unsigned int *)IMEM_CONTROL = IMC | ENICPLB;
109         SSYNC();
110 }
111
112 void icache_disable(void)
113 {
114         if ((*pCHIPID >> 28) < 2)
115                 return;
116         SSYNC();
117         asm(" .align 8; ");
118         *(unsigned int *)IMEM_CONTROL &= ~(IMC | ENICPLB);
119         SSYNC();
120 }
121
122 int icache_status(void)
123 {
124         unsigned int value;
125         value = *(unsigned int *)IMEM_CONTROL;
126
127         if (value & (IMC | ENICPLB))
128                 return CACHE_ON;
129         else
130                 return CACHE_OFF;
131 }
132
133 void dcache_enable(void)
134 {
135         unsigned int *I0, *I1;
136         unsigned int temp;
137         int i, j = 0;
138
139         /* Before enable dcache, disable it first */
140         dcache_disable();
141         I0 = (unsigned int *)DCPLB_ADDR0;
142         I1 = (unsigned int *)DCPLB_DATA0;
143
144         /* make sure the locked ones go in first */
145         for (i = 0; i < page_descriptor_table_size; i++) {
146                 if (CPLB_LOCK & dcplb_table[i][1]) {
147                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
148                                  dcplb_table[i][0], dcplb_table[i][1]);
149                         *I0++ = dcplb_table[i][0];
150                         *I1++ = dcplb_table[i][1];
151                         j++;
152                 } else {
153                         debug("skip   %02i %02i 0x%08x 0x%08x\n", i, j,
154                                  dcplb_table[i][0], dcplb_table[i][1]);
155                 }
156         }
157
158         for (i = 0; i < page_descriptor_table_size; i++) {
159                 if (!(CPLB_LOCK & dcplb_table[i][1])) {
160                         debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
161                                  dcplb_table[i][0], dcplb_table[i][1]);
162                         *I0++ = dcplb_table[i][0];
163                         *I1++ = dcplb_table[i][1];
164                         j++;
165                         if (j == 16) {
166                                 break;
167                         }
168                 }
169         }
170
171         /* Fill the rest with invalid entry */
172         if (j <= 15) {
173                 for (; j < 16; j++) {
174                         debug("filling %i with 0", j);
175                         *I1++ = 0x0;
176                 }
177         }
178
179         temp = *(unsigned int *)DMEM_CONTROL;
180         SSYNC();
181         asm(" .align 8; ");
182         *(unsigned int *)DMEM_CONTROL =
183             ACACHE_BCACHE | ENDCPLB | PORT_PREF0 | temp;
184         SSYNC();
185 }
186
187 void dcache_disable(void)
188 {
189         unsigned int *I0, *I1;
190         int i;
191
192         SSYNC();
193         asm(" .align 8; ");
194         *(unsigned int *)DMEM_CONTROL &=
195             ~(ACACHE_BCACHE | ENDCPLB | PORT_PREF0);
196         SSYNC();
197
198         /* after disable dcache,
199          * clear it so we don't confuse the next application
200          */
201         I0 = (unsigned int *)DCPLB_ADDR0;
202         I1 = (unsigned int *)DCPLB_DATA0;
203
204         for (i = 0; i < 16; i++) {
205                 *I0++ = 0x0;
206                 *I1++ = 0x0;
207         }
208 }
209
210 int dcache_status(void)
211 {
212         unsigned int value;
213         value = *(unsigned int *)DMEM_CONTROL;
214
215         if (value & (ENDCPLB))
216                 return CACHE_ON;
217         else
218                 return CACHE_OFF;
219 }