clean invalid code
[firefly-linux-kernel-4.4.55.git] / drivers / mtd / nand / rk2818_nand.c
1
2 /*
3  * drivers/mtd/nand/rk2818_nand.c
4  *
5  * Copyright (C) 2010 RockChip, Inc.
6  * Author: hxy@rock-chips.com
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17  
18 #include <linux/module.h>
19 #include <linux/delay.h>
20 #include <linux/slab.h>
21 #include <linux/init.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/nand.h>
24 #include <linux/mtd/partitions.h>
25 #include <linux/interrupt.h>
26 #include <linux/device.h>
27 #include <linux/platform_device.h>
28 #include <linux/clk.h>
29 #include <linux/err.h>
30 #include <linux/io.h>
31
32 #include <mach/rk2818_nand.h>
33
34 #define PROGRAM_BUSY_COUNT   10000
35 #define ERASE_BUSY_COUNT            20000
36 #define READ_BUSY_COUNT             5000
37
38 /* Define delays in microsec for NAND device operations */
39 #define TROP_US_DELAY   2000
40
41 struct rk2818_nand_mtd {
42         struct mtd_info         mtd;
43         struct nand_chip                nand;
44         struct mtd_partition    *parts;
45         struct device           *dev;
46        const struct rk2818_nand_flash *flash_info;
47
48         struct clk              *clk;
49         void __iomem            *regs;
50         uint16_t                        col_addr;       
51 };
52
53 /* OOB placement block for use with software ecc generation */
54 static struct nand_ecclayout nand_sw_eccoob_8 = {
55         .eccbytes = 48,
56         .eccpos = { 8, 9, 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
57                           32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55},
58         .oobfree = {{0,8},{56, 72}}
59 };
60
61 /* OOB placement block for use with hardware ecc generation */
62 static struct nand_ecclayout nand_hw_eccoob_16 = {
63         .eccbytes = 28,
64         .eccpos = { 4,  5, 6,  7,  8, 9, 10,11,12,13,14,15,16,17,
65                           18,19,20,21,22,23,24,25,26,27,28,29,30,31},
66         .oobfree = {{0, 4}}
67 };
68
69 #ifdef CONFIG_MTD_PARTITIONS
70 static const char *part_probes[] = { "cmdlinepart", NULL };
71 #endif
72
73
74 static void rk2818_nand_wait_busy(struct mtd_info *mtd, uint32_t timeout)
75 {
76       
77         struct nand_chip *nand_chip = mtd->priv;
78         struct rk2818_nand_mtd *master = nand_chip->priv;
79         pNANDC pRK28NC=  (pNANDC)(master->regs);
80         
81         while (timeout > 0)
82         {
83                 timeout--;
84                 udelay(10);
85                 if ( pRK28NC->FMCTL& FMC_FRDY) 
86                         break;
87                 
88         }
89         
90     return;
91 }
92
93 static void rk2818_nand_wait_bchdone(struct mtd_info *mtd, uint32_t timeout)
94 {
95       
96         struct nand_chip *nand_chip = mtd->priv;
97         struct rk2818_nand_mtd *master = nand_chip->priv;
98         pNANDC pRK28NC=  (pNANDC)(master->regs);
99         
100         while (timeout > 0)
101         {
102                 timeout--;
103                 udelay(1);
104                 if(pRK28NC->BCHST &(1<<1))
105                         break;          
106         }
107         
108     return;
109 }
110
111 // only for dma mode 
112 static void wait_op_done(struct mtd_info *mtd, int max_retries, uint16_t param)
113 {
114        struct nand_chip *nand_chip = mtd->priv;
115         struct rk2818_nand_mtd *master = nand_chip->priv;
116         pNANDC pRK28NC=  (pNANDC)(master->regs);
117         
118         while (max_retries-- > 0) {
119                 udelay(1);
120                 if (pRK28NC->FLCTL & FL_RDY)
121                         break;          
122         }             
123 }
124
125 static int rk2818_nand_dev_ready(struct mtd_info *mtd)
126 {
127         struct nand_chip *nand_chip = mtd->priv;
128         struct rk2818_nand_mtd *master = nand_chip->priv;
129         pNANDC pRK28NC=  (pNANDC)(master->regs);
130           
131         if(pRK28NC->FMCTL& FMC_FRDY)
132            return 1;
133         else
134            return 0;
135 }
136
137 /*
138 *  ÉèÖÃƬѡ
139 */
140 static void rk2818_nand_select_chip(struct mtd_info *mtd, int chip)
141 {
142         struct nand_chip *nand_chip = mtd->priv;
143         struct rk2818_nand_mtd *master = nand_chip->priv;
144         pNANDC pRK28NC=  (pNANDC)(master->regs);
145         
146         pRK28NC ->FMCTL |= 0x1<<chip;
147 }
148
149 /*
150  *   ¶ÁÒ»¸ö×Ö½ÚÊý¾Ý
151 */
152 static u_char rk2818_nand_read_byte(struct mtd_info *mtd)
153 {
154         struct nand_chip *nand_chip = mtd->priv;
155         struct rk2818_nand_mtd *master = nand_chip->priv;
156         pNANDC pRK28NC=  (pNANDC)(master->regs);
157         
158         u_char ret = 0; 
159         pRK28NC->FLCTL &= ~FL_BYPASS;  // bypass mode
160         ret = (u_char)(pRK28NC ->chip[0].data);
161         return ret;
162 }
163
164 /*
165  *   ¶ÁÒ»¸öword ³¤¶ÈÊý¾Ý
166 */
167 static u16 rk2818_nand_read_word(struct mtd_info *mtd)
168 {
169         struct nand_chip *nand_chip = mtd->priv;
170         struct rk2818_nand_mtd *master = nand_chip->priv;
171         pNANDC pRK28NC=  (pNANDC)(master->regs);
172         
173         u_char tmp1 = 0,tmp2=0;
174         u16 ret=0;
175
176         pRK28NC->FLCTL &= ~FL_BYPASS;  // bypass mode
177           
178         tmp1 = (u_char)(pRK28NC ->chip[0].data);
179         tmp2 = (u_char)(pRK28NC ->chip[0].data);
180
181         ret =   (tmp2 <<8)|tmp1;
182           
183         return ret;
184 }
185
186 static void rk2818_nand_read_buf(struct mtd_info *mtd, u_char* const buf, int len)
187 {
188        struct nand_chip *nand_chip = mtd->priv;
189         struct rk2818_nand_mtd *master = nand_chip->priv;
190         pNANDC pRK28NC=  (pNANDC)(master->regs);
191         uint32_t  i;
192         
193    
194         if ( len < mtd->writesize )   // read oob
195         {
196                 pRK28NC ->BCHCTL = BCH_RST;
197                pRK28NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ;         
198                 wait_op_done(mtd,TROP_US_DELAY,0);
199                 rk2818_nand_wait_bchdone(mtd,TROP_US_DELAY) ;  
200                 memcpy(buf,(u_char *)(pRK28NC->spare),4);  //  only use nandc sram0
201         }
202         else
203        {
204            pRK28NC->FLCTL |= FL_BYPASS;  // dma mode           
205             for(i=0;i<mtd->writesize/0x400;i++)
206                 {
207                        pRK28NC ->BCHCTL = BCH_RST;
208                 pRK28NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ;        
209                         wait_op_done(mtd,TROP_US_DELAY,0);
210                         rk2818_nand_wait_bchdone(mtd,TROP_US_DELAY) ;
211                 memcpy(buf+i*0x400,(u_char *)(pRK28NC->buf),0x400);  //  only use nandc sram0
212                 }
213         }
214         
215         return; 
216
217 }
218
219 static void rk2818_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
220 {
221        struct nand_chip *nand_chip = mtd->priv;
222         struct rk2818_nand_mtd *master = nand_chip->priv;
223         pNANDC pRK28NC=  (pNANDC)(master->regs);
224      
225         uint32_t  i = 0;
226
227          pRK28NC->FLCTL |= FL_BYPASS;  // dma mode
228           for(i=0;i<mtd->writesize/0x400;i++)
229             {
230                memcpy((u_char *)(pRK28NC->buf),buf+i*0x400,0x400);  //  only use nandc sram0    
231                 pRK28NC ->BCHCTL =BCH_WR|BCH_RST;               
232                 pRK28NC ->FLCTL = (0<<4)|FL_COR_EN|0x1<<5|FL_RDN|FL_BYPASS|FL_START;
233                 wait_op_done(mtd,TROP_US_DELAY,0);      
234             }
235
236 }
237
238
239 static void rk2818_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, int page_addr)
240 {
241        struct nand_chip *nand_chip = mtd->priv;
242         struct rk2818_nand_mtd *master = nand_chip->priv;
243         pNANDC pRK28NC=  (pNANDC)(master->regs);
244
245        uint32_t timeout = 1000;
246         char status,ret;
247         
248         switch (command) {
249
250        case NAND_CMD_READID:
251                 pRK28NC ->chip[0].cmd = command;
252                 pRK28NC ->chip[0].addr = 0x0;
253                 while (timeout>0)
254                 {
255                  timeout --;
256                    udelay(1);  
257                   if(pRK28NC->FLCTL&FL_INTCLR)
258                          break;
259                   
260                 }
261                 
262                 break;
263                 
264        case NAND_CMD_READ0:
265               pRK28NC ->chip[0].cmd = command;
266                if ( column>= 0 )
267                  {
268                    pRK28NC ->chip[0].addr = column & 0xff;      
269                    if( mtd->writesize > 512) 
270                          pRK28NC ->chip[0].addr = (column >> 8) & 0xff;
271                  }
272                 if ( page_addr>=0 )
273                    {
274                         pRK28NC ->chip[0].addr = page_addr & 0xff;
275                         pRK28NC ->chip[0].addr = (page_addr >> 8) & 0xFF;
276                         pRK28NC ->chip[0].addr = (page_addr >> 16) & 0xff;
277                    }
278                 if( mtd->writesize > 512)
279                     pRK28NC ->chip[0].cmd = NAND_CMD_READSTART;
280
281                 rk2818_nand_wait_busy(mtd,READ_BUSY_COUNT);
282                 
283                 break;
284                 
285         case NAND_CMD_READ1:
286               pRK28NC ->chip[0].cmd = command;
287                 break;
288                 
289        case NAND_CMD_READOOB:
290                 pRK28NC ->BCHCTL = 0x0;         
291                 if( mtd->writesize > 512 )
292                         command = NAND_CMD_READ0;  // È«²¿¶Á£¬°üÀ¨¶Áoob
293                 
294                 pRK28NC ->chip[0].cmd = command;  
295
296               if ( mtd->writesize >512 )
297                {
298                         if ( column>= 0 )
299                          {
300                            pRK28NC ->chip[0].addr = (column + mtd->writesize) & 0xff;   
301                              pRK28NC ->chip[0].addr = ( (column + mtd->writesize)  >> 8) & 0xff;
302                          }
303                         if ( page_addr>=0 )
304                            {
305                                 pRK28NC ->chip[0].addr = page_addr & 0xff;
306                                 pRK28NC ->chip[0].addr = (page_addr >> 8) & 0xFF;
307                                 pRK28NC ->chip[0].addr = (page_addr >> 16) & 0xff;
308                            }
309                         pRK28NC ->chip[0].cmd = NAND_CMD_READSTART;
310               }
311                 else
312                 {
313                    pRK28NC ->chip[0].addr = column;
314                 }
315                         
316                 rk2818_nand_wait_busy(mtd,READ_BUSY_COUNT);
317                 
318          
319                 break;  
320                 
321         case NAND_CMD_PAGEPROG:
322                 pRK28NC ->FMCTL |= FMC_WP;  //½â³ýд±£»¤
323                 pRK28NC ->chip[0].cmd = command;
324                 rk2818_nand_wait_busy(mtd,PROGRAM_BUSY_COUNT);
325                 
326                 pRK28NC ->chip[0].cmd  = NAND_CMD_STATUS;
327                 status = pRK28NC ->chip[0].data;
328                 
329                 if(status&0x1)
330                         ret = -1;
331                 else
332                         ret =0;
333                 
334                 break;
335                 
336         case NAND_CMD_ERASE1:
337                 pRK28NC ->FMCTL |= FMC_WP;  //½â³ýд±£»¤
338                 pRK28NC ->BCHCTL = 0x0;
339                 pRK28NC ->chip[0].cmd  = command;
340                 if ( page_addr>=0 )
341                    {
342                         pRK28NC ->chip[0].addr = page_addr & 0xff;
343                         pRK28NC ->chip[0].addr = (page_addr>>8)&0xff;
344                         pRK28NC ->chip[0].addr = (page_addr>>16)&0xff;
345                    }  
346                 break;
347                 
348         case NAND_CMD_ERASE2:
349                 pRK28NC ->FMCTL |= FMC_WP;  //½â³ýд±£»¤
350                 pRK28NC ->chip[0].cmd  = command;              
351                 rk2818_nand_wait_busy(mtd,ERASE_BUSY_COUNT);
352                 pRK28NC ->chip[0].cmd  = NAND_CMD_STATUS;
353                 status = pRK28NC ->chip[0].data;
354                 
355                 if(status&0x1)
356                         ret = -1;
357                 else
358                         ret =0;
359                 
360                 break;
361                 
362         case NAND_CMD_SEQIN:
363                 pRK28NC ->FMCTL |= FMC_WP;  //½â³ýд±£»¤
364                 pRK28NC ->chip[0].cmd  = command;
365                udelay(1);
366                 if ( column>= 0 )
367                   {
368                    pRK28NC ->chip[0].addr = column;
369                      if( mtd->writesize > 512) 
370                        pRK28NC ->chip[0].addr = (column >> 8) & 0xff;
371                   }
372                 if( page_addr>=0 )
373                   {
374                         pRK28NC ->chip[0].addr = page_addr & 0xff;
375                         pRK28NC ->chip[0].addr = (page_addr>>8)&0xff;
376                         pRK28NC ->chip[0].addr = (page_addr>>16)&0xff;
377                  }
378                 
379                 break;
380                 
381         case NAND_CMD_STATUS:
382                 pRK28NC ->BCHCTL = 0x0;
383                 pRK28NC ->chip[0].cmd = command;
384                 break;
385
386         case NAND_CMD_RESET:
387                 pRK28NC ->chip[0].cmd = command;
388                 break;
389
390         /* This applies to read commands */
391         default:
392                pRK28NC ->chip[0].cmd = command;
393                 break;
394         }
395
396         udelay (1);
397    
398 }
399
400 int rk2818_nand_calculate_ecc(struct mtd_info *mtd,const uint8_t *dat,uint8_t *ecc_code)
401 {
402      struct nand_chip *nand_chip = mtd->priv;
403      struct rk2818_nand_mtd *master = nand_chip->priv;
404      pNANDC pRK28NC=  (pNANDC)(master->regs);
405  
406      int eccdata[7],i;
407          
408         for(i=0;i<7;i++) 
409          {
410             eccdata[i] = pRK28NC->spare[i+1];
411
412                    
413             ecc_code[i*4] = eccdata[i]& 0xff;
414             ecc_code[i*4+1] = (eccdata[i]>> 8)& 0xff;
415             ecc_code[i*4+2] = (eccdata[i]>>16)& 0xff;
416             ecc_code[i*4+3] = (eccdata[i]>>24)& 0xff;
417                   
418           }             
419         
420      return 0;
421 }
422
423  void rk2818_nand_hwctl_ecc(struct mtd_info *mtd, int mode)
424  {
425        struct nand_chip *nand_chip = mtd->priv;
426         struct rk2818_nand_mtd *master = nand_chip->priv;
427         pNANDC pRK28NC=  (pNANDC)(master->regs);
428
429         pRK28NC->BCHCTL = 1;  // reset bch and enable hw ecc
430                 
431        return;
432  }
433  
434  int rk2818_nand_correct_data(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,uint8_t *calc_ecc)
435  {
436        struct nand_chip *nand_chip = mtd->priv;
437         struct rk2818_nand_mtd *master = nand_chip->priv;
438         pNANDC pRK28NC=  (pNANDC)(master->regs);                
439
440         // hw correct data
441        if( pRK28NC->BCHST & (1<<2) )
442          {
443                 DEBUG(MTD_DEBUG_LEVEL0,
444                       "rk2818 nand :hw ecc uncorrectable error\n");
445                 return -1;
446         }
447         
448        return 0;
449  }
450  
451  int rk2818_nand_read_page(struct mtd_info *mtd,struct nand_chip *chip,uint8_t *buf, int page)
452  {
453        struct nand_chip *nand_chip = mtd->priv;
454         struct rk2818_nand_mtd *master = nand_chip->priv;
455         pNANDC pRK28NC=  (pNANDC)(master->regs);
456
457           
458         int i;
459         
460
461         rk2818_nand_wait_busy(mtd,READ_BUSY_COUNT);
462            
463        pRK28NC->FLCTL |= FL_BYPASS;  // dma mode
464
465         for(i=0;i<mtd->writesize/0x400;i++)
466         {
467                pRK28NC ->BCHCTL = BCH_RST;
468                pRK28NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ;         
469                 wait_op_done(mtd,TROP_US_DELAY,0);   
470                 rk2818_nand_wait_bchdone(mtd,TROP_US_DELAY) ;
471           
472               memcpy(buf+i*0x400,(u_char *)(pRK28NC->buf),0x400);  //  only use nandc sram0
473         }
474                 
475     return 0;
476         
477  }
478
479 void  rk2818_nand_write_page(struct mtd_info *mtd,struct nand_chip *chip,const uint8_t *buf)
480  {
481        struct nand_chip *nand_chip = mtd->priv;
482         struct rk2818_nand_mtd *master = nand_chip->priv;
483         pNANDC pRK28NC=  (pNANDC)(master->regs);
484        uint32_t  i = 0;
485
486
487         
488         pRK28NC->FLCTL |= FL_BYPASS;  // dma mode
489           for(i=0;i<mtd->writesize/0x400;i++)
490            {
491                memcpy((u_char *)(pRK28NC->buf),(buf+i*0x400),0x400);  //  only use nandc sram0          
492                if(i==0)
493                    memcpy((u_char *)(pRK28NC->spare),(u_char *)(chip->oob_poi + chip->ops.ooboffs),4);  
494                         
495                 pRK28NC ->BCHCTL = BCH_WR|BCH_RST;              
496                 pRK28NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_RDN|FL_BYPASS|FL_START;
497                 wait_op_done(mtd,TROP_US_DELAY,0);      
498            }
499
500          pRK28NC ->chip[0].cmd = NAND_CMD_PAGEPROG;
501           rk2818_nand_wait_busy(mtd,PROGRAM_BUSY_COUNT);
502           
503         
504     return;
505           
506  }
507
508 int rk2818_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, int page, int sndcmd)
509 {       
510        struct nand_chip *nand_chip = mtd->priv;
511         struct rk2818_nand_mtd *master = nand_chip->priv;
512         pNANDC pRK28NC=  (pNANDC)(master->regs);
513        int i;
514
515         if (sndcmd) {
516                 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
517                 sndcmd = 0;
518         }
519                 
520         rk2818_nand_wait_busy(mtd,READ_BUSY_COUNT);
521            
522        pRK28NC->FLCTL |= FL_BYPASS;  // dma mode
523
524         for(i=0;i<mtd->writesize/0x400;i++)
525         {
526                pRK28NC ->BCHCTL = BCH_RST;
527                pRK28NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ;         
528                 wait_op_done(mtd,TROP_US_DELAY,0);   
529                 rk2818_nand_wait_bchdone(mtd,TROP_US_DELAY) ;          
530          //     memcpy(buf+i*0x400,(u_char *)(pRK28NC->buf),0x400);  //  only use nandc sram0
531               if(i==0)
532                  memcpy((u_char *)(chip->oob_poi+ chip->ops.ooboffs),(u_char *)(pRK28NC->spare),4); 
533         }
534
535
536         return sndcmd;
537 }
538
539 int     rk2818_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int page)
540 {
541        struct nand_chip *nand_chip = mtd->priv;
542         struct rk2818_nand_mtd *master = nand_chip->priv;
543         pNANDC pRK28NC=  (pNANDC)(master->regs);
544
545           
546         int i;
547         
548
549         rk2818_nand_wait_busy(mtd,READ_BUSY_COUNT);
550            
551        pRK28NC->FLCTL |= FL_BYPASS;  // dma mode
552
553         for(i=0;i<mtd->writesize/0x400;i++)
554         {
555                pRK28NC ->BCHCTL = BCH_RST;
556                pRK28NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ;         
557                 wait_op_done(mtd,TROP_US_DELAY,0);   
558                 rk2818_nand_wait_bchdone(mtd,TROP_US_DELAY) ;          
559               memcpy(buf+i*0x400,(u_char *)(pRK28NC->buf),0x400);  //  only use nandc sram0
560               if(i==0)
561                  memcpy((u_char *)(chip->oob_poi+ chip->ops.ooboffs),(u_char *)(pRK28NC->spare),4); 
562         }
563                 
564     return 0;
565 }
566
567
568 static int rk2818_nand_probe(struct platform_device *pdev)
569 {
570        struct nand_chip *this;
571         struct mtd_info *mtd;
572         struct rk2818_nand_platform_data *pdata = pdev->dev.platform_data;
573         struct rk2818_nand_mtd *master;
574         struct resource *res;
575         int err = 0;
576         pNANDC pRK28NC;
577
578 #ifdef CONFIG_MTD_PARTITIONS
579         struct mtd_partition *partitions = NULL;
580         int num_partitions = 0;
581 #endif
582
583       /* Allocate memory for MTD device structure and private data */
584         master = kzalloc(sizeof(struct rk2818_nand_mtd), GFP_KERNEL);
585         if (!master)
586                 return -ENOMEM;
587
588          master->dev = &pdev->dev;
589         /* structures must be linked */
590         this = &master->nand;
591         mtd = &master->mtd;
592         mtd->priv = this;
593         mtd->owner = THIS_MODULE;
594        mtd->name = dev_name(&pdev->dev);
595            
596         /* 50 us command delay time */
597         this->chip_delay = 5;
598
599         this->priv = master;
600         this->dev_ready = rk2818_nand_dev_ready;
601         this->cmdfunc = rk2818_nand_cmdfunc;
602         this->select_chip = rk2818_nand_select_chip;
603         this->read_byte = rk2818_nand_read_byte;
604         this->read_word = rk2818_nand_read_word;
605         this->write_buf = rk2818_nand_write_buf;
606         this->read_buf = rk2818_nand_read_buf;
607         this->options |= NAND_USE_FLASH_BBT;    // open bbt options
608         
609            
610         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
611         if (!res) {
612                 err = -ENODEV;
613                 goto outres;
614         }
615
616         master->regs = ioremap(res->start, res->end - res->start + 1);
617         if (!master->regs) {
618                 err = -EIO;
619                 goto outres;
620         }
621
622         if (pdata->hw_ecc) {
623                 this->ecc.calculate = rk2818_nand_calculate_ecc;
624                 this->ecc.hwctl = rk2818_nand_hwctl_ecc;
625                 this->ecc.correct = rk2818_nand_correct_data;
626                 this->ecc.mode = NAND_ECC_HW;
627                 this->ecc.read_page = rk2818_nand_read_page;
628                 this->ecc.write_page = rk2818_nand_write_page;
629                 this->ecc.read_oob = rk2818_nand_read_oob;
630                 this->ecc.read_page_raw = rk2818_nand_read_page_raw;
631                 this->ecc.size = 1024;
632                 this->ecc.bytes = 28;
633                 this->ecc.layout = &nand_hw_eccoob_16;  
634         } else {
635                 this->ecc.size = 256;
636                 this->ecc.bytes = 3;
637                 this->ecc.layout = &nand_sw_eccoob_8;
638                 this->ecc.mode = NAND_ECC_SOFT;         
639         }
640
641        pRK28NC =  (pNANDC)(master->regs);
642        pRK28NC ->FMCTL = FMC_WP|FMC_FRDY|(0x1<<0);
643        pRK28NC ->FMWAIT |=  (1<<FMW_RWCS_OFFSET)|(4<<FMW_RWPW_OFFSET)|(1<<FMW_CSRW_OFFSET);
644         pRK28NC ->BCHCTL = 0x1;
645         
646         /* Reset NAND */
647         this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
648         /* NAND bus width determines access funtions used by upper layer */
649         if (pdata->width == 2) {
650                 this->options |= NAND_BUSWIDTH_16;
651                 this->ecc.layout = &nand_hw_eccoob_16;
652         }
653
654         /* Scan to find existence of the device */
655         if (nand_scan(mtd, 1)) {
656                 DEBUG(MTD_DEBUG_LEVEL0,
657                       "RK2818 NAND: Unable to find any NAND device.\n");
658                 err = -ENXIO;
659                 goto outscan;
660         }
661
662 #ifdef CONFIG_MTD_PARTITIONS
663         num_partitions = parse_mtd_partitions(mtd, part_probes, &partitions, 0);
664         if (num_partitions > 0) {
665                 printk(KERN_INFO "Using commandline partition definition\n");
666               add_mtd_partitions(mtd, partitions, num_partitions);
667                 if(partitions)
668                  kfree(partitions);
669         } else if (pdata->nr_parts) {
670                 printk(KERN_INFO "Using board partition definition\n");
671                 add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
672         } else
673 #endif
674         {
675                 printk(KERN_INFO "no partition info available, registering whole flash at once\n");
676                 add_mtd_device(mtd);
677         }
678
679         platform_set_drvdata(pdev, master);
680
681         return 0;
682         
683 outres:
684 outscan:
685         iounmap(master->regs);
686         kfree(master);
687
688         return err;
689         
690 }
691
692 static int rk2818_nand_remove(struct platform_device *pdev)
693 {
694         struct rk2818_nand_mtd *master = platform_get_drvdata(pdev);
695
696         platform_set_drvdata(pdev, NULL);
697
698         nand_release(&master->mtd);
699         iounmap(master->regs);
700         kfree(master);
701
702         return 0;
703 }
704
705 #ifdef CONFIG_PM
706 static int rk2818_nand_suspend(struct platform_device *pdev, pm_message_t state)
707 {
708         struct mtd_info *info = platform_get_drvdata(pdev);
709         int ret = 0;
710
711         DEBUG(MTD_DEBUG_LEVEL0, "RK2818_NAND : NAND suspend\n");
712         if (info)
713                 ret = info->suspend(info);
714         return ret;
715 }
716
717 static int rk2818_nand_resume(struct platform_device *pdev)
718 {
719         struct mtd_info *info = platform_get_drvdata(pdev);
720         int ret = 0;
721
722         DEBUG(MTD_DEBUG_LEVEL0, "RK2818_NAND : NAND resume\n");
723         /* Enable the NFC clock */
724
725         if (info)
726                 info->resume(info);
727
728         return ret;
729 }
730 #else
731 #define rk2818_nand_suspend   NULL
732 #define rk2818_nand_resume    NULL
733 #endif  /* CONFIG_PM */
734
735
736 static struct platform_driver rk2818_nand_driver = {
737         .driver = {
738                    .name = "rk2818-nand",
739                    },
740        .probe    = rk2818_nand_probe,
741         .remove = rk2818_nand_remove,
742         .suspend = rk2818_nand_suspend,
743         .resume = rk2818_nand_resume,
744 };
745
746 static int __init rk2818_nand_init(void)
747 {
748         /* Register the device driver structure. */
749         printk("rk2818_nand_init\n");
750         return platform_driver_register(&rk2818_nand_driver);;
751 }
752
753 static void __exit rk2818_nand_exit(void)
754 {
755         /* Unregister the device structure */
756         platform_driver_unregister(&rk2818_nand_driver);
757 }
758
759 module_init(rk2818_nand_init);
760 module_exit(rk2818_nand_exit);
761
762 MODULE_LICENSE("GPL");
763 MODULE_AUTHOR("hxy <hxy@rock-chips.com>");
764 MODULE_DESCRIPTION("MTD NAND driver for rk2818 device");
765