1/* 2 * Copyright �� 2000-2010 David Woodhouse <dwmw2@infradead.org> et al. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * 18 */ 19 20#ifndef __MTD_CFI_H__ 21#define __MTD_CFI_H__ 22 23#include <linux/delay.h> 24#include <linux/types.h> 25#include <linux/bug.h> 26#include <linux/interrupt.h> 27#include <linux/mtd/flashchip.h> 28#include <linux/mtd/map.h> 29#include <linux/mtd/cfi_endian.h> 30#include <linux/mtd/xip.h> 31 32#ifdef CONFIG_MTD_CFI_I1 33#define cfi_interleave(cfi) 1 34#define cfi_interleave_is_1(cfi) (cfi_interleave(cfi) == 1) 35#else 36#define cfi_interleave_is_1(cfi) (0) 37#endif 38 39#ifdef CONFIG_MTD_CFI_I2 40# ifdef cfi_interleave 41# undef cfi_interleave 42# define cfi_interleave(cfi) ((cfi)->interleave) 43# else 44# define cfi_interleave(cfi) 2 45# endif 46#define cfi_interleave_is_2(cfi) (cfi_interleave(cfi) == 2) 47#else 48#define cfi_interleave_is_2(cfi) (0) 49#endif 50 51#ifdef CONFIG_MTD_CFI_I4 52# ifdef cfi_interleave 53# undef cfi_interleave 54# define cfi_interleave(cfi) ((cfi)->interleave) 55# else 56# define cfi_interleave(cfi) 4 57# endif 58#define cfi_interleave_is_4(cfi) (cfi_interleave(cfi) == 4) 59#else 60#define cfi_interleave_is_4(cfi) (0) 61#endif 62 63#ifdef CONFIG_MTD_CFI_I8 64# ifdef cfi_interleave 65# undef cfi_interleave 66# define cfi_interleave(cfi) ((cfi)->interleave) 67# else 68# define cfi_interleave(cfi) 8 69# endif 70#define cfi_interleave_is_8(cfi) (cfi_interleave(cfi) == 8) 71#else 72#define cfi_interleave_is_8(cfi) (0) 73#endif 74 75#ifndef cfi_interleave 76#warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. 77static inline int cfi_interleave(void *cfi) 78{ 79 BUG(); 80 return 0; 81} 82#endif 83 84static inline int cfi_interleave_supported(int i) 85{ 86 switch (i) { 87#ifdef CONFIG_MTD_CFI_I1 88 case 1: 89#endif 90#ifdef CONFIG_MTD_CFI_I2 91 case 2: 92#endif 93#ifdef CONFIG_MTD_CFI_I4 94 case 4: 95#endif 96#ifdef CONFIG_MTD_CFI_I8 97 case 8: 98#endif 99 return 1; 100 101 default: 102 return 0; 103 } 104} 105 106 107/* NB: these values must represents the number of bytes needed to meet the 108 * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes. 109 * These numbers are used in calculations. 110 */ 111#define CFI_DEVICETYPE_X8 (8 / 8) 112#define CFI_DEVICETYPE_X16 (16 / 8) 113#define CFI_DEVICETYPE_X32 (32 / 8) 114#define CFI_DEVICETYPE_X64 (64 / 8) 115 116 117/* Device Interface Code Assignments from the "Common Flash Memory Interface 118 * Publication 100" dated December 1, 2001. 119 */ 120#define CFI_INTERFACE_X8_ASYNC 0x0000 121#define CFI_INTERFACE_X16_ASYNC 0x0001 122#define CFI_INTERFACE_X8_BY_X16_ASYNC 0x0002 123#define CFI_INTERFACE_X32_ASYNC 0x0003 124#define CFI_INTERFACE_X16_BY_X32_ASYNC 0x0005 125#define CFI_INTERFACE_NOT_ALLOWED 0xffff 126 127 128/* NB: We keep these structures in memory in HOST byteorder, except 129 * where individually noted. 130 */ 131 132/* Basic Query Structure */ 133struct cfi_ident { 134 uint8_t qry[3]; 135 uint16_t P_ID; 136 uint16_t P_ADR; 137 uint16_t A_ID; 138 uint16_t A_ADR; 139 uint8_t VccMin; 140 uint8_t VccMax; 141 uint8_t VppMin; 142 uint8_t VppMax; 143 uint8_t WordWriteTimeoutTyp; 144 uint8_t BufWriteTimeoutTyp; 145 uint8_t BlockEraseTimeoutTyp; 146 uint8_t ChipEraseTimeoutTyp; 147 uint8_t WordWriteTimeoutMax; 148 uint8_t BufWriteTimeoutMax; 149 uint8_t BlockEraseTimeoutMax; 150 uint8_t ChipEraseTimeoutMax; 151 uint8_t DevSize; 152 uint16_t InterfaceDesc; 153 uint16_t MaxBufWriteSize; 154 uint8_t NumEraseRegions; 155 uint32_t EraseRegionInfo[0]; /* Not host ordered */ 156} __packed; 157 158/* Extended Query Structure for both PRI and ALT */ 159 160struct cfi_extquery { 161 uint8_t pri[3]; 162 uint8_t MajorVersion; 163 uint8_t MinorVersion; 164} __packed; 165 166/* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */ 167 168struct cfi_pri_intelext { 169 uint8_t pri[3]; 170 uint8_t MajorVersion; 171 uint8_t MinorVersion; 172 uint32_t FeatureSupport; /* if bit 31 is set then an additional uint32_t feature 173 block follows - FIXME - not currently supported */ 174 uint8_t SuspendCmdSupport; 175 uint16_t BlkStatusRegMask; 176 uint8_t VccOptimal; 177 uint8_t VppOptimal; 178 uint8_t NumProtectionFields; 179 uint16_t ProtRegAddr; 180 uint8_t FactProtRegSize; 181 uint8_t UserProtRegSize; 182 uint8_t extra[0]; 183} __packed; 184 185struct cfi_intelext_otpinfo { 186 uint32_t ProtRegAddr; 187 uint16_t FactGroups; 188 uint8_t FactProtRegSize; 189 uint16_t UserGroups; 190 uint8_t UserProtRegSize; 191} __packed; 192 193struct cfi_intelext_blockinfo { 194 uint16_t NumIdentBlocks; 195 uint16_t BlockSize; 196 uint16_t MinBlockEraseCycles; 197 uint8_t BitsPerCell; 198 uint8_t BlockCap; 199} __packed; 200 201struct cfi_intelext_regioninfo { 202 uint16_t NumIdentPartitions; 203 uint8_t NumOpAllowed; 204 uint8_t NumOpAllowedSimProgMode; 205 uint8_t NumOpAllowedSimEraMode; 206 uint8_t NumBlockTypes; 207 struct cfi_intelext_blockinfo BlockTypes[1]; 208} __packed; 209 210struct cfi_intelext_programming_regioninfo { 211 uint8_t ProgRegShift; 212 uint8_t Reserved1; 213 uint8_t ControlValid; 214 uint8_t Reserved2; 215 uint8_t ControlInvalid; 216 uint8_t Reserved3; 217} __packed; 218 219/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ 220 221struct cfi_pri_amdstd { 222 uint8_t pri[3]; 223 uint8_t MajorVersion; 224 uint8_t MinorVersion; 225 uint8_t SiliconRevision; /* bits 1-0: Address Sensitive Unlock */ 226 uint8_t EraseSuspend; 227 uint8_t BlkProt; 228 uint8_t TmpBlkUnprotect; 229 uint8_t BlkProtUnprot; 230 uint8_t SimultaneousOps; 231 uint8_t BurstMode; 232 uint8_t PageMode; 233 uint8_t VppMin; 234 uint8_t VppMax; 235 uint8_t TopBottom; 236} __packed; 237 238/* Vendor-Specific PRI for Atmel chips (command set 0x0002) */ 239 240struct cfi_pri_atmel { 241 uint8_t pri[3]; 242 uint8_t MajorVersion; 243 uint8_t MinorVersion; 244 uint8_t Features; 245 uint8_t BottomBoot; 246 uint8_t BurstMode; 247 uint8_t PageMode; 248} __packed; 249 250struct cfi_pri_query { 251 uint8_t NumFields; 252 uint32_t ProtField[1]; /* Not host ordered */ 253} __packed; 254 255struct cfi_bri_query { 256 uint8_t PageModeReadCap; 257 uint8_t NumFields; 258 uint32_t ConfField[1]; /* Not host ordered */ 259} __packed; 260 261#define P_ID_NONE 0x0000 262#define P_ID_INTEL_EXT 0x0001 263#define P_ID_AMD_STD 0x0002 264#define P_ID_INTEL_STD 0x0003 265#define P_ID_AMD_EXT 0x0004 266#define P_ID_WINBOND 0x0006 267#define P_ID_ST_ADV 0x0020 268#define P_ID_MITSUBISHI_STD 0x0100 269#define P_ID_MITSUBISHI_EXT 0x0101 270#define P_ID_SST_PAGE 0x0102 271#define P_ID_SST_OLD 0x0701 272#define P_ID_INTEL_PERFORMANCE 0x0200 273#define P_ID_INTEL_DATA 0x0210 274#define P_ID_RESERVED 0xffff 275 276 277#define CFI_MODE_CFI 1 278#define CFI_MODE_JEDEC 0 279 280struct cfi_private { 281 uint16_t cmdset; 282 void *cmdset_priv; 283 int interleave; 284 int device_type; 285 int cfi_mode; /* Are we a JEDEC device pretending to be CFI? */ 286 int addr_unlock1; 287 int addr_unlock2; 288 struct mtd_info *(*cmdset_setup)(struct map_info *); 289 struct cfi_ident *cfiq; /* For now only one. We insist that all devs 290 must be of the same type. */ 291 int mfr, id; 292 int numchips; 293 map_word sector_erase_cmd; 294 unsigned long chipshift; /* Because they're of the same type */ 295 const char *im_name; /* inter_module name for cmdset_setup */ 296 struct flchip chips[0]; /* per-chip data structure for each chip */ 297}; 298 299uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, 300 struct map_info *map, struct cfi_private *cfi); 301 302map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi); 303#define CMD(x) cfi_build_cmd((x), map, cfi) 304 305unsigned long cfi_merge_status(map_word val, struct map_info *map, 306 struct cfi_private *cfi); 307#define MERGESTATUS(x) cfi_merge_status((x), map, cfi) 308 309uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t base, 310 struct map_info *map, struct cfi_private *cfi, 311 int type, map_word *prev_val); 312 313static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) 314{ 315 map_word val = map_read(map, addr); 316 317 if (map_bankwidth_is_1(map)) { 318 return val.x[0]; 319 } else if (map_bankwidth_is_2(map)) { 320 return cfi16_to_cpu(map, val.x[0]); 321 } else { 322 /* No point in a 64-bit byteswap since that would just be 323 swapping the responses from different chips, and we are 324 only interested in one chip (a representative sample) */ 325 return cfi32_to_cpu(map, val.x[0]); 326 } 327} 328 329static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) 330{ 331 map_word val = map_read(map, addr); 332 333 if (map_bankwidth_is_1(map)) { 334 return val.x[0] & 0xff; 335 } else if (map_bankwidth_is_2(map)) { 336 return cfi16_to_cpu(map, val.x[0]); 337 } else { 338 /* No point in a 64-bit byteswap since that would just be 339 swapping the responses from different chips, and we are 340 only interested in one chip (a representative sample) */ 341 return cfi32_to_cpu(map, val.x[0]); 342 } 343} 344 345void cfi_udelay(int us); 346 347int __xipram cfi_qry_present(struct map_info *map, __u32 base, 348 struct cfi_private *cfi); 349int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map, 350 struct cfi_private *cfi); 351void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map, 352 struct cfi_private *cfi); 353 354struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size, 355 const char* name); 356struct cfi_fixup { 357 uint16_t mfr; 358 uint16_t id; 359 void (*fixup)(struct mtd_info *mtd); 360}; 361 362#define CFI_MFR_ANY 0xFFFF 363#define CFI_ID_ANY 0xFFFF 364#define CFI_MFR_CONTINUATION 0x007F 365 366#define CFI_MFR_AMD 0x0001 367#define CFI_MFR_AMIC 0x0037 368#define CFI_MFR_ATMEL 0x001F 369#define CFI_MFR_EON 0x001C 370#define CFI_MFR_FUJITSU 0x0004 371#define CFI_MFR_HYUNDAI 0x00AD 372#define CFI_MFR_INTEL 0x0089 373#define CFI_MFR_MACRONIX 0x00C2 374#define CFI_MFR_NEC 0x0010 375#define CFI_MFR_PMC 0x009D 376#define CFI_MFR_SAMSUNG 0x00EC 377#define CFI_MFR_SHARP 0x00B0 378#define CFI_MFR_SST 0x00BF 379#define CFI_MFR_ST 0x0020 /* STMicroelectronics */ 380#define CFI_MFR_TOSHIBA 0x0098 381#define CFI_MFR_WINBOND 0x00DA 382 383void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups); 384 385typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip, 386 unsigned long adr, int len, void *thunk); 387 388int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, 389 loff_t ofs, size_t len, void *thunk); 390 391 392#endif /* __MTD_CFI_H__ */ 393