xref: /openbmc/linux/drivers/mtd/nand/raw/sm_common.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
293db446aSBoris Brezillon /*
393db446aSBoris Brezillon  * Copyright © 2009 - Maxim Levitsky
493db446aSBoris Brezillon  * Common routines & support for SmartMedia/xD format
593db446aSBoris Brezillon  */
693db446aSBoris Brezillon #include <linux/bitops.h>
793db446aSBoris Brezillon #include <linux/mtd/mtd.h>
893db446aSBoris Brezillon 
993db446aSBoris Brezillon /* Full oob structure as written on the flash */
1093db446aSBoris Brezillon struct sm_oob {
1193db446aSBoris Brezillon 	uint32_t reserved;
1293db446aSBoris Brezillon 	uint8_t data_status;
1393db446aSBoris Brezillon 	uint8_t block_status;
1493db446aSBoris Brezillon 	uint8_t lba_copy1[2];
1593db446aSBoris Brezillon 	uint8_t ecc2[3];
1693db446aSBoris Brezillon 	uint8_t lba_copy2[2];
1793db446aSBoris Brezillon 	uint8_t ecc1[3];
1893db446aSBoris Brezillon } __packed;
1993db446aSBoris Brezillon 
2093db446aSBoris Brezillon 
2193db446aSBoris Brezillon /* one sector is always 512 bytes, but it can consist of two nand pages */
2293db446aSBoris Brezillon #define SM_SECTOR_SIZE		512
2393db446aSBoris Brezillon 
2493db446aSBoris Brezillon /* oob area is also 16 bytes, but might be from two pages */
2593db446aSBoris Brezillon #define SM_OOB_SIZE		16
2693db446aSBoris Brezillon 
2793db446aSBoris Brezillon /* This is maximum zone size, and all devices that have more that one zone
2893db446aSBoris Brezillon    have this size */
2993db446aSBoris Brezillon #define SM_MAX_ZONE_SIZE 	1024
3093db446aSBoris Brezillon 
3193db446aSBoris Brezillon /* support for small page nand */
3293db446aSBoris Brezillon #define SM_SMALL_PAGE 		256
3393db446aSBoris Brezillon #define SM_SMALL_OOB_SIZE	8
3493db446aSBoris Brezillon 
3593db446aSBoris Brezillon 
3693db446aSBoris Brezillon int sm_register_device(struct mtd_info *mtd, int smartmedia);
3793db446aSBoris Brezillon 
3893db446aSBoris Brezillon 
sm_sector_valid(struct sm_oob * oob)3993db446aSBoris Brezillon static inline int sm_sector_valid(struct sm_oob *oob)
4093db446aSBoris Brezillon {
4193db446aSBoris Brezillon 	return hweight16(oob->data_status) >= 5;
4293db446aSBoris Brezillon }
4393db446aSBoris Brezillon 
sm_block_valid(struct sm_oob * oob)4493db446aSBoris Brezillon static inline int sm_block_valid(struct sm_oob *oob)
4593db446aSBoris Brezillon {
4693db446aSBoris Brezillon 	return hweight16(oob->block_status) >= 7;
4793db446aSBoris Brezillon }
4893db446aSBoris Brezillon 
sm_block_erased(struct sm_oob * oob)4993db446aSBoris Brezillon static inline int sm_block_erased(struct sm_oob *oob)
5093db446aSBoris Brezillon {
5193db446aSBoris Brezillon 	static const uint32_t erased_pattern[4] = {
5293db446aSBoris Brezillon 		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
5393db446aSBoris Brezillon 
5493db446aSBoris Brezillon 	/* First test for erased block */
5593db446aSBoris Brezillon 	if (!memcmp(oob, erased_pattern, sizeof(*oob)))
5693db446aSBoris Brezillon 		return 1;
5793db446aSBoris Brezillon 	return 0;
5893db446aSBoris Brezillon }
59