mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 05:50:17 +00:00 
			
		
		
		
	mtd: nand: Store nand ID in struct nand_chip
Upstream linux commit 7f501f0a72036d. Store the NAND ID in struct nand_chip to avoid passing id_data and id_len as function parameters. Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
This commit is contained in:
		
							parent
							
								
									1ca6f9483e
								
							
						
					
					
						commit
						bd87603d5a
					
				@ -4160,16 +4160,14 @@ static int nand_get_bits_per_cell(u8 cellinfo)
 | 
				
			|||||||
 * chip. The rest of the parameters must be decoded according to generic or
 | 
					 * chip. The rest of the parameters must be decoded according to generic or
 | 
				
			||||||
 * manufacturer-specific "extended ID" decoding patterns.
 | 
					 * manufacturer-specific "extended ID" decoding patterns.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip)
 | 
				
			||||||
				u8 id_data[8])
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int extid, id_len;
 | 
						int extid, id_len;
 | 
				
			||||||
	/* The 3rd id byte holds MLC / multichip data */
 | 
						/* The 3rd id byte holds MLC / multichip data */
 | 
				
			||||||
	chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
 | 
						chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]);
 | 
				
			||||||
	/* The 4th id byte is the important one */
 | 
						/* The 4th id byte is the important one */
 | 
				
			||||||
	extid = id_data[3];
 | 
						extid = chip->id.data[3];
 | 
				
			||||||
 | 
						id_len = chip->id.len;
 | 
				
			||||||
	id_len = nand_id_len(id_data, 8);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Field definitions are in the following datasheets:
 | 
						 * Field definitions are in the following datasheets:
 | 
				
			||||||
@ -4180,8 +4178,8 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			|||||||
	 * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
 | 
						 * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
 | 
				
			||||||
	 * ID to decide what to do.
 | 
						 * ID to decide what to do.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
 | 
						if (id_len == 6 && chip->id.data[0] == NAND_MFR_SAMSUNG &&
 | 
				
			||||||
			!nand_is_slc(chip) && id_data[5] != 0x00) {
 | 
						    !nand_is_slc(chip) && chip->id.data[5] != 0x00) {
 | 
				
			||||||
		/* Calc pagesize */
 | 
							/* Calc pagesize */
 | 
				
			||||||
		mtd->writesize = 2048 << (extid & 0x03);
 | 
							mtd->writesize = 2048 << (extid & 0x03);
 | 
				
			||||||
		extid >>= 2;
 | 
							extid >>= 2;
 | 
				
			||||||
@ -4214,7 +4212,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			|||||||
		/* Calc blocksize */
 | 
							/* Calc blocksize */
 | 
				
			||||||
		mtd->erasesize = (128 * 1024) <<
 | 
							mtd->erasesize = (128 * 1024) <<
 | 
				
			||||||
			(((extid >> 1) & 0x04) | (extid & 0x03));
 | 
								(((extid >> 1) & 0x04) | (extid & 0x03));
 | 
				
			||||||
	} else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
 | 
						} else if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX &&
 | 
				
			||||||
			!nand_is_slc(chip)) {
 | 
								!nand_is_slc(chip)) {
 | 
				
			||||||
		unsigned int tmp;
 | 
							unsigned int tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -4278,10 +4276,10 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			|||||||
		 *                         110b -> 24nm
 | 
							 *                         110b -> 24nm
 | 
				
			||||||
		 * - ID byte 5, bit[7]:    1 -> BENAND, 0 -> raw SLC
 | 
							 * - ID byte 5, bit[7]:    1 -> BENAND, 0 -> raw SLC
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA &&
 | 
							if (id_len >= 6 && chip->id.data[0] == NAND_MFR_TOSHIBA &&
 | 
				
			||||||
		    nand_is_slc(chip) &&
 | 
							    nand_is_slc(chip) &&
 | 
				
			||||||
				(id_data[5] & 0x7) == 0x6 /* 24nm */ &&
 | 
							    (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
 | 
				
			||||||
				!(id_data[4] & 0x80) /* !BENAND */) {
 | 
							    !(chip->id.data[4] & 0x80) /* !BENAND */) {
 | 
				
			||||||
			mtd->oobsize = 32 * mtd->writesize >> 9;
 | 
								mtd->oobsize = 32 * mtd->writesize >> 9;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -4294,9 +4292,9 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			|||||||
 * the chip.
 | 
					 * the chip.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				struct nand_flash_dev *type, u8 id_data[8])
 | 
									struct nand_flash_dev *type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int maf_id = id_data[0];
 | 
						int maf_id = chip->id.data[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mtd->erasesize = type->erasesize;
 | 
						mtd->erasesize = type->erasesize;
 | 
				
			||||||
	mtd->writesize = type->pagesize;
 | 
						mtd->writesize = type->pagesize;
 | 
				
			||||||
@ -4311,11 +4309,11 @@ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			|||||||
	 * listed in nand_ids table.
 | 
						 * listed in nand_ids table.
 | 
				
			||||||
	 * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
 | 
						 * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && id_data[5] == 0x00
 | 
						if (maf_id == NAND_MFR_AMD && chip->id.data[4] != 0x00 &&
 | 
				
			||||||
			&& id_data[6] == 0x00 && id_data[7] == 0x00
 | 
						    chip->id.data[5] == 0x00 && chip->id.data[6] == 0x00 &&
 | 
				
			||||||
			&& mtd->writesize == 512) {
 | 
						    chip->id.data[7] == 0x00 && mtd->writesize == 512) {
 | 
				
			||||||
		mtd->erasesize = 128 * 1024;
 | 
							mtd->erasesize = 128 * 1024;
 | 
				
			||||||
		mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
 | 
							mtd->erasesize <<= ((chip->id.data[3] & 0x03) << 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -4325,9 +4323,9 @@ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			|||||||
 * page size, cell-type information).
 | 
					 * page size, cell-type information).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void nand_decode_bbm_options(struct mtd_info *mtd,
 | 
					static void nand_decode_bbm_options(struct mtd_info *mtd,
 | 
				
			||||||
				    struct nand_chip *chip, u8 id_data[8])
 | 
									    struct nand_chip *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int maf_id = id_data[0];
 | 
						int maf_id = chip->id.data[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set the bad block position */
 | 
						/* Set the bad block position */
 | 
				
			||||||
	if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16))
 | 
						if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16))
 | 
				
			||||||
@ -4362,14 +4360,14 @@ static inline bool is_full_id_nand(struct nand_flash_dev *type)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
		   struct nand_flash_dev *type, u8 *id_data)
 | 
							   struct nand_flash_dev *type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!strncmp((char *)type->id, (char *)id_data, type->id_len)) {
 | 
						if (!strncmp((char *)type->id, (char *)chip->id.data, type->id_len)) {
 | 
				
			||||||
		mtd->writesize = type->pagesize;
 | 
							mtd->writesize = type->pagesize;
 | 
				
			||||||
		mtd->erasesize = type->erasesize;
 | 
							mtd->erasesize = type->erasesize;
 | 
				
			||||||
		mtd->oobsize = type->oobsize;
 | 
							mtd->oobsize = type->oobsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
 | 
							chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]);
 | 
				
			||||||
		chip->chipsize = (uint64_t)type->chipsize << 20;
 | 
							chip->chipsize = (uint64_t)type->chipsize << 20;
 | 
				
			||||||
		chip->options |= type->options;
 | 
							chip->options |= type->options;
 | 
				
			||||||
		chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
 | 
							chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
 | 
				
			||||||
