blob: 77e0931bcd6c8fd552898e4e5e2b8b191a341e0a [file] [log] [blame]
wdenkfe8c2802002-11-03 00:38:21 +00001/*
2 * flash.c: Support code for the flash chips on the Xilinx ML2 board
3 *
4 * Copyright 2002 Mind NV
5 *
6 * http://www.mind.be/
7 *
8 * Author : Peter De Schrijver (p2@mind.be)
9 *
10 * This software may be used and distributed according to the terms of
11 * the GNU General Public License (GPL) version 2, incorporated herein by
12 * reference. Drivers based on or derived from this code fall under the GPL
13 * and must retain the authorship, copyright and this license notice. This
14 * file is not a complete program and may only be used when the entire program
15 * is licensed under the GPL.
16 *
17 */
18
19#include <common.h>
20#include <asm/u-boot.h>
21#include <configs/ML2.h>
22
23#define FLASH_BANK_SIZE (64*1024*1024)
24
25flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
26
27#define SECT_SIZE (512*1024)
28
29#define CMD_READ_ARRAY 0x00FF00FF00FF00FULL
30#define CMD_IDENTIFY 0x0090009000900090ULL
31#define CMD_ERASE_SETUP 0x0020002000200020ULL
32#define CMD_ERASE_CONFIRM 0x00D000D000D000D0ULL
33#define CMD_PROGRAM 0x0040004000400040ULL
34#define CMD_RESUME 0x00D000D000D000D0ULL
35#define CMD_SUSPEND 0x00B000B000B000B0ULL
36#define CMD_STATUS_READ 0x0070007000700070ULL
37#define CMD_STATUS_RESET 0x0050005000500050ULL
38
39#define BIT_BUSY 0x0080008000800080ULL
40#define BIT_ERASE_SUSPEND 0x004000400400040ULL
41#define BIT_ERASE_ERROR 0x0020002000200020ULL
42#define BIT_PROGRAM_ERROR 0x0010001000100010ULL
43#define BIT_VPP_RANGE_ERROR 0x0008000800080008ULL
44#define BIT_PROGRAM_SUSPEND 0x0004000400040004ULL
45#define BIT_PROTECT_ERROR 0x0002000200020002ULL
46#define BIT_UNDEFINED 0x0001000100010001ULL
47
48#define BIT_SEQUENCE_ERROR 0x0030003000300030ULL
49
50#define BIT_TIMEOUT 0x80000000
51
52
53inline void eieio(void) {
54
55 __asm__ __volatile__ ("eieio" : : : "memory");
56
57}
58
59ulong flash_init(void) {
60
61 int i, j;
62 ulong size = 0;
63
64 for(i=0;i<CFG_MAX_FLASH_BANKS;i++) {
65 ulong flashbase = 0;
66
67 flash_info[i].flash_id = (INTEL_MANUFACT & FLASH_VENDMASK) |
68 (INTEL_ID_28F128J3A & FLASH_TYPEMASK);
69 flash_info[i].size = FLASH_BANK_SIZE;
70 flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
71 memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
72 if (i==0)
73 flashbase = CFG_FLASH_BASE;
74 else
75 panic("configured to many flash banks!\n");
76 for (j = 0; j < flash_info[i].sector_count; j++)
77 flash_info[i].start[j]=flashbase + j * SECT_SIZE;
78
79 size += flash_info[i].size;
80 }
81
82 return size;
83}
84
85void flash_print_info (flash_info_t *info) {
86
87 int i;
88
89 switch (info->flash_id & FLASH_VENDMASK) {
90 case (INTEL_MANUFACT & FLASH_VENDMASK):
91 printf("Intel: ");
92 break;
93 default:
94 printf("Unknown Vendor ");
95 break;
96 }
97
98 switch (info->flash_id & FLASH_TYPEMASK) {
99 case (INTEL_ID_28F128J3A & FLASH_TYPEMASK):
100 printf("4x 28F128J3A (128Mbit)\n");
101 break;
102 default:
103 printf("Unknown Chip Type\n");
104 break;
105 }
106
107 printf(" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
108 printf(" Sector Start Addresses:");
109 for (i = 0; i < info->sector_count; i++) {
110 if ((i % 5) == 0)
111 printf("\n ");
112 printf (" %08lX%s", info->start[i],
113 info->protect[i] ? " (RO)" : " ");
114 }
115 printf ("\n");
116}
117
118int flash_error (unsigned long long code) {
119
120 if (code & BIT_TIMEOUT) {
121 printf ("Timeout\n");
122 return ERR_TIMOUT;
123 }
124
125 if (~code & BIT_BUSY) {
126 printf ("Busy\n");
127 return ERR_PROG_ERROR;
128 }
129
130 if (code & BIT_VPP_RANGE_ERROR) {
131 printf ("Vpp range error\n");
132 return ERR_PROG_ERROR;
133 }
134
135 if (code & BIT_PROTECT_ERROR) {
136 printf ("Device protect error\n");
137 return ERR_PROG_ERROR;
138 }
139
140 if (code & BIT_SEQUENCE_ERROR) {
141 printf ("Command seqence error\n");
142 return ERR_PROG_ERROR;
143 }
144
145 if (code & BIT_ERASE_ERROR) {
146 printf ("Block erase error\n");
147 return ERR_PROG_ERROR;
148 }
149
150 if (code & BIT_PROGRAM_ERROR) {
151 printf ("Program error\n");
152 return ERR_PROG_ERROR;
153 }
154
155 if (code & BIT_ERASE_SUSPEND) {
156 printf ("Block erase suspended\n");
157 return ERR_PROG_ERROR;
158 }
159
160 if (code & BIT_PROGRAM_SUSPEND) {
161 printf ("Program suspended\n");
162 return ERR_PROG_ERROR;
163 }
164
165 return ERR_OK;
166
167}
168
169int flash_erase (flash_info_t *info, int s_first, int s_last) {
170
171 int rc = ERR_OK;
172 int sect;
173 unsigned long long result;
174
175 if (info->flash_id == FLASH_UNKNOWN)
176 return ERR_UNKNOWN_FLASH_TYPE;
177
178 if ((s_first < 0) || (s_first > s_last))
179 return ERR_INVAL;
180
181 if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK))
182 return ERR_UNKNOWN_FLASH_VENDOR;
183
184 for (sect=s_first; sect<=s_last; ++sect)
185 if (info->protect[sect])
186 return ERR_PROTECTED;
187
188 for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
189 volatile unsigned long long *addr=
190 (unsigned long long *)(info->start[sect]);
191
192 printf("Erasing sector %2d ... ", sect);
193
194 *addr=CMD_STATUS_RESET;
195 eieio();
196 *addr=CMD_ERASE_SETUP;
197 eieio();
198 *addr=CMD_ERASE_CONFIRM;
199 eieio();
200
201 do {
202 result = *addr;
203 } while(~result & BIT_BUSY);
204
205 *addr=CMD_READ_ARRAY;
206
207 if ((rc = flash_error(result)) == ERR_OK)
208 printf("ok.\n");
209 else
210 break;
211 }
212
213 if (ctrlc())
214 printf("User Interrupt!\n");
215
216 return rc;
217}
218
219volatile static int write_word (flash_info_t *info, ulong dest, unsigned long long data) {
220
221 volatile unsigned long long *addr=(unsigned long long *)dest;
222 unsigned long long result;
223 int rc = ERR_OK;
224
225 result=*addr;
226 if ((result & data) != data)
227 return ERR_NOT_ERASED;
228
229 *addr=CMD_STATUS_RESET;
230 eieio();
231 *addr=CMD_PROGRAM;
232 eieio();
233 *addr=data;
234 eieio();
235
236 do {
237 result=*addr;
238 } while(~result & BIT_BUSY);
239
240 *addr=CMD_READ_ARRAY;
241
242 rc = flash_error(result);
243
244 return rc;
245
246}
247
248int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) {
249
250 ulong cp, wp;
251 unsigned long long data;
252 int l;
253 int i,rc;
254
255 wp=(addr & ~7);
256
257 if((l=addr-wp) != 0) {
258 data=0;
259 for(i=0,cp=wp;i<l;++i,++cp)
260 data = (data >> 8) | (*(uchar *)cp << 24);
261
262 for (; i<8 && cnt>0; ++i) {
263 data = (data >> 8) | (*src++ << 24);
264 --cnt;
265 ++cp;
266 }
267
268 for (; i<8; ++i, ++cp)
269 data = (data >> 8) | (*(uchar *)cp << 24);
270
271 if ((rc = write_word(info, wp, data)) != 0)
272 return rc;
273
274 wp+=8;
275 }
276
277 while(cnt>=8) {
278 data=*((unsigned long long *)src);
279 if ((rc = write_word(info, wp, data)) != 0)
280 return rc;
281 src+=8;
282 wp+=8;
283 cnt-=8;
284 }
285
286 if(cnt == 0)
287 return ERR_OK;
288
289 data = 0;
290 for (i=0, cp=wp; i<8 && cnt>0; ++i, ++cp) {
291 data = (data >> 8) | (*src++ << 24);
292 --cnt;
293 }
294 for (; i<8; ++i, ++cp) {
295 data = (data >> 8) | (*(uchar *)cp << 24);
296 }
297
298 return write_word(info, wp, data);
299
300}
301