]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/altera/common/flash.c
ARM: highbank: use default prompt
[karo-tx-uboot.git] / board / altera / common / flash.c
1 /*
2  * (C) Copyright 2000-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8
9 #include <common.h>
10 #include <nios.h>
11
12 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
13
14 /*--------------------------------------------------------------------*/
15 void flash_print_info (flash_info_t * info)
16 {
17         int i, k;
18         unsigned long size;
19         int erased;
20         volatile unsigned char *flash;
21
22         printf ("  Size: %ld KB in %d Sectors\n",
23                 info->size >> 10, info->sector_count);
24         printf ("  Sector Start Addresses:");
25         for (i = 0; i < info->sector_count; ++i) {
26
27                 /* Check if whole sector is erased */
28                 if (i != (info->sector_count - 1))
29                         size = info->start[i + 1] - info->start[i];
30                 else
31                         size = info->start[0] + info->size - info->start[i];
32                 erased = 1;
33                 flash = (volatile unsigned char *) info->start[i];
34                 for (k = 0; k < size; k++) {
35                         if (*flash++ != 0xff) {
36                                 erased = 0;
37                                 break;
38                         }
39                 }
40
41                 /* Print the info */
42                 if ((i % 5) == 0)
43                         printf ("\n   ");
44                 printf (" %08lX%s%s", info->start[i], erased ? " E" : "  ",
45                         info->protect[i] ? "RO " : "   ");
46         }
47         printf ("\n");
48 }
49
50 /*-------------------------------------------------------------------*/
51
52
53 int flash_erase (flash_info_t * info, int s_first, int s_last)
54 {
55         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
56         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
57         int prot, sect;
58         unsigned oldpri;
59         ulong start;
60
61         /* Some sanity checking */
62         if ((s_first < 0) || (s_first > s_last)) {
63                 printf ("- no sectors to erase\n");
64                 return 1;
65         }
66
67         prot = 0;
68         for (sect = s_first; sect <= s_last; ++sect) {
69                 if (info->protect[sect]) {
70                         prot++;
71                 }
72         }
73         if (prot) {
74                 printf ("- Warning: %d protected sectors will not be erased!\n",
75                         prot);
76         } else {
77                 printf ("\n");
78         }
79
80 #ifdef DEBUG
81         for (sect = s_first; sect <= s_last; sect++) {
82                 printf("- Erase: Sect: %i @ 0x%08x\n", sect,  info->start[sect]);
83         }
84 #endif
85
86         /* NOTE: disabling interrupts on Nios can be very bad since it
87          * also disables the LO_LIMIT exception. It's better here to
88          * set the interrupt priority to 3 & restore it when we're done.
89          */
90         oldpri = ipri (3);
91
92         /* It's ok to erase multiple sectors provided we don't delay more
93          * than 50 usec between cmds ... at which point the erase time-out
94          * occurs. So don't go and put printf() calls in the loop ... it
95          * won't be very helpful ;-)
96          */
97         for (sect = s_first; sect <= s_last; sect++) {
98                 if (info->protect[sect] == 0) { /* not protected */
99                         addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
100                         *addr = 0xaa;
101                         *addr = 0x55;
102                         *addr = 0x80;
103                         *addr = 0xaa;
104                         *addr = 0x55;
105                         *addr2 = 0x30;
106                         /* Now just wait for 0xff & provide some user
107                          * feedback while we wait. Here we have to grant
108                          * timer interrupts. Otherwise get_timer() can't
109                          * work right. */
110                         ipri(oldpri);
111                         start = get_timer (0);
112                         while (*addr2 != 0xff) {
113                                 udelay (1000 * 1000);
114                                 putc ('.');
115                                 if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
116                                         printf ("timeout\n");
117                                         return 1;
118                                 }
119                         }
120                         oldpri = ipri (3); /* disallow non important irqs again */
121                 }
122         }
123
124         printf ("\n");
125
126         /* Restore interrupt priority */
127         ipri (oldpri);
128
129         return 0;
130 }
131
132 /*-----------------------------------------------------------------------
133  * Copy memory to flash, returns:
134  * 0 - OK
135  * 1 - write timeout
136  * 2 - Flash not erased
137  */
138
139 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
140 {
141
142         vu_char *cmd = (vu_char *) info->start[0];
143         vu_char *dst = (vu_char *) addr;
144         unsigned char b;
145         unsigned oldpri;
146         ulong start;
147
148         while (cnt) {
149                 /* Check for sufficient erase */
150                 b = *src;
151                 if ((*dst & b) != b) {
152                         printf ("%02x : %02x\n", *dst, b);
153                         return (2);
154                 }
155
156                 /* Disable interrupts other than window underflow
157                  * (interrupt priority 2)
158                  */
159                 oldpri = ipri (3);
160                 *cmd = 0xaa;
161                 *cmd = 0x55;
162                 *cmd = 0xa0;
163                 *dst = b;
164
165                 /* Verify write */
166                 start = get_timer (0);
167                 while (*dst != b) {
168                         if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
169                                 ipri (oldpri);
170                                 return 1;
171                         }
172                 }
173                 dst++;
174                 src++;
175                 cnt--;
176                 ipri (oldpri);
177         }
178
179         return (0);
180 }