]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/bf533-ezkit/flash.c
karo: tx28: set CONFIG_ENV_OVERWRITE also for NAND environment
[karo-tx-uboot.git] / board / bf533-ezkit / flash.c
1 /*
2  * U-boot - flash.c Flash driver for PSD4256GV
3  *
4  * Copyright (c) 2005-2007 Analog Devices Inc.
5  * This file is based on BF533EzFlash.c originally written by Analog Devices, Inc.
6  *
7  * (C) Copyright 2000-2004
8  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
9  *
10  * SPDX-License-Identifier:     GPL-2.0+
11  */
12
13 #include <asm/io.h>
14 #include "flash-defines.h"
15
16 int AFP_NumSectors = 40;
17 long AFP_SectorSize1 = 0x10000;
18 int AFP_SectorSize2 = 0x4000;
19
20 void flash_reset(void)
21 {
22         reset_flash();
23 }
24
25 unsigned long flash_get_size(ulong baseaddr, flash_info_t * info, int bank_flag)
26 {
27         int id = 0, i = 0;
28         static int FlagDev = 1;
29
30         id = get_codes();
31         if (FlagDev) {
32 #ifdef DEBUG
33                 printf("Device ID of the Flash is %x\n", id);
34 #endif
35                 FlagDev = 0;
36         }
37         info->flash_id = id;
38
39         switch (bank_flag) {
40         case 0:
41                 for (i = PriFlashABegin; i < SecFlashABegin; i++)
42                         info->start[i] = (baseaddr + (i * AFP_SectorSize1));
43                 info->size = 0x200000;
44                 info->sector_count = 32;
45                 break;
46         case 1:
47                 info->start[0] = baseaddr + SecFlashASec1Off;
48                 info->start[1] = baseaddr + SecFlashASec2Off;
49                 info->start[2] = baseaddr + SecFlashASec3Off;
50                 info->start[3] = baseaddr + SecFlashASec4Off;
51                 info->size = 0x10000;
52                 info->sector_count = 4;
53                 break;
54         case 2:
55                 info->start[0] = baseaddr + SecFlashBSec1Off;
56                 info->start[1] = baseaddr + SecFlashBSec2Off;
57                 info->start[2] = baseaddr + SecFlashBSec3Off;
58                 info->start[3] = baseaddr + SecFlashBSec4Off;
59                 info->size = 0x10000;
60                 info->sector_count = 4;
61                 break;
62         }
63         return (info->size);
64 }
65
66 unsigned long flash_init(void)
67 {
68         unsigned long size_b0, size_b1, size_b2;
69         int i;
70
71         size_b0 = size_b1 = size_b2 = 0;
72 #ifdef DEBUG
73         printf("Flash Memory Start 0x%x\n", CONFIG_SYS_FLASH_BASE);
74         printf("Memory Map for the Flash\n");
75         printf("0x20000000 - 0x200FFFFF Flash A Primary (1MB)\n");
76         printf("0x20100000 - 0x201FFFFF Flash B Primary (1MB)\n");
77         printf("0x20200000 - 0x2020FFFF Flash A Secondary (64KB)\n");
78         printf("0x20280000 - 0x2028FFFF Flash B Secondary (64KB)\n");
79         printf("Please type command flinfo for information on Sectors \n");
80 #endif
81         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
82                 flash_info[i].flash_id = FLASH_UNKNOWN;
83         }
84
85         size_b0 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[0], 0);
86         size_b1 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[1], 1);
87         size_b2 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[2], 2);
88
89         if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
90                 printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
91                        size_b0, size_b0 >> 20);
92         }
93
94         (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH0_BASE,
95                             (flash_info[0].start[2] - 1), &flash_info[0]);
96
97         return (size_b0 + size_b1 + size_b2);
98 }
99
100 void flash_print_info(flash_info_t * info)
101 {
102         int i;
103
104         if (info->flash_id == FLASH_UNKNOWN) {
105                 printf("missing or unknown FLASH type\n");
106                 return;
107         }
108
109         switch (info->flash_id) {
110         case FLASH_PSD4256GV:
111                 printf("ST Microelectronics ");
112                 break;
113         default:
114                 printf("Unknown Vendor: (0x%08lX) ", info->flash_id);
115                 break;
116         }
117         for (i = 0; i < info->sector_count; ++i) {
118                 if ((i % 5) == 0)
119                         printf("\n   ");
120                 printf(" %08lX%s",
121                        info->start[i], info->protect[i] ? " (RO)" : "     ");
122         }
123         printf("\n");
124         return;
125 }
126
127 int flash_erase(flash_info_t * info, int s_first, int s_last)
128 {
129         int cnt = 0, i;
130         int prot, sect;
131
132         prot = 0;
133         for (sect = s_first; sect <= s_last; ++sect) {
134                 if (info->protect[sect])
135                         prot++;
136         }
137
138         if (prot)
139                 printf("- Warning: %d protected sectors will not be erased!\n",
140                        prot);
141         else
142                 printf("\n");
143
144         cnt = s_last - s_first + 1;
145
146         if (cnt == FLASH_TOT_SECT) {
147                 printf("Erasing flash, Please Wait \n");
148                 if (erase_flash() < 0) {
149                         printf("Erasing flash failed \n");
150                         return FLASH_FAIL;
151                 }
152         } else {
153                 printf("Erasing Flash locations, Please Wait\n");
154                 for (i = s_first; i <= s_last; i++) {
155                         if (info->protect[i] == 0) {    /* not protected */
156                                 if (erase_block_flash(i, info->start[i]) < 0) {
157                                         printf("Error Sector erasing \n");
158                                         return FLASH_FAIL;
159                                 }
160                         }
161                 }
162         }
163         return FLASH_SUCCESS;
164 }
165
166 int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
167 {
168         int ret;
169         int d;
170         if (addr % 2) {
171                 read_flash(addr - 1 - CONFIG_SYS_FLASH_BASE, &d);
172                 d = (int)((d & 0x00FF) | (*src++ << 8));
173                 ret = write_data(addr - 1, 2, (uchar *) & d);
174                 if (ret == FLASH_FAIL)
175                         return ERR_NOT_ERASED;
176                 ret = write_data(addr + 1, cnt - 1, src);
177         } else
178                 ret = write_data(addr, cnt, src);
179         if (ret == FLASH_FAIL)
180                 return ERR_NOT_ERASED;
181         return FLASH_SUCCESS;
182 }
183
184 int write_data(long lStart, long lCount, uchar * pnData)
185 {
186         long i = 0;
187         unsigned long ulOffset = lStart - CONFIG_SYS_FLASH_BASE;
188         int d;
189         int nSector = 0;
190         int flag = 0;
191
192         if (lCount % 2) {
193                 flag = 1;
194                 lCount = lCount - 1;
195         }
196
197         for (i = 0; i < lCount - 1; i += 2, ulOffset += 2) {
198                 get_sector_number(ulOffset, &nSector);
199                 read_flash(ulOffset, &d);
200                 if (d != 0xffff) {
201                         printf
202                             ("Flash not erased at offset 0x%lx Please erase to reprogram\n",
203                              ulOffset);
204                         return FLASH_FAIL;
205                 }
206                 unlock_flash(ulOffset);
207                 d = (int)(pnData[i] | pnData[i + 1] << 8);
208                 write_flash(ulOffset, d);
209                 if (poll_toggle_bit(ulOffset) < 0) {
210                         printf("Error programming the flash \n");
211                         return FLASH_FAIL;
212                 }
213                 if ((i > 0) && (!(i % AFP_SectorSize2)))
214                         printf(".");
215         }
216         if (flag) {
217                 get_sector_number(ulOffset, &nSector);
218                 read_flash(ulOffset, &d);
219                 if (d != 0xffff) {
220                         printf
221                             ("Flash not erased at offset 0x%lx Please erase to reprogram\n",
222                              ulOffset);
223                         return FLASH_FAIL;
224                 }
225                 unlock_flash(ulOffset);
226                 d = (int)(pnData[i] | (d & 0xFF00));
227                 write_flash(ulOffset, d);
228                 if (poll_toggle_bit(ulOffset) < 0) {
229                         printf("Error programming the flash \n");
230                         return FLASH_FAIL;
231                 }
232         }
233         return FLASH_SUCCESS;
234 }
235
236 int read_data(long ulStart, long lCount, long lStride, int *pnData)
237 {
238         long i = 0;
239         int j = 0;
240         long ulOffset = ulStart;
241         int iShift = 0;
242         int iNumWords = 2;
243         int nLeftover = lCount % 4;
244         int nHi, nLow;
245         int nSector = 0;
246
247         for (i = 0; (i < lCount / 4) && (i < BUFFER_SIZE); i++) {
248                 for (iShift = 0, j = 0; j < iNumWords; j += 2) {
249                         if ((ulOffset >= INVALIDLOCNSTART)
250                             && (ulOffset < INVALIDLOCNEND))
251                                 return FLASH_FAIL;
252
253                         get_sector_number(ulOffset, &nSector);
254                         read_flash(ulOffset, &nLow);
255                         ulOffset += (lStride * 2);
256                         read_flash(ulOffset, &nHi);
257                         ulOffset += (lStride * 2);
258                         pnData[i] = (nHi << 16) | nLow;
259                 }
260         }
261         if (nLeftover > 0) {
262                 if ((ulOffset >= INVALIDLOCNSTART)
263                     && (ulOffset < INVALIDLOCNEND))
264                         return FLASH_FAIL;
265
266                 get_sector_number(ulOffset, &nSector);
267                 read_flash(ulOffset, &pnData[i]);
268         }
269         return FLASH_SUCCESS;
270 }
271
272 int write_flash(long nOffset, int nValue)
273 {
274         long addr;
275
276         addr = (CONFIG_SYS_FLASH_BASE + nOffset);
277         SSYNC();
278         *(unsigned volatile short *)addr = nValue;
279         SSYNC();
280         if (poll_toggle_bit(nOffset) < 0)
281                 return FLASH_FAIL;
282         return FLASH_SUCCESS;
283 }
284
285 int read_flash(long nOffset, int *pnValue)
286 {
287         int nValue = 0x0;
288         long addr = (CONFIG_SYS_FLASH_BASE + nOffset);
289
290         if (nOffset != 0x2)
291                 reset_flash();
292         SSYNC();
293         nValue = *(volatile unsigned short *)addr;
294         SSYNC();
295         *pnValue = nValue;
296         return true;
297 }
298
299 int poll_toggle_bit(long lOffset)
300 {
301         unsigned int u1, u2;
302         unsigned long timeout = 0xFFFFFFFF;
303         volatile unsigned long *FB =
304             (volatile unsigned long *)(0x20000000 + lOffset);
305         while (1) {
306                 if (timeout < 0)
307                         break;
308                 u1 = *(volatile unsigned short *)FB;
309                 u2 = *(volatile unsigned short *)FB;
310                 if ((u1 & 0x0040) == (u2 & 0x0040))
311                         return FLASH_SUCCESS;
312                 if ((u2 & 0x0020) == 0x0000)
313                         continue;
314                 u1 = *(volatile unsigned short *)FB;
315                 if ((u2 & 0x0040) == (u1 & 0x0040))
316                         return FLASH_SUCCESS;
317                 else {
318                         reset_flash();
319                         return FLASH_FAIL;
320                 }
321                 timeout--;
322         }
323         printf("Time out occured \n");
324         if (timeout < 0)
325                 return FLASH_FAIL;
326 }
327
328 void reset_flash(void)
329 {
330         write_flash(WRITESEQ1, RESET_VAL);
331         /* Wait for 10 micro seconds */
332         udelay(10);
333 }
334
335 int erase_flash(void)
336 {
337         write_flash(WRITESEQ1, WRITEDATA1);
338         write_flash(WRITESEQ2, WRITEDATA2);
339         write_flash(WRITESEQ3, WRITEDATA3);
340         write_flash(WRITESEQ4, WRITEDATA4);
341         write_flash(WRITESEQ5, WRITEDATA5);
342         write_flash(WRITESEQ6, WRITEDATA6);
343
344         if (poll_toggle_bit(0x0000) < 0)
345                 return FLASH_FAIL;
346
347         write_flash(SecFlashAOff + WRITESEQ1, WRITEDATA1);
348         write_flash(SecFlashAOff + WRITESEQ2, WRITEDATA2);
349         write_flash(SecFlashAOff + WRITESEQ3, WRITEDATA3);
350         write_flash(SecFlashAOff + WRITESEQ4, WRITEDATA4);
351         write_flash(SecFlashAOff + WRITESEQ5, WRITEDATA5);
352         write_flash(SecFlashAOff + WRITESEQ6, WRITEDATA6);
353
354         if (poll_toggle_bit(SecFlashASec1Off) < 0)
355                 return FLASH_FAIL;
356
357         write_flash(PriFlashBOff + WRITESEQ1, WRITEDATA1);
358         write_flash(PriFlashBOff + WRITESEQ2, WRITEDATA2);
359         write_flash(PriFlashBOff + WRITESEQ3, WRITEDATA3);
360         write_flash(PriFlashBOff + WRITESEQ4, WRITEDATA4);
361         write_flash(PriFlashBOff + WRITESEQ5, WRITEDATA5);
362         write_flash(PriFlashBOff + WRITESEQ6, WRITEDATA6);
363
364         if (poll_toggle_bit(PriFlashBOff) < 0)
365                 return FLASH_FAIL;
366
367         write_flash(SecFlashBOff + WRITESEQ1, WRITEDATA1);
368         write_flash(SecFlashBOff + WRITESEQ2, WRITEDATA2);
369         write_flash(SecFlashBOff + WRITESEQ3, WRITEDATA3);
370         write_flash(SecFlashBOff + WRITESEQ4, WRITEDATA4);
371         write_flash(SecFlashBOff + WRITESEQ5, WRITEDATA5);
372         write_flash(SecFlashBOff + WRITESEQ6, WRITEDATA6);
373
374         if (poll_toggle_bit(SecFlashBOff) < 0)
375                 return FLASH_FAIL;
376
377         return FLASH_SUCCESS;
378 }
379
380 int erase_block_flash(int nBlock, unsigned long address)
381 {
382         long ulSectorOff = 0x0;
383
384         if ((nBlock < 0) || (nBlock > AFP_NumSectors))
385                 return false;
386
387         ulSectorOff = (address - CONFIG_SYS_FLASH_BASE);
388
389         write_flash((WRITESEQ1 | ulSectorOff), WRITEDATA1);
390         write_flash((WRITESEQ2 | ulSectorOff), WRITEDATA2);
391         write_flash((WRITESEQ3 | ulSectorOff), WRITEDATA3);
392         write_flash((WRITESEQ4 | ulSectorOff), WRITEDATA4);
393         write_flash((WRITESEQ5 | ulSectorOff), WRITEDATA5);
394
395         write_flash(ulSectorOff, BlockEraseVal);
396
397         if (poll_toggle_bit(ulSectorOff) < 0)
398                 return FLASH_FAIL;
399
400         return FLASH_SUCCESS;
401 }
402
403 void unlock_flash(long ulOffset)
404 {
405         unsigned long ulOffsetAddr = ulOffset;
406         ulOffsetAddr &= 0xFFFF0000;
407
408         write_flash((WRITESEQ1 | ulOffsetAddr), UNLOCKDATA1);
409         write_flash((WRITESEQ2 | ulOffsetAddr), UNLOCKDATA2);
410         write_flash((WRITESEQ3 | ulOffsetAddr), UNLOCKDATA3);
411 }
412
413 int get_codes()
414 {
415         int dev_id = 0;
416
417         write_flash(WRITESEQ1, GETCODEDATA1);
418         write_flash(WRITESEQ2, GETCODEDATA2);
419         write_flash(WRITESEQ3, GETCODEDATA3);
420
421         read_flash(0x0002, &dev_id);
422         dev_id &= 0x00FF;
423
424         reset_flash();
425
426         return dev_id;
427 }
428
429 void get_sector_number(long ulOffset, int *pnSector)
430 {
431         int nSector = 0;
432
433         if (ulOffset >= SecFlashAOff) {
434                 if ((ulOffset < SecFlashASec1Off)
435                     && (ulOffset < SecFlashASec2Off)) {
436                         nSector = SECT32;
437                 } else if ((ulOffset >= SecFlashASec2Off)
438                            && (ulOffset < SecFlashASec3Off)) {
439                         nSector = SECT33;
440                 } else if ((ulOffset >= SecFlashASec3Off)
441                            && (ulOffset < SecFlashASec4Off)) {
442                         nSector = SECT34;
443                 } else if ((ulOffset >= SecFlashASec4Off)
444                            && (ulOffset < SecFlashAEndOff)) {
445                         nSector = SECT35;
446                 }
447         } else if (ulOffset >= SecFlashBOff) {
448                 if ((ulOffset < SecFlashBSec1Off)
449                     && (ulOffset < SecFlashBSec2Off)) {
450                         nSector = SECT36;
451                 }
452                 if ((ulOffset < SecFlashBSec2Off)
453                     && (ulOffset < SecFlashBSec3Off)) {
454                         nSector = SECT37;
455                 }
456                 if ((ulOffset < SecFlashBSec3Off)
457                     && (ulOffset < SecFlashBSec4Off)) {
458                         nSector = SECT38;
459                 }
460                 if ((ulOffset < SecFlashBSec4Off)
461                     && (ulOffset < SecFlashBEndOff)) {
462                         nSector = SECT39;
463                 }
464         } else if ((ulOffset >= PriFlashAOff) && (ulOffset < SecFlashAOff)) {
465                 nSector = ulOffset & 0xffff0000;
466                 nSector = ulOffset >> 16;
467                 nSector = nSector & 0x000ff;
468         }
469
470         if ((nSector >= 0) && (nSector < AFP_NumSectors)) {
471                 *pnSector = nSector;
472         }
473 }