Commit 981a8d60 authored by Tudor Ambarus's avatar Tudor Ambarus Committed by Vignesh Raghavendra
Browse files

mtd: spi-nor: Parse SFDP SCCR Map



Parse just the 22nd dword and look for the 'DTR Octal Mode Enable
Volatile bit'.

SPI_NOR_IO_MODE_EN_VOLATILE should be set just for the flashes
that don't define the optional SFDP SCCR Map. For the others,
let the SFDP do its job and fill the SNOR_F_IO_MODE_EN_VOLATILE
flag. We avoid this way polluting the flash flags when declaring
one.

Signed-off-by: default avatarTudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: default avatarPratyush Yadav <p.yadav@ti.com>
Signed-off-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Link: https://lore.kernel.org/r/20201005153138.6437-10-p.yadav@ti.com
parent c6908077
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@
#define SFDP_SECTOR_MAP_ID	0xff81	/* Sector Map Table */
#define SFDP_4BAIT_ID		0xff84  /* 4-byte Address Instruction 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

@@ -1195,6 +1199,46 @@ static int spi_nor_parse_profile1(struct spi_nor *nor,
	return ret;
}

#define SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE		BIT(31)

/**
 * 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.
 * @params:		pointer to the 'struct spi_nor_flash_parameter' to be.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_parse_sccr(struct spi_nor *nor,
			      const struct sfdp_parameter_header *sccr_header,
			      struct spi_nor_flash_parameter *params)
{
	u32 *dwords, addr;
	size_t len;
	int ret;

	len = sccr_header->length * sizeof(*dwords);
	dwords = kmalloc(len, GFP_KERNEL);
	if (!dwords)
		return -ENOMEM;

	addr = SFDP_PARAM_HEADER_PTP(sccr_header);
	ret = spi_nor_read_sfdp(nor, addr, len, dwords);
	if (ret)
		goto out;

	le32_to_cpu_array(dwords, sccr_header->length);

	if (FIELD_GET(SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE, dwords[22]))
		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;

out:
	kfree(dwords);
	return ret;
}

/**
 * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
 * @nor:		pointer to a 'struct spi_nor'
@@ -1300,6 +1344,10 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
			err = spi_nor_parse_profile1(nor, param_header, params);
			break;

		case SFDP_SCCR_MAP_ID:
			err = spi_nor_parse_sccr(nor, param_header, params);
			break;

		default:
			break;
		}