]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/Marvell/common/intel_flash.c
gic: fixed compilation error in GICv2 wait for interrupt macro
[karo-tx-uboot.git] / board / Marvell / common / intel_flash.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  *
7  * Hacked for the marvell db64360 eval board by
8  * Ingo Assmus <ingo.assmus@keymile.com>
9  */
10
11 #include <common.h>
12 #include <mpc8xx.h>
13 #include "../include/mv_gen_reg.h"
14 #include "../include/memory.h"
15 #include "intel_flash.h"
16
17
18 /*-----------------------------------------------------------------------
19  * Protection Flags:
20  */
21 #define FLAG_PROTECT_SET        0x01
22 #define FLAG_PROTECT_CLEAR      0x02
23
24 static void bank_reset (flash_info_t * info, int sect)
25 {
26         bank_addr_t addrw, eaddrw;
27
28         addrw = (bank_addr_t) info->start[sect];
29         eaddrw = BANK_ADDR_NEXT_WORD (addrw);
30
31         while (addrw < eaddrw) {
32 #ifdef FLASH_DEBUG
33                 printf ("  writing reset cmd to addr 0x%08lx\n",
34                         (unsigned long) addrw);
35 #endif
36                 *addrw = BANK_CMD_RST;
37                 addrw++;
38         }
39 }
40
41 static void bank_erase_init (flash_info_t * info, int sect)
42 {
43         bank_addr_t addrw, saddrw, eaddrw;
44         int flag;
45
46 #ifdef FLASH_DEBUG
47         printf ("0x%08x BANK_CMD_PROG\n", BANK_CMD_PROG);
48         printf ("0x%08x BANK_CMD_ERASE1\n", BANK_CMD_ERASE1);
49         printf ("0x%08x BANK_CMD_ERASE2\n", BANK_CMD_ERASE2);
50         printf ("0x%08x BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT);
51         printf ("0x%08x BANK_CMD_RST\n", BANK_CMD_RST);
52         printf ("0x%08x BANK_STAT_RDY\n", BANK_STAT_RDY);
53         printf ("0x%08x BANK_STAT_ERR\n", BANK_STAT_ERR);
54 #endif
55
56         saddrw = (bank_addr_t) info->start[sect];
57         eaddrw = BANK_ADDR_NEXT_WORD (saddrw);
58
59 #ifdef FLASH_DEBUG
60         printf ("erasing sector %d, start addr = 0x%08lx "
61                 "(bank next word addr = 0x%08lx)\n", sect,
62                 (unsigned long) saddrw, (unsigned long) eaddrw);
63 #endif
64
65         /* Disable intrs which might cause a timeout here */
66         flag = disable_interrupts ();
67
68         for (addrw = saddrw; addrw < eaddrw; addrw++) {
69 #ifdef FLASH_DEBUG
70                 printf ("  writing erase cmd to addr 0x%08lx\n",
71                         (unsigned long) addrw);
72 #endif
73                 *addrw = BANK_CMD_ERASE1;
74                 *addrw = BANK_CMD_ERASE2;
75         }
76
77         /* re-enable interrupts if necessary */
78         if (flag)
79                 enable_interrupts ();
80 }
81
82 static int bank_erase_poll (flash_info_t * info, int sect)
83 {
84         bank_addr_t addrw, saddrw, eaddrw;
85         int sectdone, haderr;
86
87         saddrw = (bank_addr_t) info->start[sect];
88         eaddrw = BANK_ADDR_NEXT_WORD (saddrw);
89
90         sectdone = 1;
91         haderr = 0;
92
93         for (addrw = saddrw; addrw < eaddrw; addrw++) {
94                 bank_word_t stat = *addrw;
95
96 #ifdef FLASH_DEBUG
97                 printf ("  checking status at addr "
98                         "0x%08x [0x%08x]\n", (unsigned long) addrw, stat);
99 #endif
100                 if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY)
101                         sectdone = 0;
102                 else if ((stat & BANK_STAT_ERR) != 0) {
103                         printf (" failed on sector %d "
104                                 "(stat = 0x%08x) at "
105                                 "address 0x%p\n", sect, stat, addrw);
106                         *addrw = BANK_CMD_CLR_STAT;
107                         haderr = 1;
108                 }
109         }
110
111         if (haderr)
112                 return (-1);
113         else
114                 return (sectdone);
115 }
116
117 int write_word_intel (bank_addr_t addr, bank_word_t value)
118 {
119         bank_word_t stat;
120         ulong start;
121         int flag, retval;
122
123         /* Disable interrupts which might cause a timeout here */
124         flag = disable_interrupts ();
125
126         *addr = BANK_CMD_PROG;
127
128         *addr = value;
129
130         /* re-enable interrupts if necessary */
131         if (flag)
132                 enable_interrupts ();
133
134         retval = 0;
135
136         /* data polling for D7 */
137         start = get_timer (0);
138         do {
139                 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
140                         retval = 1;
141                         goto done;
142                 }
143                 stat = *addr;
144         } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
145
146         if ((stat & BANK_STAT_ERR) != 0) {
147                 printf ("flash program failed (stat = 0x%08lx) "
148                         "at address 0x%08lx\n", (ulong) stat, (ulong) addr);
149                 *addr = BANK_CMD_CLR_STAT;
150                 retval = 3;
151         }
152
153       done:
154         /* reset to read mode */
155         *addr = BANK_CMD_RST;
156
157         return (retval);
158 }
159
160 /*-----------------------------------------------------------------------
161  */
162
163 int flash_erase_intel (flash_info_t * info, int s_first, int s_last)
164 {
165         int prot, sect, haderr;
166         ulong start, now, last;
167
168 #ifdef FLASH_DEBUG
169         printf ("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
170                 "  Bank # %d: ", s_last - s_first + 1, s_first, s_last,
171                 (info - flash_info) + 1);
172         flash_print_info (info);
173 #endif
174
175         if ((s_first < 0) || (s_first > s_last)) {
176                 if (info->flash_id == FLASH_UNKNOWN) {
177                         printf ("- missing\n");
178                 } else {
179                         printf ("- no sectors to erase\n");
180                 }
181                 return 1;
182         }
183
184         prot = 0;
185         for (sect = s_first; sect <= s_last; ++sect) {
186                 if (info->protect[sect]) {
187                         prot++;
188                 }
189         }
190
191         if (prot) {
192                 printf ("- Warning: %d protected sector%s will not be erased!\n", prot, (prot > 1 ? "s" : ""));
193         }
194
195         start = get_timer (0);
196         last = 0;
197         haderr = 0;
198
199         for (sect = s_first; sect <= s_last; sect++) {
200                 if (info->protect[sect] == 0) { /* not protected */
201                         ulong estart;
202                         int sectdone;
203
204                         bank_erase_init (info, sect);
205
206                         /* wait at least 80us - let's wait 1 ms */
207                         udelay (1000);
208
209                         estart = get_timer (start);
210
211                         do {
212                                 now = get_timer (start);
213
214                                 if (now - estart > CONFIG_SYS_FLASH_ERASE_TOUT) {
215                                         printf ("Timeout (sect %d)\n", sect);
216                                         haderr = 1;
217                                         break;
218                                 }
219 #ifndef FLASH_DEBUG
220                                 /* show that we're waiting */
221                                 if ((now - last) > 1000) {      /* every second */
222                                         putc ('.');
223                                         last = now;
224                                 }
225 #endif
226
227                                 sectdone = bank_erase_poll (info, sect);
228
229                                 if (sectdone < 0) {
230                                         haderr = 1;
231                                         break;
232                                 }
233
234                         } while (!sectdone);
235
236                         if (haderr)
237                                 break;
238                 }
239         }
240
241         if (haderr > 0)
242                 printf (" failed\n");
243         else
244                 printf (" done\n");
245
246         /* reset to read mode */
247         for (sect = s_first; sect <= s_last; sect++) {
248                 if (info->protect[sect] == 0) { /* not protected */
249                         bank_reset (info, sect);
250                 }
251         }
252         return haderr;
253 }