1 /*
2  * Copyright (c) 2013-2022 ARM Limited. All rights reserved.
3  * Copyright 2019-2022 NXP. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the License); you may
8  * not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #include "Driver_Flash.h"
21 #include "platform_base_address.h"
22 #include "flash_layout.h"
23 #include "fsl_iap.h"
24 
25 #ifndef ARG_UNUSED
26 #define ARG_UNUSED(arg)  ((void)arg)
27 #endif
28 
29 /* Below CMDs apply to both C040HDATFC and C040HDFC flash */
30 #define FLASH_CMD_INIT 0
31 #define FLASH_CMD_READ_SINGLE_WORD 3
32 
33 /* INT_STATUS - Interrupt status bits - taken from LPC5588_cm33_core0.h */
34 
35 #define FLASH_INT_STATUS_OVL_MASK                (0x10U)
36 
37 /* Alignment macros - taken from bootloader_common.h */
38 #ifndef ALIGN_DOWN
39 #define ALIGN_DOWN(x, a) ((x) & -(a))
40 #endif
41 
42 /* Flash property defines */
43 
44 /* Mask the number of bits required to select the 32-bit data word (DATAW) from the flash line */
45 #define FLASH_DATAW_IDX_MAX 3    /* Max DATAW index, 3 for a 128-bit flash line, 7 for 256-bit. */
46 
47 #define FLASH_READMODE_REG          (FLASH->DATAW[0])
48 #define FLASH_READMODE_ECC_MASK     (0x4U)
49 #define FLASH_READMODE_ECC_SHIFT    (2U)
50 #define FLASH_READMODE_ECC(x)       (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_ECC_SHIFT)) & FLASH_READMODE_ECC_MASK)
51 #define FLASH_READMODE_MARGIN_MASK  (0xC00U)
52 #define FLASH_READMODE_MARGIN_SHIFT (10U)
53 #define FLASH_READMODE_MARGIN(x)    (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_MARGIN_SHIFT)) & FLASH_READMODE_MARGIN_MASK)
54 #define FLASH_READMODE_DMACC_MASK   (0x8000U)
55 #define FLASH_READMODE_DMACC_SHIFT  (15U)
56 #define FLASH_READMODE_DMACC(x)     (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_DMACC_SHIFT)) & FLASH_READMODE_DMACC_MASK)
57 
58 /* Driver version */
59 #define ARM_FLASH_DRV_VERSION    ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
60 
61 /**
62  * \brief Flash driver capability macro definitions \ref ARM_FLASH_CAPABILITIES
63  */
64 /* Flash Ready event generation capability values */
65 #define EVENT_READY_NOT_AVAILABLE   (0u)
66 #define EVENT_READY_AVAILABLE       (1u)
67 
68 /* Data access size values */
69  enum {
70     DATA_WIDTH_8BIT   = 0u,
71     DATA_WIDTH_16BIT,
72     DATA_WIDTH_32BIT,
73     DATA_WIDTH_ENUM_SIZE
74 };
75 
76 static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = {
77     sizeof(uint8_t),
78     sizeof(uint16_t),
79     sizeof(uint32_t),
80 };
81 
82 /* Chip erase capability values */
83 #define CHIP_ERASE_NOT_SUPPORTED    (0u)
84 #define CHIP_ERASE_SUPPORTED        (1u)
85 
86 /* ARM FLASH device structure */
87 struct arm_flash_dev_t {
88     ARM_FLASH_INFO *data;         /*!< FLASH data */
89     flash_config_t flashInstance; /*!< FLASH config*/
90 };
91 
92 /* Flash Status */
93 static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
94 
95 /* Driver Version */
96 static const ARM_DRIVER_VERSION DriverVersion = {
97     ARM_FLASH_API_VERSION,
98     ARM_FLASH_DRV_VERSION
99 };
100 
101 /* Driver Capabilities */
102 static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
103     EVENT_READY_NOT_AVAILABLE,
104     DATA_WIDTH_8BIT,
105     CHIP_ERASE_NOT_SUPPORTED
106 };
107 
108 static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
109     .sector_info  = NULL,                  /* Uniform sector layout */
110     .sector_count = FLASH0_SIZE / FLASH0_PAGE_SIZE,
111     .sector_size  = FLASH0_PAGE_SIZE,
112     .page_size    = FLASH0_PAGE_SIZE,
113     .program_unit = FLASH0_PAGE_SIZE,
114     .erased_value = 0x00};
115 
116 static struct arm_flash_dev_t ARM_FLASH0_DEV = {
117     .data        = &(ARM_FLASH0_DEV_DATA)};
118 
119 static struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV;
120 
121 /* Prototypes */
122 
123 /* Internal function Flash command sequence. Called by driver APIs only*/
124 static status_t flash_command_sequence(flash_config_t *config);
125 
126 //static status_t FLASH_ReadInit(flash_config_t *config);
127 static status_t FLASH_ReadData(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes);
128 static status_t FLASH_ReadSingleWord(flash_config_t *config, uint32_t start, uint32_t *readbackData);
129 
130 static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
131                            uint32_t offset);
132 static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
133                              uint32_t param);
134 
135 /* Functions */
136 
ARM_Flash_GetVersion(void)137 static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
138 {
139     return DriverVersion;
140 }
141 
ARM_Flash_GetCapabilities(void)142 static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
143 {
144     return DriverCapabilities;
145 }
146 
147 static bool flash_init_is_done = false;
ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)148 static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
149 {
150     ARG_UNUSED(cb_event);
151     status_t status;
152 
153     if (flash_init_is_done == false)
154     {
155         if (DriverCapabilities.data_width >= DATA_WIDTH_ENUM_SIZE) {
156             return ARM_DRIVER_ERROR;
157         }
158 
159         /* Call initialization from Flash API */
160         status = FLASH_Init(&FLASH0_DEV->flashInstance);
161 
162         if(status != kStatus_Success){
163             return ARM_DRIVER_ERROR;
164         }
165 
166 
167         /* Disable Error Detection functionality */
168         FLASH0_DEV->flashInstance.modeConfig.readSingleWord.readWithEccOff = 0x1;
169         flash_init_is_done = true;
170         #if 0
171             /* Initialization of Flash by means of its registers to be able read data*/
172             if(FLASH_ReadInit(&FLASH0_DEV->flashInstance) != kStatus_Success){
173 			    return ARM_DRIVER_ERROR;
174             }
175         #endif
176     }
177 
178     return ARM_DRIVER_OK;
179 }
180 
ARM_Flash_Uninitialize(void)181 static int32_t ARM_Flash_Uninitialize(void)
182 {
183     flash_init_is_done = false;
184     /* Nothing to be done */
185     return ARM_DRIVER_OK;
186 }
187 
ARM_Flash_PowerControl(ARM_POWER_STATE state)188 static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
189 {
190     switch (state) {
191     case ARM_POWER_FULL:
192         /* Nothing to be done */
193         return ARM_DRIVER_OK;
194 
195     case ARM_POWER_OFF:
196     case ARM_POWER_LOW:
197     default:
198         return ARM_DRIVER_ERROR_UNSUPPORTED;
199     }
200 }
201 
ARM_Flash_ReadData(uint32_t addr,void * data,uint32_t cnt)202 static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
203 {
204     static uint32_t status;
205 
206     /* Conversion between data items and bytes */
207     cnt *= data_width_byte[DriverCapabilities.data_width];
208 
209     /* Check Flash memory boundaries */
210     status = is_range_valid(FLASH0_DEV, addr + cnt);
211     if(status != kStatus_Success) {
212         return ARM_DRIVER_ERROR_PARAMETER;
213     }
214 
215     /* Read Data */
216 #if 1
217     if(cnt) {
218         status  = FLASH_ReadData(&FLASH0_DEV->flashInstance, addr, (uint8_t *)data, cnt);
219         if(status != kStatus_Success) {
220             return ARM_DRIVER_ERROR;
221         }
222     }
223 #else /* Bus fault when reading erased memory */
224     (void)memcpy(data, (uint8_t *)addr, cnt);
225 #endif
226     cnt /= data_width_byte[DriverCapabilities.data_width];
227     return cnt;
228 }
229 
ARM_Flash_ProgramData(uint32_t addr,const void * data,uint32_t cnt)230 static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, uint32_t cnt)
231 {
232     static uint32_t status;
233     uint32_t failedAddress, failedData;
234     /* Conversion between data items and bytes */
235     cnt *= data_width_byte[DriverCapabilities.data_width];
236 
237     /* Check Flash memory boundaries */
238     status = is_range_valid(FLASH0_DEV, addr);
239     status |= is_write_aligned(FLASH0_DEV, addr);
240     status |= is_write_aligned(FLASH0_DEV, cnt);
241     if(status != kStatus_Success) {
242         return ARM_DRIVER_ERROR_PARAMETER;
243     }
244 
245     status = FLASH_Program(&FLASH0_DEV->flashInstance, addr, (uint8_t *)data, cnt);
246     if (status != kStatus_Success) {
247         return ARM_DRIVER_ERROR;
248     }
249 
250     status = FLASH_VerifyProgram(&FLASH0_DEV->flashInstance, addr, cnt, (const uint8_t *)data,
251 				 &failedAddress, &failedData);
252     if (status != kStatus_Success) {
253         return ARM_DRIVER_ERROR;
254     }
255 
256     cnt /= data_width_byte[DriverCapabilities.data_width];
257     return cnt;
258 }
259 
ARM_Flash_EraseSector(uint32_t addr)260 static int32_t ARM_Flash_EraseSector(uint32_t addr)
261 {
262     static uint32_t status;
263 
264     status = is_range_valid(FLASH0_DEV, addr);
265     status |= is_write_aligned(FLASH0_DEV, addr);
266     if(status != kStatus_Success) {
267         return ARM_DRIVER_ERROR_PARAMETER;
268     }
269 
270     status = FLASH_Erase(&FLASH0_DEV->flashInstance, addr, FLASH0_DEV->data->sector_size, kFLASH_ApiEraseKey);
271     if (status != kStatus_Success) {
272         return ARM_DRIVER_ERROR;
273     }
274 
275     return ARM_DRIVER_OK;
276 }
277 
ARM_Flash_GetStatus(void)278 static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
279 {
280     return FlashStatus;
281 }
282 
ARM_Flash_GetInfo(void)283 static ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
284 {
285     return FLASH0_DEV->data;
286 }
287 
288 ARM_DRIVER_FLASH Driver_FLASH0 = {
289     .GetVersion = ARM_Flash_GetVersion,
290     .GetCapabilities = ARM_Flash_GetCapabilities,
291     .Initialize = ARM_Flash_Initialize,
292     .Uninitialize = ARM_Flash_Uninitialize,
293     .PowerControl = ARM_Flash_PowerControl,
294     .ReadData = ARM_Flash_ReadData,
295     .ProgramData = ARM_Flash_ProgramData,
296     .EraseSector = ARM_Flash_EraseSector,
297     .GetStatus = ARM_Flash_GetStatus,
298     .GetInfo = ARM_Flash_GetInfo
299 };
300 
301 #if 0
302 static status_t FLASH_ReadInit(flash_config_t *config)
303 {
304     status_t status = kStatus_Fail;
305 
306 	if (config == NULL)
307     {
308         return kStatus_FLASH_InvalidArgument;
309     }
310 
311     /* config->PFlashTotalSize was initialized to 0xA0000 (640kB) by FLASH API.
312 		   This value needs to be changed to 0x98000 (608kB)*/
313     config->PFlashTotalSize = FLASH_TOTAL_SIZE;
314 
315     /* Immediately after leaving reset mode, an initialization phase takes place,
316        where some memory locations are read, and corresponding volatile locations
317        are initialized depending on the value just read. */
318     FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK;
319     FLASH->CMD = FLASH_CMD_INIT;
320     status = flash_command_sequence(config);
321 
322     if (kStatus_FLASH_Success != status)
323     {
324         return status;
325     }
326 
327     return kStatus_FLASH_Success;
328 }
329 #endif
330 
FLASH_ReadData(flash_config_t * config,uint32_t start,uint8_t * dest,uint32_t lengthInBytes)331 static status_t FLASH_ReadData(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes)
332 {
333     status_t status = kStatus_Fail;
334 
335     uint32_t readbackData[FLASH_DATAW_IDX_MAX + 1];
336     while (lengthInBytes)
337     {
338         uint32_t alignedStart = ALIGN_DOWN(start, (uint32_t)kFLASH_AlignementUnitSingleWordRead);
339         status = FLASH_ReadSingleWord(config, alignedStart, readbackData);
340         if (status != kStatus_FLASH_Success)
341         {
342             break;
343         }
344         for (uint32_t i = 0; i < sizeof(readbackData); i++)
345         {
346             if ((alignedStart == start) && lengthInBytes)
347             {
348                 *dest = *((uint8_t *)readbackData + i);
349                 dest++;
350                 start++;
351                 lengthInBytes--;
352             }
353             alignedStart++;
354         }
355     }
356 
357     return status;
358 }
359 
FLASH_ReadSingleWord(flash_config_t * config,uint32_t start,uint32_t * readbackData)360 static status_t FLASH_ReadSingleWord(flash_config_t *config, uint32_t start, uint32_t *readbackData)
361 {
362     status_t status = kStatus_Fail;
363 
364     if (readbackData == NULL)
365     {
366         return kStatus_FLASH_InvalidArgument;
367     }
368 
369     FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK |
370                             FLASH_INT_CLR_STATUS_DONE_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK;
371 
372     /* Set start address */
373     FLASH->STARTA = start >> 4;
374 
375     /* ReadSingleWord notes:
376     Flash contains one DMACC word per page. Such words are not readable through
377     the read interface. DMACC words are managed internally by the controller in
378     order to store a flag (all1), which can be used to verify whether a programming
379     operation was prematurely terminated.
380     DMACC words are all_0 for an erased page, all_1 for a programmed page */
381 
382     /* Set read modes */
383     FLASH_READMODE_REG = FLASH_READMODE_ECC(config->modeConfig.readSingleWord.readWithEccOff) |
384                          FLASH_READMODE_MARGIN(config->modeConfig.readSingleWord.readMarginLevel) |
385                          FLASH_READMODE_DMACC(config->modeConfig.readSingleWord.readDmaccWord);
386 
387     /* Calling flash command sequence function to execute the command */
388     FLASH->CMD = FLASH_CMD_READ_SINGLE_WORD;
389     status = flash_command_sequence(config);
390 
391     if (kStatus_FLASH_Success == status)
392     {
393         for (uint32_t datawIndex = 0; datawIndex <= FLASH_DATAW_IDX_MAX; datawIndex++)
394         {
395             *readbackData++ = FLASH->DATAW[datawIndex];
396         }
397     }
398 
399     return status;
400 }
401 
402 /* This function is used to perform the command write sequence to the flash. */
flash_command_sequence(flash_config_t * config)403 static status_t flash_command_sequence(flash_config_t *config)
404 {
405     status_t status = kStatus_Fail;
406     uint32_t registerValue;
407 
408     while (!(FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK))
409         ;
410 
411     /* Check error bits */
412     /* Get flash status register value */
413     registerValue = FLASH->INT_STATUS;
414 
415     /* Checking access error */
416     if (registerValue & FLASH_INT_STATUS_FAIL_MASK)
417     {
418         status = kStatus_FLASH_CommandFailure;
419     }
420     else if (registerValue & FLASH_INT_STATUS_ERR_MASK)
421     {
422         status = kStatus_FLASH_CommandNotSupported;
423     }
424     else if (registerValue & FLASH_INT_STATUS_ECC_ERR_MASK)
425     {
426         status = kStatus_FLASH_EccError;
427     }
428     else if (registerValue & FLASH_INT_STATUS_OVL_MASK)
429     {
430         status = kStatus_FLASH_RegulationLoss;
431     }
432     else
433     {
434         status = kStatus_FLASH_Success;
435     }
436 
437     return status;
438 }
439 
440 /* Check if the Flash memory boundaries are not violated. */
is_range_valid(struct arm_flash_dev_t * flash_dev,uint32_t offset)441 static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
442                            uint32_t offset)
443 {
444 
445     uint32_t flash_limit = FLASH_TOTAL_SIZE - 1;
446 
447     return (offset > flash_limit) ? (kStatus_Fail) : (kStatus_Success) ;
448 }
449 
450 /* Check if the parameter is aligned to program_unit. */
is_write_aligned(struct arm_flash_dev_t * flash_dev,uint32_t param)451 static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
452                              uint32_t param)
453 {
454     return ((param % flash_dev->data->program_unit) != 0) ? (kStatus_Fail) : (kStatus_Success);
455 }