• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisiónea8015b852305387b379a88d256ffe80d373d20a (tree)
Tiempo2002-10-27 01:43:06
Autorwdenk <wdenk>
Commiterwdenk

Log Message

Initial revision

Cambiar Resumen

Diferencia incremental

--- /dev/null
+++ b/board/cradle/flash.c
@@ -0,0 +1,367 @@
1+/*
2+ * (C) Copyright 2002
3+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4+ *
5+ * (C) Copyright 2002
6+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7+ * Marius Groeger <mgroeger@sysgo.de>
8+ *
9+ * See file CREDITS for list of people who contributed to this
10+ * project.
11+ *
12+ * This program is free software; you can redistribute it and/or
13+ * modify it under the terms of the GNU General Public License as
14+ * published by the Free Software Foundation; either version 2 of
15+ * the License, or (at your option) any later version.
16+ *
17+ * This program is distributed in the hope that it will be useful,
18+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+ * GNU General Public License for more details.
21+ *
22+ * You should have received a copy of the GNU General Public License
23+ * along with this program; if not, write to the Free Software
24+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25+ * MA 02111-1307 USA
26+ */
27+
28+#include <common.h>
29+
30+#define FLASH_BANK_SIZE 0x400000
31+#define MAIN_SECT_SIZE 0x20000
32+
33+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
34+
35+
36+/*-----------------------------------------------------------------------
37+ */
38+
39+ulong flash_init(void)
40+{
41+ int i, j;
42+ ulong size = 0;
43+
44+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
45+ {
46+ ulong flashbase = 0;
47+ flash_info[i].flash_id =
48+ (INTEL_MANUFACT & FLASH_VENDMASK) |
49+ (INTEL_ID_28F128J3 & FLASH_TYPEMASK);
50+ flash_info[i].size = FLASH_BANK_SIZE;
51+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
52+ memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
53+ switch (i)
54+ {
55+ case 0:
56+ flashbase = PHYS_FLASH_1;
57+ break;
58+ case 1:
59+ flashbase = PHYS_FLASH_2;
60+ break;
61+ default:
62+ panic("configured to many flash banks!\n");
63+ break;
64+ }
65+ for (j = 0; j < flash_info[i].sector_count; j++)
66+ {
67+ flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE;
68+ }
69+ size += flash_info[i].size;
70+ }
71+
72+ /* Protect monitor and environment sectors
73+ */
74+ flash_protect(FLAG_PROTECT_SET,
75+ CFG_FLASH_BASE,
76+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
77+ &flash_info[0]);
78+
79+ flash_protect(FLAG_PROTECT_SET,
80+ CFG_ENV_ADDR,
81+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
82+ &flash_info[0]);
83+
84+ return size;
85+}
86+
87+/*-----------------------------------------------------------------------
88+ */
89+void flash_print_info (flash_info_t *info)
90+{
91+ int i, j;
92+
93+ for (j=0; j<CFG_MAX_FLASH_BANKS; j++)
94+ {
95+ switch (info->flash_id & FLASH_VENDMASK)
96+ {
97+ case (INTEL_MANUFACT & FLASH_VENDMASK):
98+ printf("Intel: ");
99+ break;
100+ default:
101+ printf("Unknown Vendor ");
102+ break;
103+ }
104+
105+ switch (info->flash_id & FLASH_TYPEMASK)
106+ {
107+ case (INTEL_ID_28F320J3A & FLASH_TYPEMASK):
108+ printf("28F320J3A (32Mbit)\n");
109+ break;
110+ case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
111+ printf("28F128J3 (128Mbit)\n");
112+ break;
113+ default:
114+ printf("Unknown Chip Type\n");
115+ goto Done;
116+ break;
117+ }
118+
119+ printf(" Size: %ld MB in %d Sectors\n",
120+ info->size >> 20, info->sector_count);
121+
122+ printf(" Sector Start Addresses:");
123+ for (i = 0; i < info->sector_count; i++)
124+ {
125+ if ((i % 5) == 0)
126+ {
127+ printf ("\n ");
128+ }
129+ printf (" %08lX%s", info->start[i],
130+ info->protect[i] ? " (RO)" : " ");
131+ }
132+ printf ("\n");
133+ info++;
134+ }
135+
136+Done:
137+}
138+
139+/*-----------------------------------------------------------------------
140+ */
141+
142+int flash_erase (flash_info_t *info, int s_first, int s_last)
143+{
144+ int flag, prot, sect;
145+ int rc = ERR_OK;
146+
147+ if (info->flash_id == FLASH_UNKNOWN)
148+ return ERR_UNKNOWN_FLASH_TYPE;
149+
150+ if ((s_first < 0) || (s_first > s_last)) {
151+ return ERR_INVAL;
152+ }
153+
154+ if ((info->flash_id & FLASH_VENDMASK) !=
155+ (INTEL_MANUFACT & FLASH_VENDMASK)) {
156+ return ERR_UNKNOWN_FLASH_VENDOR;
157+ }
158+
159+ prot = 0;
160+ for (sect=s_first; sect<=s_last; ++sect) {
161+ if (info->protect[sect]) {
162+ prot++;
163+ }
164+ }
165+ if (prot)
166+ return ERR_PROTECTED;
167+
168+ /*
169+ * Disable interrupts which might cause a timeout
170+ * here. Remember that our exception vectors are
171+ * at address 0 in the flash, and we don't want a
172+ * (ticker) exception to happen while the flash
173+ * chip is in programming mode.
174+ */
175+ flag = disable_interrupts();
176+
177+ /* Start erase on unprotected sectors */
178+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
179+
180+ printf("Erasing sector %2d ... ", sect);
181+
182+ /* arm simple, non interrupt dependent timer */
183+ reset_timer_masked();
184+
185+ if (info->protect[sect] == 0) { /* not protected */
186+ vu_short *addr = (vu_short *)(info->start[sect]);
187+
188+ *addr = 0x20; /* erase setup */
189+ *addr = 0xD0; /* erase confirm */
190+
191+ while ((*addr & 0x80) != 0x80) {
192+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
193+ *addr = 0xB0; /* suspend erase */
194+ *addr = 0xFF; /* reset to read mode */
195+ rc = ERR_TIMOUT;
196+ goto outahere;
197+ }
198+ }
199+
200+ /* clear status register command */
201+ *addr = 0x50;
202+ /* reset to read mode */
203+ *addr = 0xFF;
204+ }
205+ printf("ok.\n");
206+ }
207+ if (ctrlc())
208+ printf("User Interrupt!\n");
209+
210+outahere:
211+
212+ /* allow flash to settle - wait 10 ms */
213+ udelay_masked(10000);
214+
215+ if (flag)
216+ enable_interrupts();
217+
218+ return rc;
219+}
220+
221+/*-----------------------------------------------------------------------
222+ * Copy memory to flash
223+ */
224+
225+static int write_word (flash_info_t *info, ulong dest, ushort data)
226+{
227+ vu_short *addr = (vu_short *)dest, val;
228+ int rc = ERR_OK;
229+ int flag;
230+
231+ /* Check if Flash is (sufficiently) erased
232+ */
233+ if ((*addr & data) != data)
234+ return ERR_NOT_ERASED;
235+
236+ /*
237+ * Disable interrupts which might cause a timeout
238+ * here. Remember that our exception vectors are
239+ * at address 0 in the flash, and we don't want a
240+ * (ticker) exception to happen while the flash
241+ * chip is in programming mode.
242+ */
243+ flag = disable_interrupts();
244+
245+ /* clear status register command */
246+ *addr = 0x50;
247+
248+ /* program set-up command */
249+ *addr = 0x40;
250+
251+ /* latch address/data */
252+ *addr = data;
253+
254+ /* arm simple, non interrupt dependent timer */
255+ reset_timer_masked();
256+
257+ /* wait while polling the status register */
258+ while(((val = *addr) & 0x80) != 0x80)
259+ {
260+ if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
261+ rc = ERR_TIMOUT;
262+ /* suspend program command */
263+ *addr = 0xB0;
264+ goto outahere;
265+ }
266+ }
267+
268+ if(val & 0x1A) { /* check for error */
269+ printf("\nFlash write error %02x at address %08lx\n",
270+ (int)val, (unsigned long)dest);
271+ if(val & (1<<3)) {
272+ printf("Voltage range error.\n");
273+ rc = ERR_PROG_ERROR;
274+ goto outahere;
275+ }
276+ if(val & (1<<1)) {
277+ printf("Device protect error.\n");
278+ rc = ERR_PROTECTED;
279+ goto outahere;
280+ }
281+ if(val & (1<<4)) {
282+ printf("Programming error.\n");
283+ rc = ERR_PROG_ERROR;
284+ goto outahere;
285+ }
286+ rc = ERR_PROG_ERROR;
287+ goto outahere;
288+ }
289+
290+outahere:
291+ /* read array command */
292+ *addr = 0xFF;
293+
294+ if (flag)
295+ enable_interrupts();
296+
297+ return rc;
298+}
299+
300+/*-----------------------------------------------------------------------
301+ * Copy memory to flash.
302+ */
303+
304+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
305+{
306+ ulong cp, wp;
307+ ushort data;
308+ int l;
309+ int i, rc;
310+
311+ wp = (addr & ~1); /* get lower word aligned address */
312+
313+ /*
314+ * handle unaligned start bytes
315+ */
316+ if ((l = addr - wp) != 0)
317+ {
318+ data = 0;
319+ for (i=0, cp=wp; i<l; ++i, ++cp) {
320+ data = (data >> 8) | (*(uchar *)cp << 8);
321+ }
322+ for (; i<2 && cnt>0; ++i) {
323+ data = (data >> 8) | (*src++ << 8);
324+ --cnt;
325+ ++cp;
326+ }
327+ for (; cnt==0 && i<2; ++i, ++cp) {
328+ data = (data >> 8) | (*(uchar *)cp << 8);
329+ }
330+
331+ if ((rc = write_word(info, wp, data)) != 0) {
332+ return (rc);
333+ }
334+ wp += 2;
335+ }
336+
337+ /*
338+ * handle word aligned part
339+ */
340+ while (cnt >= 2) {
341+ data = *((vu_short*)src);
342+ if ((rc = write_word(info, wp, data)) != 0) {
343+ return (rc);
344+ }
345+ src += 2;
346+ wp += 2;
347+ cnt -= 2;
348+ }
349+
350+ if (cnt == 0) {
351+ return ERR_OK;
352+ }
353+
354+ /*
355+ * handle unaligned tail bytes
356+ */
357+ data = 0;
358+ for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
359+ data = (data >> 8) | (*src++ << 8);
360+ --cnt;
361+ }
362+ for (; i<2; ++i, ++cp) {
363+ data = (data >> 8) | (*(uchar *)cp << 8);
364+ }
365+
366+ return write_word(info, wp, data);
367+}
--- /dev/null
+++ b/board/dnp1110/flash.c
@@ -0,0 +1,473 @@
1+/*
2+ * (C) Copyright 2002
3+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4+ * Rolf Offermanns <rof@sysgo.de>
5+ *
6+ * See file CREDITS for list of people who contributed to this
7+ * project.
8+ *
9+ * This program is free software; you can redistribute it and/or
10+ * modify it under the terms of the GNU General Public License as
11+ * published by the Free Software Foundation; either version 2 of
12+ * the License, or (at your option) any later version.
13+ *
14+ * This program is distributed in the hope that it will be useful,
15+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+ * GNU General Public License for more details.
18+ *
19+ * You should have received a copy of the GNU General Public License
20+ * along with this program; if not, write to the Free Software
21+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22+ * MA 02111-1307 USA
23+ */
24+
25+#include <common.h>
26+
27+ulong myflush(void);
28+
29+
30+#define FLASH_BANK_SIZE 0x800000
31+#define MAIN_SECT_SIZE 0x20000
32+#define PARAM_SECT_SIZE 0x4000
33+
34+/* puzzle magic for lart
35+ * data_*_flash are def'd in flashasm.S
36+ */
37+
38+extern u32 data_from_flash(u32);
39+extern u32 data_to_flash(u32);
40+
41+#define PUZZLE_FROM_FLASH(x) (x)
42+#define PUZZLE_TO_FLASH(x) (x)
43+
44+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
45+
46+
47+#define CMD_READ_ARRAY 0x00FF00FF
48+#define CMD_IDENTIFY 0x00900090
49+#define CMD_ERASE_SETUP 0x00200020
50+#define CMD_ERASE_CONFIRM 0x00D000D0
51+#define CMD_PROGRAM 0x00400040
52+#define CMD_RESUME 0x00D000D0
53+#define CMD_SUSPEND 0x00B000B0
54+#define CMD_STATUS_READ 0x00700070
55+#define CMD_STATUS_RESET 0x00500050
56+
57+#define BIT_BUSY 0x00800080
58+#define BIT_ERASE_SUSPEND 0x00400040
59+#define BIT_ERASE_ERROR 0x00200020
60+#define BIT_PROGRAM_ERROR 0x00100010
61+#define BIT_VPP_RANGE_ERROR 0x00080008
62+#define BIT_PROGRAM_SUSPEND 0x00040004
63+#define BIT_PROTECT_ERROR 0x00020002
64+#define BIT_UNDEFINED 0x00010001
65+
66+#define BIT_SEQUENCE_ERROR 0x00300030
67+#define BIT_TIMEOUT 0x80000000
68+
69+/*-----------------------------------------------------------------------
70+ */
71+
72+ulong flash_init(void)
73+{
74+ int i, j;
75+ ulong size = 0;
76+
77+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
78+ {
79+ ulong flashbase = 0;
80+ flash_info[i].flash_id =
81+ (INTEL_MANUFACT & FLASH_VENDMASK) |
82+ (INTEL_ID_28F160F3B & FLASH_TYPEMASK);
83+ flash_info[i].size = FLASH_BANK_SIZE;
84+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
85+ memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
86+ if (i == 0)
87+ flashbase = PHYS_FLASH_1;
88+ else
89+ panic("configured to many flash banks!\n");
90+ for (j = 0; j < flash_info[i].sector_count; j++)
91+ {
92+ if (j <= 7)
93+ {
94+ flash_info[i].start[j] = flashbase + j * PARAM_SECT_SIZE;
95+ }
96+ else
97+ {
98+ flash_info[i].start[j] = flashbase + (j - 7)*MAIN_SECT_SIZE;
99+ }
100+ }
101+ size += flash_info[i].size;
102+ }
103+
104+ /* Protect monitor and environment sectors
105+ */
106+ flash_protect(FLAG_PROTECT_SET,
107+ CFG_FLASH_BASE,
108+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
109+ &flash_info[0]);
110+
111+ flash_protect(FLAG_PROTECT_SET,
112+ CFG_ENV_ADDR,
113+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
114+ &flash_info[0]);
115+
116+ return size;
117+}
118+
119+/*-----------------------------------------------------------------------
120+ */
121+void flash_print_info (flash_info_t *info)
122+{
123+ int i;
124+
125+ switch (info->flash_id & FLASH_VENDMASK)
126+ {
127+ case (INTEL_MANUFACT & FLASH_VENDMASK):
128+ printf("Intel: ");
129+ break;
130+ default:
131+ printf("Unknown Vendor ");
132+ break;
133+ }
134+
135+ switch (info->flash_id & FLASH_TYPEMASK)
136+ {
137+ case (INTEL_ID_28F160F3B & FLASH_TYPEMASK):
138+ printf("2x 28F160F3B (16Mbit)\n");
139+ break;
140+ default:
141+ printf("Unknown Chip Type\n");
142+ goto Done;
143+ break;
144+ }
145+
146+ printf(" Size: %ld MB in %d Sectors\n",
147+ info->size >> 20, info->sector_count);
148+
149+ printf(" Sector Start Addresses:");
150+ for (i = 0; i < info->sector_count; i++)
151+ {
152+ if ((i % 5) == 0)
153+ {
154+ printf ("\n ");
155+ }
156+ printf (" %08lX%s", info->start[i],
157+ info->protect[i] ? " (RO)" : " ");
158+ }
159+ printf ("\n");
160+
161+Done:
162+}
163+
164+/*-----------------------------------------------------------------------
165+ */
166+
167+int flash_error (ulong code)
168+{
169+ /* Check bit patterns */
170+ /* SR.7=0 is busy, SR.7=1 is ready */
171+ /* all other flags indicate error on 1 */
172+ /* SR.0 is undefined */
173+ /* Timeout is our faked flag */
174+
175+ /* sequence is described in Intel 290644-005 document */
176+
177+ /* check Timeout */
178+ if (code & BIT_TIMEOUT)
179+ {
180+ printf ("Timeout\n");
181+ return ERR_TIMOUT;
182+ }
183+
184+ /* check Busy, SR.7 */
185+ if (~code & BIT_BUSY)
186+ {
187+ printf ("Busy\n");
188+ return ERR_PROG_ERROR;
189+ }
190+
191+ /* check Vpp low, SR.3 */
192+ if (code & BIT_VPP_RANGE_ERROR)
193+ {
194+ printf ("Vpp range error\n");
195+ return ERR_PROG_ERROR;
196+ }
197+
198+ /* check Device Protect Error, SR.1 */
199+ if (code & BIT_PROTECT_ERROR)
200+ {
201+ printf ("Device protect error\n");
202+ return ERR_PROG_ERROR;
203+ }
204+
205+ /* check Command Seq Error, SR.4 & SR.5 */
206+ if (code & BIT_SEQUENCE_ERROR)
207+ {
208+ printf ("Command seqence error\n");
209+ return ERR_PROG_ERROR;
210+ }
211+
212+ /* check Block Erase Error, SR.5 */
213+ if (code & BIT_ERASE_ERROR)
214+ {
215+ printf ("Block erase error\n");
216+ return ERR_PROG_ERROR;
217+ }
218+
219+ /* check Program Error, SR.4 */
220+ if (code & BIT_PROGRAM_ERROR)
221+ {
222+ printf ("Program error\n");
223+ return ERR_PROG_ERROR;
224+ }
225+
226+ /* check Block Erase Suspended, SR.6 */
227+ if (code & BIT_ERASE_SUSPEND)
228+ {
229+ printf ("Block erase suspended\n");
230+ return ERR_PROG_ERROR;
231+ }
232+
233+ /* check Program Suspended, SR.2 */
234+ if (code & BIT_PROGRAM_SUSPEND)
235+ {
236+ printf ("Program suspended\n");
237+ return ERR_PROG_ERROR;
238+ }
239+
240+ /* OK, no error */
241+ return ERR_OK;
242+}
243+
244+/*-----------------------------------------------------------------------
245+ */
246+
247+int flash_erase (flash_info_t *info, int s_first, int s_last)
248+{
249+ ulong result;
250+ int iflag, cflag, prot, sect;
251+ int rc = ERR_OK;
252+
253+ /* first look for protection bits */
254+
255+ if (info->flash_id == FLASH_UNKNOWN)
256+ return ERR_UNKNOWN_FLASH_TYPE;
257+
258+ if ((s_first < 0) || (s_first > s_last)) {
259+ return ERR_INVAL;
260+ }
261+
262+ if ((info->flash_id & FLASH_VENDMASK) !=
263+ (INTEL_MANUFACT & FLASH_VENDMASK)) {
264+ return ERR_UNKNOWN_FLASH_VENDOR;
265+ }
266+
267+ prot = 0;
268+ for (sect=s_first; sect<=s_last; ++sect) {
269+ if (info->protect[sect]) {
270+ prot++;
271+ }
272+ }
273+ if (prot)
274+ return ERR_PROTECTED;
275+
276+ /*
277+ * Disable interrupts which might cause a timeout
278+ * here. Remember that our exception vectors are
279+ * at address 0 in the flash, and we don't want a
280+ * (ticker) exception to happen while the flash
281+ * chip is in programming mode.
282+ */
283+ cflag = icache_status();
284+ icache_disable();
285+ iflag = disable_interrupts();
286+
287+ /* Start erase on unprotected sectors */
288+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
289+ {
290+ printf("Erasing sector %2d ... ", sect);
291+
292+ /* arm simple, non interrupt dependent timer */
293+ reset_timer_masked();
294+
295+ if (info->protect[sect] == 0)
296+ { /* not protected */
297+ vu_long *addr = (vu_long *)(info->start[sect]);
298+
299+ *addr = PUZZLE_TO_FLASH(CMD_STATUS_RESET);
300+ *addr = PUZZLE_TO_FLASH(CMD_ERASE_SETUP);
301+ *addr = PUZZLE_TO_FLASH(CMD_ERASE_CONFIRM);
302+
303+ /* wait until flash is ready */
304+ do
305+ {
306+ /* check timeout */
307+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
308+ {
309+ *addr = PUZZLE_TO_FLASH(CMD_SUSPEND);
310+ result = BIT_TIMEOUT;
311+ break;
312+ }
313+
314+ result = PUZZLE_FROM_FLASH(*addr);
315+ } while (~result & BIT_BUSY);
316+
317+ *addr = PUZZLE_TO_FLASH(CMD_READ_ARRAY);
318+
319+ if ((rc = flash_error(result)) != ERR_OK)
320+ goto outahere;
321+
322+ printf("ok.\n");
323+ }
324+ else /* it was protected */
325+ {
326+ printf("protected!\n");
327+ }
328+ }
329+
330+ if (ctrlc())
331+ printf("User Interrupt!\n");
332+
333+outahere:
334+ /* allow flash to settle - wait 10 ms */
335+ udelay_masked(10000);
336+
337+ if (iflag)
338+ enable_interrupts();
339+
340+ if (cflag)
341+ icache_enable();
342+
343+ return rc;
344+}
345+
346+/*-----------------------------------------------------------------------
347+ * Copy memory to flash
348+ */
349+
350+volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
351+{
352+ vu_long *addr = (vu_long *)dest;
353+ ulong result;
354+ int rc = ERR_OK;
355+ int cflag, iflag;
356+
357+ /* Check if Flash is (sufficiently) erased
358+ */
359+ result = PUZZLE_FROM_FLASH(*addr);
360+ if ((result & data) != data)
361+ return ERR_NOT_ERASED;
362+
363+ /*
364+ * Disable interrupts which might cause a timeout
365+ * here. Remember that our exception vectors are
366+ * at address 0 in the flash, and we don't want a
367+ * (ticker) exception to happen while the flash
368+ * chip is in programming mode.
369+ */
370+ cflag = icache_status();
371+ icache_disable();
372+ iflag = disable_interrupts();
373+
374+ *addr = PUZZLE_TO_FLASH(CMD_STATUS_RESET);
375+ *addr = PUZZLE_TO_FLASH(CMD_PROGRAM);
376+ *addr = data;
377+
378+ /* arm simple, non interrupt dependent timer */
379+ reset_timer_masked();
380+
381+ /* wait until flash is ready */
382+ do
383+ {
384+ /* check timeout */
385+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
386+ {
387+ *addr = PUZZLE_TO_FLASH(CMD_SUSPEND);
388+ result = BIT_TIMEOUT;
389+ break;
390+ }
391+
392+ result = PUZZLE_FROM_FLASH(*addr);
393+ } while (~result & BIT_BUSY);
394+
395+ *addr = PUZZLE_TO_FLASH(CMD_READ_ARRAY);
396+
397+ rc = flash_error(result);
398+
399+ if (iflag)
400+ enable_interrupts();
401+
402+ if (cflag)
403+ icache_enable();
404+
405+ return rc;
406+}
407+
408+/*-----------------------------------------------------------------------
409+ * Copy memory to flash.
410+ */
411+
412+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
413+{
414+ ulong cp, wp, data;
415+ int l;
416+ int i, rc;
417+
418+ wp = (addr & ~3); /* get lower word aligned address */
419+
420+ /*
421+ * handle unaligned start bytes
422+ */
423+ if ((l = addr - wp) != 0) {
424+ data = 0;
425+ for (i=0, cp=wp; i<l; ++i, ++cp) {
426+ data = (data >> 8) | (*(uchar *)cp << 24);
427+ }
428+ for (; i<4 && cnt>0; ++i) {
429+ data = (data >> 8) | (*src++ << 24);
430+ --cnt;
431+ ++cp;
432+ }
433+ for (; cnt==0 && i<4; ++i, ++cp) {
434+ data = (data >> 8) | (*(uchar *)cp << 24);
435+ }
436+
437+ if ((rc = write_word(info, wp, data)) != 0) {
438+ return (rc);
439+ }
440+ wp += 4;
441+ }
442+
443+ /*
444+ * handle word aligned part
445+ */
446+ while (cnt >= 4) {
447+ data = *((vu_long*)src);
448+ if ((rc = write_word(info, wp, data)) != 0) {
449+ return (rc);
450+ }
451+ src += 4;
452+ wp += 4;
453+ cnt -= 4;
454+ }
455+
456+ if (cnt == 0) {
457+ return ERR_OK;
458+ }
459+
460+ /*
461+ * handle unaligned tail bytes
462+ */
463+ data = 0;
464+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
465+ data = (data >> 8) | (*src++ << 24);
466+ --cnt;
467+ }
468+ for (; i<4; ++i, ++cp) {
469+ data = (data >> 8) | (*(uchar *)cp << 24);
470+ }
471+
472+ return write_word(info, wp, data);
473+}
--- /dev/null
+++ b/board/lart/flash.c
@@ -0,0 +1,473 @@
1+/*
2+ * (C) Copyright 2002
3+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4+ * Marius Groeger <mgroeger@sysgo.de>
5+ *
6+ * See file CREDITS for list of people who contributed to this
7+ * project.
8+ *
9+ * This program is free software; you can redistribute it and/or
10+ * modify it under the terms of the GNU General Public License as
11+ * published by the Free Software Foundation; either version 2 of
12+ * the License, or (at your option) any later version.
13+ *
14+ * This program is distributed in the hope that it will be useful,
15+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+ * GNU General Public License for more details.
18+ *
19+ * You should have received a copy of the GNU General Public License
20+ * along with this program; if not, write to the Free Software
21+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22+ * MA 02111-1307 USA
23+ */
24+
25+#include <common.h>
26+
27+ulong myflush(void);
28+
29+
30+#define FLASH_BANK_SIZE 0x800000
31+#define MAIN_SECT_SIZE 0x20000
32+#define PARAM_SECT_SIZE 0x4000
33+
34+/* puzzle magic for lart
35+ * data_*_flash are def'd in flashasm.S
36+ */
37+
38+extern u32 data_from_flash(u32);
39+extern u32 data_to_flash(u32);
40+
41+#define PUZZLE_FROM_FLASH(x) data_from_flash((x))
42+#define PUZZLE_TO_FLASH(x) data_to_flash((x))
43+
44+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
45+
46+
47+#define CMD_READ_ARRAY 0x00FF00FF
48+#define CMD_IDENTIFY 0x00900090
49+#define CMD_ERASE_SETUP 0x00200020
50+#define CMD_ERASE_CONFIRM 0x00D000D0
51+#define CMD_PROGRAM 0x00400040
52+#define CMD_RESUME 0x00D000D0
53+#define CMD_SUSPEND 0x00B000B0
54+#define CMD_STATUS_READ 0x00700070
55+#define CMD_STATUS_RESET 0x00500050
56+
57+#define BIT_BUSY 0x00800080
58+#define BIT_ERASE_SUSPEND 0x00400040
59+#define BIT_ERASE_ERROR 0x00200020
60+#define BIT_PROGRAM_ERROR 0x00100010
61+#define BIT_VPP_RANGE_ERROR 0x00080008
62+#define BIT_PROGRAM_SUSPEND 0x00040004
63+#define BIT_PROTECT_ERROR 0x00020002
64+#define BIT_UNDEFINED 0x00010001
65+
66+#define BIT_SEQUENCE_ERROR 0x00300030
67+#define BIT_TIMEOUT 0x80000000
68+
69+/*-----------------------------------------------------------------------
70+ */
71+
72+ulong flash_init(void)
73+{
74+ int i, j;
75+ ulong size = 0;
76+
77+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
78+ {
79+ ulong flashbase = 0;
80+ flash_info[i].flash_id =
81+ (INTEL_MANUFACT & FLASH_VENDMASK) |
82+ (INTEL_ID_28F160F3B & FLASH_TYPEMASK);
83+ flash_info[i].size = FLASH_BANK_SIZE;
84+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
85+ memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
86+ if (i == 0)
87+ flashbase = PHYS_FLASH_1;
88+ else
89+ panic("configured to many flash banks!\n");
90+ for (j = 0; j < flash_info[i].sector_count; j++)
91+ {
92+ if (j <= 7)
93+ {
94+ flash_info[i].start[j] = flashbase + j * PARAM_SECT_SIZE;
95+ }
96+ else
97+ {
98+ flash_info[i].start[j] = flashbase + (j - 7)*MAIN_SECT_SIZE;
99+ }
100+ }
101+ size += flash_info[i].size;
102+ }
103+
104+ /* Protect monitor and environment sectors
105+ */
106+ flash_protect(FLAG_PROTECT_SET,
107+ CFG_FLASH_BASE,
108+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
109+ &flash_info[0]);
110+
111+ flash_protect(FLAG_PROTECT_SET,
112+ CFG_ENV_ADDR,
113+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
114+ &flash_info[0]);
115+
116+ return size;
117+}
118+
119+/*-----------------------------------------------------------------------
120+ */
121+void flash_print_info (flash_info_t *info)
122+{
123+ int i;
124+
125+ switch (info->flash_id & FLASH_VENDMASK)
126+ {
127+ case (INTEL_MANUFACT & FLASH_VENDMASK):
128+ printf("Intel: ");
129+ break;
130+ default:
131+ printf("Unknown Vendor ");
132+ break;
133+ }
134+
135+ switch (info->flash_id & FLASH_TYPEMASK)
136+ {
137+ case (INTEL_ID_28F160F3B & FLASH_TYPEMASK):
138+ printf("2x 28F160F3B (16Mbit)\n");
139+ break;
140+ default:
141+ printf("Unknown Chip Type\n");
142+ goto Done;
143+ break;
144+ }
145+
146+ printf(" Size: %ld MB in %d Sectors\n",
147+ info->size >> 20, info->sector_count);
148+
149+ printf(" Sector Start Addresses:");
150+ for (i = 0; i < info->sector_count; i++)
151+ {
152+ if ((i % 5) == 0)
153+ {
154+ printf ("\n ");
155+ }
156+ printf (" %08lX%s", info->start[i],
157+ info->protect[i] ? " (RO)" : " ");
158+ }
159+ printf ("\n");
160+
161+Done:
162+}
163+
164+/*-----------------------------------------------------------------------
165+ */
166+
167+int flash_error (ulong code)
168+{
169+ /* Check bit patterns */
170+ /* SR.7=0 is busy, SR.7=1 is ready */
171+ /* all other flags indicate error on 1 */
172+ /* SR.0 is undefined */
173+ /* Timeout is our faked flag */
174+
175+ /* sequence is described in Intel 290644-005 document */
176+
177+ /* check Timeout */
178+ if (code & BIT_TIMEOUT)
179+ {
180+ printf ("Timeout\n");
181+ return ERR_TIMOUT;
182+ }
183+
184+ /* check Busy, SR.7 */
185+ if (~code & BIT_BUSY)
186+ {
187+ printf ("Busy\n");
188+ return ERR_PROG_ERROR;
189+ }
190+
191+ /* check Vpp low, SR.3 */
192+ if (code & BIT_VPP_RANGE_ERROR)
193+ {
194+ printf ("Vpp range error\n");
195+ return ERR_PROG_ERROR;
196+ }
197+
198+ /* check Device Protect Error, SR.1 */
199+ if (code & BIT_PROTECT_ERROR)
200+ {
201+ printf ("Device protect error\n");
202+ return ERR_PROG_ERROR;
203+ }
204+
205+ /* check Command Seq Error, SR.4 & SR.5 */
206+ if (code & BIT_SEQUENCE_ERROR)
207+ {
208+ printf ("Command seqence error\n");
209+ return ERR_PROG_ERROR;
210+ }
211+
212+ /* check Block Erase Error, SR.5 */
213+ if (code & BIT_ERASE_ERROR)
214+ {
215+ printf ("Block erase error\n");
216+ return ERR_PROG_ERROR;
217+ }
218+
219+ /* check Program Error, SR.4 */
220+ if (code & BIT_PROGRAM_ERROR)
221+ {
222+ printf ("Program error\n");
223+ return ERR_PROG_ERROR;
224+ }
225+
226+ /* check Block Erase Suspended, SR.6 */
227+ if (code & BIT_ERASE_SUSPEND)
228+ {
229+ printf ("Block erase suspended\n");
230+ return ERR_PROG_ERROR;
231+ }
232+
233+ /* check Program Suspended, SR.2 */
234+ if (code & BIT_PROGRAM_SUSPEND)
235+ {
236+ printf ("Program suspended\n");
237+ return ERR_PROG_ERROR;
238+ }
239+
240+ /* OK, no error */
241+ return ERR_OK;
242+}
243+
244+/*-----------------------------------------------------------------------
245+ */
246+
247+int flash_erase (flash_info_t *info, int s_first, int s_last)
248+{
249+ ulong result;
250+ int iflag, cflag, prot, sect;
251+ int rc = ERR_OK;
252+
253+ /* first look for protection bits */
254+
255+ if (info->flash_id == FLASH_UNKNOWN)
256+ return ERR_UNKNOWN_FLASH_TYPE;
257+
258+ if ((s_first < 0) || (s_first > s_last)) {
259+ return ERR_INVAL;
260+ }
261+
262+ if ((info->flash_id & FLASH_VENDMASK) !=
263+ (INTEL_MANUFACT & FLASH_VENDMASK)) {
264+ return ERR_UNKNOWN_FLASH_VENDOR;
265+ }
266+
267+ prot = 0;
268+ for (sect=s_first; sect<=s_last; ++sect) {
269+ if (info->protect[sect]) {
270+ prot++;
271+ }
272+ }
273+ if (prot)
274+ return ERR_PROTECTED;
275+
276+ /*
277+ * Disable interrupts which might cause a timeout
278+ * here. Remember that our exception vectors are
279+ * at address 0 in the flash, and we don't want a
280+ * (ticker) exception to happen while the flash
281+ * chip is in programming mode.
282+ */
283+ cflag = icache_status();
284+ icache_disable();
285+ iflag = disable_interrupts();
286+
287+ /* Start erase on unprotected sectors */
288+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
289+ {
290+ printf("Erasing sector %2d ... ", sect);
291+
292+ /* arm simple, non interrupt dependent timer */
293+ reset_timer_masked();
294+
295+ if (info->protect[sect] == 0)
296+ { /* not protected */
297+ vu_long *addr = (vu_long *)(info->start[sect]);
298+
299+ *addr = PUZZLE_TO_FLASH(CMD_STATUS_RESET);
300+ *addr = PUZZLE_TO_FLASH(CMD_ERASE_SETUP);
301+ *addr = PUZZLE_TO_FLASH(CMD_ERASE_CONFIRM);
302+
303+ /* wait until flash is ready */
304+ do
305+ {
306+ /* check timeout */
307+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
308+ {
309+ *addr = PUZZLE_TO_FLASH(CMD_SUSPEND);
310+ result = BIT_TIMEOUT;
311+ break;
312+ }
313+
314+ result = PUZZLE_FROM_FLASH(*addr);
315+ } while (~result & BIT_BUSY);
316+
317+ *addr = PUZZLE_TO_FLASH(CMD_READ_ARRAY);
318+
319+ if ((rc = flash_error(result)) != ERR_OK)
320+ goto outahere;
321+
322+ printf("ok.\n");
323+ }
324+ else /* it was protected */
325+ {
326+ printf("protected!\n");
327+ }
328+ }
329+
330+ if (ctrlc())
331+ printf("User Interrupt!\n");
332+
333+outahere:
334+ /* allow flash to settle - wait 10 ms */
335+ udelay_masked(10000);
336+
337+ if (iflag)
338+ enable_interrupts();
339+
340+ if (cflag)
341+ icache_enable();
342+
343+ return rc;
344+}
345+
346+/*-----------------------------------------------------------------------
347+ * Copy memory to flash
348+ */
349+
350+volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
351+{
352+ vu_long *addr = (vu_long *)dest;
353+ ulong result;
354+ int rc = ERR_OK;
355+ int cflag, iflag;
356+
357+ /* Check if Flash is (sufficiently) erased
358+ */
359+ result = PUZZLE_FROM_FLASH(*addr);
360+ if ((result & data) != data)
361+ return ERR_NOT_ERASED;
362+
363+ /*
364+ * Disable interrupts which might cause a timeout
365+ * here. Remember that our exception vectors are
366+ * at address 0 in the flash, and we don't want a
367+ * (ticker) exception to happen while the flash
368+ * chip is in programming mode.
369+ */
370+ cflag = icache_status();
371+ icache_disable();
372+ iflag = disable_interrupts();
373+
374+ *addr = PUZZLE_TO_FLASH(CMD_STATUS_RESET);
375+ *addr = PUZZLE_TO_FLASH(CMD_PROGRAM);
376+ *addr = data;
377+
378+ /* arm simple, non interrupt dependent timer */
379+ reset_timer_masked();
380+
381+ /* wait until flash is ready */
382+ do
383+ {
384+ /* check timeout */
385+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
386+ {
387+ *addr = PUZZLE_TO_FLASH(CMD_SUSPEND);
388+ result = BIT_TIMEOUT;
389+ break;
390+ }
391+
392+ result = PUZZLE_FROM_FLASH(*addr);
393+ } while (~result & BIT_BUSY);
394+
395+ *addr = PUZZLE_TO_FLASH(CMD_READ_ARRAY);
396+
397+ rc = flash_error(result);
398+
399+ if (iflag)
400+ enable_interrupts();
401+
402+ if (cflag)
403+ icache_enable();
404+
405+ return rc;
406+}
407+
408+/*-----------------------------------------------------------------------
409+ * Copy memory to flash.
410+ */
411+
412+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
413+{
414+ ulong cp, wp, data;
415+ int l;
416+ int i, rc;
417+
418+ wp = (addr & ~3); /* get lower word aligned address */
419+
420+ /*
421+ * handle unaligned start bytes
422+ */
423+ if ((l = addr - wp) != 0) {
424+ data = 0;
425+ for (i=0, cp=wp; i<l; ++i, ++cp) {
426+ data = (data >> 8) | (*(uchar *)cp << 24);
427+ }
428+ for (; i<4 && cnt>0; ++i) {
429+ data = (data >> 8) | (*src++ << 24);
430+ --cnt;
431+ ++cp;
432+ }
433+ for (; cnt==0 && i<4; ++i, ++cp) {
434+ data = (data >> 8) | (*(uchar *)cp << 24);
435+ }
436+
437+ if ((rc = write_word(info, wp, data)) != 0) {
438+ return (rc);
439+ }
440+ wp += 4;
441+ }
442+
443+ /*
444+ * handle word aligned part
445+ */
446+ while (cnt >= 4) {
447+ data = *((vu_long*)src);
448+ if ((rc = write_word(info, wp, data)) != 0) {
449+ return (rc);
450+ }
451+ src += 4;
452+ wp += 4;
453+ cnt -= 4;
454+ }
455+
456+ if (cnt == 0) {
457+ return ERR_OK;
458+ }
459+
460+ /*
461+ * handle unaligned tail bytes
462+ */
463+ data = 0;
464+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
465+ data = (data >> 8) | (*src++ << 24);
466+ --cnt;
467+ }
468+ for (; i<4; ++i, ++cp) {
469+ data = (data >> 8) | (*(uchar *)cp << 24);
470+ }
471+
472+ return write_word(info, wp, data);
473+}
--- /dev/null
+++ b/board/lubbock/flash.c
@@ -0,0 +1,363 @@
1+/*
2+ * (C) Copyright 2002
3+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4+ *
5+ * (C) Copyright 2002
6+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7+ * Marius Groeger <mgroeger@sysgo.de>
8+ *
9+ * See file CREDITS for list of people who contributed to this
10+ * project.
11+ *
12+ * This program is free software; you can redistribute it and/or
13+ * modify it under the terms of the GNU General Public License as
14+ * published by the Free Software Foundation; either version 2 of
15+ * the License, or (at your option) any later version.
16+ *
17+ * This program is distributed in the hope that it will be useful,
18+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+ * GNU General Public License for more details.
21+ *
22+ * You should have received a copy of the GNU General Public License
23+ * along with this program; if not, write to the Free Software
24+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25+ * MA 02111-1307 USA
26+ */
27+
28+#include <common.h>
29+
30+#define FLASH_BANK_SIZE 0x2000000
31+#define MAIN_SECT_SIZE 0x40000 /* 2x16 = 256k per sector */
32+
33+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
34+
35+
36+/*-----------------------------------------------------------------------
37+ */
38+
39+ulong flash_init(void)
40+{
41+ int i, j;
42+ ulong size = 0;
43+
44+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
45+ {
46+ ulong flashbase = 0;
47+ flash_info[i].flash_id =
48+ (INTEL_MANUFACT & FLASH_VENDMASK) |
49+ (INTEL_ID_28F128J3 & FLASH_TYPEMASK);
50+ flash_info[i].size = FLASH_BANK_SIZE;
51+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
52+ memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
53+ switch (i)
54+ {
55+ case 0:
56+ flashbase = PHYS_FLASH_1;
57+ break;
58+ case 1:
59+ flashbase = PHYS_FLASH_2;
60+ break;
61+ default:
62+ panic("configured to many flash banks!\n");
63+ break;
64+ }
65+ for (j = 0; j < flash_info[i].sector_count; j++)
66+ {
67+ flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE;
68+ }
69+ size += flash_info[i].size;
70+ }
71+
72+ /* Protect monitor and environment sectors
73+ */
74+ flash_protect(FLAG_PROTECT_SET,
75+ CFG_FLASH_BASE,
76+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
77+ &flash_info[0]);
78+
79+ flash_protect(FLAG_PROTECT_SET,
80+ CFG_ENV_ADDR,
81+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
82+ &flash_info[0]);
83+
84+ return size;
85+}
86+
87+/*-----------------------------------------------------------------------
88+ */
89+void flash_print_info (flash_info_t *info)
90+{
91+ int i, j;
92+
93+ for (j=0; j<CFG_MAX_FLASH_BANKS; j++)
94+ {
95+ switch (info->flash_id & FLASH_VENDMASK)
96+ {
97+ case (INTEL_MANUFACT & FLASH_VENDMASK):
98+ printf("Intel: ");
99+ break;
100+ default:
101+ printf("Unknown Vendor ");
102+ break;
103+ }
104+
105+ switch (info->flash_id & FLASH_TYPEMASK)
106+ {
107+ case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
108+ printf("28F128J3 (128Mbit)\n");
109+ break;
110+ default:
111+ printf("Unknown Chip Type\n");
112+ goto Done;
113+ break;
114+ }
115+
116+ printf(" Size: %ld MB in %d Sectors\n",
117+ info->size >> 20, info->sector_count);
118+
119+ printf(" Sector Start Addresses:");
120+ for (i = 0; i < info->sector_count; i++)
121+ {
122+ if ((i % 5) == 0)
123+ {
124+ printf ("\n ");
125+ }
126+ printf (" %08lX%s", info->start[i],
127+ info->protect[i] ? " (RO)" : " ");
128+ }
129+ printf ("\n");
130+ info++;
131+ }
132+
133+Done:
134+}
135+
136+/*-----------------------------------------------------------------------
137+ */
138+
139+int flash_erase (flash_info_t *info, int s_first, int s_last)
140+{
141+ int flag, prot, sect;
142+ int rc = ERR_OK;
143+
144+ if (info->flash_id == FLASH_UNKNOWN)
145+ return ERR_UNKNOWN_FLASH_TYPE;
146+
147+ if ((s_first < 0) || (s_first > s_last)) {
148+ return ERR_INVAL;
149+ }
150+
151+ if ((info->flash_id & FLASH_VENDMASK) !=
152+ (INTEL_MANUFACT & FLASH_VENDMASK)) {
153+ return ERR_UNKNOWN_FLASH_VENDOR;
154+ }
155+
156+ prot = 0;
157+ for (sect=s_first; sect<=s_last; ++sect) {
158+ if (info->protect[sect]) {
159+ prot++;
160+ }
161+ }
162+ if (prot)
163+ return ERR_PROTECTED;
164+
165+ /*
166+ * Disable interrupts which might cause a timeout
167+ * here. Remember that our exception vectors are
168+ * at address 0 in the flash, and we don't want a
169+ * (ticker) exception to happen while the flash
170+ * chip is in programming mode.
171+ */
172+ flag = disable_interrupts();
173+
174+ /* Start erase on unprotected sectors */
175+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
176+
177+ printf("Erasing sector %2d ... ", sect);
178+
179+ /* arm simple, non interrupt dependent timer */
180+ reset_timer_masked();
181+
182+ if (info->protect[sect] == 0) { /* not protected */
183+ vu_short *addr = (vu_short *)(info->start[sect]);
184+
185+ *addr = 0x20; /* erase setup */
186+ *addr = 0xD0; /* erase confirm */
187+
188+ while ((*addr & 0x80) != 0x80) {
189+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
190+ *addr = 0xB0; /* suspend erase */
191+ *addr = 0xFF; /* reset to read mode */
192+ rc = ERR_TIMOUT;
193+ goto outahere;
194+ }
195+ }
196+
197+ /* clear status register command */
198+ *addr = 0x50;
199+ /* reset to read mode */
200+ *addr = 0xFF;
201+ }
202+ printf("ok.\n");
203+ }
204+ if (ctrlc())
205+ printf("User Interrupt!\n");
206+
207+outahere:
208+
209+ /* allow flash to settle - wait 10 ms */
210+ udelay_masked(10000);
211+
212+ if (flag)
213+ enable_interrupts();
214+
215+ return rc;
216+}
217+
218+/*-----------------------------------------------------------------------
219+ * Copy memory to flash
220+ */
221+
222+static int write_word (flash_info_t *info, ulong dest, ushort data)
223+{
224+ vu_short *addr = (vu_short *)dest, val;
225+ int rc = ERR_OK;
226+ int flag;
227+
228+ /* Check if Flash is (sufficiently) erased
229+ */
230+ if ((*addr & data) != data)
231+ return ERR_NOT_ERASED;
232+
233+ /*
234+ * Disable interrupts which might cause a timeout
235+ * here. Remember that our exception vectors are
236+ * at address 0 in the flash, and we don't want a
237+ * (ticker) exception to happen while the flash
238+ * chip is in programming mode.
239+ */
240+ flag = disable_interrupts();
241+
242+ /* clear status register command */
243+ *addr = 0x50;
244+
245+ /* program set-up command */
246+ *addr = 0x40;
247+
248+ /* latch address/data */
249+ *addr = data;
250+
251+ /* arm simple, non interrupt dependent timer */
252+ reset_timer_masked();
253+
254+ /* wait while polling the status register */
255+ while(((val = *addr) & 0x80) != 0x80)
256+ {
257+ if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
258+ rc = ERR_TIMOUT;
259+ /* suspend program command */
260+ *addr = 0xB0;
261+ goto outahere;
262+ }
263+ }
264+
265+ if(val & 0x1A) { /* check for error */
266+ printf("\nFlash write error %02x at address %08lx\n",
267+ (int)val, (unsigned long)dest);
268+ if(val & (1<<3)) {
269+ printf("Voltage range error.\n");
270+ rc = ERR_PROG_ERROR;
271+ goto outahere;
272+ }
273+ if(val & (1<<1)) {
274+ printf("Device protect error.\n");
275+ rc = ERR_PROTECTED;
276+ goto outahere;
277+ }
278+ if(val & (1<<4)) {
279+ printf("Programming error.\n");
280+ rc = ERR_PROG_ERROR;
281+ goto outahere;
282+ }
283+ rc = ERR_PROG_ERROR;
284+ goto outahere;
285+ }
286+
287+outahere:
288+ /* read array command */
289+ *addr = 0xFF;
290+
291+ if (flag)
292+ enable_interrupts();
293+
294+ return rc;
295+}
296+
297+/*-----------------------------------------------------------------------
298+ * Copy memory to flash.
299+ */
300+
301+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
302+{
303+ ulong cp, wp;
304+ ushort data;
305+ int l;
306+ int i, rc;
307+
308+ wp = (addr & ~1); /* get lower word aligned address */
309+
310+ /*
311+ * handle unaligned start bytes
312+ */
313+ if ((l = addr - wp) != 0) {
314+ data = 0;
315+ for (i=0, cp=wp; i<l; ++i, ++cp) {
316+ data = (data >> 8) | (*(uchar *)cp << 8);
317+ }
318+ for (; i<2 && cnt>0; ++i) {
319+ data = (data >> 8) | (*src++ << 8);
320+ --cnt;
321+ ++cp;
322+ }
323+ for (; cnt==0 && i<2; ++i, ++cp) {
324+ data = (data >> 8) | (*(uchar *)cp << 8);
325+ }
326+
327+ if ((rc = write_word(info, wp, data)) != 0) {
328+ return (rc);
329+ }
330+ wp += 2;
331+ }
332+
333+ /*
334+ * handle word aligned part
335+ */
336+ while (cnt >= 2) {
337+ data = *((vu_short*)src);
338+ if ((rc = write_word(info, wp, data)) != 0) {
339+ return (rc);
340+ }
341+ src += 2;
342+ wp += 2;
343+ cnt -= 2;
344+ }
345+
346+ if (cnt == 0) {
347+ return ERR_OK;
348+ }
349+
350+ /*
351+ * handle unaligned tail bytes
352+ */
353+ data = 0;
354+ for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
355+ data = (data >> 8) | (*src++ << 8);
356+ --cnt;
357+ }
358+ for (; i<2; ++i, ++cp) {
359+ data = (data >> 8) | (*(uchar *)cp << 8);
360+ }
361+
362+ return write_word(info, wp, data);
363+}
--- /dev/null
+++ b/board/shannon/flash.c
@@ -0,0 +1,472 @@
1+/*
2+ * (C) Copyright 2002
3+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4+ * Alex Zuepke <azu@sysgo.de>
5+ *
6+ * See file CREDITS for list of people who contributed to this
7+ * project.
8+ *
9+ * This program is free software; you can redistribute it and/or
10+ * modify it under the terms of the GNU General Public License as
11+ * published by the Free Software Foundation; either version 2 of
12+ * the License, or (at your option) any later version.
13+ *
14+ * This program is distributed in the hope that it will be useful,
15+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+ * GNU General Public License for more details.
18+ *
19+ * You should have received a copy of the GNU General Public License
20+ * along with this program; if not, write to the Free Software
21+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22+ * MA 02111-1307 USA
23+ */
24+
25+#include <common.h>
26+
27+ulong myflush(void);
28+
29+
30+#define FLASH_BANK_SIZE 0x400000 /* 4 MB */
31+#define MAIN_SECT_SIZE 0x20000 /* 128 KB */
32+
33+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
34+
35+
36+#define CMD_READ_ARRAY 0x00F000F0
37+#define CMD_UNLOCK1 0x00AA00AA
38+#define CMD_UNLOCK2 0x00550055
39+#define CMD_ERASE_SETUP 0x00800080
40+#define CMD_ERASE_CONFIRM 0x00300030
41+#define CMD_PROGRAM 0x00A000A0
42+#define CMD_UNLOCK_BYPASS 0x00200020
43+
44+#define MEM_FLASH_ADDR1 (*(volatile u32 *)(CFG_FLASH_BASE + (0x00000555 << 2)))
45+#define MEM_FLASH_ADDR2 (*(volatile u32 *)(CFG_FLASH_BASE + (0x000002AA << 2)))
46+
47+#define BIT_ERASE_DONE 0x00800080
48+#define BIT_RDY_MASK 0x00800080
49+#define BIT_PROGRAM_ERROR 0x00200020
50+#define BIT_TIMEOUT 0x80000000 /* our flag */
51+
52+#define READY 1
53+#define ERR 2
54+#define TMO 4
55+
56+/*-----------------------------------------------------------------------
57+ */
58+
59+ulong flash_init(void)
60+{
61+ int i, j;
62+ ulong size = 0;
63+
64+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
65+ {
66+ ulong flashbase = 0;
67+ flash_info[i].flash_id =
68+ (AMD_MANUFACT & FLASH_VENDMASK) |
69+ (AMD_ID_LV160B & FLASH_TYPEMASK);
70+ flash_info[i].size = FLASH_BANK_SIZE;
71+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
72+ memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
73+ if (i == 0)
74+ flashbase = PHYS_FLASH_1;
75+ else
76+ panic("configured to many flash banks!\n");
77+ for (j = 0; j < flash_info[i].sector_count; j++)
78+ {
79+
80+ if (j <= 3)
81+ {
82+ /* 1st one is 32 KB */
83+ if (j == 0)
84+ {
85+ flash_info[i].start[j] = flashbase + 0;
86+ }
87+
88+ /* 2nd and 3rd are both 16 KB */
89+ if ((j == 1) || (j == 2))
90+ {
91+ flash_info[i].start[j] = flashbase + 0x8000 + (j-1)*0x4000;
92+ }
93+
94+ /* 4th 64 KB */
95+ if (j == 3)
96+ {
97+ flash_info[i].start[j] = flashbase + 0x10000;
98+ }
99+ }
100+ else
101+ {
102+ flash_info[i].start[j] = flashbase + (j - 3)*MAIN_SECT_SIZE;
103+ }
104+ }
105+ size += flash_info[i].size;
106+ }
107+
108+ /*
109+ * Protect monitor and environment sectors
110+ * Inferno is complicated, it's hardware locked
111+ */
112+#ifdef CONFIG_INFERNO
113+ /* first one, 0x00000 to 0x07fff */
114+ flash_protect(FLAG_PROTECT_SET,
115+ CFG_FLASH_BASE + 0x00000,
116+ CFG_FLASH_BASE + 0x08000 - 1,
117+ &flash_info[0]);
118+
119+ /* third to 10th, 0x0c000 - 0xdffff */
120+ flash_protect(FLAG_PROTECT_SET,
121+ CFG_FLASH_BASE + 0x0c000,
122+ CFG_FLASH_BASE + 0xe0000 - 1,
123+ &flash_info[0]);
124+#else
125+ flash_protect(FLAG_PROTECT_SET,
126+ CFG_FLASH_BASE,
127+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
128+ &flash_info[0]);
129+
130+ flash_protect(FLAG_PROTECT_SET,
131+ CFG_ENV_ADDR,
132+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
133+ &flash_info[0]);
134+#endif
135+ return size;
136+}
137+
138+/*-----------------------------------------------------------------------
139+ */
140+void flash_print_info (flash_info_t *info)
141+{
142+ int i;
143+
144+ switch (info->flash_id & FLASH_VENDMASK)
145+ {
146+ case (AMD_MANUFACT & FLASH_VENDMASK):
147+ printf("AMD: ");
148+ break;
149+ default:
150+ printf("Unknown Vendor ");
151+ break;
152+ }
153+
154+ switch (info->flash_id & FLASH_TYPEMASK)
155+ {
156+ case (AMD_ID_LV160B & FLASH_TYPEMASK):
157+ printf("2x Amd29F160BB (16Mbit)\n");
158+ break;
159+ default:
160+ printf("Unknown Chip Type\n");
161+ goto Done;
162+ break;
163+ }
164+
165+ printf(" Size: %ld MB in %d Sectors\n",
166+ info->size >> 20, info->sector_count);
167+
168+ printf(" Sector Start Addresses:");
169+ for (i = 0; i < info->sector_count; i++)
170+ {
171+ if ((i % 5) == 0)
172+ {
173+ printf ("\n ");
174+ }
175+ printf (" %08lX%s", info->start[i],
176+ info->protect[i] ? " (RO)" : " ");
177+ }
178+ printf ("\n");
179+
180+Done:
181+}
182+
183+/*-----------------------------------------------------------------------
184+ */
185+
186+int flash_erase (flash_info_t *info, int s_first, int s_last)
187+{
188+ ulong result;
189+ int iflag, cflag, prot, sect;
190+ int rc = ERR_OK;
191+ int chip1, chip2;
192+
193+ /* first look for protection bits */
194+
195+ if (info->flash_id == FLASH_UNKNOWN)
196+ return ERR_UNKNOWN_FLASH_TYPE;
197+
198+ if ((s_first < 0) || (s_first > s_last)) {
199+ return ERR_INVAL;
200+ }
201+
202+ if ((info->flash_id & FLASH_VENDMASK) !=
203+ (AMD_MANUFACT & FLASH_VENDMASK)) {
204+ return ERR_UNKNOWN_FLASH_VENDOR;
205+ }
206+
207+ prot = 0;
208+ for (sect=s_first; sect<=s_last; ++sect) {
209+ if (info->protect[sect]) {
210+ prot++;
211+ }
212+ }
213+ if (prot)
214+ return ERR_PROTECTED;
215+
216+ /*
217+ * Disable interrupts which might cause a timeout
218+ * here. Remember that our exception vectors are
219+ * at address 0 in the flash, and we don't want a
220+ * (ticker) exception to happen while the flash
221+ * chip is in programming mode.
222+ */
223+ cflag = icache_status();
224+ icache_disable();
225+ iflag = disable_interrupts();
226+
227+ /* Start erase on unprotected sectors */
228+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
229+ {
230+ printf("Erasing sector %2d ... ", sect);
231+
232+ /* arm simple, non interrupt dependent timer */
233+ reset_timer_masked();
234+
235+ if (info->protect[sect] == 0)
236+ { /* not protected */
237+ vu_long *addr = (vu_long *)(info->start[sect]);
238+
239+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
240+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
241+ MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
242+
243+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
244+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
245+ *addr = CMD_ERASE_CONFIRM;
246+
247+ /* wait until flash is ready */
248+ chip1 = chip2 = 0;
249+
250+ do
251+ {
252+ result = *addr;
253+
254+ /* check timeout */
255+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
256+ {
257+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
258+ chip1 = TMO;
259+ break;
260+ }
261+
262+ if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
263+ chip1 = READY;
264+
265+ if (!chip1 && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
266+ chip1 = ERR;
267+
268+ if (!chip2 && (result >> 16) & BIT_ERASE_DONE)
269+ chip2 = READY;
270+
271+ if (!chip2 && (result >> 16) & BIT_PROGRAM_ERROR)
272+ chip2 = ERR;
273+
274+ } while (!chip1 || !chip2);
275+
276+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
277+
278+ if (chip1 == ERR || chip2 == ERR)
279+ {
280+ rc = ERR_PROG_ERROR;
281+ goto outahere;
282+ }
283+ if (chip1 == TMO)
284+ {
285+ rc = ERR_TIMOUT;
286+ goto outahere;
287+ }
288+
289+ printf("ok.\n");
290+ }
291+ else /* it was protected */
292+ {
293+ printf("protected!\n");
294+ }
295+ }
296+
297+ if (ctrlc())
298+ printf("User Interrupt!\n");
299+
300+outahere:
301+ /* allow flash to settle - wait 10 ms */
302+ udelay_masked(10000);
303+
304+ if (iflag)
305+ enable_interrupts();
306+
307+ if (cflag)
308+ icache_enable();
309+
310+ return rc;
311+}
312+
313+/*-----------------------------------------------------------------------
314+ * Copy memory to flash
315+ */
316+
317+volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
318+{
319+ vu_long *addr = (vu_long *)dest;
320+ ulong result;
321+ int rc = ERR_OK;
322+ int cflag, iflag;
323+ int chip1, chip2;
324+
325+ /*
326+ * Check if Flash is (sufficiently) erased
327+ */
328+ result = *addr;
329+ if ((result & data) != data)
330+ return ERR_NOT_ERASED;
331+
332+
333+ /*
334+ * Disable interrupts which might cause a timeout
335+ * here. Remember that our exception vectors are
336+ * at address 0 in the flash, and we don't want a
337+ * (ticker) exception to happen while the flash
338+ * chip is in programming mode.
339+ */
340+ cflag = icache_status();
341+ icache_disable();
342+ iflag = disable_interrupts();
343+
344+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
345+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
346+ MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
347+ *addr = CMD_PROGRAM;
348+ *addr = data;
349+
350+ /* arm simple, non interrupt dependent timer */
351+ reset_timer_masked();
352+
353+ /* wait until flash is ready */
354+ chip1 = chip2 = 0;
355+ do
356+ {
357+ result = *addr;
358+
359+ /* check timeout */
360+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
361+ {
362+ chip1 = ERR | TMO;
363+ break;
364+ }
365+ if (!chip1 && ((result & 0x80) == (data & 0x80)))
366+ chip1 = READY;
367+
368+ if (!chip1 && ((result & 0xFFFF) & BIT_PROGRAM_ERROR))
369+ {
370+ result = *addr;
371+
372+ if ((result & 0x80) == (data & 0x80))
373+ chip1 = READY;
374+ else
375+ chip1 = ERR;
376+ }
377+
378+ if (!chip2 && ((result & (0x80 << 16)) == (data & (0x80 << 16))))
379+ chip2 = READY;
380+
381+ if (!chip2 && ((result >> 16) & BIT_PROGRAM_ERROR))
382+ {
383+ result = *addr;
384+
385+ if ((result & (0x80 << 16)) == (data & (0x80 << 16)))
386+ chip2 = READY;
387+ else
388+ chip2 = ERR;
389+ }
390+
391+ } while (!chip1 || !chip2);
392+
393+ *addr = CMD_READ_ARRAY;
394+
395+ if (chip1 == ERR || chip2 == ERR || *addr != data)
396+ rc = ERR_PROG_ERROR;
397+
398+ if (iflag)
399+ enable_interrupts();
400+
401+ if (cflag)
402+ icache_enable();
403+
404+ return rc;
405+}
406+
407+/*-----------------------------------------------------------------------
408+ * Copy memory to flash.
409+ */
410+
411+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
412+{
413+ ulong cp, wp, data;
414+ int l;
415+ int i, rc;
416+
417+ wp = (addr & ~3); /* get lower word aligned address */
418+
419+ /*
420+ * handle unaligned start bytes
421+ */
422+ if ((l = addr - wp) != 0) {
423+ data = 0;
424+ for (i=0, cp=wp; i<l; ++i, ++cp) {
425+ data = (data >> 8) | (*(uchar *)cp << 24);
426+ }
427+ for (; i<4 && cnt>0; ++i) {
428+ data = (data >> 8) | (*src++ << 24);
429+ --cnt;
430+ ++cp;
431+ }
432+ for (; cnt==0 && i<4; ++i, ++cp) {
433+ data = (data >> 8) | (*(uchar *)cp << 24);
434+ }
435+
436+ if ((rc = write_word(info, wp, data)) != 0) {
437+ return (rc);
438+ }
439+ wp += 4;
440+ }
441+
442+ /*
443+ * handle word aligned part
444+ */
445+ while (cnt >= 4) {
446+ data = *((vu_long*)src);
447+ if ((rc = write_word(info, wp, data)) != 0) {
448+ return (rc);
449+ }
450+ src += 4;
451+ wp += 4;
452+ cnt -= 4;
453+ }
454+
455+ if (cnt == 0) {
456+ return ERR_OK;
457+ }
458+
459+ /*
460+ * handle unaligned tail bytes
461+ */
462+ data = 0;
463+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
464+ data = (data >> 8) | (*src++ << 24);
465+ --cnt;
466+ }
467+ for (; i<4; ++i, ++cp) {
468+ data = (data >> 8) | (*(uchar *)cp << 24);
469+ }
470+
471+ return write_word(info, wp, data);
472+}
--- /dev/null
+++ b/board/smdk2400/flash.c
@@ -0,0 +1,491 @@
1+/*
2+ * (C) Copyright 2002
3+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4+ * Marius Groeger <mgroeger@sysgo.de>
5+ *
6+ * (C) Copyright 2002
7+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
8+ *
9+ * See file CREDITS for list of people who contributed to this
10+ * project.
11+ *
12+ * This program is free software; you can redistribute it and/or
13+ * modify it under the terms of the GNU General Public License as
14+ * published by the Free Software Foundation; either version 2 of
15+ * the License, or (at your option) any later version.
16+ *
17+ * This program is distributed in the hope that it will be useful,
18+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+ * GNU General Public License for more details.
21+ *
22+ * You should have received a copy of the GNU General Public License
23+ * along with this program; if not, write to the Free Software
24+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25+ * MA 02111-1307 USA
26+ */
27+
28+/* #define DEBUG */
29+
30+#include <common.h>
31+#include <environment.h>
32+
33+#define FLASH_BANK_SIZE 0x1000000 /* 2 x 8 MB */
34+#define MAIN_SECT_SIZE 0x40000 /* 2 x 128 kB */
35+
36+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
37+
38+
39+#define CMD_READ_ARRAY 0x00FF00FF
40+#define CMD_IDENTIFY 0x00900090
41+#define CMD_ERASE_SETUP 0x00200020
42+#define CMD_ERASE_CONFIRM 0x00D000D0
43+#define CMD_PROGRAM 0x00400040
44+#define CMD_RESUME 0x00D000D0
45+#define CMD_SUSPEND 0x00B000B0
46+#define CMD_STATUS_READ 0x00700070
47+#define CMD_STATUS_RESET 0x00500050
48+
49+#define BIT_BUSY 0x00800080
50+#define BIT_ERASE_SUSPEND 0x00400040
51+#define BIT_ERASE_ERROR 0x00200020
52+#define BIT_PROGRAM_ERROR 0x00100010
53+#define BIT_VPP_RANGE_ERROR 0x00080008
54+#define BIT_PROGRAM_SUSPEND 0x00040004
55+#define BIT_PROTECT_ERROR 0x00020002
56+#define BIT_UNDEFINED 0x00010001
57+
58+#define BIT_SEQUENCE_ERROR 0x00300030
59+#define BIT_TIMEOUT 0x80000000
60+
61+/*-----------------------------------------------------------------------
62+ */
63+
64+ulong flash_init (void)
65+{
66+ int i, j;
67+ ulong size = 0;
68+
69+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
70+ ulong flashbase = 0;
71+
72+ flash_info[i].flash_id =
73+ (INTEL_MANUFACT & FLASH_VENDMASK) |
74+ (INTEL_ID_28F640J3A & FLASH_TYPEMASK);
75+ flash_info[i].size = FLASH_BANK_SIZE;
76+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
77+ memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
78+ if (i == 0)
79+ flashbase = PHYS_FLASH_1;
80+ else
81+ panic ("configured too many flash banks!\n");
82+ for (j = 0; j < flash_info[i].sector_count; j++) {
83+ flash_info[i].start[j] = flashbase;
84+
85+ /* uniform sector size */
86+ flashbase += MAIN_SECT_SIZE;
87+ }
88+ size += flash_info[i].size;
89+ }
90+
91+ /*
92+ * Protect monitor and environment sectors
93+ */
94+ flash_protect ( FLAG_PROTECT_SET,
95+ CFG_FLASH_BASE,
96+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
97+ &flash_info[0]);
98+
99+ flash_protect ( FLAG_PROTECT_SET,
100+ CFG_ENV_ADDR,
101+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
102+
103+#ifdef CFG_ENV_ADDR_REDUND
104+ flash_protect ( FLAG_PROTECT_SET,
105+ CFG_ENV_ADDR_REDUND,
106+ CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
107+ &flash_info[0]);
108+#endif
109+
110+ return size;
111+}
112+
113+/*-----------------------------------------------------------------------
114+ */
115+void flash_print_info (flash_info_t * info)
116+{
117+ int i;
118+
119+ switch (info->flash_id & FLASH_VENDMASK) {
120+ case (INTEL_MANUFACT & FLASH_VENDMASK):
121+ printf ("Intel: ");
122+ break;
123+ default:
124+ printf ("Unknown Vendor ");
125+ break;
126+ }
127+
128+ switch (info->flash_id & FLASH_TYPEMASK) {
129+ case (INTEL_ID_28F640J3A & FLASH_TYPEMASK):
130+ printf ("2x 28F640J3A (64Mbit)\n");
131+ break;
132+ default:
133+ printf ("Unknown Chip Type\n");
134+ goto Done;
135+ break;
136+ }
137+
138+ printf (" Size: %ld MB in %d Sectors\n",
139+ info->size >> 20, info->sector_count);
140+
141+ printf (" Sector Start Addresses:");
142+ for (i = 0; i < info->sector_count; i++) {
143+ if ((i % 5) == 0) {
144+ printf ("\n ");
145+ }
146+ printf (" %08lX%s",
147+ info->start[i],
148+ info->protect[i] ? " (RO)" : " ");
149+ }
150+ printf ("\n");
151+
152+ Done:
153+}
154+
155+/*-----------------------------------------------------------------------
156+ */
157+
158+int flash_error (ulong code)
159+{
160+ /* Check bit patterns */
161+ /* SR.7=0 is busy, SR.7=1 is ready */
162+ /* all other flags indicate error on 1 */
163+ /* SR.0 is undefined */
164+ /* Timeout is our faked flag */
165+
166+ /* sequence is described in Intel 290644-005 document */
167+
168+ /* check Timeout */
169+ if (code & BIT_TIMEOUT) {
170+ puts ("Timeout\n");
171+ return ERR_TIMOUT;
172+ }
173+
174+ /* check Busy, SR.7 */
175+ if (~code & BIT_BUSY) {
176+ puts ("Busy\n");
177+ return ERR_PROG_ERROR;
178+ }
179+
180+ /* check Vpp low, SR.3 */
181+ if (code & BIT_VPP_RANGE_ERROR) {
182+ puts ("Vpp range error\n");
183+ return ERR_PROG_ERROR;
184+ }
185+
186+ /* check Device Protect Error, SR.1 */
187+ if (code & BIT_PROTECT_ERROR) {
188+ puts ("Device protect error\n");
189+ return ERR_PROG_ERROR;
190+ }
191+
192+ /* check Command Seq Error, SR.4 & SR.5 */
193+ if (code & BIT_SEQUENCE_ERROR) {
194+ puts ("Command seqence error\n");
195+ return ERR_PROG_ERROR;
196+ }
197+
198+ /* check Block Erase Error, SR.5 */
199+ if (code & BIT_ERASE_ERROR) {
200+ puts ("Block erase error\n");
201+ return ERR_PROG_ERROR;
202+ }
203+
204+ /* check Program Error, SR.4 */
205+ if (code & BIT_PROGRAM_ERROR) {
206+ puts ("Program error\n");
207+ return ERR_PROG_ERROR;
208+ }
209+
210+ /* check Block Erase Suspended, SR.6 */
211+ if (code & BIT_ERASE_SUSPEND) {
212+ puts ("Block erase suspended\n");
213+ return ERR_PROG_ERROR;
214+ }
215+
216+ /* check Program Suspended, SR.2 */
217+ if (code & BIT_PROGRAM_SUSPEND) {
218+ puts ("Program suspended\n");
219+ return ERR_PROG_ERROR;
220+ }
221+
222+ /* OK, no error */
223+ return ERR_OK;
224+}
225+
226+/*-----------------------------------------------------------------------
227+ */
228+
229+int flash_erase (flash_info_t * info, int s_first, int s_last)
230+{
231+ ulong result, result1;
232+ int iflag, prot, sect;
233+ int rc = ERR_OK;
234+
235+#ifdef USE_920T_MMU
236+ int cflag;
237+#endif
238+
239+ debug ("flash_erase: s_first %d s_last %d\n", s_first, s_last);
240+
241+ /* first look for protection bits */
242+
243+ if (info->flash_id == FLASH_UNKNOWN)
244+ return ERR_UNKNOWN_FLASH_TYPE;
245+
246+ if ((s_first < 0) || (s_first > s_last)) {
247+ return ERR_INVAL;
248+ }
249+
250+ if ((info->flash_id & FLASH_VENDMASK) !=
251+ (INTEL_MANUFACT & FLASH_VENDMASK)) {
252+ return ERR_UNKNOWN_FLASH_VENDOR;
253+ }
254+
255+ prot = 0;
256+ for (sect = s_first; sect <= s_last; ++sect) {
257+ if (info->protect[sect]) {
258+ prot++;
259+ }
260+ }
261+
262+ if (prot) {
263+ printf ("- Warning: %d protected sectors will not be erased!\n",
264+ prot);
265+ } else {
266+ printf ("\n");
267+ }
268+
269+ /*
270+ * Disable interrupts which might cause a timeout
271+ * here. Remember that our exception vectors are
272+ * at address 0 in the flash, and we don't want a
273+ * (ticker) exception to happen while the flash
274+ * chip is in programming mode.
275+ */
276+#ifdef USE_920T_MMU
277+ cflag = dcache_status ();
278+ dcache_disable ();
279+#endif
280+ iflag = disable_interrupts ();
281+
282+ /* Start erase on unprotected sectors */
283+ for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
284+
285+ debug ("Erasing sector %2d @ %08lX... ",
286+ sect, info->start[sect]);
287+
288+ /* arm simple, non interrupt dependent timer */
289+ reset_timer_masked ();
290+
291+ if (info->protect[sect] == 0) { /* not protected */
292+ vu_long *addr = (vu_long *) (info->start[sect]);
293+ ulong bsR7, bsR7_2, bsR5, bsR5_2;
294+
295+ /* *addr = CMD_STATUS_RESET; */
296+ *addr = CMD_ERASE_SETUP;
297+ *addr = CMD_ERASE_CONFIRM;
298+
299+ /* wait until flash is ready */
300+ do {
301+ /* check timeout */
302+ if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
303+ *addr = CMD_STATUS_RESET;
304+ result = BIT_TIMEOUT;
305+ break;
306+ }
307+
308+ *addr = CMD_STATUS_READ;
309+ result = *addr;
310+ bsR7 = result & (1 << 7);
311+ bsR7_2 = result & (1 << 23);
312+ } while (!bsR7 | !bsR7_2);
313+
314+ *addr = CMD_STATUS_READ;
315+ result1 = *addr;
316+ bsR5 = result1 & (1 << 5);
317+ bsR5_2 = result1 & (1 << 21);
318+#ifdef SAMSUNG_FLASH_DEBUG
319+ printf ("bsR5 %lx bsR5_2 %lx\n", bsR5, bsR5_2);
320+ if (bsR5 != 0 && bsR5_2 != 0)
321+ printf ("bsR5 %lx bsR5_2 %lx\n", bsR5, bsR5_2);
322+#endif
323+
324+ *addr = CMD_READ_ARRAY;
325+ *addr = CMD_RESUME;
326+
327+ if ((rc = flash_error (result)) != ERR_OK)
328+ goto outahere;
329+#if 0
330+ printf ("ok.\n");
331+ } else { /* it was protected */
332+
333+ printf ("protected!\n");
334+#endif
335+ }
336+ }
337+
338+outahere:
339+ /* allow flash to settle - wait 10 ms */
340+ udelay_masked (10000);
341+
342+ if (iflag)
343+ enable_interrupts ();
344+
345+#ifdef USE_920T_MMU
346+ if (cflag)
347+ dcache_enable ();
348+#endif
349+ return rc;
350+}
351+
352+/*-----------------------------------------------------------------------
353+ * Copy memory to flash
354+ */
355+
356+volatile static int write_word (flash_info_t * info, ulong dest,
357+ ulong data)
358+{
359+ vu_long *addr = (vu_long *) dest;
360+ ulong result;
361+ int rc = ERR_OK;
362+ int iflag;
363+
364+#ifdef USE_920T_MMU
365+ int cflag;
366+#endif
367+
368+ /*
369+ * Check if Flash is (sufficiently) erased
370+ */
371+ result = *addr;
372+ if ((result & data) != data)
373+ return ERR_NOT_ERASED;
374+
375+ /*
376+ * Disable interrupts which might cause a timeout
377+ * here. Remember that our exception vectors are
378+ * at address 0 in the flash, and we don't want a
379+ * (ticker) exception to happen while the flash
380+ * chip is in programming mode.
381+ */
382+#ifdef USE_920T_MMU
383+ cflag = dcache_status ();
384+ dcache_disable ();
385+#endif
386+ iflag = disable_interrupts ();
387+
388+ /* *addr = CMD_STATUS_RESET; */
389+ *addr = CMD_PROGRAM;
390+ *addr = data;
391+
392+ /* arm simple, non interrupt dependent timer */
393+ reset_timer_masked ();
394+
395+ /* wait until flash is ready */
396+ do {
397+ /* check timeout */
398+ if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
399+ *addr = CMD_SUSPEND;
400+ result = BIT_TIMEOUT;
401+ break;
402+ }
403+
404+ *addr = CMD_STATUS_READ;
405+ result = *addr;
406+ } while (~result & BIT_BUSY);
407+
408+ /* *addr = CMD_READ_ARRAY; */
409+ *addr = CMD_STATUS_READ;
410+ result = *addr;
411+
412+ rc = flash_error (result);
413+
414+ if (iflag)
415+ enable_interrupts ();
416+
417+#ifdef USE_920T_MMU
418+ if (cflag)
419+ dcache_enable ();
420+#endif
421+ *addr = CMD_READ_ARRAY;
422+ *addr = CMD_RESUME;
423+ return rc;
424+}
425+
426+/*-----------------------------------------------------------------------
427+ * Copy memory to flash.
428+ */
429+
430+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
431+{
432+ ulong cp, wp, data;
433+ int l;
434+ int i, rc;
435+
436+ wp = (addr & ~3); /* get lower word aligned address */
437+
438+ /*
439+ * handle unaligned start bytes
440+ */
441+ if ((l = addr - wp) != 0) {
442+ data = 0;
443+ for (i = 0, cp = wp; i < l; ++i, ++cp) {
444+ data = (data >> 8) | (*(uchar *) cp << 24);
445+ }
446+ for (; i < 4 && cnt > 0; ++i) {
447+ data = (data >> 8) | (*src++ << 24);
448+ --cnt;
449+ ++cp;
450+ }
451+ for (; cnt == 0 && i < 4; ++i, ++cp) {
452+ data = (data >> 8) | (*(uchar *) cp << 24);
453+ }
454+
455+ if ((rc = write_word (info, wp, data)) != 0) {
456+ return (rc);
457+ }
458+ wp += 4;
459+ }
460+
461+ /*
462+ * handle word aligned part
463+ */
464+ while (cnt >= 4) {
465+ data = *((vu_long *) src);
466+ if ((rc = write_word (info, wp, data)) != 0) {
467+ return (rc);
468+ }
469+ src += 4;
470+ wp += 4;
471+ cnt -= 4;
472+ }
473+
474+ if (cnt == 0) {
475+ return ERR_OK;
476+ }
477+
478+ /*
479+ * handle unaligned tail bytes
480+ */
481+ data = 0;
482+ for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
483+ data = (data >> 8) | (*src++ << 24);
484+ --cnt;
485+ }
486+ for (; i < 4; ++i, ++cp) {
487+ data = (data >> 8) | (*(uchar *) cp << 24);
488+ }
489+
490+ return write_word (info, wp, data);
491+}
--- /dev/null
+++ b/board/smdk2410/flash.c
@@ -0,0 +1,446 @@
1+/*
2+ * (C) Copyright 2002
3+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4+ * Alex Zuepke <azu@sysgo.de>
5+ *
6+ * See file CREDITS for list of people who contributed to this
7+ * project.
8+ *
9+ * This program is free software; you can redistribute it and/or
10+ * modify it under the terms of the GNU General Public License as
11+ * published by the Free Software Foundation; either version 2 of
12+ * the License, or (at your option) any later version.
13+ *
14+ * This program is distributed in the hope that it will be useful,
15+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+ * GNU General Public License for more details.
18+ *
19+ * You should have received a copy of the GNU General Public License
20+ * along with this program; if not, write to the Free Software
21+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22+ * MA 02111-1307 USA
23+ */
24+
25+#include <common.h>
26+
27+ulong myflush(void);
28+
29+
30+#define FLASH_BANK_SIZE PHYS_FLASH_SIZE
31+#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
32+
33+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
34+
35+
36+#define CMD_READ_ARRAY 0x000000F0
37+#define CMD_UNLOCK1 0x000000AA
38+#define CMD_UNLOCK2 0x00000055
39+#define CMD_ERASE_SETUP 0x00000080
40+#define CMD_ERASE_CONFIRM 0x00000030
41+#define CMD_PROGRAM 0x000000A0
42+#define CMD_UNLOCK_BYPASS 0x00000020
43+
44+#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))
45+#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA << 1)))
46+
47+#define BIT_ERASE_DONE 0x00000080
48+#define BIT_RDY_MASK 0x00000080
49+#define BIT_PROGRAM_ERROR 0x00000020
50+#define BIT_TIMEOUT 0x80000000 /* our flag */
51+
52+#define READY 1
53+#define ERR 2
54+#define TMO 4
55+
56+/*-----------------------------------------------------------------------
57+ */
58+
59+ulong flash_init(void)
60+{
61+ int i, j;
62+ ulong size = 0;
63+
64+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
65+ {
66+ ulong flashbase = 0;
67+ flash_info[i].flash_id =
68+#if defined(CONFIG_AMD_LV400)
69+ (AMD_MANUFACT & FLASH_VENDMASK) |
70+ (AMD_ID_LV400B & FLASH_TYPEMASK);
71+#elif defined(CONFIG_AMD_LV800)
72+ (AMD_MANUFACT & FLASH_VENDMASK) |
73+ (AMD_ID_LV800B & FLASH_TYPEMASK);
74+#else
75+#error "Unknown flash configured"
76+#endif
77+ flash_info[i].size = FLASH_BANK_SIZE;
78+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
79+ memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
80+ if (i == 0)
81+ flashbase = PHYS_FLASH_1;
82+ else
83+ panic("configured to many flash banks!\n");
84+ for (j = 0; j < flash_info[i].sector_count; j++)
85+ {
86+ if (j <= 3)
87+ {
88+ /* 1st one is 16 KB */
89+ if (j == 0)
90+ {
91+ flash_info[i].start[j] = flashbase + 0;
92+ }
93+
94+ /* 2nd and 3rd are both 8 KB */
95+ if ((j == 1) || (j == 2))
96+ {
97+ flash_info[i].start[j] = flashbase + 0x4000 + (j-1)*0x2000;
98+ }
99+
100+ /* 4th 32 KB */
101+ if (j == 3)
102+ {
103+ flash_info[i].start[j] = flashbase + 0x8000;
104+ }
105+ }
106+ else
107+ {
108+ flash_info[i].start[j] = flashbase + (j - 3)*MAIN_SECT_SIZE;
109+ }
110+ }
111+ size += flash_info[i].size;
112+ }
113+
114+ flash_protect(FLAG_PROTECT_SET,
115+ CFG_FLASH_BASE,
116+ CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
117+ &flash_info[0]);
118+
119+ flash_protect(FLAG_PROTECT_SET,
120+ CFG_ENV_ADDR,
121+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
122+ &flash_info[0]);
123+
124+ return size;
125+}
126+
127+/*-----------------------------------------------------------------------
128+ */
129+void flash_print_info (flash_info_t *info)
130+{
131+ int i;
132+
133+ switch (info->flash_id & FLASH_VENDMASK)
134+ {
135+ case (AMD_MANUFACT & FLASH_VENDMASK):
136+ printf("AMD: ");
137+ break;
138+ default:
139+ printf("Unknown Vendor ");
140+ break;
141+ }
142+
143+ switch (info->flash_id & FLASH_TYPEMASK)
144+ {
145+ case (AMD_ID_LV400B & FLASH_TYPEMASK):
146+ printf("1x Amd29LV400BB (4Mbit)\n");
147+ break;
148+ case (AMD_ID_LV800B & FLASH_TYPEMASK):
149+ printf("1x Amd29LV800BB (8Mbit)\n");
150+ break;
151+ default:
152+ printf("Unknown Chip Type\n");
153+ goto Done;
154+ break;
155+ }
156+
157+ printf(" Size: %ld MB in %d Sectors\n",
158+ info->size >> 20, info->sector_count);
159+
160+ printf(" Sector Start Addresses:");
161+ for (i = 0; i < info->sector_count; i++)
162+ {
163+ if ((i % 5) == 0)
164+ {
165+ printf ("\n ");
166+ }
167+ printf (" %08lX%s", info->start[i],
168+ info->protect[i] ? " (RO)" : " ");
169+ }
170+ printf ("\n");
171+
172+Done:
173+}
174+
175+/*-----------------------------------------------------------------------
176+ */
177+
178+int flash_erase (flash_info_t *info, int s_first, int s_last)
179+{
180+ ushort result;
181+ int iflag, cflag, prot, sect;
182+ int rc = ERR_OK;
183+ int chip;
184+
185+ /* first look for protection bits */
186+
187+ if (info->flash_id == FLASH_UNKNOWN)
188+ return ERR_UNKNOWN_FLASH_TYPE;
189+
190+ if ((s_first < 0) || (s_first > s_last)) {
191+ return ERR_INVAL;
192+ }
193+
194+ if ((info->flash_id & FLASH_VENDMASK) !=
195+ (AMD_MANUFACT & FLASH_VENDMASK)) {
196+ return ERR_UNKNOWN_FLASH_VENDOR;
197+ }
198+
199+ prot = 0;
200+ for (sect=s_first; sect<=s_last; ++sect) {
201+ if (info->protect[sect]) {
202+ prot++;
203+ }
204+ }
205+ if (prot)
206+ return ERR_PROTECTED;
207+
208+ /*
209+ * Disable interrupts which might cause a timeout
210+ * here. Remember that our exception vectors are
211+ * at address 0 in the flash, and we don't want a
212+ * (ticker) exception to happen while the flash
213+ * chip is in programming mode.
214+ */
215+ cflag = icache_status();
216+ icache_disable();
217+ iflag = disable_interrupts();
218+
219+ /* Start erase on unprotected sectors */
220+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
221+ {
222+ printf("Erasing sector %2d ... ", sect);
223+
224+ /* arm simple, non interrupt dependent timer */
225+ reset_timer_masked();
226+
227+ if (info->protect[sect] == 0)
228+ { /* not protected */
229+ vu_short *addr = (vu_short *)(info->start[sect]);
230+
231+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
232+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
233+ MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
234+
235+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
236+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
237+ *addr = CMD_ERASE_CONFIRM;
238+
239+ /* wait until flash is ready */
240+ chip = 0;
241+
242+ do
243+ {
244+ result = *addr;
245+
246+ /* check timeout */
247+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
248+ {
249+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
250+ chip = TMO;
251+ break;
252+ }
253+
254+ if (!chip && (result & 0xFFFF) & BIT_ERASE_DONE)
255+ chip = READY;
256+
257+ if (!chip && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
258+ chip = ERR;
259+
260+ } while (!chip);
261+
262+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
263+
264+ if (chip == ERR)
265+ {
266+ rc = ERR_PROG_ERROR;
267+ goto outahere;
268+ }
269+ if (chip == TMO)
270+ {
271+ rc = ERR_TIMOUT;
272+ goto outahere;
273+ }
274+
275+ printf("ok.\n");
276+ }
277+ else /* it was protected */
278+ {
279+ printf("protected!\n");
280+ }
281+ }
282+
283+ if (ctrlc())
284+ printf("User Interrupt!\n");
285+
286+outahere:
287+ /* allow flash to settle - wait 10 ms */
288+ udelay_masked(10000);
289+
290+ if (iflag)
291+ enable_interrupts();
292+
293+ if (cflag)
294+ icache_enable();
295+
296+ return rc;
297+}
298+
299+/*-----------------------------------------------------------------------
300+ * Copy memory to flash
301+ */
302+
303+volatile static int write_hword (flash_info_t *info, ulong dest, ushort data)
304+{
305+ vu_short *addr = (vu_short *)dest;
306+ ushort result;
307+ int rc = ERR_OK;
308+ int cflag, iflag;
309+ int chip;
310+
311+ /*
312+ * Check if Flash is (sufficiently) erased
313+ */
314+ result = *addr;
315+ if ((result & data) != data)
316+ return ERR_NOT_ERASED;
317+
318+
319+ /*
320+ * Disable interrupts which might cause a timeout
321+ * here. Remember that our exception vectors are
322+ * at address 0 in the flash, and we don't want a
323+ * (ticker) exception to happen while the flash
324+ * chip is in programming mode.
325+ */
326+ cflag = icache_status();
327+ icache_disable();
328+ iflag = disable_interrupts();
329+
330+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
331+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
332+ MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
333+ *addr = CMD_PROGRAM;
334+ *addr = data;
335+
336+ /* arm simple, non interrupt dependent timer */
337+ reset_timer_masked();
338+
339+ /* wait until flash is ready */
340+ chip = 0;
341+ do
342+ {
343+ result = *addr;
344+
345+ /* check timeout */
346+ if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
347+ {
348+ chip = ERR | TMO;
349+ break;
350+ }
351+ if (!chip && ((result & 0x80) == (data & 0x80)))
352+ chip = READY;
353+
354+ if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR))
355+ {
356+ result = *addr;
357+
358+ if ((result & 0x80) == (data & 0x80))
359+ chip = READY;
360+ else
361+ chip = ERR;
362+ }
363+
364+ } while (!chip);
365+
366+ *addr = CMD_READ_ARRAY;
367+
368+ if (chip == ERR || *addr != data)
369+ rc = ERR_PROG_ERROR;
370+
371+ if (iflag)
372+ enable_interrupts();
373+
374+ if (cflag)
375+ icache_enable();
376+
377+ return rc;
378+}
379+
380+/*-----------------------------------------------------------------------
381+ * Copy memory to flash.
382+ */
383+
384+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
385+{
386+ ulong cp, wp;
387+ int l;
388+ int i, rc;
389+ ushort data;
390+
391+ wp = (addr & ~1); /* get lower word aligned address */
392+
393+ /*
394+ * handle unaligned start bytes
395+ */
396+ if ((l = addr - wp) != 0) {
397+ data = 0;
398+ for (i=0, cp=wp; i<l; ++i, ++cp) {
399+ data = (data >> 8) | (*(uchar *)cp << 8);
400+ }
401+ for (; i<2 && cnt>0; ++i) {
402+ data = (data >> 8) | (*src++ << 8);
403+ --cnt;
404+ ++cp;
405+ }
406+ for (; cnt==0 && i<2; ++i, ++cp) {
407+ data = (data >> 8) | (*(uchar *)cp << 8);
408+ }
409+
410+ if ((rc = write_hword(info, wp, data)) != 0) {
411+ return (rc);
412+ }
413+ wp += 2;
414+ }
415+
416+ /*
417+ * handle word aligned part
418+ */
419+ while (cnt >= 2) {
420+ data = *((vu_short*)src);
421+ if ((rc = write_hword(info, wp, data)) != 0) {
422+ return (rc);
423+ }
424+ src += 2;
425+ wp += 2;
426+ cnt -= 2;
427+ }
428+
429+ if (cnt == 0) {
430+ return ERR_OK;
431+ }
432+
433+ /*
434+ * handle unaligned tail bytes
435+ */
436+ data = 0;
437+ for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
438+ data = (data >> 8) | (*src++ << 8);
439+ --cnt;
440+ }
441+ for (; i<2; ++i, ++cp) {
442+ data = (data >> 8) | (*(uchar *)cp << 8);
443+ }
444+
445+ return write_hword(info, wp, data);
446+}