2 #include <jffs2/jffs2.h>
3 #include <asm/addrspace.h>
5 #include "ar7240_soc.h"
6 #include "ar7240_flash.h"
8 #define SIZE_INBYTES_4MBYTES (4 * 1024 * 1024)
9 #define SIZE_INBYTES_8MBYTES (2 * SIZE_INBYTES_4MBYTES)
10 #define SIZE_INBYTES_16MBYTES (2 * SIZE_INBYTES_8MBYTES)
12 #define SIZE_INBYTES_4KBYTES (4 * 1024)
13 #define SIZE_INBYTES_64KBYTES (16 * SIZE_INBYTES_4KBYTES)
15 #ifndef DEFAULT_FLASH_SIZE_IN_MB
16 #error "DEFAULT_FLASH_SIZE_IN_MB not defined!"
19 extern void led_toggle(void);
20 extern void all_led_off(void);
21 extern int reset_button_status(void);
26 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
31 static void ar7240_spi_write_enable(void);
32 static void ar7240_spi_poll(void);
33 static void ar7240_spi_write_page(uint32_t addr, uint8_t * data, int len);
34 static void ar7240_spi_sector_erase(uint32_t addr);
37 * Returns JEDEC ID from SPI flash
39 static ulong read_id(void){
40 unsigned int flashid = 0;
42 ar7240_reg_wr_nf(AR7240_SPI_FS, 1);
43 ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);
45 ar7240_spi_bit_banger(0x9F);
52 flashid = ar7240_reg_rd(AR7240_SPI_RD_STATUS);
56 * - manufacture ID (1b)
59 flashid = flashid >> 8;
63 return((ulong)flashid);
66 static void flash_set_geom(int size, int sector_count, int sector_size){
68 flash_info_t *info = &flash_info[0];
71 info->sector_count = sector_count;
72 info->sector_size = sector_size;
74 for(i = 0; i < info->sector_count; i++){
75 info->start[i] = CFG_FLASH_BASE + (i * info->sector_size);
80 unsigned long flash_init(void){
82 #if defined(PLL_IN_FLASH_MAGIC_OFFSET)
83 u32 pll_magic, spi_control;
85 pll_magic = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET);
87 // read SPI CONTROL Configuration register (SPI_CONTROL) value stored in FLASH (PLL_IN_FLASH_MAGIC_OFFSET + 12)
88 spi_control = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 12);
91 info = &flash_info[0];
94 ar7240_reg_wr(AR7240_SPI_FS, 0x01);
96 // if reset button is pressed -> write default CLOCK_DIVIDER for SPI CLOCK
97 if(reset_button_status()){
98 ar7240_reg_wr(AR7240_SPI_CLOCK, AR7240_SPI_CONTROL_DEFAULT);
100 #if defined(PLL_IN_FLASH_MAGIC_OFFSET)
101 // do we have PLL_MAGIC in FLASH?
102 if(pll_magic == PLL_IN_FLASH_MAGIC){
103 ar7240_reg_wr(AR7240_SPI_CLOCK, spi_control);
106 ar7240_reg_wr(AR7240_SPI_CLOCK, AR7240_SPI_CONTROL);
107 #if defined(PLL_IN_FLASH_MAGIC_OFFSET)
112 ar7240_reg_wr(AR7240_SPI_FS, 0x0);
115 info->flash_id = read_id();
119 // fill flash info based on JEDEC ID
120 switch(info->flash_id){
124 case 0x010215: // tested
125 flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES);
126 puts("Spansion S25FL032P (4 MB)");
130 flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES);
131 puts("Atmel AT25DF321 (4 MB)");
134 case 0x1C3016: // tested
135 flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES);
136 puts("EON EN25Q32 (4 MB)");
139 case 0x1C3116: // tested
140 flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES);
141 puts("EON EN25F32 (4 MB)");
145 flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES);
146 puts("Micron M25P32 (4 MB)");
150 flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES);
151 puts("Winbond W25Q32 (4 MB)");
155 flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES);
156 puts("Macronix MX25L320 (4 MB)");
163 flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES);
164 puts("Spansion S25FL064P (8 MB)");
168 flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES);
169 puts("Atmel AT25DF641 (8 MB)");
172 case 0x1C3017: // tested
173 flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES);
174 puts("EON EN25Q64 (8 MB)");
178 flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES);
179 puts("Micron M25P64 (8 MB)");
182 case 0xEF4017: // tested
183 flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES);
184 puts("Winbond W25Q64 (8 MB)");
187 case 0xC22017: // tested
189 flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES);
190 puts("Macronix MX25L64 (8 MB)");
196 case 0xEF4018: // tested
197 flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES);
198 puts("Winbond W25Q128 (16 MB)");
203 flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES);
204 puts("Macronix MX25L128 (16 MB)");
208 flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES);
209 puts("Spansion S25FL127S (16 MB)");
213 flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES);
214 puts("Micron N25Q128 (16 MB)");
221 #if (DEFAULT_FLASH_SIZE_IN_MB == 4)
222 flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES);
223 puts("Unknown type (using only 4 MB)\n");
224 #elif (DEFAULT_FLASH_SIZE_IN_MB == 8)
225 flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES);
226 puts("Unknown type (using only 8 MB)\n");
227 #elif (DEFAULT_FLASH_SIZE_IN_MB == 16)
228 flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES);
229 puts("Unknown type (using only 16 MB)\n");
231 printf("\nPlease, send request to add support\nfor your FLASH - JEDEC ID: 0x%06lX\n", info->flash_id);
232 info->flash_id = FLASH_CUSTOM;
241 int flash_erase(flash_info_t *info, int s_first, int s_last){
242 int i, j, sector_size = info->size / info->sector_count;
248 for(i = s_first; i <= s_last; i++){
249 ar7240_spi_sector_erase(i * sector_size);
268 * Write a buffer from memory to flash:
269 * 0. Assumption: Caller has already erased the appropriate sectors.
270 * 1. call page programming for every 256 bytes
272 int write_buff(flash_info_t *info, uchar *source, ulong addr, ulong len){
273 int total = 0, len_this_lp, bytes_this_page;
277 printf("Writting at address: 0x%08lX\n", addr);
278 addr = addr - CFG_FLASH_BASE;
281 src = source + total;
283 bytes_this_page = AR7240_SPI_PAGE_SIZE - (addr % AR7240_SPI_PAGE_SIZE);
284 len_this_lp = ((len - total) > bytes_this_page) ? bytes_this_page : (len - total);
285 ar7240_spi_write_page(dst, src, len_this_lp);
286 total += len_this_lp;
295 static void ar7240_spi_write_enable(){
296 ar7240_reg_wr_nf(AR7240_SPI_FS, 1);
297 ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);
298 ar7240_spi_bit_banger(AR7240_SPI_CMD_WREN);
302 static void ar7240_spi_poll(){
306 ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);
307 ar7240_spi_bit_banger(AR7240_SPI_CMD_RD_STATUS);
308 ar7240_spi_delay_8();
309 rd = (ar7240_reg_rd(AR7240_SPI_RD_STATUS) & 1);
313 static void ar7240_spi_write_page(uint32_t addr, uint8_t *data, int len){
317 ar7240_spi_write_enable();
318 ar7240_spi_bit_banger(AR7240_SPI_CMD_PAGE_PROG);
319 ar7240_spi_send_addr(addr);
321 for(i = 0; i < len; i++){
323 ar7240_spi_bit_banger(ch);
330 static void ar7240_spi_sector_erase(uint32_t addr){
331 ar7240_spi_write_enable();
332 ar7240_spi_bit_banger(AR7240_SPI_CMD_SECTOR_ERASE);
333 ar7240_spi_send_addr(addr);