tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / mtd / nand / dolphin_nand.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #define DOLPHIN_UBOOT
15
16 #ifdef DOLPHIN_UBOOT
17 #include <common.h>
18 #include <malloc.h>
19 #include <asm/io.h>
20 #include <asm/errno.h>
21 #include <config.h>
22
23 #include <asm/arch/sci_types.h>
24 #include <asm/arch/pinmap.h>
25 #include <asm/arch/bits.h>
26
27 #include <nand.h>
28 #include <linux/mtd/nand.h>
29
30 #include <asm/arch-sc8830/sprd_nfc_reg_v2.h>
31 //#include <asm/arch/sc8810_reg_base.h>
32 #include <asm/arch/regs_ana.h>
33 #include <asm/arch/analog_reg_v3.h>
34 //#include <asm/arch/sc8810_reg_ahb.h>
35 //#include <asm/arch/sc8810_reg_global.h>
36 #include <asm/arch/gpio_drvapi.h>
37 #include <asm/arch/regs_global.h>
38 //#include <asm/arch/regs_cpc.h>
39 //#include <asm/arch/pin_reg_v3.h>
40
41 #ifdef CONFIG_NAND_SPL
42 #define udelay(x) \
43         do { \
44                 volatile int i; \
45                 int cnt = 200 * (x); \
46                 for (i=0; i<cnt; i++);\
47         } while(0);
48 #endif
49
50 #define mdelay(_ms) udelay((_ms)*1000)
51
52 #define NAND_DBG
53
54 #if defined(CONFIG_NAND_SPL) || !defined(NAND_DBG)
55 #define DPRINT(arg...) do{}while(0)
56 #else
57 #define DPRINT printf
58 #endif
59 #define ASSERT(cond) { assert(cond); }
60
61
62 #define NFC_MC_ICMD_ID  (0xCD)
63 #define NFC_MC_ADDR_ID  (0x0A)
64 #define NFC_MC_WRB0_ID  (0xB0)
65 #define NFC_MC_WRB1_ID  (0xB1)
66 #define NFC_MC_MRDT_ID  (0xD0)
67 #define NFC_MC_MWDT_ID  (0xD1)
68 #define NFC_MC_SRDT_ID  (0xD2)
69 #define NFC_MC_SWDT_ID  (0xD3)
70 #define NFC_MC_IDST_ID  (0xDD)
71 #define NFC_MC_CSEN_ID  (0xCE)
72 #define NFC_MC_NOP_ID   (0xF0)
73 #define NFC_MC_DONE_ID  (0xFF)
74 #define NFC_MAX_CHIP    1
75 #define NFC_TIMEOUT_VAL         0x1000000
76
77 #define NAND_MC_CMD(x)  (uint16_t)(((x & 0xff) << 8) | NFC_MC_ICMD_ID)
78 #define NAND_MC_ADDR(x) (uint16_t)(((x & 0xff) << 8) | (NFC_MC_ADDR_ID << 4))
79 #define NAND_MC_WRB0(x) (uint16_t)(NFC_MC_WRB0_ID)
80 #define NAND_MC_MRDT    (uint16_t)(NFC_MC_MRDT_ID)
81 #define NAND_MC_MWDT    (uint16_t)(NFC_MC_MWDT_ID)
82 #define NAND_MC_SRDT    (uint16_t)(NFC_MC_SRDT_ID)
83 #define NAND_MC_SWDT    (uint16_t)(NFC_MC_SWDT_ID)
84 #define NAND_MC_IDST(x) (uint16_t)((NFC_MC_IDST_ID) | ((x -1) << 8))
85 #define NAND_MC_NOP(x)  (uint16_t)(((x & 0xff) << 8) | NFC_MC_NOP_ID)
86
87
88 #define NAND_MC_BUFFER_SIZE (24)
89
90 static int mtderasesize = 0;
91 static int mtdwritesize = 0;
92 static int mtdoobsize = 0;
93
94 #endif  //DOLPHIN_UBOOT end
95
96
97 #ifdef DOLPHIN_KERNEL
98 #include <linux/kernel.h>
99 #include <linux/module.h>
100 #include <linux/interrupt.h>
101 #include <linux/dma-mapping.h>
102 #include <linux/platform_device.h>
103 #include <linux/delay.h>
104 #include <linux/mtd/mtd.h>
105 #include <linux/mtd/nand.h>
106 #include <linux/mtd/partitions.h>
107 #include <linux/io.h>
108 #include <linux/irq.h>
109 #include <linux/slab.h>
110 #include <linux/spinlock.h>
111 #include <mach/globalregs.h>
112 #include <mach/pinmap.h>
113
114 #include "dolphin_nand.h"
115 #define DPRINT printk
116
117 #endif  //DOLPHIN_KERNEL
118
119
120
121 #define SPRD_ASSERT(cond) { if (!(cond)) while(1); }
122 #define STATIC_FUNC static
123
124 #include "sprd_nand_param.h"
125
126
127 /* 2 bit correct, sc8810 support 1, 2, 4, 8, 12,14, 24 */
128 #define CONFIG_SYS_NAND_ECC_MODE    (2)
129 //#define CONFIG_SYS_NAND_ECC_MODE      8
130 /* Number of ECC bytes per OOB - S3C6400 calculates 4 bytes ECC in 1-bit mode */
131 #define CONFIG_SYS_NAND_ECCBYTES    (4)
132 //#define CONFIG_SYS_NAND_ECCBYTES      14
133
134 #define NAND_MC_BUFFER_SIZE         (24)
135 #define CONFIG_SYS_NAND_ECCSIZE     (512)
136 #define CONFIG_SYS_NAND_5_ADDR_CYCLE    5
137 #define SPRD_NAND_CLOCK (153)
138
139 #define IRQ_TIMEOUT  100//unit:ms,IRQ timeout value
140 #define DRIVER_NAME "sc8830_nand"
141
142
143 enum NAND_ERR_CORRECT_S {
144     NAND_FATAL_ERROR=0,
145     NAND_ERR_NEED_RETRY,
146     NAND_ERR_FIXED,
147     NAND_NO_ERROR
148 };
149
150 enum NAND_HANDLE_STATUS_S {
151     NAND_HANDLE_DONE=0,
152     NAND_HANDLE_TIMEOUT,
153     NAND_HANDLE_ERR
154 };
155
156 static enum NAND_HANDLE_STATUS_S  handle_status = NAND_HANDLE_DONE;
157 static enum NAND_ERR_CORRECT_S ret_irq_en = NAND_NO_ERROR;
158
159 STATIC_FUNC void nfc_enable_interrupt(void);
160 STATIC_FUNC void nfc_disable_interrupt(void);
161 STATIC_FUNC void nfc_clear_interrupt(void);
162
163
164 //#define NAND_IRQ_EN
165 #ifdef NAND_IRQ_EN
166 #include <linux/completion.h>
167 #include <mach/irqs.h>
168
169 static struct completion nfc_op_completion;
170 STATIC_FUNC void nfc_wait_op_done(void);
171 #endif
172
173
174 struct sprd_dolphin_nand_info {
175         struct mtd_info *mtd;
176         struct nand_chip *nand;
177
178         #ifdef DOLPHIN_UBOOT
179         struct device *pdev;
180         #endif
181
182         #ifdef DOLPHIN_KERNEL
183         struct platform_device *pdev;
184         #endif
185
186         struct sprd_nand_param *param;
187         uint32_t chip; //chip index
188         uint32_t v_mbuf; //virtual main buffer address
189         uint32_t p_mbuf; //phy main buffer address
190         uint32_t v_oob; // virtual oob buffer address
191         uint32_t p_oob; //phy oob buffer address
192         uint32_t page; //page address
193         uint16_t column; //column address
194         uint16_t oob_size;
195         uint16_t m_size; //main part size per sector
196         uint16_t s_size; //oob size per sector
197         uint8_t a_cycles;//address cycles, 3, 4, 5
198         uint8_t sct_pg; //sector per page
199         uint8_t info_pos;
200         uint8_t info_size;
201         uint8_t ecc_mode;//0-1bit, 1-2bit, 2-4bit, 3-8bit,4-12bit,5-16bit,6-24bit
202         uint8_t ecc_pos; // ecc postion
203         uint8_t wp_en; //write protect enable
204         uint16_t write_size;
205         uint16_t page_per_bl;//page per block
206         uint16_t  buf_head;
207         uint16_t _buf_tail;
208         uint8_t ins_num;//instruction number
209         uint32_t ins[NAND_MC_BUFFER_SIZE >> 1]; 
210 };
211
212
213 #define mtd_to_dolphin(m) (&g_dolphin)
214
215 //gloable variable 
216 static struct nand_ecclayout sprd_dolphin_nand_oob_default = {
217         .eccbytes = 0,
218         .eccpos = {0},
219         .oobfree = {
220                 {.offset = 2,
221                  .length = 46}}
222 };
223 struct sprd_dolphin_nand_info g_dolphin = {0};
224 //save the data read by read_byte and read_word api interface functon
225 static __attribute__((aligned(4))) uint8_t s_oob_data[NAND_MAX_OOBSIZE];
226 //static __attribute__((aligned(4))) uint8_t s_oob_data[8];
227 //static __attribute__((aligned(4))) uint8_t s_id_status[8];
228
229 STATIC_FUNC int sprd_dolphin_nand_read_id(struct sprd_dolphin_nand_info *dolphin, uint32_t *buf);
230 STATIC_FUNC int sprd_dolphin_nand_reset(struct sprd_dolphin_nand_info *dolphin);
231 STATIC_FUNC int sprd_dolphin_nand_wait_finish(struct sprd_dolphin_nand_info *dolphin); 
232
233 STATIC_FUNC uint32_t sprd_dolphin_reg_read(uint32_t addr)
234 {
235         return readl(addr);
236 }
237 STATIC_FUNC void sprd_dolphin_reg_write(uint32_t addr, uint32_t val)
238 {
239         writel(val, addr);
240 }
241 STATIC_FUNC void sprd_dolphin_reg_or(uint32_t addr, uint32_t val)
242 {
243         sprd_dolphin_reg_write(addr, sprd_dolphin_reg_read(addr) | val);
244 }
245 STATIC_FUNC void sprd_dolphin_reg_and(uint32_t addr, uint32_t mask)
246 {
247         sprd_dolphin_reg_write(addr, sprd_dolphin_reg_read(addr) & mask);
248 }
249 STATIC_FUNC void sprd_dolphin_nand_int_clr(uint32_t bit_clear)
250 {
251         sprd_dolphin_reg_write(NFC_INT_REG, bit_clear);
252 }
253
254 STATIC_FUNC void nfc_clear_interrupt(void)
255 {
256         uint32_t value = 0;
257         
258         value = ( INT_STSMCH_CLR | INT_WP_CLR | INT_TO_CLR | INT_DONE_CLR);
259         sprd_dolphin_reg_or(NFC_INT_REG, value); /* clear all interrupt status */
260
261         //value = NFC_CMD_CLR;
262         //sprd_dolphin_reg_or(NFC_START_REG, value); /* clear all interrupt status */
263 }
264
265 STATIC_FUNC void nfc_enable_interrupt(void)
266 {
267         uint32_t value = 0;
268         
269         value = (INT_TO_EN | INT_DONE_EN);
270         sprd_dolphin_reg_or(NFC_INT_REG, value); /* clear all interrupt status */
271 }
272
273 STATIC_FUNC void nfc_disable_interrupt(void)
274 {
275         uint32_t value = 0;
276         
277         value = ~(INT_TO_EN | INT_DONE_EN);
278         sprd_dolphin_reg_and(NFC_INT_REG, value); /* clear all interrupt status */
279 }
280
281 unsigned int ecc_mode_convert(uint32_t mode)
282 {
283         uint32_t mode_m;
284         switch(mode)
285         {
286         case 1:
287                 mode_m = 0;
288                 break;
289         case 2:
290                 mode_m = 1;
291                 break;
292         case 4:
293                 mode_m = 2;
294                 break;
295         case 8:
296                 mode_m = 3;
297                 break;
298         case 12:
299                 mode_m = 4;
300                 break;
301         case 16:
302                 mode_m = 5;
303                 break;
304         case 24:
305                 mode_m = 6;
306                 break;
307         case 40:
308                 mode_m = 7;
309                 break;
310         case 60:
311                 mode_m = 8;
312                 break;
313         default:
314                 mode_m = 0;
315                 break;
316         }
317         return mode_m;
318 }
319
320 STATIC_FUNC void dolphin_set_timing_config(struct sprd_nand_timing *timing  , uint32_t nfc_clk_MHz) {
321         u32 reg_val, temp_val;
322
323                 reg_val = 0;
324
325                 /* get acs value : 0ns */
326                 reg_val |= ((2 & 0x1F) << NFC_ACS_OFFSET);
327
328                 /* get ace value + 6ns read delay time, and rwl added */
329                 temp_val = (timing->ace_ns + 6) * nfc_clk_MHz / 1000;
330                 if (((timing->ace_ns * nfc_clk_MHz) % 1000)  != 0) {
331                         temp_val++;
332                 }
333                 reg_val |= ((temp_val & 0x1F) << NFC_ACE_OFFSET);
334
335                 /* get rws value : 20 ns */
336                 temp_val = 20 * nfc_clk_MHz / 1000;
337                 if (((timing->ace_ns * nfc_clk_MHz) % 1000)  != 0) {
338                         temp_val++;
339                 }
340                 reg_val |= ((temp_val & 0x3F) << NFC_RWS_OFFSET);
341
342                 /* get rws value : 0 ns */
343                 reg_val |= ((2 & 0x1F) << NFC_RWE_OFFSET);
344
345                 /* get rwh value */
346                 temp_val = (timing->rwh_ns + 6) * nfc_clk_MHz / 1000;
347                 if (((timing->ace_ns * nfc_clk_MHz) % 1000)  != 0) {
348                         temp_val++;
349                 }
350                 reg_val |= ((temp_val & 0x1F) << NFC_RWH_OFFSET);
351
352                 /* get rwl value, 6 is read delay time*/
353                 temp_val = (timing->rwl_ns + 6) * nfc_clk_MHz / 1000;
354                 if (((timing->ace_ns * nfc_clk_MHz) % 1000)  != 0) {
355                         temp_val++;
356                 }
357                 reg_val |= (temp_val & 0x3F);
358
359                 DPRINT("%s nand timing val: 0x%x\n\r", __func__, reg_val);
360
361                 sprd_dolphin_reg_write(NFC_TIMING_REG, reg_val);
362
363 }
364
365 #ifdef CONFIG_NAND_SPL
366 struct sprd_dolphin_boot_header_info {
367         uint32_t check_sum;
368         uint32_t sct_size; //
369         uint32_t acycle; // 3, 4, 5
370         uint32_t bus_width; //0 ,1
371         uint32_t spare_size; //spare part sise for one sector
372         uint32_t ecc_mode; //0--1bit, 1--2bit,2--4bit,3--8bit,4--12bit, 5--16bit, 6--24bit
373         uint32_t ecc_pos; // ecc postion at spare part
374         uint32_t sct_per_page; //sector per page
375         uint32_t info_pos;
376         uint32_t info_size;
377         uint32_t magic_num; //0xaa55a5a5        
378         uint32_t ecc_value[27];
379 };
380 void boad_nand_param_init(struct sprd_dolphin_nand_info *dolphin, struct nand_chip *chip, uint8 *id)
381 {
382         int extid;
383         uint32_t writesize;
384         uint32_t oobsize;
385         uint32_t erasesize;
386         uint32_t busw;
387         
388         /* The 4th id byte is the important one */
389         extid = id[3];
390         writesize = 1024 << (extid & 0x3);
391         extid >>= 2;
392         /* Calc oobsize */
393         oobsize = (8 << (extid & 0x01)) * (writesize >> 9);
394         extid >>= 2;
395         /* Calc blocksize. Blocksize is multiples of 64KiB */
396         erasesize = (64 * 1024) << (extid & 0x03);
397         extid >>= 2;
398         /* Get buswidth information */
399         busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
400         dolphin->write_size = writesize;
401         dolphin->m_size =CONFIG_SYS_NAND_ECCSIZE;
402         dolphin->sct_pg = writesize / CONFIG_SYS_NAND_ECCSIZE;
403         dolphin->s_size = oobsize / dolphin->sct_pg;
404         dolphin->ecc_mode = ecc_mode_convert(CONFIG_SYS_NAND_ECC_MODE);
405         dolphin->ecc_pos = dolphin->s_size - ((14 * CONFIG_SYS_NAND_ECC_MODE + 7) / 8);
406         dolphin->info_pos = dolphin->ecc_pos - 1;
407         dolphin->info_size = 1;
408         dolphin->page_per_bl = erasesize / dolphin->write_size;
409         dolphin->a_cycles = CONFIG_SYS_NAND_5_ADDR_CYCLE;
410         if(NAND_BUSWIDTH_16 == busw)
411         {
412                 chip->options |= NAND_BUSWIDTH_16;
413         }
414         else
415         {
416                 chip->options &= ~NAND_BUSWIDTH_16;
417         }
418 }
419
420 /*
421  * because the dolphin firmware use the nand identify process
422  * and the data at the header of nand_spl is the nand param used at nand read and write,
423  * so in nand_spl, don't need read the id or use the onfi spec to calculate the nand param,
424  * just use the param at the nand_spl header instead of
425  */
426 void nand_hardware_config(struct mtd_info *mtd, struct nand_chip *chip)
427 {
428         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
429         struct sprd_nand_param* param;
430         struct sprd_nand_oob* oob;
431         struct sprd_nand_timing* timing;
432
433         uint8 *id;
434         sprd_dolphin_nand_reset(dolphin);
435         mdelay(1);
436         sprd_dolphin_nand_read_id(dolphin, (uint32_t *)s_oob_data);
437         boad_nand_param_init(dolphin, dolphin->nand, s_oob_data);
438         id = s_oob_data;
439         
440         param = SprdGetNandParam(id);
441
442         if (param != NULL) {
443                 dolphin->param = param;
444                 oob = &param->sOOB;
445                 timing = &param->sTiming;
446                 
447                 dolphin_set_timing_config(timing, SPRD_NAND_CLOCK);
448                 
449                 //save the param config
450                 dolphin->write_size = param->nPageSize;
451                 dolphin->page_per_bl = param->nBlkSize / param->nPageSize;
452                 dolphin->m_size = param->nSecSize;
453                 dolphin->sct_pg = (param->nPageSize / param->nSecSize);
454                 dolphin->oob_size = param->nSpareSize;
455                 dolphin->a_cycles = param->nCycles;
456                 
457                 dolphin->s_size = oob->nOOBSize;
458                 dolphin->info_pos = oob->nInfoPos;
459                 dolphin->info_size = oob->nInfoSize;
460                 dolphin->ecc_pos = oob->nEccPos;
461                 dolphin->ecc_mode = ecc_mode_convert(oob->nEccBits);
462                 dolphin->nand=chip;
463                 dolphin->mtd = mtd;
464
465                 chip->ecc.bytes  = (oob->nEccBits * 14 + 7) / 8;
466 #ifdef DOLPHIN_UBOOT
467                 chip->eccbitmode = oob->nEccBits;
468 #endif
469                 if(param->nBusWidth)
470                 {
471                         chip->options |= NAND_BUSWIDTH_16;
472                 }
473                 else
474                 {
475                         chip->options &= ~NAND_BUSWIDTH_16;
476                 }
477         }
478         mtd->writesize = dolphin->write_size;
479         mtd->oobsize = dolphin->s_size * dolphin->sct_pg;
480         mtd->erasesize = dolphin->page_per_bl * dolphin->write_size;
481 }
482
483 #else 
484
485 STATIC_FUNC void sprd_dolphin_nand_ecc_layout_gen(struct sprd_nand_oob *oob, uint8_t sector_num, struct nand_ecclayout *layout)
486 {
487         uint8_t sct = 0;
488         uint32_t i = 0;
489         uint32_t offset;
490         uint32_t used_len ; //one sector ecc data size(byte)
491         uint32_t eccbytes = 0; //one page ecc data size(byte)
492         uint32_t oobfree_len = 0;
493
494         used_len = (14 * oob->nEccBits + 7) / 8 + oob->nInfoSize;
495         if(sector_num > ARRAY_SIZE(layout->oobfree))
496         {
497                 while(1);
498         }
499         for(sct = 0; sct < sector_num; sct++)
500         {
501                 //offset = (oob_size * sct) + ecc_pos;
502                 //for(i = 0; i < ecc_len; i++)
503                 offset = (oob->nOOBSize * sct) + oob->nEccPos;
504                 for(i = 0; i < used_len; i++)
505                 {
506                         layout->eccpos[eccbytes++] = offset + i;
507                 }
508                 layout->oobfree[sct].offset = oob->nOOBSize * sct;
509                 layout->oobfree[sct].length = oob->nOOBSize - used_len ;
510                 oobfree_len += oob->nOOBSize - used_len;
511         }
512         //for bad mark postion
513         layout->oobfree[0].offset = 2;
514         layout->oobfree[0].length = oob->nOOBSize - used_len - 2;
515         oobfree_len -= 2;
516         layout->eccbytes = used_len * sector_num;
517 }
518
519 void nand_hardware_config(struct mtd_info *mtd, struct nand_chip *chip, uint8_t id[5])
520 {
521         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
522         struct sprd_nand_param* param;
523         struct sprd_nand_oob* oob;
524         struct sprd_nand_timing* timing;
525         
526         param = SprdGetNandParam(id);
527
528         if (param != NULL) {
529                 dolphin->param = param;
530                 oob = &param->sOOB;
531                 timing = &param->sTiming;
532                 
533                 dolphin_set_timing_config(timing, SPRD_NAND_CLOCK);
534                 
535                 //save the param config
536                 dolphin->write_size = param->nPageSize;
537                 dolphin->page_per_bl = param->nBlkSize / param->nPageSize;
538                 dolphin->m_size = param->nSecSize;
539                 dolphin->sct_pg = (param->nPageSize / param->nSecSize);
540                 dolphin->oob_size = param->nSpareSize;
541                 dolphin->a_cycles = param->nCycles;
542                 
543                 dolphin->s_size = oob->nOOBSize;
544                 dolphin->info_pos = oob->nInfoPos;
545                 dolphin->info_size = oob->nInfoSize;
546                 dolphin->ecc_pos = oob->nEccPos;
547                 dolphin->ecc_mode = ecc_mode_convert(oob->nEccBits);
548                 dolphin->nand=chip;
549                 dolphin->mtd = mtd;
550
551                 chip->ecc.bytes  = (oob->nEccBits * 14 + 7) / 8;
552 #ifdef DOLPHIN_UBOOT
553                 chip->eccbitmode = oob->nEccBits;
554 #endif
555                 if(param->nBusWidth)
556                 {
557                         chip->options |= NAND_BUSWIDTH_16;
558                 }
559                 else
560                 {
561                         chip->options &= ~NAND_BUSWIDTH_16;
562                 }
563
564                 /* Calculate the address shift from the page size */
565                 chip->page_shift = ffs(mtd->writesize) - 1;
566                 /* Convert chipsize to number of pages per chip -1. */
567                 chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
568                 sprd_dolphin_nand_ecc_layout_gen(oob, dolphin->sct_pg, &sprd_dolphin_nand_oob_default);
569                 chip->ecc.layout = &sprd_dolphin_nand_oob_default;
570
571                 mtd->writesize = dolphin->write_size;
572                 mtd->oobsize = dolphin->oob_size;
573                 mtd->erasesize = dolphin->page_per_bl * dolphin->write_size;
574         }
575         else {
576                 int steps;
577                 struct sprd_nand_oob oob_tmp;
578                 
579                 //save the param config
580                 steps = mtd->writesize / CONFIG_SYS_NAND_ECCSIZE;
581                 dolphin->ecc_mode = ecc_mode_convert(CONFIG_SYS_NAND_ECC_MODE);
582                 dolphin->m_size = CONFIG_SYS_NAND_ECCSIZE;
583                 dolphin->s_size = mtd->oobsize / steps;
584                 dolphin->a_cycles = mtd->writesize / CONFIG_SYS_NAND_ECCSIZE;
585                 dolphin->sct_pg = steps;
586                 dolphin->info_pos = dolphin->s_size - CONFIG_SYS_NAND_ECCBYTES - 1;
587                 dolphin->info_size = 1;
588                 dolphin->write_size = mtd->writesize;
589                 dolphin->page_per_bl = mtd->erasesize / mtd->writesize;
590                 dolphin->oob_size = mtd->oobsize;
591                 dolphin->ecc_pos = dolphin->s_size - CONFIG_SYS_NAND_ECCBYTES;
592                 dolphin->mtd = mtd;
593
594                 oob_tmp.nOOBSize = dolphin->s_size;
595                 oob_tmp.nInfoPos = dolphin->info_pos;
596                 oob_tmp.nInfoSize = dolphin->info_size;
597                 oob_tmp.nEccPos = dolphin->ecc_pos;
598                 oob_tmp.nEccBits = CONFIG_SYS_NAND_ECC_MODE;
599                 sprd_dolphin_nand_ecc_layout_gen(&oob_tmp, dolphin->sct_pg, &sprd_dolphin_nand_oob_default);
600
601                 chip->ecc.layout = &sprd_dolphin_nand_oob_default;
602 #ifdef DOLPHIN_UBOOT
603                 chip->eccbitmode = CONFIG_SYS_NAND_ECC_MODE;
604 #endif
605                 if(chip->chipsize > (128 << 20)) {
606                         dolphin->a_cycles = 5;
607                 }
608                 else {
609                         dolphin->a_cycles = 4;
610                 }
611         }
612 }
613
614 #endif  //end CONFIG_NAND_SPL
615
616
617
618 #ifdef DOLPHIN_UBOOT
619 #ifndef CONFIG_NAND_SPL
620 typedef struct {
621         uint8_t *m_buf;
622         uint8_t *s_buf;
623         uint8_t m_sct;
624         uint8_t s_sct;
625         uint8_t dir; //if dir is 0, read dadta from NFC buffer, if 1, write data to NFC buffer
626         uint16_t m_size;
627         uint16_t s_size;
628 } sprd_dolphin_nand_data_param;
629
630 STATIC_FUNC unsigned int sprd_dolphin_data_trans(sprd_dolphin_nand_data_param *param)
631 {
632         uint32_t cfg0 = 0;
633         uint32_t cfg1 = 0;
634         uint32_t cfg2 = 0;
635         cfg0 = NFC_ONLY_MST_MODE | MAIN_SPAR_APT | NFC_WPN;
636         if(param->dir)
637         {
638                 cfg0 |= NFC_RW;
639         }
640         if(param->m_sct != 0)
641         {
642                 cfg0 |= (param->m_sct - 1) << SECTOR_NUM_OFFSET;
643                 cfg0 |= MAIN_USE;
644                 cfg1 |= (param->m_size - 1);
645                 sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, (uint32_t)param->m_buf);
646         }
647         if(param->s_sct != 0)
648         {
649                 cfg0 |= SPAR_USE;
650                 cfg1 |= (param->s_size - 1) << SPAR_SIZE_OFFSET;
651                 cfg2 |= (param->s_sct - 1) << SPAR_SECTOR_NUM_OFFSET;
652                 sprd_dolphin_reg_write(NFC_SPAR_ADDR_REG, (uint32_t)param->s_buf);
653         }
654         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
655         sprd_dolphin_reg_write(NFC_CFG1_REG, cfg1);
656         sprd_dolphin_reg_write(NFC_CFG2_REG, cfg2);
657         sprd_dolphin_nand_int_clr(INT_STSMCH_CLR | INT_WP_CLR | INT_TO_CLR | INT_DONE_CLR);//clear all interrupt
658         sprd_dolphin_reg_write(NFC_START_REG, NFC_START);
659         sprd_dolphin_nand_wait_finish(&g_dolphin);
660         return 0;
661 }
662 void sprd_ecc_ctrl(struct sprd_ecc_param *param, uint32_t dir)
663 {
664         uint32_t cfg0 = 0;
665         uint32_t cfg1 = 0;
666         uint32_t cfg2 = 0;
667         cfg0 = NFC_ONLY_ECC_MODE | MAIN_SPAR_APT;
668         if(dir)
669         {
670                 cfg0 |= NFC_RW;
671         }
672         cfg1 |=(param->sinfo_size - 1) << SPAR_INFO_SIZE_OFFSET;
673         cfg1 |=(param->sp_size - 1) << SPAR_SIZE_OFFSET;
674         cfg1 |= (param->m_size - 1);
675         
676         cfg2 |= (param->sinfo_pos)<< SPAR_INFO_POS_OFFSET;
677         cfg2 |= ecc_mode_convert(param->mode) << ECC_MODE_OFFSET;
678         cfg2 |= param->ecc_pos;
679         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
680         sprd_dolphin_reg_write(NFC_CFG1_REG, cfg1);
681         sprd_dolphin_reg_write(NFC_CFG2_REG, cfg2);
682         sprd_dolphin_nand_int_clr(INT_STSMCH_CLR | INT_WP_CLR | INT_TO_CLR | INT_DONE_CLR);//clear all interrupt
683         sprd_dolphin_reg_write(NFC_START_REG, NFC_START);
684         sprd_dolphin_nand_wait_finish(&g_dolphin);
685 }
686
687 unsigned int sprd_ecc_encode(struct sprd_ecc_param *param)
688 {
689         struct sprd_dolphin_nand_info *dolphin;
690         sprd_dolphin_nand_data_param d_param;
691
692         dolphin = &g_dolphin;
693         memset(&d_param, 0, sizeof(d_param));
694
695         d_param.m_buf = param->p_mbuf;
696         d_param.s_buf = param->p_sbuf;
697         d_param.m_sct = param->ecc_num;
698         d_param.s_sct = param->ecc_num;
699         d_param.dir = 1;
700         d_param.m_size = param->m_size;
701         d_param.s_size = param->sp_size;
702
703         Dcache_CleanRegion((unsigned int)d_param.m_buf, d_param.m_sct*d_param.m_size);
704         Dcache_CleanRegion((unsigned int)d_param.s_buf, d_param.s_sct*d_param.s_size);
705
706         sprd_dolphin_data_trans(&d_param);
707         sprd_ecc_ctrl(param, 1);
708         d_param.dir = 0;
709         d_param.m_sct = 0;
710
711         Dcache_InvalRegion((unsigned int)d_param.m_buf , d_param.m_sct*d_param.m_size);
712         Dcache_InvalRegion((unsigned int)d_param.s_buf , d_param.s_sct*d_param.s_size);
713
714         sprd_dolphin_data_trans(&d_param); //read the ecc value from nfc buffer
715         return 0;
716 }
717 #endif  //CONFIG_NAND_SPL end
718 #endif  //DOLPHIN_UBOOT END
719
720
721
722 //add one macro instruction to nand controller
723 STATIC_FUNC void sprd_dolphin_nand_ins_init(struct sprd_dolphin_nand_info *dolphin)
724 {
725         dolphin->ins_num = 0;
726 }
727 STATIC_FUNC void sprd_dolphin_nand_ins_add(uint16_t ins, struct sprd_dolphin_nand_info *dolphin)
728 {
729         uint16_t *buf = (uint16_t *)dolphin->ins;
730         if(dolphin->ins_num >= NAND_MC_BUFFER_SIZE)
731         {
732                 while(1);
733         }
734         *(buf + dolphin->ins_num) = ins;
735         dolphin->ins_num++;
736 }
737
738 STATIC_FUNC void sprd_dolphin_nand_ins_exec(struct sprd_dolphin_nand_info *dolphin)
739 {
740         uint32_t i;
741         uint32_t cfg0;
742         
743         for(i = 0; i < ((dolphin->ins_num + 1) >> 1); i++)
744         {
745                 sprd_dolphin_reg_write(NFC_INST0_REG + (i << 2), dolphin->ins[i]);
746         }
747         cfg0 = sprd_dolphin_reg_read(NFC_CFG0_REG);
748         if(dolphin->wp_en)
749         {
750                 cfg0 &= ~NFC_WPN;
751         }
752         else
753         {
754                 cfg0 |= NFC_WPN;
755         }
756         if(dolphin->chip)
757         {
758                 cfg0 |= CS_SEL;
759         }
760         else
761         {
762                 cfg0 &= ~CS_SEL;
763         }
764         sprd_dolphin_nand_int_clr(INT_STSMCH_CLR | INT_WP_CLR | INT_TO_CLR | INT_DONE_CLR);//clear all interrupt
765         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
766         sprd_dolphin_reg_write(NFC_START_REG, NFC_START);
767 }
768
769 STATIC_FUNC int sprd_dolphin_nand_wait_finish(struct sprd_dolphin_nand_info *dolphin)
770 {
771         unsigned int value;
772         unsigned int counter = 0;
773         while((counter < NFC_TIMEOUT_VAL/*time out*/))
774         {
775                 value = sprd_dolphin_reg_read(NFC_INT_REG);
776                 if(value & INT_DONE_RAW)
777                 {
778                         break;
779                 }
780                 counter ++;
781         }
782         sprd_dolphin_reg_write(NFC_INT_REG, 0xf00); //clear all interrupt status
783         if(counter >= NFC_TIMEOUT_VAL)
784         {
785         //while (1);
786                 return -1;
787         }
788         return 0;
789 }
790
791 STATIC_FUNC void sprd_dolphin_nand_wp_en(struct sprd_dolphin_nand_info *dolphin, int en)
792 {
793         if(en)
794         {
795                 dolphin->wp_en = 1;
796         }
797         else
798         {
799                 dolphin->wp_en = 0;
800         }
801 }
802 STATIC_FUNC void sprd_dolphin_select_chip(struct mtd_info *mtd, int chip)
803 {
804         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
805         if(chip < 0) { //for release caller
806                 return;
807         }
808         //DPRINT("sprd_dolphin_select_chip, %x\r\n", chip);
809         dolphin->chip = chip;
810 #ifdef CONFIG_NAND_SPL
811         nand_hardware_config(mtd,dolphin->nand);
812 #endif
813 }
814
815 STATIC_FUNC void sprd_dolphin_nand_read_status(struct sprd_dolphin_nand_info *dolphin)
816 {
817         uint32_t *buf;
818     //DPRINT("%s enter\n", __func__);
819
820         sprd_dolphin_nand_ins_init(dolphin);
821         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_STATUS), dolphin);
822         sprd_dolphin_nand_ins_add(NAND_MC_NOP(10), dolphin);
823         sprd_dolphin_nand_ins_add(NAND_MC_IDST(1), dolphin);
824         sprd_dolphin_nand_ins_add(NFC_MC_DONE_ID, dolphin);
825         sprd_dolphin_reg_write(NFC_CFG0_REG, NFC_ONLY_NAND_MODE);
826         sprd_dolphin_nand_ins_exec(dolphin);
827         sprd_dolphin_nand_wait_finish(dolphin);
828         buf = (uint32_t *)s_oob_data;
829         *buf = sprd_dolphin_reg_read(NFC_STATUS0_REG);
830         dolphin->buf_head = 0;
831         dolphin->_buf_tail = 1;
832
833     //DPRINT("%s leave\n", __func__);
834 }
835 STATIC_FUNC int sprd_dolphin_nand_read_id(struct sprd_dolphin_nand_info *dolphin, uint32_t *buf)
836 {
837     //DPRINT("%s enter\n", __func__);
838         
839         sprd_dolphin_nand_ins_init(dolphin);
840         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_READID), dolphin);
841         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(0), dolphin);
842         sprd_dolphin_nand_ins_add(NAND_MC_NOP(10), dolphin);
843         sprd_dolphin_nand_ins_add(NAND_MC_IDST(8), dolphin);
844         sprd_dolphin_nand_ins_add(NFC_MC_DONE_ID, dolphin);
845         
846         sprd_dolphin_reg_write(NFC_CFG0_REG, NFC_ONLY_NAND_MODE);
847         sprd_dolphin_nand_ins_exec(dolphin);
848         if (sprd_dolphin_nand_wait_finish(dolphin) != 0)
849     {
850         return -1;
851     }
852         *buf = sprd_dolphin_reg_read(NFC_STATUS0_REG);
853         *(buf + 1) = sprd_dolphin_reg_read(NFC_STATUS1_REG);
854         dolphin->buf_head = 0;
855         dolphin->_buf_tail = 8;
856
857     //DPRINT("%s leave\n", __func__);
858
859     return 0;
860 }
861 STATIC_FUNC int sprd_dolphin_nand_reset(struct sprd_dolphin_nand_info *dolphin)
862 {
863     //DPRINT("%s enter\n", __func__);
864
865         sprd_dolphin_nand_ins_init(dolphin);
866         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_RESET), dolphin);
867         sprd_dolphin_nand_ins_add(NFC_MC_WRB0_ID, dolphin); //wait rb
868         sprd_dolphin_nand_ins_add(NFC_MC_DONE_ID, dolphin);
869         //config register
870         sprd_dolphin_reg_write(NFC_CFG0_REG, NFC_ONLY_NAND_MODE);
871         sprd_dolphin_nand_ins_exec(dolphin);
872         if (sprd_dolphin_nand_wait_finish(dolphin) != 0)
873     {
874         return 0;
875     }
876
877     //DPRINT("%s leave\n", __func__);
878
879     return 0;
880 }
881 STATIC_FUNC u32 sprd_dolphin_get_decode_sts(u32 index)
882 {
883         uint32_t err;
884         uint32_t shift;
885         uint32_t reg_addr;
886         reg_addr = NFC_STATUS0_REG + (index & 0xfffffffc);
887         shift = (index & 0x3) << 3;
888         err = sprd_dolphin_reg_read(reg_addr);
889         err >>= shift;
890         if((err & ECC_ALL_FF))
891         {
892                 err &= ERR_ERR_NUM0_MASK;
893         }
894         else
895         {
896                 err = 0;
897         }
898         return err;
899 }
900
901
902 #ifdef DOLPHIN_UBOOT
903 //read large page
904 STATIC_FUNC int sprd_dolphin_nand_read_lp(struct mtd_info *mtd,uint8_t *mbuf, uint8_t *sbuf,uint32_t raw)
905 {
906         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
907         struct nand_chip *chip = dolphin->nand;
908         uint32_t column;
909         uint32_t page_addr;
910         uint32_t cfg0;
911         uint32_t cfg1;
912         uint32_t cfg2;
913         uint32_t i;
914         uint32_t err;
915         int size = 0 ,sct_size;
916         int ret  = 0;
917         uint8_t ecc_bit=0 ;
918         int num  =0 ;
919         page_addr = dolphin->page;
920         
921         if(sbuf) {
922                 column = mtd->writesize;
923         }
924         else
925         {
926                 column = 0;
927         }
928         if(chip->options & NAND_BUSWIDTH_16)
929         {
930                 column >>= 1;
931         }
932         //DPRINT("sprd_dolphin_nand_read_lp,page_addr = %x,column = %x\r\n",page_addr, column);
933         sprd_dolphin_nand_ins_init(dolphin);
934         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_READ0), dolphin);
935         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(column & 0xff), dolphin);
936         column >>= 8;
937         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(column & 0xff), dolphin);
938
939         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
940         page_addr >>= 8;
941         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
942         
943         if (5 == dolphin->a_cycles)// five address cycles
944         {
945                 page_addr >>= 8;
946                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
947         }
948         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_READSTART), dolphin);
949         
950         sprd_dolphin_nand_ins_add(NFC_MC_WRB0_ID, dolphin); //wait rb
951         if(mbuf && sbuf)
952         {
953                 sprd_dolphin_nand_ins_add(NAND_MC_SRDT, dolphin);
954                 //switch to main part
955                 sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_RNDOUT), dolphin);
956                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(0), dolphin);
957                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(0), dolphin);
958                 sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_RNDOUTSTART), dolphin);
959                 sprd_dolphin_nand_ins_add(NAND_MC_MRDT, dolphin);
960         }
961         else
962         {
963                 sprd_dolphin_nand_ins_add(NAND_MC_MRDT, dolphin);
964         }
965         sprd_dolphin_nand_ins_add(NFC_MC_DONE_ID, dolphin);
966         //config registers 
967         cfg0 = NFC_AUTO_MODE | MAIN_SPAR_APT | ((dolphin->sct_pg - 1)<< SECTOR_NUM_OFFSET);
968         if((!raw) && mbuf && sbuf)
969         {
970                 cfg0 |= ECC_EN | DETECT_ALL_FF;
971         }
972         if(chip->options & NAND_BUSWIDTH_16)
973         {
974                 cfg0 |= BUS_WIDTH;
975         }
976         cfg1 = (dolphin->info_size) << SPAR_INFO_SIZE_OFFSET;
977         cfg2 = (dolphin->ecc_mode << 12) | (dolphin->info_pos << SPAR_INFO_POS_OFFSET) | ((dolphin->sct_pg - 1) << SPAR_SECTOR_NUM_OFFSET) | dolphin->ecc_pos;
978
979 #ifndef CONFIG_NAND_SPL
980         if (mbuf)
981         {
982                 Dcache_CleanRegion((unsigned int)mbuf, dolphin->m_size*dolphin->sct_pg);
983                 Dcache_InvalRegion((unsigned int)mbuf, dolphin->m_size*dolphin->sct_pg);
984         }
985
986         if (sbuf)
987         {
988                 Dcache_CleanRegion((unsigned int)sbuf, dolphin->s_size*dolphin->sct_pg);
989                 Dcache_InvalRegion((unsigned int)sbuf, dolphin->s_size*dolphin->sct_pg);
990         }
991 #endif
992
993         if(mbuf && sbuf)
994         {
995                 cfg1 |= (dolphin->m_size - 1) | ((dolphin->s_size  - 1)<< SPAR_SIZE_OFFSET);
996                 sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, (uint32_t)mbuf);
997                 sprd_dolphin_reg_write(NFC_SPAR_ADDR_REG, (uint32_t)sbuf);
998                 cfg0 |= MAIN_USE | SPAR_USE;
999         }
1000         else
1001         {
1002                 if(mbuf)
1003                 {
1004                         cfg1 |= (dolphin->m_size - 1);
1005                         sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, (uint32_t)mbuf);
1006                 }
1007                 if(sbuf)
1008                 {
1009                         cfg1 |= (dolphin->s_size - 1);
1010                         sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, (uint32_t)sbuf);
1011                 }
1012                 cfg0 |= MAIN_USE;
1013         }       
1014         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
1015         sprd_dolphin_reg_write(NFC_CFG1_REG, cfg1);
1016         sprd_dolphin_reg_write(NFC_CFG2_REG, cfg2);
1017         
1018         sprd_dolphin_nand_ins_exec(dolphin);
1019         sprd_dolphin_nand_wait_finish(dolphin);
1020         if(!raw) {
1021                 for(i = 0; i < dolphin->sct_pg; i++) {
1022                         err = sprd_dolphin_get_decode_sts(i);
1023                         if(err == ERR_ERR_NUM0_MASK) {
1024                             ret = 0;
1025                             ecc_bit = 0;
1026                             size = dolphin->s_size * (i+1);
1027                             sct_size = dolphin->s_size;
1028                             while(sct_size--){
1029                                 if(sbuf[--size] != 0xFF){
1030                                     DPRINT("%s spare area bif flip 0x%x\n",__func__, sbuf[size]);
1031                                     for(num=0; num<8; num++){
1032                                         if(!(sbuf[size]>>num & 0x1)){
1033                                             ecc_bit++;
1034                                             if(ecc_bit > chip->eccbitmode){
1035                                                 ret = -1;
1036                                                 DPRINT("%s spare area ecc check err\n",__func__);
1037                                                 break;
1038                                             }
1039                                         }
1040                                     }
1041                                     if(ret<0){
1042                                         mtd->ecc_stats.failed++;
1043                                         break;
1044                                     }
1045                                     sbuf[size]=0xff;
1046                                 }
1047                             }
1048                             if(!ret){
1049                                 size = dolphin->m_size*(i+1) ;
1050                                 sct_size = dolphin->m_size ;
1051                                 while(sct_size--){
1052                                     if(mbuf[--size] != 0xFF){
1053                                         DPRINT("%s main area bif flip 0x%x\n",__func__, mbuf[size]);
1054                                         for(num = 0 ; num < 8 ; num++){
1055                                             if(!(mbuf[size]>>num & 0x1) ){
1056                                                 ecc_bit++;
1057                                             }
1058                                             if(ecc_bit > chip->eccbitmode){
1059                                                 ret = -1;
1060                                                 DPRINT("%s main+spare area ecc check err\n",__func__);
1061                                                 break;
1062                                             }
1063                                         }
1064                                     }
1065                                     if(ret<0){
1066                                         mtd->ecc_stats.failed++;
1067                                         break;
1068                                     }
1069                                     mbuf[size] = 0xff;
1070                                 }
1071                             }
1072                         }
1073                         else {
1074                                 mtd->ecc_stats.corrected += err;
1075                         }
1076                 }
1077         }
1078
1079         return 0;
1080 }
1081
1082
1083 STATIC_FUNC int sprd_dolphin_nand_write_lp(struct mtd_info *mtd,const uint8_t *mbuf, uint8_t *sbuf,uint32_t raw)
1084 {
1085         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1086         struct nand_chip *chip = dolphin->nand;
1087         uint32_t column;
1088         uint32_t page_addr;
1089         uint32_t cfg0;
1090         uint32_t cfg1;
1091         uint32_t cfg2;
1092         page_addr = dolphin->page;
1093         if(mbuf) {
1094                 column = 0;
1095         }
1096         else {
1097                 column = mtd->writesize;
1098         }       
1099         if(chip->options & NAND_BUSWIDTH_16)
1100         {
1101                 column >>= 1;
1102         }
1103
1104         sprd_dolphin_nand_ins_init(dolphin);
1105         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_SEQIN), dolphin);
1106         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(column & 0xff), dolphin);
1107         column >>= 8;
1108         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(column & 0xff), dolphin);
1109         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1110         page_addr >>= 8;
1111         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1112         
1113         if (5 == dolphin->a_cycles)// five address cycles
1114         {
1115                 page_addr >>= 8;
1116                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1117         }
1118         
1119         sprd_dolphin_nand_ins_add(NAND_MC_MWDT, dolphin);
1120         if(mbuf && sbuf)
1121         {
1122                 sprd_dolphin_nand_ins_add(NAND_MC_SWDT, dolphin);
1123         }
1124         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_PAGEPROG), dolphin);
1125         sprd_dolphin_nand_ins_add(NFC_MC_WRB0_ID, dolphin); //wait rb
1126
1127         sprd_dolphin_nand_ins_add(NFC_MC_DONE_ID, dolphin);
1128         //config registers 
1129         cfg0 = NFC_AUTO_MODE | NFC_RW |  NFC_WPN | MAIN_SPAR_APT | ((dolphin->sct_pg - 1)<< SECTOR_NUM_OFFSET);
1130         if((!raw) && mbuf && sbuf)
1131         {
1132                 cfg0 |= ECC_EN;
1133         }
1134         if(chip->options & NAND_BUSWIDTH_16)
1135         {
1136                 cfg0 |= BUS_WIDTH;
1137         }
1138         cfg1 = ((dolphin->info_size) << SPAR_INFO_SIZE_OFFSET);
1139         cfg2 = (dolphin->ecc_mode << 12) | (dolphin->info_pos << SPAR_INFO_POS_OFFSET) | ((dolphin->sct_pg - 1) << SPAR_SECTOR_NUM_OFFSET) | dolphin->ecc_pos;
1140
1141 #ifndef CONFIG_NAND_SPL
1142         if (mbuf)
1143         {
1144                 Dcache_CleanRegion((unsigned int)mbuf, dolphin->m_size*dolphin->sct_pg);
1145                 Dcache_InvalRegion((unsigned int)mbuf, dolphin->m_size*dolphin->sct_pg);
1146         }
1147
1148         if (sbuf)
1149         {
1150                 Dcache_CleanRegion((unsigned int)sbuf, dolphin->s_size*dolphin->sct_pg);
1151                 Dcache_InvalRegion((unsigned int)sbuf, dolphin->s_size*dolphin->sct_pg);
1152         }
1153 #endif
1154
1155         if(mbuf && sbuf)
1156         {
1157                 cfg0 |= MAIN_USE | SPAR_USE;
1158                 cfg1 |= (dolphin->m_size - 1) | ((dolphin->s_size - 1) << SPAR_SIZE_OFFSET);
1159                 sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, (uint32_t)mbuf);
1160                 sprd_dolphin_reg_write(NFC_SPAR_ADDR_REG, (uint32_t)sbuf);
1161         }
1162         else
1163         {
1164                 cfg0 |= MAIN_USE;
1165                 if(mbuf)
1166                 {
1167                         cfg1 |= dolphin->m_size - 1;
1168                         sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, (uint32_t)mbuf);
1169                 }
1170                 else
1171                 {
1172                         cfg1 |= dolphin->s_size - 1;
1173                         sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, (uint32_t)sbuf);
1174                 }
1175         }
1176         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
1177         sprd_dolphin_reg_write(NFC_CFG1_REG, cfg1);
1178         sprd_dolphin_reg_write(NFC_CFG2_REG, cfg2);
1179         sprd_dolphin_nand_ins_exec(dolphin);
1180         sprd_dolphin_nand_wait_finish(dolphin);
1181         return 0;
1182 }
1183 #endif
1184
1185
1186
1187 #ifdef DOLPHIN_KERNEL
1188
1189 #ifdef  NAND_IRQ_EN
1190 STATIC_FUNC void sprd_dolphin_nand_ins_exec_irq(struct sprd_dolphin_nand_info *dolphin)
1191 {
1192         uint32_t i;
1193         uint32_t cfg0;
1194         uint32_t value = 0;
1195         
1196     //DPRINT("%s enter\n", __func__);
1197
1198         for(i = 0; i < ((dolphin->ins_num + 1) >> 1); i++)
1199         {
1200                 sprd_dolphin_reg_write(NFC_INST0_REG + (i << 2), dolphin->ins[i]);
1201         }
1202         cfg0 = sprd_dolphin_reg_read(NFC_CFG0_REG);
1203         if(dolphin->wp_en)
1204         {
1205                 cfg0 &= ~NFC_WPN;
1206         }
1207         else
1208         {
1209                 cfg0 |= NFC_WPN;
1210         }
1211         if(dolphin->chip)
1212         {
1213                 cfg0 |= CS_SEL;
1214         }
1215         else
1216         {
1217                 cfg0 &= ~CS_SEL;
1218         }
1219         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
1220
1221         nfc_clear_interrupt();
1222         nfc_enable_interrupt();
1223
1224         sprd_dolphin_reg_write(NFC_START_REG, NFC_START);
1225
1226     //DPRINT("%s leave\n", __func__);
1227 }
1228
1229 STATIC_FUNC int sprd_dolphin_nand_wait_finish_irq(struct sprd_dolphin_nand_info *dolphin)
1230 {
1231         unsigned int value;
1232         unsigned int counter = 0;
1233         
1234     //DPRINT("%s enter\n", __func__);
1235
1236         nfc_wait_op_done();
1237         if(handle_status==NAND_HANDLE_DONE)
1238         {
1239                         ret_irq_en=NAND_NO_ERROR;
1240                 }
1241                 else if(handle_status==NAND_HANDLE_TIMEOUT)
1242                 {
1243                         ret_irq_en=NAND_ERR_NEED_RETRY;
1244                 }
1245                 else if(handle_status==NAND_HANDLE_ERR)
1246                 {
1247                         ret_irq_en=NAND_ERR_NEED_RETRY;
1248                 }
1249
1250     //DPRINT("%s leave\n", __func__);
1251
1252         return 0;
1253 }
1254
1255 STATIC_FUNC void nfc_wait_op_done(void)
1256 {
1257         if (!wait_for_completion_timeout(&nfc_op_completion, msecs_to_jiffies(IRQ_TIMEOUT)))
1258         {
1259                 handle_status=NAND_HANDLE_ERR;
1260                 DPRINT(KERN_ERR "%s, wait irq timeout\n", __func__);
1261     }
1262 }
1263
1264 STATIC_FUNC irqreturn_t nfc_irq_handler(int irq, void *dev_id)
1265 {
1266         unsigned int value;
1267     
1268     //DPRINT("%s enter\n", __func__); /*diable irq*/
1269         nfc_disable_interrupt();
1270
1271         value = sprd_dolphin_reg_read(NFC_INT_REG);
1272         //DPRINT("%s, NFC_INT_REG:0x%x\n", __func__, value);
1273         /*record handle status*/
1274         if(value & INT_TO_STS)
1275         {
1276                 
1277                 DPRINT(KERN_ALERT "%s, timeout occur NFC_INT_REG:0x%x\n", __func__, value);
1278                 handle_status=NAND_HANDLE_TIMEOUT;
1279         }
1280         else if(value & INT_DONE_STS)
1281         {
1282                 handle_status=NAND_HANDLE_DONE;
1283         }
1284         
1285         /*clear irq status*/
1286         //value = (INT_DONE_CLR | INT_TO_CLR);
1287         //sprd_dolphin_reg_or(NFC_INT_REG, value); /* clear all interrupt status */
1288
1289         //value = NFC_CMD_CLR;
1290         //sprd_dolphin_reg_or(NFC_START_REG, value); /* clear all interrupt status */
1291         
1292         nfc_clear_interrupt();
1293
1294         complete(&nfc_op_completion);
1295
1296     //DPRINT("%s leave\n", __func__);
1297
1298         return IRQ_HANDLED;
1299 }
1300 #endif
1301
1302
1303 //read large page
1304 STATIC_FUNC int sprd_dolphin_nand_read_lp(struct mtd_info *mtd,uint8_t *mbuf, uint8_t *sbuf,uint32_t raw)
1305 {
1306         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1307         struct nand_chip *chip = dolphin->nand;
1308         uint32_t column;
1309         uint32_t page_addr;
1310         uint32_t cfg0;
1311         uint32_t cfg1;
1312         uint32_t cfg2;
1313         uint32_t i;
1314         uint32_t err;
1315         int size = 0 ,sct_size;
1316         int ret  = 0;
1317         int num  = 0;
1318         uint8_t ecc_bit=0 ;
1319         page_addr = dolphin->page;
1320
1321         //DPRINT("%s enter\n", __func__);
1322         
1323         if(sbuf) {
1324                 column = mtd->writesize;
1325         }
1326         else
1327         {
1328                 column = 0;
1329         }
1330         if(chip->options & NAND_BUSWIDTH_16)
1331         {
1332                 column >>= 1;
1333         }
1334         //DPRINT("sprd_dolphin_nand_read_lp,page_addr = %x,column = %x\r\n",page_addr, column);
1335         
1336         sprd_dolphin_nand_ins_init(dolphin);
1337         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_READ0), dolphin);
1338         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(column & 0xff), dolphin);
1339         column >>= 8;
1340         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(column & 0xff), dolphin);
1341
1342         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1343         page_addr >>= 8;
1344         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1345         
1346         if (5 == dolphin->a_cycles)// five address cycles
1347         {
1348                 page_addr >>= 8;
1349                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1350         }
1351         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_READSTART), dolphin);
1352         
1353         sprd_dolphin_nand_ins_add(NFC_MC_WRB0_ID, dolphin); //wait rb
1354         if(mbuf && sbuf)
1355         {
1356                 sprd_dolphin_nand_ins_add(NAND_MC_SRDT, dolphin);
1357                 //switch to main part
1358                 sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_RNDOUT), dolphin);
1359                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(0), dolphin);
1360                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(0), dolphin);
1361                 sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_RNDOUTSTART), dolphin);
1362                 sprd_dolphin_nand_ins_add(NAND_MC_MRDT, dolphin);
1363         }
1364         else
1365         {
1366                 sprd_dolphin_nand_ins_add(NAND_MC_MRDT, dolphin);
1367         }
1368         sprd_dolphin_nand_ins_add(NFC_MC_DONE_ID, dolphin);
1369         //config registers 
1370         cfg0 = NFC_AUTO_MODE | MAIN_SPAR_APT | ((dolphin->sct_pg - 1)<< SECTOR_NUM_OFFSET);
1371         if((!raw) && mbuf && sbuf)
1372         {
1373                 cfg0 |= ECC_EN | DETECT_ALL_FF;
1374         }
1375         if(chip->options & NAND_BUSWIDTH_16)
1376         {
1377                 cfg0 |= BUS_WIDTH;
1378         }
1379         cfg1 = (dolphin->info_size) << SPAR_INFO_SIZE_OFFSET;
1380         cfg2 = (dolphin->ecc_mode << 12) | (dolphin->info_pos << SPAR_INFO_POS_OFFSET) | ((dolphin->sct_pg - 1) << SPAR_SECTOR_NUM_OFFSET) | dolphin->ecc_pos;
1381
1382         if(mbuf && sbuf)
1383         {
1384                 cfg1 |= (dolphin->m_size - 1) | ((dolphin->s_size  - 1)<< SPAR_SIZE_OFFSET);
1385                 sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, dolphin->p_mbuf);
1386                 sprd_dolphin_reg_write(NFC_SPAR_ADDR_REG, dolphin->p_oob);
1387                 cfg0 |= MAIN_USE | SPAR_USE;
1388         }
1389         else
1390         {
1391                 if(mbuf)
1392                 {
1393                         cfg1 |= (dolphin->m_size - 1);
1394                         sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, dolphin->p_mbuf);
1395                 }
1396                 if(sbuf)
1397                 {
1398                         cfg1 |= (dolphin->s_size - 1);
1399                         sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, dolphin->p_oob);
1400                 }
1401                 cfg0 |= MAIN_USE;
1402         }       
1403         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
1404         sprd_dolphin_reg_write(NFC_CFG1_REG, cfg1);
1405         sprd_dolphin_reg_write(NFC_CFG2_REG, cfg2);
1406
1407         
1408 #ifdef NAND_IRQ_EN
1409         sprd_dolphin_nand_ins_exec_irq(dolphin);
1410         sprd_dolphin_nand_wait_finish_irq(dolphin);
1411 #else
1412         sprd_dolphin_nand_ins_exec(dolphin);
1413         sprd_dolphin_nand_wait_finish(dolphin);
1414 #endif
1415
1416
1417         if(!raw) {
1418                 for(i = 0; i < dolphin->sct_pg; i++) {
1419                         err = sprd_dolphin_get_decode_sts(i);
1420                         if(err == ERR_ERR_NUM0_MASK) {
1421                             ret = 0;
1422                             ecc_bit = 0;
1423                             size = dolphin->s_size * (i+1);
1424                             sct_size = dolphin->s_size;
1425                             while(sct_size--){
1426                                 if(sbuf[--size] != 0xFF){
1427                                     DPRINT("%s spare area bif flip 0x%x\n",__func__,sbuf[size]);
1428                                     for(num=0; num<8; num++){
1429                                         if(!(sbuf[size]>>num & 0x1)){
1430                                             ecc_bit++;
1431                                             if(ecc_bit> chip->ecc.strength){
1432                                                 ret=-1;
1433                                                 DPRINT("%s  spare area ecc check error!\n",__func__);
1434                                                 break;
1435                                             }
1436                                         }
1437                                     }
1438                                     if(ret<0){
1439                                         mtd->ecc_stats.failed++;
1440                                         break;
1441                                     }
1442                                     sbuf[size]=0xff;
1443                                 }
1444                             }
1445                             if(!ret){
1446                                 size = dolphin->m_size*(i+1) ;
1447                                 sct_size = dolphin->m_size ;
1448                                 while(sct_size--){
1449                                     if(mbuf[--size] != 0xFF){
1450                                         DPRINT("%s main area bif flip 0x%x\n",__func__,mbuf[size]);
1451                                         for(num = 0 ; num < 8 ; num++){
1452                                             if(!(mbuf[size]>>num & 0x1) ){
1453                                                 ecc_bit++;
1454                                                 if(ecc_bit > chip->ecc.strength){
1455                                                     ret = -1;
1456                                                     DPRINT("%s  main+spare area ecc check error!\n",__func__);
1457                                                     break;
1458                                                 }
1459                                             }
1460                                         }
1461                                     }
1462                                     if(ret<0){
1463                                         mtd->ecc_stats.failed++;
1464                                         break;
1465                                     }
1466                                     mbuf[size] = 0xff;
1467                                }
1468                             }
1469                         }
1470                         else {
1471                                 mtd->ecc_stats.corrected += err;
1472                         }
1473                 }
1474         }
1475
1476         if(mbuf) {
1477                 memcpy(mbuf, (const void *)dolphin->v_mbuf, dolphin->write_size);
1478         }
1479         if(sbuf) {
1480                 memcpy(sbuf, (const void *)dolphin->v_oob, dolphin->oob_size);
1481         }
1482
1483         return 0;
1484 }
1485
1486
1487
1488 STATIC_FUNC int sprd_dolphin_nand_write_lp(struct mtd_info *mtd,const uint8_t *mbuf, uint8_t *sbuf,uint32_t raw)
1489 {
1490         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1491         struct nand_chip *chip = dolphin->nand;
1492         uint32_t column;
1493         uint32_t page_addr;
1494         uint32_t cfg0;
1495         uint32_t cfg1;
1496         uint32_t cfg2;
1497         page_addr = dolphin->page;
1498
1499     //DPRINT("%s, page addr is %lx\n", __func__, page_addr);
1500         
1501         if(mbuf) {
1502                 column = 0;
1503         }
1504         else {
1505                 column = mtd->writesize;
1506         }       
1507         if(chip->options & NAND_BUSWIDTH_16)
1508         {
1509                 column >>= 1;
1510         }
1511         
1512         if(mbuf) {
1513                 memcpy((void *)dolphin->v_mbuf, (const void *)mbuf, dolphin->write_size);
1514         }
1515         if(sbuf) {
1516                 memcpy((void *)dolphin->v_oob, (const void *)sbuf, dolphin->oob_size);
1517         }
1518
1519         sprd_dolphin_nand_ins_init(dolphin);
1520         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_SEQIN), dolphin);
1521         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(column & 0xff), dolphin);
1522         column >>= 8;
1523         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(column & 0xff), dolphin);
1524         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1525         page_addr >>= 8;
1526         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1527         
1528         if (5 == dolphin->a_cycles)// five address cycles
1529         {
1530                 page_addr >>= 8;
1531                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1532         }
1533         
1534         sprd_dolphin_nand_ins_add(NAND_MC_MWDT, dolphin);
1535         if(mbuf && sbuf)
1536         {
1537                 sprd_dolphin_nand_ins_add(NAND_MC_SWDT, dolphin);
1538         }
1539         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_PAGEPROG), dolphin);
1540         sprd_dolphin_nand_ins_add(NFC_MC_WRB0_ID, dolphin); //wait rb
1541
1542         sprd_dolphin_nand_ins_add(NFC_MC_DONE_ID, dolphin);
1543         //config registers 
1544         cfg0 = NFC_AUTO_MODE | NFC_RW |  NFC_WPN | MAIN_SPAR_APT | ((dolphin->sct_pg - 1)<< SECTOR_NUM_OFFSET);
1545         if((!raw) && mbuf && sbuf)
1546         {
1547                 cfg0 |= ECC_EN;
1548         }
1549         if(chip->options & NAND_BUSWIDTH_16)
1550         {
1551                 cfg0 |= BUS_WIDTH;
1552         }
1553         cfg1 = ((dolphin->info_size) << SPAR_INFO_SIZE_OFFSET);
1554         cfg2 = (dolphin->ecc_mode << 12) | (dolphin->info_pos << SPAR_INFO_POS_OFFSET) | ((dolphin->sct_pg - 1) << SPAR_SECTOR_NUM_OFFSET) | dolphin->ecc_pos;
1555
1556         if(mbuf && sbuf)
1557         {
1558                 cfg0 |= MAIN_USE | SPAR_USE;
1559                 cfg1 |= (dolphin->m_size - 1) | ((dolphin->s_size - 1) << SPAR_SIZE_OFFSET);
1560                 sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, dolphin->p_mbuf);
1561                 sprd_dolphin_reg_write(NFC_SPAR_ADDR_REG, dolphin->p_oob);
1562         }
1563         else
1564         {
1565                 cfg0 |= MAIN_USE;
1566                 if(mbuf)
1567                 {
1568                         cfg1 |= dolphin->m_size - 1;
1569                         sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, dolphin->p_mbuf);
1570                 }
1571                 else
1572                 {
1573                         cfg1 |= dolphin->s_size - 1;
1574                         sprd_dolphin_reg_write(NFC_MAIN_ADDR_REG, dolphin->p_oob);
1575                 }
1576         }
1577         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
1578         sprd_dolphin_reg_write(NFC_CFG1_REG, cfg1);
1579         sprd_dolphin_reg_write(NFC_CFG2_REG, cfg2);
1580
1581         
1582 #ifdef NAND_IRQ_EN
1583         sprd_dolphin_nand_ins_exec_irq(dolphin);
1584         sprd_dolphin_nand_wait_finish_irq(dolphin);
1585 #else
1586         sprd_dolphin_nand_ins_exec(dolphin);
1587         sprd_dolphin_nand_wait_finish(dolphin);
1588 #endif
1589
1590         return 0;
1591 }
1592 #endif
1593
1594
1595
1596 STATIC_FUNC int sprd_dolphin_nand_read_sp(struct mtd_info *mtd,uint8_t *mbuf, uint8_t *sbuf,uint32_t raw)
1597 {
1598         return 0;
1599 }
1600 STATIC_FUNC int sprd_dolphin_nand_write_sp(struct mtd_info *mtd,const uint8_t *mbuf, uint8_t *sbuf,uint32_t raw)
1601 {
1602         return 0;
1603 }
1604 STATIC_FUNC void sprd_dolphin_erase(struct mtd_info *mtd, int page_addr)
1605 {
1606         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1607         uint32_t cfg0 = 0;
1608     
1609         //DPRINT("%s, page addr is %x\r\n", __func__ , page_addr);
1610     
1611         sprd_dolphin_nand_ins_init(dolphin);
1612         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_ERASE1), dolphin);
1613         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1614         page_addr >>= 8;
1615         sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1616         if((5 == dolphin->a_cycles) || ((4 == dolphin->a_cycles) && (512 == dolphin->write_size)))
1617         {
1618                 page_addr >>= 8;
1619                 sprd_dolphin_nand_ins_add(NAND_MC_ADDR(page_addr & 0xff), dolphin);
1620         }
1621         sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_ERASE2), dolphin);
1622         sprd_dolphin_nand_ins_add(NFC_MC_WRB0_ID, dolphin); //wait rb
1623
1624         sprd_dolphin_nand_ins_add(NFC_MC_DONE_ID, dolphin);
1625         cfg0 = NFC_WPN | NFC_ONLY_NAND_MODE;
1626         sprd_dolphin_reg_write(NFC_CFG0_REG, cfg0);
1627
1628
1629         #ifdef NAND_IRQ_EN
1630         sprd_dolphin_nand_ins_exec_irq(dolphin);
1631         sprd_dolphin_nand_wait_finish_irq(dolphin);
1632         #else
1633         sprd_dolphin_nand_ins_exec(dolphin);
1634         sprd_dolphin_nand_wait_finish(dolphin);
1635         #endif
1636
1637     //DPRINT("%s leave\n", __func__);
1638 }
1639 STATIC_FUNC uint8_t sprd_dolphin_read_byte(struct mtd_info *mtd)
1640 {
1641         uint8_t ch = 0xff;
1642         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1643         if(dolphin->buf_head < dolphin->_buf_tail)
1644         {
1645                 ch = s_oob_data[dolphin->buf_head ++];
1646         }
1647         return ch;
1648 }
1649 STATIC_FUNC uint16_t sprd_dolphin_read_word(struct mtd_info *mtd)
1650 {
1651         uint16_t data = 0xffff;
1652         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1653         if(dolphin->buf_head < (dolphin->_buf_tail - 1))
1654         {
1655                 data = s_oob_data[dolphin->buf_head ++];
1656                 data |= ((uint16_t)s_oob_data[dolphin->buf_head ++]) << 8;
1657         }
1658         return data;
1659 }
1660
1661 STATIC_FUNC int sprd_dolphin_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
1662 {
1663         return 0;
1664 }
1665
1666 STATIC_FUNC int sprd_dolphin_ecc_calculate(struct mtd_info *mtd, const uint8_t *data,
1667                                 uint8_t *ecc_code)
1668 {
1669         return 0;
1670 }
1671
1672 STATIC_FUNC int sprd_dolphin_ecc_correct(struct mtd_info *mtd, uint8_t *data,
1673                                 uint8_t *read_ecc, uint8_t *calc_ecc)
1674 {
1675         return 0;
1676 }
1677
1678 static int sprd_dolphin_read_page(struct mtd_info *mtd, struct nand_chip *chip,
1679                         uint8_t *buf, int page)
1680 {
1681         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1682         dolphin->page = page;
1683         if(512 == mtd->writesize)
1684         {
1685                 sprd_dolphin_nand_read_sp(mtd, buf, chip->oob_poi, 0);
1686         }
1687         else
1688         {
1689                 sprd_dolphin_nand_read_lp(mtd, buf, chip->oob_poi, 0);
1690         }
1691         return 0;
1692 }
1693 static int sprd_dolphin_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1694                                 uint8_t *buf, int page)
1695 {
1696         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1697         dolphin->page = page;
1698         if(512 == mtd->writesize)
1699         {
1700                 sprd_dolphin_nand_read_sp(mtd, buf, chip->oob_poi, 1);
1701         }
1702         else
1703         {
1704                 sprd_dolphin_nand_read_lp(mtd, buf, chip->oob_poi, 1);
1705         }
1706         return 0;
1707 }
1708 STATIC_FUNC int sprd_dolphin_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
1709                            int page, int sndcmd)
1710 {
1711         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1712         dolphin->page = page;
1713         if(512 == mtd->writesize)
1714         {
1715                 sprd_dolphin_nand_read_sp(mtd, 0, chip->oob_poi, 1);
1716         }
1717         else
1718         {
1719                 sprd_dolphin_nand_read_lp(mtd, 0, chip->oob_poi, 1);
1720         }
1721         return 0;
1722 }
1723 STATIC_FUNC void sprd_dolphin_write_page(struct mtd_info *mtd, struct nand_chip *chip,
1724                                 const uint8_t *buf)
1725 {
1726         if(512 == mtd->writesize)
1727         {
1728                 sprd_dolphin_nand_write_sp(mtd, buf, chip->oob_poi, 0); 
1729         }
1730         else
1731         {
1732                 sprd_dolphin_nand_write_lp(mtd, buf, chip->oob_poi, 0); 
1733         }
1734
1735 }
1736 STATIC_FUNC void sprd_dolphin_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1737                                         const uint8_t *buf)
1738 {
1739         if(512 == mtd->writesize)
1740         {
1741                 sprd_dolphin_nand_write_sp(mtd, buf, chip->oob_poi, 1); 
1742         }
1743         else
1744         {
1745                 sprd_dolphin_nand_write_lp(mtd, buf, chip->oob_poi, 1); 
1746         }
1747 }
1748 STATIC_FUNC int sprd_dolphin_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
1749                                 int page)
1750 {
1751         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);   
1752         dolphin->page = page;
1753         if(512 == mtd->writesize)
1754         {
1755                 sprd_dolphin_nand_write_sp(mtd, 0, chip->oob_poi, 1);
1756         }
1757         else
1758         {
1759                 sprd_dolphin_nand_write_lp(mtd, 0, chip->oob_poi, 1);
1760         }
1761         return 0;
1762 }
1763
1764
1765 /**
1766  * nand_block_bad - [DEFAULT] Read bad block marker from the chip
1767  * @mtd:        MTD device structure
1768  * @ofs:        offset from device start
1769  * @getchip:    0, if the chip is already selected
1770  *
1771  * Check, if the block is bad.
1772  */
1773 STATIC_FUNC int sprd_dolphin_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
1774 {
1775         int page, chipnr, res = 0;
1776         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1777         struct nand_chip *chip = mtd->priv;
1778         uint16_t bad;
1779         uint16_t *buf;
1780
1781         page = (int)((long)ofs >> chip->page_shift) & chip->pagemask;
1782
1783         if (getchip) {
1784                 chipnr = (int)((long)ofs >> chip->chip_shift);
1785                 /* Select the NAND device */
1786                 chip->select_chip(mtd, chipnr);
1787         }
1788
1789         chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
1790         if(512 == dolphin->write_size) {
1791                 sprd_dolphin_nand_read_sp(mtd, 0, s_oob_data, 1);
1792         }
1793         else  {
1794                 sprd_dolphin_nand_read_lp(mtd, 0, s_oob_data, 1);
1795         }
1796         dolphin->buf_head = 0;
1797         dolphin->_buf_tail = mtd->oobsize;
1798         buf = (uint16_t *)(s_oob_data + chip->badblockpos);
1799
1800         if (chip->options & NAND_BUSWIDTH_16) {
1801                 bad = *(buf);
1802                 if ((bad & 0xFF) != 0xff) {
1803                         res = 1;
1804                 }
1805         } else {
1806                 bad = *(buf) & 0xff;
1807                 if (bad != 0xff){
1808                         res = 1;
1809                 }
1810         }
1811         return res;
1812 }
1813
1814 STATIC_FUNC void sprd_dolphin_nand_cmdfunc(struct mtd_info *mtd, unsigned int command,
1815                             int column, int page_addr)
1816 {
1817         struct sprd_dolphin_nand_info *dolphin = mtd_to_dolphin(mtd);
1818         /* Emulate NAND_CMD_READOOB */
1819         if (command == NAND_CMD_READOOB) {
1820                 column += mtd->writesize;
1821                 command = NAND_CMD_READ0;
1822         }
1823         /*
1824          * program and erase have their own busy handlers
1825          * status, sequential in, and deplete1 need no delay
1826          */
1827         switch (command) {
1828         case NAND_CMD_STATUS:
1829                 sprd_dolphin_nand_read_status(dolphin);
1830                 break;
1831         case NAND_CMD_READID:
1832                 sprd_dolphin_nand_read_id(dolphin, (uint32_t *)s_oob_data);
1833                 break;
1834         case NAND_CMD_RESET:
1835                 sprd_dolphin_nand_reset(dolphin);
1836                 break;
1837         case NAND_CMD_ERASE1:
1838                 sprd_dolphin_erase(mtd, page_addr);
1839                 break;
1840         case NAND_CMD_READ0:
1841         case NAND_CMD_SEQIN:
1842                 dolphin->column = column;
1843                 dolphin->page = page_addr;
1844         default:
1845                 break;
1846         }
1847 }
1848 STATIC_FUNC void sprd_dolphin_nand_hwecc_ctl(struct mtd_info *mtd, int mode)
1849 {
1850         return; //do nothing
1851 }
1852
1853
1854
1855 #ifdef DOLPHIN_UBOOT
1856 #define DOLPHIN_AHB_BASE SPRD_AHB_PHYS
1857 #define DOLPHIN_PIN_BASE SPRD_PIN_PHYS
1858 #define DOLPHIN_AHB_RST  (DOLPHIN_AHB_BASE + 0x0004)
1859 #define DOLPHIN_NANC_CLK_CFG  (DOLPHIN_AHB_BASE + 0x0060)
1860
1861 #define DOLPHIN_ADISLAVE_BASE           SPRD_ADISLAVE_PHYS
1862 #define DOLPHIN_ANA_CTL_GLB_BASE                (DOLPHIN_ADISLAVE_BASE + 0x8800)
1863
1864 #define DOLPHIN_NFC_REG_BASE  SPRD_NFC_PHYS
1865 #define DOLPHIN_NFC_TIMING_REG  (DOLPHIN_NFC_REG_BASE + 0x14)
1866 #define DOLPHIN_NFC_TIMEOUT_REG  (DOLPHIN_NFC_REG_BASE + 0x34)
1867 #endif
1868
1869 #ifdef DOLPHIN_KERNEL
1870 #define DOLPHIN_AHB_BASE SPRD_AHB_BASE
1871 #define DOLPHIN_PIN_BASE SPRD_PIN_BASE
1872 #define DOLPHIN_AHB_RST  (DOLPHIN_AHB_BASE + 0x0004)
1873 #define DOLPHIN_NANC_CLK_CFG  (DOLPHIN_AHB_BASE + 0x0060)
1874
1875 #define DOLPHIN_ADISLAVE_BASE           SPRD_ADISLAVE_BASE
1876 #define DOLPHIN_ANA_CTL_GLB_BASE                (DOLPHIN_ADISLAVE_BASE + 0x8800)
1877
1878 #define DOLPHIN_NFC_REG_BASE  SPRD_NFC_BASE
1879 #define DOLPHIN_NFC_TIMING_REG  (DOLPHIN_NFC_REG_BASE + 0x14)
1880 #define DOLPHIN_NFC_TIMEOUT_REG  (DOLPHIN_NFC_REG_BASE + 0x34)
1881 #endif
1882
1883
1884 STATIC_FUNC void sprd_dolphin_nand_hw_init(struct sprd_dolphin_nand_info *dolphin)
1885 {
1886         int i = 0;
1887         uint32_t val;
1888
1889         sprd_dolphin_reg_and(DOLPHIN_NANC_CLK_CFG, ~(BIT(1) | BIT(0)));
1890         sprd_dolphin_reg_or(DOLPHIN_NANC_CLK_CFG, BIT(0));
1891
1892         sprd_dolphin_reg_or(DOLPHIN_AHB_BASE, BIT(19) | BIT(18) | BIT(17));
1893
1894         sprd_dolphin_reg_or(DOLPHIN_AHB_RST,BIT(20));
1895         mdelay(1);
1896         sprd_dolphin_reg_and(DOLPHIN_AHB_RST, ~(BIT(20)));
1897
1898         val = (3)  | (4 << NFC_RWH_OFFSET) | (3 << NFC_RWE_OFFSET) | (3 << NFC_RWS_OFFSET) | (3 << NFC_ACE_OFFSET) | (3 << NFC_ACS_OFFSET);
1899         sprd_dolphin_reg_write(DOLPHIN_NFC_TIMING_REG, val);
1900         sprd_dolphin_reg_write(DOLPHIN_NFC_TIMEOUT_REG, 0xffffffff);
1901         sprd_dolphin_reg_write(DOLPHIN_NFC_REG_BASE + 0x118, 3);
1902
1903 #if 0
1904         sprd_dolphin_reg_or(DOLPHIN_PIN_BASE + REG_PIN_NFWPN, BIT(7) | BIT(8) | BIT(9));
1905         sprd_dolphin_reg_and(DOLPHIN_PIN_BASE + REG_PIN_NFWPN, ~(BIT(4) | BIT(5)));
1906         sprd_dolphin_reg_or(DOLPHIN_PIN_BASE + REG_PIN_NFRB, BIT(7) | BIT(8) | BIT(9));
1907         sprd_dolphin_reg_and(DOLPHIN_PIN_BASE + REG_PIN_NFRB, ~(BIT(4) | BIT(5)));
1908         for(i = 0; i < 22; ++i)
1909         {
1910                 sprd_dolphin_reg_or(DOLPHIN_PIN_BASE + REG_PIN_NFCLE + (i << 2), BIT(7) | BIT(8) | BIT(9));
1911                 sprd_dolphin_reg_and(DOLPHIN_PIN_BASE + REG_PIN_NFCLE + (i << 2), ~(BIT(4) | BIT(5)));
1912         }
1913 #endif
1914         i = sprd_dolphin_reg_read(DOLPHIN_ANA_CTL_GLB_BASE+0x3c);
1915         i &= ~0x7F00;
1916         i |= 0x38 << 8;
1917         sprd_dolphin_reg_write(DOLPHIN_ANA_CTL_GLB_BASE + 0x3c, i);
1918
1919         i = sprd_dolphin_reg_read(DOLPHIN_ANA_CTL_GLB_BASE+0x20);
1920         i &= ~0xFF;
1921         i |= 0x38 << 0;
1922         sprd_dolphin_reg_write(DOLPHIN_ANA_CTL_GLB_BASE + 0x20, i);
1923         
1924         //close write protect
1925         sprd_dolphin_nand_wp_en(dolphin, 0);
1926 }
1927
1928
1929 int board_nand_init(struct nand_chip *chip)
1930 {
1931         DPRINT("board_nand_init\r\n");
1932
1933         sprd_dolphin_nand_hw_init(&g_dolphin);
1934
1935         chip->select_chip = sprd_dolphin_select_chip;
1936         chip->cmdfunc = sprd_dolphin_nand_cmdfunc;
1937         chip->read_byte = sprd_dolphin_read_byte;
1938         chip->read_word = sprd_dolphin_read_word;
1939         chip->waitfunc = sprd_dolphin_waitfunc;
1940         chip->ecc.mode = NAND_ECC_HW;
1941         chip->ecc.calculate = sprd_dolphin_ecc_calculate;
1942         chip->ecc.hwctl = sprd_dolphin_nand_hwecc_ctl;
1943         chip->ecc.correct = sprd_dolphin_ecc_correct;
1944         chip->ecc.read_page = sprd_dolphin_read_page;
1945         chip->ecc.read_page_raw = sprd_dolphin_read_page_raw;
1946         chip->ecc.write_page = sprd_dolphin_write_page;
1947         chip->ecc.write_page_raw = sprd_dolphin_write_page_raw;
1948         chip->ecc.read_oob = sprd_dolphin_read_oob;
1949         chip->ecc.write_oob = sprd_dolphin_write_oob;
1950         chip->erase_cmd = sprd_dolphin_erase;
1951         
1952         chip->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
1953         g_dolphin.ecc_mode = ecc_mode_convert(CONFIG_SYS_NAND_ECC_MODE);
1954         g_dolphin.nand = chip;
1955
1956 #ifdef DOLPHIN_KERNEL
1957         chip->ecc.strength = CONFIG_SYS_NAND_ECC_MODE;
1958 #endif
1959
1960 #ifdef DOLPHIN_UBOOT
1961         chip->eccbitmode = CONFIG_SYS_NAND_ECC_MODE;
1962 #endif
1963
1964         //dolphin_set_timing_config(&g_dolphin, SPRD_NAND_CLOCK);       /* 153 is current clock 153MHz */
1965
1966         chip->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
1967
1968         chip->chip_delay = 20;
1969         chip->priv = &g_dolphin;
1970
1971         //DPRINT("v2   board eccbitmode %d\n", chip->eccbitmode);
1972
1973         chip->options = NAND_BUSWIDTH_16;
1974
1975         return 0;
1976 }
1977
1978 #ifdef DOLPHIN_UBOOT
1979 #ifndef CONFIG_NAND_SPL
1980 void McuReadNandType(unsigned char *array)
1981 {
1982
1983 }
1984 #endif
1985
1986 static unsigned long nfc_read_status(void)
1987 {
1988         unsigned long status = 0;
1989
1990         sprd_dolphin_nand_read_status(&g_dolphin);      
1991         status = s_oob_data[0];
1992
1993         return status;
1994 }
1995
1996 #ifndef CONFIG_NAND_SPL
1997 static int sprd_scan_one_block(int blk, int erasesize, int writesize)
1998 {
1999         int i, cmd;
2000         int status = 1, ii;
2001         u32 size = 0;
2002         int oobsize = mtdoobsize;
2003         int column, page_addr;
2004
2005         page_addr = blk * (erasesize / writesize);
2006         for (ii = 0; ii < 2; ii ++) {
2007                 DPRINT("please debug here : %s %d\n", __FUNCTION__, __LINE__);
2008                 sprd_dolphin_nand_ins_init(&g_dolphin);
2009                 sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_READ0), &g_dolphin);
2010                 sprd_dolphin_nand_ins_add(NAND_MC_CMD(NAND_CMD_READSTART), &g_dolphin);
2011                 if ((s_oob_data[0] != 0xff) || (s_oob_data[1] != 0xff))
2012                         break;
2013         } //for (ii = 0; ii < 2; ii ++)
2014
2015         if ((s_oob_data[0] == 0xff) && (s_oob_data[1] == 0xff))
2016                 status = 0; //good block
2017         else
2018                 status = 1; //bad block
2019
2020         return status;
2021 }
2022
2023 static unsigned long nand_ctl_erase_block(int blk, int erasesize, int writesize)
2024 {
2025         int cmd, status;
2026         int page_addr;
2027
2028         page_addr = blk * (erasesize / writesize);
2029         sprd_dolphin_erase(&g_dolphin, page_addr);
2030         status = nfc_read_status();
2031
2032         return status;
2033 }
2034 #endif
2035
2036
2037 #ifndef CONFIG_NAND_SPL
2038 void nand_scan_patition(int blocks, int erasesize, int writesize)
2039 {
2040         int blk;
2041         int ret;
2042         int status;
2043
2044         //read_chip_id();
2045         for (blk = 0; blk < blocks; blk ++) {
2046                 ret = sprd_scan_one_block(blk, erasesize, writesize);
2047                 if (ret != 0) {
2048                         DPRINT("\n%d is bad, scrub to erase it, ", blk);
2049                         ret = nand_ctl_erase_block(blk, erasesize, writesize);
2050                         DPRINT("0x%02x\n", ret);
2051                 } else {
2052                         ret = nand_ctl_erase_block(blk, erasesize, writesize);
2053                         DPRINT("erasing block : %d    %d % \r", blk, (blk * 100 ) / blocks);
2054                 }
2055         }
2056 }
2057 int nand_scan_block(int block, int erasesize, int writesize){
2058         int ret = 0;
2059         ret = nand_ctl_erase_block(block, erasesize, writesize);
2060         ret = ret&1;
2061
2062         return ret;
2063 }
2064 #endif
2065 #endif  //DOLPHIN_UBOOT end
2066
2067
2068
2069 #ifdef DOLPHIN_KERNEL
2070 extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
2071                                 struct mtd_partition **pparts,
2072                                 struct mtd_part_parser_data *data);
2073
2074 static struct mtd_info *sprd_mtd = NULL;
2075 #ifdef CONFIG_MTD_CMDLINE_PARTS
2076 const char *part_probes[] = { "cmdlinepart", NULL };
2077 #endif
2078
2079 STATIC_FUNC int sprd_nand_dma_init(struct sprd_dolphin_nand_info *dolphin)
2080 {
2081         dma_addr_t phys_addr = 0;
2082         void *virt_ptr = 0;
2083         virt_ptr = dma_alloc_coherent(NULL, dolphin->write_size, &phys_addr, GFP_KERNEL);
2084         if (virt_ptr == NULL) {
2085                 DPRINT(KERN_ERR "NAND - Failed to allocate memory for DMA main buffer\n");
2086                 return -ENOMEM;
2087         }
2088         dolphin->v_mbuf = (u32)virt_ptr;
2089         dolphin->p_mbuf = (u32)phys_addr;
2090
2091         virt_ptr = dma_alloc_coherent(NULL, dolphin->oob_size, &phys_addr, GFP_KERNEL);
2092         if (virt_ptr == NULL) {
2093                 DPRINT(KERN_ERR "NAND - Failed to allocate memory for DMA oob buffer\n");
2094                 dma_free_coherent(NULL, dolphin->write_size, (void *)dolphin->v_mbuf, (dma_addr_t)dolphin->p_mbuf);
2095                 return -ENOMEM;
2096         }
2097         dolphin->v_oob = (u32)virt_ptr;
2098         dolphin->p_oob = (u32)phys_addr;
2099         return 0;
2100 }
2101 STATIC_FUNC void sprd_nand_dma_deinit(struct sprd_dolphin_nand_info *dolphin)
2102 {
2103         dma_free_coherent(NULL, dolphin->write_size, (void *)dolphin->v_mbuf, (dma_addr_t)dolphin->p_mbuf);
2104         dma_free_coherent(NULL, dolphin->write_size, (void *)dolphin->v_oob, (dma_addr_t)dolphin->p_oob);
2105 }
2106 STATIC_FUNC int sprd_nand_probe(struct platform_device *pdev)
2107 {
2108         struct nand_chip *this;
2109         struct resource *regs = NULL;
2110         struct mtd_partition *partitions = NULL;
2111         int num_partitions = 0;
2112         int ret = 0;
2113
2114
2115         #ifdef  NAND_IRQ_EN
2116         int err = 0;
2117         init_completion(&nfc_op_completion);
2118         err = request_irq(IRQ_NFC_INT, nfc_irq_handler, 0, DRIVER_NAME, NULL);
2119         if (err) {
2120         DPRINT(KERN_ERR "request_irq error\n");
2121                 goto prob_err;  
2122     }
2123     DPRINT(KERN_ALERT "request_irq ok\n");
2124         #endif
2125         
2126
2127         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2128         if (!regs) {
2129                 dev_err(&pdev->dev,"resources unusable\n");
2130                 goto prob_err;
2131         }
2132
2133         memset(&g_dolphin, 0 , sizeof(g_dolphin));
2134
2135         platform_set_drvdata(pdev, &g_dolphin);
2136         g_dolphin.pdev = pdev;
2137
2138         sprd_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
2139         this = (struct nand_chip *)(&sprd_mtd[1]);
2140         memset((char *)sprd_mtd, 0, sizeof(struct mtd_info));
2141         memset((char *)this, 0, sizeof(struct nand_chip));
2142
2143         sprd_mtd->priv = this;
2144
2145         this->options |= NAND_BUSWIDTH_16;
2146         //this->options |= NAND_NO_READRDY;
2147
2148         board_nand_init(this);
2149
2150
2151     if (sprd_dolphin_nand_reset(&g_dolphin) != 0)
2152     {
2153         ret = -ENXIO;
2154         DPRINT(KERN_ERR "nand reset failed!!!!!!!!!!!!!\n");
2155         goto prob_err;
2156     }
2157     msleep(1);
2158
2159     if (sprd_dolphin_nand_read_id(&g_dolphin, (uint32_t *)s_oob_data) != 0)
2160     {
2161         ret = -ENXIO;
2162         DPRINT(KERN_ERR "nand read id failed, no nand device!!!!!!!!!!!!!\n");
2163     }
2164     DPRINT(KERN_ALERT "nand read id ok, nand exists!!!!!!!!!!!!!\n");
2165
2166         //nand_scan(sprd_mtd, 1);
2167         /* first scan to find the device and get the page size */
2168         if (nand_scan_ident(sprd_mtd, 1, NULL)) {
2169                 ret = -ENXIO;
2170                 goto prob_err;
2171         }
2172         sprd_dolphin_nand_read_id(&g_dolphin, (uint32_t *)s_oob_data);
2173         nand_hardware_config(sprd_mtd, this, s_oob_data);
2174         if(sprd_nand_dma_init(&g_dolphin) != 0) {
2175                 return -ENOMEM;
2176         }
2177         
2178         //this->IO_ADDR_R = g_dolphin.v_mbuf;
2179         //this->IO_ADDR_W = g_dolphin.v_mbuf;
2180
2181         /* second phase scan */
2182         if (nand_scan_tail(sprd_mtd)) {
2183                 ret = -ENXIO;
2184                 goto prob_err;
2185         }
2186
2187         sprd_mtd->name = "sprd-nand";
2188         num_partitions = parse_mtd_partitions(sprd_mtd, part_probes, &partitions, 0);
2189
2190         if ((!partitions) || (num_partitions == 0)) {
2191                 DPRINT(KERN_ALERT "No parititions defined, or unsupported device.\n");
2192                 goto release;
2193         }
2194
2195 #ifdef CONFIG_MTD_CMDLINE_PARTS
2196         mtd_device_register(sprd_mtd, partitions, num_partitions);
2197 #endif
2198
2199         return 0;
2200 release:
2201         nand_release(sprd_mtd);
2202         sprd_nand_dma_deinit(&g_dolphin);
2203 prob_err:
2204         sprd_dolphin_reg_and(DOLPHIN_AHB_BASE,~(BIT(19) | BIT(18) | BIT(17)));
2205         kfree(sprd_mtd);
2206         return ret;
2207 }
2208
2209 STATIC_FUNC int sprd_nand_remove(struct platform_device *pdev)
2210 {
2211         platform_set_drvdata(pdev, NULL);
2212         nand_release(sprd_mtd);
2213         sprd_nand_dma_deinit(&g_dolphin);
2214         kfree(sprd_mtd);
2215         return 0;
2216 }
2217
2218 #ifdef CONFIG_PM
2219 STATIC_FUNC int sprd_nand_suspend(struct platform_device *dev, pm_message_t pm)
2220 {
2221         //nothing to do
2222         return 0;
2223 }
2224
2225 STATIC_FUNC int sprd_nand_resume(struct platform_device *dev)
2226 {
2227         sprd_dolphin_nand_hw_init(&g_dolphin);
2228         return 0;
2229 }
2230 #else
2231 #define sprd_nand_suspend NULL
2232 #define sprd_nand_resume NULL
2233 #endif
2234
2235 static struct platform_driver sprd_nand_driver = {
2236         .probe          = sprd_nand_probe,
2237         .remove         = sprd_nand_remove,
2238         .suspend        = sprd_nand_suspend,
2239         .resume         = sprd_nand_resume,
2240         .driver         = {
2241                 .name   = "sprd-nand",
2242                 .owner  = THIS_MODULE,
2243         },
2244 };
2245
2246 STATIC_FUNC int __init sprd_nand_init(void)
2247 {
2248         return platform_driver_register(&sprd_nand_driver);
2249 }
2250
2251 STATIC_FUNC void __exit sprd_nand_exit(void)
2252 {
2253         platform_driver_unregister(&sprd_nand_driver);
2254 }
2255
2256 module_init(sprd_nand_init);
2257 module_exit(sprd_nand_exit);
2258
2259 MODULE_LICENSE("GPL");
2260 MODULE_AUTHOR("giya.li@spreadtrum.com");
2261 MODULE_DESCRIPTION("SPRD dolphin MTD NAND driver");
2262 MODULE_ALIAS("platform:sprd-nand");
2263
2264 #endif
2265
2266
2267
2268
2269
2270
2271