1 /**************************************************************************//**
2 *
3 * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date            Author       Notes
9 * 2021-1-13       Wayne        First version
10 *
11 ******************************************************************************/
12 
13 #ifndef __SPINAND_H__
14 #define __SPINAND_H__
15 
16 #include <rtthread.h>
17 
18 #include <drivers/mtd_nand.h>
19 #include "drv_spi.h"
20 #include <board.h>
21 
22 struct spinand_ops
23 {
24     rt_err_t (*block_erase)(struct rt_qspi_device *qspi, uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
25     uint8_t (*block_isbad)(struct rt_qspi_device *qspi, uint32_t u32PageAddr);
26     rt_err_t (*block_markbad)(struct rt_qspi_device *qspi,  uint32_t u32PageAddr);
27     rt_err_t (*die_select)(struct rt_qspi_device *qspi, uint8_t select_die);
28     rt_err_t (*jedecid_get)(struct rt_qspi_device *qspi, uint32_t *pu32ID);
29     rt_err_t (*program_dataload)(struct rt_qspi_device *qspi, uint8_t u8AddrH, uint8_t u8AddrL, uint8_t *pu8DataBuff,
30                                  uint32_t u32DataCount, uint8_t *pu8SpareBuff, uint32_t u32SpareCount);
31 
32     rt_err_t (*program_execute)(struct rt_qspi_device *qspi,  uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
33     rt_err_t (*read_dataload)(struct rt_qspi_device *qspi, uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
34     rt_err_t (*read_quadoutput)(struct rt_qspi_device *qspi, uint8_t u8AddrH, uint8_t u8AddrL, uint8_t *pu8DataBuff, uint32_t u32DataCount);
35 };
36 typedef struct spinand_ops *nu_spinand_ops_t;
37 
38 #define SPINAND_FLASH_JEDECID              g_spinandflash_dev.info.u32JEDECID
39 #define SPINAND_FLASH_PAGE_SIZE            g_spinandflash_dev.info.u16PageSize
40 #define SPINAND_FLASH_OOB_SIZE             g_spinandflash_dev.info.u16OOBSize
41 #define SPINAND_FLASH_QUADREAD_CMDID       g_spinandflash_dev.info.u8QuadReadCmdId
42 #define SPINAND_FLASH_DUMMYBYTE            g_spinandflash_dev.info.u8DummyByte
43 #define SPINAND_FLASH_BLOCK_NUM            g_spinandflash_dev.info.u32BlockPerFlash
44 #define SPINAND_FLASH_PAGE_PER_BLOCK_NUM   g_spinandflash_dev.info.u32PagePerBlock
45 #define SPINAND_FLASH_DESCRIPTION          g_spinandflash_dev.info.szDescription
46 #define SPINAND_FLASH_MCP                  g_spinandflash_dev.info.u8IsDieSelect
47 
48 #define SPINAND_FLASH_INFO                 &g_spinandflash_dev.info
49 #define SPINAND_FLASH_QSPI                 g_spinandflash_dev.qspi_device
50 #define SPINAND_FLASH_LOCK                 &g_spinandflash_dev.lock
51 #define SPINAND_FLASH_OPS                  g_spinandflash_dev.ops
52 
53 #define SPINAND_DIE_ID0 (0)
54 #define SPINAND_DIE_ID1 (1)
55 
56 #define SPINAND_SPARE_LAYOUT_SIZE          16
57 
58 /* SPI NAND flash information */
59 struct nu_spinand_info
60 {
61     uint32_t   u32JEDECID;
62     uint16_t   u16PageSize;
63     uint16_t   u16OOBSize;
64     uint8_t    u8QuadReadCmdId;
65     uint8_t    u8ReadStatusCmdId;
66     uint8_t    u8WriteStatusCmdid;
67     uint8_t    u8StatusValue;
68     uint8_t    u8DummyByte;
69     uint32_t   u32BlockPerFlash;
70     uint32_t   u32PagePerBlock;
71     uint8_t    u8IsDieSelect;
72     const char *szDescription;
73 
74     uint8_t    au8DataLayout[SPINAND_SPARE_LAYOUT_SIZE];
75     uint8_t    au8EccLayout[SPINAND_SPARE_LAYOUT_SIZE];
76 };
77 typedef struct nu_spinand_info *nu_spinand_info_t;
78 
79 struct nu_spinand
80 {
81     struct nu_spinand_info info;
82     struct rt_qspi_device *qspi_device;
83     nu_spinand_ops_t       ops;
84     struct rt_mutex        lock;
85 };
86 typedef struct nu_spinand *nu_spinand_t;
87 
88 rt_err_t rt_hw_mtd_spinand_register(const char *device_name);
89 rt_size_t nu_qspi_transfer_message(struct rt_qspi_device  *device, struct rt_qspi_message *message);
90 rt_err_t nu_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length, void *recv_buf, rt_size_t recv_length);
91 rt_err_t nu_qspi_send(struct rt_qspi_device *device, const void *send_buf, rt_size_t length);
92 rt_err_t spinand_flash_init(struct rt_qspi_device *qspi);
93 rt_err_t spinand_jedecid_get(struct rt_qspi_device *qspi, uint32_t *pu32ID);
94 int spinand_supported_flash_size(void);
95 nu_spinand_info_t spinand_info_get(int idx);
96 
97 extern struct nu_spinand g_spinandflash_dev;
98 extern rt_uint8_t spinand_flash_data_layout[SPINAND_SPARE_LAYOUT_SIZE];
99 extern rt_uint8_t spinand_flash_ecc_layout[SPINAND_SPARE_LAYOUT_SIZE];
100 
101 #endif /* __SPINAND_H__ */
102