diff options
Diffstat (limited to 'target/linux/mediatek/files-5.10/drivers/mtd/mtk-snand/mtk-snand-def.h')
-rw-r--r-- | target/linux/mediatek/files-5.10/drivers/mtd/mtk-snand/mtk-snand-def.h | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/target/linux/mediatek/files-5.10/drivers/mtd/mtk-snand/mtk-snand-def.h b/target/linux/mediatek/files-5.10/drivers/mtd/mtk-snand/mtk-snand-def.h new file mode 100644 index 0000000000..1a93d93dcd --- /dev/null +++ b/target/linux/mediatek/files-5.10/drivers/mtd/mtk-snand/mtk-snand-def.h @@ -0,0 +1,268 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#ifndef _MTK_SNAND_DEF_H_ +#define _MTK_SNAND_DEF_H_ + +#include "mtk-snand-os.h" + +#ifdef PRIVATE_MTK_SNAND_HEADER +#include "mtk-snand.h" +#else +#include <mtk-snand.h> +#endif + +struct mtk_snand_plat_dev; + +enum snand_flash_io { + SNAND_IO_1_1_1, + SNAND_IO_1_1_2, + SNAND_IO_1_2_2, + SNAND_IO_1_1_4, + SNAND_IO_1_4_4, + + __SNAND_IO_MAX +}; + +#define SPI_IO_1_1_1 BIT(SNAND_IO_1_1_1) +#define SPI_IO_1_1_2 BIT(SNAND_IO_1_1_2) +#define SPI_IO_1_2_2 BIT(SNAND_IO_1_2_2) +#define SPI_IO_1_1_4 BIT(SNAND_IO_1_1_4) +#define SPI_IO_1_4_4 BIT(SNAND_IO_1_4_4) + +struct snand_opcode { + uint8_t opcode; + uint8_t dummy; +}; + +struct snand_io_cap { + uint8_t caps; + struct snand_opcode opcodes[__SNAND_IO_MAX]; +}; + +#define SNAND_OP(_io, _opcode, _dummy) [_io] = { .opcode = (_opcode), \ + .dummy = (_dummy) } + +#define SNAND_IO_CAP(_name, _caps, ...) \ + struct snand_io_cap _name = { .caps = (_caps), \ + .opcodes = { __VA_ARGS__ } } + +#define SNAND_MAX_ID_LEN 4 + +enum snand_id_type { + SNAND_ID_DYMMY, + SNAND_ID_ADDR = SNAND_ID_DYMMY, + SNAND_ID_DIRECT, + + __SNAND_ID_TYPE_MAX +}; + +struct snand_id { + uint8_t type; /* enum snand_id_type */ + uint8_t len; + uint8_t id[SNAND_MAX_ID_LEN]; +}; + +#define SNAND_ID(_type, ...) \ + { .type = (_type), .id = { __VA_ARGS__ }, \ + .len = sizeof((uint8_t[]) { __VA_ARGS__ }) } + +struct snand_mem_org { + uint16_t pagesize; + uint16_t sparesize; + uint16_t pages_per_block; + uint16_t blocks_per_die; + uint16_t planes_per_die; + uint16_t ndies; +}; + +#define SNAND_MEMORG(_ps, _ss, _ppb, _bpd, _ppd, _nd) \ + { .pagesize = (_ps), .sparesize = (_ss), .pages_per_block = (_ppb), \ + .blocks_per_die = (_bpd), .planes_per_die = (_ppd), .ndies = (_nd) } + +typedef int (*snand_select_die_t)(struct mtk_snand *snf, uint32_t dieidx); + +struct snand_flash_info { + const char *model; + struct snand_id id; + const struct snand_mem_org memorg; + const struct snand_io_cap *cap_rd; + const struct snand_io_cap *cap_pl; + snand_select_die_t select_die; +}; + +#define SNAND_INFO(_model, _id, _memorg, _cap_rd, _cap_pl, ...) \ + { .model = (_model), .id = _id, .memorg = _memorg, \ + .cap_rd = (_cap_rd), .cap_pl = (_cap_pl), __VA_ARGS__ } + +const struct snand_flash_info *snand_flash_id_lookup(enum snand_id_type type, + const uint8_t *id); + +struct mtk_snand_soc_data { + uint16_t sector_size; + uint16_t max_sectors; + uint16_t fdm_size; + uint16_t fdm_ecc_size; + uint16_t fifo_size; + + bool bbm_swap; + bool empty_page_check; + uint32_t mastersta_mask; + + const uint8_t *spare_sizes; + uint32_t num_spare_size; +}; + +enum mtk_ecc_regs { + ECC_DECDONE, +}; + +struct mtk_ecc_soc_data { + const uint8_t *ecc_caps; + uint32_t num_ecc_cap; + const uint32_t *regs; + uint16_t mode_shift; + uint8_t errnum_bits; + uint8_t errnum_shift; +}; + +struct mtk_snand { + struct mtk_snand_plat_dev *pdev; + + void __iomem *nfi_base; + void __iomem *ecc_base; + + enum mtk_snand_soc soc; + const struct mtk_snand_soc_data *nfi_soc; + const struct mtk_ecc_soc_data *ecc_soc; + bool snfi_quad_spi; + bool quad_spi_op; + + const char *model; + uint64_t size; + uint64_t die_size; + uint32_t erasesize; + uint32_t writesize; + uint32_t oobsize; + + uint32_t num_dies; + snand_select_die_t select_die; + + uint8_t opcode_rfc; + uint8_t opcode_pl; + uint8_t dummy_rfc; + uint8_t mode_rfc; + uint8_t mode_pl; + + uint32_t writesize_mask; + uint32_t writesize_shift; + uint32_t erasesize_mask; + uint32_t erasesize_shift; + uint64_t die_mask; + uint32_t die_shift; + + uint32_t spare_per_sector; + uint32_t raw_sector_size; + uint32_t ecc_strength; + uint32_t ecc_steps; + uint32_t ecc_bytes; + uint32_t ecc_parity_bits; + + uint8_t *page_cache; /* Used by read/write page */ + uint8_t *buf_cache; /* Used by block bad/markbad & auto_oob */ + int *sect_bf; /* Used by ECC correction */ +}; + +enum mtk_snand_log_category { + SNAND_LOG_NFI, + SNAND_LOG_SNFI, + SNAND_LOG_ECC, + SNAND_LOG_CHIP, + + __SNAND_LOG_CAT_MAX +}; + +int mtk_ecc_setup(struct mtk_snand *snf, void *fmdaddr, uint32_t max_ecc_bytes, + uint32_t msg_size); +int mtk_snand_ecc_encoder_start(struct mtk_snand *snf); +void mtk_snand_ecc_encoder_stop(struct mtk_snand *snf); +int mtk_snand_ecc_decoder_start(struct mtk_snand *snf); +void mtk_snand_ecc_decoder_stop(struct mtk_snand *snf); +int mtk_ecc_wait_decoder_done(struct mtk_snand *snf); +int mtk_ecc_check_decode_error(struct mtk_snand *snf); +int mtk_ecc_fixup_empty_sector(struct mtk_snand *snf, uint32_t sect); + +int mtk_snand_mac_io(struct mtk_snand *snf, const uint8_t *out, uint32_t outlen, + uint8_t *in, uint32_t inlen); +int mtk_snand_set_feature(struct mtk_snand *snf, uint32_t addr, uint32_t val); + +int mtk_snand_log(struct mtk_snand_plat_dev *pdev, + enum mtk_snand_log_category cat, const char *fmt, ...); + +#define snand_log_nfi(pdev, fmt, ...) \ + mtk_snand_log(pdev, SNAND_LOG_NFI, fmt, ##__VA_ARGS__) + +#define snand_log_snfi(pdev, fmt, ...) \ + mtk_snand_log(pdev, SNAND_LOG_SNFI, fmt, ##__VA_ARGS__) + +#define snand_log_ecc(pdev, fmt, ...) \ + mtk_snand_log(pdev, SNAND_LOG_ECC, fmt, ##__VA_ARGS__) + +#define snand_log_chip(pdev, fmt, ...) \ + mtk_snand_log(pdev, SNAND_LOG_CHIP, fmt, ##__VA_ARGS__) + +/* ffs64 */ +static inline int mtk_snand_ffs64(uint64_t x) +{ + if (!x) + return 0; + + if (!(x & 0xffffffff)) + return ffs((uint32_t)(x >> 32)) + 32; + + return ffs((uint32_t)(x & 0xffffffff)); +} + +/* NFI dummy commands */ +#define NFI_CMD_DUMMY_READ 0x00 +#define NFI_CMD_DUMMY_WRITE 0x80 + +/* SPI-NAND opcodes */ +#define SNAND_CMD_RESET 0xff +#define SNAND_CMD_BLOCK_ERASE 0xd8 +#define SNAND_CMD_READ_FROM_CACHE_QUAD 0xeb +#define SNAND_CMD_WINBOND_SELECT_DIE 0xc2 +#define SNAND_CMD_READ_FROM_CACHE_DUAL 0xbb +#define SNAND_CMD_READID 0x9f +#define SNAND_CMD_READ_FROM_CACHE_X4 0x6b +#define SNAND_CMD_READ_FROM_CACHE_X2 0x3b +#define SNAND_CMD_PROGRAM_LOAD_X4 0x32 +#define SNAND_CMD_SET_FEATURE 0x1f +#define SNAND_CMD_READ_TO_CACHE 0x13 +#define SNAND_CMD_PROGRAM_EXECUTE 0x10 +#define SNAND_CMD_GET_FEATURE 0x0f +#define SNAND_CMD_READ_FROM_CACHE 0x0b +#define SNAND_CMD_WRITE_ENABLE 0x06 +#define SNAND_CMD_PROGRAM_LOAD 0x02 + +/* SPI-NAND feature addresses */ +#define SNAND_FEATURE_MICRON_DIE_ADDR 0xd0 +#define SNAND_MICRON_DIE_SEL_1 BIT(6) + +#define SNAND_FEATURE_STATUS_ADDR 0xc0 +#define SNAND_STATUS_OIP BIT(0) +#define SNAND_STATUS_WEL BIT(1) +#define SNAND_STATUS_ERASE_FAIL BIT(2) +#define SNAND_STATUS_PROGRAM_FAIL BIT(3) + +#define SNAND_FEATURE_CONFIG_ADDR 0xb0 +#define SNAND_FEATURE_QUAD_ENABLE BIT(0) +#define SNAND_FEATURE_ECC_EN BIT(4) + +#define SNAND_FEATURE_PROTECT_ADDR 0xa0 + +#endif /* _MTK_SNAND_DEF_H_ */ |