Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / evb64260 / 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  * Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00
7  */
8
9 #include <common.h>
10 #include <mpc8xx.h>
11 #include <galileo/gt64260R.h>
12 #include <galileo/memory.h>
13 #include "intel_flash.h"
14
15
16 /*-----------------------------------------------------------------------
17  * Protection Flags:
18  */
19 #define FLAG_PROTECT_SET        0x01
20 #define FLAG_PROTECT_CLEAR      0x02
21
22 static void
23 bank_reset(flash_info_t *info, int sect)
24 {
25         bank_addr_t addrw, eaddrw;
26
27         addrw = (bank_addr_t)info->start[sect];
28         eaddrw = BANK_ADDR_NEXT_WORD(addrw);
29
30         while (addrw < eaddrw) {
31 #ifdef FLASH_DEBUG
32                 printf("  writing reset cmd to addr 0x%08lx\n",
33                         (unsigned long)addrw);
34 #endif
35                 *addrw = BANK_CMD_RST;
36                 addrw++;
37         }
38 }
39
40 static void
41 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
83 bank_erase_poll(flash_info_t *info, int sect)
84 {
85         bank_addr_t addrw, saddrw, eaddrw;
86         int sectdone, haderr;
87
88         saddrw = (bank_addr_t)info->start[sect];
89         eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
90
91         sectdone = 1;
92         haderr = 0;
93
94         for (addrw = saddrw; addrw < eaddrw; addrw++) {
95                 bank_word_t stat = *addrw;
96
97 #ifdef FLASH_DEBUG
98                 printf("  checking status at addr "
99                         "0x%08x [0x%08x]\n",
100                         (unsigned long)addrw, stat);
101 #endif
102                 if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY)
103                         sectdone = 0;
104                 else if ((stat & BANK_STAT_ERR) != 0) {
105                         printf(" failed on sector %d "
106                                 "(stat = 0x%08x) at "
107                                 "address 0x%p\n",
108                                 sect, stat, addrw);
109                         *addrw = BANK_CMD_CLR_STAT;
110                         haderr = 1;
111                 }
112         }
113
114         if (haderr)
115                 return (-1);
116         else
117                 return (sectdone);
118 }
119
120 int
121 write_word_intel(bank_addr_t addr, bank_word_t value)
122 {
123         bank_word_t stat;
124         ulong start;
125         int flag, retval;
126
127         /* Disable interrupts which might cause a timeout here */
128         flag = disable_interrupts();
129
130         *addr = BANK_CMD_PROG;
131
132         *addr = value;
133
134         /* re-enable interrupts if necessary */
135         if (flag)
136                 enable_interrupts();
137
138         retval = 0;
139
140         /* data polling for D7 */
141         start = get_timer (0);
142         do {
143                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
144                         retval = 1;
145                         goto done;
146                 }
147                 stat = *addr;
148         } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
149
150         if ((stat & BANK_STAT_ERR) != 0) {
151                 printf("flash program failed (stat = 0x%08lx) "
152                         "at address 0x%08lx\n", (ulong)stat, (ulong)addr);
153                 *addr = BANK_CMD_CLR_STAT;
154                 retval = 3;
155         }
156
157 done:
158         /* reset to read mode */
159         *addr = BANK_CMD_RST;
160
161         return (retval);
162 }
163
164 /*-----------------------------------------------------------------------
165  */
166
167 int
168 flash_erase_intel(flash_info_t *info, int s_first, int s_last)
169 {
170         int prot, sect, haderr;
171         ulong start, now, last;
172
173 #ifdef FLASH_DEBUG
174         printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
175                 "  Bank # %d: ", s_last - s_first + 1, s_first, s_last,
176                 (info - flash_info) + 1);
177         flash_print_info(info);
178 #endif
179
180         if ((s_first < 0) || (s_first > s_last)) {
181                 if (info->flash_id == FLASH_UNKNOWN) {
182                         printf ("- missing\n");
183                 } else {
184                         printf ("- no sectors to erase\n");
185                 }
186                 return 1;
187         }
188
189         prot = 0;
190         for (sect=s_first; sect<=s_last; ++sect) {
191                 if (info->protect[sect]) {
192                         prot++;
193                 }
194         }
195
196         if (prot) {
197                 printf("- Warning: %d protected sector%s will not be erased!\n",
198                         prot, (prot > 1 ? "s" : ""));
199         }
200
201         start = get_timer (0);
202         last = 0;
203         haderr = 0;
204
205         for (sect = s_first; sect <= s_last; sect++) {
206                 if (info->protect[sect] == 0) { /* not protected */
207                         ulong estart;
208                         int sectdone;
209
210                         bank_erase_init(info, sect);
211
212                         /* wait at least 80us - let's wait 1 ms */
213                         udelay (1000);
214
215                         estart = get_timer(start);
216
217                         do {
218                                 now = get_timer(start);
219
220                                 if (now - estart > CONFIG_SYS_FLASH_ERASE_TOUT) {
221                                         printf ("Timeout (sect %d)\n", sect);
222                                         haderr = 1;
223                                         break;
224                                 }
225
226 #ifndef FLASH_DEBUG
227                                 /* show that we're waiting */
228                                 if ((now - last) > 1000) { /* every second */
229                                         putc ('.');
230                                         last = now;
231                                 }
232 #endif
233
234                                 sectdone = bank_erase_poll(info, sect);
235
236                                 if (sectdone < 0) {
237                                         haderr = 1;
238                                         break;
239                                 }
240
241                         } while (!sectdone);
242
243                         if (haderr)
244                                 break;
245                 }
246         }
247
248         if (haderr > 0)
249                 printf (" failed\n");
250         else
251                 printf (" done\n");
252
253         /* reset to read mode */
254         for (sect = s_first; sect <= s_last; sect++) {
255                 if (info->protect[sect] == 0) { /* not protected */
256                         bank_reset(info, sect);
257                 }
258         }
259         return haderr;
260 }