]>
Commit | Line | Data |
---|---|---|
2abbe075 WD |
1 | /* LowLevel function for ATMEL DataFlash support |
2 | * Author : Hamid Ikdoumi (Atmel) | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License as | |
6 | * published by the Free Software Foundation; either version 2 of | |
7 | * the License, or (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program; if not, write to the Free Software | |
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
17 | * MA 02111-1307 USA | |
18 | * | |
19 | */ | |
20 | #include <common.h> | |
21 | #include <config.h> | |
22 | #ifdef CONFIG_HAS_DATAFLASH | |
23 | #include <asm/hardware.h> | |
24 | #include <dataflash.h> | |
25 | ||
26 | AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS]; | |
27 | static AT91S_DataFlash DataFlashInst; | |
28 | ||
29 | int cs[][CFG_MAX_DATAFLASH_BANKS] = { | |
30 | {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */ | |
31 | {CFG_DATAFLASH_LOGIC_ADDR_CS3, 3} | |
32 | }; | |
33 | ||
34 | extern void AT91F_SpiInit (void); | |
35 | extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc); | |
36 | extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash, | |
37 | unsigned long addr, | |
38 | unsigned long size, char *buffer); | |
39 | ||
40 | ||
41 | int AT91F_DataflashInit (void) | |
42 | { | |
43 | int i, j; | |
44 | int dfcode; | |
45 | ||
46 | AT91F_SpiInit (); | |
47 | ||
48 | for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { | |
49 | ||
50 | dataflash_info[i].id = 0; | |
51 | dataflash_info[i].Device.pages_number = 0; | |
52 | dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc); | |
53 | ||
54 | switch (dfcode) { | |
55 | case AT45DB161: | |
56 | dataflash_info[i].Device.pages_number = 4096; | |
57 | dataflash_info[i].Device.pages_size = 528; | |
58 | dataflash_info[i].Device.page_offset = 10; | |
59 | dataflash_info[i].Device.byte_mask = 0x300; | |
60 | dataflash_info[i].Device.cs = cs[i][1]; | |
61 | dataflash_info[i].Desc.DataFlash_state = IDLE; | |
62 | dataflash_info[i].logical_address = cs[i][0]; | |
63 | dataflash_info[i].id = dfcode; | |
64 | break; | |
65 | ||
66 | case AT45DB321: | |
67 | dataflash_info[i].Device.pages_number = 8192; | |
68 | dataflash_info[i].Device.pages_size = 528; | |
69 | dataflash_info[i].Device.page_offset = 10; | |
70 | dataflash_info[i].Device.byte_mask = 0x300; | |
71 | dataflash_info[i].Device.cs = cs[i][1]; | |
72 | dataflash_info[i].Desc.DataFlash_state = IDLE; | |
73 | dataflash_info[i].logical_address = cs[i][0]; | |
74 | dataflash_info[i].id = dfcode; | |
75 | break; | |
76 | ||
77 | case AT45DB642: | |
78 | dataflash_info[i].Device.pages_number = 8192; | |
79 | dataflash_info[i].Device.pages_size = 1056; | |
80 | dataflash_info[i].Device.page_offset = 11; | |
81 | dataflash_info[i].Device.byte_mask = 0x700; | |
82 | dataflash_info[i].Device.cs = cs[i][1]; | |
83 | dataflash_info[i].Desc.DataFlash_state = IDLE; | |
84 | dataflash_info[i].logical_address = cs[i][0]; | |
85 | dataflash_info[i].id = dfcode; | |
86 | break; | |
87 | ||
88 | default: | |
89 | break; | |
90 | } | |
91 | ||
92 | for (j = 0; j < dataflash_info[i].Device.pages_number; j++) | |
93 | dataflash_info[i].protect[j] = FLAG_PROTECT_SET; | |
94 | ||
95 | } | |
96 | return (1); | |
97 | } | |
98 | ||
99 | ||
2abbe075 WD |
100 | void dataflash_print_info (void) |
101 | { | |
102 | int i; | |
103 | ||
104 | for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { | |
105 | if (dataflash_info[i].id != 0) { | |
106 | printf ("DataFlash:"); | |
107 | switch (dataflash_info[i].id) { | |
108 | case AT45DB161: | |
109 | printf ("AT45DB161\n"); | |
110 | break; | |
111 | ||
112 | case AT45DB321: | |
113 | printf ("AT45DB321\n"); | |
114 | break; | |
115 | ||
116 | case AT45DB642: | |
117 | printf ("AT45DB642\n"); | |
118 | break; | |
119 | } | |
120 | ||
121 | printf ("Nb pages: %6d\n" | |
122 | "Page Size: %6d\n" | |
123 | "Size=%8d bytes\n" | |
124 | "Logical address: 0x%08X\n", | |
125 | (unsigned int) dataflash_info[i].Device.pages_number, | |
126 | (unsigned int) dataflash_info[i].Device.pages_size, | |
127 | (unsigned int) dataflash_info[i].Device.pages_number * | |
128 | dataflash_info[i].Device.pages_size, | |
129 | (unsigned int) dataflash_info[i].logical_address); | |
130 | } | |
131 | } | |
132 | } | |
133 | ||
134 | ||
135 | /*------------------------------------------------------------------------------*/ | |
136 | /* Function Name : AT91F_DataflashSelect */ | |
137 | /* Object : Select the correct device */ | |
138 | /*------------------------------------------------------------------------------*/ | |
139 | AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash, | |
140 | unsigned int *addr) | |
141 | { | |
142 | char addr_valid = 0; | |
143 | int i; | |
144 | ||
145 | for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) | |
146 | if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) { | |
147 | addr_valid = 1; | |
148 | break; | |
149 | } | |
150 | if (!addr_valid) { | |
151 | pFlash = (AT91PS_DataFlash) 0; | |
152 | return pFlash; | |
153 | } | |
154 | pFlash->pDataFlashDesc = &(dataflash_info[i].Desc); | |
155 | pFlash->pDevice = &(dataflash_info[i].Device); | |
156 | *addr -= dataflash_info[i].logical_address; | |
157 | return (pFlash); | |
158 | } | |
159 | ||
160 | /*------------------------------------------------------------------------------*/ | |
161 | /* Function Name : addr_dataflash */ | |
162 | /* Object : Test if address is valid */ | |
163 | /*------------------------------------------------------------------------------*/ | |
164 | int addr_dataflash (unsigned long addr) | |
165 | { | |
166 | int addr_valid = 0; | |
167 | int i; | |
168 | ||
169 | for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { | |
170 | if ((((int) addr) & 0xFF000000) == | |
171 | dataflash_info[i].logical_address) { | |
172 | addr_valid = 1; | |
173 | break; | |
174 | } | |
175 | } | |
176 | ||
177 | return addr_valid; | |
178 | } | |
179 | ||
180 | /*------------------------------------------------------------------------------*/ | |
181 | /* Function Name : read_dataflash */ | |
182 | /* Object : dataflash memory read */ | |
183 | /*------------------------------------------------------------------------------*/ | |
184 | int read_dataflash (unsigned long addr, unsigned long size, char *result) | |
185 | { | |
186 | int AddrToRead = addr; | |
187 | AT91PS_DataFlash pFlash = &DataFlashInst; | |
188 | ||
189 | pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead); | |
190 | if (pFlash == 0) | |
191 | return -1; | |
192 | ||
193 | return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result)); | |
194 | } | |
195 | ||
196 | ||
197 | /*-----------------------------------------------------------------------------*/ | |
198 | /* Function Name : write_dataflash */ | |
199 | /* Object : write a block in dataflash */ | |
200 | /*-----------------------------------------------------------------------------*/ | |
201 | int write_dataflash (unsigned long addr_dest, unsigned long addr_src, | |
202 | unsigned long size) | |
203 | { | |
204 | extern AT91S_DataFlashStatus AT91F_DataFlashWrite( | |
205 | AT91PS_DataFlash, uchar *, int, int); | |
206 | int AddrToWrite = addr_dest; | |
207 | AT91PS_DataFlash pFlash = &DataFlashInst; | |
208 | ||
209 | pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite); | |
210 | if (AddrToWrite == -1) | |
211 | return -1; | |
212 | ||
213 | return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite, | |
214 | size); | |
215 | } | |
216 | ||
217 | ||
218 | void dataflash_perror (int err) | |
219 | { | |
220 | switch (err) { | |
221 | case ERR_OK: | |
222 | break; | |
223 | case ERR_TIMOUT: | |
224 | printf ("Timeout writing to DataFlash\n"); | |
225 | break; | |
226 | case ERR_PROTECTED: | |
227 | printf ("Can't write to protected DataFlash sectors\n"); | |
228 | break; | |
229 | case ERR_INVAL: | |
230 | printf ("Outside available DataFlash\n"); | |
231 | break; | |
232 | case ERR_UNKNOWN_FLASH_TYPE: | |
233 | printf ("Unknown Type of DataFlash\n"); | |
234 | break; | |
235 | case ERR_PROG_ERROR: | |
236 | printf ("General DataFlash Programming Error\n"); | |
237 | break; | |
238 | default: | |
239 | printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err); | |
240 | break; | |
241 | } | |
242 | } | |
243 | ||
244 | #endif |