Esempio n. 1
0
/*
 * 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);
}
Esempio n. 2
0
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;
}