developer | fd40db2 | 2021-04-29 10:08:25 +0800 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ |
| 2 | /* |
| 3 | * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. |
| 4 | * |
| 5 | * Author: Weijie Gao <weijie.gao@mediatek.com> |
| 6 | */ |
| 7 | |
| 8 | #ifndef _MTK_SNAND_DEF_H_ |
| 9 | #define _MTK_SNAND_DEF_H_ |
| 10 | |
| 11 | #include "mtk-snand-os.h" |
| 12 | |
| 13 | #ifdef PRIVATE_MTK_SNAND_HEADER |
| 14 | #include "mtk-snand.h" |
| 15 | #else |
| 16 | #include <mtk-snand.h> |
| 17 | #endif |
| 18 | |
| 19 | struct mtk_snand_plat_dev; |
| 20 | |
| 21 | enum snand_flash_io { |
| 22 | SNAND_IO_1_1_1, |
| 23 | SNAND_IO_1_1_2, |
| 24 | SNAND_IO_1_2_2, |
| 25 | SNAND_IO_1_1_4, |
| 26 | SNAND_IO_1_4_4, |
| 27 | |
| 28 | __SNAND_IO_MAX |
| 29 | }; |
| 30 | |
| 31 | #define SPI_IO_1_1_1 BIT(SNAND_IO_1_1_1) |
| 32 | #define SPI_IO_1_1_2 BIT(SNAND_IO_1_1_2) |
| 33 | #define SPI_IO_1_2_2 BIT(SNAND_IO_1_2_2) |
| 34 | #define SPI_IO_1_1_4 BIT(SNAND_IO_1_1_4) |
| 35 | #define SPI_IO_1_4_4 BIT(SNAND_IO_1_4_4) |
| 36 | |
| 37 | struct snand_opcode { |
| 38 | uint8_t opcode; |
| 39 | uint8_t dummy; |
| 40 | }; |
| 41 | |
| 42 | struct snand_io_cap { |
| 43 | uint8_t caps; |
| 44 | struct snand_opcode opcodes[__SNAND_IO_MAX]; |
| 45 | }; |
| 46 | |
| 47 | #define SNAND_OP(_io, _opcode, _dummy) [_io] = { .opcode = (_opcode), \ |
| 48 | .dummy = (_dummy) } |
| 49 | |
| 50 | #define SNAND_IO_CAP(_name, _caps, ...) \ |
| 51 | struct snand_io_cap _name = { .caps = (_caps), \ |
| 52 | .opcodes = { __VA_ARGS__ } } |
| 53 | |
| 54 | #define SNAND_MAX_ID_LEN 4 |
| 55 | |
| 56 | enum snand_id_type { |
| 57 | SNAND_ID_DYMMY, |
| 58 | SNAND_ID_ADDR = SNAND_ID_DYMMY, |
| 59 | SNAND_ID_DIRECT, |
| 60 | |
| 61 | __SNAND_ID_TYPE_MAX |
| 62 | }; |
| 63 | |
| 64 | struct snand_id { |
| 65 | uint8_t type; /* enum snand_id_type */ |
| 66 | uint8_t len; |
| 67 | uint8_t id[SNAND_MAX_ID_LEN]; |
| 68 | }; |
| 69 | |
| 70 | #define SNAND_ID(_type, ...) \ |
| 71 | { .type = (_type), .id = { __VA_ARGS__ }, \ |
| 72 | .len = sizeof((uint8_t[]) { __VA_ARGS__ }) } |
| 73 | |
| 74 | struct snand_mem_org { |
| 75 | uint16_t pagesize; |
| 76 | uint16_t sparesize; |
| 77 | uint16_t pages_per_block; |
| 78 | uint16_t blocks_per_die; |
| 79 | uint16_t planes_per_die; |
| 80 | uint16_t ndies; |
| 81 | }; |
| 82 | |
| 83 | #define SNAND_MEMORG(_ps, _ss, _ppb, _bpd, _ppd, _nd) \ |
| 84 | { .pagesize = (_ps), .sparesize = (_ss), .pages_per_block = (_ppb), \ |
| 85 | .blocks_per_die = (_bpd), .planes_per_die = (_ppd), .ndies = (_nd) } |
| 86 | |
| 87 | typedef int (*snand_select_die_t)(struct mtk_snand *snf, uint32_t dieidx); |
| 88 | |
| 89 | struct snand_flash_info { |
| 90 | const char *model; |
| 91 | struct snand_id id; |
| 92 | const struct snand_mem_org memorg; |
| 93 | const struct snand_io_cap *cap_rd; |
| 94 | const struct snand_io_cap *cap_pl; |
| 95 | snand_select_die_t select_die; |
| 96 | }; |
| 97 | |
| 98 | #define SNAND_INFO(_model, _id, _memorg, _cap_rd, _cap_pl, ...) \ |
| 99 | { .model = (_model), .id = _id, .memorg = _memorg, \ |
| 100 | .cap_rd = (_cap_rd), .cap_pl = (_cap_pl), __VA_ARGS__ } |
| 101 | |
| 102 | const struct snand_flash_info *snand_flash_id_lookup(enum snand_id_type type, |
| 103 | const uint8_t *id); |
| 104 | |
| 105 | struct mtk_snand_soc_data { |
| 106 | uint16_t sector_size; |
| 107 | uint16_t max_sectors; |
| 108 | uint16_t fdm_size; |
| 109 | uint16_t fdm_ecc_size; |
| 110 | uint16_t fifo_size; |
| 111 | |
| 112 | bool bbm_swap; |
| 113 | bool empty_page_check; |
| 114 | uint32_t mastersta_mask; |
| 115 | |
| 116 | const uint8_t *spare_sizes; |
| 117 | uint32_t num_spare_size; |
developer | 17ded80 | 2021-07-06 20:48:25 +0800 | [diff] [blame] | 118 | |
| 119 | uint16_t latch_lat; |
| 120 | uint16_t sample_delay; |
developer | fd40db2 | 2021-04-29 10:08:25 +0800 | [diff] [blame] | 121 | }; |
| 122 | |
| 123 | enum mtk_ecc_regs { |
| 124 | ECC_DECDONE, |
| 125 | }; |
| 126 | |
| 127 | struct mtk_ecc_soc_data { |
| 128 | const uint8_t *ecc_caps; |
| 129 | uint32_t num_ecc_cap; |
| 130 | const uint32_t *regs; |
| 131 | uint16_t mode_shift; |
| 132 | uint8_t errnum_bits; |
| 133 | uint8_t errnum_shift; |
| 134 | }; |
| 135 | |
| 136 | struct mtk_snand { |
| 137 | struct mtk_snand_plat_dev *pdev; |
| 138 | |
| 139 | void __iomem *nfi_base; |
| 140 | void __iomem *ecc_base; |
| 141 | |
| 142 | enum mtk_snand_soc soc; |
| 143 | const struct mtk_snand_soc_data *nfi_soc; |
| 144 | const struct mtk_ecc_soc_data *ecc_soc; |
| 145 | bool snfi_quad_spi; |
| 146 | bool quad_spi_op; |
| 147 | |
| 148 | const char *model; |
| 149 | uint64_t size; |
| 150 | uint64_t die_size; |
| 151 | uint32_t erasesize; |
| 152 | uint32_t writesize; |
| 153 | uint32_t oobsize; |
| 154 | |
| 155 | uint32_t num_dies; |
| 156 | snand_select_die_t select_die; |
| 157 | |
| 158 | uint8_t opcode_rfc; |
| 159 | uint8_t opcode_pl; |
| 160 | uint8_t dummy_rfc; |
| 161 | uint8_t mode_rfc; |
| 162 | uint8_t mode_pl; |
| 163 | |
| 164 | uint32_t writesize_mask; |
| 165 | uint32_t writesize_shift; |
| 166 | uint32_t erasesize_mask; |
| 167 | uint32_t erasesize_shift; |
| 168 | uint64_t die_mask; |
| 169 | uint32_t die_shift; |
| 170 | |
| 171 | uint32_t spare_per_sector; |
| 172 | uint32_t raw_sector_size; |
| 173 | uint32_t ecc_strength; |
| 174 | uint32_t ecc_steps; |
| 175 | uint32_t ecc_bytes; |
| 176 | uint32_t ecc_parity_bits; |
| 177 | |
| 178 | uint8_t *page_cache; /* Used by read/write page */ |
| 179 | uint8_t *buf_cache; /* Used by block bad/markbad & auto_oob */ |
developer | 4da1bed | 2021-05-08 17:30:37 +0800 | [diff] [blame] | 180 | int *sect_bf; /* Used by ECC correction */ |
developer | fd40db2 | 2021-04-29 10:08:25 +0800 | [diff] [blame] | 181 | }; |
| 182 | |
| 183 | enum mtk_snand_log_category { |
| 184 | SNAND_LOG_NFI, |
| 185 | SNAND_LOG_SNFI, |
| 186 | SNAND_LOG_ECC, |
| 187 | SNAND_LOG_CHIP, |
| 188 | |
| 189 | __SNAND_LOG_CAT_MAX |
| 190 | }; |
| 191 | |
| 192 | int mtk_ecc_setup(struct mtk_snand *snf, void *fmdaddr, uint32_t max_ecc_bytes, |
| 193 | uint32_t msg_size); |
| 194 | int mtk_snand_ecc_encoder_start(struct mtk_snand *snf); |
| 195 | void mtk_snand_ecc_encoder_stop(struct mtk_snand *snf); |
| 196 | int mtk_snand_ecc_decoder_start(struct mtk_snand *snf); |
| 197 | void mtk_snand_ecc_decoder_stop(struct mtk_snand *snf); |
| 198 | int mtk_ecc_wait_decoder_done(struct mtk_snand *snf); |
developer | 4da1bed | 2021-05-08 17:30:37 +0800 | [diff] [blame] | 199 | int mtk_ecc_check_decode_error(struct mtk_snand *snf); |
| 200 | int mtk_ecc_fixup_empty_sector(struct mtk_snand *snf, uint32_t sect); |
developer | fd40db2 | 2021-04-29 10:08:25 +0800 | [diff] [blame] | 201 | |
| 202 | int mtk_snand_mac_io(struct mtk_snand *snf, const uint8_t *out, uint32_t outlen, |
| 203 | uint8_t *in, uint32_t inlen); |
| 204 | int mtk_snand_set_feature(struct mtk_snand *snf, uint32_t addr, uint32_t val); |
| 205 | |
| 206 | int mtk_snand_log(struct mtk_snand_plat_dev *pdev, |
| 207 | enum mtk_snand_log_category cat, const char *fmt, ...); |
| 208 | |
| 209 | #define snand_log_nfi(pdev, fmt, ...) \ |
| 210 | mtk_snand_log(pdev, SNAND_LOG_NFI, fmt, ##__VA_ARGS__) |
| 211 | |
| 212 | #define snand_log_snfi(pdev, fmt, ...) \ |
| 213 | mtk_snand_log(pdev, SNAND_LOG_SNFI, fmt, ##__VA_ARGS__) |
| 214 | |
| 215 | #define snand_log_ecc(pdev, fmt, ...) \ |
| 216 | mtk_snand_log(pdev, SNAND_LOG_ECC, fmt, ##__VA_ARGS__) |
| 217 | |
| 218 | #define snand_log_chip(pdev, fmt, ...) \ |
| 219 | mtk_snand_log(pdev, SNAND_LOG_CHIP, fmt, ##__VA_ARGS__) |
| 220 | |
| 221 | /* ffs64 */ |
| 222 | static inline int mtk_snand_ffs64(uint64_t x) |
| 223 | { |
| 224 | if (!x) |
| 225 | return 0; |
| 226 | |
| 227 | if (!(x & 0xffffffff)) |
| 228 | return ffs((uint32_t)(x >> 32)) + 32; |
| 229 | |
| 230 | return ffs((uint32_t)(x & 0xffffffff)); |
| 231 | } |
| 232 | |
| 233 | /* NFI dummy commands */ |
| 234 | #define NFI_CMD_DUMMY_READ 0x00 |
| 235 | #define NFI_CMD_DUMMY_WRITE 0x80 |
| 236 | |
| 237 | /* SPI-NAND opcodes */ |
| 238 | #define SNAND_CMD_RESET 0xff |
| 239 | #define SNAND_CMD_BLOCK_ERASE 0xd8 |
| 240 | #define SNAND_CMD_READ_FROM_CACHE_QUAD 0xeb |
| 241 | #define SNAND_CMD_WINBOND_SELECT_DIE 0xc2 |
| 242 | #define SNAND_CMD_READ_FROM_CACHE_DUAL 0xbb |
| 243 | #define SNAND_CMD_READID 0x9f |
| 244 | #define SNAND_CMD_READ_FROM_CACHE_X4 0x6b |
| 245 | #define SNAND_CMD_READ_FROM_CACHE_X2 0x3b |
| 246 | #define SNAND_CMD_PROGRAM_LOAD_X4 0x32 |
| 247 | #define SNAND_CMD_SET_FEATURE 0x1f |
| 248 | #define SNAND_CMD_READ_TO_CACHE 0x13 |
| 249 | #define SNAND_CMD_PROGRAM_EXECUTE 0x10 |
| 250 | #define SNAND_CMD_GET_FEATURE 0x0f |
| 251 | #define SNAND_CMD_READ_FROM_CACHE 0x0b |
| 252 | #define SNAND_CMD_WRITE_ENABLE 0x06 |
| 253 | #define SNAND_CMD_PROGRAM_LOAD 0x02 |
| 254 | |
| 255 | /* SPI-NAND feature addresses */ |
| 256 | #define SNAND_FEATURE_MICRON_DIE_ADDR 0xd0 |
| 257 | #define SNAND_MICRON_DIE_SEL_1 BIT(6) |
| 258 | |
| 259 | #define SNAND_FEATURE_STATUS_ADDR 0xc0 |
| 260 | #define SNAND_STATUS_OIP BIT(0) |
| 261 | #define SNAND_STATUS_WEL BIT(1) |
| 262 | #define SNAND_STATUS_ERASE_FAIL BIT(2) |
| 263 | #define SNAND_STATUS_PROGRAM_FAIL BIT(3) |
| 264 | |
| 265 | #define SNAND_FEATURE_CONFIG_ADDR 0xb0 |
| 266 | #define SNAND_FEATURE_QUAD_ENABLE BIT(0) |
| 267 | #define SNAND_FEATURE_ECC_EN BIT(4) |
| 268 | |
| 269 | #define SNAND_FEATURE_PROTECT_ADDR 0xa0 |
| 270 | |
| 271 | #endif /* _MTK_SNAND_DEF_H_ */ |