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