source: ar5315_microredboot/microredboot/boot/src/arch/ar2315.c @ 12336

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

fix compiling bugs and increase version number

File size: 9.5 KB
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 */
11static unsigned int sectorsize = 0x10000;
12static unsigned int linuxaddr = 0xbfc10000;
13static unsigned int flashbase = 0xa8000000;
14static 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
53static 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
61static 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
154struct 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
168struct 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
186static __u32 spiflash_regread32(int reg)
187{
188        volatile __u32 *data = (__u32 *)(AR531XPLUS_SPI + reg);
189
190        return (*data);
191}
192
193static 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
211static __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
254static 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
285static int flash_erase_nvram(unsigned int flashsize, unsigned int blocksize)
286{
287        unsigned int res;
288        unsigned int offset = nvramdetect;
289        struct opcodes *ptr_opcode;
290        __u32 temp, reg;
291        if (!nvramdetect) {
292                puts("nvram can and will not erased, since nvram was not detected on this device (maybe dd-wrt isnt installed)!\n");
293                return;
294        }
295        printf("erasing nvram at [0x%08X]\n", nvramdetect);
296
297        ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE];
298
299        temp = ((__u32)offset << 8) | (__u32)(ptr_opcode->code);
300        spiflash_sendcmd(SPI_WRITE_ENABLE, 0);
301        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0);
302
303        spiflash_regwrite32(SPI_FLASH_OPCODE, temp);
304
305        reg =
306            (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt |
307            SPI_CTL_START;
308        spiflash_regwrite32(SPI_FLASH_CTL, reg);
309
310        busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20);
311
312        puts("done\n");
313        return 0;
314}
315
316static int flashdetected = 0;
317static int flashdetect(void)
318{
319        if (flashdetected)
320                return 0;
321        flashsize = 8 * 1024 * 1024;
322        flashbase = 0xa8000000;
323        int index = 0;
324        if (!(index = spiflash_probe_chip())) {
325                puts("Found no serial flash device, cannot reset to factory defaults\n");
326                return -1;
327        } else {
328                flashsize = flashconfig_tbl[index].byte_cnt;
329                sectorsize = flashconfig_tbl[index].sector_size;
330                if (flashsize == 8 * 1024 * 1024)
331                        flashbase = 0xa8000000;
332                else
333                        flashbase = 0xbfc00000;
334                printf
335                    ("Found Flash device SIZE=0x%08X SECTORSIZE=0x%08X FLASHBASE=0x%08X\n",
336                     flashsize, sectorsize, flashbase);
337        }
338        flashdetected = 1;
339        return 0;
340
341}
Note: See TracBrowser for help on using the repository browser.