Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org> et al.
0004  */
0005 
0006 #ifndef __MTD_CFI_H__
0007 #define __MTD_CFI_H__
0008 
0009 #include <linux/delay.h>
0010 #include <linux/types.h>
0011 #include <linux/bug.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/mtd/flashchip.h>
0014 #include <linux/mtd/map.h>
0015 #include <linux/mtd/cfi_endian.h>
0016 #include <linux/mtd/xip.h>
0017 
0018 #ifdef CONFIG_MTD_CFI_I1
0019 #define cfi_interleave(cfi) 1
0020 #define cfi_interleave_is_1(cfi) (cfi_interleave(cfi) == 1)
0021 #else
0022 #define cfi_interleave_is_1(cfi) (0)
0023 #endif
0024 
0025 #ifdef CONFIG_MTD_CFI_I2
0026 # ifdef cfi_interleave
0027 #  undef cfi_interleave
0028 #  define cfi_interleave(cfi) ((cfi)->interleave)
0029 # else
0030 #  define cfi_interleave(cfi) 2
0031 # endif
0032 #define cfi_interleave_is_2(cfi) (cfi_interleave(cfi) == 2)
0033 #else
0034 #define cfi_interleave_is_2(cfi) (0)
0035 #endif
0036 
0037 #ifdef CONFIG_MTD_CFI_I4
0038 # ifdef cfi_interleave
0039 #  undef cfi_interleave
0040 #  define cfi_interleave(cfi) ((cfi)->interleave)
0041 # else
0042 #  define cfi_interleave(cfi) 4
0043 # endif
0044 #define cfi_interleave_is_4(cfi) (cfi_interleave(cfi) == 4)
0045 #else
0046 #define cfi_interleave_is_4(cfi) (0)
0047 #endif
0048 
0049 #ifdef CONFIG_MTD_CFI_I8
0050 # ifdef cfi_interleave
0051 #  undef cfi_interleave
0052 #  define cfi_interleave(cfi) ((cfi)->interleave)
0053 # else
0054 #  define cfi_interleave(cfi) 8
0055 # endif
0056 #define cfi_interleave_is_8(cfi) (cfi_interleave(cfi) == 8)
0057 #else
0058 #define cfi_interleave_is_8(cfi) (0)
0059 #endif
0060 
0061 #ifndef cfi_interleave
0062 #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
0063 static inline int cfi_interleave(void *cfi)
0064 {
0065     BUG();
0066     return 0;
0067 }
0068 #endif
0069 
0070 static inline int cfi_interleave_supported(int i)
0071 {
0072     switch (i) {
0073 #ifdef CONFIG_MTD_CFI_I1
0074     case 1:
0075 #endif
0076 #ifdef CONFIG_MTD_CFI_I2
0077     case 2:
0078 #endif
0079 #ifdef CONFIG_MTD_CFI_I4
0080     case 4:
0081 #endif
0082 #ifdef CONFIG_MTD_CFI_I8
0083     case 8:
0084 #endif
0085         return 1;
0086 
0087     default:
0088         return 0;
0089     }
0090 }
0091 
0092 
0093 /* NB: these values must represents the number of bytes needed to meet the
0094  *     device type (x8, x16, x32).  Eg. a 32 bit device is 4 x 8 bytes.
0095  *     These numbers are used in calculations.
0096  */
0097 #define CFI_DEVICETYPE_X8  (8 / 8)
0098 #define CFI_DEVICETYPE_X16 (16 / 8)
0099 #define CFI_DEVICETYPE_X32 (32 / 8)
0100 #define CFI_DEVICETYPE_X64 (64 / 8)
0101 
0102 
0103 /* Device Interface Code Assignments from the "Common Flash Memory Interface
0104  * Publication 100" dated December 1, 2001.
0105  */
0106 #define CFI_INTERFACE_X8_ASYNC      0x0000
0107 #define CFI_INTERFACE_X16_ASYNC     0x0001
0108 #define CFI_INTERFACE_X8_BY_X16_ASYNC   0x0002
0109 #define CFI_INTERFACE_X32_ASYNC     0x0003
0110 #define CFI_INTERFACE_X16_BY_X32_ASYNC  0x0005
0111 #define CFI_INTERFACE_NOT_ALLOWED   0xffff
0112 
0113 
0114 /* NB: We keep these structures in memory in HOST byteorder, except
0115  * where individually noted.
0116  */
0117 
0118 /* Basic Query Structure */
0119 struct cfi_ident {
0120     uint8_t  qry[3];
0121     uint16_t P_ID;
0122     uint16_t P_ADR;
0123     uint16_t A_ID;
0124     uint16_t A_ADR;
0125     uint8_t  VccMin;
0126     uint8_t  VccMax;
0127     uint8_t  VppMin;
0128     uint8_t  VppMax;
0129     uint8_t  WordWriteTimeoutTyp;
0130     uint8_t  BufWriteTimeoutTyp;
0131     uint8_t  BlockEraseTimeoutTyp;
0132     uint8_t  ChipEraseTimeoutTyp;
0133     uint8_t  WordWriteTimeoutMax;
0134     uint8_t  BufWriteTimeoutMax;
0135     uint8_t  BlockEraseTimeoutMax;
0136     uint8_t  ChipEraseTimeoutMax;
0137     uint8_t  DevSize;
0138     uint16_t InterfaceDesc;
0139     uint16_t MaxBufWriteSize;
0140     uint8_t  NumEraseRegions;
0141     uint32_t EraseRegionInfo[]; /* Not host ordered */
0142 } __packed;
0143 
0144 /* Extended Query Structure for both PRI and ALT */
0145 
0146 struct cfi_extquery {
0147     uint8_t  pri[3];
0148     uint8_t  MajorVersion;
0149     uint8_t  MinorVersion;
0150 } __packed;
0151 
0152 /* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */
0153 
0154 struct cfi_pri_intelext {
0155     uint8_t  pri[3];
0156     uint8_t  MajorVersion;
0157     uint8_t  MinorVersion;
0158     uint32_t FeatureSupport; /* if bit 31 is set then an additional uint32_t feature
0159                     block follows - FIXME - not currently supported */
0160     uint8_t  SuspendCmdSupport;
0161     uint16_t BlkStatusRegMask;
0162     uint8_t  VccOptimal;
0163     uint8_t  VppOptimal;
0164     uint8_t  NumProtectionFields;
0165     uint16_t ProtRegAddr;
0166     uint8_t  FactProtRegSize;
0167     uint8_t  UserProtRegSize;
0168     uint8_t  extra[];
0169 } __packed;
0170 
0171 struct cfi_intelext_otpinfo {
0172     uint32_t ProtRegAddr;
0173     uint16_t FactGroups;
0174     uint8_t  FactProtRegSize;
0175     uint16_t UserGroups;
0176     uint8_t  UserProtRegSize;
0177 } __packed;
0178 
0179 struct cfi_intelext_blockinfo {
0180     uint16_t NumIdentBlocks;
0181     uint16_t BlockSize;
0182     uint16_t MinBlockEraseCycles;
0183     uint8_t  BitsPerCell;
0184     uint8_t  BlockCap;
0185 } __packed;
0186 
0187 struct cfi_intelext_regioninfo {
0188     uint16_t NumIdentPartitions;
0189     uint8_t  NumOpAllowed;
0190     uint8_t  NumOpAllowedSimProgMode;
0191     uint8_t  NumOpAllowedSimEraMode;
0192     uint8_t  NumBlockTypes;
0193     struct cfi_intelext_blockinfo BlockTypes[1];
0194 } __packed;
0195 
0196 struct cfi_intelext_programming_regioninfo {
0197     uint8_t  ProgRegShift;
0198     uint8_t  Reserved1;
0199     uint8_t  ControlValid;
0200     uint8_t  Reserved2;
0201     uint8_t  ControlInvalid;
0202     uint8_t  Reserved3;
0203 } __packed;
0204 
0205 /* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */
0206 
0207 struct cfi_pri_amdstd {
0208     uint8_t  pri[3];
0209     uint8_t  MajorVersion;
0210     uint8_t  MinorVersion;
0211     uint8_t  SiliconRevision; /* bits 1-0: Address Sensitive Unlock */
0212     uint8_t  EraseSuspend;
0213     uint8_t  BlkProt;
0214     uint8_t  TmpBlkUnprotect;
0215     uint8_t  BlkProtUnprot;
0216     uint8_t  SimultaneousOps;
0217     uint8_t  BurstMode;
0218     uint8_t  PageMode;
0219     uint8_t  VppMin;
0220     uint8_t  VppMax;
0221     uint8_t  TopBottom;
0222     /* Below field are added from version 1.5 */
0223     uint8_t  ProgramSuspend;
0224     uint8_t  UnlockBypass;
0225     uint8_t  SecureSiliconSector;
0226     uint8_t  SoftwareFeatures;
0227 #define CFI_POLL_STATUS_REG BIT(0)
0228 #define CFI_POLL_DQ     BIT(1)
0229 } __packed;
0230 
0231 /* Vendor-Specific PRI for Atmel chips (command set 0x0002) */
0232 
0233 struct cfi_pri_atmel {
0234     uint8_t pri[3];
0235     uint8_t MajorVersion;
0236     uint8_t MinorVersion;
0237     uint8_t Features;
0238     uint8_t BottomBoot;
0239     uint8_t BurstMode;
0240     uint8_t PageMode;
0241 } __packed;
0242 
0243 struct cfi_pri_query {
0244     uint8_t  NumFields;
0245     uint32_t ProtField[1]; /* Not host ordered */
0246 } __packed;
0247 
0248 struct cfi_bri_query {
0249     uint8_t  PageModeReadCap;
0250     uint8_t  NumFields;
0251     uint32_t ConfField[1]; /* Not host ordered */
0252 } __packed;
0253 
0254 #define P_ID_NONE               0x0000
0255 #define P_ID_INTEL_EXT          0x0001
0256 #define P_ID_AMD_STD            0x0002
0257 #define P_ID_INTEL_STD          0x0003
0258 #define P_ID_AMD_EXT            0x0004
0259 #define P_ID_WINBOND            0x0006
0260 #define P_ID_ST_ADV             0x0020
0261 #define P_ID_MITSUBISHI_STD     0x0100
0262 #define P_ID_MITSUBISHI_EXT     0x0101
0263 #define P_ID_SST_PAGE           0x0102
0264 #define P_ID_SST_OLD            0x0701
0265 #define P_ID_INTEL_PERFORMANCE  0x0200
0266 #define P_ID_INTEL_DATA         0x0210
0267 #define P_ID_RESERVED           0xffff
0268 
0269 
0270 #define CFI_MODE_CFI    1
0271 #define CFI_MODE_JEDEC  0
0272 
0273 struct cfi_private {
0274     uint16_t cmdset;
0275     void *cmdset_priv;
0276     int interleave;
0277     int device_type;
0278     int cfi_mode;       /* Are we a JEDEC device pretending to be CFI? */
0279     int addr_unlock1;
0280     int addr_unlock2;
0281     struct mtd_info *(*cmdset_setup)(struct map_info *);
0282     struct cfi_ident *cfiq; /* For now only one. We insist that all devs
0283                   must be of the same type. */
0284     int mfr, id;
0285     int numchips;
0286     map_word sector_erase_cmd;
0287     unsigned long chipshift; /* Because they're of the same type */
0288     const char *im_name;     /* inter_module name for cmdset_setup */
0289     unsigned long quirks;
0290     struct flchip chips[];  /* per-chip data structure for each chip */
0291 };
0292 
0293 uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs,
0294                 struct map_info *map, struct cfi_private *cfi);
0295 
0296 map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi);
0297 #define CMD(x)  cfi_build_cmd((x), map, cfi)
0298 
0299 unsigned long cfi_merge_status(map_word val, struct map_info *map,
0300                        struct cfi_private *cfi);
0301 #define MERGESTATUS(x) cfi_merge_status((x), map, cfi)
0302 
0303 uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t base,
0304                 struct map_info *map, struct cfi_private *cfi,
0305                 int type, map_word *prev_val);
0306 
0307 static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr)
0308 {
0309     map_word val = map_read(map, addr);
0310 
0311     if (map_bankwidth_is_1(map)) {
0312         return val.x[0];
0313     } else if (map_bankwidth_is_2(map)) {
0314         return cfi16_to_cpu(map, val.x[0]);
0315     } else {
0316         /* No point in a 64-bit byteswap since that would just be
0317            swapping the responses from different chips, and we are
0318            only interested in one chip (a representative sample) */
0319         return cfi32_to_cpu(map, val.x[0]);
0320     }
0321 }
0322 
0323 static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr)
0324 {
0325     map_word val = map_read(map, addr);
0326 
0327     if (map_bankwidth_is_1(map)) {
0328         return val.x[0] & 0xff;
0329     } else if (map_bankwidth_is_2(map)) {
0330         return cfi16_to_cpu(map, val.x[0]);
0331     } else {
0332         /* No point in a 64-bit byteswap since that would just be
0333            swapping the responses from different chips, and we are
0334            only interested in one chip (a representative sample) */
0335         return cfi32_to_cpu(map, val.x[0]);
0336     }
0337 }
0338 
0339 void cfi_udelay(int us);
0340 
0341 int __xipram cfi_qry_present(struct map_info *map, __u32 base,
0342                  struct cfi_private *cfi);
0343 int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,
0344                  struct cfi_private *cfi);
0345 void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map,
0346                    struct cfi_private *cfi);
0347 
0348 struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size,
0349                  const char* name);
0350 struct cfi_fixup {
0351     uint16_t mfr;
0352     uint16_t id;
0353     void (*fixup)(struct mtd_info *mtd);
0354 };
0355 
0356 #define CFI_MFR_ANY     0xFFFF
0357 #define CFI_ID_ANY      0xFFFF
0358 #define CFI_MFR_CONTINUATION    0x007F
0359 
0360 #define CFI_MFR_AMD     0x0001
0361 #define CFI_MFR_AMIC        0x0037
0362 #define CFI_MFR_ATMEL       0x001F
0363 #define CFI_MFR_EON     0x001C
0364 #define CFI_MFR_FUJITSU     0x0004
0365 #define CFI_MFR_HYUNDAI     0x00AD
0366 #define CFI_MFR_INTEL       0x0089
0367 #define CFI_MFR_MACRONIX    0x00C2
0368 #define CFI_MFR_NEC     0x0010
0369 #define CFI_MFR_PMC     0x009D
0370 #define CFI_MFR_SAMSUNG     0x00EC
0371 #define CFI_MFR_SHARP       0x00B0
0372 #define CFI_MFR_SST     0x00BF
0373 #define CFI_MFR_ST      0x0020 /* STMicroelectronics */
0374 #define CFI_MFR_MICRON      0x002C /* Micron */
0375 #define CFI_MFR_TOSHIBA     0x0098
0376 #define CFI_MFR_WINBOND     0x00DA
0377 
0378 void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups);
0379 
0380 typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip,
0381                   unsigned long adr, int len, void *thunk);
0382 
0383 int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
0384     loff_t ofs, size_t len, void *thunk);
0385 
0386 
0387 #endif /* __MTD_CFI_H__ */