blob: a05604e556989d00aa68cf44adef9f27c02a0dea [file] [log] [blame]
xf.libfc6e712025-02-07 01:54:34 -08001/*********************************************************************
2 Copyright 2016 by ZXIC Corporation.
3*
4* FileName:: spifc.c
5* File Mark:
6* Description:
7* Others:
8* Version:
9* Author:
10* Date:
11
12* History 1:
13* Date:
14* Version:
15* Author:
16* Modification:
17* History 2:
18**********************************************************************/
19#include <common.h>
20#include <asm/arch/spifc.h>
21#include <asm/io.h>
22#include <bbt.h>
23
24#include "flash.h"
25
26
27static const struct spi_flash_device_para *spi_flash_info = NULL;
28/* spi flash parameter config */
29static const struct spi_flash_device_para spi_flash_para[] = {
30 /* GIGADEVICE GD5F1GQ4R 128MB 1.8V SPI-NAND */
31 {0xC8, 0xC1, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
32 /* GIGADEVICE GD5F1GQ5RExxG 128MB 1.8V SPI-NAND */
33 {0xC8, 0x41, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
34 /* GIGADEVICE GD5F2GQ4R 256MB SPI-NAND */
35 {0xC8, 0xC2, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
36 /* GIGADEVICE GD5F4GQ4U 512MB SPI-NAND */
37 {0xC8, 0xC4, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
38 /* GIGADEVICE GD5F4GQ6REY2G 512MB SPI-NAND*/
39 {0xC8, 0x45, 0x77, 2048, 11, 128, 17, 4096, 0x20000, 1},
40
41 /* PARAGON PN26Q01AWSIUG 128MB SPI-NAND */
42 {0xA1, 0xC1, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
43 /* PN26Q02AWSIUG 1.8V 2G-BIT SPI NAND */
44 {0xA1, 0xC2, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
45
46 /* HYF1GQ4IAACAE SPI-NAND */
47 {0xC9, 0x51, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
48 /* HYF2GQ4IAACAE SPI-NAND */
49 {0xC9, 0x52, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
50 /*winbond W25N01G*/
51 {0xEF, 0xBA, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
52 /*winbond W25N02G*/
53 {0xEF, 0xBB, 0x77, 2048, 11, 64, 17, 2048, 0x20000, 1},
54 /* TOSHIBA TC58CYG0S3HRAIG 128MB SPI-NAND*/
55 {0x98, 0xB2, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
56 /* TOSHIBA TC58CYG1S3HRAIG 256MB SPI-NAND*/
57 {0x98, 0xBB, 0x77, 2048, 11, 64, 17, 2048, 0x20000, 1},
58 /* ZETTA ZD35X1GAXXX 128MB SPI-NAND*/
59 {0xBA, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
60 /* DOSILICON DS35X1GAXXX 128MB SPI-NAND*/
61 {0xE5, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
62 /* DOSILICON DS35X12BXXX 64MB SPI-NAND*/
63 {0xE5, 0xA5, 0x77, 2048, 11, 128, 17, 512, 0x20000, 1},
64 /* FUDANWEI FM25LS01 128MB SPI-NAND*/
65 {0xA1, 0xA5, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
66 /* hosin HG-SPIXGb-1XAIA 128MB SPI-NAND*/
67 {0xD6, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
68 /* EMST F50D1G41LB (2M) 128MB SPI-NAND */
69 {0xC8, 0x11, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
70 /* FORESEE F35UQA001G 128MB SPI-NAND */
71 {0xCD, 0x61, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
72 /* FORESEE F35UQA512M 64MB SPI-NAND */
73 {0xCD, 0x60, 0x77, 2048, 11, 64, 17, 512, 0x20000, 1},
74 /* micron-MT29F2G01ABAGDWB-ITG 256MB SPI-NAND */
75 {0x2C, 0x25, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 2},
76 /* ESMT F50D44G41XB (2X) 512MB SPI-NAND*/
77 {0x2C, 0x35, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
78 /*XTX XT26Q04D 512M SPI-NAND*/
79 {0x0B, 0x53, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
80 /*UNIM UM19A0LISW 128M SPI-NAND*/
81 {0xB0, 0x15, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
xf.lic1c1f422025-03-12 19:38:15 -070082 /* GD5F4GM8RExxG 512MB SPI-NAND */
83 {0xC8, 0x85, 0x77, 2048, 11, 64, 17, 4096, 0x20000, 1},
xf.libfc6e712025-02-07 01:54:34 -080084 {0}
85};
86
87
88/*
89 ******************************************************************************
90 * Function: spifc_enable
91 * Description:
92 * Parameters:
93 * Input:
94 * Output:
95 * Returns:
96 * Others:
97 *******************************************************************************
98 */
99static void spifc_enable(void)
100{
101 volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
102
103 if( spi->SFC_EN & FC_EN_BACK )
104 return;
105
106 spi->SFC_EN |= FC_EN;
107 spi->SFC_CTRL0 |= FC_SCLK_PAUSE_EN;
108}
109
110/*
111 ******************************************************************************
112 * Function: spifc_clear_fifo
113 * Description:
114 * Parameters:
115 * Input:
116 * Output:
117 * Returns:
118 * Others:
119 *******************************************************************************
120 */
121void spifc_clear_fifo( void )
122{
123 volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
124
125 spi->SFC_CTRL0 |= (FC_RXFIFO_THRES | FC_TXFIFO_THRES |
126 FC_RXFIFO_CLR | FC_TXFIFO_CLR);
127}
128
129
130/*
131 ******************************************************************************
132 * Function: spifc_setup_cmd
133 * Description:
134 * Parameters:
135 * Input:
136 * Output:
137 * Returns:
138 * Others:
139 *******************************************************************************
140 */
141static void spifc_setup_cmd( struct spiflash_cmd_t *cmd,
142 uint32_t addr, uint32_t len )
143{
144 volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
145 uint32_t wrap = 0;
146 uint32_t tmp = 0;
147
148 /* ÃüÁîÂë */
149 spi->SFC_INS = cmd->cmd;
150
151 /* Êý¾Ý³¤¶È */
152 if( len )
153 spi->SFC_BYTE_NUM = len - 1;
154 else
155 spi->SFC_BYTE_NUM = 0;
156
157 switch( len )
158 {
159 case 2048:
160 wrap = WRAP_SIZE_MAIN;
161 break;
162 case 2112:
163 wrap = WRAP_SIZE_MAIN_OOB;;
164 break;
165 case 64:
166 wrap = WRAP_SIZE_OOB;;
167 break;
168 default:
169 wrap = 0;
170 break;
171 }
172
173 /* µØÖ·Âë */
174 switch( spi->SFC_INS )
175 {
176 case CMD_READ_FROM_CACHE:
177 // case CMD_READ_FROM_CACHE_X2:
178 case CMD_READ_FROM_CACHE_X4:
179 case CMD_READ_FROM_CACHE_QIO:
180 case CMD_PROGRAM_LOAD:
181 case CMD_PROGRAM_LOAD_X4:
182 // case CMD_PROGRAM_LOAD_RANDOM:
183 // case CMD_PROGRAM_LOAD_RANDOM_X4:
184 //case CMD_PROGRAM_LOAD_RANDOM_QIO:
185 addr |= wrap;
186 break;
187
188 default:
189 addr = addr;
190 break;
191 }
192 spi->SFC_ADDR = addr;
193
194 /* µØÖ·Âë¡¢¿ÕÖÜÆÚ¡¢¶Á/д ʹÄÜÉèÖà */
195 spi->SFC_CTRL1 = 0;
196 spi->SFC_CTRL1 = ((cmd->addr_tx_en << FC_ADDR_TX_EN) |
197 (cmd->dumy_tx_en << FC_DUMMY_TX_EN) |
198 (cmd->data_rx_en << FC_READ_DAT_EN) |
199 (cmd->data_tx_en << FC_WRITE_DAT_EN));
200
201
202 /* ¿ÕÖÜÆÚÊý¡¢µØÖ·¿í¶È(1£¬2£¬3£¬4×Ö½Ú)¡¢
203 * µØÖ·/Êý¾ÝÏß¶È¡¢´«Êäģʽ
204 */
205#if 0
206 tmp = spi->SFC_CTRL2;
207 tmp &= 0x1f;
208 tmp |= ((cmd->dumy_bytes << FC_DUMMY_BYTE_NUM) |
209 (cmd->dumy_bits << FC_DUMMY_BIT_NUM) |
210 (cmd->addr_width << FC_ADDR_BYTE_NUM));
211 spi->SFC_CTRL2 = tmp;
212#else
213 spi->SFC_CTRL2 = 0;
214 tmp |= ((cmd->dumy_bytes << FC_DUMMY_BYTE_NUM) |
215 (cmd->dumy_bits << FC_DUMMY_BIT_NUM) |
216 (cmd->addr_width << FC_ADDR_BYTE_NUM));
217 tmp &= ~0x700;
218 spi->SFC_CTRL2 = tmp;
219#endif
220
221}
222
223
224/*
225 ******************************************************************************
226 * Function: spifc_clear_int
227 * Description:
228 * Parameters:
229 * Input:
230 * Output:
231 * Returns:
232 * Others:
233 *******************************************************************************
234 */
235 void spifc_clear_int( void )
236{
237 volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
238
239 if(spi->SFC_INT_RAW & 0x2)
240 printf("\n");
241
242 spi->SFC_INT_SW_CLR = 0xFF; //clear int ?
243}
244
245
246/*
247 ******************************************************************************
248 * Function: spifc_wait_cmd_end
249 * Description:
250 * Parameters:
251 * Input:
252 * Output:
253 * Returns:
254 * Others:
255 *******************************************************************************
256 */
257static int spifc_wait_cmd_end( void )
258{
259 volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
260 uint32_t int_status = 0;
261
262 while(!(spi->SFC_INT_RAW & FC_INT_RAW_MASK));
263
264 int_status = spi->SFC_INT_RAW;
265 spi->SFC_INT_SW_CLR = int_status; /* clear intrrupt */
266
267 if(int_status & FC_INT_RAW_CMD_END)
268 {
269 return 0;
270 }
271 else
272 {
273 printf("intr err.\n");
274 return -1;
275 }
276
277}
278
279
280/*
281 ******************************************************************************
282 * Function: spifc_read_fifo_one_byte
283 * Description:
284 * Parameters:
285 * Input:
286 * Output:
287 * Returns:
288 *
289 * Others: only for:
290 [Instruction] |--addr width is 8 bit
291 [addr] |--get feature
292 [data_rx]
293 *******************************************************************************
294 */
295static int spifc_read_fifo_one_byte( uint8_t *value )
296{
297 uint32_t sw = 0;
298 volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
299
300 sw = spi->SFC_SW;
301
302 if( ((sw >> FC_RX_FIFO_CNT) & FC_RX_FIFO_CNT_MASK) != 1 )
303 {
304 return -1;
305 }
306
307 *value = (uint8_t)spi->SFC_DATA;
308
309 return 0;
310}
311
312
313/*
314 ******************************************************************************
315 * Function: spifc_read_fifo
316 * Description:
317 * Parameters:
318 * Input:
319 * Output:
320 * Returns:
321 * Others:
322 *******************************************************************************
323 */
324static uint32_t spifc_read_fifo( uint32_t len, uint8_t *buf )
325{
326 volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
327 uint32_t *p = (uint32_t *)buf;
328 uint32_t cnt = 0;
329
330 while(cnt < ((len+3)>>2))
331 {
332 if(spi->SFC_SW & (FC_RX_FIFO_CNT_MASK<<FC_RX_FIFO_CNT))//rx fifo not empty
333 {
334 p[cnt++]= spi->SFC_DATA;
335 }
336 }
337
338 return (cnt<<2);
339}
340
341
342/*
343 ******************************************************************************
344 * Function: spifc_start
345 * Description:
346 * Parameters:
347 * Input:
348 * Output:
349 * Returns:
350 * Others:
351 *******************************************************************************
352 */
353static void spifc_start( void )
354{
355 volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
356
357 spi->SFC_START |= FC_START;
358}
359
360/*
361 ******************************************************************************
362 * Function: spifc_get_feature
363 * Description:
364 * Parameters:
365 * Input:
366 * Output:
367 * Returns:
368 *
369 * Others: [Instruction] |--addr width is 8 bit
370 [addr] |--get feature
371 [data_rx] |--read id
372
373 *******************************************************************************
374 */
375 static int spifc_get_feature( uint32_t reg_addr, uint8_t *value)
376 {
377 int ret = 0;
378
379 struct spiflash_cmd_t cmd = {CMD_GET_FEATURE,
380 1,
381 FC_ADDR_BYTE_NUM_8,
382 0,
383 1,
384 0,
385 0,
386 0
387 };
388
389 spifc_clear_fifo();
390 spifc_clear_int();
391
392 spifc_setup_cmd(&cmd, reg_addr, 1);
393 spifc_start();
394 ret = spifc_wait_cmd_end();
395 if(ret != 0)
396 {
397 return ret;
398 }
399
400 ret = spifc_read_fifo_one_byte(value);
401 if(ret != 0)
402 {
403 return ret;
404 }
405
406 return 0;
407}
408
409/*
410 ******************************************************************************
411 * Function: spifc_read_id
412 * Description:
413 * Parameters:
414 * Input:
415 * Output:
416 * Returns:
417 *
418 * Others: [Instruction] |--addr width is 8 bit
419 [addr] |--get feature
420 [data_rx] |--read id
421 *******************************************************************************
422 */
423static int spifc_read_id(uint32_t reg_addr, uint8_t *value, uint8_t len)
424{
425 int ret = 0;
426
427 struct spiflash_cmd_t cmd = { CMD_READ_ID,
428 1,
429 FC_ADDR_BYTE_NUM_8,
430 0,
431 1,
432 0,
433 0,
434 0
435 };
436
437 spifc_clear_fifo();
438 spifc_clear_int();
439 spifc_setup_cmd(&cmd, reg_addr, len);
440 spifc_start();
441 ret = spifc_wait_cmd_end();
442 if(ret != 0)
443 {
444 return ret;
445 }
446
447 ret = spifc_read_fifo(len, value);
448 if(ret != 0)
449 {
450 return ret;
451 }
452
453 return 0;
454}
455
456
457/*
458 ******************************************************************************
459 * Function: spifc_read_page_to_cache
460 * Description:
461 * Parameters:
462 * Input:
463 * Output:
464 * Returns:
465 * Others: [Instruction] |--addr width is 24 bit(page/block addr!!!!)
466 [addr] |--page read
467 |--block erase
468 |--program execute
469 *******************************************************************************
470 */
471static int spifc_read_page_to_cache(uint32_t page_addr)
472{
473 int ret = 0;
474 uint8_t status = 0;
475
476 struct spiflash_cmd_t cmd = { CMD_READ_PAGE_TO_CACHE,
477 1,
478 FC_ADDR_BYTE_NUM_24,
479 0,
480 0,
481 0,
482 0,
483 0
484 };
485
486 spifc_clear_fifo();
487 spifc_clear_int();
488 spifc_setup_cmd(&cmd, page_addr, 0);
489 spifc_start();
490 ret = spifc_wait_cmd_end();
491 if(ret != 0)
492 {
493 return ret;
494 }
495
496 do
497 {
498 spifc_get_feature(REG_STATUS, &status);
499 }while( status & OIP);
500
501 return 0;
502}
503
504/*
505 ******************************************************************************
506 * Function: spifc_read_from_cache
507 * Description:
508 * Parameters:
509 * Input:
510 * Output:
511 * Returns:
512 * Others: [Instruction] |--addr width is 16 bit
513 [addr] |--dummy cycel 8/4/2
514 [dummy] |--read form cache(X1,X2,X4)
515 [data_rx] |--read form cache(dual,quad)IO
516 *******************************************************************************
517 */
518static int spifc_read_from_cache(uint32_t column_addr, uint32_t len, uint8_t *buf)
519{
520 int ret = 0;
521
522 uint32_t len_tmp = 0;
523 struct spiflash_cmd_t cmd;
524
525 cmd.cmd = CMD_READ_FROM_CACHE;
526 cmd.dumy_bytes = 1;
527 cmd.dumy_bits = 0;
528 cmd.addr_tx_en = 1;
529 cmd.addr_width = FC_ADDR_BYTE_NUM_16;
530 cmd.data_tx_en = 0;
531 cmd.data_rx_en = 1;
532 cmd.dumy_tx_en = 1;
533
534 spifc_clear_fifo();
535 spifc_clear_int();
536 spifc_setup_cmd(&cmd, column_addr, len);
537 spifc_start();
538
539 len_tmp = spifc_read_fifo(len, buf);
540 if( len_tmp != len )
541 {
542 ret = -2;
543 return ret;
544 }
545
546 ret = spifc_wait_cmd_end();
547 if( ret != 0 )
548 {
549 return ret;
550 }
551
552 return 0;
553}
554
555
556/*
557 ******************************************************************************
558 * Function: nand_read_oob
559 * Description:
560 * Parameters:
561 * Input:
562 * Output:
563 * Returns:
564 * Others:
565 *******************************************************************************
566 */
567void spifc_read_oob(uint8_t *buf, uint32_t offset, uint32_t len)
568{
569 uint32_t column_offset = spi_flash_info->page_size;
570 uint32_t page = offset >> (spi_flash_info->page_size_shift);
571 uint32_t blocks = offset >> (spi_flash_info->block_size_shift);
572
573 spifc_read_page_to_cache(page);
574
575 if((spi_flash_info->planes == 2) && ((blocks%2) != 0))
576 {
577 column_offset |= (0x1 << 12);
578 }
579 spifc_read_from_cache(column_offset, spi_flash_info->oob_size, buf);
580}
581
582
583/*
584 ******************************************************************************
585 * Function: read_page
586 * Description:
587 * Parameters:
588 * Input:
589 * Output:
590 * Returns:
591 * Others:
592 *******************************************************************************
593 */
594int32_t spifc_read_page(uint32_t buf, uint32_t offset)
595{
596 int ret = 0;
597 uint8_t feature = 0x0;
598
599 uint32_t page = offset >> (spi_flash_info->page_size_shift);
600 uint32_t blocks = offset >> (spi_flash_info->block_size_shift);
601 uint32_t column_offset = 0;
602
603 if( (buf & 0x3) != 0 ) /* DMAµØÖ·ÒªÇó4×Ö½Ú¶ÔÆë */
604 {
605 printf("addr err.\n");
606 return -1;
607 }
608
609 ret = spifc_read_page_to_cache(page);
610 if( ret != 0 )
611 return ret;
612
613 ret = spifc_get_feature(REG_STATUS, &feature);
614 if(ret != 0)
615 return ret;
616
617 if((feature>>ECC_ERR_BIT & 0x3) == 0x2)
618 {
619 printf("ecc err.\n");
620 return -1;
621 }
622 if((spi_flash_info->planes == 2) && ((blocks%2) != 0))
623 {
624 column_offset |= (0x1 << 12);
625 }
626 ret = spifc_read_from_cache(column_offset, spi_flash_info->page_size, (uint8_t *)buf);
627 if(ret != 0)
628 return ret;
629
630 return 0;
631}
632
633/*
634 ******************************************************************************
635 * Function: read_page
636 * Description:
637 * Parameters:
638 * Input:
639 * Output:
640 * Returns:
641 * Others:
642 *******************************************************************************
643 */
644int32_t spifc_read_page_raw(uint32_t buf, uint32_t offset)
645{
646 int ret = 0;
647 uint8_t feature = 0x0;
648
649 uint32_t page = offset >> (spi_flash_info->page_size_shift);
650
651 if( (buf & 0x3) != 0 ) /* DMAµØÖ·ÒªÇó4×Ö½Ú¶ÔÆë */
652 {
653 printf("addr err.\n");
654 return -1;
655 }
656
657 ret = spifc_read_page_to_cache(page);
658 if( ret != 0 )
659 return ret;
660
661 ret = spifc_read_from_cache(0, spi_flash_info->page_size, (uint8_t *)buf);
662 if(ret != 0)
663 return ret;
664
665 return 0;
666}
667
668
669/*
670 ******************************************************************************
671 * Function: nand_read
672 * Description:
673 * Parameters:
674 * Input:
675 * Output:
676 * Returns:
677 * Others: from: must page align len: must page align
678 *******************************************************************************
679 */
680int32_t spifc_read(uint32_t from, uint32_t len, uint32_t to)
681{
682 uint32_t offset = from;
683 uint32_t left_to_read = len;
684 uint32_t p_to = to;
685 int32_t ret = 0;
686 int32_t page_size = (spi_flash_info->page_size);
687
688 if((offset & (page_size - 1)) || (len & (page_size - 1)) )
689 {
690 return -1;
691 }
692
693 while( left_to_read > 0 )
694 {
695 ret = spifc_read_page(p_to, offset);
696 if(ret != 0)
697 {
698 return -1;
699 }
700
701 left_to_read -= page_size;
702 offset += page_size;
703 p_to += page_size;
704 }
705 return 0;
706}
707
708
709/*******************************************************************************
710 * Function: nand_read_id
711 * Description:
712 * Parameters:
713 * Input:
714 *
715 * Output:
716 *
717 * Returns:
718 *
719 *
720 * Others:
721 ********************************************************************************/
722 int32_t read_id (void)
723{
724 uint8_t id[4];
725 const struct spi_flash_device_para *spi_flash = &spi_flash_para[0];
726
727 spifc_read_id(0x0, id, 2);
728
729 while( spi_flash->manuf_id != 0 )
730 {
731 if( ((uint8_t)id[0] == spi_flash->manuf_id) &&
732 ((uint8_t)id[1] == spi_flash->device_id) )
733 {
734 spi_flash_info = spi_flash;
735 return 0;
736 };
737 spi_flash++;
738 }
739
740 return -1;
741}
742
743/*******************************************************************************
744 * Function:
745 * Description:
746 * Parameters:
747 * Input:
748 *
749 * Output:
750 *
751 * Returns:
752 *
753 *
754 * Others:
755 ********************************************************************************/
756int32_t read_data(uint32_t from, uint32_t len, uint32_t to)
757{
758 uint32_t offset = from;
759 uint32_t left_to_read = len;
760 uint32_t p_to = to;
761 int32_t ret = 0;
762 int32_t block_size = (spi_flash_info->block_size);
763
764 while(left_to_read > 0)
765 {
766 uint32_t block_offset = offset & (block_size - 1);
767 uint32_t read_length;
768
769 if( nand_block_isbad(offset) )
770 {
771 offset += block_size;
772 continue;
773 }
774
775 if (left_to_read < (block_size - block_offset))
776 read_length = left_to_read;
777 else
778 read_length = block_size - block_offset;
779
780 ret = spifc_read(offset, read_length, p_to);
781 if(ret != 0)
782 {
783 return -1;
784 }
785
786 left_to_read -= read_length;
787 offset += read_length;
788 p_to += read_length;
789 }
790
791 return 0;
792}
793
794/*******************************************************************************
795 * Function: nand_init
796 * Description:
797 * Parameters:
798 * Input:
799 *
800 * Output:
801 *
802 * Returns:
803 *
804 *
805 * Others:
806 ********************************************************************************/
807int32_t spifc_init (void)
808{
809 int32_t ret = 0;
810 spifc_enable();
811 ret = read_id();
812 if(ret != 0)
813 {
814 printf("id err!\n");
815 return -1;
816 }
817
818 flash.flash_type = SPI_NAND_BOOT;
819 flash.manuf_id = spi_flash_info->manuf_id;
820 flash.device_id = spi_flash_info->device_id;
821 flash.page_size = spi_flash_info->page_size;
822 flash.page_size_shift = spi_flash_info->page_size_shift;
823 flash.oob_size = spi_flash_info->oob_size;
824 flash.block_size = spi_flash_info->block_size;
825 flash.block_size_shift = spi_flash_info->block_size_shift;
826 flash.block_num = spi_flash_info->block_num;
827 flash.read_page_raw = spifc_read_page_raw;
828 flash.read_oob = spifc_read_oob;
829 flash.read = read_data;
830
831 return 0;
832
833}
834
835/*
836 ******************************************************************************
837 * Function:
838 * Description:
839 * Parameters:
840 * Input:
841 * Output:
842 * Returns:
843 * Others:
844 *******************************************************************************
845 */
846int board_flash_init(void)
847{
848 int ret = 0;
849 char boot_mode = 0;
850
851 printf("spi-nand:");
852
853 boot_mode = get_boot_mode();
854#if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
855 if(boot_mode == NOR_BOOT)
856 {
857 writel(CFG_START_MODE_SPI_NAND, CFG_BOOT_MODE_START_MODE_FOR_UBOOT);
858 return 0;
859 }
860#else
861 if(boot_mode != SPI_NAND_BOOT)
862 {
863 printf("mode err.\n");
864 return -1;
865 }
866#endif
867 writel(CFG_START_MODE_SPI_NAND, CFG_BOOT_MODE_START_MODE_FOR_UBOOT);
868 ret = spifc_init();
869 if(ret != 0)
870 {
871 printf("init err.\n");
872 return -1;
873 }
874 printf("init ok.\n");
875
876// nand_creat_bbt();
877nand_creat_ram_bbt();
878
879 return 0;
880}
881
882