1 /* 2 * Copyright (C) 2017-2024 Alibaba Group Holding Limited 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 /****************************************************************************** 20 * @file spinand.h 21 * @brief header file for spinand driver 22 * @version V1.0 23 * @date 17. Aug 2017 24 * @model spinand 25 ******************************************************************************/ 26 #ifndef _DRV_NANDFLASH_H_ 27 #define _DRV_NANDFLASH_H_ 28 29 30 #include <stdint.h> 31 #include <drv/gpio.h> 32 #include <drv/qspi.h> 33 #include <drv/common.h> 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 #define SPINAND_DEF_SPEED (1000000) 40 #define SPIANND_DEF_MAX_WAIT_TIME (1000) ///< max wait time in ms 41 42 typedef union { 43 csi_qspi_t qspi; ///< hold qspi object 44 } csi_nand_spi_qspi_t; 45 46 47 typedef struct { 48 uint32_t target; ///< target in chip 49 uint32_t lun; ///< lun in target 50 uint32_t plane; ///< plane number in lun 51 uint32_t block; ///< block index in lun 52 uint32_t page; ///< page index in lun 53 uint32_t offset; ///< column offset within page 54 }csi_nand_pos_t; 55 56 typedef enum{ 57 SPI_MEM_NODATA, ///< no data portion 58 SPI_MEM_DATA_IN, ///< read data 59 SPI_MEM_DATA_OUT ///< write data 60 }csi_spi_mem_dir_t; 61 62 typedef struct{ 63 64 struct{ 65 uint8_t buswidth; ///< cmd buswidth 66 uint8_t opcode; ///< cmd code 67 }cmd; 68 69 struct { 70 uint8_t buswidth; ///< addr buswidth 71 uint8_t nbytes; ///< bytes of addr 72 uint64_t val; ///< addr value 73 }addr; 74 75 struct { 76 uint8_t nbytes; ///< dummy bytes 77 uint8_t buswidth; ///< bus width 78 }dummy; 79 80 81 struct { 82 uint8_t buswidth; ///< data buswidth 83 uint32_t nbytes; ///< data len 84 csi_spi_mem_dir_t dir; ///< data xfer dir 85 union{ 86 void* in; ///< read data buf ptr 87 void* out; ///< write datat buf ptr 88 }buf; 89 }data; 90 91 }spi_mem_op_t; 92 93 typedef struct { 94 const uint8_t *id; ///< point to chip id array 95 const uint8_t len; ///< id length 96 }csi_spinand_id_t; 97 98 typedef struct { 99 uint8_t id[4]; ///< id data 100 uint8_t len; ///< id length 101 }csi_nand_id_t; 102 103 104 typedef struct{ 105 uint16_t strength; ///< number of hw-ecc engine bits 106 uint16_t step_size; ///< corect size by ecc per-step 107 }csi_nand_ecc_req_t; 108 109 typedef struct { 110 uint32_t bits_per_cell; ///< bit per-cell 111 uint32_t pagesize; ///< page size 112 uint32_t oobsize; ///< spare area size 113 uint32_t pages_per_eraseblock; ///< pages per block 114 uint32_t eraseblocks_per_lun; ///< blocks per lun(logic unit number== max block index ) 115 uint32_t max_bad_eraseblocks_per_lun; ///< max bad blocks per lun 116 uint32_t planes_per_lun; ///< planes per-lun 117 uint32_t luns_per_target; ///< luns per die 118 uint32_t ntargets; ///< target index 119 }csi_nand_mem_layout_t; 120 121 122 123 typedef struct { 124 char *model; ///< chip name of vendor 125 uint32_t flags; ///< chip-specific feature bits group 126 csi_spinand_id_t devid; ///< devid of chip 127 csi_nand_mem_layout_t memorg; ///< mem layout of chip 128 csi_nand_ecc_req_t eccreq; ///< ecc capabilty of chip 129 csi_error_t (*select_target)(void *spinand, uint32_t target); ///< select target 130 csi_error_t (*check_ecc_status)(void *spinand,uint8_t status); ///< check vendor specific ecc status 131 }csi_spinand_info_t; 132 133 134 typedef struct { 135 csi_error_t (*init) (void *spinand); ///< vendor chip inition 136 void (*uninit) (void *spinand); ///< vendor chip uninition 137 }csi_spinand_manufacturer_ops_t; 138 139 typedef struct { 140 uint8_t id; ///< vendor id 141 char *name; ///< vendor name 142 const csi_spinand_info_t *chips; ///< vendor chip param 143 uint32_t nchips; ///< chips number supported 144 const csi_spinand_manufacturer_ops_t *ops; ///< vendor specific operations 145 }csi_spinand_manufacturer_t; 146 147 148 typedef struct { 149 char *model_name; ///< name of nand-device module 150 uint16_t page_size; ///< page-size of nand-device 151 uint16_t oob_size; ///< oob-size(spare size) of nand-device 152 uint16_t pages_per_block; ///< pages-per-block 153 uint16_t max_bad_blocks; ///< max possible bad blocks of nand-device 154 uint32_t total_blocks; ///< total blocks of nand-device 155 }csi_spinand_dev_params_t; 156 157 typedef struct 158 { 159 void *xfer_buf; ///< point to xfer data buf 160 uint32_t xfer_buf_len; ///< length of xfer buf ,count in byte 161 uint16_t rxfer_copy_offset; ///< copy offset from word-aligned buf 162 uint16_t rxfer_origin_len; ///< copy length from word-aligned buf 163 }csi_xfer_data_buf_t; 164 165 166 /** 167 \brief Flash control block 168 */ 169 typedef struct { 170 #define SPINAND_SCRAT_BUF_LEN 4 ///< scratch buf len 171 csi_nand_spi_qspi_t spi_qspi; ///< Spi/qspi handle 172 uint8_t scractbuf[SPINAND_SCRAT_BUF_LEN]; ///< scracthbuf for read/write id or reg 173 uint8_t cur_target; ///< current target 174 uint16_t max_tx_size; ///< max tx op size 175 uint16_t max_rx_size; ///< max rx op size 176 csi_xfer_data_buf_t xfer; ///< xfer buf 177 csi_spinand_info_t *chip_info; ///< Point to vendor private feature struct 178 csi_spinand_manufacturer_t *maf; ///< point to manufacture 179 void (*spi_cs_callback)(csi_gpio_pin_state_t value); ///< gpio chip select for spi or qspi 180 csi_error_t (*spi_mem)(void *spinand,spi_mem_op_t *op); ///< spi-mem op function 181 void *priv; ///< User private param 182 } csi_spinand_t; 183 184 typedef enum { 185 XFER_CPU_POLLING, ///< transfer by qspi with cpu polling mode 186 XFER_DMA, ///< transfer by qspi with external dma engine 187 XFER_INTR, ///< transfer by qspi with cpu-interrut 188 }csi_spinand_xfer_t; 189 190 /** 191 \brief Initialize NANDFLASH with qspi controler and probe flash device 192 \param[in] spinand NANDFLASH handle 193 \param[in] qspi_idx QSPI controler index 194 \param[in] spi_cs_callback GPIO info for chip select,if NULL, not use gpio cs 195 \return Error code 196 */ 197 csi_error_t csi_spinand_qspi_init(csi_spinand_t *spinand, uint32_t qspi_idx,void *gpio_cs_callback); 198 199 /** 200 \brief De-initialize NANDFLASH Interface based on spi controler. stops operation and releases the software resources used by the interface 201 \param[in] spinand NANDFLASH handle to operate 202 \return Error code 203 */ 204 void csi_spinand_qspi_uninit(csi_spinand_t *spinand); 205 206 /** 207 \brief set xfer mode 208 \param[in] spinand NANDFLASH handle to operate 209 \param[in] xfer_mode please ref csi_spinand_xfer_t 210 \return Error code 211 */ 212 csi_error_t csi_spinand_set_xfer_mode(csi_spinand_t *spinand,csi_spinand_xfer_t xfer_mode); 213 214 215 /** 216 \brief get flash device infomation 217 \param[in] spinand NANDFLASH handle to operate 218 \param[in] flash_info User storage to get flash vendor info after flash init 219 \return spinand_info_t 220 */ 221 222 csi_error_t csi_spinand_get_flash_info(csi_spinand_t *spinand, csi_spinand_dev_params_t *flash_info); 223 224 /** 225 \brief Read data from Flash 226 \param[in] spinand NANDFLASH handle to operate 227 \param[in] offset Data address, offset address relative to zero 228 \param[out] data Pointer to a buffer storing the data read from Flash 229 \param[in] cnt Number of data items to read 230 \return If receive successful, this function shall return the num of data witch is received successfulful 231 otherwise, the function shall return Error code 232 */ 233 int32_t csi_spinand_read(csi_spinand_t *spinand, uint64_t offset, void *data, uint32_t size); 234 235 236 /** 237 \brief Read spare data from specific page 238 \param[in] spinand NANDFLASH handle to operate 239 \param[in] page_addr page addr, address relative to zero, addr need page size aligned 240 \param[in] spare_offset offset address within the spare area of the page 241 \param[out] data Pointer to a buffer storing the data read from Flash 242 \param[in] size Number of data items to read 243 \return If receive successful, this function shall return the num of data witch is received successfully 244 otherwise, the function shall return Error code 245 */ 246 int32_t csi_spinand_read_spare_data(csi_spinand_t *spinand,uint64_t page_addr,uint32_t spare_offset,void *data, uint32_t size); 247 248 /** 249 \brief write data to Flash 250 \param[in] spinand NANDFLASH handle to operate 251 \param[in] offset Data address, offset address relative to zero 252 \param[in] data Pointer to a buffer containing the data to be programmed to Flash. 253 \param[in] size Number of data items to program 254 \return If program successful, this function shall return the num of data witch is programed successfully 255 otherwise, the function shall return Error code 256 */ 257 int32_t csi_spinand_write(csi_spinand_t *spinand, uint64_t offset, const void *data, uint64_t size); 258 259 /** 260 \brief write spare data to specific page 261 \param[in] spinand NANDFLASH handle to operate 262 \param[in] page_addr page addr, address relative to zero, addr need page size aligned 263 \param[in] spare_offset offset address within the spare area of the page 264 \param[out] data Pointer to a buffer storing the data write to Flash 265 \param[in] size Number of data items to write 266 \return If program successful, this function shall return the num of data witch is programed successfully 267 otherwise, the function shall return Error code 268 */ 269 int32_t csi_spinand_write_spare_data(csi_spinand_t *spinand,uint64_t page_addr,uint32_t spare_offset,void *data, uint32_t size); 270 271 272 /** 273 \brief Erase Flash Sector 274 \param[in] spinand NANDFLASH handle to operate 275 \param[in] offset Data address, offset address relative to zero 276 \param[in] size Length to be erased 277 \param[out] last erased block addr 278 \return Error code 279 */ 280 csi_error_t csi_spinand_erase(csi_spinand_t *spinand, uint64_t offset, uint64_t size, uint64_t *last_fail_addr); 281 282 /** 283 \brief check whether the block is bad 284 \param[in] spinand NANDFLASH handle to operate 285 \param[in] block_addr block addr (count in bytes) 286 \return 1: bad 0: not bad <0 err code 287 */ 288 289 290 int32_t csi_spinand_block_is_bad(csi_spinand_t *spinand,uint64_t block_addr); 291 292 /** 293 \brief mark block as a bad block 294 \param[in] spinand NANDFLASH handle to operate 295 \param[in] block_addr block addr (count in bytes) 296 \return Error code 297 */ 298 csi_error_t csi_spinand_block_mark_bad(csi_spinand_t *spinand, uint64_t block_addr); 299 300 /** 301 \brief reset spinand device 302 \param[in] spinand NANDFLASH handle to operate 303 \return Error code 304 */ 305 int32_t csi_spinand_reset(csi_spinand_t *spinand); 306 307 /** 308 \brief Set QSPI frequence 309 \param[in] spinand NANDFLASH handle to operate 310 \param[in] hz NANDFLASH frequence 311 \return The actual config frequency 312 */ 313 uint32_t csi_spinand_frequence(csi_spinand_t *spinand, uint32_t hz); 314 315 316 317 #ifdef __cplusplus 318 } 319 #endif 320 321 #endif /* _DRV_NANDFLASH_H_ */ 322