linux/drivers/mtd/spi-nor/sfdp.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2005, Intec Automation Inc.
 * Copyright (C) 2014, Freescale Semiconductor, Inc.
 */

#include <linux/bitfield.h>
#include <linux/mtd/spi-nor.h>
#include <linux/slab.h>
#include <linux/sort.h>

#include "core.h"

#define SFDP_PARAM_HEADER_ID(p)
#define SFDP_PARAM_HEADER_PTP(p)
#define SFDP_PARAM_HEADER_PARAM_LEN(p)

#define SFDP_BFPT_ID
#define SFDP_SECTOR_MAP_ID
#define SFDP_4BAIT_ID
#define SFDP_PROFILE1_ID
#define SFDP_SCCR_MAP_ID
#define SFDP_SCCR_MAP_MC_ID

#define SFDP_SIGNATURE

struct sfdp_header {};

/* Fast Read settings. */
struct sfdp_bfpt_read {};

struct sfdp_bfpt_erase {};

#define SMPT_CMD_ADDRESS_LEN_MASK
#define SMPT_CMD_ADDRESS_LEN_0
#define SMPT_CMD_ADDRESS_LEN_3
#define SMPT_CMD_ADDRESS_LEN_4
#define SMPT_CMD_ADDRESS_LEN_USE_CURRENT

#define SMPT_CMD_READ_DUMMY_MASK
#define SMPT_CMD_READ_DUMMY_SHIFT
#define SMPT_CMD_READ_DUMMY(_cmd)
#define SMPT_CMD_READ_DUMMY_IS_VARIABLE

#define SMPT_CMD_READ_DATA_MASK
#define SMPT_CMD_READ_DATA_SHIFT
#define SMPT_CMD_READ_DATA(_cmd)

#define SMPT_CMD_OPCODE_MASK
#define SMPT_CMD_OPCODE_SHIFT
#define SMPT_CMD_OPCODE(_cmd)

#define SMPT_MAP_REGION_COUNT_MASK
#define SMPT_MAP_REGION_COUNT_SHIFT
#define SMPT_MAP_REGION_COUNT(_header)

#define SMPT_MAP_ID_MASK
#define SMPT_MAP_ID_SHIFT
#define SMPT_MAP_ID(_header)

#define SMPT_MAP_REGION_SIZE_MASK
#define SMPT_MAP_REGION_SIZE_SHIFT
#define SMPT_MAP_REGION_SIZE(_region)

#define SMPT_MAP_REGION_ERASE_TYPE_MASK
#define SMPT_MAP_REGION_ERASE_TYPE(_region)

#define SMPT_DESC_TYPE_MAP
#define SMPT_DESC_END

#define SFDP_4BAIT_DWORD_MAX

struct sfdp_4bait {};

/**
 * spi_nor_read_raw() - raw read of serial flash memory. read_opcode,
 *			addr_nbytes and read_dummy members of the struct spi_nor
 *			should be previously set.
 * @nor:	pointer to a 'struct spi_nor'
 * @addr:	offset in the serial flash memory
 * @len:	number of bytes to read
 * @buf:	buffer where the data is copied into (dma-safe memory)
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_read_raw(struct spi_nor *nor, u32 addr, size_t len, u8 *buf)
{}

/**
 * spi_nor_read_sfdp() - read Serial Flash Discoverable Parameters.
 * @nor:	pointer to a 'struct spi_nor'
 * @addr:	offset in the SFDP area to start reading data from
 * @len:	number of bytes to read
 * @buf:	buffer where the SFDP data are copied into (dma-safe memory)
 *
 * Whatever the actual numbers of bytes for address and dummy cycles are
 * for (Fast) Read commands, the Read SFDP (5Ah) instruction is always
 * followed by a 3-byte address and 8 dummy clock cycles.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr,
			     size_t len, void *buf)
{}

/**
 * spi_nor_read_sfdp_dma_unsafe() - read Serial Flash Discoverable Parameters.
 * @nor:	pointer to a 'struct spi_nor'
 * @addr:	offset in the SFDP area to start reading data from
 * @len:	number of bytes to read
 * @buf:	buffer where the SFDP data are copied into
 *
 * Wrap spi_nor_read_sfdp() using a kmalloc'ed bounce buffer as @buf is now not
 * guaranteed to be dma-safe.
 *
 * Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp()
 *          otherwise.
 */
static int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr,
					size_t len, void *buf)
{}

static void
spi_nor_set_read_settings_from_bfpt(struct spi_nor_read_command *read,
				    u16 half,
				    enum spi_nor_protocol proto)
{}

static const struct sfdp_bfpt_read sfdp_bfpt_reads[] =;

static const struct sfdp_bfpt_erase sfdp_bfpt_erases[] =;

