1 /*
2  * Copyright (c) 2018-2020 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  * \file gfc100_eflash_drv.h
19  *
20  * \brief Generic driver for GFC100 flash controller
21  */
22 
23 #ifndef __GFC100_FLASH_DRV_H__
24 #define __GFC100_FLASH_DRV_H__
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include <stdint.h>
31 #include <stdbool.h>
32 
33 enum gfc100_error_t {
34     GFC100_ERROR_NONE = 0U,          /*!< No error */
35     GFC100_ERROR_NOT_INITED,         /*!< Device not inited error */
36     GFC100_ERROR_CMD_PENDING,        /*!< Previous cmd is still pending error */
37     GFC100_ERROR_INVALID_WORD_WIDTH, /*!< Invalid word width error */
38     GFC100_ERROR_INVALID_PARAM,      /*!< Invalid parameter error */
39     GFC100_ERROR_OUT_OF_RANGE,       /*!< Flash address out of range error */
40     GFC100_ERROR_CMD_FAIL,           /*!< Command failed error */
41     GFC100_ERROR_UNALIGNED_PARAM     /*!< Unaligned parameter error */
42 };
43 
44 /** GFC100 Flash controller device configuration structure */
45 struct gfc100_eflash_dev_cfg_t {
46     const uint32_t base;  /*!< GFC100 base address */
47 };
48 
49 /** GFC100 Flash controller device data structure */
50 struct gfc100_eflash_dev_data_t {
51     bool is_initialized;     /*!< Indicates if the device is initialized */
52     uint32_t flash_size;     /*!< Size of the flash area */
53 };
54 
55 /** GFC100 Flash controller device structure */
56 struct gfc100_eflash_dev_t {
57     const struct gfc100_eflash_dev_cfg_t* const cfg;
58                                                     /*!< GFC100 configuration */
59     struct gfc100_eflash_dev_data_t* const data;    /*!< GFC100 data */
60 };
61 
62 enum gfc100_erase_type_t {
63     GFC100_ERASE_PAGE = 0U,        /*!< Erase 1 page */
64     GFC100_MASS_ERASE_MAIN_AREA,   /*!< Erase main area */
65     GFC100_MASS_ERASE_ALL          /*!< Erase main + extended area */
66 };
67 
68 /**
69  * \brief Initializes GFC100 flash controller
70  *
71  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
72  * \param[in] sys_clk  System clock in Hz
73  *
74  * \note This API needs to be called prior to any other APIs.
75  * \note For better performance, this function doesn't check if dev is NULL
76  */
77 void gfc100_eflash_init(struct gfc100_eflash_dev_t *dev, uint32_t sys_clk);
78 
79 /**
80  * \brief Reads data from the flash in a blocking call
81  *
82  * \param[in]     dev   GFC100 device struct \ref gfc100_eflash_dev_t
83  * \param[in]     addr  Address to read data from the flash
84  * \param[out]    data  Pointer to store data read from the flash
85  * \param[in,out] len   Number of bytes to read, number of bytes read
86  *
87  * \return Returns error code as specified in \ref gfc100_error_t
88  *
89  * \note This API reads the flash memory by sending read commands with the
90  *       controller, but reading through the AHB directly mapped address gives
91  *       better performance (if flash is mapped for direct read).
92  * \note Addr is expected to be within the [0x0 - Flash size] range
93  * \note For better performance, this function doesn't check if dev is NULL
94  * \note Addr, data and len can have any aligment
95  */
96 enum gfc100_error_t gfc100_eflash_read(struct gfc100_eflash_dev_t *dev,
97                                       uint32_t addr, void *data, uint32_t *len);
98 
99 /**
100  * \brief Writes data to the flash in a blocking call
101  *
102  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
103  * \param[in] addr     Address to write data to the flash
104  * \param[in] data     Pointer to the data to be written
105  * \param[in] len      Number of bytes to write
106  *
107  * \return Returns error code as specified in \ref gfc100_error_t
108  *
109  * \note Flash area needs to be pre-erased before writing to it
110  * \note Addr is expected to be within the [0x0 - Flash size] range
111  * \note For better performance, this function doesn't check if dev is NULL
112  * \note Addr and len must be 4 bytes aligned
113  */
114 enum gfc100_error_t gfc100_eflash_write(struct gfc100_eflash_dev_t *dev,
115                                         uint32_t addr, const void *data,
116                                         uint32_t *len);
117 
118 /**
119  * \brief Writes data to the flash in a blocking call
120  *
121  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
122  * \param[in] addr     Address to write data to the flash
123  * \param[in] data     Pointer to the data to be written
124  * \param[in] len      Number of bytes to write
125  *
126  * \return Returns error code as specified in \ref gfc100_error_t
127  *
128  * \note This API uses the Row Write command by sending the commands
129  *       continuously so the controller won't close the transfer and start a new
130  *       for the next 4 bytes.This gives much better performance
131  *       than simple Write command, so this API is preferred to use if many
132  *       bytes needs to be written to the flash.
133  * \note Addr is expected to be within the [0x0 - Flash size] range
134  * \note For better performance, this function doesn't check if dev is NULL
135  * \note Addr and len must be 4 bytes aligned
136  */
137 enum gfc100_error_t gfc100_eflash_row_write(struct gfc100_eflash_dev_t *dev,
138                                            uint32_t addr, const void *data,
139                                            uint32_t *len);
140 
141 /**
142  * \brief Erases the flash
143  *
144  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
145  * \param[in] addr     Address of the page to erase
146  * \param[in] erase    Erase type \ref gfc100_erase_type_t
147  *
148  * \return Returns error code as specified in \ref gfc100_error_t
149  *
150  * \note For better performance, this function doesn't check if dev is NULL
151  * \note Addr is expected to be within the [0x0 - Flash size] range
152  * \note Addr is only used for page erase, and is automatically aligned
153  *       to page size.
154  */
155 enum gfc100_error_t gfc100_eflash_erase(struct gfc100_eflash_dev_t *dev,
156                                        uint32_t addr,
157                                        enum gfc100_erase_type_t erase);
158 
159 /**
160  * \brief Checks if controller is locked
161  *
162  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
163  *
164  * \return Returns true is controller is locked, false otherwise
165  *
166  * \note For better performance, this function doesn't check if dev is NULL
167  * \note This can be used by the software to detect why the APB request
168  *       is being held up.
169  */
170 bool gfc100_is_controller_locked(struct gfc100_eflash_dev_t *dev);
171 
172 /**
173  * \brief Gets flash memory size in bytes
174  *
175  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
176  *
177  * \return Returns the size of the flash memory in bytes
178  *
179  * \note For better performance, this function doesn't check if dev is NULL
180  */
181 uint32_t gfc100_get_eflash_size(struct gfc100_eflash_dev_t *dev);
182 
183 /**
184  * \brief Gets flash page size in bytes
185  *
186  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
187  *
188  * \return Returns the page size of the flash memory in bytes
189  *
190  * \note For better performance, this function doesn't check if dev is NULL
191  */
192 uint32_t gfc100_get_eflash_page_size(struct gfc100_eflash_dev_t *dev);
193 
194 /**
195  * \brief Gets number of info pages
196  *
197  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
198  *
199  * \return Returns the number of info pages from the extended area
200  *
201  * \note For better performance, this function doesn't check if dev is NULL.
202  */
203 uint32_t gfc100_get_num_of_info_pages(struct gfc100_eflash_dev_t *dev);
204 
205 /**
206  * \brief Gets process specific error bits
207  *
208  * \param[in] dev      GFC100 device struct \ref gfc100_eflash_dev_t
209  *
210  * \return Returns the error bits specified by the process specific part
211  *         of the controller.
212  *
213  * \note For better performance, this function doesn't check if dev is NULL.
214  * \note Can be used for debug purposes.
215  */
216 uint32_t gfc100_get_proc_spec_error(struct gfc100_eflash_dev_t *dev);
217 
218 #ifdef __cplusplus
219 }
220 #endif
221 
222 #endif  /* __GFC100_FLASH_DRV_H__ */
223 
224