mtd: spi-nor: Parse SFDP SCCR Map
Parse SCCR 22nd dword and check DTR Octal Mode Enable Volatile bit for Octal DTR enable Signed-off-by: JaimeLiao <jaimeliao.tw@gmail.com> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
This commit is contained in:
		
							parent
							
								
									68ad73b70c
								
							
						
					
					
						commit
						bebdc23750
					
				|  | @ -65,6 +65,10 @@ struct sfdp_parameter_header { | ||||||
| #define SFDP_SECTOR_MAP_ID	0xff81	/* Sector Map Table */ | #define SFDP_SECTOR_MAP_ID	0xff81	/* Sector Map Table */ | ||||||
| #define SFDP_SST_ID		0x01bf	/* Manufacturer specific Table */ | #define SFDP_SST_ID		0x01bf	/* Manufacturer specific Table */ | ||||||
| #define SFDP_PROFILE1_ID	0xff05	/* xSPI Profile 1.0 Table */ | #define SFDP_PROFILE1_ID	0xff05	/* xSPI Profile 1.0 Table */ | ||||||
|  | #define SFDP_SCCR_MAP_ID	0xff87	/* | ||||||
|  | 					 * Status, Control and Configuration | ||||||
|  | 					 * Register Map. | ||||||
|  | 					 */ | ||||||
| 
 | 
 | ||||||
| #define SFDP_SIGNATURE		0x50444653U | #define SFDP_SIGNATURE		0x50444653U | ||||||
| #define SFDP_JESD216_MAJOR	1 | #define SFDP_JESD216_MAJOR	1 | ||||||
|  | @ -174,6 +178,9 @@ struct sfdp_header { | ||||||
| #define PROFILE1_DWORD5_DUMMY_100MHZ		GENMASK(11, 7) | #define PROFILE1_DWORD5_DUMMY_100MHZ		GENMASK(11, 7) | ||||||
| #define PROFILE1_DUMMY_DEFAULT			20 | #define PROFILE1_DUMMY_DEFAULT			20 | ||||||
| 
 | 
 | ||||||
|  | /* Status, Control and Configuration Register Map(SCCR) */ | ||||||
|  | #define SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE      BIT(31) | ||||||
|  | 
 | ||||||
| struct sfdp_bfpt { | struct sfdp_bfpt { | ||||||
| 	u32	dwords[BFPT_DWORD_MAX]; | 	u32	dwords[BFPT_DWORD_MAX]; | ||||||
| }; | }; | ||||||
|  | @ -2456,6 +2463,44 @@ out: | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * spi_nor_parse_sccr() - Parse the Status, Control and Configuration Register | ||||||
|  |  *			  Map. | ||||||
|  |  * @nor:		  pointer to a 'struct spi_nor' | ||||||
|  |  * @sccr_header:	  pointer to the 'struct sfdp_parameter_header' describing | ||||||
|  |  * 			  the SCCR Map table length and version. | ||||||
|  |  * | ||||||
|  |  * Return: 0 on success, -errno otherwise. | ||||||
|  |  */ | ||||||
|  | static int spi_nor_parse_sccr(struct spi_nor *nor, | ||||||
|  | 			      const struct sfdp_parameter_header *sccr_header) | ||||||
|  | { | ||||||
|  | 	u32 *table, addr; | ||||||
|  | 	size_t len; | ||||||
|  | 	int ret, i; | ||||||
|  | 
 | ||||||
|  | 	len = sccr_header->length * sizeof(*table); | ||||||
|  | 	table = kmalloc(len, GFP_KERNEL); | ||||||
|  | 	if (!table) | ||||||
|  | 		return -ENOMEM; | ||||||
|  | 
 | ||||||
|  | 	addr = SFDP_PARAM_HEADER_PTP(sccr_header); | ||||||
|  | 	ret = spi_nor_read_sfdp(nor, addr, len, table); | ||||||
|  | 	if (ret) | ||||||
|  | 		goto out; | ||||||
|  | 
 | ||||||
|  | 	/* Fix endianness of the table DWORDs. */ | ||||||
|  | 	for (i = 0; i < sccr_header->length; i++) | ||||||
|  | 		table[i] = le32_to_cpu(table[i]); | ||||||
|  | 
 | ||||||
|  | 	if (FIELD_GET(SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE, table[22])) | ||||||
|  | 		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE; | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	kfree(table); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. |  * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. | ||||||
|  * @nor:		pointer to a 'struct spi_nor' |  * @nor:		pointer to a 'struct spi_nor' | ||||||
|  | @ -2562,6 +2607,10 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, | ||||||
| 			err = spi_nor_parse_profile1(nor, param_header, params); | 			err = spi_nor_parse_profile1(nor, param_header, params); | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
|  | 		case SFDP_SCCR_MAP_ID: | ||||||
|  | 			err = spi_nor_parse_sccr(nor, param_header); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
| 		default: | 		default: | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  | @ -3620,6 +3669,9 @@ static int spi_nor_octal_dtr_enable(struct spi_nor *nor) | ||||||
| 	      nor->write_proto == SNOR_PROTO_8_8_8_DTR)) | 	      nor->write_proto == SNOR_PROTO_8_8_8_DTR)) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
|  | 	if (!(nor->flags & SNOR_F_IO_MODE_EN_VOLATILE)) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
| 	ret = nor->octal_dtr_enable(nor); | 	ret = nor->octal_dtr_enable(nor); | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		return ret; | 		return ret; | ||||||
|  |  | ||||||
|  | @ -290,6 +290,7 @@ enum spi_nor_option_flags { | ||||||
| 	SNOR_F_USE_CLSR		= BIT(5), | 	SNOR_F_USE_CLSR		= BIT(5), | ||||||
| 	SNOR_F_BROKEN_RESET	= BIT(6), | 	SNOR_F_BROKEN_RESET	= BIT(6), | ||||||
| 	SNOR_F_SOFT_RESET	= BIT(7), | 	SNOR_F_SOFT_RESET	= BIT(7), | ||||||
|  | 	SNOR_F_IO_MODE_EN_VOLATILE = BIT(8), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct spi_nor; | struct spi_nor; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue