]> git.sur5r.net Git - u-boot/blob - drivers/dataflash.c
* Code cleanup:
[u-boot] / drivers / dataflash.c
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
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