2 * (C) Copyright 2006 Embedded Artists AB <www.embeddedartists.com>
4 * Modified to use the routines in cpu/arm720t/lpc2292/flash.c by
5 * Gary Jennejohn <garyj@denx,de>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 #include <asm/arch/hardware.h>
26 #define SST_BASEADDR 0x80000000
27 #define SST_ADDR1 ((volatile ushort*)(SST_BASEADDR + (0x5555 << 1)))
28 #define SST_ADDR2 ((volatile ushort*)(SST_BASEADDR + (0x2AAA << 1)))
31 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
];
33 extern int lpc2292_copy_buffer_to_flash(flash_info_t
*, ulong
);
34 extern int lpc2292_flash_erase(flash_info_t
*, int, int);
35 extern int lpc2292_write_buff (flash_info_t
*, uchar
*, ulong
, ulong
);
37 /*-----------------------------------------------------------------------
40 void write_word_sst(ulong addr
, ushort data
)
47 *((volatile ushort
*)addr
) = data
;
50 tmp
= *((volatile ushort
*)addr
);
51 } while (tmp
!= data
);
54 /*-----------------------------------------------------------------------
57 ulong
flash_init (void)
63 flash_info
[0].flash_id
= (PHILIPS_LPC2292
& FLASH_VENDMASK
);
64 flash_info
[0].size
= 0x003E000; /* 256 - 8 KB */
65 flash_info
[0].sector_count
= 17;
66 memset (flash_info
[0].protect
, 0, 17);
67 flashbase
= 0x00000000;
68 for (j
= 0, k
= 0; j
< 8; j
++, k
++) {
69 flash_info
[0].start
[k
] = flashbase
;
70 flashbase
+= 0x00002000;
72 for (j
= 0; j
< 2; j
++, k
++) {
73 flash_info
[0].start
[k
] = flashbase
;
74 flashbase
+= 0x00010000;
76 for (j
= 0; j
< 7; j
++, k
++) {
77 flash_info
[0].start
[k
] = flashbase
;
78 flashbase
+= 0x00002000;
80 size
+= flash_info
[0].size
;
82 flash_info
[1].flash_id
= (SST_MANUFACT
& FLASH_VENDMASK
);
83 flash_info
[1].size
= 0x00200000; /* 2 MB */
84 flash_info
[1].sector_count
= 512;
85 memset (flash_info
[1].protect
, 0, 512);
86 flashbase
= SST_BASEADDR
;
87 for (j
=0; j
<512; j
++) {
88 flash_info
[1].start
[j
] = flashbase
;
89 flashbase
+= 0x1000; /* 4 KB sectors */
91 size
+= flash_info
[1].size
;
93 /* Protect monitor and environment sectors */
94 flash_protect (FLAG_PROTECT_SET
,
96 0x0 + monitor_flash_len
- 1,
99 flash_protect (FLAG_PROTECT_SET
,
101 CONFIG_ENV_ADDR
+ CONFIG_ENV_SIZE
- 1,
107 /*-----------------------------------------------------------------------
109 void flash_print_info (flash_info_t
* info
)
117 switch (info
->flash_id
& FLASH_VENDMASK
) {
118 case (SST_MANUFACT
& FLASH_VENDMASK
):
121 case (PHILIPS_LPC2292
& FLASH_VENDMASK
):
125 printf ("Unknown Vendor ");
129 printf (" Size: %ld KB in %d Sectors\n",
130 info
->size
>> 10, info
->sector_count
);
132 printf (" Sector Start Addresses:");
133 for (i
= 0; i
< info
->sector_count
; i
++) {
137 if (i
< (info
->sector_count
- 1)) {
138 count
= info
->start
[i
+1] - info
->start
[i
];
141 count
= info
->start
[0] + info
->size
- info
->start
[i
];
143 p
= (unsigned char*)(info
->start
[i
]);
145 for (j
= 0; j
< count
; j
++) {
152 printf (" %08lX%s%s", info
->start
[i
], info
->protect
[i
] ? " RO" : " ",
153 erased
? " E" : " ");
158 int flash_erase_sst (flash_info_t
* info
, int s_first
, int s_last
)
162 for (i
= s_first
; i
<= s_last
; i
++) {
168 *((volatile ushort
*)(info
->start
[i
])) = 0x0030;
169 /* wait for erase to finish */
176 int flash_erase (flash_info_t
* info
, int s_first
, int s_last
)
178 switch (info
->flash_id
& FLASH_VENDMASK
) {
179 case (SST_MANUFACT
& FLASH_VENDMASK
):
180 return flash_erase_sst(info
, s_first
, s_last
);
181 case (PHILIPS_LPC2292
& FLASH_VENDMASK
):
182 return lpc2292_flash_erase(info
, s_first
, s_last
);
184 return ERR_PROTECTED
;
186 return ERR_PROTECTED
;
189 /*-----------------------------------------------------------------------
190 * Copy memory to flash.
195 int write_buff_sst (flash_info_t
* info
, uchar
* src
, ulong addr
, ulong cnt
)
205 dst_org
= (uchar
*)addr
;
207 if (addr
& 1) { /* if odd address */
208 tmp
= *((uchar
*)(addr
- 1)); /* little endian */
210 write_word_sst(addr
- 1, tmp
);
216 tmp
= ((*(src
+1)) << 8) + (*src
); /* little endian */
217 write_word_sst(addr
, tmp
);
223 tmp
= (*((uchar
*)(addr
+ 1))) << 8;
225 write_word_sst(addr
, tmp
);
228 for (i
= 0; i
< cnt_org
; i
++) {
229 if (*dst_org
!= *src_org
) {
230 printf("Write failed. Byte %lX differs\n", i
);
231 ret
= ERR_PROG_ERROR
;
241 int write_buff (flash_info_t
* info
, uchar
* src
, ulong addr
, ulong cnt
)
243 switch (info
->flash_id
& FLASH_VENDMASK
) {
244 case (SST_MANUFACT
& FLASH_VENDMASK
):
245 return write_buff_sst(info
, src
, addr
, cnt
);
246 case (PHILIPS_LPC2292
& FLASH_VENDMASK
):
247 return lpc2292_write_buff(info
, src
, addr
, cnt
);
249 return ERR_PROG_ERROR
;
251 return ERR_PROG_ERROR
;