source: src/linux/universal/linux-3.5/drivers/mtd/devices/wzrag300nh_flash.c @ 31660

Last change on this file since 31660 was 31660, checked in by brainslayer, 7 weeks ago

use new squashfs in all kernels

File size: 25.0 KB
Line 
1/*
2 * This file contains glue for Atheros ar7100 spi flash interface
3 * Primitives are ar7100_spi_*
4 * mtd flash implements are ar7100_flash_*
5 */
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/types.h>
9#include <linux/errno.h>
10#include <linux/slab.h>
11#include <linux/mtd/mtd.h>
12#include <linux/mtd/partitions.h>
13#include "../mtdcore.h"
14#include <asm/delay.h>
15#include <asm/io.h>
16#include <linux/semaphore.h>
17#include <linux/squashfs_fs.h>
18
19#include "ar7100.h"
20#include "wzrag300nh_flash.h"
21
22#include <linux/proc_fs.h>
23
24/* this is passed in as a boot parameter by bootloader */
25extern int __ath_flash_size;
26
27#undef  AR7100_FLASH_MAX_BANKS
28#define AR7100_FLASH_MAX_BANKS  2
29/*
30 * statics
31 */
32static void ar7100_spi_write_enable(unsigned int cs);
33static void ar7100_spi_poll(unsigned int cs);
34static void ar7100_spi_fast_read(unsigned int cs, uint32_t addr, uint8_t *data, int len);
35static void ar7100_spi_read(unsigned int cs, uint32_t addr, uint8_t *data, int len);
36static void ar7100_spi_write_page(uint32_t addr, uint8_t *data, int len);
37static void ar7100_spi_sector_erase(uint32_t addr);
38
39
40
41static  __u32   _s_lastaddr     = 0;
42static  __u32   _f_lastwrite= 0;
43static  __u32   _f_init         = 1;
44static  __u32   _f_on           = 0;
45static  __u32   _s_jiffies      = 0;
46#define _S_OALASTADDR_MASK      0xFFFFC000      //16KBytes
47
48#define IS_NEW_SEQUENCE(F_WRITE)                ( ((F_WRITE)==0 && _f_lastwrite) || (jiffies-_s_jiffies)>(HZ/10) )
49
50#define DBGMSG(S)       do { printk(KERN_DEBUG "%s[%08lX]::%s\n", __FUNCTION__, jiffies, (S)); } while(0)
51
52#if 0// defined(CONFIG_MACH_AR7100)
53//#include      "asm/mach-ar7100/ar7100.h"
54#define DIAG_GPIO_NO                    (1<<1)
55#define DIAG_INIT(F_WRITE)              do { if(IS_NEW_SEQUENCE(F_WRITE)){_f_on=0;} while(_f_init) { ar7100_reg_rmw_set(AR7100_GPIO_OE, DIAG_GPIO_NO); _f_init=0; } } while(0)
56#define DIAG_ON()                               do { ar7100_reg_wr(AR7100_GPIO_CLEAR, DIAG_GPIO_NO); _s_jiffies=jiffies; } while(0)
57#define DIAG_OFF()                              do { ar7100_reg_wr(AR7100_GPIO_SET, DIAG_GPIO_NO); _s_jiffies=jiffies; } while(0)
58#define DIAG_BLINK()                    do { _f_on = (_f_on+1) & 0x1; if (_f_on) DIAG_ON(); else DIAG_OFF(); } while(0)
59
60#else   //defined  CONFIG_AR9100
61#define DIAG_GPIO_NO                    (1<<1)
62#define DIAG_INIT(F_WRITE)              do {  } while(0)
63#define DIAG_ON()                               do {  } while(0)
64#define DIAG_OFF()                              do {  } while(0)
65#define DIAG_BLINK()                    do {  } while(0)
66#endif  //defined  CONFIG_AR9100
67
68#define down mutex_lock
69#define up mutex_unlock
70#define init_MUTEX mutex_init
71#define DECLARE_MUTEX(a) struct mutex a
72
73
74static DECLARE_MUTEX(ar7100_flash_sem);
75
76/* GLOBAL FUNCTIONS */
77void
78ar7100_flash_spi_down(void) {
79  down(&ar7100_flash_sem);
80}
81
82void
83ar7100_flash_spi_up(void) {
84  up(&ar7100_flash_sem);
85}
86
87EXPORT_SYMBOL(ar7100_flash_spi_down);
88EXPORT_SYMBOL(ar7100_flash_spi_up);
89
90u_int32_t       g_buffalo_clock_div     = 3;
91u_int32_t       g_buffalo_current_div;
92
93static  u_int32_t       ar7100_cpu_freq = 0, ar7100_ahb_freq, ar7100_ddr_freq;
94
95static  void    get_ahb_clock(void)
96{
97    uint32_t pll, pll_div, cpu_div, ahb_div, ddr_div, freq;
98    pll = ar7100_reg_rd(AR7100_PLL_CONFIG);
99
100    pll_div  = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
101    freq     = pll_div * 40000000;
102    cpu_div  = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
103    ddr_div  = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
104    ahb_div  = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1)*2;
105
106    ar7100_cpu_freq = freq/cpu_div;
107    ar7100_ddr_freq = freq/ddr_div;
108    ar7100_ahb_freq = ar7100_cpu_freq/ahb_div;
109}
110
111static void     buffalo_spi_clock_update()
112{
113        if (g_buffalo_clock_div != g_buffalo_current_div) {
114                if (g_buffalo_clock_div>=0 && g_buffalo_clock_div<64) {
115                        u_int32_t       last_value;
116                        unsigned long flags;
117                        ar7100_flash_spi_down();
118
119
120                        ar7100_reg_wr(AR7100_SPI_FS, 1);
121
122                        last_value      = ar7100_reg_rd(AR7100_SPI_CLOCK) & 0x3f;
123
124                        //      write value
125                        ar7100_reg_wr_nf(AR7100_SPI_CLOCK, 0x40 | (g_buffalo_clock_div & 0x3f));
126                        g_buffalo_current_div   = ar7100_reg_rd(AR7100_SPI_CLOCK) & 0x3f;
127
128
129#define         AR7100_SPI_CMD_WRITE_SR 0x1
130                        ar7100_spi_write_enable(0);
131                        ar7100_spi_bit_banger(0, AR7100_SPI_CMD_WRITE_SR);
132                        ar7100_spi_bit_banger(0, 0x0);
133                        ar7100_spi_go(0);
134                        ar7100_spi_poll(0);
135
136                        ar7100_reg_wr(AR7100_SPI_FS, 0);
137
138#if     0
139                        {
140                                unsigned long flags;
141                                //      disable interrupts
142                                local_irq_save(flags);
143                                local_irq_disable();
144
145
146                                ar7100_reg_wr_nf(AR7100_PLL_CONFIG, (ar7100_reg_rd(AR7100_PLL_CONFIG) & (~((unsigned int)PLL_CONFIG_LOCKED_MASK))));
147                                ar7100_reg_wr_nf(AR7100_CPU_CLOCK_CONTROL, CLOCK_CONTROL_RST_SWITCH_MASK|CLOCK_CONTROL_CLOCK_SWITCH_MASK);
148                                ar7100_reg_rmw_clear(AR7100_CPU_CLOCK_CONTROL, CLOCK_CONTROL_RST_SWITCH_MASK);
149
150
151                                //      wait
152                                for ( ; 0==(ar7100_reg_rd(AR7100_PLL_CONFIG) & PLL_CONFIG_LOCKED_MASK) ; )
153                                        ;
154
155
156                                //      enable interrupts
157                                local_irq_enable();
158                                local_irq_restore(flags);
159                        }
160#endif
161
162
163
164                        //      read-back
165                        printk("SPI clock changed %d --> %d\n", ar7100_ahb_freq / (2 << last_value), ar7100_ahb_freq / (2 << g_buffalo_current_div));
166
167                        ar7100_flash_spi_up();
168                }
169        }
170}
171
172//
173//      for BUFFALO debug
174//
175static  int     atoi(const char *p)
176{
177        int             ret             = 0;
178        int             minus   = 0;
179        do      {
180                if (p==NULL)
181                        break;
182
183                for (; *p==' ' ; p++)
184                        ;
185
186                if (*p=='-') {
187                        minus   = 1;
188                        p++;
189                }
190
191                for (; p && *p>='0' && *p<='9' ; p++)
192                        ret     = (ret * 10) + (*p - '0');
193        } while(0);
194
195        return  (minus ? -ret : ret);
196}
197
198static  int     buffalo_set_value_write_proc(struct file *file, const char *buf, unsigned long count, void *data)
199{
200        char                    tmp[16];
201        int                             len     = count;
202
203//      printk(KERN_EMERG "@@set_value called\n");
204
205        if (len>=sizeof(tmp))   len     = sizeof(tmp)-1;
206        memset(tmp,0,sizeof(tmp));
207        if(copy_from_user(tmp, buf, len)){
208                printk(KERN_NOTICE "@@copy_from_user fail\n");
209                return -EFAULT;
210        }
211
212        if (data)
213        {
214                u_int32_t       val = atoi(tmp);
215                printk(KERN_EMERG "@@change value %d -> %d\n", *(u_int32_t *)data, val);
216
217                *(u_int32_t *)data      = val;
218                buffalo_spi_clock_update();
219                return  count;
220        }
221        return  -EFAULT;
222}
223
224static struct proc_dir_entry *g_pktlog_pde;
225static  void    create_proc_entry_buffalo(void *sc)
226{
227//      static int idx=0;
228        struct proc_dir_entry *ent;
229        char name[32];
230
231#define BUFFALO_DEBUG_PROC_DIR "spi_debug"
232        sprintf(name, BUFFALO_DEBUG_PROC_DIR);
233        g_pktlog_pde = proc_mkdir(name, NULL);
234
235//      if (idx)        return;
236
237        //      g_buffalo_backup_clock
238        sprintf(name, "clock_div");
239        ent     = create_proc_entry(name, 0644, g_pktlog_pde);
240        if (ent) {
241                extern  u_int32_t       g_buffalo_clock_div;
242                ent->data               = &g_buffalo_clock_div;
243                ent->write_proc = buffalo_set_value_write_proc;
244        }
245        //      count-up
246//      idx++;
247}
248
249#define AR7100_FLASH_SIZE_2MB          (2*1024*1024)
250#define AR7100_FLASH_SIZE_4MB          (4*1024*1024)
251#define AR7100_FLASH_SIZE_8MB          (8*1024*1024)
252#define AR7100_FLASH_SIZE_16MB         (16*1024*1024)
253#define AR7100_FLASH_PG_SIZE_256B       256
254#ifndef ST25P28
255#define AR7100_FLASH_SECTOR_SIZE_64KB  (64*1024)
256#else
257#define AR7100_FLASH_SECTOR_SIZE_256KB  (256*1024)
258#endif
259
260#define AR7100_FLASH_SIZE_12MB         (12*1024*1024)
261#define AR7100_FLASH_SIZE_32MB         (32*1024*1024)
262
263#define AR7100_FLASH_NAME               "ar7100-nor0"
264/*
265 * bank geometry
266 */
267typedef struct ar7100_flash_geom {
268        const char *name;
269        u_int8_t         chip_id[3];
270    uint32_t     size;
271    uint32_t     sector_size;
272    uint32_t     nsectors;
273    uint32_t     pgsize;
274}ar7100_flash_geom_t;
275
276ar7100_flash_geom_t g_flash_geom_tbl[] = {
277                                        //      chip-id                                 dev-size        blk-siz         n-sec   page-siz
278          {     "S25FL064P",    { 0x01, 0x02, 0x16 },   0x00800000,     0x10000,           0,    256    }               //S25FL064P
279        , {     "M25P64V6P",    { 0x20, 0x20, 0x17 },   0x00800000,     0x10000,           0,    256    }               //S25FL064P
280        , {     "MX25L64-45E",  { 0xc2, 0x20, 0x17 },   0x00800000,     0x10000,           0,    256    }               //MX25L64-45E
281        , {     "MX25L128-45E", { 0xc2, 0x20, 0x18 },   0x01000000,     0x10000,           0,    256    }               //MX25L128-45E
282        , {     "W25Q128BV",    { 0xef, 0x40, 0x18 },   0x01000000,     0x10000,           0,    256    }               //W25Q128BV
283        , {     "S25FL128P",    { 0x01, 0x20, 0x18 },   0x01000000,     0x10000,           0,    256    }               //S25FL128P
284        , {     NULL,                   { 0x00, 0x00, 0x00 },   0x00000000,     0x00000,           0,      0    }               //dummy
285};
286
287ar7100_flash_geom_t     g_flash_geoms[AR7100_FLASH_MAX_BANKS];
288
289
290
291
292static struct mtd_partition dir_parts[] = {
293      {name: "RedBoot", offset: 0, size:0x50000,},
294      {name: "linux", offset: 0x60000, size:0x1f90000,},
295      {name: "rootfs", offset: 0x0, size:0x2b0000,},
296      {name: "ddwrt", offset: 0x0, size:0x2b0000,},
297      {name: "nvram", offset: 0x3d0000, size:0x10000,},
298      {name: "FIS directory", offset: 0x3e0000, size:0x10000,},
299      {name: "board_config", offset: 0x3f0000, size:0x10000,},
300      {name: "fullflash", offset: 0x3f0000, size:0x10000,},
301      {name: "uboot-env", offset: 0x40000, size:0x10000,},
302      {name:NULL,},
303};
304
305         
306static int
307ar7100_flash_probe()
308{
309    return 0;
310}
311
312static int
313ar7100_flash_erase(struct mtd_info *mtd,struct erase_info *instr)
314{
315    int nsect, s_curr, s_last;
316    uint64_t res;
317
318    if (instr->addr + instr->len > mtd->size) return (-EINVAL);
319
320    ar7100_flash_spi_down();
321
322
323        res = instr->len;
324        do_div(res, mtd->erasesize);
325        nsect = res;
326
327        if (((uint32_t)instr->len) % mtd->erasesize)
328                nsect++;
329
330
331        res = instr->addr;
332        do_div(res,mtd->erasesize);
333        s_curr = res;
334        s_last  = s_curr + nsect;
335
336    do {
337
338        ar7100_spi_sector_erase(s_curr * AR7100_SPI_SECTOR_SIZE);
339
340    } while (++s_curr < s_last);
341
342    ar7100_spi_done();
343
344
345    ar7100_flash_spi_up();
346
347    if (instr->callback) {
348        instr->state |= MTD_ERASE_DONE;
349        instr->callback (instr);
350    }
351
352
353
354    return 0;
355}
356
357static unsigned int     ar7100_spi_get_cs(unsigned int addr)
358{
359        if (g_flash_geoms[0].size) {
360                return  (g_flash_geoms[0].size <= addr);
361        } else {
362                return  (g_flash_geoms[1].size);
363        }
364}
365
366static int
367ar7100_flash_read_dmc(unsigned int cs, void *buf, size_t len)
368{
369        u_int8_t        *data   = buf;
370        size_t          i;
371        ar7100_flash_spi_down();
372
373        ar7100_reg_wr_nf(AR7100_SPI_FS, 1);
374        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);
375        ar7100_spi_bit_banger(cs,AR7100_SPI_CMD_READ_DMC);
376        ar7100_spi_delay_8(cs);
377//      ar7100_spi_delay_8(cs);
378//      ar7100_spi_delay_8(cs);
379
380        for (i=0; i<len ; i++, data++) {
381                ar7100_spi_delay_8(cs);
382                *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
383        }
384
385        ar7100_spi_done();
386
387        {
388                u_int8_t        msg[256];
389                size_t          msglen=0;
390                for (i=0 ; i<len ; i++) {
391                        if ((i%16)==0) {
392                                if (msglen)     printk("%s\n", msg);
393                                memset(msg,0,sizeof(msg));
394                                msglen  = sprintf(msg, "%04X : %02X", i, data[i]);
395                        } else {
396                                msglen  += sprintf(msg+msglen, " %02X", data[i]);
397                        }
398                }
399                if (msglen)     printk("%s\n", msg);
400        }
401
402        ar7100_flash_spi_up();
403
404        return  0;
405}
406
407static int
408ar7100_flash_read_manid(unsigned int cs, void *buf, size_t len)
409{
410        u_int8_t        *data   = buf;
411        size_t          i;
412        ar7100_flash_spi_down();
413
414        ar7100_reg_wr_nf(AR7100_SPI_FS, 1);
415        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);
416        ar7100_spi_bit_banger(cs,AR7100_SPI_CMD_READ_MANID);
417        ar7100_spi_send_addr(cs,0);
418//      ar7100_spi_delay_8(cs);
419
420        for (i=0; i<len ; i++, data++) {
421                ar7100_spi_delay_8(cs);
422                *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
423        }
424
425        ar7100_spi_done();
426
427        {
428                u_int8_t        msg[256];
429                size_t          msglen=0;
430                for (i=0, data=buf ; i<len ; i++) {
431                        if ((i%16)==0) {
432                                if (msglen)     printk("%s\n", msg);
433                                memset(msg,0,sizeof(msg));
434                                msglen  = sprintf(msg, "%04X : %02X", i, data[i]);
435                        } else {
436                                msglen  += sprintf(msg+msglen, " %02X", data[i]);
437                        }
438                }
439                if (msglen)     printk("%s\n", msg);
440        }
441
442        ar7100_flash_spi_up();
443
444        return  0;
445}
446
447static int
448ar7100_flash_read_id(unsigned int cs, void *buf, size_t len)
449{
450        u_int8_t        *data   = buf;
451        size_t          i;
452        ar7100_flash_spi_down();
453
454        ar7100_reg_wr_nf(AR7100_SPI_FS, 1);
455        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);
456        ar7100_spi_bit_banger(cs,AR7100_SPI_CMD_READ_ID);
457//      ar7100_spi_delay_8(cs);
458//      ar7100_spi_delay_8(cs);
459//      ar7100_spi_delay_8(cs);
460
461        for (i=0; i<len ; i++, data++) {
462                ar7100_spi_delay_8(cs);
463                *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
464        }
465
466        ar7100_spi_done();
467
468        {
469                u_int8_t        msg[256];
470                size_t          msglen=0;
471                for (data=buf, i=0 ; i<len ; i++) {
472                        if ((i%16)==0) {
473                                if (msglen)     printk("%s\n", msg);
474                                memset(msg,0,sizeof(msg));
475                                msglen  = sprintf(msg, "%04X : %02X", i, data[i]);
476                        } else {
477                                msglen  += sprintf(msg+msglen, " %02X", data[i]);
478                        }
479                }
480                if (msglen)     printk("%s\n", msg);
481        }
482
483        ar7100_flash_spi_up();
484
485        return  0;
486}
487
488static int
489ar7100_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
490                  size_t *retlen ,u_char *buf)
491{
492    uint32_t addr0, addr1;
493    size_t      len0, len1;
494
495    if (!len) return (0);
496    if (from + len > mtd->size) return (-EINVAL);
497
498
499    ar7100_flash_spi_down();
500
501    if (ar7100_spi_get_cs(from)) {
502        len0    = 0;
503        addr0   = 0;
504        len1    = len;
505        addr1   = (from - g_flash_geoms[0].size) | 0xbe000000;
506    } else if (ar7100_spi_get_cs(from+len)) {
507        len0    = g_flash_geoms[0].size - from;
508        addr0   = from | 0xbf000000;
509        len1    = len - len0;
510        addr1   = 0xbe000000;
511    } else {
512        len0    = len;
513        addr0   = from | 0xbf000000;
514        len1    = 0;
515        addr1   = 0;
516    }
517        if (len0)       memcpy(buf, (uint8_t *)(addr0), len0);
518//      if (len1)       memcpy(buf+len0, (uint8_t *)(addr1), len1);
519//      if (len0)       ar7100_spi_fast_read(0, addr0, buf, len0);
520        if (len1)       ar7100_spi_fast_read(1, addr1, buf+len0, len1);
521//      if (len0)       ar7100_spi_read(0, addr0, buf, len0);
522//      if (len1)       ar7100_spi_read(1, addr1, buf+len0, len1);
523//      if (len1) {
524//              if (addr1 < 0xbe200000)  ar7100_spi_read(1, addr1, buf+len0, len1);
525//              else                                     ar7100_spi_fast_read(1, addr1, buf+len0, len1);
526//      }
527
528    *retlen = len;
529
530    ar7100_flash_spi_up();
531
532    return 0;
533}
534
535static int
536ar7100_flash_write (struct mtd_info *mtd, loff_t to, size_t len,
537                    size_t *retlen, const u_char *buf)
538{
539    int total = 0, len_this_lp, bytes_this_page;
540    uint32_t addr = 0;
541    u_char *mem;
542
543
544    ar7100_flash_spi_down();
545
546
547    while(total < len) {
548        mem              = buf + total;
549        addr             = to  + total;
550        bytes_this_page  = AR7100_SPI_PAGE_SIZE - (addr % AR7100_SPI_PAGE_SIZE);
551        len_this_lp      = min((len - total), bytes_this_page);
552
553
554        ar7100_spi_write_page(addr, mem, len_this_lp);
555        total += len_this_lp;
556
557    }
558
559    ar7100_spi_done();
560
561
562    ar7100_flash_spi_up();
563
564    *retlen = len;
565
566
567    return 0;
568}
569
570
571/*
572 * sets up flash_info and returns size of FLASH (bytes)
573 */
574static int __init ar7100_flash_init (void)
575{
576    int i, np;
577    ar7100_flash_geom_t *geom;
578    struct mtd_info *mtd;
579    struct mtd_partition *mtd_parts;
580    uint8_t index;
581
582    init_MUTEX(&ar7100_flash_sem);
583
584    //  enable cs#1
585    ar7100_reg_rmw_set(0xb8040028, (1 << 12));
586
587        //      enable clock changing
588        create_proc_entry_buffalo(NULL);
589        get_ahb_clock();
590//      buffalo_spi_clock_update();
591
592
593        printk("check spi banks %d\n", AR7100_FLASH_MAX_BANKS);
594
595
596        for(i = 0; i < AR7100_FLASH_MAX_BANKS; i++) {
597                u_int8_t        chip_id[3];
598                int                     j;
599
600                struct {                                                                                //      offset
601                        u_int8_t        man_id;                                                 //      00h
602                        u_int8_t        dev_id_0;                                               //      01h
603                        u_int8_t        dev_id_1;                                               //      02h
604                        u_int8_t        dev_id_2;                                               //      03h
605                        u_int8_t        pad1[0x10 - 0x04];                              //      04h - 0fh
606                        u_int8_t        qry[3];                                                 //      10h - 12h
607                        u_int8_t        cmdset_id[2];                                   //      13h - 14h
608                        u_int8_t        addr_table[2];                                  //      15h - 16h
609                        u_int8_t        oem_cmdset_id[2];                               //      17h - 18h
610                        u_int8_t        oem_addr_table[2];                              //      19h - 1ah
611                        u_int8_t        VccMin;                                                 //      1bh
612                        u_int8_t        VccMax;                                                 //      1ch
613                        u_int8_t        VppMin;                                                 //      1dh
614                        u_int8_t        VppMax;                                                 //      1eh
615                        u_int8_t        WordWriteTimeoutTyp;                    //      1fh
616                        u_int8_t        BufWriteTimeoutTyp;                             //      20h
617                        u_int8_t        BlockEraseTimeoutTyp;                   //      21h
618                        u_int8_t        ChipEraseTimeoutTyp;                    //      22h
619                        u_int8_t        WordWriteTimeoutMax;                    //      23h
620                        u_int8_t        BufWriteTimeoutMax;                             //      24h
621                        u_int8_t        BlockEraseTimeoutMax;                   //      25h
622                        u_int8_t        ChipEraseTimeoutMax;                    //      26h
623                        u_int8_t        DevSize;                                                //      27h
624                        u_int16_t       InterfaceDesc;                                  //      28h - 29h
625                        u_int16_t       MaxBufWriteSize;                                //      2ah - 2bh
626                        u_int8_t        NumEraseRegions;                                //      2ch
627                        struct {
628                                u_int8_t        nEraseNum;                                      //      2dh, 31h, 35h, 39h
629                                u_int8_t        nEraseSiz0;                                     //      2eh, 32h, 36h, 3ah
630                                u_int8_t        nEraseSiz1;                                     //      2fh, 33h, 37h, 3bh
631                                u_int8_t        nEraseSiz2;                                     //      30h, 34h, 38h, 3ch
632                        } EraseRegionInfo[4];
633                        u_int8_t        pad2[0x40 - 0x3d];                              //      3dh - 3fh
634                        u_int8_t        pri[3];                                                 //      40h - 42h
635                        u_int8_t        MajVer;                                                 //      43h
636                        u_int8_t        MinVer;                                                 //      44h
637                        u_int8_t        SupportUnlock;                                  //      45h
638                        u_int8_t        SupportEraseSuspend;                    //      46h
639                        u_int8_t        SupportSectorProtect;                   //      47h
640                        u_int8_t        SupportSectorUnprotect;                 //      48h
641                        u_int8_t        TypeSectorProtect;                              //      49h
642                        u_int8_t        TypeSimulaneousOpe;                             //      4ah
643                        u_int8_t        TypeBurstMode;                                  //      4bh
644                        u_int8_t        TypePageMode;                                   //      4ch
645                        u_int8_t        AccSupplyMin;                                   //      4dh
646                        u_int8_t        AccSupplyMax;                                   //      4eh
647                        u_int8_t        WriteProtection;                                //      4fh
648                        u_int8_t        SupportProgramSuspend;                  //      50h
649                } cfi_buf;
650
651#if     0
652                struct  {
653                        u_int32_t       dmc_signature;                                  //      00h - 03h       0x50444653
654                        u_int8_t        dmc_MinVer;
655                        u_int8_t        dmc_MajVer;
656                        u_int8_t        nHeader;                                                //      06h
657                        u_int8_t        pad1[1];                                                //      07h
658                        u_int8_t        ;                                                               //      00h
659                        u_int8_t        ;                                                               //      00h
660                        u_int8_t        ;                                                               //      00h
661                        u_int8_t        ;                                                               //      00h
662                        u_int8_t        ;                                                               //      00h
663                        u_int8_t        ;                                                               //      00h
664                        u_int8_t        ;                                                               //      00h
665                        u_int8_t        ;                                                               //      00h
666                        u_int8_t        ;                                                               //      00h
667
668                } dmc_buf;
669#endif
670
671                memset(&chip_id[0], 0, sizeof(chip_id));
672                ar7100_flash_read_id(i, &chip_id[0], sizeof(chip_id));
673
674                for (j=0 ; j<sizeof(g_flash_geom_tbl)/sizeof(g_flash_geom_tbl[0]) ; j++) {
675                        if (memcmp(g_flash_geom_tbl[j].chip_id, chip_id, sizeof(g_flash_geom_tbl[j].chip_id))==0) {
676                                if (g_flash_geom_tbl[j].name) {
677                                        printk("found %s device on bank#%d\n", g_flash_geom_tbl[j].name, i);
678                                        g_flash_geoms[i]        = g_flash_geom_tbl[j];
679                                        if (g_flash_geoms[i].sector_size!=0 && g_flash_geoms[i].nsectors==0)
680                                                g_flash_geoms[i].nsectors       = g_flash_geoms[i].size / g_flash_geoms[i].sector_size;
681                                        break;
682                                }
683                        }
684                }
685
686#if     0
687                ar7100_flash_read_manid(i, &cfi_buf, sizeof(cfi_buf));
688                memset(&cfi_buf, 0, sizeof(cfi_buf));
689                ar7100_flash_read_id(i, &cfi_buf, sizeof(cfi_buf));
690                if (cfi_buf.qry[0]=='Q' && cfi_buf.qry[1]=='R' && cfi_buf.qry[2]=='Y') {
691                        g_flash_geoms[i].size                   = 2 << cfi_buf.DevSize;
692                        g_flash_geoms[i].sector_size    = 64 * 1024;
693                        g_flash_geoms[i].nsectors               = g_flash_geoms[i].size / g_flash_geoms[i].sector_size;
694                        g_flash_geoms[i].pgsize                 = 2 << cfi_buf.MaxBufWriteSize;
695                }
696#endif
697        }
698        printk("SPI flash size total:%d Mbytes\n", (g_flash_geoms[0].size + g_flash_geoms[1].size) >> 20);
699
700        mtd         =  kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
701        if (!mtd) {
702                printk("Cant allocate mtd stuff\n");
703                return -1;
704        }
705        memset(mtd, 0, sizeof(struct mtd_info));
706
707        mtd->name               =   AR7100_FLASH_NAME;
708        mtd->type               =   MTD_NORFLASH;
709        mtd->flags              =   (MTD_CAP_NORFLASH|MTD_WRITEABLE);
710        mtd->size               =   g_flash_geoms[0].size + g_flash_geoms[1].size;
711        mtd->erasesize          =   g_flash_geoms[0].sector_size;
712        mtd->numeraseregions    =   0;
713        mtd->eraseregions       =   NULL;
714        mtd->owner              =   THIS_MODULE;
715        mtd->_erase              =   ar7100_flash_erase;
716        mtd->_read               =   ar7100_flash_read;
717        mtd->_write              =   ar7100_flash_write;
718        mtd->priv                               = g_flash_geoms;
719        int offset = 0;
720        struct squashfs_super_block *sb;
721
722        char buf[512];
723        int retlen;
724        unsigned int rootsize,len;
725
726                while ((offset + mtd->erasesize) < mtd->size) {
727                        mtd_read(mtd,offset,512,&retlen,&buf[0]);
728                        if (*((__u32 *)buf) == SQUASHFS_MAGIC_SWAP) {
729                                printk(KERN_EMERG "\nfound squashfs at %X\n",offset);
730                                sb = (struct squashfs_super_block *)buf;
731                                dir_parts[2].offset = offset;
732
733                                dir_parts[2].size = sb->bytes_used;
734                                len = dir_parts[2].offset + dir_parts[2].size;
735                                len += (mtd->erasesize - 1);
736                                len &= ~(mtd->erasesize - 1);
737                                dir_parts[2].size = (len & 0x1ffffff) - dir_parts[2].offset;
738                                dir_parts[3].offset = dir_parts[2].offset + dir_parts[2].size;
739                                dir_parts[6].offset = mtd->size - mtd->erasesize;       // board config
740                                dir_parts[6].size = mtd->erasesize;
741                                dir_parts[5].offset = dir_parts[6].offset;      //fis config
742                                dir_parts[5].size = mtd->erasesize;
743                                dir_parts[4].offset = dir_parts[5].offset - mtd->erasesize;     //nvram
744                                dir_parts[4].size = mtd->erasesize;
745                                dir_parts[3].size = dir_parts[4].offset - dir_parts[3].offset;
746                                rootsize = dir_parts[4].offset - offset;        //size of rootfs aligned to nvram offset
747                                dir_parts[1].size = (dir_parts[2].offset -dir_parts[1].offset) + rootsize;
748                                break;
749                        }
750                offset+=4096;
751                }
752                dir_parts[7].offset = 0;        // linux + nvram = phy size
753                dir_parts[7].size = mtd->size;  // linux + nvram = phy size
754                add_mtd_partitions(mtd, dir_parts, 9);
755
756    return 0;
757}
758
759static void __exit ar7100_flash_exit(void)
760{
761    /*
762     * nothing to do
763     */
764}
765
766
767/*
768 * Primitives to implement flash operations
769 */
770static void
771ar7100_spi_write_enable(unsigned int cs) 
772{
773    ar7100_reg_wr_nf(AR7100_SPI_FS, 1);                 
774    ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
775    ar7100_spi_bit_banger(cs,AR7100_SPI_CMD_WREN);             
776    ar7100_spi_go(cs);
777}
778
779static void
780ar7100_spi_read(unsigned int cs, uint32_t addr, uint8_t *data, int len)
781{
782
783        if (cs) {
784#if     1
785                ar7100_reg_wr_nf(AR7100_SPI_FS, 1);                 
786                for (; len>0 ; len--, addr++, data++) {
787                        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
788                        ar7100_spi_bit_banger_1(0x3);       
789                        ar7100_spi_send_addr(cs,addr);
790                        ar7100_spi_delay_8(cs);
791                        *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
792                }
793                ar7100_spi_done();
794#else
795#if     0
796                //      Ʊ€ž·ë²Ì
797                ar7100_reg_wr_nf(AR7100_SPI_FS, 1);                 
798        for (; len>0 ; len--, data++) {
799                ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
800                ar7100_spi_bit_banger_1(0x3);       
801                        ar7100_spi_send_addr(cs,addr);
802                        ar7100_spi_delay_8(cs);
803                        *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
804        }
805        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
806                ar7100_spi_done();
807#else
808                ar7100_reg_wr_nf(AR7100_SPI_FS, 1);                 
809        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
810        ar7100_spi_bit_banger_1(0x3);       
811                ar7100_spi_send_addr(cs,addr);
812                ar7100_spi_delay_8(cs);
813        for (; len>0 ; len--, data++) {
814                        *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
815        }
816        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
817                ar7100_spi_done();
818#endif
819#endif
820        } else {
821                ar7100_reg_wr_nf(AR7100_SPI_FS, 1);                 
822        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
823        ar7100_spi_bit_banger_0(0x3);       
824                ar7100_spi_send_addr(cs,addr);
825                ar7100_spi_delay_8(cs);
826        for (; len>0 ; len--, data++) {
827                        *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
828        }
829                ar7100_spi_done();
830        }
831}
832
833static void
834ar7100_spi_fast_read(unsigned int cs, uint32_t addr, uint8_t *data, int len)
835{
836
837        if (cs) {
838                ar7100_reg_wr_nf(AR7100_SPI_FS, 1);                 
839                ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
840                ar7100_spi_bit_banger_1(AR7100_SPI_CMD_FAST_READ);       
841                ar7100_spi_send_addr(cs,addr);
842                ar7100_spi_delay_8(cs);
843                for (; len>0 ; len--, data++) {
844                        ar7100_spi_delay_8(cs);
845                        *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
846                }
847                ar7100_spi_done();
848#if             0               //OK pattern
849                ar7100_reg_wr_nf(AR7100_SPI_FS, 1);                 
850                for (; len>0 ; len--, addr++, data++) {
851                        ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
852                        ar7100_spi_bit_banger_1(AR7100_SPI_CMD_FAST_READ);       
853                        ar7100_spi_send_addr(cs,addr);
854                        ar7100_spi_delay_8(cs);
855                        ar7100_spi_delay_8(cs);
856                        *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
857                }
858                ar7100_spi_done();
859#endif  //CONFIG_BUFFALO
860
861        } else {
862                ar7100_reg_wr_nf(AR7100_SPI_FS, 1);                 
863                ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
864                ar7100_spi_bit_banger_0(AR7100_SPI_CMD_FAST_READ);       
865                ar7100_spi_send_addr(cs,addr);
866                ar7100_spi_delay_8(cs);
867                for (; len>0 ; len--, data++) {
868                        ar7100_spi_delay_8(cs);
869                        *data   = (uint8_t)ar7100_reg_rd(AR7100_SPI_RD_STATUS);
870                }
871                ar7100_spi_done();
872        }
873}
874
875static void
876ar7100_spi_poll(unsigned int cs)   
877{
878    int rd;                                                 
879
880        if (cs) {
881            do {
882                ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
883                ar7100_spi_bit_banger_1(AR7100_SPI_CMD_RD_STATUS);       
884                ar7100_spi_delay_8(cs);
885                rd = (ar7100_reg_rd(AR7100_SPI_RD_STATUS) & 1);               
886            }while(rd);
887        } else {
888            do {
889                ar7100_reg_wr_nf(AR7100_SPI_WRITE, AR7100_SPI_CS_DIS);     
890                ar7100_spi_bit_banger_0(AR7100_SPI_CMD_RD_STATUS);       
891                ar7100_spi_delay_8(cs);
892                rd = (ar7100_reg_rd(AR7100_SPI_RD_STATUS) & 1);               
893            }while(rd);
894        }
895}
896
897static void
898ar7100_spi_write_page(uint32_t addr, uint8_t *data, int len)
899{
900    int i;
901    uint8_t ch;
902    unsigned int cs = ar7100_spi_get_cs(addr);
903
904    ar7100_spi_write_enable(cs);
905    ar7100_spi_bit_banger(cs,AR7100_SPI_CMD_PAGE_PROG);
906    ar7100_spi_send_addr(cs,addr);
907
908    if (cs) {
909            for(i = 0; i < len; i++) {
910                ch = *(data + i);
911                ar7100_spi_bit_banger_1(ch);
912            }
913    } else {
914            for(i = 0; i < len; i++) {
915                ch = *(data + i);
916                ar7100_spi_bit_banger_0(ch);
917            }
918    }
919
920
921    ar7100_spi_go(cs);
922    ar7100_spi_poll(cs);
923}
924
925static void
926ar7100_spi_sector_erase(uint32_t addr)
927{
928    unsigned int cs = ar7100_spi_get_cs(addr);
929    ar7100_spi_write_enable(cs);
930    ar7100_spi_bit_banger(cs,AR7100_SPI_CMD_SECTOR_ERASE);
931    ar7100_spi_send_addr(cs,addr);
932    ar7100_spi_go(cs);
933    ar7100_spi_poll(cs);
934}
935
936module_init(ar7100_flash_init);
937module_exit(ar7100_flash_exit);
Note: See TracBrowser for help on using the repository browser.