1 /*
2  * Copyright 2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef _FSL_ROMAPI_FLEXSPI_H_
8 #define _FSL_ROMAPI_FLEXSPI_H_
9 
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include "fsl_common.h"
13 
14 typedef struct
15 {
16     uint8_t time_100ps;  // Data valid time, in terms of 100ps
17     uint8_t delay_cells; // Data valid time, in terms of delay cells
18 } flexspi_dll_time_t;
19 
20 //!@brief FlexSPI Pad Configuration Override
21 typedef struct
22 {
23     uint8_t pu_pd_override_en;
24     uint8_t pu_pd_value;
25     uint8_t sr_config_override_en;
26     uint8_t sr_config_value;
27 } flexspi_pad_config_override_t;
28 
29 //!@brief FlexSPI LUT Sequence structure
30 typedef struct _lut_sequence
31 {
32     uint8_t seqNum; //!< Sequence Number, valid number: 1-16
33     uint8_t seqId;  //!< Sequence Index, valid number: 0-15
34     uint16_t reserved;
35 } flexspi_lut_seq_t;
36 
37 //!@brief FlexSPI Memory Configuration Block
38 typedef struct _FlexSPIConfig
39 {
40     uint32_t tag;               //!< [0x000-0x003] Tag, fixed value 0x42464346UL
41     uint32_t version;           //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix
42     uint32_t reserved0;         //!< [0x008-0x00b] Reserved for future use
43     uint8_t readSampleClkSrc;   //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3
44     uint8_t csHoldTime;         //!< [0x00d-0x00d] CS hold time, default value: 3
45     uint8_t csSetupTime;        //!< [0x00e-0x00e] CS setup time, default value: 3
46     uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For
47     //! Serial NAND, need to refer to datasheet
48     uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable
49     uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch,
50     //! Generic configuration, etc.
51     uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for
52     //! DPI/QPI/OPI switch or reset command
53     flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt
54     //! sequence number, [31:16] Reserved
55     uint32_t deviceModeArg;    //!< [0x018-0x01b] Argument/Parameter for device configuration
56     uint8_t configCmdEnable;   //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable
57     uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe
58     flexspi_lut_seq_t
59         configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq
60     uint32_t reserved1;   //!< [0x02c-0x02f] Reserved for future use
61     uint32_t configCmdArgs[3];     //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands
62     uint32_t reserved2;            //!< [0x03c-0x03f] Reserved for future use
63     uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more
64     //! details
65     uint8_t deviceType;    //!< [0x044-0x044] Device Type:  See Flash Type Definition for more details
66     uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal
67     uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot
68     //! Chapter for more details
69     uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot
70     //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH
71     uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use
72     uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1
73     uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 (unused/not applicable on RW610)
74     uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1
75     uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 (unused/not applicable on RW610)
76     flexspi_pad_config_override_t csPadSettingOverride;   //!< [0x060-0x063] CS pad setting override value
77     flexspi_pad_config_override_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value
78     flexspi_pad_config_override_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value
79     flexspi_pad_config_override_t dqsPadSettingOverride;  //!< [0x06c-0x06f] DQS pad setting override value
80     uint32_t timeoutInMs;                                 //!< [0x070-0x073] Timeout threshold for read status command
81     uint32_t commandInterval;                             //!< [0x074-0x077] CS deselect interval between two commands
82     flexspi_dll_time_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B
83     uint16_t busyOffset;                 //!< [0x07c-0x07d] Busy offset, valid value: 0-31
84     uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 -
85     //! busy flag is 0 when flash device is busy
86     uint32_t lookupTable[64];           //!< [0x080-0x17f] Lookup table holds Flash command sequences
87     flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences
88     uint32_t dll0CrVal;                 //!> [0x1b0-0x1b3] Customizable DLL0CR setting
89     uint32_t dll1CrVal;                 //!> [0x1b4-0x1b7] Customizable DLL1CR setting
90     uint32_t reserved4[2];              //!< [0x1b8-0x1bf] Reserved for future use
91 } flexspi_mem_config_t;
92 
93 typedef enum _FlexSPIOperationType
94 {
95     kFlexSpiOperation_Command, //!< FlexSPI operation: Only command, both TX and
96     //! RX buffer are ignored.
97     kFlexSpiOperation_Config, //!< FlexSPI operation: Configure device mode, the
98     //! TX FIFO size is fixed in LUT.
99     kFlexSpiOperation_Write, //!< FlexSPI operation: Write,  only TX buffer is
100     //! effective
101     kFlexSpiOperation_Read, //!< FlexSPI operation: Read, only Rx Buffer is
102     //! effective.
103     kFlexSpiOperation_End = kFlexSpiOperation_Read,
104 } flexspi_operation_t;
105 
106 //!@brief FlexSPI Transfer Context
107 typedef struct _FlexSpiXfer
108 {
109     flexspi_operation_t operation; //!< FlexSPI operation
110     uint32_t baseAddress;          //!< FlexSPI operation base address
111     uint32_t seqId;                //!< Sequence Id
112     uint32_t seqNum;               //!< Sequence Number
113     bool isParallelModeEnable;     //!< Is a parallel transfer
114     bool keepState;                //!< Keep the data in the FIFO before triggering the operation
115     uint32_t *txBuffer;            //!< Tx buffer
116     uint32_t txSize;               //!< Tx size in bytes
117     uint32_t *rxBuffer;            //!< Rx buffer
118     uint32_t rxSize;               //!< Rx size in bytes
119 } flexspi_xfer_t;
120 
121 /*
122  *  Serial NOR configuration block
123  */
124 typedef struct _flexspi_nor_config
125 {
126     flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI
127     uint32_t pageSize;              //!< Page size of Serial NOR
128     uint32_t sectorSize;            //!< Sector size of Serial NOR
129     uint8_t ipcmdSerialClkFreq;     //!< Clock frequency for IP command
130     uint8_t isUniformBlockSize;     //!< Sector/Block size is the same
131     uint8_t isDataOrderSwapped;     //!< Data order (D0, D1, D2, D3) is swapped (D1,D0, D3, D2)
132     uint8_t reserved0[1];           //!< Reserved for future use
133     uint8_t serialNorType;          //!< Serial NOR Flash type: 0/1/2/3
134     uint8_t needExitNoCmdMode;      //!< Need to exit NoCmd mode before other IP command
135     uint8_t halfClkForNonReadCmd;   //!< Half the Serial Clock for non-read command: true/false
136     uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP commmand execution
137     uint32_t blockSize;             //!< Block size
138     uint32_t flashStateCtx;         //!< Flash State Context
139     uint32_t reserve2[10];          //!< Reserved for future use
140 } flexspi_nor_config_t;
141 
142 /*
143  * Serial NOR Configuration Option
144  */
145 typedef struct _serial_nor_config_option
146 {
147     union
148     {
149         struct
150         {
151             uint32_t max_freq : 4;          //!< Maximum supported Frequency
152             uint32_t misc_mode : 4;         //!< miscellaneous mode
153             uint32_t quad_mode_setting : 4; //!< Quad mode setting
154             uint32_t cmd_pads : 4;          //!< Command pads
155             uint32_t query_pads : 4;        //!< SFDP read pads
156             uint32_t device_type : 4;       //!< Device type
157             uint32_t option_size : 4;       //!< Option size, in terms of uint32_t, size = (option_size + 1) * 4
158             uint32_t tag : 4;               //!< Tag, must be 0x0C
159         } B;
160         uint32_t U;
161     } option0;
162 
163     union
164     {
165         struct
166         {
167             uint32_t dummy_cycles : 8;     //!< Dummy cycles before read
168             uint32_t status_override : 8;  //!< Override status register value during device mode configuration
169             uint32_t pinmux_group : 4;     //!< The pinmux group selection
170             uint32_t dqs_pinmux_group : 4; //!< The DQS Pinmux Group Selection
171             uint32_t drive_strength : 4;   //!< The Drive Strength of FlexSPI Pads
172             uint32_t flash_connection : 4; //!< Flash connection option: 0 - Single Flash connected to port A, 1 -
173             //! Parallel mode, 2 - Single Flash connected to Port B
174         } B;
175         uint32_t U;
176     } option1;
177 
178 } serial_nor_config_option_t;
179 
180 //!@brief FLEXSPI Flash driver API Interface
181 typedef struct
182 {
183     uint32_t version;
184     status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
185     status_t (*wait_busy)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address, bool keepState);
186     status_t (*page_program)(
187         uint32_t instance, flexspi_nor_config_t *config, uint32_t dstAddr, const uint32_t *src, bool keepState);
188     status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
189     status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
190     status_t (*erase_sector)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
191     status_t (*erase_block)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
192     status_t (*read)(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);
193     void (*config_clock)(uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode);
194     status_t (*set_clock_source)(uint32_t clockSrc);
195     status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
196     void (*hw_reset)(uint32_t instance, uint32_t reset_logic);
197     status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
198     status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);
199     status_t (*partial_program)(uint32_t instance,
200                                 flexspi_nor_config_t *config,
201                                 uint32_t dstAddr,
202                                 const uint32_t *src,
203                                 uint32_t length,
204                                 bool keepState);
205 } flexspi_nor_flash_driver_t;
206 
207 /*******************************************************************************
208  * API
209  ******************************************************************************/
210 
211 #if defined(__cplusplus)
212 extern "C" {
213 #endif
214 
215 uint32_t flexspi_nor_flash_version(void);
216 
217 //!@brief Initialize Serial NOR devices via FlexSPI
218 status_t flexspi_nor_flash_init(uint32_t instance, flexspi_nor_config_t *config);
219 
220 //!@brief Wait until Serial NOR device is idle
221 status_t flexspi_nor_flash_wait_busy(uint32_t instance, flexspi_nor_config_t *config, uint32_t address, bool keepState);
222 //!@brief Program data to Serial NOR via FlexSPI
223 status_t flexspi_nor_flash_page_program(
224     uint32_t instance, flexspi_nor_config_t *config, uint32_t dstAddr, const uint32_t *src, bool keepState);
225 
226 //!@brief Erase all the Serial NOR devices connected on FlexSPI
227 status_t flexspi_nor_flash_erase_all(uint32_t instance, flexspi_nor_config_t *config);
228 
229 //!@brief Erase Flash Region specified by address and length
230 status_t flexspi_nor_flash_erase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
231 
232 //!@brief Erase one sector specified by address
233 status_t flexspi_nor_flash_erase_sector(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
234 
235 //!@brief Erase one block specified by address
236 status_t flexspi_nor_flash_erase_block(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
237 
238 //!@brief Read data from Serial NOR
239 status_t flexspi_nor_flash_read(
240     uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);
241 
242 //!@brief Configure Clock for FlexSPI
243 void flexspi_clock_config(uint32_t instance, uint32_t freq, uint32_t sampleClkMode);
244 
245 //!@brief Set the clock source for FlexSPI NOR
246 status_t flexspi_nor_set_clock_source(uint32_t clockSource);
247 
248 //!@brief Get FlexSPI NOR Configuration Block based on specified option
249 status_t flexspi_nor_get_config(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
250 
251 //!@brief Reset FlexSPI NOR Flash
252 void flexspi_nor_hw_reset(uint32_t instance, uint32_t reset_logic);
253 
254 //!@brief Perform FlexSPI command
255 status_t flexspi_command_xfer(uint32_t instance, flexspi_xfer_t *xfer);
256 
257 //!@brief Configure FlexSPI Lookup table
258 status_t flexspi_update_lut(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);
259 
260 //!@brief Partially Program data to Serial NOR via FlexSPI
261 status_t flexspi_nor_flash_partial_program(uint32_t instance,
262                                            flexspi_nor_config_t *config,
263                                            uint32_t dstAddr,
264                                            const uint32_t *src,
265                                            uint32_t length,
266                                            bool keepState);
267 
268 #endif /* _FSL_ROMAPI_FLEXSPI_H_ */
269