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_marusys_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_marusys_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_marusys_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..a43cb1f 100644
185 --- a/drivers/mtd/brcmnand/brcmnand_base.c
186 +++ b/drivers/mtd/brcmnand/brcmnand_base.c
187 @@ -537,7 +537,7 @@ static brcmnand_chip_Id brcmnand_chips[] = {
188 .chipId = HYNIX_HY27UT088G2A,
189 .mafId = FLASHTYPE_HYNIX,
190 .chipIdStr = "HYNIX_HY27UT088G2A",
191 - .options = NAND_USE_FLASH_BBT, /* Use BBT on flash */
192 + .options = NAND_USE_FLASH_BBT|NAND_SCAN_BI_3RD_PAGE, /* BBT on flash + BI on (last-2) page */
193 //| NAND_COMPLEX_OOB_WRITE /* Write data together with OOB for write_oob */
194 .idOptions = BRCMNAND_ID_EXT_BYTES,
196 @@ -550,7 +550,7 @@ static brcmnand_chip_Id brcmnand_chips[] = {
197 .chipId = HYNIX_HY27UAG8T2M,
198 .mafId = FLASHTYPE_HYNIX,
199 .chipIdStr = "HYNIX_HY27UAG8T2M",
200 - .options = NAND_USE_FLASH_BBT, /* Use BBT on flash */
201 + .options = NAND_USE_FLASH_BBT|NAND_SCAN_BI_3RD_PAGE, /* BBT on flash + BI on (last-2) page */
202 //| NAND_COMPLEX_OOB_WRITE /* Write data together with OOB for write_oob */
203 .idOptions = BRCMNAND_ID_EXT_BYTES,
205 @@ -605,13 +605,43 @@ static const unsigned char ffchars[] = {
207 //static unsigned char eccmask[128]; // Will be initialized during probe
209 +//static unsigned char eccmask[128]; // Will be initialized during probe
211 +#define BCHP_NAND_LAST_REG BCHP_NAND_BLK_WR_PROTECT
212 +static uint32_t brcmnand_registerHoles[] = {
220 +#if CONFIG_MTD_BRCMNAND_VERSION > CONFIG_MTD_BRCMNAND_VERS_3_3
221 +#error "Not supported in 2.6.18 kernels"
222 + 0x28c4, 0x28c8, 0x28cc,
223 + 0x2910, 0x2914, 0x2918, 0x291c,
224 + 0x2920, 0x2924, 0x2928, 0x292c,
228 +// Is there a register at the location
229 +static int inRegisterHoles(uint32_t reg)
233 + for (i=0; i < ARRAY_SIZE(brcmnand_registerHoles); i++) {
234 + if (reg == brcmnand_registerHoles[i])
235 + return 1; // In register hole
237 + return 0; // Not in hole
240 static uint32_t brcmnand_ctrl_read(uint32_t nandCtrlReg)
242 volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS
243 + nandCtrlReg - BCHP_NAND_REVISION);
245 - if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
246 + if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_LAST_REG ||
247 (nandCtrlReg & 0x3) != 0) {
248 printk("brcmnand_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
250 @@ -625,7 +655,7 @@ static void brcmnand_ctrl_write(uint32_t nandCtrlReg, uint32_t val)
251 volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS
252 + nandCtrlReg - BCHP_NAND_REVISION);
254 - if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
255 + if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_LAST_REG ||
256 (nandCtrlReg & 0x3) != 0) {
257 printk( "brcmnand_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
259 @@ -689,6 +719,30 @@ if (gdebug > 3) printk("%s: offset=%0llx cs=%d ldw = %08x, udw = %08x\n", __FUN
260 return (ldw); //(ldw ^ 0x1FC00000);
264 + * Disable ECC, and return the original ACC register (for restore)
266 +uint32_t brcmnand_disable_ecc(void)
272 + acc0 = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
273 + acc = acc0 & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
274 + brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
280 +void brcmnand_restore_ecc(uint32_t orig_acc0)
282 + brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, orig_acc0);
288 /* Dont delete, may be useful for debugging */
290 @@ -739,7 +793,7 @@ static void print_config_regs(void)
291 nand_acc_control, nand_config, flash_id, nand_timing1, nand_timing2);
294 -#define NUM_NAND_REGS (1+((BCHP_NAND_BLK_WR_PROTECT-BCHP_NAND_REVISION)/4))
295 +#define NUM_NAND_REGS (1+((BCHP_NAND_LAST_REG-BCHP_NAND_REVISION)/4))
297 static void print_nand_ctrl_regs(void)
299 @@ -1533,7 +1587,7 @@ void dump_nand_regs(struct brcmnand_chip* chip, loff_t offset, uint32_t pa, int
300 uint32_t reg = BCHP_NAND_REVISION+(i*4);
303 - if (reg == 0x281c) { // No NAND register at 0x281c
304 + if (inRegisterHoles(reg)) { // No NAND register at 0x281c
308 @@ -1603,6 +1657,7 @@ static int brcmnand_EDU_write_is_complete(struct mtd_info *mtd, int* outp_needBB
309 if (hif_err != 0) // No timeout
311 uint32_t flashStatus; // = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
315 if (!(hif_err & HIF_INTR2_EDU_DONE))
316 @@ -1612,11 +1667,7 @@ printk("hif_err=%08x\n", hif_err);
317 /******************* BUG BUG BUG *****************
318 * THT 01/06/09: What if EDU returns bus error? We should not mark the block bad then.
320 - //Get status: should we check HIF_INTR2_ERR?
321 - if (hif_err & HIF_INTR2_EDU_ERR)
322 - edu_err = EDU_get_error_status_register();
328 //EDU_volatileWrite(EDU_BASE_ADDRESS + EDU_DONE, 0x00000000);
329 @@ -1624,28 +1675,36 @@ printk("hif_err=%08x\n", hif_err);
330 flashStatus = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
332 /* Just to be dead sure */
333 - if (!(flashStatus & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK)) {
334 - ret = brcmnand_ctrl_write_is_complete(mtd, outp_needBBT);
335 - // No need to check on the EDU side, already done inside ctrl_write_is_complete
337 + while (!(flashStatus & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK) && retries-- > 0) {
338 + // Cant call the ctrl version, we are in ISR context
339 + // ret = brcmnand_ctrl_write_is_complete(mtd, outp_needBBT);
340 + udelay(5000); // Wait for a total of 100 usec
341 //dump_nand_regs(chip, 0, 0, numDumps++);
343 + flashStatus = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
348 + //Get status: should we check HIF_INTR2_ERR?
349 + if (hif_err & HIF_INTR2_EDU_ERR)
350 + edu_err = EDU_get_error_status_register();
354 -// 2nd dump after CTRL_READY is asserted
356 -//dump_nand_regs(chip, 0, 0, numDumps++);
360 - if ((edu_err & EDU_ERR_STATUS_NandWrite) || (flashStatus & 0x01)) {
361 - /* Write did not complete, flash error, will mark block bad */
362 + /* sanity check on last cmd status */
363 + if ((edu_err & EDU_ERR_STATUS_NandWrite) && !(flashStatus & 0x1)) {
364 + int cmd = chip->ctrl_read(BCHP_NAND_CMD_START);
365 + printk(KERN_ERR"%s: false EDU write error status (edu_err: 0x%08X, flashStatus: 0x%08X) for NAND CMD %x \n",
366 + __FUNCTION__, edu_err, flashStatus, cmd);
367 + edu_err = EDU_get_error_status_register();
370 + /* we primarily rely on NAND controller FLASH_STATUS bit 0, since EDU error may not be cleared yet */
371 + if ((edu_err & EDU_ERR_STATUS_NandWrite) && (flashStatus & 0x01)) {
372 + /* // Write is complete, but not successful, flash error, will mark block bad */
374 - printk("EDU_write_is_complete(): error 0x%08X\n", edu_err);
376 + printk(KERN_ERR"%s: flash write error (edu_err: 0x%08X, flashStatus: 0x%08X)\n",
377 + __FUNCTION__, edu_err, flashStatus);
378 + ret = 1; // Write is complete, but not successful
383 @@ -1743,6 +1802,42 @@ printk("%s: AUTO: oob=%p, chip->oob_poi=%p, ooboffs=%d, len=%d, bytes=%d, boffs=
389 +#define DEBUG_UNCERR
391 +static uint32_t uncErrOob[7];
392 +static u_char uncErrData[512];
395 +void brcmnand_post_mortem_dump(struct mtd_info* mtd, loff_t offset)
399 + printk("%s at offset %llx\n", __FUNCTION__, offset);
402 + printk("NAND registers snapshot \n");
403 + for (i=0; i<NUM_NAND_REGS; i++) {
404 + uint32_t reg = BCHP_NAND_REVISION+(i*4);
407 + if (inRegisterHoles(reg)) { // No NAND register at 0x281c
411 + regval = brcmnand_ctrl_read(reg);
413 + if ((i % 4) == 0) {
414 + printk("\n%08x:", reg);
416 + printk(" %08x", regval);
424 * Returns 0 on success
425 * Expect a controller read was done before hand, and that the OOB data are read into NAND registers.
426 @@ -1769,7 +1864,7 @@ static int brcmnand_handle_false_read_ecc_unc_errors(
430 - uint32_t acc, acc0;
435 @@ -1779,19 +1874,17 @@ static int brcmnand_handle_false_read_ecc_unc_errors(
437 #if 1 /* Testing 1 2 3 */
439 - acc = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
440 - acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
441 - brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
442 + acc0 = brcmnand_disable_ecc();
444 chip->ctrl_writeAddr(chip, offset, 0);
445 PLATFORM_IOFLUSH_WAR();
446 - chip->ctrl_write(BCHP_NAND_CMD_START, OP_SPARE_AREA_READ);
447 + chip->ctrl_write(BCHP_NAND_CMD_START, OP_PAGE_READ);
449 // Wait until cache is filled up, disabling ECC checking
450 (void) brcmnand_spare_is_valid(mtd, FL_READING, 1);
453 - brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
454 + brcmnand_restore_ecc(acc0);
457 for (i = 0; i < 4; i++) {
458 @@ -1815,8 +1908,10 @@ print_oobbuf(p8, 16);
460 printk("p8[%d]=%02x\n", i, p8[i]);
468 {printk("%s: offset=%0llx, i=%d from %d to %d, eccOobSize=%d, eccbytes=%d, erased=%d, allFF=%d\n",
469 __FUNCTION__, offset, i, chip->eccOobSize-chip->eccbytes, chip->eccOobSize,
470 @@ -1847,6 +1942,25 @@ chip->eccOobSize, chip->eccbytes, erased, allFF);}
471 /* Real error: Disturb read returns uncorrectable errors */
473 if (gdebug > 3 ) {printk("<-- %s: ret -EBADMSG\n", __FUNCTION__);}
477 + // Copy the data buffer
478 + brcmnand_from_flash_memcpy32(chip, uncErrData, offset, mtd->eccsize);
479 + for (i = 0; i < 4; i++) {
480 + uncErrOob[i] = p32[i];
483 + printk("%s: Uncorrectable error at offset %llx\n", __FUNCTION__, offset);
486 + print_databuf(uncErrData, mtd->eccsize);
487 + printk("Spare Area\n");
488 + print_oobbuf((u_char*) uncErrOob, 16);
490 + brcmnand_post_mortem_dump(mtd, offset);
496 @@ -2027,16 +2141,14 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
497 struct brcmnand_chip* chip = mtd->priv;
498 static uint32_t ucdata[128];
499 u_char* uncorr_data = (u_char*) ucdata;
500 - uint32_t acc, acc0;
503 unsigned long irqflags;
505 int ret = 0, retries=2;
508 - acc = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
509 - acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
510 - brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
511 + acc0 = brcmnand_disable_ecc();
513 while (retries >= 0) {
514 // Resubmit the read-op
515 @@ -2070,7 +2182,7 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
523 // Reread the uncorrected buffer.
524 @@ -2098,8 +2210,10 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
525 offset, inp_hwECC[0], inp_hwECC[1], inp_hwECC[2],
526 inoutp_swECC[0], inoutp_swECC[1], inoutp_swECC[2]);
531 - brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
532 + brcmnand_restore_ecc(acc0);
536 @@ -2432,15 +2546,22 @@ brcmnand_edu_read_comp_intr(struct mtd_info* mtd,
538 static uint32_t oob0[4]; // Sparea Area to handle ECC workaround, aligned on DW boundary
539 uint32_t* p32 = (oobarea ? (uint32_t*) oobarea : (uint32_t*) &oob0[0]);
542 if (intr_status & HIF_INTR2_EDU_ERR) {
543 printk("%s: Should not call me with EDU ERR\n", __FUNCTION__);
546 intfc_status = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
547 - if (!(intfc_status & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK)) {
548 - printk("%s: Impossible, HIF_INTR2_CTRL_READY already asserted\n", __FUNCTION__);
550 + while (!(intfc_status & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK) && retries > 0) {
552 + udelay(5); // NAND guaranteed to finish read within 90us, this should be plenty of time
553 + intfc_status = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
555 + if (retries <= 0) {
556 + printk("%s: Impossible, HIF_INTR2_CTRL_READY already asserted, intr_status=%08x, offset=%llx\n",
557 + __FUNCTION__, intr_status, offset);
558 + //BUG(); Should assert here, but don't want to crash. HW guy guaranteed that it is set!!!!
561 // Remember last good sector read. Needed for HIF_INTR2 workaround.
562 @@ -3905,6 +4026,7 @@ static int brcmnand_refresh_blk(struct mtd_info *mtd, loff_t from)
563 * EDU ISR Implementation
566 +extern void EDU_issue_command(uint32_t dram_addr, uint32_t ext_addr,uint8 cmd);
569 * Submit the read op, then return immediately, without waiting for completion.
570 @@ -4437,7 +4559,7 @@ static int brcmnand_do_read_ops(struct mtd_info *mtd, loff_t from,
571 buffer_aligned = EDU_buffer_OK(bufpoi, EDU_READ);
573 // (3) Batch mode if writing more than 1 pages.
574 - numPages = min(MAX_JOB_QUEUE_SIZE, readlen>>chip->page_shift);
575 + numPages = min(MAX_JOB_QUEUE_SIZE, (int) (readlen>>chip->page_shift));
577 // Only do Batch mode if all 3 conditions are satisfied.
578 if (!aligned || !buffer_aligned || numPages <= 1) {
579 @@ -4935,22 +5057,26 @@ if (gdebug > 3) printk("-->%s: addr=%0llx\n", __FUNCTION__, addr);
580 * (2) OOB area is included in ECC calculation for BCH, so no need to check it
583 - if (chip->ecclevel != BRCMNAND_ECC_HAMMING) {
589 page = ((uint64_t) addr) >> chip->page_shift;
590 // Must read entire page
591 ret = chip->read_page(mtd, vbuf, oobbuf, page);
593 - printk(KERN_ERR "%s: brcmnand_read_page at %08x failed ret=%d\n",
594 + printk(KERN_ERR "%s: read_page at %08x failed ret=%d\n",
595 __FUNCTION__, (unsigned int) addr, ret);
596 + brcmnand_post_mortem_dump(mtd, addr);
603 + if (chip->ecclevel != BRCMNAND_ECC_HAMMING) {
604 + return ret; // We won't verify the OOB if not Hamming
608 * If there are no Input Buffer, there is nothing to verify.
609 * Reading the page should be enough.
610 @@ -5087,6 +5213,7 @@ printk("-->%s, offset=%0llx\n", __FUNCTION__, offset);}
612 printk(KERN_ERR "%s: brcmnand_posted_write_cache failed at offset=%0llx, ret=%d\n",
613 __FUNCTION__, offset + dataWritten, ret);
617 dataWritten += chip->eccsize;
618 @@ -5142,7 +5269,7 @@ printk("-->%s, page=%0llx\n", __FUNCTION__, page);}
622 - if (unlikely(!EDU_buffer_OK(inp_buf, EDU_WRITE)))
623 + if (unlikely(!EDU_buffer_OK((void*) inp_buf, EDU_WRITE)))
625 if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, trying non-EDU read\n", __FUNCTION__);
626 /* EDU does not work on non-aligned buffers */
627 @@ -5186,6 +5313,9 @@ if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, tryin
628 while (!list_empty(&gJobQ.jobQ)) {
629 spin_unlock_irqrestore(&gJobQ.lock, flags);
630 ret = ISR_wait_for_queue_completion();
634 spin_lock_irqsave(&gJobQ.lock, flags);
636 spin_unlock_irqrestore(&gJobQ.lock, flags);
637 @@ -5267,6 +5397,9 @@ if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, tryin
638 while (!list_empty(&gJobQ.jobQ)) {
639 spin_unlock_irqrestore(&gJobQ.lock, flags);
640 ret = ISR_wait_for_queue_completion();
644 spin_lock_irqsave(&gJobQ.lock, flags);
646 spin_unlock_irqrestore(&gJobQ.lock, flags);
647 @@ -5428,7 +5561,7 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s, offset=%0llx\n", __FUNCTION__, to);
649 * Group several pages for submission for small page NAND
651 - numPages = min(MAX_JOB_QUEUE_SIZE, writelen>>chip->page_shift);
652 + numPages = min(MAX_JOB_QUEUE_SIZE, (int) (writelen>>chip->page_shift));
655 if (buffer_aligned && numPages > 1 && chip->pageSize == chip->eccsize) {
656 @@ -5455,6 +5588,10 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s, offset=%0llx\n", __FUNCTION__, to);
659 ret = brcmnand_isr_write_pages(mtd, buf, chip->oob_poi, realpage, numPages);
667 @@ -5520,8 +5657,8 @@ printk("-->%s, offset=%0llx\n", __FUNCTION__, to);}
669 /* Do not allow writes past end of device */
670 if (unlikely((to + len) > device_size(mtd))) {
671 - DEBUG(MTD_DEBUG_LEVEL0, "%s: ", __FUNCTION__,
672 - "Attempt to write beyond end of device\n");
673 + DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to write beyond end of device\n",
675 printk("Attempt to write beyond end of device\n");
678 @@ -5674,8 +5811,8 @@ printk("-->%s, offset=%0llx, len=%08x\n", __FUNCTION__, to, (int) ops->len);}
680 if (unlikely((to + ops->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 @@ -6137,8 +6274,9 @@ if (gdebug > 3 ) {printk( "%s: Erase past end of device, instr_addr=%016llx, in
691 /* Check if we have a bad block, we do not erase bad blocks */
692 if (brcmnand_block_checkbad(mtd, addr, 0, allowbbt)) {
693 - printk (KERN_ERR "%s: attempt to erase a bad block at addr 0x%08x\n", __FUNCTION__, (unsigned int) addr);
694 + printk (KERN_ERR "%s: attempt to erase a bad block at addr 0x%llx\n", __FUNCTION__, addr);
695 instr->state = MTD_ERASE_FAILED;
697 goto erase_one_block;
700 @@ -6898,11 +7036,11 @@ static int brcmnand_probe(struct mtd_info *mtd, unsigned int chipSelect)
701 if (chip->cellinfo) {
702 unsigned long devIdExt = chip->ctrl_read(BCHP_NAND_FLASH_DEVICE_ID_EXT);
703 unsigned char devId5thByte = (devIdExt & 0xff000000) >> 24;
704 - unsigned int nbrPlanes;
705 - unsigned int planeSizeMB, chipSizeMB, nandConfigChipSize;
706 + unsigned int nbrPlanes = 0;
707 + unsigned int planeSizeMB = 0, chipSizeMB, nandConfigChipSize;
708 unsigned char devId4thdByte = (chip->device_id & 0xff);
709 - unsigned int pageSize, pageSizeBits;
710 - unsigned int blockSize, blockSizeBits;
711 + unsigned int pageSize = 0, pageSizeBits = 0;
712 + unsigned int blockSize = 0, blockSizeBits = 0;
713 //unsigned int oobSize;
716 @@ -7043,7 +7181,7 @@ PRINTK("nandConfigChipSize = %04x\n", nandConfigChipSize);
717 else if ((brcmnand_chips[i].idOptions & BRCMNAND_ID_EXT_BYTES_TYPE2) ==
718 BRCMNAND_ID_EXT_BYTES_TYPE2)
720 - unsigned int oobSize, oobSizePerPage;
721 + unsigned int oobSize, oobSizePerPage = 0;
722 //uint32_t nandconfig, chipSizeShift;
724 /*---------------- 4th ID byte: page size, block size and OOB size ---------------- */
725 @@ -7663,11 +7801,6 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
727 cs = chip->CS[chip->numchips - 1];
728 PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
737 @@ -7678,6 +7811,7 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
738 printk("NAND_CS_NAND_XOR=%08x\n", nand_xor);
740 #ifdef CONFIG_MTD_BRCMNAND_DISABLE_XOR
742 /* Testing 1,2,3: Force XOR disable on CS0, if not done by CFE */
743 if (chip->CS[0] == 0) {
744 printk("Disabling XOR: Before: SEL=%08x, XOR=%08x\n", nand_select, nand_xor);
745 @@ -7699,6 +7833,11 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
746 printk("Disabling XOR on CS#%1d\n", chip->CS[i]);
747 chip->xor_disable[i] = 1;
751 + printk("Enable XOR on CS#%1d\n", chip->CS[i]);
752 + chip->xor_disable[i] = 0;
757 @@ -8021,7 +8160,7 @@ printk("Corrected ECC to Hamming for SLC flashes: ACC_CONTROL = %08lx from %08lx
760 if ( chip->ecclevel >= BRCMNAND_ECC_BCH_4) {
761 - corr_threshold = 2;
762 + corr_threshold = 3; // Changed from 2, since refresh is costly and vulnerable to AC-ON/OFF tests.
765 corr_threshold = 1; // 1 , default for Hamming
766 @@ -8227,6 +8366,13 @@ printk(KERN_INFO "ECC layout=%s\n", "brcmnand_oob_bch8_4k");
767 chip->ecclayout = &brcmnand_oob_bch8_4k;
770 + else if (NAND_IS_MLC(chip) && mtd->oobsize >= 216 &&
771 + chip->ecclevel == BRCMNAND_ECC_BCH_4 && mtd->writesize == 4096)
773 +printk(KERN_INFO "ECC layout=%s\n", "brcmnand_oob_bch4_4k");
774 + chip->ecclayout = &brcmnand_oob_bch4_4k;
778 printk(KERN_WARNING "No oob scheme defined for oobsize %d\n", mtd->oobsize);
780 @@ -8389,8 +8535,8 @@ printk(KERN_INFO "%s, eccsize=%d, writesize=%d, eccsteps=%d, ecclevel=%d, eccbyt
784 -#ifdef CONFIG_MTD_BRCMNAND_DISABLE_XOR
788 printk("-----------------------------------------------------\n");
789 print_nand_ctrl_regs();
790 printk("-----------------------------------------------------\n");
791 @@ -8411,7 +8557,6 @@ gdebug=4;
796 PRINTK("%s 99\n", __FUNCTION__);
799 diff --git a/drivers/mtd/brcmnand/brcmnand_bbt.c b/drivers/mtd/brcmnand/brcmnand_bbt.c
800 index 91e8510..d8924de 100644
801 --- a/drivers/mtd/brcmnand/brcmnand_bbt.c
802 +++ b/drivers/mtd/brcmnand/brcmnand_bbt.c
803 @@ -67,6 +67,7 @@ when who what
807 +#include <linux/kernel.h>
808 #include <linux/slab.h>
809 #include <linux/types.h>
810 #include <linux/mtd/mtd.h>
811 @@ -76,6 +77,7 @@ when who what
812 #include <linux/bitops.h>
813 #include <linux/delay.h>
814 #include <linux/vmalloc.h>
815 +#include <linux/syscalls.h>
817 #include "brcmnand_priv.h"
819 @@ -84,10 +86,50 @@ when who what
821 //#define PRINTK printk
823 +char brcmNandBBTMsg[1024];
824 +// #define BBT_DEBUG
825 +#ifdef BBT_DEBUG // Bypass quiet flag
827 +static int do_printk = 0; // To be turned on when we hit BBT out of space
828 +asmlinkage int bbt_vprintk(const char *fmt, va_list args)
830 + //unsigned long flags;
833 + //static char printk_buf[1024];
834 + //static int log_level_unknown = 1;
836 + extern void uart_puts(const char *);
838 + printed_len = vsprintf(brcmNandBBTMsg, fmt, args);
839 + uart_puts(brcmNandBBTMsg);
841 + return printed_len;
844 +asmlinkage int bbt_printk(const char *fmt, ...)
852 + va_start(args, fmt);
853 + r = bbt_vprintk(fmt, args);
859 +#define PRINTK bbt_printk
860 +//#define printk bbt_printk
864 extern int gClearBBT;
867 -char brcmNandBBTMsg[1024];
870 * rescan: 1. Rescan for bad blocks, and update existing BBT
871 @@ -204,7 +246,7 @@ __FUNCTION__,i, i, td->pattern[i], td->offs+i, p[td->offs + i]);
872 * Read the bad block table starting from page.
875 -static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
876 +static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, uint64_t page, int num,
877 int bits, int offs, int reserved_block_code)
879 int res, i, j, act = 0;
880 @@ -212,7 +254,9 @@ static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int
881 size_t retlen, len, totlen;
883 uint8_t msk = (uint8_t) ((1 << bits) - 1);
886 +int save_do_printk = do_printk;
888 totlen = (num * bits) >> 3;
889 from = ((loff_t)page) << this->page_shift;
891 @@ -222,6 +266,8 @@ static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int
892 this->ctrl_write(BCHP_NAND_ECC_CORR_ADDR, 0);
893 this->ctrl_write(BCHP_NAND_ECC_UNC_ADDR, 0);
899 len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
900 @@ -229,10 +275,14 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
901 res = mtd->read(mtd, from, len, &retlen, buf);
904 - printk (KERN_INFO "brcmnand_bbt: Error reading bad block table\n");
905 + printk (KERN_ERR "%s: Error reading bad block table, retlen=%d\n", __FUNCTION__);
908 - printk (KERN_WARNING "brcmnand_bbt: ECC error while reading bad block table\n");
909 + printk (KERN_ERR "%s: ECC error while reading bad block table\n", __FUNCTION__);
910 +PRINTK ("%s: ECC error while reading bad block table, res=%d\n", __FUNCTION__, res);
912 + /* THT 11/10/09: If read fails, we should ignore the data, so return w/o analyzing it */
917 @@ -245,6 +295,8 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
918 if (reserved_block_code && (tmp == reserved_block_code)) {
919 printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
920 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
921 +PRINTK ( "nand_read_bbt: Reserved block at 0x%08x\n",
922 + ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
923 this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
924 mtd->ecc_stats.bbtblocks++;
926 @@ -253,6 +305,8 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
927 * message to MTD_DEBUG_LEVEL0 */
928 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
929 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
930 +PRINTK ( "nand_read_bbt: Bad block at 0x%08x\n",
931 + ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
932 /* Factory marked bad or worn out ? */
934 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
935 @@ -261,8 +315,11 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
936 mtd->ecc_stats.badblocks++;
940 +do_printk=save_do_printk;
944 + from += (loff_t)len;
948 @@ -283,6 +340,12 @@ static int brcmnand_read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nan
949 struct brcmnand_chip *this = mtd->priv;
953 +int save_do_printk = do_printk;
956 +PRINTK("-->brcmnand_read_abs_bbt td=%c%c%c%c, td->pages[0]=%llx\n",
957 + td->pattern[0], td->pattern[1],td->pattern[2], td->pattern[3], td->pages[0]);
959 PRINTK("-->brcmnand_read_abs_bbt\n");
960 bits = td->options & NAND_BBT_NRBITS_MSK;
961 @@ -293,6 +356,9 @@ PRINTK("-->brcmnand_read_abs_bbt\n");
962 res = brcmnand_read_bbt (mtd, buf, td->pages[i], this->chipSize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
964 PRINTK("<-- brcmnand_read_abs_bbt ret = %d\n", res);
966 +do_printk = save_do_printk;
970 offs += this->chipSize >> (this->bbt_erase_shift + 2);
971 @@ -302,10 +368,16 @@ PRINTK("<-- brcmnand_read_abs_bbt ret = %d\n", res);
972 (uint32_t) (this->mtdSize >> this->bbt_erase_shift), bits, 0, td->reserved_block_code);
974 PRINTK("<-- brcmnand_read_abs_bbt 2 ret = %d\n", res);
976 +do_printk = save_do_printk;
981 PRINTK("<-- brcmnand_read_abs_bbt ret 0\n");
983 +do_printk = save_do_printk;
988 @@ -316,15 +388,23 @@ static int brcmnand_scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t off
991 struct mtd_oob_ops ops;
994 ops.mode = MTD_OOB_RAW;
996 ops.ooblen = mtd->oobsize;
998 + ops.oobbuf = &buf[mtd->writesize];
1002 - return mtd->read_oob(mtd, offs, &ops);
1003 + ret = mtd->read_oob(mtd, offs, &ops);
1005 +PRINTK("%s: Reading BBT Sig @%0llx, OOB=\n", __FUNCTION__, offs);
1007 +if (do_printk || gdebug)
1008 + print_oobbuf(ops.oobbuf, mtd->oobsize);
1014 @@ -377,7 +457,9 @@ PRINTK("read primary version\n");
1015 brcmnand_scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
1017 td->version[0] = buf[mtd->writesize + td->veroffs];
1018 - printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
1019 + printk(KERN_DEBUG "Bad block table at page %llx, version 0x%02X\n",
1020 + td->pages[0], td->version[0]);
1021 +PRINTK( "Bad block table at page %llx, version 0x%02X\n",
1022 td->pages[0], td->version[0]);
1025 @@ -387,8 +469,10 @@ PRINTK("read mirror version\n");
1026 brcmnand_scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
1028 md->version[0] = buf[mtd->writesize + md->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 md->pages[0], md->version[0]);
1032 +PRINTK( "Bad block table at page %llx, version 0x%02X\n",
1033 + td->pages[0], td->version[0]);
1035 PRINTK("<-- %s\n", __FUNCTION__);
1037 @@ -434,7 +518,7 @@ static int brcmnand_scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr
1038 int pagesPerBlock = mtd->erasesize/mtd->writesize;
1041 - offs += (pagesPerBlock -1 ) * mtd->writesize;
1042 + offs += (loff_t)((pagesPerBlock -1 ) * mtd->writesize);
1044 ops.len = mtd->oobsize;
1045 ops.ooblen = mtd->oobsize;
1046 @@ -444,19 +528,26 @@ static int brcmnand_scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr
1047 ops.mode = MTD_OOB_PLACE;
1049 for (j=0; j < len; j++) {
1051 - * Read the full oob until read_oob is fixed to
1052 - * handle single byte reads for 16 bit
1055 ret = mtd->read_oob(mtd, offs, &ops);
1056 + if (ret == -EBADMSG) {// Uncorrectable errors
1060 + acc0 = brcmnand_disable_ecc();
1062 + // Re-read the OOB
1063 + ret = mtd->read_oob(mtd, offs, &ops);
1065 + // Enable ECC back
1066 + brcmnand_restore_ecc(acc0);
1071 if (check_short_pattern(buf, bd))
1074 - offs += (dir * mtd->writesize);
1075 + offs += (loff_t)(dir * mtd->writesize);
1079 @@ -489,8 +580,14 @@ PRINTK("-->brcmnand_create_bbt, bbt_erase_shift=%d, this->page_shift=%d\n", this
1080 if (bd->options & NAND_BBT_SCANALLPAGES)
1081 len = 1 << (this->bbt_erase_shift - this->page_shift);
1082 else { // Also for MLC
1083 - if (bd->options & NAND_BBT_SCAN2NDPAGE)
1085 + if (bd->options & NAND_BBT_SCAN2NDPAGE) {
1086 + if (this->options & NAND_SCAN_BI_3RD_PAGE) {
1087 + len = 3; // For Hynix MLC chips
1096 @@ -546,7 +643,7 @@ from, bd->options, mtd64_ll_low(startblock), mtd64_ll_low(numblocks));
1100 - from += (1 << this->bbt_erase_shift);
1101 + from += (loff_t)(1 << this->bbt_erase_shift);
1105 @@ -577,6 +674,7 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1106 int scanlen = mtd->writesize + mtd->oobsize;
1108 int blocktopage = this->bbt_erase_shift - this->page_shift;
1111 /* Search direction top -> down ? */
1112 if (td->options & NAND_BBT_LASTBLOCK) {
1113 @@ -604,15 +702,22 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1114 for (i = 0; i < chips; i++) {
1115 /* Reset version information */
1117 - td->pages[i] = -1;
1118 + td->pages[i] = BBT_NULL_PAGE;
1119 /* Scan the maximum number of blocks */
1120 for (block = 0; block < td->maxblocks; block++) {
1122 - int actblock = startblock + dir * block;
1123 + int64_t actblock = startblock + dir * block;
1124 loff_t offs = (uint64_t) actblock << this->bbt_erase_shift;
1127 /* Read first page */
1128 - brcmnand_scan_read_raw(mtd, buf, offs, mtd->writesize);
1129 + ret = brcmnand_scan_read_raw(mtd, buf, offs, mtd->writesize);
1131 + /* Here if the read routine returns -77 then the BBT data is invalid, ignore it */
1133 + // Ignore BBT if not there.
1136 if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
1137 td->pages[i] = actblock << blocktopage;
1138 if (td->options & NAND_BBT_VERSION) {
1139 @@ -625,10 +730,12 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1141 /* Check, if we found a bbt for each requested chip */
1142 for (i = 0; i < chips; i++) {
1143 - if (td->pages[i] == -1)
1144 - printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
1145 + if (td->pages[i] == BBT_NULL_PAGE)
1146 + printk (KERN_WARNING "Bad block table %c%c%c%c not found for chip %d\n",
1147 + td->pattern[0], td->pattern[1], td->pattern[2], td->pattern[3], i);
1150 - printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
1151 + printk(KERN_DEBUG "Bad block table found at page %llx, version 0x%02X\n", td->pages[i],
1155 @@ -674,6 +781,8 @@ static int brcmnand_search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
1159 +// 0 == OK, 1 = outofspace for BBT0, 2=outofspace for BBT1
1160 +static int outofspace_bbt = 0;
1161 static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1162 struct nand_bbt_descr *td, struct nand_bbt_descr *md,
1164 @@ -682,7 +791,7 @@ static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1165 struct erase_info einfo;
1166 int i, j, res, chip = 0, skip, dir;
1167 uint32_t bits, offs, sft, sftmsk, bbtoffs;
1168 - uint64_t startblock, numblocks, page, i64;
1169 + int64_t startblock, numblocks, page, i64;
1170 int nrchips, pageoffs, ooboffs;
1172 uint8_t rcode = td->reserved_block_code;
1173 @@ -690,6 +799,7 @@ static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1175 struct mtd_oob_ops ops;
1177 +bbt_outofspace_retry:
1179 DEBUG(MTD_DEBUG_LEVEL3, "-->%s\n", __FUNCTION__);
1180 ops.ooblen = mtd->oobsize;
1181 @@ -714,7 +824,8 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s\n", __FUNCTION__);
1185 -PRINTK("numblocks=%d, nrchips=%d\n", numblocks, nrchips);
1186 +PRINTK("%s Creating %c%c%c%c numblocks=%d, nrchips=%d, td->pages[0]=%llx\n",
1187 +__FUNCTION__, td->pattern[0],td->pattern[1], td->pattern[2], td->pattern[3] , numblocks, nrchips, td->pages[0]);
1189 /* Loop through the chips */
1190 for (; chip < nrchips; chip++) {
1191 @@ -723,7 +834,7 @@ PRINTK("numblocks=%d, nrchips=%d\n", numblocks, nrchips);
1192 * This applies for absolute placement too, as we have the
1193 * page nr. in td->pages.
1195 - if (td->pages[chip] != -1LL) {
1196 + if (td->pages[chip] != BBT_NULL_PAGE) {
1197 page = td->pages[chip];
1198 PRINTK("There is already a version of the table, go ahead and write it\n");
1200 @@ -741,11 +852,12 @@ PRINTK("There is already a version of the table, go ahead and write it\n");
1204 -printk("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n",
1205 +PRINTK("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n",
1206 __FUNCTION__, startblock, dir, td->maxblocks, skip);
1208 for (i = skip; i < td->maxblocks; i++) {
1209 - uint64_t block = startblock + dir * i;
1210 + uint64_t block = startblock + (int64_t) (dir * i);
1211 + // THT One byte contains 4 set of 2-bits, so divide block by 4 to index the BBT byte
1212 uint32_t blockindex = (uint32_t) (block >> 2);
1214 /* Check, if the block is bad */
1215 @@ -753,18 +865,36 @@ printk("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n",
1216 PRINTK("%s: Checking BBT: i=%d, block=%0llx, BBT=%08x\n",
1217 __FUNCTION__, i, block, this->bbt[blockindex]);
1219 - switch ((this->bbt[blockindex] >>
1220 - (2 * (block & 0x03))) & 0x03) {
1221 + // THT: bbt[blockindex] is the byte we are looking for, now get the 2 bits that
1222 + // is the BBT for the block (Shift (0,1,2,3) *2 positions depending on the block modulo 4)
1223 + switch ((this->bbt[blockindex] >> (2 * (block & 0x03)))
1229 page = block << (this->bbt_erase_shift - this->page_shift);
1231 +PRINTK("%s: Checking BBT2: page=%llx, md->pages[chip]=%llx\n",
1232 + __FUNCTION__, page, md->pages[chip]);
1234 /* Check, if the block is used by the mirror table */
1235 if (!md || md->pages[chip] != page)
1238 - printk (KERN_ERR "No space left to write bad block table\n");
1241 + if (!do_printk) { // If we get here then turn on debugging and retry
1245 + uint8_t rcode = td->reserved_block_code;
1246 + goto bbt_outofspace_retry;
1249 + printk (KERN_ERR "No space left to write bad block table %c%c%c%c\n",
1250 + td->pattern[0], td->pattern[1], td->pattern[2], td->pattern[3]);
1251 + brcmnand_post_mortem_dump(mtd, page<<this->page_shift);
1255 @@ -840,6 +970,11 @@ PRINTK("%s: Not NAND_BBT_SAVECONTENT\n", __FUNCTION__);
1257 /* Pattern is located in oob area of first page */
1258 memcpy(&buf[ooboffs + td->offs], td->pattern, td->len);
1260 + // Write the version number (1 byte)
1261 + if (td->options & NAND_BBT_VERSION) {
1262 + buf[ooboffs + td->veroffs]=td->version[0];
1266 /* walk through the memory table */
1267 @@ -955,21 +1090,30 @@ static int brcmnand_check_create (struct mtd_info *mtd, uint8_t *buf, struct nan
1269 /* Per chip or per device ? */
1270 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
1273 + * THT: Reset version to 0 if 0xff
1275 + if ((td->options & NAND_BBT_VERSION) && (td->version[i]==0xff) && td->pages[i] != BBT_NULL_PAGE)
1276 + td->version[i] = 0;
1277 + if ((md->options & NAND_BBT_VERSION) && (md->version[i]==0xff) && md->pages[i] != BBT_NULL_PAGE)
1278 + md->version[i] = 0;
1280 /* Mirrored table available ? */
1282 - if (td->pages[i] == -1 && md->pages[i] == -1) {
1283 + if (td->pages[i] == BBT_NULL_PAGE && md->pages[i] == BBT_NULL_PAGE) {
1288 - if (td->pages[i] == -1) {
1289 + if (td->pages[i] == BBT_NULL_PAGE) {
1291 td->version[i] = md->version[i];
1296 - if (md->pages[i] == -1) {
1297 + if (md->pages[i] == BBT_NULL_PAGE) {
1299 md->version[i] = td->version[i];
1301 @@ -996,7 +1140,7 @@ static int brcmnand_check_create (struct mtd_info *mtd, uint8_t *buf, struct nan
1305 - if (td->pages[i] == -1) {
1306 + if (td->pages[i] == BBT_NULL_PAGE) {
1310 @@ -1015,25 +1159,46 @@ create:
1316 /* read back first ? */
1318 - brcmnand_read_abs_bbt (mtd, buf, rd, chipsel);
1320 + res = brcmnand_read_abs_bbt (mtd, buf, rd, chipsel);
1322 /* If they weren't versioned, read both. */
1324 - brcmnand_read_abs_bbt (mtd, buf, rd2, chipsel);
1327 + int bbtlen = (uint32_t) (this->mtdSize >> (this->bbt_erase_shift + 2));
1328 + /* Clear the in-memory BBT first */
1329 +PRINTK("%s: Discarding previously read BBT %c%c%c%c, res=%d\n",
1330 +__FUNCTION__, rd->pattern[0], rd->pattern[1], rd->pattern[2], rd->pattern[3], res);
1331 + memset(this->bbt, 0, bbtlen);
1333 + res = brcmnand_read_abs_bbt (mtd, buf, rd2, chipsel);
1335 +PRINTK("%s: Read BBT %c%c%c%c returns res=%d, discarding\n",
1336 +__FUNCTION__, rd2->pattern[0], rd2->pattern[1], rd2->pattern[2], rd2->pattern[3], res);
1340 /* Write the bad block table to the device ? */
1341 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1342 res = brcmnand_write_bbt (mtd, buf, td, md, chipsel);
1345 + if (res ==-ENOSPC)
1346 + outofspace_bbt |= 1;
1351 /* Write the mirror bad block table to the device ? */
1352 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
1353 res = brcmnand_write_bbt (mtd, buf, md, td, chipsel);
1356 + if (res ==-ENOSPC)
1357 + outofspace_bbt |= 2;
1363 @@ -1067,7 +1232,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
1364 for (i = 0; i < chips; i++) {
1365 if ((td->options & NAND_BBT_ABSPAGE) ||
1366 !(td->options & NAND_BBT_WRITE)) {
1367 - if (td->pages[i] == -1)
1368 + if (td->pages[i] == BBT_NULL_PAGE)
1370 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
1372 @@ -1231,9 +1396,14 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s offs=%0llx\n", __FUNCTION__, offs);
1376 - td->version[chip]++;
1377 + (td->version[chip])++;
1379 + if (td->version[chip] == 0xff)
1380 + td->version[chip] =1;
1382 - md->version[chip]++;
1383 + (md->version[chip])++;
1384 + if (md->version[chip] == 0xff)
1385 + md->version[chip] =1;
1387 /* Write the bad block table to the device ? */
1388 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1389 @@ -1251,6 +1421,219 @@ out:
1394 + * brcmnand_reconstruct_bbt - [private] recreate bad block table(s)
1395 + * @mtd: MTD device structure
1396 + * @whichbbt: 1 = TD, 2 = MD
1398 + * The function reconstruct the bad block table(s) from the BI indicators.
1400 +int brcmnand_reconstruct_bbt (struct mtd_info *mtd, int whichbbt)
1402 + struct brcmnand_chip *this = mtd->priv;
1403 + int len, res = 0, writeops = 0;
1404 + int chip, chipsel;
1405 + uint8_t *buf = NULL;
1406 + struct nand_bbt_descr *td = this->bbt_td;
1407 + struct nand_bbt_descr *md = this->bbt_md;
1410 + uint64_t bOffset, startBlock, badBlock = 0;
1413 +PRINTK( "-->%s whichBBT=%x\n", __FUNCTION__, whichbbt);
1415 + if (!this->bbt || !td)
1419 + len = (uint32_t) (this->mtdSize >> (this->bbt_erase_shift + 2));
1420 + /* Allocate a temporary buffer for one eraseblock incl. oob */
1421 + len = (1 << this->bbt_erase_shift);
1422 + len += (len >> this->page_shift) * mtd->oobsize;
1423 + buf = vmalloc (len);
1425 + printk (KERN_ERR "brcmnand_update_bbt: Out of memory\n");
1430 + * Wipe out the BBT entries for the BBT space, and reconstruct it,
1431 + * but do not modify the other entries outside the BBT
1433 + if (this->mtdSize <= (512<<20)) {
1440 + /* Here we unset the entries in the BBT for the BBT region */
1441 + startBlock = this->mtdSize - bbtSize;
1442 + for (bOffset = startBlock; bOffset < this->mtdSize; bOffset += mtd->erasesize) {
1443 + // Calculate index into BBT and wipe it out.
1444 + uint32_t byteIndex = (uint32_t) bOffset >> 2;
1445 + uint8_t byte = this->bbt[byteIndex];
1446 + uint8_t byte0 = byte;
1448 + /* Clear the 2 bits for this block, then assign it back */
1449 + byte &= ~(0x03 << (2 * (bOffset & 0x03)));
1451 + /* If the contents changed, mark it */
1452 + if (byte != byte0) {
1454 + badBlock = bOffset;
1459 + /* Now erase the BBT region, adding to bad block if erase fail */
1462 + int64_t goodBlock = BBT_NULL_PAGE;
1464 + switch (writeops & 0x03) {
1465 + case 0x1: goodBlock = md->pages[0] >> this->page_shift; break;
1466 + case 0x2: goodBlock = td->pages[0] >> this->page_shift; break;
1467 + case 0x3: goodBlock = BBT_NULL_PAGE; break;
1468 + case 0: /* Impossible */ goodBlock = BBT_NULL_PAGE; break;
1472 + static char buf[512+58]; // 31 for alignment, +27 for OOB size
1476 + all0 = (uint8_t*) ((((unsigned int) &buf[0]) + 31) & (~31));
1477 + oob0 = &all0[512];
1479 + memset(all0, 0, 512);
1480 + memset(oob0, 0, 27);
1482 + for (bOffset = startBlock; bOffset < this->mtdSize; bOffset += mtd->erasesize) {
1486 + /* Skip over the good BBT */
1488 + if (bOffset == goodBlock)
1491 + PRINTK("Erasing block at %0llx\n", bOffset);
1492 + this->ctrl_writeAddr(this, bOffset, 0);
1494 + this->ctrl_write(BCHP_NAND_CMD_START, OP_BLOCK_ERASE);
1495 + // Wait until flash is ready
1496 + (void) this->write_is_complete(mtd, &needBBT);
1498 + printk(KERN_WARNING "%s: Erase failure, marking bad block @%016llx\n", __FUNCTION__, bOffset);
1500 + badBlock = bOffset;
1501 + (void) this->block_markbad(mtd, bOffset);
1504 + /* TBD: We should follow this with an ECC-disable write with all-0, ECC-enable then a re-erase
1505 + * But that is too dangerous for AC-on-off tests, especially for the BBT area
1510 + acc = bbt_ctrl_read(BCHP_NAND_ACC_CONTROL);
1511 + acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
1512 + bbt_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
1514 + chip->ctrl_writeAddr(chip, offset, 0);
1515 + PLATFORM_IOFLUSH_WAR();
1516 + chip->ctrl_write(BCHP_NAND_CMD_START, OP_PAGE_PROGRAM);
1518 + // Wait until cache is filled up, disabling ECC checking
1519 + (void) brcmnand_spare_is_valid(mtd, FL_READING, 1);
1522 + bbt_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
1529 + writeops = whichbbt;
1530 + if (modified) writeops = 3; // Do both
1532 +#if 0 // THT: TBD when we have per chip BBT
1533 + /* Do we have a bbt per chip ? */
1534 + if (td->options & NAND_BBT_PERCHIP) {
1535 + chip = (int) (offs >> this->chip_shift);
1543 + /* Warning this codes only support 1 NAND chip */
1545 + if (((writeops & 3) == 3) && (td->options & NAND_BBT_WRITE)) {
1548 +PRINTK("%s: Reconstructing both BBTs\n", __FUNCTION__);
1550 + td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1551 + res = brcmnand_write_bbt (mtd, buf, td, md, 0);
1553 + res2 = brcmnand_write_bbt (mtd, buf, md, td, 0);
1555 + if (!res && res2) /* At least one table write succeed. */
1562 + /* Write the bad block table to the device */
1564 + if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1565 +PRINTK("%s: Recreating Bbt0\n", __FUNCTION__);
1567 + td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1569 + // Look for the location of 1BBT
1570 + res = brcmnand_search_bbt(mtd, buf, md);
1572 + if (res) { // Mirror not found
1573 + PRINTK("%s: Re-creating Bbt0, but 1bBT is also bad, rescan for both\n", __FUNCTION__);
1578 +PRINTK("%s: Reconstructing both BBT0 from BBT1 at %08x\n", __FUNCTION__, md->pages[0]);
1579 + res = brcmnand_write_bbt (mtd, buf, td, md, 0);
1583 + /* Write the mirror bad block table to the device ? */
1584 + if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
1585 +PRINTK("%s: Recreating 1bBT\n", __FUNCTION__);
1587 + td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1589 + // Look for the location of Bbt0:
1590 + res = brcmnand_search_bbt(mtd, buf, td);
1592 + if (res) { // Mirror not found
1593 + PRINTK("%s: Re-creating Bbt0, but 1bBT is also bad, rescan for both\n", __FUNCTION__);
1597 +PRINTK("%s: Reconstructing both BBT1 from BBT0 at %08x\n", __FUNCTION__, td->pages[0]);
1598 + res = brcmnand_write_bbt (mtd, buf, md, td, 0);
1606 /* Define some generic bad / good block scan pattern which are used
1607 * while scanning a device for factory marked good / bad blocks. */
1608 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
1609 @@ -1388,11 +1771,17 @@ static int brcmnand_displayBBT(struct mtd_info* mtd)
1610 //unsigned char oobbuf[64];
1611 //struct nand_oobinfo oobsel;
1614 + int dbg=do_printk;
1616 // Size of BBT is 1MB if total flash is less than 512MB, 4MB otherwise
1617 int bbtSize = this->mtdSize > (512<<20) ? 4 << 20 : 1 << 20;
1620 - bOffsetEnd = this->mtdSize - bbtSize; // Skip BBT itself
1621 + bOffsetEnd = (loff_t)(this->mtdSize - bbtSize); // Skip BBT itself
1626 printk(KERN_INFO "----- Contents of BBT -----\n");
1627 for (bOffset=bOffsetStart; bOffset < bOffsetEnd; bOffset = bOffset + mtd->erasesize) {
1628 @@ -1402,12 +1791,50 @@ static int brcmnand_displayBBT(struct mtd_info* mtd)
1631 printk(KERN_INFO "----- END Contents of BBT -----\n");
1640 // Remove this block in production builds.
1643 +//#define TEST_CLEAR_BBT1
1644 +//#define TEST_INVALIDATE_BBT0
1646 +#ifdef TEST_INVALIDATE_BBT0
1647 +static uint32_t bbt_ctrl_read(uint32_t nandCtrlReg)
1649 + volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS
1650 + + nandCtrlReg - BCHP_NAND_REVISION);
1652 + if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
1653 + (nandCtrlReg & 0x3) != 0) {
1654 + printk("bbt_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
1656 +if (gdebug > 3) printk("%s: CMDREG=%08x val=%08x\n", __FUNCTION__, (unsigned int) nandCtrlReg, (unsigned int)*pReg);
1657 + return (uint32_t) (*pReg);
1661 +static void bbt_ctrl_write(uint32_t nandCtrlReg, uint32_t val)
1663 + volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS
1664 + + nandCtrlReg - BCHP_NAND_REVISION);
1666 + if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
1667 + (nandCtrlReg & 0x3) != 0) {
1668 + printk( "bbt_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
1670 + *pReg = (volatile unsigned long) (val);
1671 +if (gdebug > 3) printk("%s: CMDREG=%08x val=%08x\n", __FUNCTION__, nandCtrlReg, val);
1677 * Process brcmnand= kernel command arg, BEFORE building/reading BBT table.
1678 * Currently, the only accepted command is CLEARBBT, which in itself is a dangerous activity.
1679 @@ -1424,6 +1851,7 @@ static void brcmnand_preprocessKernelArg(struct mtd_info *mtd)
1684 PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n", __FUNCTION__, gClearBBT, device_size(mtd), mtd->erasesize);
1687 @@ -1431,10 +1859,48 @@ PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n", __FUNCTION__, gClearB
1689 case NANDCMD_CLEARBBT: // Force rescan of BBT (DANGEROUS, may lose Mfg's BIs).
1691 +#ifdef TEST_CLEAR_BBT1
1692 + bOffsetStart = 0x7ff00000;
1693 + bOffsetEnd = 0x7ff00000;
1694 +printk("%s: gClearBBT=clearbbt, start=%0llx, end=%0llx\n", __FUNCTION__,
1695 + bOffsetStart, bOffsetEnd);
1696 +#elif defined(TEST_INVALIDATE_BBT0)
1699 +uint8_t* oob = (uint8_t*) &oob0[0];
1701 +uint64_t bbt0Page = ((uint64_t) 0x7ff80000) >> this->page_shift;
1704 + bOffsetStart = 0x7ff80000; // FOrce it to skip erase
1705 + bOffsetEnd = 0x7ff00000;
1706 + res = this->read_page_oob(mtd, oob, bbt0Page);
1709 +memset(&oob[9], 0, 4); // * Overwrite the ECC to force EBADMSG
1710 +//bOffsetStart = 0x7ff80000;
1711 +//bOffsetEnd = 0x7ff80000;
1714 + acc0 = brcmnand_disable_ecc();
1716 +PRINTK("Invalidate ECC at page %llx\n", bbt0Page);
1718 + res = this->write_page_oob(mtd, oob, bbt0Page);
1720 + if (res) PRINTK("%s: write_page_oob failed, res=%d\n", __FUNCTION__, res);
1723 + brcmnand_restore_ecc(acc0);
1727 bOffsetStart = this->mtdSize - bbtSize;
1728 bOffsetEnd = this->mtdSize - mtd->erasesize;
1729 printk("%s: gClearBBT=clearbbt, start=%0llx, end=%0llx\n", __FUNCTION__,
1730 bOffsetStart, bOffsetEnd);
1735 case NANDCMD_SHOWBBT:
1736 @@ -1634,7 +2100,12 @@ PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n",
1738 /* How many pages should we scan */
1739 if (this->badblock_pattern->options & NAND_BBT_SCAN2NDPAGE) {
1741 + if (this->options & NAND_SCAN_BI_3RD_PAGE) {
1750 @@ -1865,6 +2336,18 @@ PRINTK("%s: gClearBBT = %d\n", __FUNCTION__, gClearBBT);
1751 (void) brcmnand_postprocessKernelArg(mtd);
1754 + /* TESTING 1 2 3: Once we fixed the bug, there is no longer need for this */
1755 + if (outofspace_bbt) {
1759 + brcmnand_reconstruct_bbt(mtd, outofspace_bbt);
1760 + outofspace_bbt = 0;
1769 diff --git a/drivers/mtd/brcmnand/brcmnand_priv.h b/drivers/mtd/brcmnand/brcmnand_priv.h
1770 index cc0f009..90ece32 100755
1771 --- a/drivers/mtd/brcmnand/brcmnand_priv.h
1772 +++ b/drivers/mtd/brcmnand/brcmnand_priv.h
1773 @@ -313,11 +313,20 @@ extern void* get_brcmnand_handle(void);
1774 extern void print_oobbuf(const unsigned char* buf, int len);
1775 extern void print_databuf(const unsigned char* buf, int len);
1777 -#if CONFIG_MTD_BRCMNAND_CORRECTABLE_ERR_HANDLING
1778 +#ifdef CONFIG_MTD_BRCMNAND_CORRECTABLE_ERR_HANDLING
1779 extern int brcmnand_cet_update(struct mtd_info *mtd, loff_t from, int *status);
1780 extern int brcmnand_cet_prepare_reboot(struct mtd_info *mtd);
1781 extern int brcmnand_cet_erasecallback(struct mtd_info *mtd, u_int32_t addr);
1782 extern int brcmnand_create_cet(struct mtd_info *mtd);
1786 + * Disable ECC, and return the original ACC register (for restore)
1788 +uint32_t brcmnand_disable_ecc(void);
1790 +void brcmnand_restore_ecc(uint32_t orig_acc0);
1792 +void brcmnand_post_mortem_dump(struct mtd_info* mtd, loff_t offset);
1795 diff --git a/drivers/mtd/maps/bcm9xxxx-flash.c b/drivers/mtd/maps/bcm9xxxx-flash.c
1796 index ef050d2..adf8854 100644
1797 --- a/drivers/mtd/maps/bcm9xxxx-flash.c
1798 +++ b/drivers/mtd/maps/bcm9xxxx-flash.c
1799 @@ -176,7 +176,7 @@ struct map_info bcm9XXXX_map
1800 #define AVAIL1_PART (-1)
1802 // DEFAULT_SIZE_MB will be defined later based on platforms.
1803 -#define DEFAULT_ROOTFS_SIZE (DEFAULT_SIZE_MB - DEFAULT_RESERVED_SIZE - DEFAULT_ECM_SIZE)
1804 +#define DEFAULT_ROOTFS_SIZE (((DEFAULT_SIZE_MB)<<20) - DEFAULT_RESERVED_SIZE - DEFAULT_ECM_SIZE)
1807 static struct mtd_partition bcm9XXXX_parts[] = {
1808 @@ -213,7 +213,7 @@ static struct mtd_partition bcm9XXXX_parts[] = {
1810 /* default for 32MB+ platforms */
1812 -#define DEFAULT_SIZE_MB 32 /* 32MB flash */
1813 +#define DEFAULT_SIZE_MB 64 /* 32MB flash */
1814 #if defined( CONFIG_MTD_ECM_PARTITION)
1815 { name: "rootfs", offset: 0, size: DEFAULT_ROOTFS_SIZE },
1816 { name: "avail1", offset: DEFAULT_ROOTFS_SIZE, size: DEFAULT_AVAIL1_SIZE },
1817 @@ -249,12 +249,27 @@ void (*gInitialize_Nor_Partition)(void) = (void (*)(void)) 0;
1818 EXPORT_SYMBOL(gInitialize_Nor_Partition);
1824 +static void print_partition(void)
1828 + for (i=0; i<gNumParts; i++) {
1829 + PRINTK("i=%d, name=%s, start=%0llx, size=%0llx\n",
1830 + i, bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].offset,
1831 + bcm9XXXX_parts[i].size);
1836 int __init init_bcm9XXXX_map(void)
1838 unsigned int avail1_size = DEFAULT_AVAIL1_SIZE;
1840 struct cfi_private *cfi;
1841 - u_int64_t ACTUAL_FLASH_SIZE = (u_int64_t) WINDOW_SIZE;
1842 + unsigned long ACTUAL_FLASH_SIZE = (unsigned long) WINDOW_SIZE;
1843 unsigned long FLASH_BASE = WINDOW_ADDR;
1845 #ifdef CONFIG_MTD_ECM_PARTITION
1846 @@ -284,6 +299,7 @@ int __init init_bcm9XXXX_map(void)
1848 //bcm9XXXX_map.size = WINDOW_SIZE;
1849 ACTUAL_FLASH_SIZE = 1 << cfi->cfiq->DevSize;
1851 if (ACTUAL_FLASH_SIZE >= (4<<20)) {
1852 FLASH_BASE = 0x20000000 - ACTUAL_FLASH_SIZE;
1854 @@ -292,6 +308,8 @@ int __init init_bcm9XXXX_map(void)
1858 +PRINTK("%s: cfiq->DevSize=%08x, actual_flash_size=%08lx, Base=%08lx\n",
1859 + __FUNCTION__, cfi->cfiq->DevSize, ACTUAL_FLASH_SIZE, FLASH_BASE);
1861 * Now that we know the NOR flash size, map again with correct size and base address.
1863 @@ -316,6 +334,9 @@ int __init init_bcm9XXXX_map(void)
1865 gNumParts = ARRAY_SIZE(bcm9XXXX_parts) - 2; /* Minus the 2 extra place holders */
1867 +PRINTK("Before adjustment, gNumParts=%d, defaultSize=%dMB\n", gNumParts, DEFAULT_SIZE_MB);
1871 #ifdef CONFIG_MTD_BRCMNAND_NOR_ACCESS
1872 /* If NOR flash is only 4MB, remove the NOR partition, leaving only CFE partition */
1873 @@ -329,7 +350,30 @@ int __init init_bcm9XXXX_map(void)
1874 bcm9XXXX_parts[1].size = bcm9XXXX_parts[0].offset; // NOR flash ends where CFE starts.
1875 bcm9XXXX_parts[1].offset = 0;
1877 -#elif defined( CONFIG_MTD_ECM_PARTITION )
1879 + /* NOR as only device */
1880 + #if defined (DEFAULT_SIZE_MB )
1882 + unsigned long defaultSize = DEFAULT_SIZE_MB << 20;
1885 + if (ACTUAL_FLASH_SIZE != defaultSize) {
1886 + // Adjust rootfs partition size, all others remain the same.
1888 + bcm9XXXX_parts[0].offset = 0; // CFE starts at 1FC00000H
1889 + bcm9XXXX_parts[0].size += (int64_t) (ACTUAL_FLASH_SIZE - defaultSize);
1891 + for (i=1; i<gNumParts; i++) {
1892 + // Adjust partition offset, but only for non NULL partitions. Size remains the same.
1893 + if ((bcm9XXXX_parts[0].offset != 0 && bcm9XXXX_parts[0].size != 0))
1895 + bcm9XXXX_parts[i].offset += (int64_t) (ACTUAL_FLASH_SIZE - defaultSize);
1901 + #if defined( CONFIG_MTD_ECM_PARTITION )
1902 if (ACTUAL_FLASH_SIZE < (64<<20)) {
1903 ecm_size = DEFAULT_OCAP_SIZE;
1905 @@ -371,7 +415,7 @@ bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1909 -#elif defined( DEFAULT_SIZE_MB )
1910 + #elif defined( DEFAULT_SIZE_MB )
1911 if (ACTUAL_FLASH_SIZE != (DEFAULT_SIZE_MB << 20)) {
1912 int64_t diffSize = (uint64_t) ACTUAL_FLASH_SIZE - (uint64_t) (DEFAULT_SIZE_MB << 20);
1914 @@ -388,7 +432,8 @@ PRINTK("Part[0] After name=%s, size=%llx, offset=%llx\n", bcm9XXXX_parts[0].name
1915 PRINTK("Part[%d] After: name=%s, size=%llx, offset=%llx\n", i, bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1919 + #endif // ECM_PARTITION ... else
1920 +#endif // NOR+NAND ... else
1924 @@ -436,7 +481,8 @@ bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1929 +PRINTK("After adjustment\n");
1932 #if defined(CONFIG_MTD_BRCMNAND)
1933 #if defined(CONFIG_MTD_BRCMNAND_NOR_ACCESS)
1934 diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
1935 index 0753e22..6ccc89d 100755
1936 --- a/include/linux/mtd/nand.h
1937 +++ b/include/linux/mtd/nand.h
1938 @@ -184,6 +184,10 @@ typedef enum {
1939 /* This option is defined if the board driver allocates its own buffers
1940 (e.g. because it needs them DMA-coherent */
1941 #define NAND_OWN_BUFFERS 0x00040000
1943 +/* For Hynix MLC flashes, the BI are written to last and (last-2) pages. */
1944 +#define NAND_SCAN_BI_3RD_PAGE 0x00100000
1946 /* Options set by nand scan */
1947 /* Nand scan has allocated controller struct */
1948 #define NAND_CONTROLLER_ALLOC 0x80000000
1949 @@ -492,9 +496,11 @@ extern struct nand_manufacturers nand_manuf_ids[];
1950 * that the pattern and the version count are always located in the oob area
1951 * of the first block.
1953 +#define BBT_NULL_PAGE (-1LL)
1954 struct nand_bbt_descr {
1956 - int pages[NAND_MAX_CHIPS];
1958 + int64_t pages[NAND_MAX_CHIPS];
1961 uint8_t version[NAND_MAX_CHIPS];
1962 @@ -534,6 +540,8 @@ struct nand_bbt_descr {
1963 #define NAND_BBT_SAVECONTENT 0x00002000
1964 /* Search good / bad pattern on the first and the second page */
1965 #define NAND_BBT_SCAN2NDPAGE 0x00004000
1966 +/* For Hynix MLC flashes BI are marked on last and (last-2) pages */
1967 +#define NAND_BBT_SCAN3RDPAGE 0x00008000
1969 /* The maximum number of blocks to scan for a bbt */
1970 #define NAND_BBT_SCAN_MAXBLOCKS 4
1971 diff --git a/drivers/mtd/brcmnand/brcmnand_base.c b/drivers/mtd/brcmnand/brcmnand_base.c
1972 index 1b81152..3ec2d3e 100644
1973 --- a/drivers/mtd/brcmnand/brcmnand_base.c
1974 +++ b/drivers/mtd/brcmnand/brcmnand_base.c
1975 @@ -181,8 +181,8 @@ static brcmnand_chip_Id brcmnand_chips[] = {
1976 .options = NAND_USE_FLASH_BBT, /* Use BBT on flash */
1978 //| NAND_COMPLEX_OOB_WRITE /* Write data together with OOB for write_oob */
1979 - .timing1 = 0, //00070000,
1981 + .timing1 = 0x4232222D,
1982 + .timing2 = 0x00000D94,
1984 .ctrlVersion = 0, /* THT Verified on data-sheet 7/10/08: Allows 4 on main and 4 on OOB */