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

Last change on this file since 31660 was 31660, checked in by brainslayer, 10 days ago

use new squashfs in all kernels

File size: 28.6 KB
Line 
1/*
2 * This file contains glue for Atheros ar7240 spi flash interface
3 * Primitives are ar7240_spi_*
4 * mtd flash implements are ar7240_flash_*
5 */
6#include <linux/version.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/types.h>
10#include <linux/errno.h>
11#include <linux/slab.h>
12#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
13#include <asm/semaphore.h>
14#else
15#include <linux/semaphore.h>
16#endif
17#include <linux/squashfs_fs.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/partitions.h>
20#include "../mtdcore.h"
21#include <asm/delay.h>
22#include <asm/io.h>
23
24#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
25#else
26#include <asm/div64.h>
27#include <linux/jiffies.h>
28#endif
29
30
31
32
33
34#include "ar7240.h"
35#include "wzrg450nh_flash.h"
36
37#ifdef  CONFIG_BUFFALO
38#include <linux/proc_fs.h>
39#endif  //CONFIG_BUFFALO
40
41/* this is passed in as a boot parameter by bootloader */
42extern int __ath_flash_size;
43
44#ifdef  CONFIG_BUFFALO
45#undef  AR7240_FLASH_MAX_BANKS
46#define AR7240_FLASH_MAX_BANKS  2
47#endif  //CONFIG_BUFFALO
48/*
49 * statics
50 */
51#ifdef  CONFIG_BUFFALO
52static void ar7240_spi_write_enable(unsigned int cs);
53static void ar7240_spi_poll(unsigned int cs);
54static void ar7240_spi_fast_read(unsigned int cs, uint32_t addr, uint8_t *data, int len);
55static void ar7240_spi_read(unsigned int cs, uint32_t addr, uint8_t *data, int len);
56#else   //CONFIG_BUFFALO
57static void ar7240_spi_write_enable(void);
58static void ar7240_spi_poll(void);
59#endif  //CONFIG_BUFFALO
60static void ar7240_spi_write_page(uint32_t addr, uint8_t *data, int len);
61static void ar7240_spi_sector_erase(uint32_t addr);
62
63
64
65#ifdef  CONFIG_BUFFALO
66//
67//      BUFFALO EXTENTION for DIAG_LED
68//
69static  __u32   _s_lastaddr     = 0;
70static  __u32   _f_lastwrite= 0;
71static  __u32   _f_init         = 1;
72static  __u32   _f_on           = 0;
73static  __u32   _s_jiffies      = 0;
74#define _S_LASTADDR_MASK        0xFFFFC000      //16KBytes
75
76#define IS_NEW_SEQUENCE(F_WRITE)                ( ((F_WRITE)==0 && _f_lastwrite) || (jiffies-_s_jiffies)>(HZ/10) )
77
78#define DBGMSG(S)       do { printk(KERN_DEBUG "%s[%08lX]::%s\n", __FUNCTION__, jiffies, (S)); } while(0)
79
80#if 0 //        defined(CONFIG_MACH_AR7240)
81//#include      "asm/mach-ar7240/ar7240.h"
82#define DIAG_GPIO_NO                    (1<<14)
83#define DIAG_INIT(F_WRITE)              do { if(IS_NEW_SEQUENCE(F_WRITE)){_f_on=0;} while(_f_init) { ar7240_reg_rmw_set(AR7240_GPIO_OE, DIAG_GPIO_NO); _f_init=0; } } while(0)
84#define DIAG_ON()                               do { ar7240_reg_wr(AR7240_GPIO_CLEAR, DIAG_GPIO_NO); _s_jiffies=jiffies; } while(0)
85#define DIAG_OFF()                              do { ar7240_reg_wr(AR7240_GPIO_SET, DIAG_GPIO_NO); _s_jiffies=jiffies; } while(0)
86#define DIAG_BLINK()                    do { _f_on = (_f_on+1) & 0x1; if (_f_on) DIAG_ON(); else DIAG_OFF(); } while(0)
87
88#else   //defined  CONFIG_AR9100
89#define DIAG_GPIO_NO                    (1<<1)
90#define DIAG_INIT(F_WRITE)              do {  } while(0)
91#define DIAG_ON()                               do {  } while(0)
92#define DIAG_OFF()                              do {  } while(0)
93#define DIAG_BLINK()                    do {  } while(0)
94#endif  //defined  CONFIG_AR9100
95#endif  //CONFIG_BUFFALO
96
97
98#define down mutex_lock
99#define up mutex_unlock
100#define init_MUTEX mutex_init
101#define DECLARE_MUTEX(a) struct mutex a
102
103static struct mutex ar7240_flash_sem;
104
105/* GLOBAL FUNCTIONS */
106void
107ar7240_flash_spi_down(void)
108{
109        mutex_lock(&ar7240_flash_sem);
110}
111
112void
113ar7240_flash_spi_up(void)
114{
115        mutex_unlock(&ar7240_flash_sem);
116}
117
118EXPORT_SYMBOL(ar7240_flash_spi_down);
119EXPORT_SYMBOL(ar7240_flash_spi_up);
120
121#ifdef  CONFIG_BUFFALO
122u_int32_t       g_buffalo_clock_div     = 3;
123u_int32_t       g_buffalo_current_div;
124
125static  u_int32_t       ar7240_cpu_freq = 0, ar7240_ahb_freq, ar7240_ddr_freq;
126
127static  void    get_ahb_clock(void)
128{
129    uint32_t pll, pll_div, ahb_div, ddr_div, freq, ref_div;
130
131    if (ar7240_cpu_freq)
132        return;
133
134    pll = ar7240_reg_rd(AR7240_PLL_CONFIG);
135
136    pll_div  = ((pll >> PLL_DIV_SHIFT) & PLL_DIV_MASK);
137    ref_div  = (pll >> REF_DIV_SHIFT) & REF_DIV_MASK;
138    ddr_div  = ((pll >> DDR_DIV_SHIFT) & DDR_DIV_MASK) + 1;
139    ahb_div  = (((pll >> AHB_DIV_SHIFT) & AHB_DIV_MASK) + 1)*2;
140
141    freq     = pll_div * ref_div * 5000000;
142
143    ar7240_cpu_freq = freq;
144    ar7240_ddr_freq = freq/ddr_div;
145    ar7240_ahb_freq = ar7240_cpu_freq/ahb_div;
146}
147
148static void     buffalo_spi_clock_update(void)
149{
150        if (g_buffalo_clock_div != g_buffalo_current_div) {
151                if (g_buffalo_clock_div>=0 && g_buffalo_clock_div<64) {
152                        u_int32_t       last_value;
153                        ar7240_flash_spi_down();
154
155
156                        ar7240_reg_wr(AR7240_SPI_FS, 1);
157
158                        last_value      = ar7240_reg_rd(AR7240_SPI_CLOCK) & 0x3f;
159
160                        //      write value
161                        ar7240_reg_wr_nf(AR7240_SPI_CLOCK, 0x40 | (g_buffalo_clock_div & 0x3f));
162                        g_buffalo_current_div   = ar7240_reg_rd(AR7240_SPI_CLOCK) & 0x3f;
163
164
165#define         AR7240_SPI_CMD_WRITE_SR 0x1
166                        ar7240_spi_write_enable(0);
167                        ar7240_spi_bit_banger(0, AR7240_SPI_CMD_WRITE_SR);
168                        ar7240_spi_bit_banger(0, 0x0);
169                        ar7240_spi_go(0);
170                        ar7240_spi_poll(0);
171
172                        ar7240_reg_wr(AR7240_SPI_FS, 0);
173
174#if     0
175                        {
176                                unsigned long flags;
177                                //      disable interrupts
178                                local_irq_save(flags);
179                                local_irq_disable();
180
181
182                                ar7240_reg_wr_nf(AR7240_PLL_CONFIG, (ar7240_reg_rd(AR7240_PLL_CONFIG) & (~((unsigned int)PLL_CONFIG_LOCKED_MASK))));
183                                ar7240_reg_wr_nf(AR7240_CPU_CLOCK_CONTROL, CLOCK_CONTROL_RST_SWITCH_MASK|CLOCK_CONTROL_CLOCK_SWITCH_MASK);
184                                ar7240_reg_rmw_clear(AR7240_CPU_CLOCK_CONTROL, CLOCK_CONTROL_RST_SWITCH_MASK);
185
186
187                                //      wait
188                                for ( ; 0==(ar7240_reg_rd(AR7240_PLL_CONFIG) & PLL_CONFIG_LOCKED_MASK) ; )
189                                        ;
190
191
192                                //      enable interrupts
193                                local_irq_enable();
194                                local_irq_restore(flags);
195                        }
196#endif
197
198
199
200                        //      read-back
201                        printk("SPI clock changed %d --> %d\n", ar7240_ahb_freq / (2 << last_value), ar7240_ahb_freq / (2 << g_buffalo_current_div));
202
203                        ar7240_flash_spi_up();
204                }
205        }
206}
207
208//
209//      for BUFFALO debug
210//
211static  int     atoi(const char *p)
212{
213        int             ret             = 0;
214        int             minus   = 0;
215        do      {
216                if (p==NULL)
217                        break;
218
219                for (; *p==' ' ; p++)
220                        ;
221
222                if (*p=='-') {
223                        minus   = 1;
224                        p++;
225                }
226
227                for (; p && *p>='0' && *p<='9' ; p++)
228                        ret     = (ret * 10) + (*p - '0');
229        } while(0);
230
231        return  (minus ? -ret : ret);
232}
233
234static  int     buffalo_set_value_write_proc(struct file *file, const char *buf, unsigned long count, void *data)
235{
236        char                    tmp[16];
237        int                             len     = count;
238
239//      printk(KERN_EMERG "@@set_value called\n");
240
241        if (len>=sizeof(tmp))   len     = sizeof(tmp)-1;
242        memset(tmp,0,sizeof(tmp));
243        if(copy_from_user(tmp, buf, len)){
244                printk(KERN_NOTICE "@@copy_from_user fail\n");
245                return -EFAULT;
246        }
247
248        if (data)
249        {
250                u_int32_t       val = atoi(tmp);
251                printk(KERN_EMERG "@@change value %d -> %d\n", *(u_int32_t *)data, val);
252
253                *(u_int32_t *)data      = val;
254                buffalo_spi_clock_update();
255                return  count;
256        }
257        return  -EFAULT;
258}
259
260static struct proc_dir_entry *g_pktlog_pde;
261static  void    create_proc_entry_buffalo(void *sc)
262{
263//      static int idx=0;
264        struct proc_dir_entry *ent;
265        char name[32];
266
267#define BUFFALO_DEBUG_PROC_DIR "spi_debug"
268        sprintf(name, BUFFALO_DEBUG_PROC_DIR);
269        g_pktlog_pde = proc_mkdir(name, NULL);
270
271//      if (idx)        return;
272
273        //      g_buffalo_backup_clock
274        sprintf(name, "clock_div");
275        ent     = create_proc_entry(name, 0644, g_pktlog_pde);
276        if (ent) {
277                extern  u_int32_t       g_buffalo_clock_div;
278                ent->data               = &g_buffalo_clock_div;
279#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
280                ent->owner = THIS_MODULE;
281#endif
282                ent->write_proc = buffalo_set_value_write_proc;
283        }
284        //      count-up
285//      idx++;
286}
287#endif  //CONFIG_BUFFALO
288
289#define AR7240_FLASH_SIZE_2MB          (2*1024*1024)
290#define AR7240_FLASH_SIZE_4MB          (4*1024*1024)
291#define AR7240_FLASH_SIZE_8MB          (8*1024*1024)
292#define AR7240_FLASH_SIZE_16MB          (16*1024*1024)
293#define AR7240_FLASH_PG_SIZE_256B       256
294
295#ifndef ST25P28
296#define AR7240_FLASH_SECTOR_SIZE_64KB  (64*1024)
297#else
298#define AR7240_FLASH_SECTOR_SIZE_256KB  (256*1024)
299#endif
300
301#ifdef  CONFIG_BUFFALO
302#define AR7240_FLASH_SIZE_12MB         (12*1024*1024)
303#define AR7240_FLASH_SIZE_32MB         (32*1024*1024)
304#endif  //CONFIG_BUFFALO
305
306#define AR7240_FLASH_NAME               "ar7240-nor0"
307/*
308 * bank geometry
309 */
310#ifndef CONFIG_BUFFALO
311typedef struct ar7240_flash_geom {
312    uint32_t     size;
313    uint32_t     sector_size;
314    uint32_t     nsectors;
315    uint32_t     pgsize;
316} ar7240_flash_geom_t;
317
318ar7240_flash_geom_t flash_geom_tbl[AR7240_FLASH_MAX_BANKS] = {
319        {
320                .size           = AR7240_FLASH_SIZE_8MB,
321                .sector_size    = AR7240_FLASH_SECTOR_SIZE_64KB,
322                .pgsize         = AR7240_FLASH_PG_SIZE_256B
323        }
324};
325#else   //CONFIG_BUFFALO
326typedef struct ar7240_flash_geom {
327        const char *name;
328        u_int8_t         chip_id[3];
329    uint32_t     size;
330    uint32_t     sector_size;
331    uint32_t     nsectors;
332    uint32_t     pgsize;
333}ar7240_flash_geom_t;
334
335ar7240_flash_geom_t g_flash_geom_tbl[] = {
336                                        //      chip-id                                 dev-size        blk-siz         n-sec   page-siz
337          {     "S25FL064P",    { 0x01, 0x02, 0x16 },   0x00800000,     0x10000,           0,    256    }               //S25FL064P
338        , {     "M25P64V6P",    { 0x20, 0x20, 0x17 },   0x00800000,     0x10000,           0,    256    }               //S25FL064P
339        , {     "MX25L64-45E",  { 0xc2, 0x20, 0x17 },   0x00800000,     0x10000,           0,    256    }               //MX25L64-45E
340        , {     "MX25L128-45E", { 0xc2, 0x20, 0x18 },   0x01000000,     0x10000,           0,    256    }               //MX25L128-45E
341        , {     "W25Q128BV",    { 0xef, 0x40, 0x18 },   0x01000000,     0x10000,           0,    256    }               //W25Q128BV
342        , {     "S25FL128P",    { 0x01, 0x20, 0x18 },   0x01000000,     0x10000,           0,    256    }               //S25FL128P
343        , {     NULL,                   { 0x00, 0x00, 0x00 },   0x00000000,     0x00000,           0,      0    }               //dummy
344};
345
346ar7240_flash_geom_t     g_flash_geoms[AR7240_FLASH_MAX_BANKS];
347
348
349#endif  //CONFIG_BUFFALO
350
351static struct mtd_partition dir_parts[] = {
352      {name: "RedBoot", offset: 0, size:0x50000,},
353      {name: "linux", offset: 0x60000, size:0x1f90000,},
354      {name: "rootfs", offset: 0x0, size:0x2b0000,},
355      {name: "ddwrt", offset: 0x0, size:0x2b0000,},
356      {name: "nvram", offset: 0x3d0000, size:0x10000,},
357      {name: "FIS directory", offset: 0x3e0000, size:0x10000,},
358      {name: "board_config", offset: 0x3f0000, size:0x10000,},
359      {name: "fullflash", offset: 0x3f0000, size:0x10000,},
360      {name: "uboot-env", offset: 0x40000, size:0x10000,},
361      {name:NULL,},
362};
363
364
365         
366static int
367ar7240_flash_probe(void)
368{
369        return 0;
370}
371
372static int
373ar7240_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
374{
375    int nsect, s_curr, s_last;
376        uint64_t  res;
377
378
379        if (instr->addr + instr->len > mtd->size)
380                return (-EINVAL);
381
382    ar7240_flash_spi_down();
383
384#       ifdef   CONFIG_BUFFALO
385        DIAG_INIT(0);
386        _f_lastwrite    = 0;
387#       endif   //CONFIG_BUFFALO
388
389        res = instr->len;
390        do_div(res, mtd->erasesize);
391        nsect = res;
392
393        if (((uint32_t)instr->len) % mtd->erasesize)
394                nsect ++;
395
396        res = instr->addr;
397        do_div(res,mtd->erasesize);
398        s_curr = res;
399
400        s_last  = s_curr + nsect;
401
402    do {
403#       ifdef   CONFIG_BUFFALO
404                DIAG_BLINK();
405#       endif   //CONFIG_BUFFALO
406
407        ar7240_spi_sector_erase(s_curr * AR7240_SPI_SECTOR_SIZE);
408    } while (++s_curr < s_last);
409
410    ar7240_spi_done();
411
412#       ifdef   CONFIG_BUFFALO
413        DIAG_OFF();
414#       endif   //CONFIG_BUFFALO
415
416    ar7240_flash_spi_up();
417
418    if (instr->callback) {
419        instr->state |= MTD_ERASE_DONE;
420        instr->callback(instr);
421    }
422
423
424
425    return 0;
426}
427
428#ifndef CONFIG_BUFFALO
429static int
430ar7240_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
431                  size_t *retlen, u_char *buf)
432{
433    uint32_t addr = from | 0xbf000000;
434
435        if (!len)
436                return (0);
437        if (from + len > mtd->size)
438                return (-EINVAL);
439
440    ar7240_flash_spi_down();
441
442    memcpy(buf, (uint8_t *)(addr), len);
443    *retlen = len;
444
445    ar7240_flash_spi_up();
446
447    return 0;
448}
449#else   //CONFIG_BUFFALO
450static unsigned int     ar7240_spi_get_cs(unsigned int addr)
451{
452        if (g_flash_geoms[0].size) {
453                return  (g_flash_geoms[0].size <= addr);
454        } else {
455                return  (g_flash_geoms[1].size);
456        }
457}
458
459static int
460ar7240_flash_read_dmc(unsigned int cs, void *buf, size_t len)
461{
462        u_int8_t        *data   = buf;
463        size_t          i;
464        ar7240_flash_spi_down();
465
466        ar7240_reg_wr_nf(AR7240_SPI_FS, 1);
467        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);
468        ar7240_spi_bit_banger(cs,AR7240_SPI_CMD_READ_DMC);
469        ar7240_spi_delay_8(cs);
470//      ar7240_spi_delay_8(cs);
471//      ar7240_spi_delay_8(cs);
472
473        for (i=0; i<len ; i++, data++) {
474                ar7240_spi_delay_8(cs);
475                *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
476        }
477
478        ar7240_spi_done();
479
480        {
481                u_int8_t        msg[256];
482                size_t          msglen=0;
483                for (i=0 ; i<len ; i++) {
484                        if ((i%16)==0) {
485                                if (msglen)     printk("%s\n", msg);
486                                memset(msg,0,sizeof(msg));
487                                msglen  = sprintf(msg, "%04X : %02X", i, data[i]);
488                        } else {
489                                msglen  += sprintf(msg+msglen, " %02X", data[i]);
490                        }
491                }
492                if (msglen)     printk("%s\n", msg);
493        }
494
495        ar7240_flash_spi_up();
496
497        return  0;
498}
499
500static int
501ar7240_flash_read_manid(unsigned int cs, void *buf, size_t len)
502{
503        u_int8_t        *data   = buf;
504        size_t          i;
505        ar7240_flash_spi_down();
506
507        ar7240_reg_wr_nf(AR7240_SPI_FS, 1);
508        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);
509        ar7240_spi_bit_banger(cs,AR7240_SPI_CMD_READ_MANID);
510        ar7240_spi_send_addr(cs,0);
511//      ar7240_spi_delay_8(cs);
512
513        for (i=0; i<len ; i++, data++) {
514                ar7240_spi_delay_8(cs);
515                *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
516        }
517
518        ar7240_spi_done();
519
520        {
521                u_int8_t        msg[256];
522                size_t          msglen=0;
523                for (i=0, data=buf ; i<len ; i++) {
524                        if ((i%16)==0) {
525                                if (msglen)     printk("%s\n", msg);
526                                memset(msg,0,sizeof(msg));
527                                msglen  = sprintf(msg, "%04X : %02X", i, data[i]);
528                        } else {
529                                msglen  += sprintf(msg+msglen, " %02X", data[i]);
530                        }
531                }
532                if (msglen)     printk("%s\n", msg);
533        }
534
535        ar7240_flash_spi_up();
536
537        return  0;
538}
539
540static int
541ar7240_flash_read_id(unsigned int cs, void *buf, size_t len)
542{
543        u_int8_t        *data   = buf;
544        size_t          i;
545        ar7240_flash_spi_down();
546
547        ar7240_reg_wr_nf(AR7240_SPI_FS, 1);
548        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);
549        ar7240_spi_bit_banger(cs,AR7240_SPI_CMD_READ_ID);
550//      ar7240_spi_delay_8(cs);
551//      ar7240_spi_delay_8(cs);
552//      ar7240_spi_delay_8(cs);
553
554        for (i=0; i<len ; i++, data++) {
555                ar7240_spi_delay_8(cs);
556                *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
557        }
558
559        ar7240_spi_done();
560
561        {
562                u_int8_t        msg[256];
563                size_t          msglen=0;
564                for (data=buf, i=0 ; i<len ; i++) {
565                        if ((i%16)==0) {
566                                if (msglen)     printk("%s\n", msg);
567                                memset(msg,0,sizeof(msg));
568                                msglen  = sprintf(msg, "%04X : %02X", i, data[i]);
569                        } else {
570                                msglen  += sprintf(msg+msglen, " %02X", data[i]);
571                        }
572                }
573                if (msglen)     printk("%s\n", msg);
574        }
575
576        ar7240_flash_spi_up();
577
578        return  0;
579}
580
581static int
582ar7240_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
583                  size_t *retlen, u_char *buf)
584{
585    uint32_t addr0, addr1;
586    size_t      len0, len1;
587
588        if (!len)
589                return (0);
590        if (from + len > mtd->size)
591                return (-EINVAL);
592
593
594    ar7240_flash_spi_down();
595
596    if (ar7240_spi_get_cs(from)) {
597        len0    = 0;
598        addr0   = 0;
599        len1    = len;
600        addr1   = (from - g_flash_geoms[0].size) | 0xbe000000;
601    } else if (ar7240_spi_get_cs(from+len)) {
602        len0    = g_flash_geoms[0].size - from;
603        addr0   = from | 0xbf000000;
604        len1    = len - len0;
605        addr1   = 0xbe000000;
606    } else {
607        len0    = len;
608        addr0   = from | 0xbf000000;
609        len1    = 0;
610        addr1   = 0;
611    }
612        if (len0)       memcpy(buf, (uint8_t *)(addr0), len0);
613//      if (len1)       memcpy(buf+len0, (uint8_t *)(addr1), len1);
614//      if (len0)       ar7240_spi_fast_read(0, addr0, buf, len0);
615        if (len1)       ar7240_spi_fast_read(1, addr1, buf+len0, len1);
616//      if (len0)       ar7240_spi_read(0, addr0, buf, len0);
617//      if (len1)       ar7240_spi_read(1, addr1, buf+len0, len1);
618//      if (len1) {
619//              if (addr1 < 0xbe200000)  ar7240_spi_read(1, addr1, buf+len0, len1);
620//              else                                     ar7240_spi_fast_read(1, addr1, buf+len0, len1);
621//      }
622
623    *retlen = len;
624
625    ar7240_flash_spi_up();
626
627    return 0;
628}
629#endif  //CONFIG_BUFFALO
630
631static int
632ar7240_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
633                    size_t *retlen, const u_char *buf)
634{
635    int total = 0, len_this_lp, bytes_this_page;
636    uint32_t addr = 0;
637    u_char *mem;
638
639
640    ar7240_flash_spi_down();
641
642#       ifdef   CONFIG_BUFFALO
643        DIAG_INIT(1);
644        _f_lastwrite    = 1;
645#       endif   //CONFIG_BUFFALO
646
647        while (total < len) {
648                mem = (u_char *) (buf + total);
649                addr = to + total;
650                bytes_this_page =
651                    AR7240_SPI_PAGE_SIZE - (addr % AR7240_SPI_PAGE_SIZE);
652                len_this_lp = min(((int)len - total), bytes_this_page);
653
654#               ifdef   CONFIG_BUFFALO
655                if ( (addr&_S_LASTADDR_MASK) != _s_lastaddr) {
656                        DIAG_BLINK();
657                        _s_lastaddr     = addr&_S_LASTADDR_MASK;
658                }
659#               endif   //CONFIG_BUFFALO
660
661        ar7240_spi_write_page(addr, mem, len_this_lp);
662        total += len_this_lp;
663    }
664
665    ar7240_spi_done();
666
667#       ifdef   CONFIG_BUFFALO
668        DIAG_OFF();
669#       endif   //CONFIG_BUFFALO
670
671    ar7240_flash_spi_up();
672
673    *retlen = len;
674
675
676    return 0;
677}
678
679
680/*
681 * sets up flash_info and returns size of FLASH (bytes)
682 */
683static int __init ar7240_flash_init(void)
684{
685    int i, np;
686    ar7240_flash_geom_t *geom;
687    struct mtd_info *mtd;
688    struct mtd_partition *mtd_parts;
689    uint8_t index;
690   
691    mutex_init(&ar7240_flash_sem);
692
693#ifdef  CONFIG_BUFFALO
694    //  enable cs#1
695
696        if (is_ar7242())
697        {
698                ar7240_reg_rmw_set(AR7240_GPIO_FUNCTIONS, (1 << 13));
699        }else
700        {
701                ar7240_reg_rmw_set(AR7240_GPIO_FUNCTIONS, (1 << 12));
702        }
703
704#endif  //CONFIG_BUFFALO
705
706#ifdef  CONFIG_BUFFALO
707        create_proc_entry_buffalo(NULL);
708        get_ahb_clock();
709//      buffalo_spi_clock_update();
710#else   //CONFIG_BUFFALO
711    ar7240_reg_wr_nf(AR7240_SPI_CLOCK, 0x43);
712#endif  //CONFIG_BUFFALO
713
714
715        printk("check spi banks %d\n", AR7240_FLASH_MAX_BANKS);
716
717
718        for(i = 0; i < AR7240_FLASH_MAX_BANKS; i++) {
719                u_int8_t        chip_id[3];
720                int                     j;
721
722                struct {                                                                                //      offset
723                        u_int8_t        man_id;                                                 //      00h
724                        u_int8_t        dev_id_0;                                               //      01h
725                        u_int8_t        dev_id_1;                                               //      02h
726                        u_int8_t        dev_id_2;                                               //      03h
727                        u_int8_t        pad1[0x10 - 0x04];                              //      04h - 0fh
728                        u_int8_t        qry[3];                                                 //      10h - 12h
729                        u_int8_t        cmdset_id[2];                                   //      13h - 14h
730                        u_int8_t        addr_table[2];                                  //      15h - 16h
731                        u_int8_t        oem_cmdset_id[2];                               //      17h - 18h
732                        u_int8_t        oem_addr_table[2];                              //      19h - 1ah
733                        u_int8_t        VccMin;                                                 //      1bh
734                        u_int8_t        VccMax;                                                 //      1ch
735                        u_int8_t        VppMin;                                                 //      1dh
736                        u_int8_t        VppMax;                                                 //      1eh
737                        u_int8_t        WordWriteTimeoutTyp;                    //      1fh
738                        u_int8_t        BufWriteTimeoutTyp;                             //      20h
739                        u_int8_t        BlockEraseTimeoutTyp;                   //      21h
740                        u_int8_t        ChipEraseTimeoutTyp;                    //      22h
741                        u_int8_t        WordWriteTimeoutMax;                    //      23h
742                        u_int8_t        BufWriteTimeoutMax;                             //      24h
743                        u_int8_t        BlockEraseTimeoutMax;                   //      25h
744                        u_int8_t        ChipEraseTimeoutMax;                    //      26h
745                        u_int8_t        DevSize;                                                //      27h
746                        u_int16_t       InterfaceDesc;                                  //      28h - 29h
747                        u_int16_t       MaxBufWriteSize;                                //      2ah - 2bh
748                        u_int8_t        NumEraseRegions;                                //      2ch
749                        struct {
750                                u_int8_t        nEraseNum;                                      //      2dh, 31h, 35h, 39h
751                                u_int8_t        nEraseSiz0;                                     //      2eh, 32h, 36h, 3ah
752                                u_int8_t        nEraseSiz1;                                     //      2fh, 33h, 37h, 3bh
753                                u_int8_t        nEraseSiz2;                                     //      30h, 34h, 38h, 3ch
754                        } EraseRegionInfo[4];
755                        u_int8_t        pad2[0x40 - 0x3d];                              //      3dh - 3fh
756                        u_int8_t        pri[3];                                                 //      40h - 42h
757                        u_int8_t        MajVer;                                                 //      43h
758                        u_int8_t        MinVer;                                                 //      44h
759                        u_int8_t        SupportUnlock;                                  //      45h
760                        u_int8_t        SupportEraseSuspend;                    //      46h
761                        u_int8_t        SupportSectorProtect;                   //      47h
762                        u_int8_t        SupportSectorUnprotect;                 //      48h
763                        u_int8_t        TypeSectorProtect;                              //      49h
764                        u_int8_t        TypeSimulaneousOpe;                             //      4ah
765                        u_int8_t        TypeBurstMode;                                  //      4bh
766                        u_int8_t        TypePageMode;                                   //      4ch
767                        u_int8_t        AccSupplyMin;                                   //      4dh
768                        u_int8_t        AccSupplyMax;                                   //      4eh
769                        u_int8_t        WriteProtection;                                //      4fh
770                        u_int8_t        SupportProgramSuspend;                  //      50h
771                } cfi_buf;
772
773#if     0
774                struct  {
775                        u_int32_t       dmc_signature;                                  //      00h - 03h       0x50444653
776                        u_int8_t        dmc_MinVer;
777                        u_int8_t        dmc_MajVer;
778                        u_int8_t        nHeader;                                                //      06h
779                        u_int8_t        pad1[1];                                                //      07h
780                        u_int8_t        ;                                                               //      00h
781                        u_int8_t        ;                                                               //      00h
782                        u_int8_t        ;                                                               //      00h
783                        u_int8_t        ;                                                               //      00h
784                        u_int8_t        ;                                                               //      00h
785                        u_int8_t        ;                                                               //      00h
786                        u_int8_t        ;                                                               //      00h
787                        u_int8_t        ;                                                               //      00h
788                        u_int8_t        ;                                                               //      00h
789
790                } dmc_buf;
791#endif
792
793                memset(&chip_id[0], 0, sizeof(chip_id));
794                ar7240_flash_read_id(i, &chip_id[0], sizeof(chip_id));
795
796                for (j=0 ; j<sizeof(g_flash_geom_tbl)/sizeof(g_flash_geom_tbl[0]) ; j++) {
797                        if (memcmp(g_flash_geom_tbl[j].chip_id, chip_id, sizeof(g_flash_geom_tbl[j].chip_id))==0) {
798                                if (g_flash_geom_tbl[j].name) {
799                                        printk("found %s device on bank#%d\n", g_flash_geom_tbl[j].name, i);
800                                        g_flash_geoms[i]        = g_flash_geom_tbl[j];
801                                        if (g_flash_geoms[i].sector_size!=0 && g_flash_geoms[i].nsectors==0)
802                                                g_flash_geoms[i].nsectors       = g_flash_geoms[i].size / g_flash_geoms[i].sector_size;
803                                        break;
804                                }
805                        }
806                }
807
808#if     0
809                ar7240_flash_read_manid(i, &cfi_buf, sizeof(cfi_buf));
810                memset(&cfi_buf, 0, sizeof(cfi_buf));
811                ar7240_flash_read_id(i, &cfi_buf, sizeof(cfi_buf));
812                if (cfi_buf.qry[0]=='Q' && cfi_buf.qry[1]=='R' && cfi_buf.qry[2]=='Y') {
813                        g_flash_geoms[i].size                   = 2 << cfi_buf.DevSize;
814                        g_flash_geoms[i].sector_size    = 64 * 1024;
815                        g_flash_geoms[i].nsectors               = g_flash_geoms[i].size / g_flash_geoms[i].sector_size;
816                        g_flash_geoms[i].pgsize                 = 2 << cfi_buf.MaxBufWriteSize;
817                }
818#endif
819        }
820        printk("SPI flash size total:%d Mbytes\n", (g_flash_geoms[0].size + g_flash_geoms[1].size) >> 20);
821
822        mtd         =  kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
823        if (!mtd) {
824                printk("Cant allocate mtd stuff\n");
825                return -1;
826        }
827        memset(mtd, 0, sizeof(struct mtd_info));
828
829
830        mtd->name               =   AR7240_FLASH_NAME;
831        mtd->type               =   MTD_NORFLASH;
832        mtd->flags              =   (MTD_CAP_NORFLASH|MTD_WRITEABLE);
833        mtd->size               =   g_flash_geoms[0].size + g_flash_geoms[1].size;
834        mtd->erasesize          =   g_flash_geoms[0].sector_size;
835        mtd->numeraseregions    =   0;
836        mtd->eraseregions       =   NULL;
837        mtd->owner              =   THIS_MODULE;
838        mtd->_erase              =   ar7240_flash_erase;
839        mtd->_read               =   ar7240_flash_read;
840        mtd->_write              =   ar7240_flash_write;
841        mtd->writesize          =   1;
842        mtd->priv                               = g_flash_geoms;
843
844        int offset = 0;
845        struct squashfs_super_block *sb;
846
847        char buf[512];
848        int retlen;
849        unsigned int rootsize,len;
850
851                while ((offset + mtd->erasesize) < mtd->size) {
852                        mtd_read(mtd,offset,512,&retlen,&buf[0]);
853                        if (*((__u32 *)buf) == SQUASHFS_MAGIC_SWAP) {
854                                printk(KERN_EMERG "\nfound squashfs at %X\n",offset);
855                                sb = (struct squashfs_super_block *)buf;
856                                dir_parts[2].offset = offset;
857
858                                dir_parts[2].size = sb->bytes_used;
859                                len = dir_parts[2].offset + dir_parts[2].size;
860                                len += (mtd->erasesize - 1);
861                                len &= ~(mtd->erasesize - 1);
862                                dir_parts[2].size = (len & 0x1ffffff) - dir_parts[2].offset;
863                                dir_parts[3].offset = dir_parts[2].offset + dir_parts[2].size;
864                                dir_parts[6].offset = mtd->size - mtd->erasesize;       // board config
865                                dir_parts[6].size = mtd->erasesize;
866                                dir_parts[5].offset = dir_parts[6].offset;      //fis config
867                                dir_parts[5].size = mtd->erasesize;
868                                dir_parts[4].offset = dir_parts[5].offset - mtd->erasesize;     //nvram
869                                dir_parts[4].size = mtd->erasesize;
870                                dir_parts[3].size = dir_parts[4].offset - dir_parts[3].offset;
871                                rootsize = dir_parts[4].offset - offset;        //size of rootfs aligned to nvram offset
872                                dir_parts[1].size = (dir_parts[2].offset -dir_parts[1].offset) + rootsize;
873                                break;
874                        }
875                offset+=4096;
876                }
877                dir_parts[7].offset = 0;        // linux + nvram = phy size
878                dir_parts[7].size = mtd->size;  // linux + nvram = phy size
879                add_mtd_partitions(mtd, dir_parts, 9);
880
881    return 0;
882}
883
884static void __exit ar7240_flash_exit(void)
885{
886    /*
887     * nothing to do
888     */
889}
890
891
892/*
893 * Primitives to implement flash operations
894 */
895#ifdef  CONFIG_BUFFALO
896static void
897ar7240_spi_write_enable(unsigned int cs) 
898{
899    ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
900    ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
901    ar7240_spi_bit_banger(cs,AR7240_SPI_CMD_WREN);             
902    ar7240_spi_go(cs);
903}
904
905static void
906ar7240_spi_read(unsigned int cs, uint32_t addr, uint8_t *data, int len)
907{
908
909        if (cs) {
910#if     1
911                ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
912                for (; len>0 ; len--, addr++, data++) {
913                        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
914                        ar7240_spi_bit_banger_1(0x3);       
915                        ar7240_spi_send_addr(cs,addr);
916                        ar7240_spi_delay_8(cs);
917                        *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
918                }
919                ar7240_spi_done();
920#else
921#if     0
922                //      Ʊ€ž·ë²Ì
923                ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
924        for (; len>0 ; len--, data++) {
925                ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
926                ar7240_spi_bit_banger_1(0x3);       
927                        ar7240_spi_send_addr(cs,addr);
928                        ar7240_spi_delay_8(cs);
929                        *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
930        }
931        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
932                ar7240_spi_done();
933#else
934                ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
935        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
936        ar7240_spi_bit_banger_1(0x3);       
937                ar7240_spi_send_addr(cs,addr);
938                ar7240_spi_delay_8(cs);
939        for (; len>0 ; len--, data++) {
940                        *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
941        }
942        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
943                ar7240_spi_done();
944#endif
945#endif
946        } else {
947                ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
948        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
949        ar7240_spi_bit_banger_0(0x3);       
950                ar7240_spi_send_addr(cs,addr);
951                ar7240_spi_delay_8(cs);
952        for (; len>0 ; len--, data++) {
953                        *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
954        }
955                ar7240_spi_done();
956        }
957}
958
959static void
960ar7240_spi_fast_read(unsigned int cs, uint32_t addr, uint8_t *data, int len)
961{
962
963        if (cs) {
964                ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
965                ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
966                ar7240_spi_bit_banger_1(AR7240_SPI_CMD_FAST_READ);       
967                ar7240_spi_send_addr(cs,addr);
968                ar7240_spi_delay_8(cs);
969                for (; len>0 ; len--, data++) {
970                        ar7240_spi_delay_8(cs);
971                        *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
972                }
973                ar7240_spi_done();
974#if             0               //OK pattern
975                ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
976                for (; len>0 ; len--, addr++, data++) {
977                        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
978                        ar7240_spi_bit_banger_1(AR7240_SPI_CMD_FAST_READ);       
979                        ar7240_spi_send_addr(cs,addr);
980                        ar7240_spi_delay_8(cs);
981                        ar7240_spi_delay_8(cs);
982                        *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
983                }
984                ar7240_spi_done();
985#endif  //CONFIG_BUFFALO
986
987        } else {
988                ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
989                ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
990                ar7240_spi_bit_banger_0(AR7240_SPI_CMD_FAST_READ);       
991                ar7240_spi_send_addr(cs,addr);
992                ar7240_spi_delay_8(cs);
993                for (; len>0 ; len--, data++) {
994                        ar7240_spi_delay_8(cs);
995                        *data   = (uint8_t)ar7240_reg_rd(AR7240_SPI_RD_STATUS);
996                }
997                ar7240_spi_done();
998        }
999}
1000
1001static void
1002ar7240_spi_poll(unsigned int cs)   
1003{
1004    int rd;                                                 
1005
1006        if (cs) {
1007            do {
1008                ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
1009                ar7240_spi_bit_banger_1(AR7240_SPI_CMD_RD_STATUS);       
1010                ar7240_spi_delay_8(cs);
1011                rd = (ar7240_reg_rd(AR7240_SPI_RD_STATUS) & 1);               
1012            }while(rd);
1013        } else {
1014            do {
1015                ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
1016                ar7240_spi_bit_banger_0(AR7240_SPI_CMD_RD_STATUS);       
1017                ar7240_spi_delay_8(cs);
1018                rd = (ar7240_reg_rd(AR7240_SPI_RD_STATUS) & 1);               
1019            }while(rd);
1020        }
1021}
1022
1023static void
1024ar7240_spi_write_page(uint32_t addr, uint8_t *data, int len)
1025{
1026    int i;
1027    uint8_t ch;
1028    unsigned int cs = ar7240_spi_get_cs(addr);
1029
1030    ar7240_spi_write_enable(cs);
1031    ar7240_spi_bit_banger(cs,AR7240_SPI_CMD_PAGE_PROG);
1032    ar7240_spi_send_addr(cs,addr);
1033
1034    if (cs) {
1035            for(i = 0; i < len; i++) {
1036                ch = *(data + i);
1037                ar7240_spi_bit_banger_1(ch);
1038            }
1039    } else {
1040            for(i = 0; i < len; i++) {
1041                ch = *(data + i);
1042                ar7240_spi_bit_banger_0(ch);
1043            }
1044    }
1045
1046
1047    ar7240_spi_go(cs);
1048    ar7240_spi_poll(cs);
1049}
1050
1051static void
1052ar7240_spi_sector_erase(uint32_t addr)
1053{
1054    unsigned int cs = ar7240_spi_get_cs(addr);
1055    ar7240_spi_write_enable(cs);
1056    ar7240_spi_bit_banger(cs,AR7240_SPI_CMD_SECTOR_ERASE);
1057    ar7240_spi_send_addr(cs,addr);
1058    ar7240_spi_go(cs);
1059    ar7240_spi_poll(cs);
1060}
1061#else   //CONFIG_BUFFALO
1062static void
1063ar7240_spi_write_enable() 
1064{
1065    ar7240_reg_wr_nf(AR7240_SPI_FS, 1);                 
1066    ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
1067    ar7240_spi_bit_banger(AR7240_SPI_CMD_WREN);             
1068    ar7240_spi_go();
1069}
1070
1071static void
1072ar7240_spi_poll()   
1073{
1074    int rd;                                                 
1075
1076    do {
1077        ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS);     
1078        ar7240_spi_bit_banger(AR7240_SPI_CMD_RD_STATUS);       
1079        ar7240_spi_delay_8();
1080        rd = (ar7240_reg_rd(AR7240_SPI_RD_STATUS) & 1);               
1081    }while(rd);
1082}
1083
1084static void
1085ar7240_spi_write_page(uint32_t addr, uint8_t *data, int len)
1086{
1087    int i;
1088    uint8_t ch;
1089
1090    ar7240_spi_write_enable();
1091    ar7240_spi_bit_banger(AR7240_SPI_CMD_PAGE_PROG);
1092    ar7240_spi_send_addr(addr);
1093
1094    for(i = 0; i < len; i++) {
1095        ch = *(data + i);
1096        ar7240_spi_bit_banger(ch);
1097    }
1098
1099    ar7240_spi_go();
1100    ar7240_spi_poll();
1101}
1102
1103static void
1104ar7240_spi_sector_erase(uint32_t addr)
1105{
1106        ar7240_spi_write_enable();
1107        ar7240_spi_bit_banger(AR7240_SPI_CMD_SECTOR_ERASE);
1108        ar7240_spi_send_addr(addr);
1109        ar7240_spi_go();
1110#if 0
1111        /*
1112         * Do not touch the GPIO's unnecessarily. Might conflict
1113         * with customer's settings.
1114         */
1115        display(0x7d);
1116#endif
1117        ar7240_spi_poll();
1118}
1119#endif  //CONFIG_BUFFALO
1120
1121module_init(ar7240_flash_init);
1122module_exit(ar7240_flash_exit);
Note: See TracBrowser for help on using the repository browser.