1 /*
2  * Copyright (c) 2018-2022 Arm Limited. All rights reserved.
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 #include "Driver_Flash.h"
18 #include "gfc100_eflash_drv.h"
19 #include "RTE_Device.h"
20 #include "device_cfg.h"
21 #include "device_definition.h"
22 #include "system_core_init.h"
23 #include "cmsis_driver_config.h"
24 
25 /**
26  * \file Driver_GFC100_EFlash.c
27  *
28  * \brief CMSIS Flash driver for GFC100 flash controller
29  */
30 
31 #ifndef ARG_UNUSED
32 #define ARG_UNUSED(arg)  (void)arg
33 #endif
34 
35 #ifndef ARG_NOT_USED
36 #define ARG_NOT_USED    0U
37 #endif
38 
39 /* Driver version */
40 #define ARM_FLASH_DRV_VERSION   ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
41 
42 const ARM_DRIVER_VERSION GFC100_EFlash_Driver_Version = {
43     ARM_FLASH_API_VERSION,  /* Defined in the CMSIS Flash Driver header file */
44     ARM_FLASH_DRV_VERSION
45 };
46 
47 /**
48  * Event ready values for ARM_FLASH_CAPABILITIES::event_ready
49  * \ref ARM_FLASH_CAPABILITIES
50  */
51 enum {
52     EVENT_READY_NOT_AVAILABLE = 0u,
53     EVENT_READY_AVAILABLE
54 };
55 
56 /**
57  * Data width values for ARM_FLASH_CAPABILITIES::data_width
58  * \ref ARM_FLASH_CAPABILITIES
59  */
60  enum {
61     DATA_WIDTH_8BIT   = 0u,
62     DATA_WIDTH_16BIT,
63     DATA_WIDTH_32BIT,
64     DATA_WIDTH_ENUM_SIZE
65 };
66 
67 static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = {
68     sizeof(uint8_t),
69     sizeof(uint16_t),
70     sizeof(uint32_t),
71 };
72 
73 /**
74  * Erase chip values for ARM_FLASH_CAPABILITIES::erase_chip
75  * \ref ARM_FLASH_CAPABILITIES
76  */
77 enum {
78     CHIP_ERASE_NOT_SUPPORTED = 0u,
79     CHIP_ERASE_SUPPORTED
80 };
81 
82 /** Driver Capabilities */
83 static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
84     .event_ready = EVENT_READY_NOT_AVAILABLE,
85     .data_width  = DATA_WIDTH_32BIT,
86     .erase_chip  = CHIP_ERASE_SUPPORTED
87 };
88 
89 /**
90  * \brief Flash busy values flash status  \ref ARM_FLASH_STATUS
91  */
92 enum {
93     DRIVER_STATUS_IDLE = 0u,
94     DRIVER_STATUS_BUSY
95 };
96 
97 /**
98  * \brief Flash error values flash status  \ref ARM_FLASH_STATUS
99  */
100 enum {
101     DRIVER_STATUS_NO_ERROR = 0u,
102     DRIVER_STATUS_ERROR
103 };
104 
105 /**
106  * \brief Arm Flash device structure.
107  */
108 typedef struct _FLASHx_Resources {
109     struct gfc100_eflash_dev_t* dev;  /*!< FLASH memory device structure */
110     ARM_FLASH_INFO *data;             /*!< FLASH memory device data */
111     ARM_FLASH_STATUS status;
112 } ARM_FLASHx_Resources;
113 
ARM_Flash_GetVersion(void)114 static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
115 {
116     return GFC100_EFlash_Driver_Version;
117 }
118 
ARM_Flash_GetCapabilities(void)119 static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
120 {
121     return DriverCapabilities;
122 }
123 
ARM_Flashx_Initialize(ARM_FLASHx_Resources * ARM_FLASHx_DEV,ARM_Flash_SignalEvent_t cb_event)124 static int32_t ARM_Flashx_Initialize(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
125                                      ARM_Flash_SignalEvent_t cb_event)
126 {
127     ARG_UNUSED(cb_event);
128 
129     uint32_t page_size = gfc100_get_eflash_page_size(ARM_FLASHx_DEV->dev);
130     uint32_t flash_size = gfc100_get_eflash_size(ARM_FLASHx_DEV->dev);
131 
132     /* Validate hardcoded parameters of the flash */
133     if ((ARM_FLASHx_DEV->data->page_size != page_size) ||
134         (ARM_FLASHx_DEV->data->sector_size != page_size) ||
135         (ARM_FLASHx_DEV->data->sector_count != (flash_size / page_size))) {
136         return ARM_DRIVER_ERROR_PARAMETER;
137     }
138 
139     gfc100_eflash_init(ARM_FLASHx_DEV->dev, SystemCoreClock);
140 
141     return ARM_DRIVER_OK;
142 }
143 
ARM_Flashx_Uninitialize(ARM_FLASHx_Resources * ARM_FLASHx_DEV)144 static int32_t ARM_Flashx_Uninitialize(ARM_FLASHx_Resources *ARM_FLASHx_DEV)
145 {
146     ARG_UNUSED(ARM_FLASHx_DEV);
147 
148     /* Nothing to do */
149     return ARM_DRIVER_OK;
150 }
151 
ARM_Flashx_PowerControl(ARM_FLASHx_Resources * ARM_FLASHx_DEV,ARM_POWER_STATE state)152 static int32_t ARM_Flashx_PowerControl(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
153                                        ARM_POWER_STATE state)
154 {
155     ARG_UNUSED(ARM_FLASHx_DEV);
156 
157     switch(state) {
158     case ARM_POWER_FULL:
159         /* Nothing to do */
160         return ARM_DRIVER_OK;
161     case ARM_POWER_OFF:
162     case ARM_POWER_LOW:
163         return ARM_DRIVER_ERROR_UNSUPPORTED;
164     default:
165         return ARM_DRIVER_ERROR_PARAMETER;
166     }
167 }
168 
ARM_Flashx_ReadData(ARM_FLASHx_Resources * ARM_FLASHx_DEV,uint32_t addr,void * data,uint32_t cnt)169 static int32_t ARM_Flashx_ReadData(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
170                                    uint32_t addr, void *data, uint32_t cnt)
171 {
172     enum gfc100_error_t err = GFC100_ERROR_NONE;
173     uint32_t flash_size = gfc100_get_eflash_size(ARM_FLASHx_DEV->dev);
174 
175     /* Conversion between data items and bytes */
176     cnt *= data_width_byte[DriverCapabilities.data_width];
177 
178     ARM_FLASHx_DEV->status.error = DRIVER_STATUS_NO_ERROR;
179 
180     /* Check if range is valid */
181     if ((addr + cnt) > flash_size) {
182         ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
183         return ARM_DRIVER_ERROR_PARAMETER;
184     }
185 
186     ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_BUSY;
187 
188     err = gfc100_eflash_read(ARM_FLASHx_DEV->dev, addr, data, &cnt);
189 
190     ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_IDLE;
191 
192     if(err != GFC100_ERROR_NONE) {
193         ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
194         return ARM_DRIVER_ERROR;
195     }
196 
197     /* Conversion between bytes and data items */
198     cnt /= data_width_byte[DriverCapabilities.data_width];
199 
200     return cnt;
201 }
202 
ARM_Flashx_ProgramData(ARM_FLASHx_Resources * ARM_FLASHx_DEV,uint32_t addr,const void * data,uint32_t cnt)203 static int32_t ARM_Flashx_ProgramData(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
204                                       uint32_t addr, const void *data,
205                                       uint32_t cnt)
206 {
207     enum gfc100_error_t err = GFC100_ERROR_NONE;
208 
209     /* Conversion between data items and bytes */
210     cnt *= data_width_byte[DriverCapabilities.data_width];
211 
212     ARM_FLASHx_DEV->status.error = DRIVER_STATUS_NO_ERROR;
213     ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_BUSY;
214 
215     /* Note: There is a significantly faster way to write to the flash using
216      * gfc100_eflash_row_write. It has the disadvantage that all IRQs have
217      * to be disabled, because the implementation is sensitive to timing.
218      * For applications where timing can be guaranteed this can be replaced
219      * with gfc100_eflash_row_write. For generic use, simple write is used here.
220      */
221     err = gfc100_eflash_write(ARM_FLASHx_DEV->dev, addr, data, &cnt);
222 
223     ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_IDLE;
224 
225     if(err != GFC100_ERROR_NONE) {
226         ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
227         if ((err == GFC100_ERROR_OUT_OF_RANGE) ||
228             (err == GFC100_ERROR_UNALIGNED_PARAM)) {
229             /* The native driver checks aligment and range */
230             return ARM_DRIVER_ERROR_PARAMETER;
231         }
232         return ARM_DRIVER_ERROR;
233     }
234 
235     /* Conversion between bytes and data items */
236     cnt /= data_width_byte[DriverCapabilities.data_width];
237 
238     return cnt;
239 }
240 
ARM_Flashx_EraseSector(ARM_FLASHx_Resources * ARM_FLASHx_DEV,uint32_t addr)241 static int32_t ARM_Flashx_EraseSector(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
242                                       uint32_t addr)
243 {
244     enum gfc100_error_t err = GFC100_ERROR_NONE;
245 
246     ARM_FLASHx_DEV->status.error = DRIVER_STATUS_NO_ERROR;
247     ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_BUSY;
248 
249     /* The erase function checks whether the address is within the valid flash
250      * address range, and the HW will align the address to page boundary if
251      * it is not aligned.
252      */
253     err = gfc100_eflash_erase(ARM_FLASHx_DEV->dev, addr, GFC100_ERASE_PAGE);
254 
255     ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_IDLE;
256 
257     if (err != GFC100_ERROR_NONE) {
258         ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
259         if (err == GFC100_ERROR_OUT_OF_RANGE) {
260             return ARM_DRIVER_ERROR_PARAMETER;
261         }
262         return ARM_DRIVER_ERROR;
263     }
264 
265     return ARM_DRIVER_OK;
266 }
267 
ARM_Flashx_EraseChip(ARM_FLASHx_Resources * ARM_FLASHx_DEV)268 static int32_t ARM_Flashx_EraseChip(ARM_FLASHx_Resources *ARM_FLASHx_DEV)
269 {
270     enum gfc100_error_t err = GFC100_ERROR_NONE;
271 
272     ARM_FLASHx_DEV->status.error = DRIVER_STATUS_NO_ERROR;
273     ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_BUSY;
274 
275     /* The erase function checks whether the address is aligned with
276      * the sector or subsector and checks the Flash memory boundaries.
277      */
278     err = gfc100_eflash_erase(ARM_FLASHx_DEV->dev, ARG_NOT_USED,
279                               GFC100_MASS_ERASE_MAIN_AREA);
280 
281     ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_IDLE;
282 
283     if(err != GFC100_ERROR_NONE) {
284         ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
285         return ARM_DRIVER_ERROR;
286     }
287 
288     return ARM_DRIVER_OK;
289 }
290 
291 static ARM_FLASH_STATUS
ARM_Flashx_GetStatus(ARM_FLASHx_Resources * ARM_FLASHx_DEV)292 ARM_Flashx_GetStatus(ARM_FLASHx_Resources *ARM_FLASHx_DEV)
293 {
294     return ARM_FLASHx_DEV->status;
295 }
296 
ARM_Flashx_GetInfo(ARM_FLASHx_Resources * ARM_FLASHx_DEV)297 static ARM_FLASH_INFO * ARM_Flashx_GetInfo(ARM_FLASHx_Resources *ARM_FLASHx_DEV)
298 {
299     return ARM_FLASHx_DEV->data;
300 }
301 
302 #if (RTE_EFLASH0)
303 static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
304     .sector_info    = NULL,     /* Uniform sector layout */
305     .sector_count   = (0x200000u / 0x4000u), /* 2MB (flash size) / 16kB */
306     .sector_size    = 0x4000u,  /* 16kB - as there are no sectors the page size
307                                  *        size is used here
308                                  */
309     .page_size      = 0x4000u,  /* 16kB */
310     .program_unit   = 4u,       /* Minimum write size in bytes */
311     .erased_value   = 0xFF
312 };
313 
314 static ARM_FLASHx_Resources ARM_FLASH0_DEV = {
315     .dev    = &EFLASH0_DEV,
316     .data   = &(ARM_FLASH0_DEV_DATA),
317     .status = {
318        .busy     = DRIVER_STATUS_IDLE,
319        .error    = DRIVER_STATUS_NO_ERROR,
320        .reserved = 0,
321      },
322 };
323 
ARM_Flash0_GetVersion(void)324 static ARM_DRIVER_VERSION ARM_Flash0_GetVersion(void)
325 {
326     return ARM_Flash_GetVersion();
327 }
328 
ARM_Flash0_GetCapabilities(void)329 static ARM_FLASH_CAPABILITIES ARM_Flash0_GetCapabilities(void)
330 {
331     return ARM_Flash_GetCapabilities();
332 }
333 
ARM_Flash0_Initialize(ARM_Flash_SignalEvent_t cb_event)334 static int32_t ARM_Flash0_Initialize(ARM_Flash_SignalEvent_t cb_event)
335 {
336     return ARM_Flashx_Initialize(&ARM_FLASH0_DEV, cb_event);
337 }
338 
ARM_Flash0_Uninitialize(void)339 static int32_t ARM_Flash0_Uninitialize(void)
340 {
341     return ARM_Flashx_Uninitialize(&ARM_FLASH0_DEV);
342 }
343 
ARM_Flash0_PowerControl(ARM_POWER_STATE state)344 static int32_t ARM_Flash0_PowerControl(ARM_POWER_STATE state)
345 {
346     return ARM_Flashx_PowerControl(&ARM_FLASH0_DEV, state);
347 }
348 
ARM_Flash0_ReadData(uint32_t addr,void * data,uint32_t cnt)349 static int32_t ARM_Flash0_ReadData(uint32_t addr, void *data, uint32_t cnt)
350 {
351     return ARM_Flashx_ReadData(&ARM_FLASH0_DEV, addr, data, cnt);
352 }
353 
ARM_Flash0_ProgramData(uint32_t addr,const void * data,uint32_t cnt)354 static int32_t ARM_Flash0_ProgramData(uint32_t addr, const void *data,
355                                       uint32_t cnt)
356 {
357     return ARM_Flashx_ProgramData(&ARM_FLASH0_DEV, addr, data, cnt);
358 }
359 
ARM_Flash0_EraseSector(uint32_t addr)360 static int32_t ARM_Flash0_EraseSector(uint32_t addr)
361 {
362     return ARM_Flashx_EraseSector(&ARM_FLASH0_DEV, addr);
363 }
364 
ARM_Flash0_EraseChip(void)365 static int32_t ARM_Flash0_EraseChip(void)
366 {
367     return ARM_Flashx_EraseChip(&ARM_FLASH0_DEV);
368 }
369 
ARM_Flash0_GetStatus(void)370 static ARM_FLASH_STATUS ARM_Flash0_GetStatus(void)
371 {
372     return ARM_Flashx_GetStatus(&ARM_FLASH0_DEV);
373 }
374 
ARM_Flash0_GetInfo(void)375 static ARM_FLASH_INFO * ARM_Flash0_GetInfo(void)
376 {
377     return ARM_Flashx_GetInfo(&ARM_FLASH0_DEV);
378 }
379 
380 ARM_DRIVER_FLASH Driver_EFLASH0 = {
381     ARM_Flash0_GetVersion,
382     ARM_Flash0_GetCapabilities,
383     ARM_Flash0_Initialize,
384     ARM_Flash0_Uninitialize,
385     ARM_Flash0_PowerControl,
386     ARM_Flash0_ReadData,
387     ARM_Flash0_ProgramData,
388     ARM_Flash0_EraseSector,
389     ARM_Flash0_EraseChip,
390     ARM_Flash0_GetStatus,
391     ARM_Flash0_GetInfo
392 };
393 #endif /* RTE_EFLASH0 */
394 
395 #if (RTE_EFLASH1)
396 static ARM_FLASH_INFO ARM_FLASH1_DEV_DATA = {
397     .sector_info    = NULL,     /* Uniform sector layout */
398     .sector_count   = (0x200000u / 0x4000u), /* 2MB (flash size) / 16kB */
399     .sector_size    = 0x4000u,  /* 16kB - as there are no sectors the page size
400                                  *        size is used here
401                                  */
402     .page_size      = 0x4000u,  /* 16kB */
403     .program_unit   = 4u,       /* Minimum write size in bytes */
404     .erased_value   = 0xFF
405 };
406 
407 static ARM_FLASHx_Resources ARM_FLASH1_DEV = {
408     .dev    = &EFLASH1_DEV,
409     .data   = &ARM_FLASH1_DEV_DATA,
410     .status = {
411        .busy     = DRIVER_STATUS_IDLE,
412        .error    = DRIVER_STATUS_NO_ERROR,
413        .reserved = 0,
414      },
415 };
416 
ARM_Flash1_GetVersion(void)417 static ARM_DRIVER_VERSION ARM_Flash1_GetVersion(void)
418 {
419     return ARM_Flash_GetVersion();
420 }
421 
ARM_Flash1_GetCapabilities(void)422 static ARM_FLASH_CAPABILITIES ARM_Flash1_GetCapabilities(void)
423 {
424     return ARM_Flash_GetCapabilities();
425 }
426 
ARM_Flash1_Initialize(ARM_Flash_SignalEvent_t cb_event)427 static int32_t ARM_Flash1_Initialize(ARM_Flash_SignalEvent_t cb_event)
428 {
429     return ARM_Flashx_Initialize(&ARM_FLASH1_DEV, cb_event);
430 }
431 
ARM_Flash1_Uninitialize(void)432 static int32_t ARM_Flash1_Uninitialize(void)
433 {
434     return ARM_Flashx_Uninitialize(&ARM_FLASH1_DEV);
435 }
436 
ARM_Flash1_PowerControl(ARM_POWER_STATE state)437 static int32_t ARM_Flash1_PowerControl(ARM_POWER_STATE state)
438 {
439     return ARM_Flashx_PowerControl(&ARM_FLASH1_DEV, state);
440 }
441 
ARM_Flash1_ReadData(uint32_t addr,void * data,uint32_t cnt)442 static int32_t ARM_Flash1_ReadData(uint32_t addr, void *data, uint32_t cnt)
443 {
444     return ARM_Flashx_ReadData(&ARM_FLASH1_DEV, addr, data, cnt);
445 }
446 
ARM_Flash1_ProgramData(uint32_t addr,const void * data,uint32_t cnt)447 static int32_t ARM_Flash1_ProgramData(uint32_t addr, const void *data,
448                                       uint32_t cnt)
449 {
450     return ARM_Flashx_ProgramData(&ARM_FLASH1_DEV, addr, data, cnt);
451 }
452 
ARM_Flash1_EraseSector(uint32_t addr)453 static int32_t ARM_Flash1_EraseSector(uint32_t addr)
454 {
455     return ARM_Flashx_EraseSector(&ARM_FLASH1_DEV, addr);
456 }
457 
ARM_Flash1_EraseChip(void)458 static int32_t ARM_Flash1_EraseChip(void)
459 {
460     return ARM_Flashx_EraseChip(&ARM_FLASH1_DEV);
461 }
462 
ARM_Flash1_GetStatus(void)463 static ARM_FLASH_STATUS ARM_Flash1_GetStatus(void)
464 {
465     return (ARM_Flashx_GetStatus(&ARM_FLASH1_DEV));
466 }
467 
ARM_Flash1_GetInfo(void)468 static ARM_FLASH_INFO * ARM_Flash1_GetInfo(void)
469 {
470     return ARM_Flashx_GetInfo(&ARM_FLASH1_DEV);
471 }
472 
473 ARM_DRIVER_FLASH Driver_EFLASH1 = {
474     ARM_Flash1_GetVersion,
475     ARM_Flash1_GetCapabilities,
476     ARM_Flash1_Initialize,
477     ARM_Flash1_Uninitialize,
478     ARM_Flash1_PowerControl,
479     ARM_Flash1_ReadData,
480     ARM_Flash1_ProgramData,
481     ARM_Flash1_EraseSector,
482     ARM_Flash1_EraseChip,
483     ARM_Flash1_GetStatus,
484     ARM_Flash1_GetInfo
485 };
486 #endif /* RTE_EFLASH1 */
487