4:18
     ˆÉÈ„ ÿÇ¿Ê '‰    /* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright Â© 2000-2010 David Woodhouse <dwmw2@infradead.org> et al.
 */

#ifndef __MTD_CFI_H__
#define __MTD_CFI_H__

#include <linux/delay.h>
#include <linux/types.h>
#include <linux/bug.h>
#include <linux/interrupt.h>
#include <linux/mtd/flashchip.h>
#include <linux/mtd/map.h>
#include <linux/mtd/cfi_endian.h>
#include <linux/mtd/xip.h>

#ifdef CONFIG_MTD_CFI_I1
#define cfi_interleave(cfi) 1
#define cfi_interleave_is_1(cfi) (cfi_interleave(cfi) == 1)
#else
#define cfi_interleave_is_1(cfi) (0)
#endif

#ifdef CONFIG_MTD_CFI_I2
# ifdef cfi_interleave
#  undef cfi_interleave
#  define cfi_interleave(cfi) ((cfi)->interleave)
# else
#  define cfi_interleave(cfi) 2
# endif
#define cfi_interleave_is_2(cfi) (cfi_interleave(cfi) == 2)
#else
#define cfi_interleave_is_2(cfi) (0)
#endif

#ifdef CONFIG_MTD_CFI_I4
# ifdef cfi_interleave
#  undef cfi_interleave
#  define cfi_interleave(cfi) ((cfi)->interleave)
# else
#  define cfi_interleave(cfi) 4
# endif
#define cfi_interleave_is_4(cfi) (cfi_interleave(cfi) == 4)
#else
#define cfi_interleave_is_4(cfi) (0)
#endif

#ifdef CONFIG_MTD_CFI_I8
# ifdef cfi_interleave
#  undef cfi_interleave
#  define cfi_interleave(cfi) ((cfi)->interleave)
# else
#  define cfi_interleave(cfi) 8
# endif
#define cfi_interleave_is_8(cfi) (cfi_interleave(cfi) == 8)
#else
#define cfi_interleave_is_8(cfi) (0)
#endif

#ifndef cfi_interleave
#warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
static inline int cfi_interleave(void *cfi)
{
	BUG();
	return 0;
}
#endif

static inline int cfi_interleave_supported(int i)
{
	switch (i) {
#ifdef CONFIG_MTD_CFI_I1
	case 1:
#endif
#ifdef CONFIG_MTD_CFI_I2
	case 2:
#endif
#ifdef CONFIG_MTD_CFI_I4
	case 4:
#endif
#ifdef CONFIG_MTD_CFI_I8
	case 8:
#endif
		return 1;

	default:
		return 0;
	}
}


/* NB: these values must represents the number of bytes needed to meet the
 *     device type (x8, x16, x32).  Eg. a 32 bit device is 4 x 8 bytes.
 *     These numbers are used in calculations.
 */
#define CFI_DEVICETYPE_X8  (8 / 8)
#define CFI_DEVICETYPE_X16 (16 / 8)
#define CFI_DEVICETYPE_X32 (32 / 8)
#define CFI_DEVICETYPE_X64 (64 / 8)


/* Device Interface Code Assignments from the "Common Flash Memory Interface
 * Publication 100" dated December 1, 2001.
 */
#define CFI_INTERFACE_X8_ASYNC		0x0000
#define CFI_INTERFACE_X16_ASYNC		0x0001
#define CFI_INTERFACE_X8_BY_X16_ASYNC	0x0002
#define CFI_INTERFACE_X32_ASYNC		0x0003
#define CFI_INTERFACE_X16_BY_X32_ASYNC	0x0005
#define CFI_INTERFACE_NOT_ALLOWED	0xffff


/* NB: We keep these structures in memory in HOST byteorder, except
 * where individually noted.
 */

/* Basic Query Structure */
struct cfi_ident {
	uint8_t  qry[3];
	uint16_t P_ID;
	uint16_t P_ADR;
	uint16_t A_ID;
	uint16_t A_ADR;
	uint8_t  VccMin;
	uint8_t  VccMax;
	uint8_t  VppMin;
	uint8_t  VppMax;
	uint8_t  WordWriteTimeoutTyp;
	uint8_t  BufWriteTimeoutTyp;
	uint8_t  BlockEraseTimeoutTyp;
	uint8_t  ChipEraseTimeoutTyp;
	uint8_t  WordWriteTimeoutMax;
	uint8_t  BufWriteTimeoutMax;
	uint8_t  BlockEraseTimeoutMax;
	uint8_t  ChipEraseTimeoutMax;
	uint8_t  DevSize;
	uint16_t InterfaceDesc;
	uint16_t MaxBufWriteSize;
	uint8_t  NumEraseRegions;
	uint32_t EraseRegionInfo[]; /* Not host ordered */
} __packed;

/* Extended Query Structure for both PRI and ALT */

struct cfi_extquery {
	uint8_t  pri[3];
	uint8_t  MajorVersion;
	uint8_t  MinorVersion;
} __packed;

/* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */

struct cfi_pri_intelext {
	uint8_t  pri[3];
	uint8_t  MajorVersion;
	uint8_t  MinorVersion;
	uint32_t FeatureSupport; /* if bit 31 is set then an additional uint32_t feature
				    block follows - FIXME - not currently supported */
	uint8_t  SuspendCmdSupport;
	uint16_t BlkStatusRegMask;
	uint8_t  VccOptimal;
	uint8_t  VppOptimal;
	uint8_t  NumProtectionFields;
	uint16_t ProtRegAddr;
	uint8_t  FactProtRegSize;
	uint8_t  UserProtRegSize;
	uint8_t  extra[];
} __packed;

struct cfi_intelext_otpinfo {
	uint32_t ProtRegAddr;
	uint16_t FactGroups;
	uint