2 #include <asm/arch/bits.h>
3 #include <asm/arch/chip_drv_config_extern.h>
4 #include <asm/arch/regs_nfc.h>
5 #include <asm/arch/regs_cpc.h>
8 #include <linux/mtd/nand.h>
10 #ifdef CONFIG_NAND_SPL
11 #define printf(arg...) do{}while(0)
15 #define NF_PARA_20M 0x7ac05 //trwl = 0 trwh = 0
16 #define NF_PARA_40M 0x7ac15 //trwl = 1 trwh = 0
17 #define NF_PARA_53M 0x7ad26 //trwl = 2 trwh = 1
18 #define NF_PARA_80M 0x7ad37 //trwl = 3 trwh = 1
19 #define NF_PARA_DEFAULT 0x7ad77 //trwl = 7 trwh = 1
20 #define NF_TIMEOUT_VAL 0x1000000
22 #define PAGE_SIZE_S 512
23 #define SPARE_SIZE_S 16
24 #define PAGE_SIZE_L 2048
25 #define SPARE_SIZE_L 64
27 #define REG_CPC_NFWPN (*((volatile unsigned int *)(CPC_NFWPN_REG)))
28 #define REG_CPC_NFRB (*((volatile unsigned int *)(CPC_NFRB_REG)))
29 #define REG_CPC_NFCLE (*((volatile unsigned int *)(CPC_NFCLE_REG)))
30 #define REG_CPC_NFALE (*((volatile unsigned int *)(CPC_NFALE_REG)))
31 #define REG_CPC_NFCEN (*((volatile unsigned int *)(CPC_NFCEN_REG)))
32 #define REG_CPC_NFWEN (*((volatile unsigned int *)(CPC_NFWEN_REG)))
33 #define REG_CPC_NFREN (*((volatile unsigned int *)(CPC_NFREN_REG)))
34 #define REG_CPC_NFD0 (*((volatile unsigned int *)(CPC_NFD0_REG)))
35 #define REG_CPC_NFD1 (*((volatile unsigned int *)(CPC_NFD1_REG)))
36 #define REG_CPC_NFD2 (*((volatile unsigned int *)(CPC_NFD2_REG)))
37 #define REG_CPC_NFD3 (*((volatile unsigned int *)(CPC_NFD3_REG)))
38 #define REG_CPC_NFD4 (*((volatile unsigned int *)(CPC_NFD4_REG)))
39 #define REG_CPC_NFD5 (*((volatile unsigned int *)(CPC_NFD5_REG)))
40 #define REG_CPC_NFD6 (*((volatile unsigned int *)(CPC_NFD6_REG)))
41 #define REG_CPC_NFD7 (*((volatile unsigned int *)(CPC_NFD7_REG)))
42 #define REG_CPC_NFD8 (*((volatile unsigned int *)(CPC_NFD8_REG)))
44 #define REG_CPC_NFD9 (*((volatile unsigned int *)(CPC_NFD9_REG)))
45 #define REG_CPC_NFD10 (*((volatile unsigned int *)(CPC_NFD10_REG)))
46 #define REG_CPC_NFD11 (*((volatile unsigned int *)(CPC_NFD11_REG)))
47 #define REG_CPC_NFD12 (*((volatile unsigned int *)(CPC_NFD12_REG)))
48 #define REG_CPC_NFD13 (*((volatile unsigned int *)(CPC_NFD13_REG)))
49 #define REG_CPC_NFD14 (*((volatile unsigned int *)(CPC_NFD14_REG)))
50 #define REG_CPC_NFD15 (*((volatile unsigned int *)(CPC_NFD15_REG)))
53 #define REG_AHB_CTL0 (*((volatile unsigned int *)(AHB_CTL0)))
54 #define REG_AHB_SOFT_RST (*((volatile unsigned int *)(AHB_SOFT_RST)))
56 #define REG_GR_NFC_MEM_DLY (*((volatile unsigned int *)(GR_NFC_MEM_DLY)))
59 #define set_sc8800g_gpio_as_nand_8bit() \
61 REG_CPC_NFWPN |= BIT_8 | BIT_9; \
62 REG_CPC_NFWPN &= ~(BIT_4 | BIT_5); \
63 REG_CPC_NFRB |= BIT_8 | BIT_9; \
64 REG_CPC_NFRB &= ~(BIT_4 | BIT_5); \
65 REG_CPC_NFCLE |= BIT_8 | BIT_9; \
66 REG_CPC_NFCLE &= ~(BIT_4 | BIT_5); \
67 REG_CPC_NFALE |= BIT_8 | BIT_9; \
68 REG_CPC_NFALE &= ~(BIT_4 | BIT_5); \
69 REG_CPC_NFCEN |= BIT_8 | BIT_9; \
70 REG_CPC_NFCEN &= ~(BIT_4 | BIT_5); \
71 REG_CPC_NFWEN |= BIT_8 | BIT_9; \
72 REG_CPC_NFWEN &= ~(BIT_4 | BIT_5); \
73 REG_CPC_NFREN |= BIT_8 | BIT_9; \
74 REG_CPC_NFREN &= ~(BIT_4 | BIT_5); \
75 REG_CPC_NFD0 |= BIT_8 | BIT_9; \
76 REG_CPC_NFD0 &= ~(BIT_4 | BIT_5); \
77 REG_CPC_NFD1 |= BIT_8 | BIT_9; \
78 REG_CPC_NFD1 &= ~(BIT_4 | BIT_5); \
79 REG_CPC_NFD2 |= BIT_8 | BIT_9; \
80 REG_CPC_NFD2 &= ~(BIT_4 | BIT_5); \
81 REG_CPC_NFD3 |= BIT_8 | BIT_9; \
82 REG_CPC_NFD3 &= ~(BIT_4 | BIT_5); \
83 REG_CPC_NFD4 |= BIT_8 | BIT_9; \
84 REG_CPC_NFD4 &= ~(BIT_4 | BIT_5); \
85 REG_CPC_NFD5 |= BIT_8 | BIT_9; \
86 REG_CPC_NFD5 &= ~(BIT_4 | BIT_5); \
87 REG_CPC_NFD6 |= BIT_8 | BIT_9; \
88 REG_CPC_NFD6 &= ~(BIT_4 | BIT_5); \
89 REG_CPC_NFD7 |= BIT_8 | BIT_9; \
90 REG_CPC_NFD7 &= ~(BIT_4 | BIT_5); \
93 #define set_sc8800g_gpio_as_nand_16bit() \
95 REG_CPC_NFD8 |= BIT_8 | BIT_9; \
96 REG_CPC_NFD8 &= ~(BIT_4 | BIT_5); \
97 REG_CPC_NFD9 |= BIT_8 | BIT_9; \
98 REG_CPC_NFD9 &= ~(BIT_4 | BIT_5); \
99 REG_CPC_NFD10 |= BIT_8 | BIT_9; \
100 REG_CPC_NFD10 &= ~(BIT_4 | BIT_5); \
101 REG_CPC_NFD11 |= BIT_8 | BIT_9; \
102 REG_CPC_NFD11 &= ~(BIT_4 | BIT_5); \
103 REG_CPC_NFD12 |= BIT_8 | BIT_9; \
104 REG_CPC_NFD12 &= ~(BIT_4 | BIT_5); \
105 REG_CPC_NFD13 |= BIT_8 | BIT_9; \
106 REG_CPC_NFD13 &= ~(BIT_4 | BIT_5); \
107 REG_CPC_NFD14 |= BIT_8 | BIT_9; \
108 REG_CPC_NFD14 &= ~(BIT_4 | BIT_5); \
109 REG_CPC_NFD15 |= BIT_8 | BIT_9; \
110 REG_CPC_NFD15 &= ~(BIT_4 | BIT_5); \
113 #define set_gpio_as_nand() \
115 REG_CPC_NFWPN = BIT_0 | BIT_4 | BIT_5; \
116 REG_CPC_NFWPN &= ~(BIT_6 | BIT_7); \
117 REG_CPC_NFRB = BIT_0 | BIT_3 | BIT_4 | BIT_5; \
118 REG_CPC_NFRB &= ~(BIT_6 | BIT_7); \
119 REG_CPC_NFCLE |= BIT_4 | BIT_5; \
120 REG_CPC_NFCLE &= ~(BIT_6 | BIT_7); \
121 REG_CPC_NFALE |= BIT_4 | BIT_5; \
122 REG_CPC_NFALE &= ~(BIT_6 | BIT_7); \
123 REG_CPC_NFCEN |= BIT_4 | BIT_5; \
124 REG_CPC_NFCEN &= ~(BIT_6 | BIT_7); \
125 REG_CPC_NFWEN |= BIT_4 | BIT_5; \
126 REG_CPC_NFWEN &= ~(BIT_6 | BIT_7); \
127 REG_CPC_NFREN |= BIT_4 | BIT_5; \
128 REG_CPC_NFREN &= ~(BIT_6 | BIT_7); \
129 REG_CPC_NFD0 |= BIT_4 | BIT_5; \
130 REG_CPC_NFD0 &= ~(BIT_6 | BIT_7); \
131 REG_CPC_NFD1 |= BIT_4 | BIT_5; \
132 REG_CPC_NFD1 &= ~(BIT_6 | BIT_7); \
133 REG_CPC_NFD2 |= BIT_4 | BIT_5; \
134 REG_CPC_NFD2 &= ~(BIT_6 | BIT_7); \
135 REG_CPC_NFD3 |= BIT_4 | BIT_5; \
136 REG_CPC_NFD3 &= ~(BIT_6 | BIT_7); \
137 REG_CPC_NFD4 |= BIT_4 | BIT_5; \
138 REG_CPC_NFD4 &= ~(BIT_6 | BIT_7); \
139 REG_CPC_NFD5 |= BIT_4 | BIT_5; \
140 REG_CPC_NFD5 &= ~(BIT_6 | BIT_7); \
141 REG_CPC_NFD6 |= BIT_4 | BIT_5; \
142 REG_CPC_NFD6 &= ~(BIT_6 | BIT_7); \
143 REG_CPC_NFD7 |= BIT_4 | BIT_5; \
144 REG_CPC_NFD7 &= ~(BIT_6 | BIT_7); \
145 REG_CPC_NFD8 |= BIT_4 | BIT_5; \
146 REG_CPC_NFD8 &= ~(BIT_6 | BIT_7); \
147 REG_CPC_NFD9 |= BIT_4 | BIT_5 | BIT_6; \
148 REG_CPC_NFD9 &= ~(BIT_7); \
149 REG_CPC_NFD10 |= BIT_4 | BIT_5 | BIT_6; \
150 REG_CPC_NFD10 &= ~(BIT_7); \
151 REG_CPC_NFD11 |= BIT_4 | BIT_5 | BIT_6; \
152 REG_CPC_NFD11 &= ~(BIT_7); \
153 REG_CPC_NFD12 |= BIT_4 | BIT_5 | BIT_6; \
154 REG_CPC_NFD12 &= ~(BIT_7); \
155 REG_CPC_NFD13 |= BIT_4 | BIT_5 | BIT_6; \
156 REG_CPC_NFD13 &= ~(BIT_7); \
157 REG_CPC_NFD14 |= BIT_4 | BIT_5 | BIT_6; \
158 REG_CPC_NFD14 &= ~(BIT_7); \
159 REG_CPC_NFD15 |= BIT_4 | BIT_5 | BIT_6; \
160 REG_CPC_NFD15 &= ~(BIT_7); \
164 struct sprd_platform_nand {
165 /* timing information for nand flash controller */
175 struct sprd_nand_address {
182 struct sprd_nand_info {
183 struct sprd_platform_nand *platform;
191 } sprd_nand_wr_mode_t;
198 } sprd_nand_area_mode_t;
200 static struct mtd_info *sprd_mtd = NULL;
201 static unsigned long g_cmdsetting = 0;
202 static sprd_nand_wr_mode_t sprd_wr_mode = NO_OP;
203 static sprd_nand_area_mode_t sprd_area_mode = NO_AREA;
204 static unsigned long nand_flash_id = 0;
205 static struct sprd_nand_address sprd_colrow_addr = {0, 0, 0, 0};
206 static __attribute__((aligned(4))) unsigned char io_wr_port[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE];
207 static nand_ecc_modes_t sprd_ecc_mode = NAND_ECC_NONE;
208 #ifdef CONFIG_SC8800G
209 static unsigned long g_buswidth = 0; /* 0: X8 bus width 1: X16 bus width */
210 static unsigned long g_addr_cycle = 4; /* advance 0 : can be set 3 or 4; advance 1: can be set 4 or 5 */
212 static unsigned long g_buswidth = 1; /* 0: X8 bus width 1: X16 bus width */
213 static unsigned long g_addr_cycle = 5; /* advance 0 : can be set 3 or 4; advance 1: can be set 4 or 5 */
216 #define NF_RESET 0xFF
217 #define NF_READ_STATUS 0x70
218 #define NF_READ_ID 0x90
220 static int nfc_wait_command_finish(void)
222 unsigned long nfc_cmd = REG_NFC_CMD;
223 unsigned long counter = 0;
225 while ((nfc_cmd & (0x1 << 31)) && (counter < NF_TIMEOUT_VAL)) {
226 nfc_cmd = REG_NFC_CMD;
230 if (NF_TIMEOUT_VAL == counter) {
237 static void nfc_reset(void)
239 unsigned long cmd = NF_RESET | (0x1 << 31);
242 nfc_wait_command_finish();
245 static unsigned long nfc_read_status(void)
247 unsigned long status = 0;
248 unsigned long cmd = NF_READ_STATUS | (0x1 << 31);
251 nfc_wait_command_finish();
253 status = REG_NFC_IDSTATUS;
257 static unsigned long nfc_read_id(void)
259 unsigned long id = 0;
260 unsigned long cmd = NF_READ_ID | (0x1 << 31);
263 nfc_wait_command_finish();
265 id = REG_NFC_IDSTATUS;
267 printk("\n%s %s %d id = 0x%08x\n", __FILE__, __FUNCTION__, __LINE__, id);
276 static unsigned long nand_bit_width(unsigned long id)
278 unsigned long bw = (id & 0x40000000) >> 30;
281 static void set_nfc_param(unsigned long ahb_clk)
285 nfc_wait_command_finish();
286 // local_irq_save(flags);
290 REG_NFC_PARA = NF_PARA_20M;
294 REG_NFC_PARA = NF_PARA_40M;
298 REG_NFC_PARA = NF_PARA_53M;
302 REG_NFC_PARA = NF_PARA_80M;
306 REG_NFC_PARA = NF_PARA_DEFAULT;
309 // local_irq_restore(flags);
313 static void nand_copy(unsigned char *src, unsigned char *dst, unsigned long len)
316 unsigned long *pDst_32, *pSrc_32;
317 unsigned short *pDst_16, *pSrc_16;
318 unsigned long flag = 0;
320 flag = (unsigned long *)dst;
324 case 0://word alignment
326 printf("%s %d\n", __FUNCTION__, __LINE__);
328 pDst_32 = (unsigned long *)dst;
329 pSrc_32 = (unsigned long *)src;
330 for (i = 0; i < (len / 4); i++) {
336 case 2://half word alignment
338 printf("%s %d\n", __FUNCTION__, __LINE__);
340 pDst_16 = (unsigned short *)dst;
341 pSrc_16 = (unsigned short *)src;
342 for (i = 0; i < (len / 2); i++) {
348 default://byte alignment
350 printf("%s %d\n", __FUNCTION__, __LINE__);
352 for (i = 0; i < len; i++) {
361 #ifdef CONFIG_NAND_SPL
362 static u_char nand_read_byte(struct mtd_info *mtd)
364 struct nand_chip *this = mtd->priv;
365 return readb(this->IO_ADDR_R);
367 static u_char nand_read_byte16(struct mtd_info *mtd)
369 struct nand_chip *this = mtd->priv;
370 #ifdef CONFIG_MTD_NAND_SPRD
371 return (uint8_t)readl(this->IO_ADDR_R);
373 return readb(this->IO_ADDR_R);
377 static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
380 struct nand_chip *this = mtd->priv;
382 #ifdef CONFIG_MTD_NAND_SPRD
383 nand_copy(buf,this->IO_ADDR_W, len);
385 for (i = 0; i < len; i++)
386 writeb(buf[i], this->IO_ADDR_W);
390 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
393 struct nand_chip *this = mtd->priv;
394 #ifdef CONFIG_MTD_NAND_SPRD
395 nand_copy(this->IO_ADDR_R, buf, len);
397 for (i = 0; i < len; i++)
398 buf[i] = readb(this->IO_ADDR_R);
403 static int sprd_nand_inithw(struct sprd_nand_info *info, struct platform_device *pdev)
406 struct sprd_platform_nand *plat = to_nand_plat(pdev);
407 unsigned long para = (plat->acs << 0) |
415 writel(para, NFCPARAMADDR);
422 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
423 void * memset(void * s, int c, size_t len)
426 char *xs = (char *)s;
429 for(i = 0; i<len; i++)
436 static void sprd_nand_hwcontrol(struct mtd_info *mtd, int cmd,
439 unsigned long phyblk, pageinblk, pageperblk;
441 // unsigned long addr_cycle = 5; /* advance 0 : can be set 3 or 4; advance 1: can be set 4 or 5 */
442 unsigned long advance = 1; /* can be set 0 or 1 */
443 unsigned long pagetype; /* 0: small page; 1: large page*/
444 // unsigned long buswidth = 1; /* 0: X8 bus width 1: X16 bus width */
445 unsigned long chipsel = 0;
446 unsigned long buswidth = g_buswidth;
447 unsigned long addr_cycle = g_addr_cycle;
448 //static unsigned long readaaa = 0;
449 struct nand_chip *this = (struct nand_chip *)(mtd->priv);
450 if (cmd == NAND_CMD_NONE)
453 if (512 == mtd->writesize)
459 else if((addr_cycle == 4) &&(advance == 1))
464 if (ctrl & NAND_CLE) {
467 REG_NFC_CMD = cmd | (0x1 << 31);
468 nfc_wait_command_finish();
470 case NAND_CMD_STATUS:
471 REG_NFC_CMD = cmd | (0x1 << 31);
472 nfc_wait_command_finish();
474 memset((unsigned char *)(this->IO_ADDR_R), 0xff, NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE);
475 nand_copy((unsigned char *)NFC_IDSTATUS, this->IO_ADDR_R, 4);
477 /* transfer to big endian */
478 i = io_wr_port[3]; io_wr_port[3] = io_wr_port[0]; io_wr_port[0] = i;
479 i = io_wr_port[2]; io_wr_port[2] = io_wr_port[1]; io_wr_port[1] = i;
482 for (i = 0; i < 4; i++)
483 printf("io_wr_port[%d] = 0x%02x\n", i, io_wr_port[i]);
486 case NAND_CMD_READID:
487 REG_NFC_CMD = cmd | (0x1 << 31);
488 nfc_wait_command_finish();
489 nand_flash_id = REG_NFC_IDSTATUS;
491 printf("nand id: %x\n", nand_flash_id);
494 case NAND_CMD_ERASE1:
495 sprd_colrow_addr.column = 0;
496 sprd_colrow_addr.row = 0;
497 sprd_colrow_addr.colflag = 0;
498 sprd_colrow_addr.rowflag = 0;
500 case NAND_CMD_ERASE2:
501 if ((0 == sprd_colrow_addr.colflag) && (0 == sprd_colrow_addr.rowflag)) {
502 printf("erase address error!\n");
505 if (1 == sprd_colrow_addr.colflag) {
506 sprd_colrow_addr.row = sprd_colrow_addr.column;
507 sprd_colrow_addr.column = 0;
508 sprd_colrow_addr.rowflag = 1;
509 sprd_colrow_addr.colflag = 0;
513 if ((0 == sprd_colrow_addr.colflag) && (1 == sprd_colrow_addr.rowflag)) {
514 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
516 REG_NFC_STR0 = sprd_colrow_addr.row * mtd->writesize;
518 REG_NFC_STR0 = sprd_colrow_addr.row * mtd->writesize * 2;
520 REG_NFC_CMD = g_cmdsetting | NAND_CMD_ERASE1;
521 nfc_wait_command_finish();
525 sprd_colrow_addr.column = 0;
526 sprd_colrow_addr.row = 0;
527 sprd_colrow_addr.colflag = 0;
528 sprd_colrow_addr.rowflag = 0;
529 sprd_wr_mode = READ_OP;
530 sprd_area_mode = NO_AREA;
531 memset(io_wr_port, 0xff, NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE);
533 case NAND_CMD_READSTART:
535 if (sprd_colrow_addr.column == (mtd->writesize >> 1)) {
536 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
537 REG_NFC_CMD = g_cmdsetting | NAND_CMD_READ0;
538 nfc_wait_command_finish();
539 nand_copy((unsigned long *)NFC_SBUF, (unsigned long *)io_wr_port, mtd->oobsize);
541 } else if (sprd_colrow_addr.column == 0) {
542 if (sprd_area_mode == DATA_AREA)
543 sprd_area_mode = DATA_OOB_AREA;
545 if (sprd_area_mode == DATA_OOB_AREA) {
546 REG_NFC_END0 = 0xffffffff;
547 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (1 << 21) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
548 REG_NFC_CMD = g_cmdsetting | NAND_CMD_READ0;
549 nfc_wait_command_finish();
550 nand_copy((unsigned char *)NFC_MBUF, io_wr_port, mtd->writesize);
551 } else if (sprd_colrow_addr.column == DATA_AREA) {
552 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
553 REG_NFC_CMD = g_cmdsetting | NAND_CMD_READ0;
554 nfc_wait_command_finish();
556 nand_copy((unsigned char *)NFC_MBUF, io_wr_port, mtd->writesize);
559 printf("Operation !!! area. %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
560 } else { //if (buswidth == 1)
561 if (sprd_colrow_addr.column == mtd->writesize) {
562 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | \
563 (pagetype << 18) | (0 << 16) | (0x1 << 31);
564 REG_NFC_CMD = g_cmdsetting | NAND_CMD_READ0;
565 nfc_wait_command_finish();
566 nand_copy((unsigned char *)NFC_SBUF, io_wr_port, mtd->oobsize);
568 /*for (i = 0; i < mtd->oobsize; i++)
569 printk(" Rport[%d]=%d ", i, io_wr_port[i]);*/
570 } else if (sprd_colrow_addr.column == 0) {
571 if (sprd_area_mode == DATA_AREA)
572 sprd_area_mode = DATA_OOB_AREA;
574 if (sprd_area_mode == DATA_OOB_AREA) {
575 /* read data and spare area, modify address */
576 REG_NFC_END0 = 0xffffffff;
577 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | \
578 (1 << 21) | (buswidth << 19) | (pagetype << 18) | \
579 (0 << 16) | (0x1 << 31);
581 REG_NFC_CMD = g_cmdsetting | NAND_CMD_READ0;
582 nfc_wait_command_finish();
584 nand_copy((unsigned char *)NFC_MBUF, io_wr_port, mtd->writesize);
589 static int readaaa = 0;
591 printk("\nREADPAGE\n");
592 for (i = 0; i < mtd->writesize; i++)
593 printk(",0x%02x", io_wr_port[i]);
600 } else if (sprd_colrow_addr.column == DATA_AREA) {
601 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | \
602 (buswidth << 19) | (pagetype << 18) | \
603 (0 << 16) | (0x1 << 31);
604 REG_NFC_CMD = g_cmdsetting | NAND_CMD_READ0;
605 nfc_wait_command_finish();
607 nand_copy((unsigned char *)NFC_MBUF, io_wr_port, mtd->writesize);
608 /*for (i = 0; i < mtd->writesize; i++)
609 printk(" Rport[%d]=%d ", i, io_wr_port[i]);*/
612 printk("Operation !!! area. %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
615 sprd_wr_mode = NO_OP;
616 sprd_area_mode = NO_AREA;
619 sprd_colrow_addr.column = 0;
620 sprd_colrow_addr.row = 0;
621 sprd_colrow_addr.colflag = 0;
622 sprd_colrow_addr.rowflag = 0;
623 sprd_wr_mode = WRITE_OP;
624 sprd_area_mode = NO_AREA;
625 memset(io_wr_port, 0xff, NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE);
627 case NAND_CMD_PAGEPROG:
630 if (sprd_colrow_addr.column == (mtd->writesize >> 1)) {
631 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
632 nand_copy((unsigned long *)io_wr_port, (unsigned long *)NFC_SBUF, mtd->oobsize);
633 REG_NFC_CMD = g_cmdsetting | NAND_CMD_SEQIN;
634 nfc_wait_command_finish();
635 } else if (sprd_colrow_addr.column == 0) {
637 if (sprd_area_mode == DATA_OOB_AREA) {
638 REG_NFC_END0 = 0xffffffff;
639 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
642 REG_NFC_CMD = g_cmdsetting | NAND_CMD_SEQIN;
643 nfc_wait_command_finish();
645 } else if (sprd_colrow_addr.column == DATA_AREA) {
646 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
647 nand_copy(io_wr_port, (unsigned char *)NFC_MBUF, mtd->writesize);
648 REG_NFC_CMD = g_cmdsetting | NAND_CMD_SEQIN;
649 nfc_wait_command_finish();
652 printf("Operation !!! area. %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
653 } else { //if (buswidth == 1)
654 if (sprd_colrow_addr.column == mtd->writesize) {
655 /*for (i = 0; i < mtd->oobsize; i++)
656 printk(" Wport[%d]=%d ", i, io_wr_port[i]);*/
658 g_cmdsetting = (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | \
659 (pagetype << 18) | (0 << 16) | (0x1 << 31);
660 nand_copy(io_wr_port, (unsigned char *)NFC_SBUF, mtd->oobsize);
661 REG_NFC_CMD = g_cmdsetting | NAND_CMD_SEQIN;
662 nfc_wait_command_finish();
663 } else if (sprd_colrow_addr.column == 0) {
664 if (sprd_area_mode == DATA_OOB_AREA) {
665 /* write data and spare area, modify address */
666 REG_NFC_END0 = 0xffffffff;
667 g_cmdsetting = (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | \
668 (pagetype << 18) | (0 << 16) | (0x1 << 31);
670 REG_NFC_CMD = g_cmdsetting | NAND_CMD_SEQIN;
671 nfc_wait_command_finish();
673 } else if (sprd_colrow_addr.column == DATA_AREA) {
674 g_cmdsetting = (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | \
675 (pagetype << 18) | (0 << 16) | (0x1 << 31);
677 //nand_copy(this->IO_ADDR_W, (unsigned char *)NFC_MBUF, mtd->writesize);
678 nand_copy(io_wr_port, (unsigned char *)NFC_MBUF, mtd->writesize);
679 REG_NFC_CMD = g_cmdsetting | NAND_CMD_SEQIN;
680 nfc_wait_command_finish();
683 printk("Operation !!! area. %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
686 sprd_wr_mode = NO_OP;
687 sprd_area_mode = NO_AREA;
693 if (0 == sprd_colrow_addr.colflag) {
694 sprd_colrow_addr.colflag = 1;
695 sprd_colrow_addr.column = cmd;
699 if (0 == sprd_colrow_addr.rowflag) {
700 sprd_colrow_addr.rowflag = 1;
701 sprd_colrow_addr.row = cmd;
704 if ((1 == sprd_colrow_addr.colflag) && (1 == sprd_colrow_addr.rowflag)) {
707 if (sprd_colrow_addr.column == (mtd->writesize >> 1)) {
708 pageperblk = mtd->erasesize / mtd->writesize;
710 phyblk = sprd_colrow_addr.row / pageperblk;
711 pageinblk = sprd_colrow_addr.row % pageperblk;
712 REG_NFC_STR0 = phyblk * pageperblk * mtd->writesize +
713 pageinblk * mtd->writesize +
714 sprd_colrow_addr.column;
715 REG_NFC_END0 = phyblk * pageperblk * mtd->writesize +
716 pageinblk * mtd->writesize +
717 sprd_colrow_addr.column + (mtd->oobsize >> 1) -1;
718 sprd_area_mode = OOB_AREA;
720 } else if (sprd_colrow_addr.column == 0) {
721 pageperblk = mtd->erasesize / mtd->writesize;
722 phyblk = sprd_colrow_addr.row / pageperblk;
723 pageinblk = sprd_colrow_addr.row % pageperblk;
724 REG_NFC_STR0 = phyblk * pageperblk * mtd->writesize +
725 pageinblk * mtd->writesize +
726 sprd_colrow_addr.column;
727 REG_NFC_END0 = phyblk * pageperblk * mtd->writesize +
728 pageinblk * mtd->writesize +
729 sprd_colrow_addr.column + (mtd->writesize >> 1) - 1;
730 sprd_area_mode = DATA_AREA;
732 printf("Operation ??? area. %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
733 } else { //if (buswidth == 0) {
734 if (sprd_colrow_addr.column == mtd->writesize) {
735 pageperblk = mtd->erasesize / mtd->writesize;
736 phyblk = sprd_colrow_addr.row / pageperblk;
737 pageinblk = sprd_colrow_addr.row % pageperblk;
739 REG_NFC_STR0 = phyblk * pageperblk * mtd->writesize * 2 +
740 pageinblk * mtd->writesize * 2 +
741 sprd_colrow_addr.column;
742 REG_NFC_END0 = phyblk * pageperblk * mtd->writesize * 2 +
743 pageinblk * mtd->writesize * 2 +
744 sprd_colrow_addr.column + mtd->oobsize -1;
745 sprd_area_mode = OOB_AREA;
746 /*printk("Operation OOB area. %s %s %d row=0x%08x column=0x%08x\n",
747 __FILE__, __FUNCTION__, __LINE__, sprd_colrow_addr.row, sprd_colrow_addr.column);*/
748 } else if (sprd_colrow_addr.column == 0) {
749 pageperblk = mtd->erasesize / mtd->writesize;
750 phyblk = sprd_colrow_addr.row / pageperblk;
751 pageinblk = sprd_colrow_addr.row % pageperblk;
753 printf("function: %s pageperblk: 0x%x phyblk: 0x%x pageinblk: 0x%x\n", __FUNCTION__, pageperblk, phyblk, pageinblk);
756 REG_NFC_STR0 = phyblk * pageperblk * mtd->writesize * 2 +
757 pageinblk * mtd->writesize * 2 +
758 sprd_colrow_addr.column;
759 REG_NFC_END0 = phyblk * pageperblk * mtd->writesize * 2 +
760 pageinblk * mtd->writesize * 2 +
761 sprd_colrow_addr.column + mtd->writesize - 1;
762 sprd_area_mode = DATA_AREA;
763 /*printk("Operation DATA area. %s %s %d row=0x%08x column=0x%08x\n",
764 __FILE__, __FUNCTION__, __LINE__, sprd_colrow_addr.row, sprd_colrow_addr.column);*/
766 printk("Operation ??? area for 8 Bits. %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
773 static unsigned long sprd_nand_readid(struct mtd_info *mtd)
775 return(nand_flash_id);
778 static int sprd_nand_devready(struct mtd_info *mtd)
780 unsigned long status = 0;
781 unsigned long cmd = NAND_CMD_STATUS | (0x1 << 31);
784 nfc_wait_command_finish();
786 status = REG_NFC_IDSTATUS;
787 if ((status & 0x1) != 0)
788 return -1; /* fail */
789 else if ((status & 0x40) == 0)
792 return 1; /* ready */
794 static void sprd_nand_select_chip(struct mtd_info *mtd, int chip)
796 struct nand_chip *this = mtd->priv;
797 struct sprd_nand_info *info = this->priv;
801 clk_enable(info->clk);
803 clk_disable(info->clk);
807 static void sprd_nand_enable_hwecc(struct mtd_info *mtd, int mode)
809 sprd_ecc_mode = mode;
812 static unsigned long sprd_nand_wr_oob(struct mtd_info *mtd)
815 nand_copy(io_wr_port, (unsigned char *)NFC_SBUF, mtd->oobsize);
817 printf("%s\n", __FUNCTION__);
819 printf("%x ", io_wr_port[i]);
825 if (sprd_area_mode == NO_AREA)
826 sprd_area_mode = OOB_AREA;
827 else if (sprd_area_mode == DATA_AREA)
828 sprd_area_mode = DATA_OOB_AREA;
833 void nand_ecc_trans(unsigned char *pEccIn, unsigned char *pEccOut, unsigned char nSct)
840 pEccOut[0] = pEccIn[0];
841 pEccOut[1] = pEccIn[1];
842 pEccOut[2] = pEccIn[2];
845 pEccOut[0] = pEccIn[0];
846 pEccOut[1] = pEccIn[1];
847 pEccOut[2] = pEccIn[2];
848 pEccOut[4] = pEccIn[4];
849 pEccOut[5] = pEccIn[5];
850 pEccOut[6] = pEccIn[6];
853 pEccOut[0] = pEccIn[0];
854 pEccOut[1] = pEccIn[1];
855 pEccOut[2] = pEccIn[2];
856 pEccOut[4] = pEccIn[4];
857 pEccOut[5] = pEccIn[5];
858 pEccOut[6] = pEccIn[6];
859 pEccOut[8] = pEccIn[8];
860 pEccOut[9] = pEccIn[9];
861 pEccOut[10] = pEccIn[10];
864 pEccOut[0] = pEccIn[0];
865 pEccOut[1] = pEccIn[1];
866 pEccOut[2] = pEccIn[2];
867 pEccOut[4] = pEccIn[4];
868 pEccOut[5] = pEccIn[5];
869 pEccOut[6] = pEccIn[6];
870 pEccOut[8] = pEccIn[8];
871 pEccOut[9] = pEccIn[9];
872 pEccOut[10] = pEccIn[10];
873 pEccOut[12] = pEccIn[12];
874 pEccOut[13] = pEccIn[13];
875 pEccOut[14] = pEccIn[14];
885 pEccOut[0] = pEccIn[2];
886 pEccOut[1] = pEccIn[1];
887 pEccOut[2] = pEccIn[3];
890 pEccOut[0] = pEccIn[2];
891 pEccOut[1] = pEccIn[1];
892 pEccOut[2] = pEccIn[3];
893 pEccOut[4] = pEccIn[6];
894 pEccOut[5] = pEccIn[5];
895 pEccOut[6] = pEccIn[7];
898 pEccOut[0] = pEccIn[2];
899 pEccOut[1] = pEccIn[1];
900 pEccOut[2] = pEccIn[3];
901 pEccOut[4] = pEccIn[6];
902 pEccOut[5] = pEccIn[5];
903 pEccOut[6] = pEccIn[7];
904 pEccOut[8] = pEccIn[10];
905 pEccOut[9] = pEccIn[9];
906 pEccOut[10] = pEccIn[11];
909 pEccOut[0] = pEccIn[2];
910 pEccOut[1] = pEccIn[1];
911 pEccOut[2] = pEccIn[3];
912 pEccOut[4] = pEccIn[6];
913 pEccOut[5] = pEccIn[5];
914 pEccOut[6] = pEccIn[7];
915 pEccOut[8] = pEccIn[10];
916 pEccOut[9] = pEccIn[9];
917 pEccOut[10] = pEccIn[11];
918 pEccOut[12] = pEccIn[14];
919 pEccOut[13] = pEccIn[13];
920 pEccOut[14] = pEccIn[15];
928 static int sprd_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
930 unsigned long *pecc_val;
933 pecc_val=(unsigned long*)ecc_code;
935 if (sprd_ecc_mode == NAND_ECC_WRITE) {
937 nand_copy(io_wr_port, (unsigned char *)NFC_MBUF, mtd->writesize);
939 pecc_val[0] = REG_NFC_PAGEECC0;
940 pecc_val[1] = REG_NFC_PAGEECC1;
941 pecc_val[2] = REG_NFC_PAGEECC2;
942 pecc_val[3] = REG_NFC_PAGEECC3;
944 static unsigned int print_times =0;
945 if(print_times < 10){
946 for(i= 0; i< mtd->writesize;i++){
947 printf("%02x ", dat[i]);
953 for(i = 0; i< 4; i++)
954 printf("write ecc %d is %x\n", i, pecc_val[i]);
957 memset(io_wr_port, 0xff, NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE);
958 } else if (sprd_ecc_mode == NAND_ECC_READ) {
960 pecc_val[0] = REG_NFC_PAGEECC0;
961 pecc_val[1] = REG_NFC_PAGEECC1;
962 pecc_val[2] = REG_NFC_PAGEECC2;
963 pecc_val[3] = REG_NFC_PAGEECC3;
965 for(i = 0; i< 4; i++)
966 printf("read ecc %d is %x\n", i, pecc_val[i]);
969 memset(io_wr_port, 0xff, NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE);
970 nand_copy((unsigned char *)NFC_SBUF, io_wr_port, mtd->oobsize);
973 printf("read oob \n");
974 for(i = 0; i<16; i++){
975 printf("%x ", ecc_code[i]);
981 sprd_ecc_mode = NAND_ECC_NONE;
986 static int countbits(unsigned long byte)
990 for (;byte; byte >>= 1)
994 static void ecc_trans(unsigned char *ecc)
1005 static int ECC_CompM(unsigned char *pEcc1, unsigned char *pEcc2, unsigned char *pBuf, unsigned char nBW)
1007 unsigned long nEccComp = 0, nEccSum = 0;
1008 unsigned long nEBit = 0;
1009 unsigned long nEByte = 0;
1010 unsigned long nXorT1 = 0, nXorT2 = 0;
1013 for (nCnt = 0; nCnt < 2; nCnt++) {
1014 nXorT1 ^= (((*pEcc1) >> nCnt) & 0x01);
1015 nXorT2 ^= (((*pEcc2) >> nCnt) & 0x01);
1018 for (nCnt = 0; nCnt < 3; nCnt++) {
1019 nEccComp |= ((~pEcc1[nCnt] ^ ~pEcc2[nCnt]) << (nCnt * 8));
1021 for(nCnt = 0; nCnt < 24; nCnt++) {
1022 nEccSum += ((nEccComp >> nCnt) & 0x01);
1025 printf("function: %s line: %d nEccSum: %d\n", __FUNCTION__, __LINE__, nEccSum);
1033 if (nXorT1 != nXorT2) {
1038 nEByte = ((nEccComp >> 9) & 0x100) +
1039 ((nEccComp >> 8) & 0x80) + ((nEccComp >> 7) & 0x40) +
1040 ((nEccComp >> 6) & 0x20) + ((nEccComp >> 5) & 0x10) +
1041 ((nEccComp >> 4) & 0x08) + ((nEccComp >> 3) & 0x04) +
1042 ((nEccComp >> 2) & 0x02) + ((nEccComp >> 1) & 0x01);
1043 nEBit = ((nEccComp >> 21) & 0x04) +
1044 ((nEccComp >> 20) & 0x02) + ((nEccComp >> 19) & 0x01);
1045 } else */{ /* (nBW == BW_X16) */
1046 nEByte = ((nEccComp >> 7) & 0x100) +
1047 ((nEccComp >> 6) & 0x80) + ((nEccComp >> 5) & 0x40) +
1048 ((nEccComp >> 4) & 0x20) + ((nEccComp >> 3) & 0x10) +
1049 ((nEccComp >> 2) & 0x08) + ((nEccComp >> 1) & 0x04) +
1050 (nEccComp & 0x02) + ((nEccComp >> 23) & 0x01);
1051 nEBit = (unsigned char)(((nEccComp >> 19) & 0x04) +
1052 ((nEccComp >> 18) & 0x02) + ((nEccComp >> 17) & 0x01));
1055 pBuf[nEByte] = (unsigned char)(pBuf[nEByte] ^ (1 << nEBit));
1066 static int correct(u_char *dat, u_char *read_ecc, u_char *calc_ecc)
1068 #ifdef CONFIG_SC8800G
1069 ecc_trans(read_ecc);
1070 ecc_trans(calc_ecc);
1072 return ECC_CompM(read_ecc, calc_ecc, dat, 1);
1077 static int sprd_nand_correct_data(struct mtd_info *mtd, uint8_t *dat,
1078 uint8_t *read_ecc, uint8_t *calc_ecc)
1082 if (mtd->writesize > 512) {
1083 for (i = 0; i < 4; i++) {
1084 if (correct(dat + 512 * i, read_ecc + 4*i + 1, calc_ecc + 4*i + 1) == -1) {
1089 retval = correct(dat, read_ecc, calc_ecc);
1094 static int sprd_nand_correct_data(struct mtd_info *mtd, uint8_t *dat,
1095 uint8_t *read_ecc, uint8_t *calc_ecc)
1098 int retval0, retval1, retval2, retval3;
1100 printk("\nthe all data\n");
1101 for(i = 0; i < 2048; i++) {
1102 printk("%02x ", *(dat + i));
1107 printk("\nthe read ecc\n");
1108 for(i = 0; i < 16; i ++) {
1109 printk("%02x ", *(read_ecc + i));
1114 printk("\nthe calc ecc\n");
1115 for(i = 0; i < 16; i ++) {
1116 printk("%02x ", *(calc_ecc + i));
1121 if (mtd->writesize > 512) {
1123 for (i = 0; i < 4; i++) {
1124 if (correct(dat + 512 * i, read_ecc + 4 * i, calc_ecc + 4 * i) == -1) {
1129 retval0 = correct(dat + 512 * 0, read_ecc + 4 * 0, calc_ecc + 4 * 0);
1130 retval1 = correct(dat + 512 * 1, read_ecc + 4 * 1, calc_ecc + 4 * 1);
1131 retval2 = correct(dat + 512 * 2, read_ecc + 4 * 2, calc_ecc + 4 * 2);
1132 retval3 = correct(dat + 512 * 3, read_ecc + 4 * 3, calc_ecc + 4 * 3);
1134 printf("function: %s retval0: %d\n", __FUNCTION__, retval0);
1135 printf("function: %s retval1: %d\n", __FUNCTION__, retval1);
1136 printf("function: %s retval2: %d\n", __FUNCTION__, retval2);
1137 printf("function: %s retval3: %d\n", __FUNCTION__, retval3);
1140 if ((retval0 == -1) || (retval1 == -1) || (retval2 == -1) || (retval3 == -1))
1143 retval = retval0 + retval1 + retval2 + retval3;
1146 retval = correct(dat, read_ecc, calc_ecc);
1149 printf("function: %s retval: %d\n", __FUNCTION__, retval);
1156 static struct sprd_nand_info g_info = {0,0};
1157 static struct sprd_platform_nand g_plat = {0};
1159 int board_nand_init(struct nand_chip *this)
1161 //struct mtd_info *mtd;
1162 unsigned long i, id, type;
1163 volatile int ik_cnt = 0;
1165 /*structs must be linked */
1167 // mtd->priv = this;
1168 //host->nand = this;
1170 g_info.platform = &g_plat;
1171 /* set sprd_colrow_addr */
1172 sprd_colrow_addr.column = 0;
1173 sprd_colrow_addr.row = 0;
1174 sprd_colrow_addr.colflag = 0;
1175 sprd_colrow_addr.rowflag = 0;
1176 sprd_wr_mode = NO_OP;
1177 sprd_area_mode = NO_AREA;
1178 sprd_ecc_mode = NAND_ECC_NONE;
1180 REG_AHB_CTL0 |= BIT_8;//no BIT_9
1181 REG_AHB_SOFT_RST |= BIT_5;
1182 for(ik_cnt = 0; ik_cnt < 0xffff; ik_cnt++);
1183 REG_AHB_SOFT_RST &= ~BIT_5;
1184 REG_NFC_INTSRC |= BIT_0 | BIT_4 | BIT_5;
1185 /* 0x1 : WPN disable, and micron nand flash status is 0xeo
1186 * 0x0 : WPN enable, and micron nand flash status is 0x60 */
1189 set_sc8800g_gpio_as_nand_8bit();
1190 set_nfc_param(0);//53MHz
1191 memset(io_wr_port, 0xff, NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE);
1196 for(ik_cnt = 0; ik_cnt < 0xfffff; ik_cnt++)
1200 type = nand_bit_width(id);
1203 this->options |= NAND_BUSWIDTH_16;
1214 /* set the timing for nand controller */
1215 /* 16-bit bus width */
1216 this->IO_ADDR_R = this->IO_ADDR_W = io_wr_port;
1217 this->cmd_ctrl = sprd_nand_hwcontrol;
1218 this->dev_ready = sprd_nand_devready;
1219 this->select_chip = sprd_nand_select_chip;
1221 #ifdef CONFIG_NAND_SPL
1222 this->read_byte = nand_read_byte;
1223 this->write_buf = nand_write_buf;
1224 this->read_buf = nand_read_buf;
1226 this->nfc_readid = sprd_nand_readid;
1227 this->nfc_wr_oob = sprd_nand_wr_oob;
1229 #ifdef CONFIG_SPRD_NAND_HWECC
1230 this->ecc.calculate = sprd_nand_calculate_ecc;
1231 this->ecc.correct = sprd_nand_correct_data;
1232 this->ecc.hwctl = sprd_nand_enable_hwecc;
1233 this->ecc.mode = NAND_ECC_HW;
1234 this->ecc.size = CONFIG_SYS_NAND_ECCSIZE;//512;
1235 this->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;//3
1237 this->ecc.mode = NAND_ECC_SOFT;
1240 this->chip_delay = 20;
1241 this->priv = &g_info;
1245 int sprd_scan_one_block(int blk, int erasesize, int writesize)
1247 unsigned long phyblk, pageinblk, pageperblk;
1249 //unsigned long addr_cycle = 5; /* advance 0 : can be set 3 or 4; advance 1: can be set 4 or 5 */
1250 unsigned long advance = 1; /* can be set 0 or 1 */
1251 unsigned long pagetype; /* 0: small page; 1: large page*/
1252 //unsigned long buswidth = 1; /* 0: X8 bus width 1: X16 bus width */
1253 unsigned long chipsel = 0;
1254 unsigned long buswidth = g_buswidth;
1255 unsigned long addr_cycle = g_addr_cycle;
1257 unsigned long column = writesize >> 1;
1258 unsigned long row = blk * (erasesize / writesize);
1261 if (512 == writesize)
1266 if (addr_cycle == 3)
1268 else if ((addr_cycle == 4) && (advance == 1))
1273 memset(io_wr_port, 0x0, NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE);
1274 if (buswidth == 1) {
1275 if (column == (writesize >> 1)) {
1276 for (ii = 0; ii < 2; ii ++) {
1278 pageperblk = (erasesize / writesize);
1280 phyblk = row / pageperblk;
1281 pageinblk = row % pageperblk;
1282 //printf("ii = %d phyblk = %d pageinblk = %d\n", ii, phyblk, pageinblk);
1283 REG_NFC_STR0 = phyblk * pageperblk * writesize +
1284 pageinblk * writesize +
1286 REG_NFC_END0 = phyblk * pageperblk * writesize +
1287 pageinblk * writesize +
1288 column + (writesize >> 1) - 1;
1290 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
1291 REG_NFC_CMD = g_cmdsetting | NAND_CMD_READ0;
1292 nfc_wait_command_finish();
1293 nand_copy((unsigned long *)NFC_SBUF, (unsigned long *)io_wr_port, 64);
1294 if ((io_wr_port[0] != 0xff) || (io_wr_port[1] != 0xff))
1300 if ((io_wr_port[0] == 0xff) && (io_wr_port[1] == 0xff))
1301 status = 0; //good block
1303 status = 1; //bad block
1308 int nand_ctl_erase_block(unsigned long addr, int writesize)
1310 unsigned long phyblk, pageinblk, pageperblk;
1312 //unsigned long addr_cycle = 5; /* advance 0 : can be set 3 or 4; advance 1: can be set 4 or 5 */
1313 unsigned long advance = 1; /* can be set 0 or 1 */
1314 unsigned long pagetype; /* 0: small page; 1: large page*/
1315 //unsigned long buswidth = 1; /* 0: X8 bus width 1: X16 bus width */
1316 unsigned long chipsel = 0;
1317 unsigned long buswidth = g_buswidth;
1318 unsigned long addr_cycle = g_addr_cycle;
1321 if (512 == writesize)
1326 if (addr_cycle == 3)
1328 else if ((addr_cycle == 4) && (advance == 1))
1333 g_cmdsetting = (chipsel << 26) | (addr_cycle << 24) | (advance << 23) | (buswidth << 19) | (pagetype << 18) | (0 << 16) | (0x1 << 31);
1335 REG_NFC_STR0 = addr;
1337 REG_NFC_STR0 = addr * 2;
1339 REG_NFC_CMD = g_cmdsetting | NAND_CMD_ERASE1;
1340 nfc_wait_command_finish();
1342 status = nfc_read_status();
1346 void nand_scan_patition(int blocks, int erasesize, int writesize)
1351 //printf("blocks = %d erasesize = 0x%08x\n", blocks, erasesize);
1352 for (blk = 0; blk < blocks; blk ++) {
1353 ret = sprd_scan_one_block(blk, erasesize, writesize);
1355 printf("\n%d is bad, scrub to erase it, ", blk);
1356 ret = nand_ctl_erase_block(blk * erasesize, writesize);
1357 printf("0x%02x\n", ret);
1359 ret = nand_ctl_erase_block(blk * erasesize, writesize);
1360 printf("erasing block : %d %d % \r", blk, (blk * 100 ) / blocks);