root/ar5315_microredboot/microredboot/boot/src/arch/ar5312.c

Revision 12370, 9.6 kB (checked in by BrainSlayer, 5 months ago)

support for senao firmware format

Line 
1 /*
2  * ar5312.c - AR5312/AR2313 specific system functions
3  *
4  * copyright 2009 Sebastian Gottschall / NewMedia-NET GmbH / DD-WRT.COM
5  * licensed under GPL conditions
6  */
7
8 #include "mips32.c"
9
10 static unsigned int sectorsize = 0x10000;
11 static unsigned int linuxaddr = 0xbe010000;
12 static unsigned int flashbase = 0xbe000000;
13 static unsigned int flashsize = 0x800000;
14
15 #define AR531X_APBBASE  0xbc000000
16 #define AR531X_GPIO     (AR531X_APBBASE + 0x2000)
17 #define AR531X_GPIO_DI      (AR531X_GPIO + 0x04)
18 #define AR531X_RESETTMR (AR531X_APBBASE + 0x3000)
19 #define AR531X_WDC      (AR531X_RESETTMR + 0x0008)
20 #define AR531X_RESET    (AR531X_RESETTMR + 0x0020)
21 #define AR531X_ENABLE   (AR531X_RESETTMR + 0x0080)
22 #define ENABLE_ENET0              0x0002
23
24 #define RESET_ENET0          0x00000020 /* cold reset ENET0 mac */
25 #define RESET_EPHY0          0x00000008 /* cold reset ENET0 phy */
26
27 #define disable_watchdog() \
28 {                                       \
29         sysRegWrite(AR531X_WDC, 0);     \
30 }                                       \
31
32 static int getGPIO(int nr)
33 {
34         volatile unsigned int *gpio = (unsigned int *)AR531X_GPIO_DI;
35         if ((*gpio & 1 << nr) == (1 << nr))
36                 return 1;
37         return 0;
38 }
39
40 static void enable_ethernet(void)
41 {
42         unsigned int mask = RESET_ENET0 | RESET_EPHY0;
43         unsigned int regtmp;
44
45         regtmp = sysRegRead(AR531X_RESET);
46         sysRegWrite(AR531X_RESET, regtmp | mask);
47         udelay(15000);
48
49         /* Pull out of reset */
50         regtmp = sysRegRead(AR531X_RESET);
51         sysRegWrite(AR531X_RESET, regtmp & ~mask);
52         udelay(25);
53         mask = ENABLE_ENET0;
54         regtmp = sysRegRead(AR531X_ENABLE);
55         sysRegWrite(AR531X_ENABLE, regtmp | mask);
56 }
57
58 typedef unsigned char FLASH_DATA_T;
59 #define FLASH_P2V( _a_ ) ((volatile FLASH_DATA_T *)((unsigned int)((_a_))))
60 #define FLASH_BLANKVALUE                (FLASH_DATA_T)(0xff)
61 #define FLASHWORD(x)                    ((FLASH_DATA_T)(x))
62 #define FLASH_POLLING_TIMEOUT   (3000000)
63 #define FLASH_READ_ID                   FLASHWORD( 0x90 )
64 #define FLASH_WP_STATE                  FLASHWORD( 0x90 )
65 #define FLASH_RESET                     FLASHWORD( 0xF0 )
66 #define FLASH_PROGRAM                   FLASHWORD( 0xA0 )
67 #define FLASH_BLOCK_ERASE               FLASHWORD( 0x30 )
68 #define FLASH_Query                                             FLASHWORD( 0x98 )       // Add by Jason for CFI support
69
70 #define FLASH_DATA                      FLASHWORD( 0x80 )       // Data complement
71 #define FLASH_BUSY                      FLASHWORD( 0x40 )       // "Toggle" bit
72 #define FLASH_ERR                       FLASHWORD( 0x20 )
73 #define FLASH_SECTOR_ERASE_TIMER        FLASHWORD( 0x08 )
74
75 #define FLASH_UNLOCKED                  FLASHWORD( 0x00 )
76 #define FLASH_WP_ADDR                   (4)
77
78 #define FLASH_SETUP_ADDR1               (0xAAA)
79 #define FLASH_SETUP_ADDR2               (0x555)
80 #define FLASH_VENDORID_ADDR             (0x0)
81 #define FLASH_DEVICEID_ADDR             (0x2)
82 #define FLASH_DEVICEID_ADDR2            (0x1c)
83 #define FLASH_DEVICEID_ADDR3            (0x1e)
84 //#define FLASH_WP_ADDR                         (0x12)
85 #define FLASH_SETUP_CODE1               FLASHWORD( 0xAA )
86 #define FLASH_SETUP_CODE2               FLASHWORD( 0x55 )
87 #define FLASH_SETUP_ERASE               FLASHWORD( 0x80 )
88 #define FLASH_ERR_OK                    0x0
89 #define FLASH_ERR_DRV_TIMEOUT           -1
90
91 typedef struct {
92         unsigned char devid;
93         unsigned char *name;
94         unsigned char size;     //in megabyte
95         unsigned char blocksize;        //in kb
96 } FLASHDEV;
97 static const FLASHDEV flashdevs[] = {
98         {.devid = 0xc9,.name = "MX29LV640",.size = 8,.blocksize = 64},
99         {.devid = 0xa7,.name = "MX29LV320C",.size = 4,.blocksize = 64},
100         {.devid = 0xa8,.name = "MX29LV320B",.size = 4,.blocksize = 64},
101         {.devid = 0xc4,.name = "MX29LV160CT",.size = 2,.blocksize = 64},
102         {.devid = 0x49,.name = "MX29LV160CB",.size = 2,.blocksize = 64},
103         {.devid = 0xed,.name = "STM29W640",.size = 8,.blocksize = 64},
104         {.devid = 0xf6,.name = "EN29LV320",.size = 4,.blocksize = 64},
105         {.devid = 0xc4,.name = "EN29LV160",.size = 2,.blocksize = 64},
106         {.devid = 0xa0,.name = "K8D3216UT",.size = 4,.blocksize = 64},
107         {.devid = 0xa1,.name = "K8D3316UT",.size = 4,.blocksize = 64},
108         {.devid = 0xa2,.name = "K8D3216UB",.size = 4,.blocksize = 64},
109         {.devid = 0xa3,.name = "K8D3316UB",.size = 4,.blocksize = 64},
110         {.devid = 0x5b,.name = "SST39VF3201",.size = 4,.blocksize = 64},
111         {.devid = 0x5a,.name = "SST39VF3202",.size = 4,.blocksize = 4},
112         {.devid = 0xf9,.name = "S29AL032D",.size = 4,.blocksize = 64},
113 };
114
115 static int flashdetected = 0;
116
117 /* detects nor flash and size by ID, if no known flash was detected, the default mapping and size will be used */
118 static int flashdetect(void)
119 {
120         if (flashdetected)
121                 return 0;
122         flashdetected = 1;
123         volatile FLASH_DATA_T *ROM;
124         volatile FLASH_DATA_T *f_s1, *f_s2;
125         FLASH_DATA_T id[4];
126         FLASH_DATA_T w;
127         long timeout = 50000;
128
129         ROM = (volatile FLASH_DATA_T *)((unsigned int)0xbe000000);
130         *(FLASH_P2V(ROM)) = FLASH_RESET;
131
132         f_s1 = FLASH_P2V(ROM + FLASH_SETUP_ADDR1);
133         f_s2 = FLASH_P2V(ROM + FLASH_SETUP_ADDR2);
134
135         *f_s1 = FLASH_RESET;
136         w = *(FLASH_P2V(ROM));
137
138         *f_s1 = FLASH_SETUP_CODE1;
139         *f_s2 = FLASH_SETUP_CODE2;
140         *f_s1 = FLASH_READ_ID;
141
142         id[0] = -1;
143         id[1] = -1;
144
145         // Manufacturers' code
146         id[0] = *(FLASH_P2V(ROM + FLASH_VENDORID_ADDR));
147         // Part number
148         id[1] = *(FLASH_P2V(ROM + FLASH_DEVICEID_ADDR));
149         id[2] = *(FLASH_P2V(ROM + FLASH_DEVICEID_ADDR2));
150         id[3] = *(FLASH_P2V(ROM + FLASH_DEVICEID_ADDR3));
151
152         *(FLASH_P2V(ROM)) = FLASH_RESET;
153
154         // Stall, waiting for flash to return to read mode.
155         int i;
156         int found = 0;
157         for (i = 0; i < sizeof(flashdevs) / sizeof(FLASHDEV); i++) {
158                 if (flashdevs[i].devid == id[1]) {
159                         printf("FLASH: %s with %dM detected\n",
160                                flashdevs[i].name, flashdevs[i].size);
161                         flashsize = flashdevs[i].size * 1024 * 1024;
162                         sectorsize = flashdevs[i].blocksize * 1024;
163                         found = 1;
164                         break;
165                 }
166         }
167         if (!found)
168                 printf
169                     ("Device not known: FLASH MANID: %X DEVID: %X DEVID2: %X DEVID3: %X\n",
170                      id[0], id[1], id[2], id[3]);
171         while ((--timeout != 0) && (w != *(FLASH_P2V(ROM)))) ;
172         return 0;
173 }
174
175 #define AR531X_FLASHCTL 0xb8400000
176 #define AR531X_FLASHCTL0        (AR531X_FLASHCTL + 0x00)
177 #define AR531X_FLASHCTL1        (AR531X_FLASHCTL + 0x04)
178 #define AR531X_FLASHCTL2        (AR531X_FLASHCTL + 0x08)
179 #define FLASHCTL_IDCY   0x0000000f      /* Idle cycle turn around time */
180 #define FLASHCTL_IDCY_S 0
181 #define FLASHCTL_WST1   0x000003e0      /* Wait state 1 */
182 #define FLASHCTL_WST1_S 5
183 #define FLASHCTL_RBLE   0x00000400      /* Read byte lane enable */
184 #define FLASHCTL_WST2   0x0000f800      /* Wait state 2 */
185 #define FLASHCTL_WST2_S 11
186 #define FLASHCTL_AC     0x00070000      /* Flash address check (added) */
187 #define FLASHCTL_AC_S   16
188 #define FLASHCTL_AC_128K 0x00000000
189 #define FLASHCTL_AC_256K 0x00010000
190 #define FLASHCTL_AC_512K 0x00020000
191 #define FLASHCTL_AC_1M   0x00030000
192 #define FLASHCTL_AC_2M   0x00040000
193 #define FLASHCTL_AC_4M   0x00050000
194 #define FLASHCTL_AC_8M   0x00060000
195 #define FLASHCTL_AC_RES  0x00070000     /* 16MB is not supported */
196 #define FLASHCTL_E      0x00080000      /* Flash bank enable (added) */
197 #define FLASHCTL_BUSERR 0x01000000      /* Bus transfer error status flag */
198 #define FLASHCTL_WPERR  0x02000000      /* Write protect error status flag */
199 #define FLASHCTL_WP     0x04000000      /* Write protect */
200 #define FLASHCTL_BM     0x08000000      /* Burst mode */
201 #define FLASHCTL_MW     0x30000000      /* Memory width */
202 #define FLASHCTL_MWx8   0x00000000      /* Memory width x8 */
203 #define FLASHCTL_MWx16  0x10000000      /* Memory width x16 */
204 #define FLASHCTL_MWx32  0x20000000      /* Memory width x32 (not supported) */
205 #define FLASHCTL_ATNR   0x00000000      /* Access type == no retry */
206 #define FLASHCTL_ATR    0x80000000      /* Access type == retry every */
207 #define FLASHCTL_ATR4   0xc0000000      /* Access type == retry every 4 */
208
209 /* erases nvram partition on the detected location or simply returns if no nvram was detected */
210 static unsigned int getPartition(char *name);
211
212 static int flash_erase_nvram(unsigned int flashsize, unsigned int blocksize)
213 {
214         int i, ticks;
215         unsigned short val;
216         if (!nvramdetect) {
217                 nvramdetect = getPartition("cfg");
218         }
219         if (!nvramdetect) {
220                 puts("nvram can and will not erased, since nvram was not detected on this device (maybe dd-wrt isnt installed)!\n");
221                 return;
222         }
223         printf("erasing nvram at [0x%08X]\n", nvramdetect);
224
225         volatile FLASH_DATA_T *ROM, *BANK;
226         volatile FLASH_DATA_T *b_p = (FLASH_DATA_T *) (nvramdetect);
227         volatile FLASH_DATA_T *b_v;
228         volatile FLASH_DATA_T *f_s0, *f_s1, *f_s2;
229         int timeout = 50000;
230         FLASH_DATA_T state;
231         BANK = ROM =
232             (volatile FLASH_DATA_T *)((unsigned long)nvramdetect &
233                                       ~(0x800000 - 1));
234         f_s0 = FLASH_P2V(BANK);
235         f_s1 = FLASH_P2V(BANK + FLASH_SETUP_ADDR1);
236         f_s2 = FLASH_P2V(BANK + FLASH_SETUP_ADDR2);
237
238         for (i = 0; i < blocksize / sectorsize; i++) {
239                 int res = FLASH_ERR_OK;
240
241                 *f_s1 = FLASH_SETUP_CODE1;
242                 *f_s2 = FLASH_SETUP_CODE2;
243                 *f_s1 = FLASH_WP_STATE;
244                 state = *FLASH_P2V(b_p + FLASH_WP_ADDR);
245                 *f_s0 = FLASH_RESET;
246
247                 if (FLASH_UNLOCKED != state) {
248                         *FLASH_P2V(ROM) = FLASH_RESET;
249                 }
250
251                 b_v = FLASH_P2V(b_p);
252
253                 *f_s1 = FLASH_SETUP_CODE1;
254                 *f_s2 = FLASH_SETUP_CODE2;
255                 *f_s1 = FLASH_SETUP_ERASE;
256                 *f_s1 = FLASH_SETUP_CODE1;
257                 *f_s2 = FLASH_SETUP_CODE2;
258                 *b_v = FLASH_BLOCK_ERASE;
259                 timeout = FLASH_POLLING_TIMEOUT;
260                 while (1) {
261                         state = *b_v;
262                         if ((state & FLASH_SECTOR_ERASE_TIMER)
263                             == FLASH_SECTOR_ERASE_TIMER)
264                                 break;
265                         udelay(1);
266                         if (--timeout == 0) {
267                                 puts("flash erase timeout\n");
268                                 res = FLASH_ERR_DRV_TIMEOUT;
269                                 break;
270                         }
271                 }
272                 if (FLASH_ERR_OK == res) {
273                         timeout = FLASH_POLLING_TIMEOUT;
274                         while (1) {
275                                 state = *b_v;
276                                 if (FLASH_BLANKVALUE == state) {
277                                         break;
278                                 }
279                                 udelay(1);
280                                 if (--timeout == 0) {
281                                         puts("flash erase timeout while waiting for erase complete\n");
282                                         res = FLASH_ERR_DRV_TIMEOUT;
283                                         break;
284                                 }
285                         }
286                 }
287
288                 if (FLASH_ERR_OK != res)
289                         *FLASH_P2V(ROM) = FLASH_RESET;
290
291                 b_v = FLASH_P2V(b_p++);
292                 if (*b_v != FLASH_BLANKVALUE) {
293                         if (FLASH_ERR_OK == res) {
294                                 puts("erase verify failed\n");
295                                 return 0;
296                         } else {
297                                 printf("[0x%08X] erased\n", b_p);
298                         }
299                 }
300                 b_p += sectorsize;
301         }
302         return 0;
303
304 }
Note: See TracBrowser for help on using the browser.