@ -4395,7 +4393,7 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	int busw, ret;
 | 
						int busw, ret;
 | 
				
			||||||
	int maf_idx;
 | 
						int maf_idx;
 | 
				
			||||||
	u8 id_data[8];
 | 
						u8 *id_data = chip->id.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
 | 
						 * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
 | 
				
			||||||
@ -4453,9 +4451,11 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	chip->options &= ~NAND_BUSWIDTH_16;
 | 
						chip->options &= ~NAND_BUSWIDTH_16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (; type->name != NULL; type++) {
 | 
						for (; type->name != NULL; type++) {
 | 
				
			||||||
		if (is_full_id_nand(type)) {
 | 
							if (is_full_id_nand(type)) {
 | 
				
			||||||
			if (find_full_id_nand(mtd, chip, type, id_data))
 | 
								if (find_full_id_nand(mtd, chip, type))
 | 
				
			||||||
				goto ident_done;
 | 
									goto ident_done;
 | 
				
			||||||
		} else if (*dev_id == type->dev_id) {
 | 
							} else if (*dev_id == type->dev_id) {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@ -4483,9 +4483,9 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (!type->pagesize) {
 | 
						if (!type->pagesize) {
 | 
				
			||||||
		/* Decode parameters from extended ID */
 | 
							/* Decode parameters from extended ID */
 | 
				
			||||||
		nand_decode_ext_id(mtd, chip, id_data);
 | 
							nand_decode_ext_id(mtd, chip);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		nand_decode_id(mtd, chip, type, id_data);
 | 
							nand_decode_id(mtd, chip, type);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Get chip options */
 | 
						/* Get chip options */
 | 
				
			||||||
@ -4523,7 +4523,7 @@ ident_done:
 | 
				
			|||||||
		return ERR_PTR(-EINVAL);
 | 
							return ERR_PTR(-EINVAL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nand_decode_bbm_options(mtd, chip, id_data);
 | 
						nand_decode_bbm_options(mtd, chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Calculate the address shift from the page size */
 | 
						/* Calculate the address shift from the page size */
 | 
				
			||||||
	chip->page_shift = ffs(mtd->writesize) - 1;
 | 
						chip->page_shift = ffs(mtd->writesize) - 1;
 | 
				
			||||||
 | 
				
			|||||||
@ -507,6 +507,19 @@ static inline void nand_hw_control_init(struct nand_hw_control *nfc)
 | 
				
			|||||||
	init_waitqueue_head(&nfc->wq);
 | 
						init_waitqueue_head(&nfc->wq);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The maximum expected count of bytes in the NAND ID sequence */
 | 
				
			||||||
 | 
					#define NAND_MAX_ID_LEN 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * struct nand_id - NAND id structure
 | 
				
			||||||
 | 
					 * @data: buffer containing the id bytes.
 | 
				
			||||||
 | 
					 * @len: ID length.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct nand_id {
 | 
				
			||||||
 | 
						u8 data[NAND_MAX_ID_LEN];
 | 
				
			||||||
 | 
						int len;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * struct nand_ecc_step_info - ECC step information of ECC engine
 | 
					 * struct nand_ecc_step_info - ECC step information of ECC engine
 | 
				
			||||||
 * @stepsize: data bytes per ECC step
 | 
					 * @stepsize: data bytes per ECC step
 | 
				
			||||||
@ -888,6 +901,8 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct nand_chip {
 | 
					struct nand_chip {
 | 
				
			||||||
	struct mtd_info mtd;
 | 
						struct mtd_info mtd;
 | 
				
			||||||
 | 
						struct nand_id id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void __iomem *IO_ADDR_R;
 | 
						void __iomem *IO_ADDR_R;
 | 
				
			||||||
	void __iomem *IO_ADDR_W;
 | 
						void __iomem *IO_ADDR_W;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user