source: ar5315_microredboot/microredboot/boot/src/arch/ar5312.c @ 12328

Last change on this file since 12328 was 12328, checked in by BrainSlayer, 4 years ago

restructure source to be better readable

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