/**
 * spi_nor_set_erase_settings_from_bfpt() - set erase type settings from BFPT
 * @erase:	pointer to a structure that describes a SPI NOR erase type
 * @size:	the size of the sector/block erased by the erase type
 * @opcode:	the SPI command op code to erase the sector/block
 * @i:		erase type index as sorted in the Basic Flash Parameter Table
 *
 * The supported Erase Types will be sorted at init in ascending order, with
 * the smallest Erase Type size being the first member in the erase_type array
 * of the spi_nor_erase_map structure. Save the Erase Type index as sorted in
 * the Basic Flash Parameter Table since it will be used later on to
 * synchronize with the supported Erase Types defined in SFDP optional tables.
 */
static void
spi_nor_set_erase_settings_from_bfpt(struct spi_nor_erase_type *erase,
				     u32 size, u8 opcode, u8 i)
{}

/**
 * spi_nor_map_cmp_erase_type() - compare the map's erase types by size
 * @l:	member in the left half of the map's erase_type array
 * @r:	member in the right half of the map's erase_type array
 *
 * Comparison function used in the sort() call to sort in ascending order the
 * map's erase types, the smallest erase type size being the first member in the
 * sorted erase_type array.
 *
 * Return: the result of @l->size - @r->size
 */
static int spi_nor_map_cmp_erase_type(const void *l, const void *r)
{}

/**
 * spi_nor_sort_erase_mask() - sort erase mask
 * @map:	the erase map of the SPI NOR
 * @erase_mask:	the erase type mask to be sorted
 *
 * Replicate the sort done for the map's erase types in BFPT: sort the erase
 * mask in ascending order with the smallest erase type size starting from
 * BIT(0) in the sorted erase mask.
 *
 * Return: sorted erase mask.
 */
static u8 spi_nor_sort_erase_mask(struct spi_nor_erase_map *map, u8 erase_mask)
{}

/**
 * spi_nor_regions_sort_erase_types() - sort erase types in each region
 * @map:	the erase map of the SPI NOR
 *
 * Function assumes that the erase types defined in the erase map are already
 * sorted in ascending order, with the smallest erase type size being the first
 * member in the erase_type array. It replicates the sort done for the map's
 * erase types. Each region's erase bitmask will indicate which erase types are
 * supported from the sorted erase types defined in the erase map.
 * Sort the all region's erase type at init in order to speed up the process of
 * finding the best erase command at runtime.
 */
static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map)
{}

/**
 * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table.
 * @nor:		pointer to a 'struct spi_nor'
 * @bfpt_header:	pointer to the 'struct sfdp_parameter_header' describing
 *			the Basic Flash Parameter Table length and version
 *
 * The Basic Flash Parameter Table is the main and only mandatory table as
 * defined by the SFDP (JESD216) specification.
 * It provides us with the total size (memory density) of the data array and
 * the number of address bytes for Fast Read, Page Program and Sector Erase
 * commands.
 * For Fast READ commands, it also gives the number of mode clock cycles and
 * wait states (regrouped in the number of dummy clock cycles) for each
 * supported instruction op code.
 * For Page Program, the page size is now available since JESD216 rev A, however
 * the supported instruction op codes are still not provided.
 * For Sector Erase commands, this table stores the supported instruction op
 * codes and the associated sector sizes.
 * Finally, the Quad Enable Requirements (QER) are also available since JESD216
 * rev A. The QER bits encode the manufacturer dependent procedure to be
 * executed to set the Quad Enable (QE) bit in some internal register of the
 * Quad SPI memory. Indeed the QE bit, when it exists, must be set before
 * sending any Quad SPI command to the memory. Actually, setting the QE bit
 * tells the memory to reassign its WP# and HOLD#/RESET# pins to functions IO2
 * and IO3 hence enabling 4 (Quad) I/O lines.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_parse_bfpt(struct spi_nor *nor,
			      const struct sfdp_parameter_header *bfpt_header)
{}

/**
 * spi_nor_smpt_addr_nbytes() - return the number of address bytes used in the
 *			       configuration detection command.
 * @nor:	pointer to a 'struct spi_nor'
 * @settings:	configuration detection command descriptor, dword1
 */
static u8 spi_nor_smpt_addr_nbytes(const struct spi_nor *nor, const u32 settings)
{}

/**
 * spi_nor_smpt_read_dummy() - return the configuration detection command read
 *			       latency, in clock cycles.
 * @nor:	pointer to a 'struct spi_nor'
 * @settings:	configuration detection command descriptor, dword1
 *
 * Return: the number of dummy cycles for an SMPT read
 */
static u8 spi_nor_smpt_read_dummy(const struct spi_nor *nor, const u32 settings)
{}

