sdk-hwV1.3/lichee/linux-4.9/drivers/mtd/awnand/spinand/physic/physic.h

205 lines
5.7 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SPINAND_PHYSIC_H
#define __SPINAND_PHYSIC_H
#include <linux/mtd/aw-spinand.h>
#include <linux/bitops.h>
#include <linux/printk.h>
#define AW_SPINAND_PHY_VER_MAIN 0x01
#define AW_SPINAND_PHY_VER_SUB 0x11
#define AW_SPINAND_PHY_VER_DATE 0x20211125
#define SECTOR_SHIFT 9
/* spinand cmd num */
#define SPI_NAND_WREN 0x06
#define SPI_NAND_WRDI 0x04
#define SPI_NAND_GETSR 0x0f
#define SPI_NAND_SETSR 0x1f
#define SPI_NAND_PAGE_READ 0x13
#define SPI_NAND_FAST_READ_X1 0x0b
#define SPI_NAND_READ_X1 0x03
#define SPI_NAND_READ_X2 0x3b
#define SPI_NAND_READ_X4 0x6b
#define SPI_NAND_READ_DUAL_IO 0xbb
#define SPI_NAND_READ_QUAD_IO 0xeb
#define SPI_NAND_RDID 0x9f
#define SPI_NAND_PP 0x02
#define SPI_NAND_PP_X4 0x32
#define SPI_NAND_RANDOM_PP 0x84
#define SPI_NAND_RANDOM_PP_X4 0x34
#define SPI_NAND_PE 0x10
#define SPI_NAND_BE 0xd8
#define SPI_NAND_RESET 0xff
#define SPI_NAND_READ_INT_ECCSTATUS 0x7c
/* status register */
#define REG_STATUS 0xc0
#define GD_REG_EXT_ECC_STATUS 0xf0
#define STATUS_BUSY BIT(0)
#define STATUS_ERASE_FAILED BIT(2)
#define STATUS_PROG_FAILED BIT(3)
#define STATUS_ECC_SHIFT 4
/* feature register */
#define REG_BLOCK_LOCK 0xa0
/* configuration register */
#define FORESEE_REG_ECC_CFG 0x90
#define REG_CFG 0xb0
#define CFG_OTP_ENABLE BIT(6)
#define CFG_BUF_MODE BIT(3)
#define CFG_ECC_ENABLE BIT(4)
#define CFG_QUAD_ENABLE BIT(0)
/* driver strength register */
#define REG_DRV 0xd0
/*differrent manufacture spinand's ecc status location maybe not the same*/
enum ecc_status_shift {
ECC_STATUS_SHIFT_0 = 0,
ECC_STATUS_SHIFT_1,
ECC_STATUS_SHIFT_2,
ECC_STATUS_SHIFT_3,
ECC_STATUS_SHIFT_4,
ECC_STATUS_SHIFT_5,
ECC_STATUS_SHIFT_6,
ECC_STATUS_SHIFT_7,
};
enum ecc_limit_err {
ECC_TYPE_ERR = 0,
BIT3_LIMIT2_TO_6_ERR7,
BIT2_LIMIT1_ERR2,
BIT2_LIMIT1_ERR2_TO_ERR3,
BIT2_LIMIT2_ERR3,
BIT2_LIMIT1_ERR2_LIMIT3,
BIT2_ERR2_LIMIT3,
BIT4_LIMIT3_TO_4_ERR15,
BIT3_LIMIT3_TO_4_ERR7,
BIT3_LIMIT5_ERR2,
BIT4_LIMIT5_TO_7_ERR8_LIMIT_12,
BIT4_LIMIT5_TO_8_ERR9_TO_15,
};
enum ecc_oob_protected {
ECC_PROTECTED_TYPE = 0,
/* all spare data are under ecc protection */
SIZE16_OFF0_LEN16,
SIZE16_OFF4_LEN12,
SIZE16_OFF4_LEN4_OFF8,
/*compatible with GD5F1GQ4UBYIG@R6*/
SIZE16_OFF4_LEN8_OFF4,
SIZE16_OFF32_LEN16,
/*compatible with XTX*/
SIZE16_OFF8_LEN16,
};
struct aw_spinand_ecc {
int (*copy_to_oob)(enum ecc_oob_protected type, unsigned char *to,
unsigned char *from, unsigned int len);
int (*copy_from_oob)(enum ecc_oob_protected type, unsigned char *to,
unsigned char *from, unsigned int len);
int (*check_ecc)(enum ecc_limit_err type, u8 status);
};
struct aw_spinand_phy_info {
const char *Model;
unsigned char NandID[MAX_ID_LEN];
unsigned int DieCntPerChip;
unsigned int BlkCntPerDie;
unsigned int PageCntPerBlk;
unsigned int SectCntPerPage;
unsigned int OobSizePerPage;
#define BAD_BLK_FLAG_MARK 0x03
#define BAD_BLK_FLAG_FRIST_1_PAGE 0x00
#define BAD_BLK_FLAG_FIRST_2_PAGE 0x01
#define BAD_BLK_FLAG_LAST_1_PAGE 0x02
#define BAD_BLK_FLAG_LAST_2_PAGE 0x03
int BadBlockFlag;
#define SPINAND_DUAL_READ BIT(0)
#define SPINAND_QUAD_READ BIT(1)
#define SPINAND_QUAD_PROGRAM BIT(2)
#define SPINAND_QUAD_NO_NEED_ENABLE BIT(3)
#define SPINAND_TWO_PLANE_SELECT BIT(7)
#define SPINAND_ONEDUMMY_AFTER_RANDOMREAD BIT(8)
int OperationOpt;
int MaxEraseTimes;
#define HAS_EXT_ECC_SE01 BIT(0)
#define HAS_EXT_ECC_STATUS BIT(1)
enum ecc_status_shift ecc_status_shift;
int EccFlag;
enum ecc_limit_err EccType;
enum ecc_oob_protected EccProtectedType;
};
/* bbt: bad block table */
struct aw_spinand_bbt {
unsigned long *bitmap;
unsigned long *en_bitmap;
int (*mark_badblock)(struct aw_spinand_chip *chip,
unsigned int blknum, bool badblk);
#define BADBLOCK (1)
#define NON_BADBLOCK (0)
#define NOT_MARKED (-1)
int (*is_badblock)(struct aw_spinand_chip *chip, unsigned int blknum);
};
struct aw_spinand_cache {
unsigned char *databuf;
unsigned char *oobbuf;
unsigned int data_maxlen;
unsigned int oob_maxlen;
unsigned int block;
unsigned int page;
#define INVALID_CACHE_ALL_AREA 0
#define VALID_CACHE_OOB BIT(1)
#define VALID_CACHE_DATA BIT(2)
unsigned int area;
/*
* If the structure cache already has the data before, just copy
* these data to req.
* @match_cache is helper to check whether the structure cache is
* what req needed.
* @copy_to_cache is helper to copy req to structure cache.
* @copy_from_cache is helper to copy structure cache to req.
*/
bool (*match_cache)(struct aw_spinand_chip *chip,
struct aw_spinand_chip_request *req);
int (*copy_to_cache)(struct aw_spinand_chip *chip,
struct aw_spinand_chip_request *req);
int (*copy_from_cache)(struct aw_spinand_chip *chip,
struct aw_spinand_chip_request *req);
/*
* 3 step:
* a) copy data from req to cache->databuf/oobbuf
* b) update cache->block/page
* c) send write cache command to spinand
*/
int (*write_to_cache)(struct aw_spinand_chip *chip,
struct aw_spinand_chip_request *req);
/*
* 3 step:
* a) send read cache command to spinand
* b) update cache->block/page
* c) copy data from cache->databuf/oobbuf to req
*/
int (*read_from_cache)(struct aw_spinand_chip *chip,
struct aw_spinand_chip_request *req);
};
extern int aw_spinand_chip_ecc_init(struct aw_spinand_chip *chip);
extern int aw_spinand_chip_ops_init(struct aw_spinand_chip *chip);
extern int aw_spinand_chip_detect(struct aw_spinand_chip *chip);
extern int aw_spinand_chip_bbt_init(struct aw_spinand_chip *chip);
extern void aw_spinand_chip_bbt_exit(struct aw_spinand_chip *chip);
extern int aw_spinand_chip_cache_init(struct aw_spinand_chip *chip);
extern void aw_spinand_chip_cache_exit(struct aw_spinand_chip *chip);
#endif