0001
0002
0003
0004
0005
0006
0007
0008 #ifndef __LINUX_MTD_SPINAND_H
0009 #define __LINUX_MTD_SPINAND_H
0010
0011 #include <linux/mutex.h>
0012 #include <linux/bitops.h>
0013 #include <linux/device.h>
0014 #include <linux/mtd/mtd.h>
0015 #include <linux/mtd/nand.h>
0016 #include <linux/spi/spi.h>
0017 #include <linux/spi/spi-mem.h>
0018
0019
0020
0021
0022
0023 #define SPINAND_RESET_OP \
0024 SPI_MEM_OP(SPI_MEM_OP_CMD(0xff, 1), \
0025 SPI_MEM_OP_NO_ADDR, \
0026 SPI_MEM_OP_NO_DUMMY, \
0027 SPI_MEM_OP_NO_DATA)
0028
0029 #define SPINAND_WR_EN_DIS_OP(enable) \
0030 SPI_MEM_OP(SPI_MEM_OP_CMD((enable) ? 0x06 : 0x04, 1), \
0031 SPI_MEM_OP_NO_ADDR, \
0032 SPI_MEM_OP_NO_DUMMY, \
0033 SPI_MEM_OP_NO_DATA)
0034
0035 #define SPINAND_READID_OP(naddr, ndummy, buf, len) \
0036 SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \
0037 SPI_MEM_OP_ADDR(naddr, 0, 1), \
0038 SPI_MEM_OP_DUMMY(ndummy, 1), \
0039 SPI_MEM_OP_DATA_IN(len, buf, 1))
0040
0041 #define SPINAND_SET_FEATURE_OP(reg, valptr) \
0042 SPI_MEM_OP(SPI_MEM_OP_CMD(0x1f, 1), \
0043 SPI_MEM_OP_ADDR(1, reg, 1), \
0044 SPI_MEM_OP_NO_DUMMY, \
0045 SPI_MEM_OP_DATA_OUT(1, valptr, 1))
0046
0047 #define SPINAND_GET_FEATURE_OP(reg, valptr) \
0048 SPI_MEM_OP(SPI_MEM_OP_CMD(0x0f, 1), \
0049 SPI_MEM_OP_ADDR(1, reg, 1), \
0050 SPI_MEM_OP_NO_DUMMY, \
0051 SPI_MEM_OP_DATA_IN(1, valptr, 1))
0052
0053 #define SPINAND_BLK_ERASE_OP(addr) \
0054 SPI_MEM_OP(SPI_MEM_OP_CMD(0xd8, 1), \
0055 SPI_MEM_OP_ADDR(3, addr, 1), \
0056 SPI_MEM_OP_NO_DUMMY, \
0057 SPI_MEM_OP_NO_DATA)
0058
0059 #define SPINAND_PAGE_READ_OP(addr) \
0060 SPI_MEM_OP(SPI_MEM_OP_CMD(0x13, 1), \
0061 SPI_MEM_OP_ADDR(3, addr, 1), \
0062 SPI_MEM_OP_NO_DUMMY, \
0063 SPI_MEM_OP_NO_DATA)
0064
0065 #define SPINAND_PAGE_READ_FROM_CACHE_OP(fast, addr, ndummy, buf, len) \
0066 SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \
0067 SPI_MEM_OP_ADDR(2, addr, 1), \
0068 SPI_MEM_OP_DUMMY(ndummy, 1), \
0069 SPI_MEM_OP_DATA_IN(len, buf, 1))
0070
0071 #define SPINAND_PAGE_READ_FROM_CACHE_OP_3A(fast, addr, ndummy, buf, len) \
0072 SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \
0073 SPI_MEM_OP_ADDR(3, addr, 1), \
0074 SPI_MEM_OP_DUMMY(ndummy, 1), \
0075 SPI_MEM_OP_DATA_IN(len, buf, 1))
0076
0077 #define SPINAND_PAGE_READ_FROM_CACHE_X2_OP(addr, ndummy, buf, len) \
0078 SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
0079 SPI_MEM_OP_ADDR(2, addr, 1), \
0080 SPI_MEM_OP_DUMMY(ndummy, 1), \
0081 SPI_MEM_OP_DATA_IN(len, buf, 2))
0082
0083 #define SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(addr, ndummy, buf, len) \
0084 SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
0085 SPI_MEM_OP_ADDR(3, addr, 1), \
0086 SPI_MEM_OP_DUMMY(ndummy, 1), \
0087 SPI_MEM_OP_DATA_IN(len, buf, 2))
0088
0089 #define SPINAND_PAGE_READ_FROM_CACHE_X4_OP(addr, ndummy, buf, len) \
0090 SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
0091 SPI_MEM_OP_ADDR(2, addr, 1), \
0092 SPI_MEM_OP_DUMMY(ndummy, 1), \
0093 SPI_MEM_OP_DATA_IN(len, buf, 4))
0094
0095 #define SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(addr, ndummy, buf, len) \
0096 SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
0097 SPI_MEM_OP_ADDR(3, addr, 1), \
0098 SPI_MEM_OP_DUMMY(ndummy, 1), \
0099 SPI_MEM_OP_DATA_IN(len, buf, 4))
0100
0101 #define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(addr, ndummy, buf, len) \
0102 SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
0103 SPI_MEM_OP_ADDR(2, addr, 2), \
0104 SPI_MEM_OP_DUMMY(ndummy, 2), \
0105 SPI_MEM_OP_DATA_IN(len, buf, 2))
0106
0107 #define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP_3A(addr, ndummy, buf, len) \
0108 SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
0109 SPI_MEM_OP_ADDR(3, addr, 2), \
0110 SPI_MEM_OP_DUMMY(ndummy, 2), \
0111 SPI_MEM_OP_DATA_IN(len, buf, 2))
0112
0113 #define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(addr, ndummy, buf, len) \
0114 SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
0115 SPI_MEM_OP_ADDR(2, addr, 4), \
0116 SPI_MEM_OP_DUMMY(ndummy, 4), \
0117 SPI_MEM_OP_DATA_IN(len, buf, 4))
0118
0119 #define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP_3A(addr, ndummy, buf, len) \
0120 SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
0121 SPI_MEM_OP_ADDR(3, addr, 4), \
0122 SPI_MEM_OP_DUMMY(ndummy, 4), \
0123 SPI_MEM_OP_DATA_IN(len, buf, 4))
0124
0125 #define SPINAND_PROG_EXEC_OP(addr) \
0126 SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1), \
0127 SPI_MEM_OP_ADDR(3, addr, 1), \
0128 SPI_MEM_OP_NO_DUMMY, \
0129 SPI_MEM_OP_NO_DATA)
0130
0131 #define SPINAND_PROG_LOAD(reset, addr, buf, len) \
0132 SPI_MEM_OP(SPI_MEM_OP_CMD(reset ? 0x02 : 0x84, 1), \
0133 SPI_MEM_OP_ADDR(2, addr, 1), \
0134 SPI_MEM_OP_NO_DUMMY, \
0135 SPI_MEM_OP_DATA_OUT(len, buf, 1))
0136
0137 #define SPINAND_PROG_LOAD_X4(reset, addr, buf, len) \
0138 SPI_MEM_OP(SPI_MEM_OP_CMD(reset ? 0x32 : 0x34, 1), \
0139 SPI_MEM_OP_ADDR(2, addr, 1), \
0140 SPI_MEM_OP_NO_DUMMY, \
0141 SPI_MEM_OP_DATA_OUT(len, buf, 4))
0142
0143
0144
0145
0146 #define SPINAND_CMD_PROG_LOAD_X4 0x32
0147 #define SPINAND_CMD_PROG_LOAD_RDM_DATA_X4 0x34
0148
0149
0150 #define REG_BLOCK_LOCK 0xa0
0151 #define BL_ALL_UNLOCKED 0x00
0152
0153
0154 #define REG_CFG 0xb0
0155 #define CFG_OTP_ENABLE BIT(6)
0156 #define CFG_ECC_ENABLE BIT(4)
0157 #define CFG_QUAD_ENABLE BIT(0)
0158
0159
0160 #define REG_STATUS 0xc0
0161 #define STATUS_BUSY BIT(0)
0162 #define STATUS_ERASE_FAILED BIT(2)
0163 #define STATUS_PROG_FAILED BIT(3)
0164 #define STATUS_ECC_MASK GENMASK(5, 4)
0165 #define STATUS_ECC_NO_BITFLIPS (0 << 4)
0166 #define STATUS_ECC_HAS_BITFLIPS (1 << 4)
0167 #define STATUS_ECC_UNCOR_ERROR (2 << 4)
0168
0169 struct spinand_op;
0170 struct spinand_device;
0171
0172 #define SPINAND_MAX_ID_LEN 4
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 #define SPINAND_READ_INITIAL_DELAY_US 6
0186 #define SPINAND_READ_POLL_DELAY_US 5
0187 #define SPINAND_RESET_INITIAL_DELAY_US 5
0188 #define SPINAND_RESET_POLL_DELAY_US 5
0189 #define SPINAND_WRITE_INITIAL_DELAY_US 75
0190 #define SPINAND_WRITE_POLL_DELAY_US 15
0191 #define SPINAND_ERASE_INITIAL_DELAY_US 250
0192 #define SPINAND_ERASE_POLL_DELAY_US 50
0193
0194 #define SPINAND_WAITRDY_TIMEOUT_MS 400
0195
0196
0197
0198
0199
0200
0201
0202 struct spinand_id {
0203 u8 data[SPINAND_MAX_ID_LEN];
0204 int len;
0205 };
0206
0207 enum spinand_readid_method {
0208 SPINAND_READID_METHOD_OPCODE,
0209 SPINAND_READID_METHOD_OPCODE_ADDR,
0210 SPINAND_READID_METHOD_OPCODE_DUMMY,
0211 };
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226 struct spinand_devid {
0227 const u8 *id;
0228 const u8 len;
0229 const enum spinand_readid_method method;
0230 };
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 struct spinand_manufacturer_ops {
0241 int (*init)(struct spinand_device *spinand);
0242 void (*cleanup)(struct spinand_device *spinand);
0243 };
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 struct spinand_manufacturer {
0255 u8 id;
0256 char *name;
0257 const struct spinand_info *chips;
0258 const size_t nchips;
0259 const struct spinand_manufacturer_ops *ops;
0260 };
0261
0262
0263 extern const struct spinand_manufacturer ato_spinand_manufacturer;
0264 extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
0265 extern const struct spinand_manufacturer macronix_spinand_manufacturer;
0266 extern const struct spinand_manufacturer micron_spinand_manufacturer;
0267 extern const struct spinand_manufacturer paragon_spinand_manufacturer;
0268 extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
0269 extern const struct spinand_manufacturer winbond_spinand_manufacturer;
0270 extern const struct spinand_manufacturer xtx_spinand_manufacturer;
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 struct spinand_op_variants {
0284 const struct spi_mem_op *ops;
0285 unsigned int nops;
0286 };
0287
0288 #define SPINAND_OP_VARIANTS(name, ...) \
0289 const struct spinand_op_variants name = { \
0290 .ops = (struct spi_mem_op[]) { __VA_ARGS__ }, \
0291 .nops = sizeof((struct spi_mem_op[]){ __VA_ARGS__ }) / \
0292 sizeof(struct spi_mem_op), \
0293 }
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 struct spinand_ecc_info {
0306 int (*get_status)(struct spinand_device *spinand, u8 status);
0307 const struct mtd_ooblayout_ops *ooblayout;
0308 };
0309
0310 #define SPINAND_HAS_QE_BIT BIT(0)
0311 #define SPINAND_HAS_CR_FEAT_BIT BIT(1)
0312
0313
0314
0315
0316
0317
0318 struct spinand_ondie_ecc_conf {
0319 u8 status;
0320 };
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340 struct spinand_info {
0341 const char *model;
0342 struct spinand_devid devid;
0343 u32 flags;
0344 struct nand_memory_organization memorg;
0345 struct nand_ecc_props eccreq;
0346 struct spinand_ecc_info eccinfo;
0347 struct {
0348 const struct spinand_op_variants *read_cache;
0349 const struct spinand_op_variants *write_cache;
0350 const struct spinand_op_variants *update_cache;
0351 } op_variants;
0352 int (*select_target)(struct spinand_device *spinand,
0353 unsigned int target);
0354 };
0355
0356 #define SPINAND_ID(__method, ...) \
0357 { \
0358 .id = (const u8[]){ __VA_ARGS__ }, \
0359 .len = sizeof((u8[]){ __VA_ARGS__ }), \
0360 .method = __method, \
0361 }
0362
0363 #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \
0364 { \
0365 .read_cache = __read, \
0366 .write_cache = __write, \
0367 .update_cache = __update, \
0368 }
0369
0370 #define SPINAND_ECCINFO(__ooblayout, __get_status) \
0371 .eccinfo = { \
0372 .ooblayout = __ooblayout, \
0373 .get_status = __get_status, \
0374 }
0375
0376 #define SPINAND_SELECT_TARGET(__func) \
0377 .select_target = __func,
0378
0379 #define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants, \
0380 __flags, ...) \
0381 { \
0382 .model = __model, \
0383 .devid = __id, \
0384 .memorg = __memorg, \
0385 .eccreq = __eccreq, \
0386 .op_variants = __op_variants, \
0387 .flags = __flags, \
0388 __VA_ARGS__ \
0389 }
0390
0391 struct spinand_dirmap {
0392 struct spi_mem_dirmap_desc *wdesc;
0393 struct spi_mem_dirmap_desc *rdesc;
0394 struct spi_mem_dirmap_desc *wdesc_ecc;
0395 struct spi_mem_dirmap_desc *rdesc_ecc;
0396 };
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424 struct spinand_device {
0425 struct nand_device base;
0426 struct spi_mem *spimem;
0427 struct mutex lock;
0428 struct spinand_id id;
0429 u32 flags;
0430
0431 struct {
0432 const struct spi_mem_op *read_cache;
0433 const struct spi_mem_op *write_cache;
0434 const struct spi_mem_op *update_cache;
0435 } op_templates;
0436
0437 struct spinand_dirmap *dirmaps;
0438
0439 int (*select_target)(struct spinand_device *spinand,
0440 unsigned int target);
0441 unsigned int cur_target;
0442
0443 struct spinand_ecc_info eccinfo;
0444
0445 u8 *cfg_cache;
0446 u8 *databuf;
0447 u8 *oobbuf;
0448 u8 *scratchbuf;
0449 const struct spinand_manufacturer *manufacturer;
0450 void *priv;
0451 };
0452
0453
0454
0455
0456
0457
0458
0459 static inline struct spinand_device *mtd_to_spinand(struct mtd_info *mtd)
0460 {
0461 return container_of(mtd_to_nanddev(mtd), struct spinand_device, base);
0462 }
0463
0464
0465
0466
0467
0468
0469
0470 static inline struct mtd_info *spinand_to_mtd(struct spinand_device *spinand)
0471 {
0472 return nanddev_to_mtd(&spinand->base);
0473 }
0474
0475
0476
0477
0478
0479
0480
0481 static inline struct spinand_device *nand_to_spinand(struct nand_device *nand)
0482 {
0483 return container_of(nand, struct spinand_device, base);
0484 }
0485
0486
0487
0488
0489
0490
0491
0492 static inline struct nand_device *
0493 spinand_to_nand(struct spinand_device *spinand)
0494 {
0495 return &spinand->base;
0496 }
0497
0498
0499
0500
0501
0502
0503
0504
0505 static inline void spinand_set_of_node(struct spinand_device *spinand,
0506 struct device_node *np)
0507 {
0508 nanddev_set_of_node(&spinand->base, np);
0509 }
0510
0511 int spinand_match_and_init(struct spinand_device *spinand,
0512 const struct spinand_info *table,
0513 unsigned int table_size,
0514 enum spinand_readid_method rdid_method);
0515
0516 int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
0517 int spinand_select_target(struct spinand_device *spinand, unsigned int target);
0518
0519 #endif