blob: fe24aaaa8b93d7ce7508204dad00ba2af9143abb [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*******************************************************************************
2 * Copyright (C) 2016, ZIXC Corporation.
3 *
4 * File Name:
5 * File Mark:
6 * Description:
7 * Others:
8 * Version: 1.0
9 * Author: geanfeng
10 * Date: 2013-3-4
11 * History 1:
12 * Date:
13 * Version:
14 * Author:
15 * Modification:
16 * History 2:
17 ********************************************************************************/
18
19/****************************************************************************
20* Include files
21****************************************************************************/
22#include "downloader_nand.h"
23#include <asm/errno.h>
24#include "partition_table.h"
25#include <linux/mtd/nor_spifc.h>
26
27
28/****************************************************************************
29* Local Macros
30****************************************************************************/
31#define DATA_WITH_OOB (1 << 0) /* whether write with oob data*/
32/****************************************************************************
33* Local Types
34****************************************************************************/
35/****************************************************************************
36* Global Variables
37****************************************************************************/
38extern partition_table_t * g_partition_table;
39extern partition_table_t * g_partition_table_dl;
40extern partition_entry_t * get_partitions(const char *partname, partition_table_t *table);
41
42/****************************************************************************
43* Global Function Prototypes
44****************************************************************************/
45/****************************************************************************
46* Function Definitions
47****************************************************************************/
48/*******************************************************************************
49 * Function:get_part_offset_skipbase
50 * Description:
51 * Parameters:
52 * Input:
53 *
54 * Output:
55 *
56 * Returns:
57 *phyBase
58 *
59 * Others:
60 ********************************************************************************/
61static int get_part_offset_skipbase(partition_entry_t * part, uint offset, uint * skipBase)
62{
63 nand_info_t * pNandInfo = NULL;
64 uint offsetSkipBase = 0;
65 uint blockNum = 0;
66 int ret = 0;
67
68 pNandInfo = &nand_info[nand_curr_device];
69 offsetSkipBase = part->part_offset;
70 assert((offset & (pNandInfo->erasesize - 1)) == 0);
71 assert((offsetSkipBase & (pNandInfo->erasesize - 1)) == 0);
72 if(offset != 0)
73 {
74 blockNum = offset /pNandInfo->erasesize;
75 while(blockNum > 0)
76 {
77 ret = nand_block_isbad (pNandInfo, offsetSkipBase);
78 offsetSkipBase += pNandInfo->erasesize;
79 if (ret)
80 {
81 continue;
82 }
83 else
84 {
85 blockNum--;
86 }
87 }
88 }
89 *skipBase = offsetSkipBase;
90
91 return 0;
92}
93
94
95/*******************************************************************************
96 * Function:nand_read_skip_bad_compt
97 * Description:
98 * Parameters:
99 * Input:
100 *
101 * Output:
102 *
103 * Returns:
104 * NULL:error else: success
105 *
106 * Others:
107 ********************************************************************************/
108int nand_read_skip_bad_compat(nand_info_t *nand, loff_t offset, size_t *length,
109 u_char *buffer, int flags)
110{
111 int rval = 0, blocksize;
112 size_t left_to_read = *length;
113 u_char *p_buffer = buffer;
114
115 if (flags & DATA_WITH_OOB) {
116 int pages;
117 pages = nand->erasesize / nand->writesize;
118 blocksize = (pages * nand->oobsize) + nand->erasesize;
119 if (*length % (nand->writesize + nand->oobsize)) {
120 printf ("Attempt to write incomplete page"
121 " in yaffs mode\n");
122 return -EINVAL;
123 }
124 } else
125 {
126 blocksize = nand->erasesize;
127 }
128
129 if ((offset & (nand->writesize - 1)) != 0) {
130 printf ("Attempt to write non page aligned data\n");
131 *length = 0;
132 return -EINVAL;
133 }
134
135 while (left_to_read > 0) {
136 size_t block_offset = offset & (nand->erasesize - 1);
137 size_t read_size, truncated_read_size;
138
139 if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
140 printf ("Skip bad block 0x%08llx\n",
141 (u64)(offset & ~(nand->erasesize - 1)));
142 offset += nand->erasesize - block_offset;
143 continue;
144 }
145
146 if (left_to_read < (blocksize - block_offset))
147 read_size = left_to_read;
148 else
149 read_size = blocksize - block_offset;
150
151 if (flags & DATA_WITH_OOB) {
152 int page, pages;
153 size_t pagesize = nand->writesize;
154 size_t pagesize_oob = pagesize + nand->oobsize;
155 struct mtd_oob_ops ops;
156 memset(&ops, 0x0, sizeof(ops));
157
158 ops.len = pagesize;
159 ops.ooblen = nand->oobsize;
160 ops.mode = MTD_OOB_RAW;
161 ops.ooboffs = 0;
162
163 pages = read_size / pagesize_oob;
164 for (page = 0; page < pages; page++) {
165 ops.datbuf = p_buffer;
166 ops.oobbuf = ops.datbuf + pagesize;
167 rval = nand->read_oob(nand, offset, &ops);
168 if (rval)
169 break;
170
171 offset += pagesize;
172 p_buffer += pagesize_oob;
173 }
174 }
175 else
176 {
177 truncated_read_size = read_size;
178 rval = nand_read(nand, offset, &truncated_read_size,
179 p_buffer);
180 offset += read_size;
181 p_buffer += read_size;
182 }
183
184 if (rval != 0) {
185 printf ("NAND read from offset %llx failed %d\n",
186 (u64)offset, rval);
187 *length -= left_to_read;
188 return rval;
189 }
190
191 left_to_read -= read_size;
192 }
193
194 return 0;
195}
196/*******************************************************************************
197 * Function:nand_read_skip_bad_compt
198 * Description:
199 * Parameters:
200 * Input:
201 *
202 * Output:
203 *
204 * Returns:
205 * NULL:error else: success
206 *
207 * Others:
208 ********************************************************************************/
209int nand_write_skip_bad_compat(nand_info_t *nand, loff_t offset, size_t *length,
210 u_char *buffer, int flags)
211{
212 int rval = 0, blocksize;
213 size_t left_to_write = *length;
214 u_char *p_buffer = buffer;
215
216 if (flags & DATA_WITH_OOB) {
217 int pages;
218 pages = nand->erasesize / nand->writesize;
219 blocksize = (pages * nand->oobsize) + nand->erasesize;
220 if (*length % (nand->writesize + nand->oobsize)) {
221 printf ("Attempt to write incomplete page"
222 " in yaffs mode\n");
223 return -EINVAL;
224 }
225 } else
226 {
227 blocksize = nand->erasesize;
228 }
229
230 /*
231 * nand_write() handles unaligned, partial page writes.
232 *
233 * We allow length to be unaligned, for convenience in
234 * using the $filesize variable.
235 *
236 * However, starting at an unaligned offset makes the
237 * semantics of bad block skipping ambiguous (really,
238 * you should only start a block skipping access at a
239 * partition boundary). So don't try to handle that.
240 */
241 if ((offset & (nand->writesize - 1)) != 0) {
242 printf ("Attempt to write non page aligned data\n");
243 *length = 0;
244 return -EINVAL;
245 }
246
247 while (left_to_write > 0) {
248 size_t block_offset = offset & (nand->erasesize - 1);
249 size_t write_size, truncated_write_size;
250
251 if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
252 printf ("Skip bad block 0x%08llx\n",
253 (u64)(offset & ~(nand->erasesize - 1)));
254 offset += nand->erasesize - block_offset;
255 continue;
256 }
257
258 if (left_to_write < (blocksize - block_offset))
259 write_size = left_to_write;
260 else
261 write_size = blocksize - block_offset;
262
263 if (flags & DATA_WITH_OOB) {
264 int page, pages;
265 size_t pagesize = nand->writesize;
266 size_t pagesize_oob = pagesize + nand->oobsize;
267 struct mtd_oob_ops ops;
268
269 ops.len = pagesize;
270 ops.ooblen = nand->oobsize;
271 ops.mode = MTD_OOB_RAW;
272 ops.ooboffs = 0;
273
274 pages = write_size / pagesize_oob;
275 for (page = 0; page < pages; page++) {
276 ops.datbuf = p_buffer;
277 ops.oobbuf = ops.datbuf + pagesize;
278 //ops.oobbuf = NULL;
279 if(*(ops.datbuf + pagesize) != 0xFF || *(ops.datbuf + pagesize+1) != 0xFF) {
280 printf ("Fs image format error\n");
281 return -EINVAL;
282 }
283 rval = nand->write_oob(nand, offset, &ops);
284
285
286 if (rval)
287 break;
288
289 offset += pagesize;
290 p_buffer += pagesize_oob;
291 }
292 }
293 else
294 {
295 truncated_write_size = write_size;
296 rval = nand_write(nand, offset, &truncated_write_size,
297 p_buffer);
298 offset += write_size;
299 p_buffer += write_size;
300 }
301
302 if (rval != 0) {
303 printf ("NAND write to offset %llx failed %d\n",
304 (u64)offset, rval);
305 *length -= left_to_write;
306 return rval;
307 }
308
309 left_to_write -= write_size;
310 }
311
312 return 0;
313}
314/*******************************************************************************
315 * Function:downloader_get_part
316 * Description:
317 * Parameters:
318 * Input:
319 *
320 * Output:
321 *
322 * Returns:
323 * NULL:error else: success
324 *
325 * Others:
326 ********************************************************************************/
327partition_entry_t * downloader_get_part(const char *partname)
328{
329 partition_entry_t *part;
330
331 part = find_partition_para((uchar *)partname);
332 if(part == NULL)
333 return NULL;
334
335 return part;
336}
337/*******************************************************************************
338 * Function:downloader_get_part_dl
339 * Description:
340 * Parameters:
341 * Input:
342 *
343 * Output:
344 *
345 * Returns:
346 * NULL:error else: success
347 *
348 * Others:
349 ********************************************************************************/
350partition_entry_t * downloader_get_part_dl(const char *partname)
351{
352 partition_entry_t *part;
353
354 part = get_partitions((const char *)partname,g_partition_table_dl);
355 if(part == NULL)
356 {
357 return NULL;
358 }
359 printf("name=%s,part-name=%s,typt=%s\n",partname,part->part_name,part->part_type);
360
361 return part;
362}
363/*******************************************************************************
364 * Function:downloader_get_part_actual_size
365 * Description:
366 * Parameters:
367 * Input:
368 *
369 * Output:
370 *
371 * Returns:
372 * NULL:error else: success
373 *
374 * Others:
375 ********************************************************************************/
376u32 downloader_get_part_actual_size(partition_entry_t *part)
377{
378 nand_info_t * pNandInfo = NULL;
379 pNandInfo = &nand_info[nand_curr_device];
380 u32 bad_blk_cnt = 0;
381 u32 offset = part->part_offset;
382 while(offset < part->part_offset + part->part_size )
383 {
384 if (nand_block_isbad (pNandInfo, offset) ){
385 bad_blk_cnt = bad_blk_cnt +1 ;
386 offset += pNandInfo->erasesize;
387 continue;
388 }
389 offset += pNandInfo->erasesize;
390 }
391 printf("downloader_get_part_actual_size:[%s] bad_blk_cnt = %d\n",part->part_name, bad_blk_cnt);
392 u32 part_actual_size = part->part_size -(bad_blk_cnt * pNandInfo->erasesize);
393 return part_actual_size;
394}
395
396/*******************************************************************************
397 * Function:downloader_nand_read
398 * Description:
399 * Parameters:
400 * Input:
401 *
402 * Output:
403 *
404 * Returns:
405 * 0: success else:error
406 *
407 * Others:
408 ********************************************************************************/
409int downloader_nand_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
410{
411 nand_info_t * pNandInfo = NULL;
412 uint nandPhyBase = 0;
413 int ret = 0;
414
415 char ack[64] = {0};
416 if(part == NULL || \
417 offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
418 {
419 printf(" [downloader_nand_read:][%s]bin_size > actual part_size \n", part->part_name);
420 sprintf(ack, " READ FAIL UNLEGAL SIZE ");
421 downloader_serial_write(ack, strlen(ack)+1);
422 return -1;
423 }
424 pNandInfo = &nand_info[nand_curr_device];
425 get_part_offset_skipbase(part,offset,&nandPhyBase);
426
427 if( strcmp((const char *)part->part_name , "zloader") == 0 )
428 {
429 /* ÕâÀﲻʹÓÃECC¶Áȡʱ£¬Òª¶ÁÈ¡OOB£¬¶øOOBµÃÊý¾Ý»á·ÅÈëdata->buf;
430 ËùÒÔ´æ·ÅÊý¾ÝµÄbuf±ØÐëΪ (1 page + oob),²»ÄÜʹÓÃÉÏÃæ´«ÏÂÀ´µÄ
431 buffer,ÒòΪbufferµÄ´óСΪ²»°üº¬ oob µÄ´óС
432 */
433 u_char *buf = kzalloc(pNandInfo->writesize + pNandInfo->oobsize, GFP_KERNEL);
434 if( buf == NULL )
435 {
436 printf("downloader_nand_read kzalloc error\n");
437 return -1;
438 }
439
440 int times = size/pNandInfo->writesize;
441 int i = 0;
442 for(; i<times; i++)
443 {
444 ret += nand_read_page_with_ecc(pNandInfo,
445 ((loff_t)i*pNandInfo->writesize),
446 &size,
447 (u_char*)buf );
448 memcpy((u_char*)buffer, buf ,pNandInfo->writesize);
449 buffer += pNandInfo->writesize;
450 }
451 kfree(buf);
452
453 }
454
455 else
456 ret = nand_read_skip_bad(pNandInfo,\
457 nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer);
458 if(ret)
459 {
460 printf("downloader_nand_read error\n");
461 return -1;
462 }
463 return 0;
464}
465
466/*******************************************************************************
467 * Function:downloader_nand_write
468 * Description:
469 * Parameters:
470 * Input:
471 *
472 * Output:
473 *
474 * Returns:
475 * 0: success else:error
476 *
477 * Others:
478 ********************************************************************************/
xf.liaa4d92f2023-09-13 00:18:58 -0700479int downloader_nand_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
lh9ed821d2023-04-07 01:36:19 -0700480{
481 nand_info_t * pNandInfo = NULL;
482 uint nandPhyBase = 0;
483 int ret = 0;
484 uchar * buf = buffer;
485 char ack[64] = {0};
486 if(part == NULL || \
487 offset>part->part_size || (size > downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
488 {
489 printf("[downloader_nand_write:][%s] bin_size > actual part_size \n", part->part_name);
490 sprintf(ack, "WRITE FAIL UNLEGAL SIZE ");
491 downloader_serial_write(ack, strlen(ack)+1);
492 return -1;
493 }
494 /*if(zftl_get_ZFTLrecord(part->part_offset))
495 {
496 printf("Function not allowed write zftl\n");
497 return -1;
498 }*/
499 pNandInfo = &nand_info[nand_curr_device];
500 get_part_offset_skipbase(part,offset,&nandPhyBase);
501 printf("entry nand_write\n");
502
503 /* רÃÅдZ-LOADʱʹÓ㬲»Ê¹ÓÃECC*/
504 if( strcmp((const char *)part->part_name , "zloader") == 0 )
xf.liaa4d92f2023-09-13 00:18:58 -0700505 {
506 if(g_nor_flag == 1)
507 {
508 int times = 0x9000/pNandInfo->writesize;
509 int i = 0;
lh9ed821d2023-04-07 01:36:19 -0700510
xf.liaa4d92f2023-09-13 00:18:58 -0700511 for(; i<times; i++)
512 {
513
514 ret += nand_write_page_with_ecc(pNandInfo,
515 ((loff_t)i*(pNandInfo->writesize)),
516 buf );
517 buf += pNandInfo->writesize;
518 }
519 }
520 else
521 {
522 if( size != 12*1024 )
523 {
524 printf("downloader_nand_write z-load size != 12k...\n");
525 return -1;
526 }
527 int times = 12*1024/pNandInfo->writesize;
528 int i = 0;
529
530 for(; i<times; i++)
531 {
532
533 ret += nand_write_page_with_ecc(pNandInfo,
534 ((loff_t)i*(pNandInfo->writesize)),
535 buf );
536 buf += pNandInfo->writesize;
537 }
538 }
lh9ed821d2023-04-07 01:36:19 -0700539 }
540
541 else
542 ret = nand_write_skip_bad(pNandInfo,\
543 nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer, 0);
544 printf("write skipbad finish, addr = %d,size = %d\n",nandPhyBase+offset%(pNandInfo->erasesize),size);
545 if(ret)
546 {
547 printf("downloader_nand_write error\n");
548 return -1;
549 }
550 return 0;
551}
552
553/*******************************************************************************
554 * Function:downloader_nand_fs_read
555 * Description:
556 * Parameters:
557 * Input:
558 *
559 * Output:
560 *
561 * Returns:
562 * 0: success else:error
563 *
564 * Others:
565 ********************************************************************************/
566int downloader_nand_fs_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
567{
568 nand_info_t * pNandInfo = NULL;
569 uint nandPhyBase = 0;
570 int ret = 0;
571
572 char ack[64] = {0};
573 if(part == NULL || \
574 offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
575 {
576 printf("[downloader_nand_fs_read:][%s] bin_size > actual part_size \n", part->part_name);
577 sprintf(ack, " FS_READ FAIL UNLEGAL SIZE ");
578 downloader_serial_write(ack, strlen(ack)+1);
579 return -1;
580 }
581 pNandInfo = &nand_info[nand_curr_device];
582 assert(pNandInfo!=NULL);
583 get_part_offset_skipbase(part,offset,&nandPhyBase);
584 ret = nand_read_skip_bad_compat(pNandInfo,nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer,DATA_WITH_OOB);
585 if(ret)
586 {
587 printf("downloader_nand_fs_read error\n");
588 return -1;
589 }
590 return 0;
591}
592
593/*******************************************************************************
594 * Function:downloader_nand_fs_write
595 * Description:
596 * Parameters:
597 * Input:
598 *
599 * Output:
600 *
601 * Returns:
602 * 0: success else:error
603 *
604 * Others:
605 ********************************************************************************/
606int downloader_nand_fs_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
607{
608 nand_info_t * pNandInfo = NULL;
609 uint nandPhyBase = 0;
610 int ret = 0;
611 char ack[64] = {0};
612 if(part == NULL || \
613 offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
614 {
615 printf("[downloader_nand_fs_write:][%s] bin_size > actual part_size \n", part->part_name);
616 sprintf(ack, " FS_WRITE FAIL UNLEGAL SIZE ");
617 downloader_serial_write(ack, strlen(ack)+1);
618 return -1;
619 }
620
621 pNandInfo = &nand_info[nand_curr_device];
622 assert(pNandInfo!=NULL);
623 get_part_offset_skipbase(part,offset,&nandPhyBase);
624 ret = nand_write_skip_bad_compat(pNandInfo,nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer, DATA_WITH_OOB);
625 if(ret)
626 {
627 printf("downloader_nand_fs_write error\n");
628 return -1;
629 }
630 return 0;
631}
632/*******************************************************************************
633 * Function:downloader_nand_erase
634 * Description:
635 * Parameters:
636 * Input:
637 *
638 * Output:
639 *
640 * Returns:
641 * 0: success else:error
642 *
643 * Others:
644 ********************************************************************************/
645int downloader_nand_erase(partition_entry_t * part, uint partEraseSize)
646{
647 nand_info_t * pNandInfo = NULL;
648 int ret = 0;
649 struct erase_info instr;
650 uint size = 0;
651
652 if(part == NULL )
653 {
654 return -1;
655 }
656
657 pNandInfo = &nand_info[nand_curr_device];
658 instr.mtd = pNandInfo;
659 instr.addr = part->part_offset;
660 assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
661 instr.callback = 0;
662 //ret=nand_erase(pNandInfo, part->part_offset, part->part_size);
663 while(size < partEraseSize && (instr.addr < (part->part_offset+part->part_size)))
664 {
665 if(nand_block_isbad (pNandInfo, instr.addr))
666 {
667 instr.addr += pNandInfo->erasesize;
668 continue ;
669 }
670 instr.len = pNandInfo->erasesize;
671 instr.state = 0;
672 ret = pNandInfo->erase(pNandInfo, &instr);
673 if(ret && instr.state == MTD_ERASE_FAILED)
674 {
675 pNandInfo->block_markbad(pNandInfo,instr.addr);
676 }
677 else if (ret == 0)
678 {
679 size += pNandInfo->erasesize;
680 }
681 else
682 {
683 printf( "downloader nand: erase error\n");
684 return 1;
685 }
686 instr.addr += pNandInfo->erasesize;
687 }
688
689 return ret;
690}
691/*******************************************************************************
692 * Function:downloader_nand_eraseall
693 * Description:
694 * Parameters:
695 * Input:
696 *
697 * Output:
698 *
699 * Returns:
700 * 0: success else:error
701 *
702 * Others:
703 ********************************************************************************/
704int downloader_nand_eraseall(void)
705{
706 nand_info_t * pNandInfo = NULL;
707 struct erase_info instr;
708 int i = 0;
709 int ret = 0;
710
711 for(i=0; i<CONFIG_SYS_MAX_NAND_DEVICE; i++)
712 {
713 pNandInfo = &nand_info[i];
714
715 instr.mtd = pNandInfo;
716 instr.addr = 0x00;
717 assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
718 instr.callback = 0;
719 while(instr.addr < pNandInfo->size)
720 {
721 if(nand_block_isbad (pNandInfo, instr.addr))
722 {
723 instr.addr += pNandInfo->erasesize;
724 continue ;
725 }
726 instr.len = pNandInfo->erasesize;
727 instr.state = 0;
728 ret = pNandInfo->erase(pNandInfo, &instr);
729 if(ret && instr.state == MTD_ERASE_FAILED)
730 {
731 pNandInfo->block_markbad(pNandInfo,instr.addr);
732 }
733 instr.addr += pNandInfo->erasesize;
734 }
735 }
736 return ret;
737}
738/*******************************************************************************
739 * Function:downloader_nand_erase_auto
740 * Description:
741 * Parameters:
742 * Input:
743 *
744 * Output:
745 *
746 * Returns:
747 * 0: success else:error
748 *
749 * Others:
750 ********************************************************************************/
751int downloader_nand_erase_auto(void)
752{
753 int ret = 0;
754 partition_entry_t *entry = &g_partition_table->table[0];
755 uint32_t entry_nums = g_partition_table->entrys;
756
757 while( entry_nums-- )
758 {
759 if ( strcmp((const char *)entry->part_name, "nvrofs") == 0 \
760 ||strcmp((const char *)entry->part_name, "ddr") == 0 \
761 ||strcmp((const char *)entry->part_name, "raw") == 0)
762 {
763 entry++;
764 continue;
765 }
766 ret = downloader_nand_erase(entry,entry->part_size);
767 entry++;
768 }
769 return ret;
770}
771
772extern struct fsl_qspi spi_nor_flash;
773
774
775/*******************************************************************************
776 * Function:downloader_nor_read
777 * Description:
778 * Parameters:
779 * Input:
780 *
781 * Output:
782 *
783 * Returns:
784 * 0: success else:error
785 *
786 * Others:
787 ********************************************************************************/
788int downloader_nor_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
789{
790 int ret = 0;
791 char ack[64] = {0};
792 size_t read_size = size;
793 struct fsl_qspi *nor = NULL;
794
795 if(part == NULL
796 ||offset>part->part_size
797 || (offset+size) > part->part_size)
798 {
799 printf(" [downloader_nor_read:][%s]bin_size > actual part_size \n", part->part_name);
800 sprintf(ack, " READ FAIL UNLEGAL SIZE ");
801 downloader_serial_write(ack, strlen(ack)+1);
802 return -1;
803 }
804
805 nor = &spi_nor_flash;
806 ret = nand_read(&(nor->nor[0].mtd), part->part_offset + offset, &read_size, buffer);
807 if(ret)
808 {
809 printf("downloader_nor_read error\n");
810 return -1;
811 }
812
813 return 0;
814}
815
816
817/*******************************************************************************
818 * Function:downloader_nor_write
819 * Description:
820 * Parameters:
821 * Input:
822 *
823 * Output:
824 *
825 * Returns:
826 * 0: success else:error
827 *
828 * Others:
829 ********************************************************************************/
830
831int downloader_nor_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
832{
833 int ret = 0;
834 size_t write_size=0;
835 char ack[64] = {0};
836 struct fsl_qspi *nor = NULL;
837
838 write_size = size;
839
840 if(part == NULL
841 || offset>part->part_size
842 || (offset+size) > part->part_size)
843 {
844 printf("[downloader_nor_write:][%s] bin_size > actual part_size \n", part->part_name);
845 sprintf(ack, "WRITE FAIL UNLEGAL SIZE ");
846 downloader_serial_write(ack, strlen(ack)+1);
847 return -1;
848 }
849
850 nor = &spi_nor_flash;
851 ret = nand_write(&(nor->nor[0].mtd), part->part_offset + offset, &write_size, buffer);
852 if(ret)
853 {
854 printf("downloader_nor_write error\n");
855 return ret;
856 }
857
858 return 0;
859}
860
861/*******************************************************************************
862 * Function:downloader_nand_erase
863 * Description:
864 * Parameters:
865 * Input:
866 *
867 * Output:
868 *
869 * Returns:
870 * 0: success else:error
871 *
872 * Others:
873 ********************************************************************************/
874int downloader_nor_erase(partition_entry_t * part, uint partEraseSize)
875{
876 int ret = 0;
877 struct fsl_qspi *nor = NULL;
878
879 if(part == NULL)
880 {
881 return -1;
882 }
883
884 nor = &spi_nor_flash;
885 ret = nand_erase(&(nor->nor[0].mtd), part->part_offset, partEraseSize);
886 if(ret)
887 {
888 printf("downloader_nor_erase error\n");
889 return ret;
890 }
891 printf("downloader_nor_erase ok\n");
892 return 0;
893}
894/*******************************************************************************
895 * Function:downloader_nor_eraseall
896 * Description:
897 * Parameters:
898 * Input:
899 *
900 * Output:
901 *
902 * Returns:
903 * 0: success else:error
904 *
905 * Others:
906 ********************************************************************************/
907int downloader_nor_eraseall(void)
908{
909 int ret = 0;
910 struct fsl_qspi *nor = NULL;
911
912 nor = &spi_nor_flash;
913 ret = nand_erase(&(nor->nor[0].mtd), 0x0, nor->nor[0].mtd.size);
914 if(ret)
915 {
916 printf("downloader_nor_eraseall error\n");
917 return ret;
918 }
919 printf("downloader_nor_eraseall ok\n");
920 return 0;
921
922}
923/*******************************************************************************
924 * Function:downloader_nor_erase_auto
925 * Description:
926 * Parameters:
927 * Input:
928 *
929 * Output:
930 *
931 * Returns:
932 * 0: success else:error
933 *
934 * Others:
935 ********************************************************************************/
936int downloader_nor_erase_auto(void)
937{
938 int ret = 0;
939 partition_entry_t *entry = &g_partition_table->table[0];
940 uint32_t entry_nums = g_partition_table->entrys;
941
942 while(entry_nums--)
943 {
944 if ( strcmp((const char *)entry->part_name, "nvrofs") == 0 \
945 ||strcmp((const char *)entry->part_name, "ddr") == 0 \
946 ||strcmp((const char *)entry->part_name, "raw") == 0)
947 {
948 entry++;
949 continue;
950 }
951 ret = downloader_nor_erase(entry,entry->part_size);
952 if(ret)
953 {
954 printf("downloader_nor_erase_auto error\n");
955 return ret;
956 }
957 entry++;
958 }
959 printf("downloader_nor_erase_auto ok\n");
960 return 0;
961}
962
963int get_nor_null_slice_flag(unsigned int *flag)
964{
965 int ret = 0;
966 size_t read_size = 0x100;
967 unchar buffer[256];
968 struct fsl_qspi *nor = NULL;
969
970 memset(buffer, 0xFF, 0x100);
971
972 nor = &spi_nor_flash;
973 ret = nand_read(&(nor->nor[0].mtd), 0x0, &read_size, buffer);
974 if(ret)
975 {
976 printf("downloader_nor_read error\n");
977 return -1;
978 }
979
980 if(strncmp((const char *)(buffer+4), "ZX7521V1", 8) == 0)
981 {
982 *flag = 1;
983 printf("nor flash not null\n");
984 }
985
986 return 0;
987}
988
989
990