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

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

support for senao firmware format

Line 
1 /*
2  * ar5315.c - AR2315/AR2316/AR2317/AR2318 specific system functions
3  *
4  * copyright 2009 Sebastian Gottschall / NewMedia-NET GmbH / DD-WRT.COM
5  * licensed under GPL conditions
6  */
7 #include "mips32.c"
8 #include "spiflash.h"
9
10 /* definition of basic flash mappings */
11 static unsigned int sectorsize = 0x10000;
12 static unsigned int linuxaddr = 0xbfc10000;
13 static unsigned int flashbase = 0xa8000000;
14 static unsigned int flashsize = 0x800000;
15
16 #define AR2316_DSLBASE          0xB1000000      /* RESET CONTROL MMR */
17 #define AR531XPLUS_SPI              0xB1300000  /* SPI FLASH MMR */
18 #define AR2316_GPIO_DI          (AR2316_DSLBASE + 0x0088)
19 #define AR2316_RESET            (AR2316_DSLBASE + 0x0004)
20 #define AR2316_IF_CTL           (AR2316_DSLBASE + 0x0018)
21 #define AR2316_ENDIAN_CTL       (AR2316_DSLBASE + 0x000c)
22 #define AR2316_WDC              (AR2316_DSLBASE + 0x003c)
23 #define AR2316_AHB_ARB_CTL      (AR2316_DSLBASE + 0x0008)
24 #define RESET_WARM_WLAN0_MAC        0x00000001  /* warm reset WLAN0 MAC */
25 #define RESET_WARM_WLAN0_BB         0x00000002  /* warm reset WLAN0 BaseBand */
26 #define RESET_MPEGTS_RSVD           0x00000004  /* warm reset MPEG-TS */
27 #define RESET_PCIDMA                0x00000008  /* warm reset PCI ahb/dma */
28 #define RESET_MEMCTL                0x00000010  /* warm reset memory controller */
29 #define RESET_LOCAL                 0x00000020  /* warm reset local bus */
30 #define RESET_I2C_RSVD              0x00000040  /* warm reset I2C bus */
31 #define RESET_SPI                   0x00000080  /* warm reset SPI interface */
32 #define RESET_UART0                 0x00000100  /* warm reset UART0 */
33 #define RESET_IR_RSVD               0x00000200  /* warm reset IR interface */
34 #define RESET_EPHY0                 0x00000400  /* cold reset ENET0 phy */
35 #define RESET_ENET0                 0x00000800  /* cold reset ENET0 mac */
36
37 #define IF_TS_LOCAL                 2
38
39 #define CONFIG_ETHERNET             0x00000040  /* Ethernet byteswap */
40
41 #define ARB_CPU                     0x00000001  /* CPU, default */
42 #define ARB_WLAN                    0x00000002  /* WLAN */
43 #define ARB_MPEGTS_RSVD             0x00000004  /* MPEG-TS */
44 #define ARB_LOCAL                   0x00000008  /* LOCAL */
45 #define ARB_PCI                     0x00000010  /* PCI */
46 #define ARB_ETHERNET                0x00000020  /* Ethernet */
47 #define ARB_RETRY                   0x00000100  /* retry policy, debug only */
48
49 #define disable_watchdog() \
50 {                                       \
51 }                                       \
52
53 static int getGPIO(int nr)
54 {
55         volatile unsigned int *gpio = (unsigned int *)AR2316_GPIO_DI;
56         if ((*gpio & 1 << nr) == (1 << nr))
57                 return 1;
58         return 0;
59 }
60
61 static void enable_ethernet(void)
62 {
63         unsigned int mask = RESET_ENET0 | RESET_EPHY0;
64         unsigned int regtmp;
65         regtmp = sysRegRead(AR2316_AHB_ARB_CTL);
66         regtmp |= ARB_ETHERNET;
67         sysRegWrite(AR2316_AHB_ARB_CTL, regtmp);
68
69         regtmp = sysRegRead(AR2316_RESET);
70         sysRegWrite(AR2316_RESET, regtmp | mask);
71         udelay(10000);
72
73         regtmp = sysRegRead(AR2316_RESET);
74         sysRegWrite(AR2316_RESET, regtmp & ~mask);
75         udelay(10000);
76
77         regtmp = sysRegRead(AR2316_IF_CTL);
78         regtmp |= IF_TS_LOCAL;
79         sysRegWrite(AR2316_IF_CTL, regtmp);
80
81         regtmp = sysRegRead(AR2316_ENDIAN_CTL);
82         regtmp &= ~CONFIG_ETHERNET;
83         sysRegWrite(AR2316_ENDIAN_CTL, regtmp);
84 }
85
86 #define FLASH_1MB  1
87 #define FLASH_2MB  2
88 #define FLASH_4MB  3
89 #define FLASH_8MB  4
90 #define FLASH_16MB 5
91 #define MAX_FLASH  6
92
93 #define STM_PAGE_SIZE           256
94
95 #define SFI_WRITE_BUFFER_SIZE   4
96 #define SFI_FLASH_ADDR_MASK     0x00ffffff
97
98 #define STM_8MBIT_SIGNATURE     0x13
99 #define STM_M25P80_BYTE_COUNT   1048576
100 #define STM_M25P80_SECTOR_COUNT 16
101 #define STM_M25P80_SECTOR_SIZE  0x10000
102
103 #define STM_16MBIT_SIGNATURE    0x14
104 #define STM_M25P16_BYTE_COUNT   2097152
105 #define STM_M25P16_SECTOR_COUNT 32
106 #define STM_M25P16_SECTOR_SIZE  0x10000
107
108 #define STM_32MBIT_SIGNATURE    0x15
109 #define STM_M25P32_BYTE_COUNT   4194304
110 #define STM_M25P32_SECTOR_COUNT 64
111 #define STM_M25P32_SECTOR_SIZE  0x10000
112
113 #define STM_64MBIT_SIGNATURE    0x16
114 #define STM_M25P64_BYTE_COUNT   8388608
115 #define STM_M25P64_SECTOR_COUNT 128
116 #define STM_M25P64_SECTOR_SIZE  0x10000
117
118 #define STM_128MBIT_SIGNATURE   0x17
119 #define STM_M25P128_BYTE_COUNT   16777216
120 #define STM_M25P128_SECTOR_COUNT 256
121 #define STM_M25P128_SECTOR_SIZE  0x10000
122
123 #define STM_1MB_BYTE_COUNT   STM_M25P80_BYTE_COUNT
124 #define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT
125 #define STM_1MB_SECTOR_SIZE  STM_M25P80_SECTOR_SIZE
126 #define STM_2MB_BYTE_COUNT   STM_M25P16_BYTE_COUNT
127 #define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT
128 #define STM_2MB_SECTOR_SIZE  STM_M25P16_SECTOR_SIZE
129 #define STM_4MB_BYTE_COUNT   STM_M25P32_BYTE_COUNT
130 #define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT
131 #define STM_4MB_SECTOR_SIZE  STM_M25P32_SECTOR_SIZE
132 #define STM_8MB_BYTE_COUNT   STM_M25P64_BYTE_COUNT
133 #define STM_8MB_SECTOR_COUNT STM_M25P64_SECTOR_COUNT
134 #define STM_8MB_SECTOR_SIZE  STM_M25P64_SECTOR_SIZE
135 #define STM_16MB_BYTE_COUNT   STM_M25P128_BYTE_COUNT
136 #define STM_16MB_SECTOR_COUNT STM_M25P128_SECTOR_COUNT
137 #define STM_16MB_SECTOR_SIZE  STM_M25P128_SECTOR_SIZE
138
139 #define SPI_FLASH_MMR           AR531XPLUS_SPI_MMR
140
141 #define SPI_WRITE_ENABLE    0
142 #define SPI_WRITE_DISABLE   1
143 #define SPI_RD_STATUS       2
144 #define SPI_WR_STATUS       3
145 #define SPI_RD_DATA         4
146 #define SPI_FAST_RD_DATA    5
147 #define SPI_PAGE_PROGRAM    6
148 #define SPI_SECTOR_ERASE    7
149 #define SPI_BULK_ERASE      8
150 #define SPI_DEEP_PWRDOWN    9
151 #define SPI_RD_SIG          10
152 #define SPI_MAX_OPCODES     11
153
154 struct flashconfig {
155         __u32 byte_cnt;
156         __u32 sector_cnt;
157         __u32 sector_size;
158         __u32 cs_addrmask;
159 } static flashconfig_tbl[MAX_FLASH] = {
160         {0, 0, 0, 0},           //
161         {STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE, 0x0},   //
162         {STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE, 0x0},   //
163         {STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE, 0x0},   //
164         {STM_8MB_BYTE_COUNT, STM_8MB_SECTOR_COUNT, STM_8MB_SECTOR_SIZE, 0x0},   //
165         {STM_16MB_BYTE_COUNT, STM_16MB_SECTOR_COUNT, STM_16MB_SECTOR_SIZE, 0x0} //
166 };
167
168 struct opcodes {
169         __u16 code;
170         __s8 tx_cnt;
171         __s8 rx_cnt;
172 } static stm_opcodes[] = {
173         {STM_OP_WR_ENABLE, 1, 0},       //
174         {STM_OP_WR_DISABLE, 1, 0},      //
175         {STM_OP_RD_STATUS, 1, 1},       //
176         {STM_OP_WR_STATUS, 1, 0},       //
177         {STM_OP_RD_DATA, 4, 4}, //
178         {STM_OP_FAST_RD_DATA, 5, 0},    //
179         {STM_OP_PAGE_PGRM, 8, 0},       //
180         {STM_OP_SECTOR_ERASE, 4, 0},    //
181         {STM_OP_BULK_ERASE, 1, 0},      //
182         {STM_OP_DEEP_PWRDOWN, 1, 0},    //
183         {STM_OP_RD_SIG, 4, 1},  //
184 };
185
186 static __u32 spiflash_regread32(int reg)
187 {
188         volatile __u32 *data = (__u32 *)(AR531XPLUS_SPI + reg);
189
190         return (*data);
191 }
192
193 static void spiflash_regwrite32(int reg, __u32 data)
194 {
195         volatile __u32 *addr = (__u32 *)(AR531XPLUS_SPI + reg);
196
197         *addr = data;
198         return;
199 }
200
201 #define busy_wait(condition, wait) \
202         do { \
203                 while (condition) { \
204                         if (!wait) \
205                             udelay(1); \
206                         else \
207                             udelay(wait*1000); \
208                 } \
209         } while (0)
210
211 static __u32 spiflash_sendcmd(int op, u32 addr)
212 {
213         u32 reg;
214         u32 mask;
215         struct opcodes *ptr_opcode;
216
217         ptr_opcode = &stm_opcodes[op];
218         busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0);
219
220         spiflash_regwrite32(SPI_FLASH_OPCODE,
221                             ((u32)ptr_opcode->code) | (addr << 8));
222
223         reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt |
224             (ptr_opcode->rx_cnt << 4) | SPI_CTL_START;
225
226         spiflash_regwrite32(SPI_FLASH_CTL, reg);
227
228         busy_wait(spiflash_regread32(SPI_FLASH_CTL) & SPI_CTL_BUSY, 0);
229
230         if (!ptr_opcode->rx_cnt)
231                 return 0;
232
233         reg = (__u32)spiflash_regread32(SPI_FLASH_DATA);
234
235         switch (ptr_opcode->rx_cnt) {
236         case 1:
237                 mask = 0x000000ff;
238                 break;
239         case 2:
240                 mask = 0x0000ffff;
241                 break;
242         case 3:
243                 mask = 0x00ffffff;
244                 break;
245         default:
246                 mask = 0xffffffff;
247                 break;
248         }
249         reg &= mask;
250
251         return reg;
252 }
253
254 static int spiflash_probe_chip(void)
255 {
256         unsigned int sig;
257         int flash_size;
258
259         sig = spiflash_sendcmd(SPI_RD_SIG, 0);
260
261         switch (sig) {
262         case STM_8MBIT_SIGNATURE:
263                 flash_size = FLASH_1MB;
264                 break;
265         case STM_16MBIT_SIGNATURE:
266                 flash_size = FLASH_2MB;
267                 break;
268         case STM_32MBIT_SIGNATURE:
269                 flash_size = FLASH_4MB;
270                 break;
271         case STM_64MBIT_SIGNATURE:
272                 flash_size = FLASH_8MB;
273                 break;
274         case STM_128MBIT_SIGNATURE:
275                 flash_size = FLASH_16MB;
276                 break;
277         default:
278                 puts("Read of flash device signature failed!\n");
279                 return (0);
280         }
281
282         return (flash_size);
283 }
284
285 static unsigned int getPartition(char *name);
286
287 /* erases nvram partition on the detected location or simply returns if no nvram was detected */
288
289 static int flash_erase_nvram(unsigned int flashsize, unsigned int blocksize)
290 {
291         unsigned int res;
292         unsigned int offset = nvramdetect;
293         struct opcodes *ptr_opcode;
294         __u32 temp, reg;
295         if (!nvramdetect) {
296                 nvramdetect = getPartition("cfg");
297         }
298         if (!nvramdetect) {
299                 puts("nvram can and will not erased, since nvram was not detected on this device (maybe dd-wrt isnt installed)!\n");
300                 return -1;
301         }
302         printf("erasing nvram at [0x%08X]\n", nvramdetect);
303
304         ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE];
305
306         temp = ((__u32)offset << 8) | (__u32)(ptr_opcode->code);
307         spiflash_sendcmd(SPI_WRITE_ENABLE, 0);
308         busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0);
309
310         spiflash_regwrite32(SPI_FLASH_OPCODE, temp);
311
312         reg =
313             (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt |
314             SPI_CTL_START;
315         spiflash_regwrite32(SPI_FLASH_CTL, reg);
316
317         busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20);
318
319         puts("done\n");
320         return 0;
321 }
322
323 static int flashdetected = 0;
324 /* detects spi flash and its size */
325 static int flashdetect(void)
326 {
327         if (flashdetected)
328                 return 0;
329         flashsize = 8 * 1024 * 1024;
330         flashbase = 0xa8000000;
331         int index = 0;
332         if (!(index = spiflash_probe_chip())) {
333                 puts("Found no serial flash device, cannot reset to factory defaults\n");
334                 return -1;
335         } else {
336                 flashsize = flashconfig_tbl[index].byte_cnt;
337                 sectorsize = flashconfig_tbl[index].sector_size;
338                 if (flashsize == 8 * 1024 * 1024)
339                         flashbase = 0xa8000000;
340                 else
341                         flashbase = 0xbfc00000;
342                 printf
343                     ("Found Flash device SIZE=0x%08X SECTORSIZE=0x%08X FLASHBASE=0x%08X\n",
344                      flashsize, sectorsize, flashbase);
345         }
346         flashdetected = 1;
347         return 0;
348
349 }
Note: See TracBrowser for help on using the browser.