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