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