/**
 * spi_nor_get_map_in_use() - get the configuration map in use
 * @nor:	pointer to a 'struct spi_nor'
 * @smpt:	pointer to the sector map parameter table
 * @smpt_len:	sector map parameter table length
 *
 * Return: pointer to the map in use, ERR_PTR(-errno) otherwise.
 */
static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt,
					 u8 smpt_len)
{}

/**
 * spi_nor_region_check_overlay() - set overlay bit when the region is overlaid
 * @region:	pointer to a structure that describes a SPI NOR erase region
 * @erase:	pointer to a structure that describes a SPI NOR erase type
 * @erase_type:	erase type bitmask
 */
static void
spi_nor_region_check_overlay(struct spi_nor_erase_region *region,
			     const struct spi_nor_erase_type *erase,
			     const u8 erase_type)
{}

/**
 * spi_nor_init_non_uniform_erase_map() - initialize the non-uniform erase map
 * @nor:	pointer to a 'struct spi_nor'
 * @smpt:	pointer to the sector map parameter table
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
					      const u32 *smpt)
{}

/**
 * spi_nor_parse_smpt() - parse Sector Map Parameter Table
 * @nor:		pointer to a 'struct spi_nor'
 * @smpt_header:	sector map parameter table header
 *
 * This table is optional, but when available, we parse it to identify the
 * location and size of sectors within the main data array of the flash memory
 * device and to identify which Erase Types are supported by each sector.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_parse_smpt(struct spi_nor *nor,
			      const struct sfdp_parameter_header *smpt_header)
{}

/**
 * spi_nor_parse_4bait() - parse the 4-Byte Address Instruction Table
 * @nor:		pointer to a 'struct spi_nor'.
 * @param_header:	pointer to the 'struct sfdp_parameter_header' describing
 *			the 4-Byte Address Instruction Table length and version.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_parse_4bait(struct spi_nor *nor,
			       const struct sfdp_parameter_header *param_header)
{}

#define PROFILE1_DWORD1_RDSR_ADDR_BYTES
#define PROFILE1_DWORD1_RDSR_DUMMY
#define PROFILE1_DWORD1_RD_FAST_CMD
#define PROFILE1_DWORD4_DUMMY_200MHZ
#define PROFILE1_DWORD5_DUMMY_166MHZ
#define PROFILE1_DWORD5_DUMMY_133MHZ
#define PROFILE1_DWORD5_DUMMY_100MHZ

/**
 * spi_nor_parse_profile1() - parse the xSPI Profile 1.0 table
 * @nor:		pointer to a 'struct spi_nor'
 * @profile1_header:	pointer to the 'struct sfdp_parameter_header' describing
 *			the Profile 1.0 Table length and version.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_parse_profile1(struct spi_nor *nor,
				  const struct sfdp_parameter_header *profile1_header)
{}

#define SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE

/**
 * 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)
{}

/**
 * spi_nor_parse_sccr_mc() - Parse the Status, Control and Configuration
 *                           Register Map Offsets for Multi-Chip SPI Memory
 *                           Devices.
 * @nor:		pointer to a 'struct spi_nor'
 * @sccr_mc_header:	pointer to the 'struct sfdp_parameter_header' describing
 *			the SCCR Map offsets table length and version.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int spi_nor_parse_sccr_mc(struct spi_nor *nor,
				 const struct sfdp_parameter_header *sccr_mc_header)
{}

/**
 * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
 * after SFDP has been parsed. Called only for flashes that define JESD216 SFDP
 * tables.
 * @nor:	pointer to a 'struct spi_nor'
 *
 * Used to tweak various flash parameters when information provided by the SFDP
 * tables are wrong.
 */
static int spi_nor_post_sfdp_fixups(struct spi_nor *nor)
{}

/**
 * spi_nor_check_sfdp_signature() - check for a valid SFDP signature
 * @nor:	pointer to a 'struct spi_nor'
 *
 * Used to detect if the flash supports the RDSFDP command as well as the
 * presence of a valid SFDP table.
 *
 * Return: 0 on success, -errno otherwise.
 */
int spi_nor_check_sfdp_signature(struct spi_nor *nor)
{}

/**
 * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
 * @nor:		pointer to a 'struct spi_nor'
 *
 * The Serial Flash Discoverable Parameters are described by the JEDEC JESD216
 * specification. This is a standard which tends to supported by almost all
 * (Q)SPI memory manufacturers. Those hard-coded tables allow us to learn at
 * runtime the main parameters needed to perform basic SPI flash operations such
 * as Fast Read, Page Program or Sector Erase commands.
 *
 * Return: 0 on success, -errno otherwise.
 */
int spi_nor_parse_sfdp(struct spi_nor *nor)
{}