1 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
2 index 0a5babf..d5299d9 100644
3 --- a/arch/mips/Kconfig
4 +++ b/arch/mips/Kconfig
5 @@ -157,7 +157,6 @@ config MIPS_BCM7405DX_NAND
8 select MTD_BRCMNAND_VERIFY_WRITE
9 - select MTD_BLOCK_ROMBLOCK
11 config MIPS_BCM97459BX_NAND
12 bool "Support for BCM97459Bx with NAND flash"
13 diff --git a/arch/mips/brcmstb/common/cfe_call.c b/arch/mips/brcmstb/common/cfe_call.c
14 index 56f2bc9..38c2f77 100644
15 --- a/arch/mips/brcmstb/common/cfe_call.c
16 +++ b/arch/mips/brcmstb/common/cfe_call.c
19 extern unsigned int cfe_seal;
21 +#if 0 // by doliyu, to fixed mtd block
22 cfeEnvVarPairs_t gCfeEnvVarPairs[] = {
23 { "LINUX_FFS_STARTAD", "LINUX_FFS_SIZE" },
24 { "SPLASH_PART_STARTAD", "SPLASH_PART_SIZE" },
25 @@ -45,6 +46,13 @@ cfeEnvVarPairs_t gCfeEnvVarPairs[] = {
30 +cfeEnvVarPairs_t gCfeEnvVarPairs[] = {
36 EXPORT_SYMBOL(gCfeEnvVarPairs);
39 diff --git a/drivers/mtd/brcmnand/bcm7xxx-nand.c b/drivers/mtd/brcmnand/bcm7xxx-nand.c
40 index 6cea6bf..d1cddfd 100644
41 --- a/drivers/mtd/brcmnand/bcm7xxx-nand.c
42 +++ b/drivers/mtd/brcmnand/bcm7xxx-nand.c
43 @@ -46,12 +46,13 @@ when who what
44 #include <linux/mtd/brcmnand.h>
45 #include "brcmnand_priv.h"
48 -//#define PRINTK printk
49 +//#define PRINTK(...)
50 +#define PRINTK printk
52 #define DRIVER_NAME "bcm7xxx-nand"
53 #define DRIVER_INFO "Broadcom STB NAND controller"
56 //#ifdef CONFIG_MTD_PARTITIONS
57 //static const char *part_probes[] = { "cmdlinepart", NULL, };
59 @@ -74,7 +75,9 @@ when who what
60 * start of flash 1f7f_ffff flashSize-8MB rootfs Linux File System
62 #define SMALLEST_FLASH_SIZE (16<<20)
63 -#define DEFAULT_RESERVED_SIZE (8<<20)
64 +//#define DEFAULT_RESERVED_SIZE (8<<20)
65 +#define DEFAULT_RESERVED_SIZE (14<<20) //doliyu
67 #define DEFAULT_SPLASH_SIZE (1<<20)
68 #define DEFAULT_BBT0_SIZE_MB (1)
69 #define DEFAULT_BBT1_SIZE_MB (4)
70 @@ -176,6 +179,7 @@ static struct mtd_partition bcm7XXX_new_partition[] =
72 static struct mtd_partition bcm7XXX_old_partition[] =
75 { name: N_ROOTFS, offset: 0, size: DEFAULT_ROOTFS_SIZE },
76 #ifdef CONFIG_MTD_ECM_PARTITION
77 { name: N_AVAIL1, offset: DEFAULT_ROOTFS_SIZE, size: DEFAULT_AVAIL1_SIZE },
78 @@ -189,8 +193,66 @@ static struct mtd_partition bcm7XXX_old_partition[] =
79 /* Add 1 extra place-holder partition for splash, and a safety guard element */
80 {name: NULL, offset: 0, size: 0},
81 {name: NULL, offset: 0, size: 0}
82 + #else /* by doliyu : for splash init*/
83 + /* name offset size */
84 + { name: "rootfs", offset: 0, size:0x07200000 /* DEFAULT_ROOTFS_SIZE*/ }, /* rootfs is total nand size - 6 M Bytes. referr to cfe. bcm97335_devs.c */
85 + { name: "kernel", offset: 0x07200000, size: 4<<20 },
86 + { name: "boot", offset: 0x07600000, size: 4<<20 },
87 + { name: "splash", offset: 0x07A00000, size: 2<<20 },
88 + { name: "cfe", offset: 0x07C00000, size: 1<<20 },
89 + { name: "mac", offset: 0x07D00000, size: 1<<19 },
90 + { name: "env", offset: 0x07D80000, size: 1<<19 },
91 + { name: "nvm", offset: 0x07E00000, size: 1<<20 }, //csh change to 1 20091207
92 + /* BBT 1MB not mountable by anyone */
93 + /* { name: "data", offset: 0x20000000, size: 0 },*/
94 + /* Add 1 extra place-holder partition for splash, and a safety guard element */
95 + /* Add 1 extra place-holder partition for splash, and a safety guard element */
96 + {name: NULL, offset: 0, size: 0},
97 + {name: NULL, offset: 0, size: 0},
98 + {name: NULL, offset: 0, size: 0}
103 +static struct mtd_partition bcm7XXX_vuplus_partition[] =
105 + /* name offset size */
106 + { name: "rootfs", offset: 0, size:0x07400000 /* DEFAULT_ROOTFS_SIZE*/ }, /* rootfs is total nand size - 6 M Bytes. referr to cfe. bcm97335_devs.c */
107 + { name: "kernel", offset: 0x07400000, size: 4<<20 },
108 + { name: "boot", offset: 0x07800000, size: 4<<20 },
109 + { name: "cfe", offset: 0x07C00000, size: 1<<20 },
110 + { name: "mac", offset: 0x07D00000, size: 1<<19 },
111 + { name: "env", offset: 0x07D80000, size: 1<<19 },
112 + { name: "nvm", offset: 0x07E00000, size: 1<<20 }, //csh change to 1 20091207
113 + /* BBT 1MB not mountable by anyone */
114 + /* { name: "data", offset: 0x20000000, size: 0 },*/
115 + /* Add 1 extra place-holder partition for splash, and a safety guard element */
116 + /* Add 1 extra place-holder partition for splash, and a safety guard element */
117 + {name: NULL, offset: 0, size: 0},
118 + {name: NULL, offset: 0, size: 0}
121 +static struct mtd_partition bcm7XXX_vuplus_splash_partition[] =
123 + /* name offset size */
124 + { name: "rootfs", offset: 0, size:0x07200000 /* DEFAULT_ROOTFS_SIZE*/ }, /* rootfs is total nand size - 6 M Bytes. referr to cfe. bcm97335_devs.c */
125 + { name: "kernel", offset: 0x07200000, size: 4<<20 },
126 + { name: "boot", offset: 0x07600000, size: 4<<20 },
127 + { name: "splash", offset: 0x07A00000, size: 2<<20 },
128 + { name: "cfe", offset: 0x07C00000, size: 1<<20 },
129 + { name: "mac", offset: 0x07D00000, size: 1<<19 },
130 + { name: "env", offset: 0x07D80000, size: 1<<19 },
131 + { name: "nvm", offset: 0x07E00000, size: 1<<20 }, //csh change to 1 20091207
132 + /* BBT 1MB not mountable by anyone */
133 + /* { name: "data", offset: 0x20000000, size: 0 },*/
134 + /* Add 1 extra place-holder partition for splash, and a safety guard element */
135 + /* Add 1 extra place-holder partition for splash, and a safety guard element */
136 + {name: NULL, offset: 0, size: 0},
137 + {name: NULL, offset: 0, size: 0}
142 #if defined( CONFIG_MTD_BRCMNAND_DISABLE_XOR )
143 static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_no_xor_partition;
145 @@ -198,7 +260,9 @@ static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_no_xor_partition;
146 static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_new_partition;
149 -static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_old_partition;
150 +//static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_old_partition;
151 +static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_vuplus_splash_partition;
155 struct brcmnand_info {
156 @@ -261,7 +325,7 @@ brcmnanddrv_setup_mtd_partitions(struct brcmnand_info* nandinfo, int *numParts)
158 * Is XOR disabled? if so use the new partition.
160 - if (nandinfo->brcmnand.xor_disable) {
161 + if (nandinfo->brcmnand.xor_disable[0]) { //by doliyu
162 bcm7XXX_nand_parts = bcm7XXX_no_xor_partition;
164 if (device_size(mtd) <= (512ULL <<20)) {
165 @@ -309,7 +373,7 @@ brcmnanddrv_setup_mtd_partitions(struct brcmnand_info* nandinfo, int *numParts)
171 /* NAND on CS1, same partition as that of CONFIG_MTD_NEW_PARTITION */
172 PRINTK("nandinfo->brcmnand.CS[0] = %d\n", nandinfo->brcmnand.CS[0]);
173 PRINTK("bcm7XXX_nand_parts=%p, bcm7XXX_new_partition=%p, bcm7XXX_old_partition=%p\n",
174 @@ -375,7 +439,7 @@ print_partition(*numParts);
175 nandinfo->parts = bcm7XXX_nand_parts;
176 bcm7XXX_nand_parts[0].size = size - DEFAULT_RESERVED_SIZE - ecm_size;
177 bcm7XXX_nand_parts[0].ecclayout = mtd->ecclayout;
178 -PRINTK("numParts=%d\n", numParts);
179 +PRINTK("numParts=%d\n", *numParts);
180 PRINTK("Part[%d] name=%s, size=%llx, offset=%llx\n", i, bcm7XXX_nand_parts[0].name,
181 bcm7XXX_nand_parts[0].size, bcm7XXX_nand_parts[0].offset);
183 diff --git a/drivers/mtd/brcmnand/brcmnand_base.c b/drivers/mtd/brcmnand/brcmnand_base.c
184 index 3bc428a..294cdfc 100644
185 --- a/drivers/mtd/brcmnand/brcmnand_base.c
186 +++ b/drivers/mtd/brcmnand/brcmnand_base.c
187 @@ -181,8 +181,8 @@ static brcmnand_chip_Id brcmnand_chips[] = {
188 .options = NAND_USE_FLASH_BBT, /* Use BBT on flash */
190 //| NAND_COMPLEX_OOB_WRITE /* Write data together with OOB for write_oob */
191 - .timing1 = 0, //00070000,
193 + .timing1 = 0x4232222D,
194 + .timing2 = 0x00000D94,
196 .ctrlVersion = 0, /* THT Verified on data-sheet 7/10/08: Allows 4 on main and 4 on OOB */
198 @@ -537,7 +537,7 @@ static brcmnand_chip_Id brcmnand_chips[] = {
199 .chipId = HYNIX_HY27UT088G2A,
200 .mafId = FLASHTYPE_HYNIX,
201 .chipIdStr = "HYNIX_HY27UT088G2A",
202 - .options = NAND_USE_FLASH_BBT, /* Use BBT on flash */
203 + .options = NAND_USE_FLASH_BBT|NAND_SCAN_BI_3RD_PAGE, /* BBT on flash + BI on (last-2) page */
204 //| NAND_COMPLEX_OOB_WRITE /* Write data together with OOB for write_oob */
205 .idOptions = BRCMNAND_ID_EXT_BYTES,
207 @@ -550,7 +550,7 @@ static brcmnand_chip_Id brcmnand_chips[] = {
208 .chipId = HYNIX_HY27UAG8T2M,
209 .mafId = FLASHTYPE_HYNIX,
210 .chipIdStr = "HYNIX_HY27UAG8T2M",
211 - .options = NAND_USE_FLASH_BBT, /* Use BBT on flash */
212 + .options = NAND_USE_FLASH_BBT|NAND_SCAN_BI_3RD_PAGE, /* BBT on flash + BI on (last-2) page */
213 //| NAND_COMPLEX_OOB_WRITE /* Write data together with OOB for write_oob */
214 .idOptions = BRCMNAND_ID_EXT_BYTES,
216 @@ -605,13 +605,43 @@ static const unsigned char ffchars[] = {
218 //static unsigned char eccmask[128]; // Will be initialized during probe
220 +//static unsigned char eccmask[128]; // Will be initialized during probe
222 +#define BCHP_NAND_LAST_REG BCHP_NAND_BLK_WR_PROTECT
223 +static uint32_t brcmnand_registerHoles[] = {
231 +#if CONFIG_MTD_BRCMNAND_VERSION > CONFIG_MTD_BRCMNAND_VERS_3_3
232 +#error "Not supported in 2.6.18 kernels"
233 + 0x28c4, 0x28c8, 0x28cc,
234 + 0x2910, 0x2914, 0x2918, 0x291c,
235 + 0x2920, 0x2924, 0x2928, 0x292c,
239 +// Is there a register at the location
240 +static int inRegisterHoles(uint32_t reg)
244 + for (i=0; i < ARRAY_SIZE(brcmnand_registerHoles); i++) {
245 + if (reg == brcmnand_registerHoles[i])
246 + return 1; // In register hole
248 + return 0; // Not in hole
251 static uint32_t brcmnand_ctrl_read(uint32_t nandCtrlReg)
253 volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS
254 + nandCtrlReg - BCHP_NAND_REVISION);
256 - if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
257 + if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_LAST_REG ||
258 (nandCtrlReg & 0x3) != 0) {
259 printk("brcmnand_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
261 @@ -625,7 +655,7 @@ static void brcmnand_ctrl_write(uint32_t nandCtrlReg, uint32_t val)
262 volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS
263 + nandCtrlReg - BCHP_NAND_REVISION);
265 - if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
266 + if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_LAST_REG ||
267 (nandCtrlReg & 0x3) != 0) {
268 printk( "brcmnand_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
270 @@ -689,6 +719,30 @@ if (gdebug > 3) printk("%s: offset=%0llx cs=%d ldw = %08x, udw = %08x\n", __FUN
271 return (ldw); //(ldw ^ 0x1FC00000);
275 + * Disable ECC, and return the original ACC register (for restore)
277 +uint32_t brcmnand_disable_ecc(void)
283 + acc0 = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
284 + acc = acc0 & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
285 + brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
291 +void brcmnand_restore_ecc(uint32_t orig_acc0)
293 + brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, orig_acc0);
299 /* Dont delete, may be useful for debugging */
301 @@ -739,7 +793,7 @@ static void print_config_regs(void)
302 nand_acc_control, nand_config, flash_id, nand_timing1, nand_timing2);
305 -#define NUM_NAND_REGS (1+((BCHP_NAND_BLK_WR_PROTECT-BCHP_NAND_REVISION)/4))
306 +#define NUM_NAND_REGS (1+((BCHP_NAND_LAST_REG-BCHP_NAND_REVISION)/4))
308 static void print_nand_ctrl_regs(void)
310 @@ -1533,7 +1587,7 @@ void dump_nand_regs(struct brcmnand_chip* chip, loff_t offset, uint32_t pa, int
311 uint32_t reg = BCHP_NAND_REVISION+(i*4);
314 - if (reg == 0x281c) { // No NAND register at 0x281c
315 + if (inRegisterHoles(reg)) { // No NAND register at 0x281c
319 @@ -1603,6 +1657,7 @@ static int brcmnand_EDU_write_is_complete(struct mtd_info *mtd, int* outp_needBB
320 if (hif_err != 0) // No timeout
322 uint32_t flashStatus; // = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
326 if (!(hif_err & HIF_INTR2_EDU_DONE))
327 @@ -1612,11 +1667,7 @@ printk("hif_err=%08x\n", hif_err);
328 /******************* BUG BUG BUG *****************
329 * THT 01/06/09: What if EDU returns bus error? We should not mark the block bad then.
331 - //Get status: should we check HIF_INTR2_ERR?
332 - if (hif_err & HIF_INTR2_EDU_ERR)
333 - edu_err = EDU_get_error_status_register();
339 //EDU_volatileWrite(EDU_BASE_ADDRESS + EDU_DONE, 0x00000000);
340 @@ -1624,28 +1675,36 @@ printk("hif_err=%08x\n", hif_err);
341 flashStatus = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
343 /* Just to be dead sure */
344 - if (!(flashStatus & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK)) {
345 - ret = brcmnand_ctrl_write_is_complete(mtd, outp_needBBT);
346 - // No need to check on the EDU side, already done inside ctrl_write_is_complete
348 + while (!(flashStatus & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK) && retries-- > 0) {
349 + // Cant call the ctrl version, we are in ISR context
350 + // ret = brcmnand_ctrl_write_is_complete(mtd, outp_needBBT);
351 + udelay(5000); // Wait for a total of 100 usec
352 //dump_nand_regs(chip, 0, 0, numDumps++);
354 + flashStatus = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
359 + //Get status: should we check HIF_INTR2_ERR?
360 + if (hif_err & HIF_INTR2_EDU_ERR)
361 + edu_err = EDU_get_error_status_register();
365 -// 2nd dump after CTRL_READY is asserted
367 -//dump_nand_regs(chip, 0, 0, numDumps++);
371 - if ((edu_err & EDU_ERR_STATUS_NandWrite) || (flashStatus & 0x01)) {
372 - /* Write did not complete, flash error, will mark block bad */
373 + /* sanity check on last cmd status */
374 + if ((edu_err & EDU_ERR_STATUS_NandWrite) && !(flashStatus & 0x1)) {
375 + int cmd = chip->ctrl_read(BCHP_NAND_CMD_START);
376 + printk(KERN_ERR"%s: false EDU write error status (edu_err: 0x%08X, flashStatus: 0x%08X) for NAND CMD %x \n",
377 + __FUNCTION__, edu_err, flashStatus, cmd);
378 + edu_err = EDU_get_error_status_register();
381 + /* we primarily rely on NAND controller FLASH_STATUS bit 0, since EDU error may not be cleared yet */
382 + if ((edu_err & EDU_ERR_STATUS_NandWrite) && (flashStatus & 0x01)) {
383 + /* // Write is complete, but not successful, flash error, will mark block bad */
385 - printk("EDU_write_is_complete(): error 0x%08X\n", edu_err);
387 + printk(KERN_ERR"%s: flash write error (edu_err: 0x%08X, flashStatus: 0x%08X)\n",
388 + __FUNCTION__, edu_err, flashStatus);
389 + ret = 1; // Write is complete, but not successful
394 @@ -1743,6 +1802,42 @@ printk("%s: AUTO: oob=%p, chip->oob_poi=%p, ooboffs=%d, len=%d, bytes=%d, boffs=
400 +#define DEBUG_UNCERR
402 +static uint32_t uncErrOob[7];
403 +static u_char uncErrData[512];
406 +void brcmnand_post_mortem_dump(struct mtd_info* mtd, loff_t offset)
410 + printk("%s at offset %llx\n", __FUNCTION__, offset);
413 + printk("NAND registers snapshot \n");
414 + for (i=0; i<NUM_NAND_REGS; i++) {
415 + uint32_t reg = BCHP_NAND_REVISION+(i*4);
418 + if (inRegisterHoles(reg)) { // No NAND register at 0x281c
422 + regval = brcmnand_ctrl_read(reg);
424 + if ((i % 4) == 0) {
425 + printk("\n%08x:", reg);
427 + printk(" %08x", regval);
435 * Returns 0 on success
436 * Expect a controller read was done before hand, and that the OOB data are read into NAND registers.
437 @@ -1769,7 +1864,7 @@ static int brcmnand_handle_false_read_ecc_unc_errors(
441 - uint32_t acc, acc0;
446 @@ -1779,19 +1874,17 @@ static int brcmnand_handle_false_read_ecc_unc_errors(
448 #if 1 /* Testing 1 2 3 */
450 - acc = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
451 - acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
452 - brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
453 + acc0 = brcmnand_disable_ecc();
455 chip->ctrl_writeAddr(chip, offset, 0);
456 PLATFORM_IOFLUSH_WAR();
457 - chip->ctrl_write(BCHP_NAND_CMD_START, OP_SPARE_AREA_READ);
458 + chip->ctrl_write(BCHP_NAND_CMD_START, OP_PAGE_READ);
460 // Wait until cache is filled up, disabling ECC checking
461 (void) brcmnand_spare_is_valid(mtd, FL_READING, 1);
464 - brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
465 + brcmnand_restore_ecc(acc0);
468 for (i = 0; i < 4; i++) {
469 @@ -1815,8 +1908,10 @@ print_oobbuf(p8, 16);
471 printk("p8[%d]=%02x\n", i, p8[i]);
479 {printk("%s: offset=%0llx, i=%d from %d to %d, eccOobSize=%d, eccbytes=%d, erased=%d, allFF=%d\n",
480 __FUNCTION__, offset, i, chip->eccOobSize-chip->eccbytes, chip->eccOobSize,
481 @@ -1847,6 +1942,25 @@ chip->eccOobSize, chip->eccbytes, erased, allFF);}
482 /* Real error: Disturb read returns uncorrectable errors */
484 if (gdebug > 3 ) {printk("<-- %s: ret -EBADMSG\n", __FUNCTION__);}
488 + // Copy the data buffer
489 + brcmnand_from_flash_memcpy32(chip, uncErrData, offset, mtd->eccsize);
490 + for (i = 0; i < 4; i++) {
491 + uncErrOob[i] = p32[i];
494 + printk("%s: Uncorrectable error at offset %llx\n", __FUNCTION__, offset);
497 + print_databuf(uncErrData, mtd->eccsize);
498 + printk("Spare Area\n");
499 + print_oobbuf((u_char*) uncErrOob, 16);
501 + brcmnand_post_mortem_dump(mtd, offset);
507 @@ -2027,16 +2141,14 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
508 struct brcmnand_chip* chip = mtd->priv;
509 static uint32_t ucdata[128];
510 u_char* uncorr_data = (u_char*) ucdata;
511 - uint32_t acc, acc0;
514 unsigned long irqflags;
516 int ret = 0, retries=2;
519 - acc = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
520 - acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
521 - brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
522 + acc0 = brcmnand_disable_ecc();
524 while (retries >= 0) {
525 // Resubmit the read-op
526 @@ -2070,7 +2182,7 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
534 // Reread the uncorrected buffer.
535 @@ -2098,8 +2210,10 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
536 offset, inp_hwECC[0], inp_hwECC[1], inp_hwECC[2],
537 inoutp_swECC[0], inoutp_swECC[1], inoutp_swECC[2]);
542 - brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
543 + brcmnand_restore_ecc(acc0);
547 @@ -2432,15 +2546,22 @@ brcmnand_edu_read_comp_intr(struct mtd_info* mtd,
549 static uint32_t oob0[4]; // Sparea Area to handle ECC workaround, aligned on DW boundary
550 uint32_t* p32 = (oobarea ? (uint32_t*) oobarea : (uint32_t*) &oob0[0]);
553 if (intr_status & HIF_INTR2_EDU_ERR) {
554 printk("%s: Should not call me with EDU ERR\n", __FUNCTION__);
557 intfc_status = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
558 - if (!(intfc_status & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK)) {
559 - printk("%s: Impossible, HIF_INTR2_CTRL_READY already asserted\n", __FUNCTION__);
561 + while (!(intfc_status & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK) && retries > 0) {
563 + udelay(5); // NAND guaranteed to finish read within 90us, this should be plenty of time
564 + intfc_status = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
566 + if (retries <= 0) {
567 + printk("%s: Impossible, HIF_INTR2_CTRL_READY already asserted, intr_status=%08x, offset=%llx\n",
568 + __FUNCTION__, intr_status, offset);
569 + //BUG(); Should assert here, but don't want to crash. HW guy guaranteed that it is set!!!!
572 // Remember last good sector read. Needed for HIF_INTR2 workaround.
573 @@ -3905,6 +4026,7 @@ static int brcmnand_refresh_blk(struct mtd_info *mtd, loff_t from)
574 * EDU ISR Implementation
577 +extern void EDU_issue_command(uint32_t dram_addr, uint32_t ext_addr,uint8 cmd);
580 * Submit the read op, then return immediately, without waiting for completion.
581 @@ -4437,7 +4559,7 @@ static int brcmnand_do_read_ops(struct mtd_info *mtd, loff_t from,
582 buffer_aligned = EDU_buffer_OK(bufpoi, EDU_READ);
584 // (3) Batch mode if writing more than 1 pages.
585 - numPages = min(MAX_JOB_QUEUE_SIZE, readlen>>chip->page_shift);
586 + numPages = min(MAX_JOB_QUEUE_SIZE, (int) (readlen>>chip->page_shift));
588 // Only do Batch mode if all 3 conditions are satisfied.
589 if (!aligned || !buffer_aligned || numPages <= 1) {
590 @@ -4935,22 +5057,26 @@ if (gdebug > 3) printk("-->%s: addr=%0llx\n", __FUNCTION__, addr);
591 * (2) OOB area is included in ECC calculation for BCH, so no need to check it
594 - if (chip->ecclevel != BRCMNAND_ECC_HAMMING) {
600 page = ((uint64_t) addr) >> chip->page_shift;
601 // Must read entire page
602 ret = chip->read_page(mtd, vbuf, oobbuf, page);
604 - printk(KERN_ERR "%s: brcmnand_read_page at %08x failed ret=%d\n",
605 + printk(KERN_ERR "%s: read_page at %08x failed ret=%d\n",
606 __FUNCTION__, (unsigned int) addr, ret);
607 + brcmnand_post_mortem_dump(mtd, addr);
614 + if (chip->ecclevel != BRCMNAND_ECC_HAMMING) {
615 + return ret; // We won't verify the OOB if not Hamming
619 * If there are no Input Buffer, there is nothing to verify.
620 * Reading the page should be enough.
621 @@ -5087,6 +5213,7 @@ printk("-->%s, offset=%0llx\n", __FUNCTION__, offset);}
623 printk(KERN_ERR "%s: brcmnand_posted_write_cache failed at offset=%0llx, ret=%d\n",
624 __FUNCTION__, offset + dataWritten, ret);
628 dataWritten += chip->eccsize;
629 @@ -5142,7 +5269,7 @@ printk("-->%s, page=%0llx\n", __FUNCTION__, page);}
633 - if (unlikely(!EDU_buffer_OK(inp_buf, EDU_WRITE)))
634 + if (unlikely(!EDU_buffer_OK((void*) inp_buf, EDU_WRITE)))
636 if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, trying non-EDU read\n", __FUNCTION__);
637 /* EDU does not work on non-aligned buffers */
638 @@ -5186,6 +5313,9 @@ if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, tryin
639 while (!list_empty(&gJobQ.jobQ)) {
640 spin_unlock_irqrestore(&gJobQ.lock, flags);
641 ret = ISR_wait_for_queue_completion();
645 spin_lock_irqsave(&gJobQ.lock, flags);
647 spin_unlock_irqrestore(&gJobQ.lock, flags);
648 @@ -5267,6 +5397,9 @@ if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, tryin
649 while (!list_empty(&gJobQ.jobQ)) {
650 spin_unlock_irqrestore(&gJobQ.lock, flags);
651 ret = ISR_wait_for_queue_completion();
655 spin_lock_irqsave(&gJobQ.lock, flags);
657 spin_unlock_irqrestore(&gJobQ.lock, flags);
658 @@ -5428,7 +5561,7 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s, offset=%0llx\n", __FUNCTION__, to);
660 * Group several pages for submission for small page NAND
662 - numPages = min(MAX_JOB_QUEUE_SIZE, writelen>>chip->page_shift);
663 + numPages = min(MAX_JOB_QUEUE_SIZE, (int) (writelen>>chip->page_shift));
666 if (buffer_aligned && numPages > 1 && chip->pageSize == chip->eccsize) {
667 @@ -5455,6 +5588,10 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s, offset=%0llx\n", __FUNCTION__, to);
670 ret = brcmnand_isr_write_pages(mtd, buf, chip->oob_poi, realpage, numPages);
678 @@ -5520,8 +5657,8 @@ printk("-->%s, offset=%0llx\n", __FUNCTION__, to);}
680 /* Do not allow writes past end of device */
681 if (unlikely((to + len) > device_size(mtd))) {
682 - DEBUG(MTD_DEBUG_LEVEL0, "%s: ", __FUNCTION__,
683 - "Attempt to write beyond end of device\n");
684 + DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to write beyond end of device\n",
686 printk("Attempt to write beyond end of device\n");
689 @@ -5674,8 +5811,8 @@ printk("-->%s, offset=%0llx, len=%08x\n", __FUNCTION__, to, (int) ops->len);}
691 if (unlikely((to + ops->len) > device_size(mtd)))
693 - DEBUG(MTD_DEBUG_LEVEL0, "%s: ", __FUNCTION__,
694 - "Attempt to write beyond end of device\n");
695 + DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to write beyond end of device\n",
697 printk("Attempt to write beyond end of device\n");
700 @@ -6137,8 +6274,9 @@ if (gdebug > 3 ) {printk( "%s: Erase past end of device, instr_addr=%016llx, in
702 /* Check if we have a bad block, we do not erase bad blocks */
703 if (brcmnand_block_checkbad(mtd, addr, 0, allowbbt)) {
704 - printk (KERN_ERR "%s: attempt to erase a bad block at addr 0x%08x\n", __FUNCTION__, (unsigned int) addr);
705 + printk (KERN_ERR "%s: attempt to erase a bad block at addr 0x%llx\n", __FUNCTION__, addr);
706 instr->state = MTD_ERASE_FAILED;
708 goto erase_one_block;
711 @@ -6898,11 +7036,11 @@ static int brcmnand_probe(struct mtd_info *mtd, unsigned int chipSelect)
712 if (chip->cellinfo) {
713 unsigned long devIdExt = chip->ctrl_read(BCHP_NAND_FLASH_DEVICE_ID_EXT);
714 unsigned char devId5thByte = (devIdExt & 0xff000000) >> 24;
715 - unsigned int nbrPlanes;
716 - unsigned int planeSizeMB, chipSizeMB, nandConfigChipSize;
717 + unsigned int nbrPlanes = 0;
718 + unsigned int planeSizeMB = 0, chipSizeMB, nandConfigChipSize;
719 unsigned char devId4thdByte = (chip->device_id & 0xff);
720 - unsigned int pageSize, pageSizeBits;
721 - unsigned int blockSize, blockSizeBits;
722 + unsigned int pageSize = 0, pageSizeBits = 0;
723 + unsigned int blockSize = 0, blockSizeBits = 0;
724 //unsigned int oobSize;
727 @@ -7043,7 +7181,7 @@ PRINTK("nandConfigChipSize = %04x\n", nandConfigChipSize);
728 else if ((brcmnand_chips[i].idOptions & BRCMNAND_ID_EXT_BYTES_TYPE2) ==
729 BRCMNAND_ID_EXT_BYTES_TYPE2)
731 - unsigned int oobSize, oobSizePerPage;
732 + unsigned int oobSize, oobSizePerPage = 0;
733 //uint32_t nandconfig, chipSizeShift;
735 /*---------------- 4th ID byte: page size, block size and OOB size ---------------- */
736 @@ -7663,11 +7801,6 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
738 cs = chip->CS[chip->numchips - 1];
739 PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
748 @@ -7678,6 +7811,7 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
749 printk("NAND_CS_NAND_XOR=%08x\n", nand_xor);
751 #ifdef CONFIG_MTD_BRCMNAND_DISABLE_XOR
753 /* Testing 1,2,3: Force XOR disable on CS0, if not done by CFE */
754 if (chip->CS[0] == 0) {
755 printk("Disabling XOR: Before: SEL=%08x, XOR=%08x\n", nand_select, nand_xor);
756 @@ -7699,6 +7833,11 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
757 printk("Disabling XOR on CS#%1d\n", chip->CS[i]);
758 chip->xor_disable[i] = 1;
762 + printk("Enable XOR on CS#%1d\n", chip->CS[i]);
763 + chip->xor_disable[i] = 0;
768 @@ -8021,7 +8160,7 @@ printk("Corrected ECC to Hamming for SLC flashes: ACC_CONTROL = %08lx from %08lx
771 if ( chip->ecclevel >= BRCMNAND_ECC_BCH_4) {
772 - corr_threshold = 2;
773 + corr_threshold = 3; // Changed from 2, since refresh is costly and vulnerable to AC-ON/OFF tests.
776 corr_threshold = 1; // 1 , default for Hamming
777 @@ -8227,6 +8366,13 @@ printk(KERN_INFO "ECC layout=%s\n", "brcmnand_oob_bch8_4k");
778 chip->ecclayout = &brcmnand_oob_bch8_4k;
781 + else if (NAND_IS_MLC(chip) && mtd->oobsize >= 216 &&
782 + chip->ecclevel == BRCMNAND_ECC_BCH_4 && mtd->writesize == 4096)
784 +printk(KERN_INFO "ECC layout=%s\n", "brcmnand_oob_bch4_4k");
785 + chip->ecclayout = &brcmnand_oob_bch4_4k;
789 printk(KERN_WARNING "No oob scheme defined for oobsize %d\n", mtd->oobsize);
791 @@ -8389,8 +8535,8 @@ printk(KERN_INFO "%s, eccsize=%d, writesize=%d, eccsteps=%d, ecclevel=%d, eccbyt
795 -#ifdef CONFIG_MTD_BRCMNAND_DISABLE_XOR
799 printk("-----------------------------------------------------\n");
800 print_nand_ctrl_regs();
801 printk("-----------------------------------------------------\n");
802 @@ -8411,7 +8557,6 @@ gdebug=4;
807 PRINTK("%s 99\n", __FUNCTION__);
810 diff --git a/drivers/mtd/brcmnand/brcmnand_bbt.c b/drivers/mtd/brcmnand/brcmnand_bbt.c
811 index 91e8510..d8924de 100644
812 --- a/drivers/mtd/brcmnand/brcmnand_bbt.c
813 +++ b/drivers/mtd/brcmnand/brcmnand_bbt.c
814 @@ -67,6 +67,7 @@ when who what
818 +#include <linux/kernel.h>
819 #include <linux/slab.h>
820 #include <linux/types.h>
821 #include <linux/mtd/mtd.h>
822 @@ -76,6 +77,7 @@ when who what
823 #include <linux/bitops.h>
824 #include <linux/delay.h>
825 #include <linux/vmalloc.h>
826 +#include <linux/syscalls.h>
828 #include "brcmnand_priv.h"
830 @@ -84,10 +86,50 @@ when who what
832 //#define PRINTK printk
834 +char brcmNandBBTMsg[1024];
835 +// #define BBT_DEBUG
836 +#ifdef BBT_DEBUG // Bypass quiet flag
838 +static int do_printk = 0; // To be turned on when we hit BBT out of space
839 +asmlinkage int bbt_vprintk(const char *fmt, va_list args)
841 + //unsigned long flags;
844 + //static char printk_buf[1024];
845 + //static int log_level_unknown = 1;
847 + extern void uart_puts(const char *);
849 + printed_len = vsprintf(brcmNandBBTMsg, fmt, args);
850 + uart_puts(brcmNandBBTMsg);
852 + return printed_len;
855 +asmlinkage int bbt_printk(const char *fmt, ...)
863 + va_start(args, fmt);
864 + r = bbt_vprintk(fmt, args);
870 +#define PRINTK bbt_printk
871 +//#define printk bbt_printk
875 extern int gClearBBT;
878 -char brcmNandBBTMsg[1024];
881 * rescan: 1. Rescan for bad blocks, and update existing BBT
882 @@ -204,7 +246,7 @@ __FUNCTION__,i, i, td->pattern[i], td->offs+i, p[td->offs + i]);
883 * Read the bad block table starting from page.
886 -static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
887 +static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, uint64_t page, int num,
888 int bits, int offs, int reserved_block_code)
890 int res, i, j, act = 0;
891 @@ -212,7 +254,9 @@ static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int
892 size_t retlen, len, totlen;
894 uint8_t msk = (uint8_t) ((1 << bits) - 1);
897 +int save_do_printk = do_printk;
899 totlen = (num * bits) >> 3;
900 from = ((loff_t)page) << this->page_shift;
902 @@ -222,6 +266,8 @@ static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int
903 this->ctrl_write(BCHP_NAND_ECC_CORR_ADDR, 0);
904 this->ctrl_write(BCHP_NAND_ECC_UNC_ADDR, 0);
910 len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
911 @@ -229,10 +275,14 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
912 res = mtd->read(mtd, from, len, &retlen, buf);
915 - printk (KERN_INFO "brcmnand_bbt: Error reading bad block table\n");
916 + printk (KERN_ERR "%s: Error reading bad block table, retlen=%d\n", __FUNCTION__);
919 - printk (KERN_WARNING "brcmnand_bbt: ECC error while reading bad block table\n");
920 + printk (KERN_ERR "%s: ECC error while reading bad block table\n", __FUNCTION__);
921 +PRINTK ("%s: ECC error while reading bad block table, res=%d\n", __FUNCTION__, res);
923 + /* THT 11/10/09: If read fails, we should ignore the data, so return w/o analyzing it */
928 @@ -245,6 +295,8 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
929 if (reserved_block_code && (tmp == reserved_block_code)) {
930 printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
931 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
932 +PRINTK ( "nand_read_bbt: Reserved block at 0x%08x\n",
933 + ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
934 this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
935 mtd->ecc_stats.bbtblocks++;
937 @@ -253,6 +305,8 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
938 * message to MTD_DEBUG_LEVEL0 */
939 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
940 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
941 +PRINTK ( "nand_read_bbt: Bad block at 0x%08x\n",
942 + ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
943 /* Factory marked bad or worn out ? */
945 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
946 @@ -261,8 +315,11 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
947 mtd->ecc_stats.badblocks++;
951 +do_printk=save_do_printk;
955 + from += (loff_t)len;
959 @@ -283,6 +340,12 @@ static int brcmnand_read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nan
960 struct brcmnand_chip *this = mtd->priv;
964 +int save_do_printk = do_printk;
967 +PRINTK("-->brcmnand_read_abs_bbt td=%c%c%c%c, td->pages[0]=%llx\n",
968 + td->pattern[0], td->pattern[1],td->pattern[2], td->pattern[3], td->pages[0]);
970 PRINTK("-->brcmnand_read_abs_bbt\n");
971 bits = td->options & NAND_BBT_NRBITS_MSK;
972 @@ -293,6 +356,9 @@ PRINTK("-->brcmnand_read_abs_bbt\n");
973 res = brcmnand_read_bbt (mtd, buf, td->pages[i], this->chipSize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
975 PRINTK("<-- brcmnand_read_abs_bbt ret = %d\n", res);
977 +do_printk = save_do_printk;
981 offs += this->chipSize >> (this->bbt_erase_shift + 2);
982 @@ -302,10 +368,16 @@ PRINTK("<-- brcmnand_read_abs_bbt ret = %d\n", res);
983 (uint32_t) (this->mtdSize >> this->bbt_erase_shift), bits, 0, td->reserved_block_code);
985 PRINTK("<-- brcmnand_read_abs_bbt 2 ret = %d\n", res);
987 +do_printk = save_do_printk;
992 PRINTK("<-- brcmnand_read_abs_bbt ret 0\n");
994 +do_printk = save_do_printk;
999 @@ -316,15 +388,23 @@ static int brcmnand_scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t off
1002 struct mtd_oob_ops ops;
1005 ops.mode = MTD_OOB_RAW;
1007 ops.ooblen = mtd->oobsize;
1009 + ops.oobbuf = &buf[mtd->writesize];
1013 - return mtd->read_oob(mtd, offs, &ops);
1014 + ret = mtd->read_oob(mtd, offs, &ops);
1016 +PRINTK("%s: Reading BBT Sig @%0llx, OOB=\n", __FUNCTION__, offs);
1018 +if (do_printk || gdebug)
1019 + print_oobbuf(ops.oobbuf, mtd->oobsize);
1025 @@ -377,7 +457,9 @@ PRINTK("read primary version\n");
1026 brcmnand_scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
1028 td->version[0] = buf[mtd->writesize + td->veroffs];
1029 - printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
1030 + printk(KERN_DEBUG "Bad block table at page %llx, version 0x%02X\n",
1031 + td->pages[0], td->version[0]);
1032 +PRINTK( "Bad block table at page %llx, version 0x%02X\n",
1033 td->pages[0], td->version[0]);
1036 @@ -387,8 +469,10 @@ PRINTK("read mirror version\n");
1037 brcmnand_scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
1039 md->version[0] = buf[mtd->writesize + md->veroffs];
1040 - printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
1041 + printk(KERN_DEBUG "Bad block table at page %llx, version 0x%02X\n",
1042 md->pages[0], md->version[0]);
1043 +PRINTK( "Bad block table at page %llx, version 0x%02X\n",
1044 + td->pages[0], td->version[0]);
1046 PRINTK("<-- %s\n", __FUNCTION__);
1048 @@ -434,7 +518,7 @@ static int brcmnand_scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr
1049 int pagesPerBlock = mtd->erasesize/mtd->writesize;
1052 - offs += (pagesPerBlock -1 ) * mtd->writesize;
1053 + offs += (loff_t)((pagesPerBlock -1 ) * mtd->writesize);
1055 ops.len = mtd->oobsize;
1056 ops.ooblen = mtd->oobsize;
1057 @@ -444,19 +528,26 @@ static int brcmnand_scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr
1058 ops.mode = MTD_OOB_PLACE;
1060 for (j=0; j < len; j++) {
1062 - * Read the full oob until read_oob is fixed to
1063 - * handle single byte reads for 16 bit
1066 ret = mtd->read_oob(mtd, offs, &ops);
1067 + if (ret == -EBADMSG) {// Uncorrectable errors
1071 + acc0 = brcmnand_disable_ecc();
1073 + // Re-read the OOB
1074 + ret = mtd->read_oob(mtd, offs, &ops);
1076 + // Enable ECC back
1077 + brcmnand_restore_ecc(acc0);
1082 if (check_short_pattern(buf, bd))
1085 - offs += (dir * mtd->writesize);
1086 + offs += (loff_t)(dir * mtd->writesize);
1090 @@ -489,8 +580,14 @@ PRINTK("-->brcmnand_create_bbt, bbt_erase_shift=%d, this->page_shift=%d\n", this
1091 if (bd->options & NAND_BBT_SCANALLPAGES)
1092 len = 1 << (this->bbt_erase_shift - this->page_shift);
1093 else { // Also for MLC
1094 - if (bd->options & NAND_BBT_SCAN2NDPAGE)
1096 + if (bd->options & NAND_BBT_SCAN2NDPAGE) {
1097 + if (this->options & NAND_SCAN_BI_3RD_PAGE) {
1098 + len = 3; // For Hynix MLC chips
1107 @@ -546,7 +643,7 @@ from, bd->options, mtd64_ll_low(startblock), mtd64_ll_low(numblocks));
1111 - from += (1 << this->bbt_erase_shift);
1112 + from += (loff_t)(1 << this->bbt_erase_shift);
1116 @@ -577,6 +674,7 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1117 int scanlen = mtd->writesize + mtd->oobsize;
1119 int blocktopage = this->bbt_erase_shift - this->page_shift;
1122 /* Search direction top -> down ? */
1123 if (td->options & NAND_BBT_LASTBLOCK) {
1124 @@ -604,15 +702,22 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1125 for (i = 0; i < chips; i++) {
1126 /* Reset version information */
1128 - td->pages[i] = -1;
1129 + td->pages[i] = BBT_NULL_PAGE;
1130 /* Scan the maximum number of blocks */
1131 for (block = 0; block < td->maxblocks; block++) {
1133 - int actblock = startblock + dir * block;
1134 + int64_t actblock = startblock + dir * block;
1135 loff_t offs = (uint64_t) actblock << this->bbt_erase_shift;
1138 /* Read first page */
1139 - brcmnand_scan_read_raw(mtd, buf, offs, mtd->writesize);
1140 + ret = brcmnand_scan_read_raw(mtd, buf, offs, mtd->writesize);
1142 + /* Here if the read routine returns -77 then the BBT data is invalid, ignore it */
1144 + // Ignore BBT if not there.
1147 if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
1148 td->pages[i] = actblock << blocktopage;
1149 if (td->options & NAND_BBT_VERSION) {
1150 @@ -625,10 +730,12 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1152 /* Check, if we found a bbt for each requested chip */
1153 for (i = 0; i < chips; i++) {
1154 - if (td->pages[i] == -1)
1155 - printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
1156 + if (td->pages[i] == BBT_NULL_PAGE)
1157 + printk (KERN_WARNING "Bad block table %c%c%c%c not found for chip %d\n",
1158 + td->pattern[0], td->pattern[1], td->pattern[2], td->pattern[3], i);
1161 - printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
1162 + printk(KERN_DEBUG "Bad block table found at page %llx, version 0x%02X\n", td->pages[i],
1166 @@ -674,6 +781,8 @@ static int brcmnand_search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
1170 +// 0 == OK, 1 = outofspace for BBT0, 2=outofspace for BBT1
1171 +static int outofspace_bbt = 0;
1172 static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1173 struct nand_bbt_descr *td, struct nand_bbt_descr *md,
1175 @@ -682,7 +791,7 @@ static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1176 struct erase_info einfo;
1177 int i, j, res, chip = 0, skip, dir;
1178 uint32_t bits, offs, sft, sftmsk, bbtoffs;
1179 - uint64_t startblock, numblocks, page, i64;
1180 + int64_t startblock, numblocks, page, i64;
1181 int nrchips, pageoffs, ooboffs;
1183 uint8_t rcode = td->reserved_block_code;
1184 @@ -690,6 +799,7 @@ static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1186 struct mtd_oob_ops ops;
1188 +bbt_outofspace_retry:
1190 DEBUG(MTD_DEBUG_LEVEL3, "-->%s\n", __FUNCTION__);
1191 ops.ooblen = mtd->oobsize;
1192 @@ -714,7 +824,8 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s\n", __FUNCTION__);
1196 -PRINTK("numblocks=%d, nrchips=%d\n", numblocks, nrchips);
1197 +PRINTK("%s Creating %c%c%c%c numblocks=%d, nrchips=%d, td->pages[0]=%llx\n",
1198 +__FUNCTION__, td->pattern[0],td->pattern[1], td->pattern[2], td->pattern[3] , numblocks, nrchips, td->pages[0]);
1200 /* Loop through the chips */
1201 for (; chip < nrchips; chip++) {
1202 @@ -723,7 +834,7 @@ PRINTK("numblocks=%d, nrchips=%d\n", numblocks, nrchips);
1203 * This applies for absolute placement too, as we have the
1204 * page nr. in td->pages.
1206 - if (td->pages[chip] != -1LL) {
1207 + if (td->pages[chip] != BBT_NULL_PAGE) {
1208 page = td->pages[chip];
1209 PRINTK("There is already a version of the table, go ahead and write it\n");
1211 @@ -741,11 +852,12 @@ PRINTK("There is already a version of the table, go ahead and write it\n");
1215 -printk("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n",
1216 +PRINTK("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n",
1217 __FUNCTION__, startblock, dir, td->maxblocks, skip);
1219 for (i = skip; i < td->maxblocks; i++) {
1220 - uint64_t block = startblock + dir * i;
1221 + uint64_t block = startblock + (int64_t) (dir * i);
1222 + // THT One byte contains 4 set of 2-bits, so divide block by 4 to index the BBT byte
1223 uint32_t blockindex = (uint32_t) (block >> 2);
1225 /* Check, if the block is bad */
1226 @@ -753,18 +865,36 @@ printk("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n",
1227 PRINTK("%s: Checking BBT: i=%d, block=%0llx, BBT=%08x\n",
1228 __FUNCTION__, i, block, this->bbt[blockindex]);
1230 - switch ((this->bbt[blockindex] >>
1231 - (2 * (block & 0x03))) & 0x03) {
1232 + // THT: bbt[blockindex] is the byte we are looking for, now get the 2 bits that
1233 + // is the BBT for the block (Shift (0,1,2,3) *2 positions depending on the block modulo 4)
1234 + switch ((this->bbt[blockindex] >> (2 * (block & 0x03)))
1240 page = block << (this->bbt_erase_shift - this->page_shift);
1242 +PRINTK("%s: Checking BBT2: page=%llx, md->pages[chip]=%llx\n",
1243 + __FUNCTION__, page, md->pages[chip]);
1245 /* Check, if the block is used by the mirror table */
1246 if (!md || md->pages[chip] != page)
1249 - printk (KERN_ERR "No space left to write bad block table\n");
1252 + if (!do_printk) { // If we get here then turn on debugging and retry
1256 + uint8_t rcode = td->reserved_block_code;
1257 + goto bbt_outofspace_retry;
1260 + printk (KERN_ERR "No space left to write bad block table %c%c%c%c\n",
1261 + td->pattern[0], td->pattern[1], td->pattern[2], td->pattern[3]);
1262 + brcmnand_post_mortem_dump(mtd, page<<this->page_shift);
1266 @@ -840,6 +970,11 @@ PRINTK("%s: Not NAND_BBT_SAVECONTENT\n", __FUNCTION__);
1268 /* Pattern is located in oob area of first page */
1269 memcpy(&buf[ooboffs + td->offs], td->pattern, td->len);
1271 + // Write the version number (1 byte)
1272 + if (td->options & NAND_BBT_VERSION) {
1273 + buf[ooboffs + td->veroffs]=td->version[0];
1277 /* walk through the memory table */
1278 @@ -955,21 +1090,30 @@ static int brcmnand_check_create (struct mtd_info *mtd, uint8_t *buf, struct nan
1280 /* Per chip or per device ? */
1281 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
1284 + * THT: Reset version to 0 if 0xff
1286 + if ((td->options & NAND_BBT_VERSION) && (td->version[i]==0xff) && td->pages[i] != BBT_NULL_PAGE)
1287 + td->version[i] = 0;
1288 + if ((md->options & NAND_BBT_VERSION) && (md->version[i]==0xff) && md->pages[i] != BBT_NULL_PAGE)
1289 + md->version[i] = 0;
1291 /* Mirrored table available ? */
1293 - if (td->pages[i] == -1 && md->pages[i] == -1) {
1294 + if (td->pages[i] == BBT_NULL_PAGE && md->pages[i] == BBT_NULL_PAGE) {
1299 - if (td->pages[i] == -1) {
1300 + if (td->pages[i] == BBT_NULL_PAGE) {
1302 td->version[i] = md->version[i];
1307 - if (md->pages[i] == -1) {
1308 + if (md->pages[i] == BBT_NULL_PAGE) {
1310 md->version[i] = td->version[i];
1312 @@ -996,7 +1140,7 @@ static int brcmnand_check_create (struct mtd_info *mtd, uint8_t *buf, struct nan
1316 - if (td->pages[i] == -1) {
1317 + if (td->pages[i] == BBT_NULL_PAGE) {
1321 @@ -1015,25 +1159,46 @@ create:
1327 /* read back first ? */
1329 - brcmnand_read_abs_bbt (mtd, buf, rd, chipsel);
1331 + res = brcmnand_read_abs_bbt (mtd, buf, rd, chipsel);
1333 /* If they weren't versioned, read both. */
1335 - brcmnand_read_abs_bbt (mtd, buf, rd2, chipsel);
1338 + int bbtlen = (uint32_t) (this->mtdSize >> (this->bbt_erase_shift + 2));
1339 + /* Clear the in-memory BBT first */
1340 +PRINTK("%s: Discarding previously read BBT %c%c%c%c, res=%d\n",
1341 +__FUNCTION__, rd->pattern[0], rd->pattern[1], rd->pattern[2], rd->pattern[3], res);
1342 + memset(this->bbt, 0, bbtlen);
1344 + res = brcmnand_read_abs_bbt (mtd, buf, rd2, chipsel);
1346 +PRINTK("%s: Read BBT %c%c%c%c returns res=%d, discarding\n",
1347 +__FUNCTION__, rd2->pattern[0], rd2->pattern[1], rd2->pattern[2], rd2->pattern[3], res);
1351 /* Write the bad block table to the device ? */
1352 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1353 res = brcmnand_write_bbt (mtd, buf, td, md, chipsel);
1356 + if (res ==-ENOSPC)
1357 + outofspace_bbt |= 1;
1362 /* Write the mirror bad block table to the device ? */
1363 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
1364 res = brcmnand_write_bbt (mtd, buf, md, td, chipsel);
1367 + if (res ==-ENOSPC)
1368 + outofspace_bbt |= 2;
1374 @@ -1067,7 +1232,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
1375 for (i = 0; i < chips; i++) {
1376 if ((td->options & NAND_BBT_ABSPAGE) ||
1377 !(td->options & NAND_BBT_WRITE)) {
1378 - if (td->pages[i] == -1)
1379 + if (td->pages[i] == BBT_NULL_PAGE)
1381 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
1383 @@ -1231,9 +1396,14 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s offs=%0llx\n", __FUNCTION__, offs);
1387 - td->version[chip]++;
1388 + (td->version[chip])++;
1390 + if (td->version[chip] == 0xff)
1391 + td->version[chip] =1;
1393 - md->version[chip]++;
1394 + (md->version[chip])++;
1395 + if (md->version[chip] == 0xff)
1396 + md->version[chip] =1;
1398 /* Write the bad block table to the device ? */
1399 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1400 @@ -1251,6 +1421,219 @@ out:
1405 + * brcmnand_reconstruct_bbt - [private] recreate bad block table(s)
1406 + * @mtd: MTD device structure
1407 + * @whichbbt: 1 = TD, 2 = MD
1409 + * The function reconstruct the bad block table(s) from the BI indicators.
1411 +int brcmnand_reconstruct_bbt (struct mtd_info *mtd, int whichbbt)
1413 + struct brcmnand_chip *this = mtd->priv;
1414 + int len, res = 0, writeops = 0;
1415 + int chip, chipsel;
1416 + uint8_t *buf = NULL;
1417 + struct nand_bbt_descr *td = this->bbt_td;
1418 + struct nand_bbt_descr *md = this->bbt_md;
1421 + uint64_t bOffset, startBlock, badBlock = 0;
1424 +PRINTK( "-->%s whichBBT=%x\n", __FUNCTION__, whichbbt);
1426 + if (!this->bbt || !td)
1430 + len = (uint32_t) (this->mtdSize >> (this->bbt_erase_shift + 2));
1431 + /* Allocate a temporary buffer for one eraseblock incl. oob */
1432 + len = (1 << this->bbt_erase_shift);
1433 + len += (len >> this->page_shift) * mtd->oobsize;
1434 + buf = vmalloc (len);
1436 + printk (KERN_ERR "brcmnand_update_bbt: Out of memory\n");
1441 + * Wipe out the BBT entries for the BBT space, and reconstruct it,
1442 + * but do not modify the other entries outside the BBT
1444 + if (this->mtdSize <= (512<<20)) {
1451 + /* Here we unset the entries in the BBT for the BBT region */
1452 + startBlock = this->mtdSize - bbtSize;
1453 + for (bOffset = startBlock; bOffset < this->mtdSize; bOffset += mtd->erasesize) {
1454 + // Calculate index into BBT and wipe it out.
1455 + uint32_t byteIndex = (uint32_t) bOffset >> 2;
1456 + uint8_t byte = this->bbt[byteIndex];
1457 + uint8_t byte0 = byte;
1459 + /* Clear the 2 bits for this block, then assign it back */
1460 + byte &= ~(0x03 << (2 * (bOffset & 0x03)));
1462 + /* If the contents changed, mark it */
1463 + if (byte != byte0) {
1465 + badBlock = bOffset;
1470 + /* Now erase the BBT region, adding to bad block if erase fail */
1473 + int64_t goodBlock = BBT_NULL_PAGE;
1475 + switch (writeops & 0x03) {
1476 + case 0x1: goodBlock = md->pages[0] >> this->page_shift; break;
1477 + case 0x2: goodBlock = td->pages[0] >> this->page_shift; break;
1478 + case 0x3: goodBlock = BBT_NULL_PAGE; break;
1479 + case 0: /* Impossible */ goodBlock = BBT_NULL_PAGE; break;
1483 + static char buf[512+58]; // 31 for alignment, +27 for OOB size
1487 + all0 = (uint8_t*) ((((unsigned int) &buf[0]) + 31) & (~31));
1488 + oob0 = &all0[512];
1490 + memset(all0, 0, 512);
1491 + memset(oob0, 0, 27);
1493 + for (bOffset = startBlock; bOffset < this->mtdSize; bOffset += mtd->erasesize) {
1497 + /* Skip over the good BBT */
1499 + if (bOffset == goodBlock)
1502 + PRINTK("Erasing block at %0llx\n", bOffset);
1503 + this->ctrl_writeAddr(this, bOffset, 0);
1505 + this->ctrl_write(BCHP_NAND_CMD_START, OP_BLOCK_ERASE);
1506 + // Wait until flash is ready
1507 + (void) this->write_is_complete(mtd, &needBBT);
1509 + printk(KERN_WARNING "%s: Erase failure, marking bad block @%016llx\n", __FUNCTION__, bOffset);
1511 + badBlock = bOffset;
1512 + (void) this->block_markbad(mtd, bOffset);
1515 + /* TBD: We should follow this with an ECC-disable write with all-0, ECC-enable then a re-erase
1516 + * But that is too dangerous for AC-on-off tests, especially for the BBT area
1521 + acc = bbt_ctrl_read(BCHP_NAND_ACC_CONTROL);
1522 + acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
1523 + bbt_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
1525 + chip->ctrl_writeAddr(chip, offset, 0);
1526 + PLATFORM_IOFLUSH_WAR();
1527 + chip->ctrl_write(BCHP_NAND_CMD_START, OP_PAGE_PROGRAM);
1529 + // Wait until cache is filled up, disabling ECC checking
1530 + (void) brcmnand_spare_is_valid(mtd, FL_READING, 1);
1533 + bbt_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
1540 + writeops = whichbbt;
1541 + if (modified) writeops = 3; // Do both
1543 +#if 0 // THT: TBD when we have per chip BBT
1544 + /* Do we have a bbt per chip ? */
1545 + if (td->options & NAND_BBT_PERCHIP) {
1546 + chip = (int) (offs >> this->chip_shift);
1554 + /* Warning this codes only support 1 NAND chip */
1556 + if (((writeops & 3) == 3) && (td->options & NAND_BBT_WRITE)) {
1559 +PRINTK("%s: Reconstructing both BBTs\n", __FUNCTION__);
1561 + td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1562 + res = brcmnand_write_bbt (mtd, buf, td, md, 0);
1564 + res2 = brcmnand_write_bbt (mtd, buf, md, td, 0);
1566 + if (!res && res2) /* At least one table write succeed. */
1573 + /* Write the bad block table to the device */
1575 + if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1576 +PRINTK("%s: Recreating Bbt0\n", __FUNCTION__);
1578 + td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1580 + // Look for the location of 1BBT
1581 + res = brcmnand_search_bbt(mtd, buf, md);
1583 + if (res) { // Mirror not found
1584 + PRINTK("%s: Re-creating Bbt0, but 1bBT is also bad, rescan for both\n", __FUNCTION__);
1589 +PRINTK("%s: Reconstructing both BBT0 from BBT1 at %08x\n", __FUNCTION__, md->pages[0]);
1590 + res = brcmnand_write_bbt (mtd, buf, td, md, 0);
1594 + /* Write the mirror bad block table to the device ? */
1595 + if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
1596 +PRINTK("%s: Recreating 1bBT\n", __FUNCTION__);
1598 + td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1600 + // Look for the location of Bbt0:
1601 + res = brcmnand_search_bbt(mtd, buf, td);
1603 + if (res) { // Mirror not found
1604 + PRINTK("%s: Re-creating Bbt0, but 1bBT is also bad, rescan for both\n", __FUNCTION__);
1608 +PRINTK("%s: Reconstructing both BBT1 from BBT0 at %08x\n", __FUNCTION__, td->pages[0]);
1609 + res = brcmnand_write_bbt (mtd, buf, md, td, 0);
1617 /* Define some generic bad / good block scan pattern which are used
1618 * while scanning a device for factory marked good / bad blocks. */
1619 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
1620 @@ -1388,11 +1771,17 @@ static int brcmnand_displayBBT(struct mtd_info* mtd)
1621 //unsigned char oobbuf[64];
1622 //struct nand_oobinfo oobsel;
1625 + int dbg=do_printk;
1627 // Size of BBT is 1MB if total flash is less than 512MB, 4MB otherwise
1628 int bbtSize = this->mtdSize > (512<<20) ? 4 << 20 : 1 << 20;
1631 - bOffsetEnd = this->mtdSize - bbtSize; // Skip BBT itself
1632 + bOffsetEnd = (loff_t)(this->mtdSize - bbtSize); // Skip BBT itself
1637 printk(KERN_INFO "----- Contents of BBT -----\n");
1638 for (bOffset=bOffsetStart; bOffset < bOffsetEnd; bOffset = bOffset + mtd->erasesize) {
1639 @@ -1402,12 +1791,50 @@ static int brcmnand_displayBBT(struct mtd_info* mtd)
1642 printk(KERN_INFO "----- END Contents of BBT -----\n");
1651 // Remove this block in production builds.
1654 +//#define TEST_CLEAR_BBT1
1655 +//#define TEST_INVALIDATE_BBT0
1657 +#ifdef TEST_INVALIDATE_BBT0
1658 +static uint32_t bbt_ctrl_read(uint32_t nandCtrlReg)
1660 + volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS
1661 + + nandCtrlReg - BCHP_NAND_REVISION);
1663 + if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
1664 + (nandCtrlReg & 0x3) != 0) {
1665 + printk("bbt_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
1667 +if (gdebug > 3) printk("%s: CMDREG=%08x val=%08x\n", __FUNCTION__, (unsigned int) nandCtrlReg, (unsigned int)*pReg);
1668 + return (uint32_t) (*pReg);
1672 +static void bbt_ctrl_write(uint32_t nandCtrlReg, uint32_t val)
1674 + volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS
1675 + + nandCtrlReg - BCHP_NAND_REVISION);
1677 + if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
1678 + (nandCtrlReg & 0x3) != 0) {
1679 + printk( "bbt_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
1681 + *pReg = (volatile unsigned long) (val);
1682 +if (gdebug > 3) printk("%s: CMDREG=%08x val=%08x\n", __FUNCTION__, nandCtrlReg, val);
1688 * Process brcmnand= kernel command arg, BEFORE building/reading BBT table.
1689 * Currently, the only accepted command is CLEARBBT, which in itself is a dangerous activity.
1690 @@ -1424,6 +1851,7 @@ static void brcmnand_preprocessKernelArg(struct mtd_info *mtd)
1695 PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n", __FUNCTION__, gClearBBT, device_size(mtd), mtd->erasesize);
1698 @@ -1431,10 +1859,48 @@ PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n", __FUNCTION__, gClearB
1700 case NANDCMD_CLEARBBT: // Force rescan of BBT (DANGEROUS, may lose Mfg's BIs).
1702 +#ifdef TEST_CLEAR_BBT1
1703 + bOffsetStart = 0x7ff00000;
1704 + bOffsetEnd = 0x7ff00000;
1705 +printk("%s: gClearBBT=clearbbt, start=%0llx, end=%0llx\n", __FUNCTION__,
1706 + bOffsetStart, bOffsetEnd);
1707 +#elif defined(TEST_INVALIDATE_BBT0)
1710 +uint8_t* oob = (uint8_t*) &oob0[0];
1712 +uint64_t bbt0Page = ((uint64_t) 0x7ff80000) >> this->page_shift;
1715 + bOffsetStart = 0x7ff80000; // FOrce it to skip erase
1716 + bOffsetEnd = 0x7ff00000;
1717 + res = this->read_page_oob(mtd, oob, bbt0Page);
1720 +memset(&oob[9], 0, 4); // * Overwrite the ECC to force EBADMSG
1721 +//bOffsetStart = 0x7ff80000;
1722 +//bOffsetEnd = 0x7ff80000;
1725 + acc0 = brcmnand_disable_ecc();
1727 +PRINTK("Invalidate ECC at page %llx\n", bbt0Page);
1729 + res = this->write_page_oob(mtd, oob, bbt0Page);
1731 + if (res) PRINTK("%s: write_page_oob failed, res=%d\n", __FUNCTION__, res);
1734 + brcmnand_restore_ecc(acc0);
1738 bOffsetStart = this->mtdSize - bbtSize;
1739 bOffsetEnd = this->mtdSize - mtd->erasesize;
1740 printk("%s: gClearBBT=clearbbt, start=%0llx, end=%0llx\n", __FUNCTION__,
1741 bOffsetStart, bOffsetEnd);
1746 case NANDCMD_SHOWBBT:
1747 @@ -1634,7 +2100,12 @@ PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n",
1749 /* How many pages should we scan */
1750 if (this->badblock_pattern->options & NAND_BBT_SCAN2NDPAGE) {
1752 + if (this->options & NAND_SCAN_BI_3RD_PAGE) {
1761 @@ -1865,6 +2336,18 @@ PRINTK("%s: gClearBBT = %d\n", __FUNCTION__, gClearBBT);
1762 (void) brcmnand_postprocessKernelArg(mtd);
1765 + /* TESTING 1 2 3: Once we fixed the bug, there is no longer need for this */
1766 + if (outofspace_bbt) {
1770 + brcmnand_reconstruct_bbt(mtd, outofspace_bbt);
1771 + outofspace_bbt = 0;
1780 diff --git a/drivers/mtd/brcmnand/brcmnand_priv.h b/drivers/mtd/brcmnand/brcmnand_priv.h
1781 index cc0f009..90ece32 100755
1782 --- a/drivers/mtd/brcmnand/brcmnand_priv.h
1783 +++ b/drivers/mtd/brcmnand/brcmnand_priv.h
1784 @@ -313,11 +313,20 @@ extern void* get_brcmnand_handle(void);
1785 extern void print_oobbuf(const unsigned char* buf, int len);
1786 extern void print_databuf(const unsigned char* buf, int len);
1788 -#if CONFIG_MTD_BRCMNAND_CORRECTABLE_ERR_HANDLING
1789 +#ifdef CONFIG_MTD_BRCMNAND_CORRECTABLE_ERR_HANDLING
1790 extern int brcmnand_cet_update(struct mtd_info *mtd, loff_t from, int *status);
1791 extern int brcmnand_cet_prepare_reboot(struct mtd_info *mtd);
1792 extern int brcmnand_cet_erasecallback(struct mtd_info *mtd, u_int32_t addr);
1793 extern int brcmnand_create_cet(struct mtd_info *mtd);
1797 + * Disable ECC, and return the original ACC register (for restore)
1799 +uint32_t brcmnand_disable_ecc(void);
1801 +void brcmnand_restore_ecc(uint32_t orig_acc0);
1803 +void brcmnand_post_mortem_dump(struct mtd_info* mtd, loff_t offset);
1806 diff --git a/drivers/mtd/maps/bcm9xxxx-flash.c b/drivers/mtd/maps/bcm9xxxx-flash.c
1807 index ef050d2..adf8854 100644
1808 --- a/drivers/mtd/maps/bcm9xxxx-flash.c
1809 +++ b/drivers/mtd/maps/bcm9xxxx-flash.c
1810 @@ -176,7 +176,7 @@ struct map_info bcm9XXXX_map
1811 #define AVAIL1_PART (-1)
1813 // DEFAULT_SIZE_MB will be defined later based on platforms.
1814 -#define DEFAULT_ROOTFS_SIZE (DEFAULT_SIZE_MB - DEFAULT_RESERVED_SIZE - DEFAULT_ECM_SIZE)
1815 +#define DEFAULT_ROOTFS_SIZE (((DEFAULT_SIZE_MB)<<20) - DEFAULT_RESERVED_SIZE - DEFAULT_ECM_SIZE)
1818 static struct mtd_partition bcm9XXXX_parts[] = {
1819 @@ -213,7 +213,7 @@ static struct mtd_partition bcm9XXXX_parts[] = {
1821 /* default for 32MB+ platforms */
1823 -#define DEFAULT_SIZE_MB 32 /* 32MB flash */
1824 +#define DEFAULT_SIZE_MB 64 /* 32MB flash */
1825 #if defined( CONFIG_MTD_ECM_PARTITION)
1826 { name: "rootfs", offset: 0, size: DEFAULT_ROOTFS_SIZE },
1827 { name: "avail1", offset: DEFAULT_ROOTFS_SIZE, size: DEFAULT_AVAIL1_SIZE },
1828 @@ -249,12 +249,27 @@ void (*gInitialize_Nor_Partition)(void) = (void (*)(void)) 0;
1829 EXPORT_SYMBOL(gInitialize_Nor_Partition);
1835 +static void print_partition(void)
1839 + for (i=0; i<gNumParts; i++) {
1840 + PRINTK("i=%d, name=%s, start=%0llx, size=%0llx\n",
1841 + i, bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].offset,
1842 + bcm9XXXX_parts[i].size);
1847 int __init init_bcm9XXXX_map(void)
1849 unsigned int avail1_size = DEFAULT_AVAIL1_SIZE;
1851 struct cfi_private *cfi;
1852 - u_int64_t ACTUAL_FLASH_SIZE = (u_int64_t) WINDOW_SIZE;
1853 + unsigned long ACTUAL_FLASH_SIZE = (unsigned long) WINDOW_SIZE;
1854 unsigned long FLASH_BASE = WINDOW_ADDR;
1856 #ifdef CONFIG_MTD_ECM_PARTITION
1857 @@ -284,6 +299,7 @@ int __init init_bcm9XXXX_map(void)
1859 //bcm9XXXX_map.size = WINDOW_SIZE;
1860 ACTUAL_FLASH_SIZE = 1 << cfi->cfiq->DevSize;
1862 if (ACTUAL_FLASH_SIZE >= (4<<20)) {
1863 FLASH_BASE = 0x20000000 - ACTUAL_FLASH_SIZE;
1865 @@ -292,6 +308,8 @@ int __init init_bcm9XXXX_map(void)
1869 +PRINTK("%s: cfiq->DevSize=%08x, actual_flash_size=%08lx, Base=%08lx\n",
1870 + __FUNCTION__, cfi->cfiq->DevSize, ACTUAL_FLASH_SIZE, FLASH_BASE);
1872 * Now that we know the NOR flash size, map again with correct size and base address.
1874 @@ -316,6 +334,9 @@ int __init init_bcm9XXXX_map(void)
1876 gNumParts = ARRAY_SIZE(bcm9XXXX_parts) - 2; /* Minus the 2 extra place holders */
1878 +PRINTK("Before adjustment, gNumParts=%d, defaultSize=%dMB\n", gNumParts, DEFAULT_SIZE_MB);
1882 #ifdef CONFIG_MTD_BRCMNAND_NOR_ACCESS
1883 /* If NOR flash is only 4MB, remove the NOR partition, leaving only CFE partition */
1884 @@ -329,7 +350,30 @@ int __init init_bcm9XXXX_map(void)
1885 bcm9XXXX_parts[1].size = bcm9XXXX_parts[0].offset; // NOR flash ends where CFE starts.
1886 bcm9XXXX_parts[1].offset = 0;
1888 -#elif defined( CONFIG_MTD_ECM_PARTITION )
1890 + /* NOR as only device */
1891 + #if defined (DEFAULT_SIZE_MB )
1893 + unsigned long defaultSize = DEFAULT_SIZE_MB << 20;
1896 + if (ACTUAL_FLASH_SIZE != defaultSize) {
1897 + // Adjust rootfs partition size, all others remain the same.
1899 + bcm9XXXX_parts[0].offset = 0; // CFE starts at 1FC00000H
1900 + bcm9XXXX_parts[0].size += (int64_t) (ACTUAL_FLASH_SIZE - defaultSize);
1902 + for (i=1; i<gNumParts; i++) {
1903 + // Adjust partition offset, but only for non NULL partitions. Size remains the same.
1904 + if ((bcm9XXXX_parts[0].offset != 0 && bcm9XXXX_parts[0].size != 0))
1906 + bcm9XXXX_parts[i].offset += (int64_t) (ACTUAL_FLASH_SIZE - defaultSize);
1912 + #if defined( CONFIG_MTD_ECM_PARTITION )
1913 if (ACTUAL_FLASH_SIZE < (64<<20)) {
1914 ecm_size = DEFAULT_OCAP_SIZE;
1916 @@ -371,7 +415,7 @@ bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1920 -#elif defined( DEFAULT_SIZE_MB )
1921 + #elif defined( DEFAULT_SIZE_MB )
1922 if (ACTUAL_FLASH_SIZE != (DEFAULT_SIZE_MB << 20)) {
1923 int64_t diffSize = (uint64_t) ACTUAL_FLASH_SIZE - (uint64_t) (DEFAULT_SIZE_MB << 20);
1925 @@ -388,7 +432,8 @@ PRINTK("Part[0] After name=%s, size=%llx, offset=%llx\n", bcm9XXXX_parts[0].name
1926 PRINTK("Part[%d] After: name=%s, size=%llx, offset=%llx\n", i, bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1930 + #endif // ECM_PARTITION ... else
1931 +#endif // NOR+NAND ... else
1935 @@ -436,7 +481,8 @@ bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1940 +PRINTK("After adjustment\n");
1943 #if defined(CONFIG_MTD_BRCMNAND)
1944 #if defined(CONFIG_MTD_BRCMNAND_NOR_ACCESS)
1945 diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
1946 index 0753e22..6ccc89d 100755
1947 --- a/include/linux/mtd/nand.h
1948 +++ b/include/linux/mtd/nand.h
1949 @@ -184,6 +184,10 @@ typedef enum {
1950 /* This option is defined if the board driver allocates its own buffers
1951 (e.g. because it needs them DMA-coherent */
1952 #define NAND_OWN_BUFFERS 0x00040000
1954 +/* For Hynix MLC flashes, the BI are written to last and (last-2) pages. */
1955 +#define NAND_SCAN_BI_3RD_PAGE 0x00100000
1957 /* Options set by nand scan */
1958 /* Nand scan has allocated controller struct */
1959 #define NAND_CONTROLLER_ALLOC 0x80000000
1960 @@ -492,9 +496,11 @@ extern struct nand_manufacturers nand_manuf_ids[];
1961 * that the pattern and the version count are always located in the oob area
1962 * of the first block.
1964 +#define BBT_NULL_PAGE (-1LL)
1965 struct nand_bbt_descr {
1967 - int pages[NAND_MAX_CHIPS];
1969 + int64_t pages[NAND_MAX_CHIPS];
1972 uint8_t version[NAND_MAX_CHIPS];
1973 @@ -534,6 +540,8 @@ struct nand_bbt_descr {
1974 #define NAND_BBT_SAVECONTENT 0x00002000
1975 /* Search good / bad pattern on the first and the second page */
1976 #define NAND_BBT_SCAN2NDPAGE 0x00004000
1977 +/* For Hynix MLC flashes BI are marked on last and (last-2) pages */
1978 +#define NAND_BBT_SCAN3RDPAGE 0x00008000
1980 /* The maximum number of blocks to scan for a bbt */
1981 #define NAND_BBT_SCAN_MAXBLOCKS 4