/* * Handle block mark swapping. * * Note that, when this function is called, it doesn't know whether it's * swapping the block mark, or swapping it *back* -- but it doesn't matter * because the the operation is the same. */ static void mxs_nand_swap_block_mark(struct mtd_info *mtd, uint8_t *data_buf, uint8_t *oob_buf) { uint32_t bit_offset; uint32_t buf_offset; uint32_t src; uint32_t dst; bit_offset = mxs_nand_mark_bit_offset(mtd); buf_offset = mxs_nand_mark_byte_offset(mtd); /* * Get the byte from the data area that overlays the block mark. Since * the ECC engine applies its own view to the bits in the page, the * physical block mark won't (in general) appear on a byte boundary in * the data. */ src = data_buf[buf_offset] >> bit_offset; src |= data_buf[buf_offset + 1] << (8 - bit_offset); dst = oob_buf[0]; oob_buf[0] = src; data_buf[buf_offset] &= ~(0xff << bit_offset); data_buf[buf_offset + 1] &= 0xff << bit_offset; data_buf[buf_offset] |= dst << bit_offset; data_buf[buf_offset + 1] |= dst >> (8 - bit_offset); }
static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler, struct fcb_block *fcb, struct mtd_info *mtd) { fcb->FingerPrint = 0x20424346; fcb->Version = 0x01000000; fcb->PageDataSize = mtd->writesize; fcb->TotalPageSize = mtd->writesize + mtd->oobsize; fcb->SectorsPerBlock = mtd->erasesize / mtd->writesize; /* Divide ECC strength by two and save the value into FCB structure. */ fcb->EccBlock0EccType = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1; fcb->EccBlockNEccType = fcb->EccBlock0EccType; fcb->EccBlock0Size = 0x00000200; fcb->EccBlockNSize = 0x00000200; fcb->NumEccBlocksPerPage = mtd->writesize / fcb->EccBlock0Size - 1; /* DBBT search area starts at second page on first block */ fcb->DBBTSearchAreaStartAddress = 1; fcb->BadBlockMarkerByte = mxs_nand_mark_byte_offset(mtd); fcb->BadBlockMarkerStartBit = mxs_nand_mark_bit_offset(mtd); fcb->BBMarkerPhysicalOffset = mtd->writesize; imx_handler->fcb_create(imx_handler, fcb, mtd); fcb->Checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4); return 0; }