]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c
TX51/TX53 Release 2011-08-19
[karo-tx-redboot.git] / packages / devs / flash / arm / mxc / v2_0 / src / mxc_nfc.c
1 //==========================================================================
2 //
3 //              mxc_nfc.c
4 //
5 //              Flash programming to support NAND flash on Freescale MXC platforms
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    Kevin Zhang <k.zhang@freescale.com>
44 // Contributors: Kevin Zhang <k.zhang@freescale.com>
45 // Date:                 2006-01-23 Initial version
46 // Date:                 2007-12-20 Update to support 4K page and bbt management.
47 // Purpose:
48 // Description:
49 //       -- Add bad block management according to Linux NAND MTD implementation.
50 //              Reference linux/drivers/mtd/nand/nand_bbt.c by Thomas Gleixner
51 //              Summary:
52 //                 1. Last 4 blocks are reserved for one main BBT and one
53 //                        mirror BBT (2 spare ones just in case a block turns bad.)
54 //                 2. The main BBT block's spare area starts with "Bbt0" followed
55 //                        by a version number starting from 1.
56 //                 3. The mirror BBT block's spare area starts with "1tbB" followed
57 //                        by a version number also starting from 1.
58 //                 4. The actual main area, starting from first page in the BBT block,
59 //                        is used to indicate if a block is bad or not through 2bit/block:
60 //                              * The table uses 2 bits per block
61 //                              * 11b:  block is good
62 //                              * 00b:  block is factory marked bad
63 //                              * 01b:  block is marked bad due to wear
64 //                              * 10b:  block is marked reserved (for BBT)
65 //              Redboot operations: During boot, it searches for the marker for
66 //                                                      either main BBT or mirror BBT based on the marker:
67 //                 case 1: Neither table is found:
68 //                                 Do the bad block scan of the whole flash with ECC off. Use
69 //                                 manufactor marked BI field to decide if a block is bad and
70 //                                 then build the BBT in RAM. Then write this table to both
71 //                                 main BBT block and mirror BBT block.
72 //                 case 2: Only one table is found:
73 //                                 Load the BBT from the flash and stored in the RAM.
74 //                                 Then build the 2nd BBT in the flash.
75 //                 case 3: If both tables found, load the one with higher version in the
76 //                                 RAM and then update the block with older BBT info with the
77 //                                 newer one. If same version, just then read out the table in
78 //                                 RAM.
79 //
80 //####DESCRIPTIONEND####
81 //
82 //==========================================================================
83
84 #include <pkgconf/hal.h>
85 #include <cyg/hal/hal_arch.h>
86 #include <cyg/hal/hal_cache.h>
87 #include <cyg/hal/hal_misc.h>
88 #include <cyg/io/nand_bbt.h>
89 #include <redboot.h>
90 #include <stdlib.h>
91
92 #include CYGHWR_MEMORY_LAYOUT_H
93
94 #include <cyg/hal/hal_io.h>
95 #define  _FLASH_PRIVATE_
96 #include <cyg/io/flash.h>
97
98 #ifdef CYGHWR_FLASH_NAND_BBT_HEADER
99 #include CYGHWR_FLASH_NAND_BBT_HEADER
100 #endif
101
102 #include <cyg/io/imx_nfc.h>
103
104 #define ECC_FORCE_ON    1
105 #define ECC_FORCE_OFF   2
106
107 typedef u64 flash_addr_t;
108
109 enum blk_bad_type
110 {
111         BLK_GOOD = 0,
112         BLK_BAD_RUNTIME = 1,
113         BLK_RESERVED = 2,
114         BLK_BAD_FACTORY = 3,
115 };
116
117 #define diag_printf1(fmt...) CYG_MACRO_START                                            \
118                 if (g_nfc_debug_level >= NFC_DEBUG_MIN) diag_printf(fmt);       \
119 CYG_MACRO_END
120
121 #define MXC_UNLOCK_BLK_END              0xFFFF
122
123 extern unsigned int hal_timer_count(void);
124 static int nfc_program_region(flash_addr_t addr, u8 *buf, u32 len);
125 static int nfc_erase_region(flash_addr_t addr, u32 len, bool skip_bad, bool verbose);
126
127 static int nfc_write_pg_random(u32 pg_no, u32 pg_off, u8 *buf, u32 ecc_force);
128 static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line,
129                                                           u32 num_of_nand_chips);
130 static int nfc_erase_blk(u32 ra);
131 static void print_page(u32 addr, bool spare_only);
132 static int nfc_read_page(u32 cs_line, u32 pg_no, u32 pg_off);
133 static int mxc_nfc_scan(bool lowlevel);
134 static void read_nflash_id(u32 *id, u32 cs_line);
135 static int nfc_program_blk(u32 ra, u8 *buf, u32 len);
136
137 static void print_pkt_16(u16 *pkt, u32 len);
138
139 // globals
140 static int g_ecc_enable = true;
141 static int g_spare_only_read_ok = true;
142 static int g_nfc_debug_level = NFC_DEBUG_DEF;
143 static bool g_nfc_debug_measure = false;
144 static bool g_is_2k_page = false;
145 static unsigned int g_block_offset;
146 static bool g_is_4k_page = false;
147 static unsigned int g_nfc_version = MXC_NFC_V1; // default to version 1.0
148 static int      num_of_nand_chips = 1;
149 static int num_of_nand_chips_for_nandsize = 1;
150 static int scale_block_cnt = 1;
151
152 #define nfc_printf(level, args...) CYG_MACRO_START      \
153                 if (g_nfc_debug_level >= level)                         \
154                         diag_printf(args);                                              \
155 CYG_MACRO_END
156
157 #if defined(NFC_V2_0) || defined(NFC_V2_1)
158 #include <cyg/io/mxc_nfc_v2.h>
159 #elif defined(NFC_V3_0)
160 #include <cyg/io/mxc_nfc_v3.h>
161 #else
162 #include <cyg/io/mxc_nfc.h>
163 #endif
164
165 #ifndef NAND_LAUNCH_REG
166 #define NAND_LAUNCH_REG                         0xDEADEEEE
167 #define NAND_CONFIGURATION1_REG         0xDEADEEEE
168 #define NFC_FLASH_CONFIG2_REG           0xDEADEEEE
169 #define NFC_FLASH_CONFIG2_ECC_EN        0xDEADEEEE
170 #define write_nfc_ip_reg(a, b)          CYG_EMPTY_STATEMENT
171 #endif
172
173 #ifndef MXCFLASH_SELECT_MULTI
174 void flash_query(void *data)
175 #else
176 void nandflash_query(void *data)
177 #endif
178 {
179         u32 id[2];
180
181         nfc_printf(NFC_DEBUG_MIN, "%s@%d data=%p\n", __FUNCTION__, __LINE__, data);
182
183         read_nflash_id(&id[0], 0);
184         nfc_printf(NFC_DEBUG_MIN, "%s(ID=0x%02x: 0x%02x, 0x%02x, 0x%02x)\n", __FUNCTION__,
185                            id[0] & 0xff, (id[0] >> 8) & 0xff, (id[0] >> 16) & 0xff, id[0] >> 24);
186         if (data != NULL) {
187                 nfc_printf(NFC_DEBUG_MAX, "%s@%d copy flash ID from %p to %p\n",
188                                 __FUNCTION__, __LINE__, &id[0], data);
189                 memcpy(data, id, sizeof(id));
190         }
191         nfc_printf(NFC_DEBUG_MAX, "%s@%d called from %p\n", __FUNCTION__, __LINE__,
192                         __builtin_return_address(0));
193 }
194
195 #ifndef MXCFLASH_SELECT_MULTI
196 int flash_program_buf(void *addr, void *data, int len)
197 #else
198 int nandflash_program_buf(void *addr, void *data, int len)
199 #endif
200 {
201         nfc_printf(NFC_DEBUG_MAX, "%s(addr=%p, data=%p, len=0x%08x)\n",
202                            __FUNCTION__, addr, data, len);
203         return nfc_program_region((u32)addr, data, len);
204 }
205
206 #ifndef MXCFLASH_SELECT_MULTI
207 int flash_erase_block(void *block, unsigned int size)
208 #else
209 int nandflash_erase_block(void *block, unsigned int size)
210 #endif
211 {
212         nfc_printf(NFC_DEBUG_MAX, "%s(block=%p, size=0x%08x)\n",
213                            __FUNCTION__, block, size);
214         return nfc_erase_region((u32)block, size, 1, 0);
215 }
216
217 #ifndef MXCFLASH_SELECT_MULTI
218 bool flash_code_overlaps(void *start, void *end)
219 #else
220 bool nandflash_code_overlaps(void *start, void *end)
221 #endif
222 {
223         extern unsigned char _stext[], _etext[];
224
225         return ((((unsigned long)&_stext >= (unsigned long)start) &&
226                          ((unsigned long)&_stext < (unsigned long)end)) ||
227                         (((unsigned long)&_etext >= (unsigned long)start) &&
228                          ((unsigned long)&_etext < (unsigned long)end)));
229 }
230
231 #ifndef MXCFLASH_SELECT_MULTI
232 int flash_hwr_map_error(int e)
233 #else
234 int nandflash_hwr_map_error(int e)
235 #endif
236 {
237         return e;
238 }
239
240 #ifndef MXCFLASH_SELECT_MULTI
241 int flash_lock_block(void *block)
242 #else
243 int nandflash_lock_block(void *block)
244 #endif
245 {
246         // Not supported yet
247         return 0;
248 }
249
250 #ifndef MXCFLASH_SELECT_MULTI
251 int flash_unlock_block(void *block, int block_size, int blocks)
252 #else
253 int nandflash_unlock_block(void *block, int block_size, int blocks)
254 #endif
255 {
256         // Not supported yet
257         return 0;
258 }
259
260 //----------------------------------------------------------------------------
261 // Now that device properties are defined, include magic for defining
262 // accessor type and constants.
263 #include <cyg/io/flash_dev.h>
264
265 // Information about supported devices
266 typedef struct flash_dev_info {
267         cyg_uint16       device_id;
268         cyg_uint16       device_id2;
269         cyg_uint16       device_id3;
270         cyg_uint16       device_id4;
271         cyg_uint16       page_size;
272         cyg_uint16       spare_size;
273         cyg_uint32       pages_per_block;
274         cyg_uint32       block_size;
275         cyg_int32        block_count;
276         cyg_uint32       device_size;
277         cyg_uint32       port_size;             // x8 or x16 IO
278         cyg_uint32       type;                  // SLC vs MLC
279         cyg_uint32       options;
280         cyg_uint32       fis_start_addr;
281         cyg_uint32       bi_off;
282         cyg_uint32       bbt_blk_max_nr;
283         cyg_uint8        vendor_info[96];
284         cyg_uint32       col_cycle;                // number of column address cycles
285         cyg_uint32       row_cycle;                // number of row address cycles
286         cyg_uint32       max_bad_blk;
287 } flash_dev_info_t;
288
289 static const flash_dev_info_t *flash_dev_info;
290 static const flash_dev_info_t supported_devices[] = {
291 #include <cyg/io/mxc_nand_parts.inl>
292 };
293 #define NUM_DEVICES                                             NUM_ELEMS(supported_devices)
294
295 #define COL_CYCLE                                               flash_dev_info->col_cycle
296 #define ROW_CYCLE                                               flash_dev_info->row_cycle
297 #define NF_PG_SZ                                                (flash_dev_info->page_size * num_of_nand_chips)
298 #define NF_SPARE_SZ                                             (flash_dev_info->spare_size * num_of_nand_chips)
299 #define NF_PG_PER_BLK                                   flash_dev_info->pages_per_block
300 #define NF_DEV_SZ                                               (flash_dev_info->device_size * num_of_nand_chips_for_nandsize)
301 #define NF_BLK_SZ                                               (flash_dev_info->block_size * num_of_nand_chips)
302 #define NF_BLK_CNT                                              (flash_dev_info->block_count / scale_block_cnt)
303 #define NF_VEND_INFO                                    flash_dev_info->vendor_info
304 #define NF_OPTIONS                                              flash_dev_info->options
305 #define NF_BBT_MAX_NR                                   flash_dev_info->bbt_blk_max_nr
306 #define NF_OPTIONS                                              flash_dev_info->options
307 #define NF_BI_OFF                                               flash_dev_info->bi_off
308
309 #define MXC_NAND_ADDR_MASK                              (NF_DEV_SZ - 1)
310 #define BLOCK_TO_OFFSET(blk)                    ((blk) * NF_PG_PER_BLK * NF_PG_SZ)
311 #define BLOCK_TO_PAGE(blk)                              ((blk) * NF_PG_PER_BLK)
312 #define BLOCK_PAGE_TO_OFFSET(blk, pge)  (((blk) * NF_PG_PER_BLK + (pge)) * NF_PG_SZ)
313 #define OFFSET_TO_BLOCK(offset)                 ((u32)((offset) / (NF_PG_SZ * NF_PG_PER_BLK)))
314 #define OFFSET_TO_PAGE(offset)                  ((u32)((offset) / NF_PG_SZ) % NF_PG_PER_BLK)
315
316 static u8 *g_bbt, *g_page_buf;
317 static u32 g_bbt_sz;
318 static bool mxcnfc_init_ok;
319 static bool mxc_nfc_scan_done;
320
321 // this callback allows the platform specific function to be called right
322 // after flash_dev_query()
323 nfc_setup_func_t *nfc_setup = NULL;
324
325 // this callback allows the platform specific iomux setup
326 nfc_iomuxsetup_func_t *nfc_iomux_setup = NULL;
327
328 static flash_addr_t flash_region_start;
329 static flash_addr_t flash_region_end;
330 static int flash_enable;
331
332 /* This assumes reading the flash with monotonically increasing flash addresses */
333 static flash_addr_t nfc_l_to_p(flash_addr_t addr)
334 {
335         if (g_block_offset == 0) {
336                 return addr & MXC_NAND_ADDR_MASK;
337         } else {
338                 flash_addr_t ra;
339                 u32 block = (addr & MXC_NAND_ADDR_MASK) / NF_BLK_SZ;
340                 u32 offset = addr % NF_BLK_SZ;
341
342                 ra = (block + g_block_offset) * NF_BLK_SZ + offset;
343                 if (offset == 0) {
344                         nfc_printf(NFC_DEBUG_MIN,
345                                            "Remapping block %u at addr 0x%08llx to block %u at addr 0x%08llx\n",
346                                            block, (u64)addr, block + g_block_offset, (u64)ra);
347                 }
348                 return ra;
349         }
350 }
351
352 static int flash_addr_valid(flash_addr_t addr)
353 {
354         if (!flash_enable) {
355                 nfc_printf(NFC_DEBUG_MIN, "No flash area enabled\n");
356                 return 1;
357         }
358         if (addr < flash_region_start || addr >= flash_region_end) {
359                 diag_printf("Flash address 0x%08llx is outside valid region 0x%08llx..0x%08llx\n",
360                                         (u64)addr, (u64)flash_region_start, (u64)flash_region_end);
361                 return 0;
362         }
363         return 1;
364 }
365
366 /* FIXME: we should pass flash_addr_t as arguments */
367 void mxc_flash_enable(void *start, void *end)
368 {
369         flash_addr_t s = (unsigned long)start & MXC_NAND_ADDR_MASK;
370         flash_addr_t e = ((unsigned long)end - 1) & MXC_NAND_ADDR_MASK;
371
372         if (start == end)
373                 return;
374         if (flash_enable++ == 0) {
375                 flash_region_start = s;
376                 flash_region_end = e;
377                 diag_printf1("Enabling flash region 0x%08llx..0x%08llx\n",
378                                          (u64)s, (u64)e);
379                 g_block_offset = 0;
380         } else {
381                 if (s < flash_region_start ||
382                         e > flash_region_end) {
383                         diag_printf("** WARNING: Enable 0x%08llx..0x%08llx outside enabled flash region 0x%08llx..0x%08llx\n",
384                                                 (u64)s, (u64)e, (u64)flash_region_start, (u64)flash_region_end);
385                 }
386         }
387 }
388
389 void mxc_flash_disable(void *start, void *end)
390 {
391         flash_addr_t s = (unsigned long)start & MXC_NAND_ADDR_MASK;
392         flash_addr_t e = ((unsigned long)end - 1) & MXC_NAND_ADDR_MASK;
393
394         if (start == end)
395                 return;
396         if (flash_enable) {
397                 if (--flash_enable == 0) {
398                         diag_printf1("Disabling flash region 0x%08llx..0x%08llx\n",
399                                                  (u64)s, (u64)e);
400                         if (s != flash_region_start ||
401                                 e != flash_region_end) {
402                                 diag_printf("** Error: Disable 0x%08llx..0x%08llx not equal to enabled flash region 0x%08llx..0x%08llx\n",
403                                                 (u64)s, (u64)e, (u64)flash_region_start, (u64)flash_region_end);
404                         }
405                 }
406         } else {
407                 diag_printf("** Error: unbalanced call to flash_disable()\n");
408         }
409 }
410
411 int
412 #ifndef MXCFLASH_SELECT_MULTI
413 flash_hwr_init(void)
414 #else
415 nandflash_hwr_init(void)
416 #endif
417 {
418         u32 id[2];
419         int i;
420
421         nfc_printf(NFC_DEBUG_MAX, "%s()\n", __FUNCTION__);
422
423         if (nfc_iomux_setup)
424                 nfc_iomux_setup();
425
426         NFC_SET_NFC_ACTIVE_CS(0);
427         NFC_CMD_INPUT(FLASH_Reset);
428
429         // Look through table for device data
430         flash_dev_query(&id[0]);
431
432         flash_dev_info = supported_devices;
433         for (i = 0; i < NUM_DEVICES; i++) {
434                 if ((flash_dev_info->device_id == (id[0] & 0xffff)) &&
435                         (flash_dev_info->device_id2 == 0xFFFF ||
436                          flash_dev_info->device_id2 == (id[0] >> 16)))
437                         break;
438                 flash_dev_info++;
439         }
440
441         // Did we find the device? If not, return error.
442         if (NUM_DEVICES == i) {
443                 diag_printf("Unrecognized NAND part: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
444                                         id[0] & 0xff, (id[0] >> 8) & 0xff, (id[0] >> 16) & 0xff, id[0] >> 24);
445                 return FLASH_ERR_DRV_WRONG_PART;
446         }
447
448         mxcnfc_init_ok = true;
449
450         if (NF_PG_SZ == 2048) {
451                 g_is_2k_page = true;
452                 g_spare_only_read_ok = false;
453         }
454         if (NF_PG_SZ == 4096) {
455                 g_is_4k_page = true;
456                 g_spare_only_read_ok = false;
457         }
458
459         nfc_printf(NFC_DEBUG_MED, "%s(): %d out of NUM_DEVICES=%d, id=0x%02x\n",
460                            __FUNCTION__, i, NUM_DEVICES, flash_dev_info->device_id);
461
462         if (nfc_setup)
463                 g_nfc_version = nfc_setup(NF_PG_SZ / num_of_nand_chips, flash_dev_info->port_size,
464                                                                 flash_dev_info->type, num_of_nand_chips);
465
466         diag_printf1("NFC version: %02x\n", g_nfc_version);
467         if (g_nfc_version >= MXC_NFC_V3) {
468                 for (i = 2; i <= NUM_OF_CS_LINES; i++) {
469                         u32 id_tmp[2];
470                         read_nflash_id(&id_tmp[0], i - 1);
471                         if (id[0] != id_tmp[0]) {
472                                 break;
473                         }
474                         /* Support interleave with 1, 2, 4, 8 chips */
475                         if (i == (num_of_nand_chips * 2)) {
476                                 num_of_nand_chips = i;
477                         }
478                         NFC_CMD_INPUT(FLASH_Reset);
479                 }
480
481                 if (nfc_setup && (num_of_nand_chips > 1)) {
482                         nfc_setup(NF_PG_SZ / num_of_nand_chips, flash_dev_info->port_size,
483                                                    flash_dev_info->type, num_of_nand_chips);
484                 }
485         }
486
487         NFC_ARCH_INIT();
488
489         g_bbt_sz = NF_BLK_CNT / 4;
490         g_bbt = malloc(g_bbt_sz); // two bit for each block
491         if (g_bbt == NULL) {
492                 diag_printf("%s(): failed to allocate %d byte for bbt\n", __FUNCTION__, g_bbt_sz);
493                 return FLASH_ERR_PROTOCOL;
494         }
495
496         g_page_buf = malloc(NF_PG_SZ); // for programming less than one page size buffer
497         if (g_page_buf == NULL) {
498                 diag_printf("%s(): failed to allocate %d byte page buffer\n", __FUNCTION__,
499                                         NF_PG_SZ);
500                 return FLASH_ERR_PROTOCOL;
501         }
502         memset(g_bbt, 0, g_bbt_sz);
503
504         /* For now cap off the Device size to 2GB */
505         i = 1;
506         while ((i <= num_of_nand_chips) && ((NF_DEV_SZ * i) < 0x80000000)) {
507                 num_of_nand_chips_for_nandsize = i;
508                 i *= 2;
509         }
510
511         scale_block_cnt = num_of_nand_chips / num_of_nand_chips_for_nandsize;
512         // Hard wired for now
513         flash_info.block_size = NF_BLK_SZ;
514         flash_info.blocks = NF_BLK_CNT - CYGNUM_FLASH_NAND_BBT_BLOCKS;
515         flash_info.start = (void *)MXC_NAND_BASE_DUMMY;
516         flash_info.end = (void *)(MXC_NAND_BASE_DUMMY + NF_DEV_SZ -
517                                                           CYGNUM_FLASH_NAND_BBT_BLOCKS * NF_BLK_SZ);
518
519         mxc_nfc_scan(false); // look for table
520
521         diag_printf1("%s(): block_size=0x%08x, blocks=0x%08x, start=%p, end=%p\n",
522                                  __FUNCTION__, flash_info.block_size, flash_info.blocks,
523                                  flash_info.start, flash_info.end);
524
525         return FLASH_ERR_OK;
526 }
527
528 // used by redboot/current/src/flash.c
529 int mxc_nand_fis_start(void)
530 {
531         return flash_dev_info->fis_start_addr * num_of_nand_chips;
532 }
533
534 static inline u8 get_byte(cyg_uint16 *buf, int offs)
535 {
536         cyg_uint16 word = buf[offs >> 1];
537         if (offs & 1) {
538                 return word >> 8;
539         }
540         return word & 0xff;
541 }
542
543 static inline void store_byte(cyg_uint16 *buf, int offs, u8 val)
544 {
545         cyg_uint16 word = buf[offs >> 1];
546
547         if (offs & 1) {
548                 word = (word & 0x00ff) | ((u16)val << 8);
549         } else {
550                 word = (word & 0xff00) | val;
551         }
552         buf[offs >> 1] = word;
553 }
554
555 static inline bool nfc_verify_addr(unsigned long dst, unsigned long len)
556 {
557         if (dst < NAND_MAIN_BUF0 || dst + len >= NAND_SPAR_BUF3 + NFC_SPARE_BUF_SZ) {
558                 diag_printf("%s: Bad NFC Buffer address 0x%08lx\n", __FUNCTION__, dst);
559                 return false;
560         }
561         return true;
562 }
563
564 static void nfc_buf_read(void *dst, unsigned long src, u32 len)
565 {
566         u16 *s = (u16 *)(src & ~1);
567         u8 *bp = dst;
568
569         if (len == 0) {
570                 return;
571         }
572         if (src + len < src) {
573                 diag_printf("%s: Bad address range 0x%08lx .. 0x%08lx\n", __FUNCTION__,
574                                         src, src + len);
575         }
576         if ((unsigned long)dst + len < (unsigned long)dst) {
577                 diag_printf("%s: Bad address range 0x%08lx .. 0x%08lx\n", __FUNCTION__,
578                                         (unsigned long)dst, (unsigned long)dst + len);
579         }
580         if (src < NAND_MAIN_BUF0 || src + len >= NAND_SPAR_BUF3 + NF_PG_SZ) {
581                 diag_printf("%s: Bad NFC Buffer address 0x%08lx\n", __FUNCTION__, src);
582                 return;
583         }
584         if ((unsigned long)dst >= NAND_MAIN_BUF0 &&
585                 (unsigned long)dst < NAND_SPAR_BUF3 + NF_PG_SZ) {
586                 diag_printf("%s: Bad memory address 0x%08lx\n", __FUNCTION__,
587                                         (unsigned long)dst);
588                 return;
589         }
590         if (src & 1) {
591                 *bp++ = get_byte(s, 1);
592                 s++;
593                 len--;
594         }
595         if ((unsigned long)bp & 1) {
596                 while (len > 1) {
597                         u16 word = *s++;
598                         *bp++ = word & 0xff;
599                         *bp++ = word >> 8;
600                         len -= 2;
601                 }
602         } else {
603                 u16 *wp = (u16 *)bp;
604
605                 while (len > 1) {
606                         *wp++ = *s++;
607                         len -= 2;
608                 }
609                 bp = (u8*)wp;
610         }
611         if (len != 0) {
612                 u16 word = *s;
613                 *bp = word & 0xff;
614         }
615 }
616
617 static void nfc_buf_write(unsigned long dst, void *src, u32 len)
618 {
619         u8 *bp = src;
620         u16 *d = (u16 *)(dst & ~1);
621
622         if (len == 0) {
623                 return;
624         }
625         if (!nfc_verify_addr(dst, len)) {
626                 return;
627         }
628         diag_printf1("Copying %u byte from %p..%p to flash buffer %08lx..%08lx\n",
629                                 len, bp, bp + len - 1, dst, dst + len - 1);
630         if (dst & 1) {
631                 store_byte(d, 1, *bp);
632                 d++;
633                 bp++;
634                 len--;
635         }
636         if ((unsigned long)bp & 1) {
637                 while (len > 1) {
638                         u16 word;
639                         word = *bp++;
640                         word |= (u16)(*bp++) << 8;
641                         *d++ = word;
642                         len -= 2;
643                 }
644         } else {
645                 u16 *wp = (u16 *)bp;
646                 while (len > 1) {
647                         *d++ = *wp++;
648                         len -= 2;
649                 }
650                 bp = (u8 *)wp;
651         }
652         if (len != 0) {
653                 store_byte(d, 1, *bp);
654         }
655 }
656
657 #ifndef NFC_V3_0
658 /*!
659  * Starts the address input cycles for different operations as defined in ops.
660  *
661  * @param ops                   operations as defined in enum nfc_addr_ops
662  * @param pg_no                 page number offset from 0
663  * @param pg_off                byte offset within the page
664  * @param is_erase              don't care for earlier NFC
665  * @param cs_line                don't care for earlier NFC
666  */
667 static void start_nfc_addr_ops(u32 ops, u32 pg_no, u32 pg_off, u32 is_erase,
668                                    u32 cs_line, u32 num_of_chips)
669 {
670         int i;
671
672         switch (ops) {
673         case FLASH_Read_ID:
674                 /* Only supports one NAND chip (CS0) */
675                 if (cs_line != 0)
676                         return;
677                 NFC_ADDR_INPUT(0);
678                 return;
679         case FLASH_Read_Mode1:
680         case FLASH_Program:
681                 for (i = 0; i < COL_CYCLE; i++, pg_off >>= 8) {
682                         NFC_ADDR_INPUT(pg_off & 0xFF);
683                 }
684                 // don't break on purpose
685         case FLASH_Block_Erase:
686                 for (i = 0; i < ROW_CYCLE; i++, pg_no >>= 8) {
687                         NFC_ADDR_INPUT(pg_no & 0xFF);
688                 }
689                 break;
690         default:
691                 diag_printf("!!!!!! %s(): wrong ops: %d !!!!!\n", __FUNCTION__, ops);
692                 return;
693         }
694 }
695 #endif                                  // #ifndef NFC_V3_0
696
697 static void read_nflash_id(u32 *id, u32 cs_line)
698 {
699         volatile u32 *ptr = (volatile u32*)NAND_MAIN_BUF0;
700
701         nfc_printf(NFC_DEBUG_MIN, "%s: read flash id from chip %d @ %p\n",
702                            __FUNCTION__, cs_line, ptr);
703
704         NFC_PRESET(MXC_UNLOCK_BLK_END);
705         NFC_SET_NFC_ACTIVE_CS(cs_line);
706         NFC_CMD_INPUT(FLASH_Read_ID);
707
708         start_nfc_addr_ops(FLASH_Read_ID, 0, 0, 0, cs_line, num_of_nand_chips);
709         NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_ID, g_ecc_enable);
710
711         *id++ = *ptr++;
712         *id++ = *ptr++;
713 }
714
715 static void mark_blk_bad(unsigned int block, unsigned char *buf,
716                                                  enum blk_bad_type bad_type)
717 {
718         unsigned int off = block >> 2;                  // byte offset - each byte can hold status for 4 blocks
719         unsigned int sft = (block & 3) << 1;    // bit shift 0, 2, 4, 6
720         unsigned char val = buf[off];
721
722         if (block > NF_BLK_CNT) {
723                 diag_printf("%s: Block number %u out of range: 0..%u\n", __FUNCTION__,
724                                         block, NF_BLK_CNT - 1);
725                 return;
726         }
727         val = (val & ~(3 << sft)) | (bad_type << sft);
728         buf[off] = val;
729 }
730
731 /*!
732  * Checks to see if a block is bad. If buf is not NULL, it indicates a valid
733  * BBT in the RAM. In this case, it assumes to have 2-bit to represent each
734  * block for good or bad
735  *                              * 11b:  block is good
736  *                              * 00b:  block is factory marked bad
737  *                              * 01b:  block is marked bad due to wear
738  *                              * 10b:  block is marked reserved (for BBT)
739  * If buf is NULL, then it indicates a low level scan based on the certain
740  * offset value in certain pages and certain offset to be non-0xFF. In this
741  * case, the HW ECC will be turned off.
742  *
743  * @param block         0-based block number
744  * @param buf           BBT buffer. Could be NULL (see above explanation)
745  *
746  * @return                      1 if bad block; 0 otherwise
747  */
748 static int nfc_is_badblock(u32 block, u8 *buf)
749 {
750         u32 off;           // byte offset
751         u32 sft;           // bit shift 0, 2, 4, 6
752         flash_addr_t addr;
753         u16 temp, i;
754         int res;
755         u32 pg_no;
756
757         if (buf) {
758                 // use BBT
759                 off = block >> 2;               // byte offset
760                 sft = (block & 3) << 1;  // bit shift 0, 2, 4, 6
761                 res = (buf[off] >> sft) & 0x3;
762                 if (res) {
763                         addr = BLOCK_TO_OFFSET(block);
764                         diag_printf1("Block %u at 0x%08llx is marked %s (%d) in BBT@%p[%02x] mask %02x\n",
765                                                  block, (u64)addr, res == BLK_RESERVED ? "reserved" :
766                                                  res == BLK_BAD_FACTORY ? "factory bad" : "runtime bad",
767                                                  res, buf, off, 3 << sft);
768                 }
769                 return res;
770         }
771
772         // need to do low level scan with ECC off
773         if (NF_OPTIONS & NAND_BBT_SCANLSTPAGE) {
774                 if (g_is_4k_page || g_is_2k_page) {
775                         addr = (block + 1) * NF_BLK_SZ - NF_PG_SZ;
776                         pg_no = addr / NF_PG_SZ;
777                         for (i = 0; i < num_of_nand_chips; i++) {
778                                 // we don't do partial page read here. No ecc either
779                                 nfc_read_pg_random(pg_no, 0, ECC_FORCE_OFF, i, num_of_nand_chips);
780                                 temp = readw((u32)NAND_MAIN_BUF0 + NF_BI_OFF);
781                                 if ((temp & 0xFF) != 0xFF) {
782                                         return BLK_BAD_FACTORY;
783                                 }
784                         }
785                 } else {
786                         diag_printf("only 2K/4K page is supported\n");
787                         // die here -- need to fix the SW
788                         while (1);
789                 }
790                 return 0;
791         }
792         addr = block * NF_BLK_SZ;
793         pg_no = addr / NF_PG_SZ;
794         for (i = 0; i < num_of_nand_chips; i++) {
795                 nfc_read_pg_random(pg_no, 0, ECC_FORCE_OFF, i, num_of_nand_chips); // no ecc
796                 if (g_is_2k_page || g_is_4k_page) {
797                         temp = readw(NAND_MAIN_BUF0 + NF_BI_OFF);
798                 } else {
799                         temp = readw(NAND_SPAR_BUF0 + 4) >> 8; // BI is at 5th byte in spare area
800                 }
801                 if ((temp & 0xFF) != 0xFF) {
802                         return BLK_BAD_FACTORY;
803                 }
804         }
805         if (NF_OPTIONS & NAND_BBT_SCAN2NDPAGE) {
806                 addr += NF_PG_SZ;
807                 pg_no++;
808                 for (i = 0; i < num_of_nand_chips; i++) {
809                         nfc_read_pg_random(pg_no, 0, ECC_FORCE_OFF, i, num_of_nand_chips); // no ecc
810                         if (g_is_2k_page || g_is_4k_page) {
811                                 temp = readw(NAND_MAIN_BUF0 + NF_BI_OFF);
812                         } else {
813                                 temp = readw(NAND_SPAR_BUF0 + 4) >> 8; // BI is at 5th byte in spare area
814                         }
815                         if ((temp & 0xFF) != 0xFF) {
816                                 return BLK_BAD_FACTORY;
817                         }
818                 }
819         }
820         return 0;
821 }
822
823 static inline void mxc_nfc_buf_clear(unsigned long buf, u8 pattern, int size)
824 {
825         int i;
826         u16 *p = (u16 *)buf;
827         u16 fill = pattern;
828
829         fill = (fill << 8) | pattern;
830         for (i = 0; i < size >> 1; i++) {
831                 p[i] = fill;
832         }
833 }
834
835 #ifdef CYGHWR_FLASH_NAND_BBT_HEADER
836 /*
837  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
838  * @buf:        the buffer to search
839  * @td:         search pattern descriptor
840  *
841  * Check for a pattern at the given place. Used to search bad block
842  * tables and good / bad block identifiers.
843 */
844 static int check_short_pattern(void *buf, struct nand_bbt_descr *td)
845 {
846         int i;
847
848         for (i = 0; i < td->len; i++) {
849                 if (get_byte(buf, td->offs + i) != td->pattern[i]) {
850                         return -1;
851                 }
852         }
853         return 0;
854 }
855
856 static int nfc_write_page(u32 pg_no, u32 pg_off, u32 ecc_force);
857 /*
858  * Program g_bbt into the NAND block with offset at g_main_bbt_addr.
859  * This assumes that the g_bbt has been built already.
860  *
861  * If g_main_bbt_addr is 0, search for a free block from the bottom 4 blocks (but make
862  * sure not re-using the mirror block). If g_mirror_bbt_page is 0, do the same thing.
863  * Otherwise, just use g_main_bbt_addr, g_mirror_bbt_page numbers to prgram the
864  * g_bbt into those two blocks.
865  * todo: need to do the version to see which one is newer.
866  *
867  * @return      0 if successful; -1 otherwise.
868  */
869 static int mxc_nfc_write_bbt_page(struct nand_bbt_descr *td)
870 {
871         int ret;
872         u32 block = td->pages / NF_PG_PER_BLK;
873         flash_addr_t addr = td->pages * NF_PG_SZ;
874
875         ret = nfc_erase_blk(addr);
876         if (ret != 0) {
877                 diag_printf("Failed to erase bbt block %u\n", block);
878                 return ret;
879         }
880         ret = nfc_write_page(td->pages, 0, 0);
881         if (ret != 0) {
882                 diag_printf("Failed to write bbt block %u\n", block);
883                 return ret;
884         }
885         mark_blk_bad(block, g_bbt, BLK_RESERVED);
886         return 0;
887 }
888
889 static int mxc_nfc_write_bbt(struct nand_bbt_descr *td, struct nand_bbt_descr *md)
890 {
891         int ret = -1;
892         int block;
893         int pg_offs = 0;
894         int page = 0;
895         u16 *buf = (u16 *)NAND_MAIN_BUF0;
896
897         for (block = NF_BLK_CNT - 1; block >= NF_BLK_CNT - td->maxblocks - 1; block--) {
898                 int pg = block * NF_PG_PER_BLK;
899
900                 if ((nfc_is_badblock(block, g_bbt) & 1) == 0) {
901                         if (md != NULL && md->pages == pg) {
902                                 continue;
903                         }
904                         td->pages = pg;
905                         break;
906                 }
907         }
908         if (td->pages < 0) {
909                 return -1;
910         }
911         mxc_nfc_buf_clear(NAND_SPAR_BUF0, 0xff, NF_SPARE_SZ);
912         mxc_nfc_buf_clear(NAND_MAIN_BUF0, 0xff, NF_PG_SZ);
913         diag_printf1("%s: Updating bbt %c%c%c%c version %d\n", __FUNCTION__,
914                                  td->pattern[0], td->pattern[1], td->pattern[2], td->pattern[3], td->version);
915         nfc_buf_write(NAND_SPAR_BUF0 + td->offs, td->pattern, td->len);
916         store_byte((u16 *)NAND_SPAR_BUF0, td->veroffs, td->version);
917
918         for (block = 0, pg_offs = 0; block < NF_BLK_CNT; pg_offs++) {
919                 u16 tmp = 0xffff;
920                 int i;
921
922                 if (pg_offs << 1 >= NF_PG_SZ) {
923                         ret = mxc_nfc_write_bbt_page(td);
924                         if (ret != 0) {
925                                 return ret;
926                         }
927                         page++;
928                         mxc_nfc_buf_clear(NAND_SPAR_BUF0, 0xff, NF_SPARE_SZ);
929                         mxc_nfc_buf_clear(NAND_MAIN_BUF0, 0xff, NF_PG_SZ);
930                         pg_offs = 0;
931                 }
932                 for (i = 0; i < 16 && block < NF_BLK_CNT; i += 2, block++) {
933                         u8 code = nfc_is_badblock(block, g_bbt);
934                         if ((code & 1) != 0) {
935                                 tmp &= ~(code << i);
936                                 diag_printf1("%s: bad block %u pattern[%p] 0x%04x mask 0x%04x\n", __FUNCTION__,
937                                                          block, &buf[pg_offs], tmp, 0x03 << i);
938                         }
939                 }
940                 buf[pg_offs] = tmp;
941         }
942         if (pg_offs > 0) {
943                 diag_printf1("%s: Writing final bbt block %d page %d\n", __FUNCTION__,
944                                          td->pages / NF_PG_PER_BLK, page);
945                 ret = mxc_nfc_write_bbt_page(td);
946         }
947         return ret;
948 }
949
950 static int mxc_nfc_update_bbt(struct nand_bbt_descr *td, struct nand_bbt_descr *md)
951 {
952         int ret;
953
954         if (td == NULL) {
955                 return -1;
956         }
957         if (td->pages < 0 && (md == NULL || md->pages == -1)) {
958                 td->version = 1;
959         } else {
960                 if (md != NULL && md->pages >= 0) {
961                         if (md->version >= td->version) {
962                                 td->version = ++md->version;
963                         } else {
964                                 md->version = ++td->version;
965                         }
966                 } else {
967                         td->version++;
968                 }
969         }
970         ret = mxc_nfc_write_bbt(td, md);
971         if (ret) {
972                 diag_printf("** Error: Failed to update main BBT\n");
973         }
974         if (md) {
975                 ret = mxc_nfc_write_bbt(md, td);
976                 if (ret) {
977                         diag_printf("** Error: Failed to update mirror BBT\n");
978                 }
979         }
980         return ret;
981 }
982
983 static int program_bbt_to_flash(void)
984 {
985         return mxc_nfc_update_bbt(g_mxc_nfc_bbt_main_descr, g_mxc_nfc_bbt_mirror_descr);
986 }
987 #else
988 static int program_bbt_to_flash(void)
989 {
990         return 0;
991 }
992 #endif
993
994 /*!
995  * Unconditionally erase a block without checking the BI field.
996  * Note that there is NO error checking for passed-in ra.
997  *
998  * @param ra            starting address in the raw address space (offset)
999  *                                      Must be block-aligned
1000  * @return                      0 if successful; -1 otherwise
1001  */
1002 static int nfc_erase_blk(u32 ra)
1003 {
1004         u16 flash_status, i;
1005         u32 pg_no, pg_off;
1006
1007         if (g_nfc_version >= MXC_NFC_V3) {
1008                 // combine the two commands for erase
1009                 nfc_reg_write((FLASH_Start_Erase << 8) | FLASH_Block_Erase, NAND_CMD_REG);
1010                 pg_no = ra / NF_PG_SZ;
1011                 pg_off = ra % NF_PG_SZ;
1012                 for (i = 0; i < num_of_nand_chips; i++) {
1013                         start_nfc_addr_ops(FLASH_Block_Erase, pg_no, pg_off, 1, i, num_of_nand_chips);
1014                         // start auto-erase
1015                         nfc_reg_write(NAND_LAUNCH_AUTO_ERASE, NAND_LAUNCH_REG);
1016                         wait_op_done();
1017                         pg_off = 0;
1018                 }
1019                 flash_status = NFC_STATUS_READ();
1020                 // check I/O bit 0 to see if it is 0 for success
1021                 if ((flash_status & ((0x1 << num_of_nand_chips) - 1)) != 0) {
1022                         return -1;
1023                 }
1024         } else {
1025                 NFC_CMD_INPUT(FLASH_Block_Erase);
1026                 start_nfc_addr_ops(FLASH_Block_Erase, ra / NF_PG_SZ, ra % NF_PG_SZ,
1027                                                    1, 0, num_of_nand_chips);
1028                 NFC_CMD_INPUT(FLASH_Start_Erase);
1029
1030                 flash_status = NFC_STATUS_READ();
1031
1032                 // check I/O bit 0 to see if it is 0 for success
1033                 if ((flash_status & 0x1) != 0) {
1034                         return -1;
1035                 }
1036         }
1037         return 0;
1038 }
1039
1040 /*!
1041  * Program a block of data in the flash. This function doesn't do
1042  * bad block checking. But if program fails, it return error.
1043  * Note: If "len" is less than a block it will program up to a page's
1044  *               boundary. If not within a page boundary, then it fills the
1045  *               rest of the page with 0xFF.
1046  *
1047  * @param ra            destination raw flash address
1048  * @param buf           source address in the RAM
1049  * @param len           len to be programmed
1050  *
1051  * @return                      0 if successful; -1 otherwise
1052  */
1053 static int nfc_program_blk(u32 ra, u8 *buf, u32 len)
1054 {
1055         u32 temp = num_of_nand_chips;
1056
1057         /* Needed when romupdate is called */
1058         if (ra == 0)
1059                 num_of_nand_chips = 1;
1060
1061         for (; len >= NF_PG_SZ; len -= NF_PG_SZ) {
1062                 if (nfc_write_pg_random(ra / NF_PG_SZ, ra % NF_PG_SZ, buf, 0) != 0) {
1063                         return -1;
1064                 }
1065                 ra += NF_PG_SZ;
1066                 buf += NF_PG_SZ;
1067         }
1068         if (len != 0) {
1069                 diag_printf1("Clearing flash buffer from %p..%p\n", g_page_buf + len - 1,
1070                                         g_page_buf + NF_PG_SZ - 1);
1071                 memset(g_page_buf + len, 0xFF, NF_PG_SZ - len);
1072                 diag_printf1("Copying partial page from %p..%p to %p..%p\n",
1073                                         buf, buf + len - 1, g_page_buf, g_page_buf + len);
1074                 memcpy(g_page_buf, buf, len);
1075                 if (nfc_write_pg_random(ra / NF_PG_SZ, ra % NF_PG_SZ, g_page_buf, 0) != 0) {
1076                         num_of_nand_chips = temp;
1077                         return -1;
1078                 }
1079         }
1080         num_of_nand_chips = temp;
1081         return 0;
1082 }
1083
1084 /*!
1085  * Erase a range of NAND flash good blocks only.
1086  * It skips bad blocks and update the BBT once it sees new bad block due to erase.
1087  * @param addr                  raw NAND flash address. it has to be block size aligned
1088  * @param len                   number of bytes
1089  * @param skip_bad              if 1, don't erase bad block; otherwise, always erase
1090  * @param verbose               use true to print more messages
1091  *
1092  * @return                              FLASH_ERR_OK (0) if successful; non-zero otherwise
1093  */
1094 static int nfc_erase_region(flash_addr_t addr, u32 len, bool skip_bad, bool verbose)
1095 {
1096         u32 sz, blk, update = 0, j = 0;
1097
1098         nfc_printf(NFC_DEBUG_MED, "%s: addr=0x%08llx len=0x%08x\n",
1099                            __FUNCTION__, (u64)addr, len);
1100
1101         if ((addr % NF_BLK_SZ) != 0) {
1102                 diag_printf("Error: flash address 0x%08llx not block aligned\n", addr);
1103                 return FLASH_ERR_INVALID;
1104         }
1105         if ((len % NF_BLK_SZ) != 0 || len == 0) {
1106                 diag_printf("Error: invalid length %u (must be > 0 and block aligned)\n", len);
1107                 return FLASH_ERR_INVALID;
1108         }
1109         addr &= MXC_NAND_ADDR_MASK;
1110         // now addr has to be block aligned
1111         for (sz = 0; sz < len; addr += NF_BLK_SZ, j++, sz += NF_BLK_SZ) {
1112                 if (!flash_addr_valid(addr)) {
1113                         return 0;
1114                 }
1115                 blk = OFFSET_TO_BLOCK(addr);
1116                 if (skip_bad && nfc_is_badblock(blk, g_bbt)) {
1117                         diag_printf("\nSkipping bad block %u at addr 0x%08llx\n",
1118                                                 blk, (u64)addr);
1119                         continue;
1120                 }
1121                 if (nfc_erase_blk(addr) != 0) {
1122                         diag_printf("\n** Error: Failed to erase block %u at addr 0x%08llx\n",
1123                                                 blk, (u64)addr);
1124                         mark_blk_bad(blk, g_bbt, BLK_BAD_RUNTIME);
1125                         // we don't need to update the table immediately here since even
1126                         // with power loss now, we should see the same erase error again.
1127                         update++;
1128                         continue;
1129                 }
1130                 if (verbose) {
1131                         if ((j % 0x20) == 0)
1132                                 diag_printf("\n%s 0x%08llx: ", skip_bad ? "Erase" : "FORCE erase", (u64)addr);
1133                         diag_printf(".");
1134                 }
1135         }
1136         if (update) {
1137                 if (program_bbt_to_flash() != 0) {
1138                         diag_printf("\nError: Failed to update bad block table\n");
1139                         return FLASH_ERR_PROGRAM;
1140                 }
1141                 diag_printf("\nnew bad blocks=%d\n", update);
1142         }
1143         return FLASH_ERR_OK;
1144 }
1145
1146 /*!
1147  * Program a range of NAND flash in blocks only.
1148  * It skips bad blocks and update the BBT once it sees new bad block due to program.
1149  * @param addr                  raw NAND flash address. it has to be block size aligned
1150  * @param len                   number of bytes
1151  * @return                              FLASH_ERR_OK (0) if successful; non-zero otherwise
1152  */
1153 static int nfc_program_region(flash_addr_t addr, u8 *buf, u32 len)
1154 {
1155         u32 sz, blk, update = 0, partial_block_size;
1156
1157         nfc_printf(NFC_DEBUG_MED, "%s: addr=0x%08llx, len=0x%08x\n",
1158                            __FUNCTION__, (u64)addr, len);
1159
1160         if ((addr % (NF_PG_SZ / num_of_nand_chips)) != 0) {
1161                 diag_printf("Error: flash address 0x%08llx not page aligned\n", (u64)addr);
1162                 return FLASH_ERR_INVALID;
1163         }
1164         if (len == 0) {
1165                 diag_printf("Error: invalid length\n");
1166                 return FLASH_ERR_INVALID;
1167         }
1168
1169         partial_block_size = NF_BLK_SZ - (addr % NF_BLK_SZ);
1170
1171         mxc_nfc_buf_clear(NAND_SPAR_BUF0, 0xff, NF_SPARE_SZ);
1172         addr = nfc_l_to_p(addr);
1173         while (1) {
1174                 if (!flash_addr_valid(addr)) {
1175                         diag_printf("\nToo many bad blocks in flash region 0x%08llx..0x%08llx\n",
1176                                                 (u64)flash_region_start, (u64)flash_region_end);
1177                         return FLASH_ERR_INVALID;
1178                 }
1179                 blk = OFFSET_TO_BLOCK(addr);
1180                 if (nfc_is_badblock(blk, g_bbt)) {
1181                         diag_printf("\nSkipping bad block %u at addr 0x%08llx\n", blk, addr);
1182                         g_block_offset++;
1183                         goto incr_address;
1184                 }
1185
1186                 sz = (len >= partial_block_size) ? partial_block_size : len;
1187
1188                 if (nfc_program_blk(addr, buf, sz) != 0) {
1189                         update++;
1190                         diag_printf("\nError: Failed to program flash block %u at addr 0x%08llx\n",
1191                                                 blk, (u64)addr);
1192                         mark_blk_bad(blk, g_bbt, BLK_BAD_RUNTIME);
1193                         // we don't need to update the table immediately here since even
1194                         // with power loss now, we should see the same program error again.
1195                         g_block_offset++;
1196                         goto incr_address;
1197                 }
1198                 diag_printf(".");
1199
1200                 len -= sz;
1201                 buf += sz;
1202                 if (len == 0)
1203                         break;
1204
1205 incr_address:
1206                 addr += partial_block_size;
1207                 partial_block_size = NF_BLK_SZ;
1208         }
1209         if (update) {
1210                 if (program_bbt_to_flash() != 0) {
1211                         diag_printf("\nError: Failed to update bad block table\n");
1212                         return -1;
1213                 }
1214         }
1215         return FLASH_ERR_OK;
1216 }
1217
1218 /*!
1219  * Read data from raw NAND flash address to memory. The MSB of the passed-
1220  * in flash address will be masked off inside the function.
1221  * It skips bad blocks and read good blocks of data for "len" bytes.
1222  *
1223  * @param addr                  NAND flash address.
1224  * @param buf                   memory buf where data will be copied to
1225  * @param len                   number of bytes
1226  * @return                              FLASH_ERR_OK (0) if successful; non-zero otherwise
1227  */
1228 int nfc_read_region(flash_addr_t addr, u8 *buf, u32 len)
1229 {
1230         u32 start_point = 0, pg_no;
1231         unsigned int offset = addr % NF_PG_SZ;
1232         int chk_bad = 1;
1233
1234         nfc_printf(NFC_DEBUG_MED, "%s: addr=0x%08llx, offset=%03x buf=0x%p, len=0x%08x\n",
1235                            __FUNCTION__, addr, offset, buf, len);
1236
1237         if (addr < (u32)flash_info.start || (addr + len) > (u32)flash_info.end || len == 0) {
1238                 diag_printf("** Error: flash address 0x%08llx..0x%08llx outside valid range %p..%p\n",
1239                                         (u64)addr, (u64)addr + len - 1, flash_info.start, flash_info.end);
1240                 return FLASH_ERR_INVALID;
1241         }
1242
1243         addr = nfc_l_to_p(addr);
1244         while (len > 0) {
1245                 int i;
1246
1247                 if (!flash_addr_valid(addr)) {
1248                         diag_printf("Too many bad blocks in flash region 0x%08llx..0x%08llx\n",
1249                                                 (u64)flash_region_start, (u64)flash_region_end);
1250                         return FLASH_ERR_INVALID;
1251                 }
1252                 if (chk_bad) {
1253                         int blk = OFFSET_TO_BLOCK(addr);
1254
1255                         if (nfc_is_badblock(blk, g_bbt)) {
1256                                 diag_printf("Skipping bad block %u at addr 0x%08llx\n", blk, (u64)addr);
1257                                 addr += NF_BLK_SZ;
1258                                 g_block_offset++;
1259                                 continue;
1260                         }
1261                         chk_bad = 0;
1262                 }
1263
1264                 pg_no = addr / NF_PG_SZ;
1265                 if (offset != 0) {
1266                         /* Find which interleaved NAND device */
1267                         start_point = offset / (NF_PG_SZ / num_of_nand_chips);
1268                 } else {
1269                         start_point = 0;
1270                 }
1271                 for (i = start_point; i < num_of_nand_chips; i++) {
1272                         int chunk_size = (NF_PG_SZ - offset) / num_of_nand_chips;
1273
1274                         if (chunk_size > len)
1275                                 chunk_size = len;
1276                         nfc_printf(NFC_DEBUG_MED, "Reading page %d addr 0x%08llx chip %d len 0x%03x\n",
1277                                            pg_no, (u64)addr, i, chunk_size);
1278                         if (nfc_read_page(i, pg_no, 0) != 0) {
1279                                 diag_printf("** Error: Failed to read flash block %u at addr 0x%08llx\n",
1280                                                         OFFSET_TO_BLOCK(addr), (u64)addr);
1281                                 return FLASH_ERR_INVALID;
1282                         }
1283                         // now do the copying
1284                         nfc_buf_read(buf, NAND_MAIN_BUF0 + offset, chunk_size);
1285
1286                         buf += chunk_size;
1287                         len -= chunk_size;
1288                         addr += NF_PG_SZ / num_of_nand_chips - offset;
1289                         offset = 0;
1290                 }
1291                 chk_bad = (addr % NF_BLK_SZ) == 0;
1292         }
1293
1294         return FLASH_ERR_OK;
1295 }
1296
1297 /*
1298  * Support only either program for main area only. Or spare-area only for 512B.
1299  * If one wants to write to the spare-area, then before calling this function,
1300  * the spare area NFC RAM buffer has to be setup already. This function doesn't touch
1301  * the spare area NFC RAM buffer.
1302  *
1303  * @param pg_no                 page number offset from 0
1304  * @param pg_off                byte offset within the page
1305  * @param buf                   data buffer in the RAM to be written to NAND flash
1306  * @param ecc_force             can force ecc to be off. Otherwise, by default it is on
1307  *                                              unless the page offset is non-zero
1308  *
1309  * @return      0 if successful; non-zero otherwise
1310  */
1311 // SP-only opearation is not supported anymore !!!
1312 static int nfc_write_pg_random(u32 pg_no, u32 pg_off, u8 *buf, u32 ecc_force)
1313 {
1314         u16 flash_status;
1315         u32 ecc = NFC_FLASH_CONFIG2_ECC_EN, v, i;
1316         u32 write_count = NF_PG_SZ, start_point = 0, rba, rba_count = 0;
1317
1318         // the 2nd condition is to test for unaligned page address -- ecc has to be off.
1319         if (ecc_force == ECC_FORCE_OFF || pg_off != 0) {
1320                 ecc = 0;
1321         }
1322
1323         diag_printf1("%s(0x%x, 0x%x, %d)\n", __FUNCTION__, pg_no, pg_off, ecc_force);
1324         if (g_nfc_version != MXC_NFC_V1) {
1325                 int i;
1326
1327                 for (i = 1; i < NFC_SPARE_BUF_SZ / 16; i++) {
1328                         memcpy((void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ),
1329                                 (void *)(NAND_SPAR_BUF0 + i * 16), 16);
1330                 }
1331         }
1332         if (g_nfc_version >= MXC_NFC_V3) {
1333                 /* Check if Page size is greater than NFC buffer */
1334                 do {
1335                         rba = nfc_reg_read(NAND_CONFIGURATION1_REG);
1336                         if ((rba >> 4) & 0x7) {
1337                                 nfc_reg_write(rba & ~0x70, NAND_CONFIGURATION1_REG);
1338                         }
1339                         if (write_count <= NFC_BUFSIZE) {
1340                                 // No need to worry about the spare area
1341                                 nfc_buf_write(NAND_MAIN_BUF0, buf, write_count);
1342                                 write_count = 0;
1343                         } else {
1344                                 // No need to worry about the spare area
1345                                 nfc_buf_write(NAND_MAIN_BUF0, buf, NFC_BUFSIZE);
1346                                 write_count -= NFC_BUFSIZE;
1347                                 buf += NFC_BUFSIZE;
1348                         }
1349                         // combine the two commands for program
1350                         nfc_reg_write((FLASH_Program << 8) | FLASH_Send_Data, NAND_CMD_REG);
1351
1352                         for (i = start_point; i < num_of_nand_chips; i++) {
1353                                 rba = rba_count * ((NF_PG_SZ / num_of_nand_chips) / 512);
1354                                 /* Completely wrote out the NFC buffer, break and copy more to the NFC buffer */
1355                                 if (rba > 7) {
1356                                         rba_count = 0;
1357                                         break;
1358                                 }
1359
1360                                 // For ECC
1361                                 v = nfc_reg_read(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
1362                                 // setup config2 register for ECC enable or not
1363                                 write_nfc_ip_reg(v | ecc, NFC_FLASH_CONFIG2_REG);
1364
1365                                 start_nfc_addr_ops(FLASH_Program, pg_no, pg_off, 0, i, num_of_nand_chips);
1366
1367                                 // start auto-program
1368                                 nfc_reg_write(NAND_LAUNCH_AUTO_PROG, NAND_LAUNCH_REG);
1369                                 if (i < (num_of_nand_chips - i))
1370                                         wait_for_auto_prog_done();
1371                                 else
1372                                         wait_op_done();
1373                                 pg_off = 0;
1374                                 rba_count++;
1375                                 rba = nfc_reg_read(NAND_CONFIGURATION1_REG);
1376                         }
1377                         flash_status = NFC_STATUS_READ();
1378                         // check I/O bit 0 to see if it is 0 for success
1379                         if ((flash_status & ((0x1 << num_of_nand_chips) - 1)) != 0) {
1380                                 return -1;
1381                         }
1382                         start_point = i;
1383                 } while (write_count > 0);
1384         } else {
1385                 nfc_buf_write(NAND_MAIN_BUF0, buf, NF_PG_SZ);
1386 #ifdef BARKER_CODE_SWAP_LOC
1387                 // To replace the data at offset MXC_NAND_BOOT_LOAD_BARKER with
1388                 // the address of the NFC base. This is needed for certain platforms.
1389                 if (pg_no == 0) {
1390                         diag_printf("\n[INFO]: copy data at 0x%x to spare area and set it to 0x%x\n",
1391                                                 BARKER_CODE_SWAP_LOC, BARKER_CODE_VAL);
1392                         nfc_reg_write(nfc_reg_read(NFC_BASE + BARKER_CODE_SWAP_LOC), NAND_SPAR_BUF0);
1393                         // todo: set BARKER_CODE_VAL and BARKER_CODE_SWAP_LOC for skye, etc.
1394                         nfc_reg_write(BARKER_CODE_VAL, NFC_BASE + BARKER_CODE_SWAP_LOC);
1395                 }
1396 #endif
1397                 NFC_CMD_INPUT(FLASH_Send_Data);
1398                 start_nfc_addr_ops(FLASH_Program, pg_no, pg_off, 0, 0, num_of_nand_chips);
1399
1400                 NFC_DATA_INPUT(RAM_BUF_0, NFC_MAIN_ONLY, ecc);
1401                 if (g_is_4k_page && PG_2K_DATA_OP_MULTI_CYCLES()) {
1402                         diag_printf("4K page with multi cycle write is not supported\n");
1403                         return -1;
1404                 }
1405                 if (g_is_2k_page && PG_2K_DATA_OP_MULTI_CYCLES()) {
1406                         NFC_DATA_INPUT_2k(RAM_BUF_1);
1407                         NFC_DATA_INPUT_2k(RAM_BUF_2);
1408                         NFC_DATA_INPUT_2k(RAM_BUF_3);
1409                 }
1410                 NFC_CMD_INPUT(FLASH_Program);
1411
1412                 flash_status = NFC_STATUS_READ();
1413                 // check I/O bit 0 to see if it is 0 for success
1414                 if ((flash_status & 0x1) != 0) {
1415                         diag_printf("** Error: failed to program page %u at 0x%08x status=0x%02x\n",
1416                                                 pg_no, pg_no * NF_PG_SZ + pg_off, flash_status);
1417                         return -1;
1418                 }
1419         }
1420         return 0;
1421 }
1422
1423 #ifdef NFC_V3_0
1424 /*
1425  * Do a page read at random address
1426  *
1427  * @param pg_no             page number offset from 0
1428  * @param pg_off             byte offset within the page
1429  * @param ecc_force        can force ecc to be off. Otherwise, by default it is on
1430  *                                    unless the page offset is non-zero
1431  * @param cs_line            indicates which NAND of interleaved NAND devices is used
1432  *
1433  * @return  0 if successful; non-zero otherwise
1434  */
1435 static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line, u32 num_of_chips)
1436 {
1437         u32 ecc = NFC_FLASH_CONFIG2_ECC_EN;
1438         u32 v, res = 0;
1439         int i;
1440
1441         // clear the NAND_STATUS_SUM_REG register
1442         nfc_reg_write(0, NAND_STATUS_SUM_REG);
1443
1444         // the 2nd condition is to test for unaligned page address -- ecc has to be off.
1445         if (ecc_force == ECC_FORCE_OFF || pg_off != 0 ) {
1446                 ecc = 0;
1447         }
1448
1449         // Take care of config1 for RBA and SP_EN
1450         v = nfc_reg_read(NAND_CONFIGURATION1_REG) & ~0x71;
1451         nfc_reg_write(v, NAND_CONFIGURATION1_REG);
1452
1453         // For ECC
1454         v = nfc_reg_read(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
1455         // setup config2 register for ECC enable or not
1456         write_nfc_ip_reg(v | ecc, NFC_FLASH_CONFIG2_REG);
1457
1458         start_nfc_addr_ops(FLASH_Read_Mode1, pg_no, pg_off, 0, cs_line, num_of_chips);
1459
1460         if (g_is_2k_page || g_is_4k_page) {
1461                 // combine the two commands for 2k/4k page read
1462                 nfc_reg_write((FLASH_Read_Mode1_LG << 8) | FLASH_Read_Mode1, NAND_CMD_REG);
1463         } else {
1464                 // just one command is enough for 512 page
1465                 nfc_reg_write(FLASH_Read_Mode1, NAND_CMD_REG);
1466         }
1467
1468         // start auto-read
1469         nfc_reg_write(NAND_LAUNCH_AUTO_READ, NAND_LAUNCH_REG);
1470         wait_op_done();
1471
1472         for (i = 1; i < NFC_SPARE_BUF_SZ / 16; i++) {
1473                 memcpy((void *)(NAND_SPAR_BUF0 + i * 16),
1474                         (void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ), 16);
1475         }
1476         v = nfc_reg_read(NAND_STATUS_SUM_REG);
1477         // test for CS0 ECC error from the STATUS_SUM register
1478         if ((v & (0x0100 << cs_line)) != 0) {
1479                 // clear the status
1480                 nfc_reg_write(v & ~(0x0100 << cs_line), NAND_STATUS_SUM_REG);
1481                 diag_printf("ECC error from NAND_STATUS_SUM_REG(0x%08lx) = 0x%08x\n",
1482                                         NAND_STATUS_SUM_REG, v);
1483                 diag_printf("NAND_ECC_STATUS_RESULT_REG(0x%08lx) = 0x%08x\n", NAND_ECC_STATUS_RESULT_REG,
1484                                         nfc_reg_read(NAND_ECC_STATUS_RESULT_REG));
1485                 res = -1;
1486         }
1487         return res;
1488 }
1489 #else
1490 // for version V1 and V2 of NFC
1491 static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line,
1492                                                           u32 num_of_nand_chips)
1493 {
1494         u32 t1, ecc = 1;
1495         u8 t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0;
1496         int res = 0;
1497
1498         nfc_printf(NFC_DEBUG_MAX, "%s: reading page %u offset 0x%03x (addr 0x%08llx)\n",
1499                            __FUNCTION__, pg_no, pg_off, (flash_addr_t)pg_no * NF_PG_SZ + pg_off);
1500
1501         if (ecc_force == ECC_FORCE_OFF || pg_off != 0 )
1502                 ecc = 0;
1503
1504         NFC_CMD_INPUT(FLASH_Read_Mode1);
1505         start_nfc_addr_ops(FLASH_Read_Mode1, pg_no, pg_off, 0, 0, num_of_nand_chips);
1506
1507         if (g_is_2k_page || g_is_4k_page) {
1508                 NFC_CMD_INPUT(FLASH_Read_Mode1_LG);
1509         }
1510
1511         NFC_DATA_OUTPUT(RAM_BUF_0, FDO_PAGE_SPARE, ecc);
1512         switch (g_nfc_version & 0xf0) {
1513         case MXC_NFC_V1:
1514                 t1 = readw(ECC_STATUS_RESULT_REG);
1515                 if (g_is_2k_page && PG_2K_DATA_OP_MULTI_CYCLES()) {
1516                         NFC_DATA_OUTPUT(RAM_BUF_1, FDO_PAGE_SPARE, ecc);
1517                         t2 = readw(ECC_STATUS_RESULT_REG);
1518                         NFC_DATA_OUTPUT(RAM_BUF_2, FDO_PAGE_SPARE, ecc);
1519                         t3 = readw(ECC_STATUS_RESULT_REG);
1520                         NFC_DATA_OUTPUT(RAM_BUF_3, FDO_PAGE_SPARE, ecc);
1521                         t4 = readw(ECC_STATUS_RESULT_REG);
1522                 }
1523
1524                 if (ecc && ((t1 & 0xA) != 0x0 || (t2 & 0xA) != 0x0 ||
1525                                         (t3 & 0xA) != 0x0 || (t4 & 0xA) != 0x0)) {
1526                         diag_printf("\n** Error: ECC error page %u, col %u: ECC status=0x%x:0x%x:0x%x:0x%x\n",
1527                                                 pg_no, pg_off, t1, t2, t3, t4);
1528                         res = -1;
1529                         goto out;
1530                 }
1531                 break;
1532         case MXC_NFC_V2:
1533                 if (g_is_2k_page && PG_2K_DATA_OP_MULTI_CYCLES()) {
1534                         NFC_DATA_OUTPUT(RAM_BUF_1, FDO_PAGE_SPARE, ecc);
1535                         NFC_DATA_OUTPUT(RAM_BUF_2, FDO_PAGE_SPARE, ecc);
1536                         NFC_DATA_OUTPUT(RAM_BUF_3, FDO_PAGE_SPARE, ecc);
1537                 }
1538                 if (ecc) {
1539                         t1 = nfc_reg_read(ECC_STATUS_RESULT_REG);
1540                         if (g_is_2k_page || g_is_4k_page) {
1541                                 t2 = (t1 >> 4) & 0xF;
1542                                 t3 = (t1 >> 8) & 0xF;
1543                                 t4 = (t1 >> 12) & 0xF;
1544                                 if (g_is_4k_page) {
1545                                         t5 = (t1 >> 16) & 0xF;
1546                                         t6 = (t1 >> 20) & 0xF;
1547                                         t7 = (t1 >> 24) & 0xF;
1548                                         t8 = (t1 >> 28) & 0xF;
1549                                 }
1550                         }
1551                         if ((t1 = (t1 & 0xF)) > 4 || t2 > 4 || t3 > 4 || t4 > 4 ||
1552                                 t5 > 4 || t6 > 4 || t7 > 4 || t8 > 4) {
1553                                 diag_printf("\n** Error: ECC error reading block %u page %u\n",
1554                                                         pg_no / NF_PG_PER_BLK, pg_no % NF_PG_PER_BLK);
1555                                 diag_printf("   ECC status=%x:%x:%x:%x:%x:%x:%x:%x\n",
1556                                                         t1, t2, t3, t4, t5, t6, t7, t8);
1557                                 res = -1;
1558                                 goto out;
1559                         }
1560                 }
1561                 break;
1562         default:
1563                 diag_printf("Unknown NFC version: %d\n", g_nfc_version);
1564                 return -1;
1565         }
1566         if (g_nfc_version != MXC_NFC_V1) {
1567                 int i;
1568
1569                 for (i = 1; i < NFC_SPARE_BUF_SZ / 16; i++) {
1570                         memcpy((void *)(NAND_SPAR_BUF0 + i * 16),
1571                                    (void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ), 16);
1572                 }
1573         }
1574 #ifdef BARKER_CODE_SWAP_LOC
1575         // To replace the data at offset BARKER_CODE_SWAP_LOC with the address of the NFC base
1576         // This is needed for certain platforms
1577         if (pg_no == 0) {
1578                 diag_printf("\n[INFO]: copy back data from spare to 0x%x\n", BARKER_CODE_SWAP_LOC);
1579                 nfc_reg_write(nfc_reg_read(NAND_SPAR_BUF0), NFC_BASE + BARKER_CODE_SWAP_LOC);
1580         }
1581 #endif
1582
1583 out:
1584         return res;
1585 }
1586 #endif                  // ifndef NFC_V3_0
1587
1588 /*!
1589  * Read a page's both main and spare area from NAND flash to the internal RAM buffer.
1590  * It always reads data to the internal buffer 0.
1591  *
1592  * @param cs_line       which NAND device is used
1593  * @param pg_no    page number of the device
1594  * @param pg_off        offset within a page
1595  *
1596  * @return                              0 if no error or 1-bit error; -1 otherwise
1597  */
1598 static int nfc_read_page(u32 cs_line, u32 pg_no, u32 pg_off)
1599 {
1600         return nfc_read_pg_random(pg_no, pg_off, ECC_FORCE_ON, cs_line, num_of_nand_chips);
1601 }
1602
1603 static int nfc_write_page(u32 pg_no, u32 pg_off, u32 ecc_force)
1604 {
1605         u16 flash_status;
1606         u32 ecc = NFC_FLASH_CONFIG2_ECC_EN;
1607
1608         diag_printf1("Writing page %u addr 0x%08llx\n",
1609                                  pg_no, (u64)pg_no * NF_PG_SZ + pg_off);
1610         if (ecc_force == ECC_FORCE_OFF || pg_off != 0) {
1611                 ecc = 0;
1612         }
1613
1614         if (g_nfc_version != MXC_NFC_V1) {
1615                 int i;
1616
1617                 for (i = NFC_SPARE_BUF_SZ / 16 - 1; i >= 0; i--) {
1618                         memcpy((void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ),
1619                                 (void *)(NAND_SPAR_BUF0 + i * 16), 16);
1620                 }
1621         }
1622         if (g_nfc_version == MXC_NFC_V3) {
1623                 int i;
1624                 u32 v;
1625                 u32 start_point = 0, rba, rba_count = 0;
1626
1627                 rba = nfc_reg_read(NAND_CONFIGURATION1_REG);
1628                 if ((rba >> 4) & 0x7) {
1629                         nfc_reg_write(rba & ~0x70, NAND_CONFIGURATION1_REG);
1630                 }
1631                 // combine the two commands for program
1632                 nfc_reg_write((FLASH_Program << 8) | FLASH_Send_Data, NAND_CMD_REG);
1633
1634                 for (i = start_point; i < num_of_nand_chips; i++) {
1635                         rba = rba_count * ((NF_PG_SZ / num_of_nand_chips) / 512);
1636                         /* Completely wrote out the NFC buffer, break and copy more to the NFC buffer */
1637                         if (rba > 7) {
1638                                 rba_count = 0;
1639                                 break;
1640                         }
1641
1642                         // For ECC
1643                         v = nfc_reg_read(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
1644                         // setup config2 register for ECC enable or not
1645                         write_nfc_ip_reg(v | ecc, NFC_FLASH_CONFIG2_REG);
1646
1647                         start_nfc_addr_ops(FLASH_Program, pg_no, pg_off, 0, i, num_of_nand_chips);
1648
1649                         // start auto-program
1650                         nfc_reg_write(NAND_LAUNCH_AUTO_PROG, NAND_LAUNCH_REG);
1651                         if (i < (num_of_nand_chips - i))
1652                                 wait_for_auto_prog_done();
1653                         else
1654                                 wait_op_done();
1655                         pg_off = 0;
1656                         rba_count++;
1657                 }
1658                 flash_status = NFC_STATUS_READ();
1659                 // check I/O bit 0 to see if it is 0 for success
1660                 if ((flash_status & ((0x1 << num_of_nand_chips) - 1)) != 0) {
1661                         return -1;
1662                 }
1663                 rba = nfc_reg_read(NAND_CONFIGURATION1_REG);
1664                 start_point = i;
1665         } else {
1666                 NFC_CMD_INPUT(FLASH_Send_Data);
1667                 start_nfc_addr_ops(FLASH_Program, pg_no, pg_off, 0, 0, num_of_nand_chips);
1668
1669                 NFC_DATA_INPUT(RAM_BUF_0, NFC_MAIN_ONLY, ecc);
1670                 if (g_is_4k_page && PG_2K_DATA_OP_MULTI_CYCLES()) {
1671                         diag_printf("4K page with multi cycle write is not supported\n");
1672                         return -1;
1673                 }
1674                 if (g_is_2k_page && PG_2K_DATA_OP_MULTI_CYCLES()) {
1675                         NFC_DATA_INPUT_2k(RAM_BUF_1);
1676                         NFC_DATA_INPUT_2k(RAM_BUF_2);
1677                         NFC_DATA_INPUT_2k(RAM_BUF_3);
1678                 }
1679                 NFC_CMD_INPUT(FLASH_Program);
1680
1681                 flash_status = NFC_STATUS_READ();
1682                 if ((flash_status & 0x1) != 0) {
1683                         diag_printf("** Error: failed to program page %u at addr 0x%08llx\n",
1684                                                 pg_no, (u64)pg_no * NF_PG_SZ + pg_off);
1685                         return -1;
1686                 }
1687         }
1688         return 0;
1689 }
1690
1691 // Read data into buffer
1692 #ifndef MXCFLASH_SELECT_MULTI
1693 int flash_read_buf(void *addr, void *data, int len)
1694 #else
1695 int nandflash_read_buf(void *addr, void *data, int len)
1696 #endif
1697 {
1698         flash_addr_t flash_addr = (unsigned long)addr;
1699         return nfc_read_region(flash_addr, data, len);
1700 }
1701
1702 void mxc_nfc_print_info(void)
1703 {
1704         diag_printf("[0x%08x bytes]: %u blocks of %u pages of %u bytes each.\n",
1705                                 NF_DEV_SZ, NF_BLK_CNT,
1706                                 NF_PG_PER_BLK, NF_PG_SZ);
1707 }
1708
1709 static int mxc_nfc_isbad_bbt(u16 *bbt, int block)
1710 {
1711         cyg_uint8 res;
1712
1713         block <<= 1;
1714         res = (get_byte(bbt, block >> 3) >> (block & 0x06)) & 0x03;
1715         res ^= 0x03;
1716         return res;
1717 }
1718
1719 static int mxc_nfc_search_bbt(struct nand_bbt_descr *td)
1720 {
1721         int i;
1722
1723         td->pages = -1;
1724         for (i = 0; i < NF_BBT_MAX_NR; i++) {
1725                 u32 blk = NF_BLK_CNT - i - 1;
1726                 flash_addr_t addr = blk * NF_BLK_SZ;
1727
1728                 if (nfc_read_pg_random(addr / NF_PG_SZ, addr % NF_PG_SZ,
1729                                                            ECC_FORCE_ON, 0, num_of_nand_chips) != 0) {
1730                         diag_printf("Failed to read bbt page %u at 0x%08llx\n",
1731                                                 (u32)(addr / NF_PG_SZ), addr);
1732                         continue;
1733                 }
1734                 if (check_short_pattern((void *)NAND_SPAR_BUF0, td) == 0) {
1735                         diag_printf1("found BBT at block %u addr %08llx\n", blk, (u64)addr);
1736                         td->pages = blk * NF_PG_PER_BLK;
1737                         td->version = get_byte((void *)NAND_SPAR_BUF0, td->veroffs);
1738                         mark_blk_bad(blk, g_bbt, BLK_RESERVED);
1739                         diag_printf1("Found version %d BBT at block %d (0x%08llx)\n",
1740                                                  td->version, td->pages / NF_PG_PER_BLK,
1741                                                  (u64)td->pages * NF_PG_SZ);
1742                         return 0;
1743                 }
1744         }
1745         return 1;
1746 }
1747
1748 /*
1749  * Look for the BBT depending on the passed-in lowlevel value.
1750  * @param       lowlevel        If true, then it does a low level scan based on factory
1751  *                                              marked BI(block info) field with ECC off to decide if a
1752  *                                              block is bad.
1753  *                                              If false, then it checks to see if an existing BBT in the
1754  *                                              flash or not. If not, then it returns -1. If yes, it will
1755  *                                              prints out the number of bad blocks.
1756  *
1757  * @return      number of bad blocks for the whole nand flash
1758  *
1759  * Note: For a brand new flash, this function has to be called with
1760  *               lowlevel=true.
1761  *
1762  *
1763  */
1764 static int mxc_nfc_scan(bool lowlevel)
1765 {
1766         u32 bad = 0, i;
1767         u32 count1 = 0, count2 = 0;
1768         u8 *buf = NULL;
1769         struct nand_bbt_descr *td = g_mxc_nfc_bbt_main_descr;
1770         struct nand_bbt_descr *md = g_mxc_nfc_bbt_mirror_descr;
1771
1772         nfc_printf(NFC_DEBUG_MAX, "%s()\n", __FUNCTION__);
1773         mxc_nfc_scan_done = 0;
1774
1775         if (g_nfc_debug_measure) {
1776                 count1 = hal_timer_count();
1777         }
1778         // read out the last 4 blocks for marker
1779         // need to keep where is the td and md block number
1780         if (!lowlevel) {
1781                 struct nand_bbt_descr *bd;
1782
1783                 diag_printf1("Searching for BBT in the flash ...\n");
1784                 if (mxc_nfc_search_bbt(td) != 0) {
1785                         diag_printf("No main BBT found in flash\n");
1786                 }
1787                 if (md && mxc_nfc_search_bbt(md) != 0) {
1788                         diag_printf("No mirror BBT found in flash\n");
1789                 }
1790                 if (td->pages == -1 && (!md || md->pages == -1)) {
1791                         diag_printf("No BBT found. Need to do \"nand scan\" first\n");
1792                         return -1;
1793                 }
1794                 if (td->pages >= 0 && (md == NULL || md->version <= td->version)) {
1795                         bd = td;
1796                         nfc_printf(NFC_DEBUG_MIN, "Using normal bbt at page %d\n", bd->pages);
1797                 } else if (md != NULL && md->pages >= 0) {
1798                         bd = md;
1799                         nfc_printf(NFC_DEBUG_MIN, "Using mirror bbt at page %d\n", bd->pages);
1800                 } else {
1801                         diag_printf("** Error: Failed to read bbt from flash\n");
1802                         return -1;
1803                 }
1804                 nfc_read_page(0, bd->pages, 0);
1805                 for (i = 0; i < NF_BLK_CNT; i++) {
1806                         int res = mxc_nfc_isbad_bbt((u16 *)NAND_MAIN_BUF0, i);
1807                         if (res) {
1808                                 // construct the bad block table
1809                                 mark_blk_bad(i, g_bbt, res);
1810                                 bad++;
1811                         }
1812                 }
1813                 buf = g_bbt;
1814         } else {
1815                 diag_printf("Doing low level scan to construct BBT\n");
1816                 for (i = 0; i < NF_BLK_CNT; i++) {
1817                         int res = nfc_is_badblock(i, buf);
1818                         if (res) {
1819                                 // construct the bad block table
1820                                 if (!buf)
1821                                         mark_blk_bad(i, g_bbt, res);
1822                                 bad++;
1823                         }
1824                 }
1825         }
1826         diag_printf1("Total bad blocks: %d\n", bad);
1827         if (g_nfc_debug_measure) {
1828                 count2 = hal_timer_count();
1829                 diag_printf("counter1=0x%x, counter2=0x%x, diff=0x%x (%u usec)\n",
1830                                         count1, count2, count2 - count1,
1831                                         (count2 - count1) * 1000000 / 32768);
1832         }
1833         mxc_nfc_scan_done = 1;
1834         return bad;
1835 }
1836
1837 ////////////////////////// "nand" commands support /////////////////////////
1838 // Image management functions
1839 local_cmd_entry("info",
1840                                 "Show nand flash info (number of good/bad blocks)",
1841                                 "",
1842                                 nand_info,
1843                                 NAND_cmds
1844                    );
1845
1846 local_cmd_entry("show",
1847                                 "Show a page main/spare areas or spare area only (-s)",
1848                                 "-f <raw page address> | -b <block> [-s]",
1849                                 nand_show,
1850                                 NAND_cmds
1851                    );
1852
1853 local_cmd_entry("read",
1854                                 "Read data from nand flash into RAM",
1855                                 "-f <raw addr> -b <mem_load_addr> -l <byte len> [-c <col>]\n"
1856                                 "      Note -c is only for 2K-page for value <0, 2048+64-1>",
1857                                 nand_read,
1858                                 NAND_cmds
1859                    );
1860
1861 local_cmd_entry("write",
1862                                 "Write data from RAM into nand flash",
1863                                 "-f <raw address> -b <memory_address> -l <image_length> [-c <col_addr>]",
1864                                 nand_write,
1865                                 NAND_cmds
1866                    );
1867
1868 local_cmd_entry("erase",
1869                                 "Erase nand flash contents",
1870                                 "-f <raw address> -l <length> [-o]\n"
1871                                 "             -o: force erase (even for bad blocks)",
1872                                 nand_erase,
1873                                 NAND_cmds
1874                    );
1875
1876 local_cmd_entry("scan",
1877                                 "Scan bad blocks and may also save bad block table into the NAND flash.",
1878                                 "[-o] [-r]\n"
1879                                 "No argument: save existing bad block table (BBT)\n"
1880                                 "            -r: re-scan with ECC off and save BBT -- for brand NEW flash\n"
1881                                 "            -o: force erase all, reconstruct BBT (no ECC) and save BBT -- for development.",
1882                                 nand_scan,
1883                                 NAND_cmds
1884                    );
1885
1886 local_cmd_entry("debug",
1887                                 "Various NAND debug features ",
1888                                 "<0> no debug messages <default>\n"
1889                                 "             <1> min debug messages\n"
1890                                 "             <2> med debug messages\n"
1891                                 "             <3> max debug messages\n"
1892                                 "             <4> enable(default)/disable h/w ECC for both r/w\n"
1893                                 "             <5> disable(default)/enalbe spare-only read\n"
1894                                 "             <9> enable/disable measurement\n"
1895                                 "             no parameter - display current debug setup",
1896                                 nand_debug_fun,
1897                                 NAND_cmds
1898                                 );
1899
1900 local_cmd_entry("bad",
1901                                 "Mark bad block in BBT",
1902                                 "[-f <raw address>] [-b <block number>] [-c]\n"
1903                                 "           -c: clear bad block mark\n"
1904                                 "           -f and -b are mutually exclusive",
1905                                 nand_bad,
1906                                 NAND_cmds
1907                                 );
1908
1909 // Define table boundaries
1910 CYG_HAL_TABLE_BEGIN( __NAND_cmds_TAB__, NAND_cmds);
1911 CYG_HAL_TABLE_END( __NAND_cmds_TAB_END__, NAND_cmds);
1912
1913 extern struct cmd __NAND_cmds_TAB__[], __NAND_cmds_TAB_END__;
1914
1915 // CLI function
1916 static cmd_fun do_nand_cmds;
1917 RedBoot_nested_cmd("nand",
1918                    "Utility function to NAND flash using raw address",
1919                    "{cmds}",
1920                    do_nand_cmds,
1921                    __NAND_cmds_TAB__, &__NAND_cmds_TAB_END__
1922                   );
1923
1924 static void nand_usage(char *why)
1925 {
1926         diag_printf("*** invalid 'nand' command: %s\n", why);
1927         cmd_usage(__NAND_cmds_TAB__, &__NAND_cmds_TAB_END__, "nand ");
1928 }
1929
1930 static u32 curr_addr;
1931 static void nand_show(int argc, char *argv[])
1932 {
1933         u32 ra, block;
1934         bool flash_addr_set = false;
1935         bool block_set = false;
1936         bool spar_only = false;
1937         struct option_info opts[3];
1938
1939         init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM,
1940                           &ra, &flash_addr_set, "NAND FLASH memory byte address");
1941         init_opts(&opts[1], 'b', true, OPTION_ARG_TYPE_NUM,
1942                           &block, &block_set, "NAND FLASH memory block number");
1943         init_opts(&opts[2], 's', false, OPTION_ARG_TYPE_FLG,
1944                           &spar_only, NULL, "Spare only");
1945
1946         if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
1947                 return;
1948         }
1949         if (flash_addr_set && block_set) {
1950                 nand_usage("options -f and -b are mutually exclusive");
1951                 return;
1952         } else if (flash_addr_set) {
1953                 curr_addr = ra;
1954         } else if (block_set) {
1955                 ra = BLOCK_TO_OFFSET(block) + (unsigned long)flash_info.start;
1956                 curr_addr = ra;
1957         } else {
1958                 ra = curr_addr;
1959                 curr_addr += NF_PG_SZ;
1960         }
1961
1962         if (ra % NF_PG_SZ) {
1963                 diag_printf("** Error: flash address must be page aligned\n");
1964                 return;
1965         }
1966
1967         ra &= MXC_NAND_ADDR_MASK;
1968         if (nfc_is_badblock(OFFSET_TO_BLOCK(ra), g_bbt)) {
1969                 diag_printf("This is a bad block\n");
1970         }
1971
1972         print_page(ra, spar_only);
1973 }
1974
1975 /*!
1976  * For low level nand read command. It doesn't check for bad block or not
1977  */
1978 static void nand_read(int argc, char *argv[])
1979 {
1980         int len;
1981         u32 mem_addr, ra, col, i, pg_no, pg_off;
1982         bool mem_addr_set = false;
1983         bool flash_addr_set = false;
1984         bool length_set = false;
1985         bool col_set = false;
1986         struct option_info opts[4];
1987         int j = 0;
1988         bool ecc_status = g_ecc_enable;
1989
1990         init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
1991                           &mem_addr, &mem_addr_set, "memory base address");
1992         init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM,
1993                           &ra, &flash_addr_set, "FLASH memory base address");
1994         init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM,
1995                           &len, &length_set, "image length [in FLASH]");
1996         init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_NUM,
1997                           &col, &col_set, "column addr");
1998
1999         if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
2000                 nand_usage("invalid arguments");
2001                 return;
2002         }
2003
2004         if (ra % NF_PG_SZ) {
2005                 diag_printf("** Error: flash address must be page aligned\n");
2006                 return;
2007         }
2008
2009         if (!mem_addr_set || !flash_addr_set || !length_set) {
2010                 nand_usage("** Error: required parameter missing");
2011                 return;
2012         }
2013         if ((mem_addr < (CYG_ADDRESS)ram_start) ||
2014                 ((mem_addr+len) >= (CYG_ADDRESS)ram_end)) {
2015                 diag_printf("** WARNING: RAM address: 0x%08x may be invalid\n", mem_addr);
2016                 diag_printf("   valid range is 0x%p-0x%p\n", ram_start, ram_end);
2017         }
2018
2019         if (col_set) {
2020                 diag_printf("Random read at page %u, column 0x%04x\n",
2021                                         ra / NF_PG_SZ, col);
2022
2023                 if (g_is_2k_page || g_is_4k_page) {
2024                         g_ecc_enable = false;
2025                 }
2026                 nfc_read_pg_random(ra / NF_PG_SZ, col, ECC_FORCE_OFF, 0, num_of_nand_chips);
2027                 if (g_is_2k_page || g_is_4k_page) {
2028                         g_ecc_enable = ecc_status;
2029                 }
2030                 nfc_buf_read((void *)mem_addr, NAND_MAIN_BUF0, NF_PG_SZ);
2031                 return;
2032         }
2033
2034         // ensure integer multiple of page size
2035         len = (len + NF_PG_SZ - 1) & ~(NF_PG_SZ - 1);
2036         ra &= MXC_NAND_ADDR_MASK;
2037         do {
2038                 if (OFFSET_TO_BLOCK(ra) > (NF_BLK_CNT - 1)) {
2039                         diag_printf("\n** Error: flash address: 0x%08x out of range\n", ra);
2040                         return;
2041                 }
2042                 if (nfc_is_badblock(OFFSET_TO_BLOCK(ra), g_bbt)) {
2043                         diag_printf("\nSkipping bad block %u at addr=0x%08llx\n",
2044                                                 OFFSET_TO_BLOCK(ra), (u64)ra);
2045                         ra = (OFFSET_TO_BLOCK(ra) + 1) *  NF_BLK_SZ;
2046                         continue;
2047                 }
2048                 pg_no = ra / NF_PG_SZ;
2049                 pg_off = ra % NF_PG_SZ;
2050                 for (i = 0; i < num_of_nand_chips; i++) {
2051                         if (nfc_read_page(i, pg_no, pg_off) != 0) {
2052                                 diag_printf("\n** Error: uncorrectable ECC at addr 0x%08x\n", ra);
2053                                 diag_printf("use 'nand bad -b %u' to mark this block in BBT\n",
2054                                                         pg_no / NF_PG_PER_BLK);
2055                         }
2056                         if ((j++ % 0x20) == 0)
2057                                 diag_printf("\n%s 0x%08x: ", __FUNCTION__, ra);
2058                         diag_printf(".");
2059
2060                         nfc_buf_read((void *)mem_addr, NAND_MAIN_BUF0, NF_PG_SZ / num_of_nand_chips);
2061
2062                         ra += NF_PG_SZ / num_of_nand_chips;
2063                         mem_addr += NF_PG_SZ / num_of_nand_chips;
2064                         len -= NF_PG_SZ / num_of_nand_chips;
2065                         pg_off = 0;
2066                 }
2067         } while (len > 0);
2068         diag_printf("\n");
2069 }
2070
2071 static void nand_write(int argc, char *argv[])
2072 {
2073         int len, len_st, j = 0;
2074         u32 mem_addr, mem_addr_st, ra, col;
2075         bool mem_addr_set = false;
2076         bool flash_addr_set = false;
2077         bool length_set = false;
2078         bool col_set = false;
2079         struct option_info opts[4];
2080         bool ecc_status = g_ecc_enable;
2081
2082         init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
2083                           &mem_addr, &mem_addr_set, "memory base address");
2084         init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM,
2085                           &ra, &flash_addr_set, "FLASH memory base address");
2086         init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM,
2087                           &len, &length_set, "image length [in FLASH]");
2088         init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_NUM,
2089                           &col, &col_set, "column addr");
2090         if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
2091                 nand_usage("invalid arguments");
2092                 return;
2093         }
2094
2095         if (!mem_addr_set || !flash_addr_set || !length_set) {
2096                 nand_usage("required parameter missing");
2097                 return;
2098         }
2099
2100         if ((mem_addr < (CYG_ADDRESS)ram_start) ||
2101                 ((mem_addr + len) >= (CYG_ADDRESS)ram_end)) {
2102                 diag_printf("** WARNING: RAM address range: %p..%p may be invalid\n",
2103                                         (void *)mem_addr, (void *)(mem_addr + len));
2104                 diag_printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
2105         }
2106
2107         if (col_set) {
2108                 diag_printf("Random write at page %u, column %u\n", ra / NF_PG_SZ, col);
2109
2110                 if (g_is_2k_page || g_is_4k_page) {
2111                         g_ecc_enable = false;
2112                 }
2113                 nfc_write_pg_random(ra / NF_PG_SZ, col, (u8 *)mem_addr, 0);
2114                 if (g_is_2k_page || g_is_4k_page) {
2115                         g_ecc_enable = ecc_status;
2116                 }
2117                 return;
2118         }
2119
2120         if ((ra % NF_PG_SZ) != 0) {
2121                 diag_printf("** Error: flash address must be page aligned\n");
2122                 return;
2123         }
2124
2125         mem_addr_st = mem_addr;
2126         len_st = len;
2127         ra &= MXC_NAND_ADDR_MASK;
2128
2129         mxc_nfc_buf_clear(NAND_SPAR_BUF0, 0xff, NF_SPARE_SZ);
2130         do {
2131                 if (OFFSET_TO_BLOCK(ra) > (NF_BLK_CNT - 1)) {
2132                         diag_printf("\nFlash address 0x%08x out of range\n", ra);
2133                         return;
2134                 }
2135                 if (nfc_is_badblock(OFFSET_TO_BLOCK(ra), g_bbt)) {
2136                         diag_printf("\nSkipping bad block %u at addr=0x%08llx\n",
2137                                                 OFFSET_TO_BLOCK(ra), (u64)ra);
2138                         ra = (OFFSET_TO_BLOCK(ra) + 1) *  NF_BLK_SZ;
2139                         continue;
2140                 }
2141
2142                 if ((ra % NF_BLK_SZ) == 0) {
2143                          mem_addr_st = mem_addr;
2144                          len_st = len;
2145                 }
2146                 if (nfc_write_pg_random(ra / NF_PG_SZ, ra % NF_PG_SZ, (u8 *)mem_addr, 0) != 0) {
2147                         if (g_nfc_debug_level >= NFC_DEBUG_DEF) {
2148                                 diag_printf("\nWarning %d: program error at addr 0x%x\n", __LINE__, ra);
2149                         }
2150                         mark_blk_bad(OFFSET_TO_BLOCK(ra), g_bbt, BLK_BAD_RUNTIME);
2151                         ra = (OFFSET_TO_BLOCK(ra) + 1) *  NF_BLK_SZ; //make sure block size aligned
2152                         mem_addr = mem_addr_st; // rewind to block boundary
2153                         len = len_st;
2154                         continue;
2155                 }
2156                 if ((j++ % 0x20) == 0)
2157                         diag_printf("\nProgramming 0x%08x: ", ra);
2158                 diag_printf(".");
2159
2160                 len -= NF_PG_SZ;
2161                 ra += NF_PG_SZ;
2162                 mem_addr += NF_PG_SZ;
2163         } while (len > 0);
2164         diag_printf("\n");
2165 }
2166
2167 void nand_debug_fun(int argc, char *argv[])
2168 {
2169         int opt;
2170         const char *dbg_lvl_str;
2171
2172         if (argc == 3) {
2173                 opt = argv[2][0] - '0';
2174                 switch (opt) {
2175                 case 0:
2176                         g_nfc_debug_level = NFC_DEBUG_NONE;
2177                         break;
2178                 case 1:
2179                         g_nfc_debug_level = NFC_DEBUG_MIN;
2180                         break;
2181                 case 2:
2182                         g_nfc_debug_level = NFC_DEBUG_MED;
2183                         break;
2184                 case 3:
2185                         g_nfc_debug_level = NFC_DEBUG_MAX;
2186                         break;
2187                 case 4:
2188                         g_ecc_enable = g_ecc_enable? false: true;
2189                         break;
2190                 case 5:
2191                         // toggle g_spare_only_read_ok
2192                         g_spare_only_read_ok = g_spare_only_read_ok? false: true;
2193                         break;
2194                 case 9:
2195                         g_nfc_debug_measure = g_nfc_debug_measure? false: true;
2196                         break;
2197
2198                 default:
2199                         diag_printf("%s(%s) not supported\n", __FUNCTION__, argv[2]);
2200                 }
2201         }
2202         switch (g_nfc_debug_level) {
2203         case NFC_DEBUG_NONE:
2204                 dbg_lvl_str = "none";
2205                 break;
2206         case NFC_DEBUG_MIN:
2207                 dbg_lvl_str = "min";
2208                 break;
2209         case NFC_DEBUG_MED:
2210                 dbg_lvl_str = "med";
2211                 break;
2212         case NFC_DEBUG_MAX:
2213                 dbg_lvl_str = "max";
2214                 break;
2215         default:
2216                 dbg_lvl_str = "invalid";
2217         }
2218         diag_printf("Current debug options are:\n");
2219         diag_printf("    h/w ECC: %s\n", g_ecc_enable ? "on" : "off");
2220         diag_printf("    sp-only read: %s\n", g_spare_only_read_ok ? "on" : "off");
2221         diag_printf("    measurement: %s\n", g_nfc_debug_measure ? "on" : "off");
2222         diag_printf("    message level: %s\n", dbg_lvl_str);
2223 }
2224
2225 static void nand_erase(int argc, char *argv[])
2226 {
2227         u32 len, ra;
2228         bool faddr_set = false;
2229         bool force_erase_set = false;
2230         bool length_set = false;
2231         struct option_info opts[4];
2232
2233         init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM,
2234                   &ra, &faddr_set, "FLASH memory base address");
2235         init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM,
2236                   &len, &length_set, "length in bytes");
2237         init_opts(&opts[2], 'o', false, OPTION_ARG_TYPE_FLG,
2238                   &force_erase_set, &force_erase_set, "force erases block");
2239
2240         if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
2241                 nand_usage("invalid arguments");
2242                 return;
2243         }
2244
2245         if (!faddr_set || !length_set) {
2246                 nand_usage("missing argument");
2247                 return;
2248         }
2249         if ((ra % NF_BLK_SZ) != 0) {
2250                 diag_printf("Address must be block aligned!\n");
2251                 diag_printf("Block size is 0x%x\n", NF_BLK_SZ);
2252                 return;
2253         }
2254         if ((len % NF_BLK_SZ) != 0) {
2255                 diag_printf("length must be block aligned!\n");
2256                 diag_printf("Block size is 0x%x\n", NF_BLK_SZ);
2257                 return;
2258         }
2259         if (len == 0) {
2260                 diag_printf("length must be > 0!\n");
2261                 return;
2262         }
2263
2264         if (!verify_action("About to erase 0x%08x bytes from nand offset 0x%08x", len, ra)) {
2265                 diag_printf("** Aborted\n");
2266                 return;
2267         }
2268
2269         diag_printf1("Enabling flash from %p..%p\n", (u8 *)ra, (u8 *)ra + len - 1);
2270         FLASH_Enable((u8 *)ra, (u8 *)ra + len);
2271         if (force_erase_set == true) {
2272                 diag_printf("Force erase ...");
2273                 nfc_erase_region(ra, len, 0, 1);
2274                 diag_printf("\n");
2275         } else {
2276                 nfc_erase_region(ra, len, 1, 1);
2277         }
2278         FLASH_Disable((u8 *)ra, (u8 *)ra + len);
2279         diag_printf("\n");
2280 }
2281
2282 extern void romupdate(int argc, char *argv[]);
2283 static void nand_scan(int argc, char *argv[])
2284 {
2285         bool force_erase = false;
2286         bool force_rescan = false;
2287         struct option_info opts[2];
2288
2289         init_opts(&opts[0], 'o', false, OPTION_ARG_TYPE_FLG,
2290                   &force_erase, NULL, "force erases block first");
2291
2292         init_opts(&opts[1], 'r', false, OPTION_ARG_TYPE_FLG,
2293                   &force_rescan, NULL, "force low level re-scan");
2294
2295         if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
2296                 nand_usage("invalid arguments");
2297                 return;
2298         }
2299
2300         if (!force_erase && !force_rescan && !mxc_nfc_scan_done) {
2301                 diag_printf("Need to build BBT first with \"nand scan [-o|-r]\"\n");
2302                 return;
2303         }
2304         if (force_erase) {
2305                 void *bbt = g_bbt;
2306
2307                 diag_printf("Force erase first ...\n");
2308                 g_bbt = NULL;
2309                 // do force erase, skipping bad blocks. After this call, g_bbt should be re-built
2310                 // for the whole NAND flash.
2311                 if (nfc_erase_region(0, NF_DEV_SZ, true, false) != 0) {
2312                         g_bbt = bbt;
2313                         return;
2314                 }
2315                 g_bbt = bbt;
2316                 mxc_nfc_scan_done = 0;
2317                 diag_printf("\n");
2318         }
2319         if (force_rescan) {
2320                 diag_printf("Force re-scan ...\n");
2321                 memset(g_bbt, 0, g_bbt_sz);
2322                 mxc_nfc_scan(true);
2323         }
2324         // program g_bbt into the flash
2325         diag_printf("Writing BBT to flash\n");
2326         if (program_bbt_to_flash() != 0) {
2327                 diag_printf("Error: Failed to write BBT to flash\n");
2328         }
2329         if (force_erase) {
2330                 romupdate(0, NULL);
2331         }
2332 }
2333
2334 static void nand_info(int argc, char *argv[])
2335 {
2336         u32 i, j = 0;
2337
2338         diag_printf("\nType:\t\t %s\n", NF_VEND_INFO);
2339         diag_printf("Total size:\t 0x%08x bytes (%d MiB)\n", NF_DEV_SZ, NF_DEV_SZ / SZ_1M);
2340         diag_printf("Total blocks:\t 0x%x (%d)\n", NF_BLK_CNT, NF_BLK_CNT);
2341         diag_printf("Block size:\t 0x%x (%d)\n", NF_BLK_SZ, NF_BLK_SZ);
2342         diag_printf("Page size:\t 0x%x (%d)\n", NF_PG_SZ, NF_PG_SZ);
2343         diag_printf("Spare size:\t 0x%x (%d)\n", NF_SPARE_SZ, NF_SPARE_SZ);
2344         diag_printf("Pages per block: 0x%x (%d)\n", NF_PG_PER_BLK, NF_PG_PER_BLK);
2345
2346         if (mxc_nfc_scan(false) == -1) {
2347                 return;
2348         }
2349         diag_printf("\n");
2350         for (i = 0; i < NF_BLK_CNT; i++) {
2351                 int res = nfc_is_badblock(i, g_bbt);
2352                 if (res & ~BLK_RESERVED) {
2353                         diag_printf("block %d at offset 0x%08x is a %s bad block\n",
2354                                                 i, i * NF_BLK_SZ, res == BLK_BAD_FACTORY ? "factory" : "runtime");
2355                         j++;
2356                 }
2357         }
2358         diag_printf("==================================\n");
2359         diag_printf("Found %d bad block(s) out of %d\n", j, i);
2360 }
2361
2362 static void nand_bad(int argc, char *argv[])
2363 {
2364         u32 ra;
2365         u32 block;
2366         bool ra_set = false;
2367         bool block_set = false;
2368         bool clear = false;
2369         struct option_info opts[3];
2370         int bad;
2371
2372         init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM,
2373                           &ra, &ra_set, "FLASH memory base address");
2374         init_opts(&opts[1], 'b', true, OPTION_ARG_TYPE_NUM,
2375                           &block, &block_set, "block number");
2376         init_opts(&opts[2], 'c', false, OPTION_ARG_TYPE_FLG,
2377                           &clear, NULL, "clear bad block marker");
2378
2379         if (!scan_opts(argc, argv, 2, opts, NUM_ELEMS(opts), NULL, 0, NULL)) {
2380                 nand_usage("invalid arguments");
2381                 return;
2382         }
2383
2384         if (!ra_set && !block_set) {
2385                 nand_usage("missing argument");
2386                 return;
2387         }
2388         if (ra_set && block_set) {
2389                 nand_usage("options -f and -b are mutually exclusive");
2390                 return;
2391         } else if (ra_set) {
2392                 block = OFFSET_TO_BLOCK(ra & MXC_NAND_ADDR_MASK);
2393         } else {
2394                 ra = BLOCK_TO_OFFSET(block) + (unsigned long)flash_info.start;
2395         }
2396         if ((ra % NF_BLK_SZ) != 0) {
2397                 diag_printf("Address is not block aligned!\n");
2398                 diag_printf("Block size is 0x%08x\n", NF_BLK_SZ);
2399                 return;
2400         }
2401
2402         bad = nfc_is_badblock(block, g_bbt);
2403         if ((bad && !clear) || (!bad && clear)) {
2404                 diag_printf("block %5u at address 0x%08x is already %s\n",
2405                                         block, ra, bad ? "bad" : "good");
2406                 return;
2407         }
2408         if (clear && bad != BLK_BAD_RUNTIME) {
2409                 diag_printf("Refusing to mark a factory bad block as good!\n");
2410                 return;
2411         }
2412         if (!verify_action("Mark block %u at address 0x%08x %s in BBT",
2413                                            block, ra, clear ? "good" : "bad")) {
2414                 diag_printf("** Aborted\n");
2415                 return;
2416         }
2417
2418         nfc_printf(NFC_DEBUG_MIN, "Marking block %5u at 0x%08x %s\n",
2419                            block, ra, clear ? "good" : "bad");
2420         mark_blk_bad(block, g_bbt, clear ? 0 : BLK_BAD_RUNTIME);
2421         mxc_nfc_update_bbt(g_mxc_nfc_bbt_main_descr,
2422                                            g_mxc_nfc_bbt_mirror_descr);
2423 }
2424
2425 static void do_nand_cmds(int argc, char *argv[])
2426 {
2427         struct cmd *cmd;
2428
2429         if (!mxcnfc_init_ok) {
2430                 flash_hwr_init();
2431                 if (!mxcnfc_init_ok) {
2432 #ifdef CYGHWR_DEVS_FLASH_MXC_MULTI
2433                         diag_printf("Warning: NAND flash hasn't been initialized. Try \"factive nand\" first\n\n");
2434 #else
2435                         diag_printf("Error: NAND flash hasn't been initialized\n");
2436 #endif
2437                         return;
2438                 }
2439         }
2440
2441         if (argc < 2) {
2442                 nand_usage("too few arguments");
2443                 return;
2444         }
2445
2446         if ((cmd = cmd_search(__NAND_cmds_TAB__, &__NAND_cmds_TAB_END__,
2447                                                   argv[1])) != NULL) {
2448                 cmd->fun(argc, argv);
2449                 return;
2450         }
2451         nand_usage("unrecognized command");
2452 }
2453
2454 /*!
2455  * Display a memory region by 16-bit words
2456  * @param pkt   pointer to the starting address of the memory
2457  * @param len   byte length of the buffer to be displayed
2458  */
2459 static void print_pkt_16(u16 *pkt, u32 len)
2460 {
2461         diag_printf("******************** %d bytes********************\n", len);
2462         u32 i = 0, tempLen = (len + 1) / 2;
2463
2464         while (tempLen != 0) {
2465                 if (tempLen >= 8) {
2466                         diag_printf("[%03x-%03x] ", i * 2, (i * 2) + 14);
2467                         diag_printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
2468                                                 pkt[i], pkt[i + 1], pkt[i + 2], pkt[i + 3],
2469                                                 pkt[i + 4], pkt[i + 5], pkt[i + 6], pkt[i + 7]);
2470                         tempLen -= 8;
2471                         i += 8;
2472                 } else {
2473                         if (tempLen != 0) {
2474                                 diag_printf("[%03x-%03x]", i * 2, (i + tempLen) * 2);
2475                                 while (tempLen-- != 0) {
2476                                         diag_printf(" %04x", pkt[i++]);
2477                                 }
2478                                 diag_printf("\n");
2479                         }
2480                         diag_printf("*************************************************\n");
2481                         return;
2482                 }
2483         }
2484 }
2485
2486 // addr = starting byte address within NAND flash
2487 static void print_page(u32 addr, bool spare_only)
2488 {
2489         u32 i, pg_no, pg_off;
2490         u32 blk_num = OFFSET_TO_BLOCK(addr), pg_num = OFFSET_TO_PAGE(addr);
2491
2492         if (addr % NF_PG_SZ) {
2493                 diag_printf("Non page-aligned read not supported here: 0x%x\n", addr);
2494                 return;
2495         }
2496         pg_no = addr / NF_PG_SZ;
2497         pg_off = addr % NF_PG_SZ;
2498         for (i = 0; i < num_of_nand_chips; i++) {
2499                 if (nfc_read_page(i, pg_no, pg_off) != 0) {
2500                         diag_printf("Error %d: uncorrectable. But still printing ...\n", __LINE__);
2501                 }
2502                 pg_off = 0;
2503                 diag_printf("\n============ Printing block(%d) page(%d)  ==============\n",
2504                                         blk_num, pg_num);
2505
2506                 diag_printf("<<<<<<<<< spare area >>>>>>>>>\n");
2507                 print_pkt_16((u16*)NAND_SPAR_BUF0, NF_SPARE_SZ);
2508
2509                 if (!spare_only) {
2510                         diag_printf("<<<<<<<<< main area >>>>>>>>>\n");
2511                         print_pkt_16((u16*)NAND_MAIN_BUF0, NF_PG_SZ / num_of_nand_chips);
2512                 }
2513
2514                 diag_printf("\n");
2515         }
2516 }