2 * (C) Copyright 2005 Ingenic Semiconductor
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.
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.
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,
20 * This file supports SST 39xF3201 and AMD S29GL032M-R4
23 #define AMD_ID_GL032 0x227E227E /* S29GL032 ID (32Mb, bottom boot sectors) */
27 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
29 /*-----------------------------------------------------------------------
32 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
);
34 /*-----------------------------------------------------------------------
37 ulong
flash_init (void)
42 /* Init: no FLASHes known */
43 for (i
= 0; i
< CFG_MAX_FLASH_BANKS
; ++i
) {
44 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
47 for (i
= 0; i
< CFG_MAX_FLASH_BANKS
; i
++) {
51 flashbase
= CFG_FLASH_BASE
;
52 size
+= flash_get_size((vu_long
*)flashbase
, &flash_info
[0]);
55 panic ("configured too many flash banks!\n");
57 memset (flash_info
[i
].protect
, 0, flash_info
[i
].sector_count
);
59 switch (flash_info
[i
].flash_id
& FLASH_TYPEMASK
) {
60 case (AMD_ID_GL032
& FLASH_TYPEMASK
):
61 for (j
= 0; j
< flash_info
[i
].sector_count
; j
++) {
62 if (j
< 8) { /* 8 x 8KB bottom boot sectors */
63 flash_info
[i
].start
[j
] = flashbase
;
66 else { /* 63 x 64KB */
67 flash_info
[i
].start
[j
] = flashbase
+ (j
-8) * 0x10000;
71 case (SST_ID_xF3201
& FLASH_TYPEMASK
):
73 for (j
= 0; j
< flash_info
[i
].sector_count
; j
++) {
75 flash_info
[i
].start
[j
] = flashbase
+ j
* 0x1000;
81 /* Protect monitor and environment sectors
83 flash_protect ( FLAG_PROTECT_SET
,
85 CFG_FLASH_BASE
+ monitor_flash_len
- 1,
88 flash_protect ( FLAG_PROTECT_SET
,
90 CFG_ENV_ADDR
+ CFG_ENV_SIZE
- 1, &flash_info
[0]);
95 /*-----------------------------------------------------------------------
97 void flash_print_info (flash_info_t
* info
)
101 switch (info
->flash_id
& FLASH_VENDMASK
) {
102 case (SST_MANUFACT
& FLASH_VENDMASK
):
105 case (AMD_MANUFACT
& FLASH_VENDMASK
):
109 printf ("Unknown Vendor ");
113 switch (info
->flash_id
& FLASH_TYPEMASK
) {
114 case (SST_ID_xF3201
& FLASH_TYPEMASK
):
115 printf ("39xF3201 (32Mbit)\n");
117 case (AMD_ID_GL032
& FLASH_TYPEMASK
):
118 printf ("29GL032 (32Mbit)\n");
121 printf ("Unknown Chip Type\n");
125 printf (" Size: %ld MB in %d Sectors\n",
126 info
->size
>> 20, info
->sector_count
);
128 printf (" Sector Start Addresses:");
129 for (i
= 0; i
< info
->sector_count
; i
++) {
133 printf (" %08lX%s", info
->start
[i
],
134 info
->protect
[i
] ? " (RO)" : " ");
139 /*-----------------------------------------------------------------------
142 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
)
145 vu_short
*saddr
= (vu_short
*)addr
;
147 /* Read Manufacturer ID and Device ID */
149 /* AMD Flash stuff */
162 if (vid
!= (AMD_MANUFACT
& 0xFFFF)) {
163 saddr
[0x5555] = 0xAA;
164 saddr
[0x2AAA] = 0x55;
165 saddr
[0x5555] = 0x90;
171 saddr
[0x5555] = 0xAA;
172 saddr
[0x2AAA] = 0x55;
173 saddr
[0x5555] = 0xF0;
176 vid
= SST_MANUFACT
& 0xFFFF;
177 did
= SST_ID_xF3201
& 0xFFFF;
181 case (SST_MANUFACT
& 0xFFFF):
182 info
->flash_id
= (SST_MANUFACT
& 0xFFFF0000);
184 case (AMD_MANUFACT
& 0xFFFF):
185 info
->flash_id
= (AMD_MANUFACT
& 0xFFFF0000);
188 info
->flash_id
= FLASH_UNKNOWN
;
189 info
->sector_count
= 0;
191 return (0); /* no or unknown flash */
195 case (SST_ID_xF3201
& 0xFFFF):
196 info
->flash_id
+= (SST_ID_xF3201
& 0xFFFF);
197 info
->sector_count
= 1024;
198 info
->size
= 0x00400000;
200 case (AMD_ID_GL032
& 0xFFFF):
201 info
->flash_id
+= (AMD_ID_GL032
& 0xFFFF);
202 info
->sector_count
= 71; /* 8 x 8KB + 63 x 64KB */
203 info
->size
= 0x00400000;
206 info
->flash_id
= FLASH_UNKNOWN
;
207 info
->sector_count
= 0;
209 return (0); /* no or unknown flash */
215 /*-----------------------------------------------------------------------
218 int flash_erase (flash_info_t
* info
, int s_first
, int s_last
)
220 volatile u16
*base
= (volatile u16
*) CFG_FLASH_BASE
;
221 int flag
, prot
, sect
;
223 unsigned int timeout
;
225 if (info
->flash_id
== FLASH_UNKNOWN
)
226 return ERR_UNKNOWN_FLASH_TYPE
;
228 if ((s_first
< 0) || (s_first
> s_last
)) {
232 if ((info
->flash_id
& FLASH_VENDMASK
) !=
233 (SST_MANUFACT
& FLASH_VENDMASK
)) {
234 return ERR_UNKNOWN_FLASH_VENDOR
;
239 for (sect
= s_first
; sect
<= s_last
; ++sect
) {
240 if (info
->protect
[sect
]) {
245 return ERR_PROTECTED
;
247 /* Disable interrupts which might cause a timeout here */
248 flag
= disable_interrupts ();
250 /* Start erase on unprotected sectors */
251 for (sect
= s_first
; sect
<= s_last
&& !ctrlc (); sect
++) {
253 printf ("Erasing sector %3d ... ", sect
);
255 if (info
->protect
[sect
] == 0) { /* not protected */
256 volatile u16
*addr
= (volatile u16
*) (info
->start
[sect
]);
258 switch (info
->flash_id
& FLASH_TYPEMASK
) {
259 case (SST_ID_xF3201
& FLASH_TYPEMASK
):
260 base
[0x5555] = 0x00AA;
261 base
[0x2AAA] = 0x0055;
262 base
[0x5555] = 0x0080;
263 base
[0x5555] = 0x00AA;
264 base
[0x2AAA] = 0x0055;
265 addr
[0x0000] = 0x0030;
267 case (AMD_ID_GL032
& FLASH_TYPEMASK
):
268 base
[0x555] = 0x00AA;
269 base
[0x2AA] = 0x0055;
270 base
[0x555] = 0x0080;
271 base
[0x555] = 0x00AA;
272 base
[0x2AA] = 0x0055;
273 addr
[0x000] = 0x0030;
276 printf ("Unknown Chip Type\n");
281 while ((*base
& 0x40) != (*base
& 0x40)) {
282 if ((timeout
--) == 0) {
291 printf ("User Interrupt!\n");
295 /* allow flash to settle - wait 20 ms */
299 enable_interrupts ();
304 /*-----------------------------------------------------------------------
305 * Copy memory to flash
308 static int write_word (flash_info_t
* info
, ulong dest
, ushort data
)
310 volatile u16
*base
= (volatile u16
*) CFG_FLASH_BASE
;
311 volatile u16
*addr
= (volatile u16
*) dest
;
314 unsigned int timeout
;
316 /* Check if Flash is (sufficiently) erased
318 if ((*addr
& data
) != data
)
319 return ERR_NOT_ERASED
;
321 /* Disable interrupts which might cause a timeout here. */
322 flag
= disable_interrupts ();
324 /* program set-up command */
325 switch (info
->flash_id
& FLASH_TYPEMASK
) {
326 case (SST_ID_xF3201
& FLASH_TYPEMASK
):
327 base
[0x5555] = 0x00AA;
328 base
[0x2AAA] = 0x0055;
329 base
[0x5555] = 0x00A0;
331 case (AMD_ID_GL032
& FLASH_TYPEMASK
):
332 base
[0x555] = 0x00AA;
333 base
[0x2AA] = 0x0055;
334 base
[0x555] = 0x00A0;
337 printf ("Unknown Chip Type\n");
341 /* load address/data */
344 /* wait while polling the status register */
346 while ((*base
& 0x40) != (*base
& 0x40)) {
347 if ((timeout
--) == 0) {
355 /* allow flash to settle - wait 10 us */
359 enable_interrupts ();
364 /*-----------------------------------------------------------------------
365 * Copy memory to flash.
368 int write_buff (flash_info_t
* info
, uchar
* src
, ulong addr
, ulong cnt
)
375 wp
= (addr
& ~1); /* get lower word aligned address */
378 * handle unaligned start bytes
380 if ((l
= addr
- wp
) != 0) {
382 for (i
= 0, cp
= wp
; i
< l
; ++i
, ++cp
) {
383 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
385 for (; i
< 2 && cnt
> 0; ++i
) {
386 data
= (data
>> 8) | (*src
++ << 8);
390 for (; cnt
== 0 && i
< 2; ++i
, ++cp
) {
391 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
394 if ((rc
= write_word (info
, wp
, data
)) != 0) {
401 * handle word aligned part
404 data
= *((vu_short
*) src
);
405 if ((rc
= write_word (info
, wp
, data
)) != 0) {
418 * handle unaligned tail bytes
421 for (i
= 0, cp
= wp
; i
< 2 && cnt
> 0; ++i
, ++cp
) {
422 data
= (data
>> 8) | (*src
++ << 8);
425 for (; i
< 2; ++i
, ++cp
) {
426 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
429 return write_word (info
, wp
, data
);