1 /*
2  * Copyright (c) 2018-2019 Arm Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * This library provides functions to control the MT25QL256ABA-1EW7-OSIT flash
19  * memory from Micron and should work for similar devices from the same vendor.
20  */
21 
22 #ifndef __MT25QL_H__
23 #define __MT25QL_H__
24 
25 #include "qspi_ip6514e_drv.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /**
32  * \brief MT25QL Flash Memory documentation defined values.
33  */
34 #define FLASH_PAGE_SIZE     (256U)          /* 256B */
35 #define SUBSECTOR_4KB       (0x00001000U)   /* 4KB */
36 #define SUBSECTOR_32KB      (0x00008000U)   /* 32KB */
37 #define SECTOR_64KB         (0x00010000U)   /* 64KB */
38 #define ADDR_BYTES          (3U)
39 
40 enum mt25ql_error_t {
41     MT25QL_ERR_NONE               = QSPI_IP6514E_ERR_NONE,
42     MT25QL_ERR_WRONG_ARGUMENT     = QSPI_IP6514E_ERR_WRONG_ARGUMENT,
43     MT25QL_ERR_CTRL_NOT_DISABLED  = QSPI_IP6514E_ERR_CONTROLLER_NOT_DISABLED,
44     MT25QL_ERR_READ_IN_PROGRESS   = QSPI_IP6514E_ERR_READ_IN_PROGRESS,
45     MT25QL_ERR_WRITE_IN_PROGRESS  = QSPI_IP6514E_ERR_WRITE_IN_PROGRESS,
46     MT25QL_ERR_ADDR_NOT_ALIGNED,
47     MT25QL_ERR_NOT_INITED,
48     MT25QL_ERR_ADDR_TOO_BIG,
49 };
50 
51 enum mt25ql_erase_t {
52     MT25QL_ERASE_ALL_FLASH     = 0U,             /*!< Erase all flash */
53     MT25QL_ERASE_SUBSECTOR_4K  = SUBSECTOR_4KB,  /*!< Erase a 4 KB subsector */
54     MT25QL_ERASE_SUBSECTOR_32K = SUBSECTOR_32KB, /*!< Erase a 32 KB subsector */
55     MT25QL_ERASE_SECTOR_64K    = SECTOR_64KB,    /*!< Erase a sector (64 KB) */
56 };
57 
58 enum mt25ql_functional_state_t {
59     MT25QL_FUNC_STATE_NOT_INITED    = 0U,
60         /*!< QSPI Flash controller is not initialized, only direct read
61          * is guaranteed to be working
62          */
63     MT25QL_FUNC_STATE_DEFAULT       = 1U,
64         /*!< The QSPI Flash controller and memory is in default state,
65          *   using basic read/write commands
66          */
67     MT25QL_FUNC_STATE_FAST          = 2U,
68         /*!< The QSPI Flash controller and memory is configured to operate in
69          *   single SPI mode and fast Flash commands could be used for read and
70          *   program operations.
71          */
72     MT25QL_FUNC_STATE_QUAD_FAST     = 3U,
73         /*!< The QSPI Flash controller and memory is configured to operate in
74          *   Quad SPI mode and fast Flash commands could be used for read and
75          *   program operations.
76          */
77 };
78 
79 struct mt25ql_config_state_t {
80     enum mt25ql_functional_state_t func_state;
81     /*!< Functional state id */
82     enum qspi_ip6514e_spi_mode_t spi_mode;
83     /*!< SPI mode for the current functional state */
84     uint8_t opcode_read;
85     /*!< Read opcode for the current functional state */
86     uint8_t opcode_write;
87     /*!< Write opcode for the current functional state */
88     uint32_t dummy_cycles_read;
89     /*!< Dummy cycles for the read command for the current functional state */
90     uint32_t dummy_cycles_write;
91     /*!< Dummy cycles for the write command for the current functional state */
92 };
93 
94 struct mt25ql_dev_t {
95     struct qspi_ip6514e_dev_t *controller;
96         /*!< QSPI Flash controller. */
97     uint32_t direct_access_start_addr;
98         /*!< AHB address to directly access the contents of the Flash memory
99          *   through the QSPI Controller.
100          */
101     uint32_t baud_rate_div;
102         /*!< Clock divisor that will be used to configure the QSPI Flash
103          *   Controller to access the Flash memory. The clock which frequency is
104          *   divived is the one linked to the QSPI Flash controller. It can only
105          *   be an even number between 2 and 32 (both included). It needs to be
106          *   high enough to support the Quad Output Fast Read command with 8
107          *   dummy cycles and the Quad Input Fast Program with 0 dummy cycles.
108          */
109     uint32_t size; /*!< Total size of the MT25QL Flash memory */
110     struct mt25ql_config_state_t config_state;
111         /*!< Configured functional state (with parameter settings) of the
112          *   QSPI Flash controller and memory.
113          */
114 
115 };
116 
117 /**
118  * \brief Change configuration of the QSPI Flash controller and MT25QL memory
119  *
120  *        Changes the configuration of the QSPI Flash controller and MT25QL
121  *        Flash memory to operate in the specified SPI mode and to use the
122  *        appropriate Flash commands for read and program operations.
123  *        It also sets:
124  *          + The number of dummy cycles for each operation
125  *          + The bytes per page constant to 256 (MT25QL Flash specific)
126  *          + The number of address bytes to 3
127  *
128  * \param[in] dev       Pointer to MT25QL device structure \ref mt25ql_dev_t
129  * \param[in] f_state   Functional state to be set on flash controller
130  *                      and device \ref mt25ql_functional_state_t
131  *
132  * \return Return error code as specified in \ref mt25ql_error_t
133  *
134  * \note This function assumes that the Flash memory device and the QSPI Flash
135  *       controller operates with the same SPI protocol. This function will fail
136  *       if the Flash device is in a different configuration.
137  */
138 enum mt25ql_error_t mt25ql_config_mode(struct mt25ql_dev_t* dev,
139                                        enum mt25ql_functional_state_t f_state);
140 
141 /**
142  * \brief Restore the QSPI Flash controller and MT25QL to reset state.
143  *
144  * \param[in] dev     Pointer to MT25QL device structure \ref mt25ql_dev_t
145  *
146  * \return Return error code as specified in \ref mt25ql_error_t
147  *
148  * \note This function assumes that the Flash memory device and the QSPI Flash
149  *       controller operates with the same SPI protocol. This function will fail
150  *       if the Flash device is in a different configuration.
151  */
152 enum mt25ql_error_t mt25ql_restore_reset_state(struct mt25ql_dev_t* dev);
153 
154 /**
155  * \brief Read bytes from the flash memory (direct access)
156  *
157  * \param[in]  dev   Pointer to MT25QL device structure \ref mt25ql_dev_t
158  * \param[in]  addr  Flash memory address for the read operation
159  * \param[out] data  Pointer where len bytes read from the flash memory will be
160  *                   written to
161  * \param[in]  len   Number of bytes to read
162  *
163  * \return Return error code as specified in \ref mt25ql_error_t
164  *
165  * \note This function will use direct access to read from the Flash memory. It
166  *       can be used to access above the direct accessible memory zone if
167  *       not all the AHB address wires are connected.
168  * \note The address given should be the address of the data inside the flash
169  *       memory. To read the first byte inside the memory, use 0x00000000.
170  */
171 enum mt25ql_error_t mt25ql_direct_read(struct mt25ql_dev_t* dev,
172                                        uint32_t addr,
173                                        void *data,
174                                        uint32_t len);
175 
176 /**
177  * \brief Write bytes in the flash memory, at a location where data has already
178  *        been erased (direct access)
179  *
180  * \param[in] dev   Pointer to MT25QL device structure \ref mt25ql_dev_t
181  * \param[in] addr  Flash memory address for the write operation
182  * \param[in] data  Pointer to the len bytes that will be written to the flash
183  *                  memory
184  * \param[in] len   Number of bytes to write
185  *
186  * \return Return error code as specified in \ref mt25ql_error_t
187  *
188  * \note This function will use direct access to write to the Flash memory. It
189  *       can be used to access outside of the direct accessible memory zone if
190  *       not all the AHB address wires are connected.
191  * \note The address given should be the address of the data inside the flash
192  *       memory. To write the first byte inside the memory, use 0x00000000.
193  * \note Writing bytes in the flash memory clear them from 1 to 0, for that
194  *       matter the location where data is written needs to be erased
195  *       beforehand.
196  */
197 enum mt25ql_error_t mt25ql_direct_write(struct mt25ql_dev_t* dev,
198                                         uint32_t addr,
199                                         const void *data,
200                                         uint32_t len);
201 
202 /**
203  * \brief Read bytes from the flash memory (using Flash commands)
204  *
205  * \param[in]  dev   Pointer to MT25QL device structure \ref mt25ql_dev_t
206  * \param[in]  addr  Flash memory address for the read operation
207  * \param[out] data  Pointer where len bytes read from the flash memory will be
208  *                   written to
209  * \param[in]  len   Number of bytes to read
210  *
211  * \return Return error code as specified in \ref mt25ql_error_t
212  *
213  * \note This function will use the Software Triggered Instruction Generator to
214  *       read from the Flash memory using Flash commands.
215  * \note The address given should be the address of the data inside the flash
216  *       memory. To read the first byte inside the memory, use 0x00000000.
217  */
218 enum mt25ql_error_t mt25ql_command_read(struct mt25ql_dev_t* dev,
219                                         uint32_t addr,
220                                         void *data,
221                                         uint32_t len);
222 
223 /**
224  * \brief Write bytes in the flash memory, at a location where data has already
225  *        been erased (using Flash commands)
226  *
227  * \param[in] dev   Pointer to MT25QL device structure \ref mt25ql_dev_t
228  * \param[in] addr  Flash memory address for the write operation
229  * \param[in] data  Pointer to the len bytes that will be written to the flash
230  *                  memory
231  * \param[in] len   Number of bytes to write
232  *
233  * \return Return error code as specified in \ref mt25ql_error_t
234  *
235  * \note This function will use the Software Triggered Instruction Generator to
236  *       write to the Flash memory using Flash commands.
237  * \note The address given should be the address of the data inside the flash
238  *       memory. To write the first byte inside the memory, use 0x00000000.
239  * \note Writing bytes in the flash memory clear them from 1 to 0, for that
240  *       matter the location where data is written needs to be erased
241  *       beforehand.
242  */
243 enum mt25ql_error_t mt25ql_command_write(struct mt25ql_dev_t* dev,
244                                          uint32_t addr,
245                                          const void *data,
246                                          uint32_t len);
247 
248 /**
249  * \brief Erase all flash memory, a sector (64 KiB) or a subsector
250  *        (32 KiB or 4 KiB)
251  *
252  * \param[in] dev        Pointer to MT25QL device structure \ref mt25ql_dev_t
253  * \param[in] addr       Address where to erase in the flash memory
254  * \param[in] erase_type Type of what to erase at the specified address:
255  *                         * whole flash memory
256  *                         * a subsector (4 KiB or 32 KiB)
257  *                         * a sector (64 KiB)
258  * \return Return error code as specified in \ref mt25ql_error_t
259  *
260  * \note The address need to be aligned with the size of what is erased or 0 if
261  *       all flash memory is to be erased.
262  */
263 enum mt25ql_error_t mt25ql_erase(struct mt25ql_dev_t* dev,
264                                  uint32_t addr,
265                                  enum mt25ql_erase_t erase_type);
266 
267 #ifdef __cplusplus
268 }
269 #endif
270 
271 #endif /* __MT25QL_H__ */
272