1 /*
2  * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 /* This file is a derivative of a previous version of
20  * platform/ext/target/musca_b1/CMSIS_Driver/Driver_Flash.c
21  * Git SHA: 9f3da0b83e45e6d26ad0be45c090d2e4382fb04f
22  */
23 
24 /* FIXME: This interim flash driver uses BRAM to emulate flash for PS.
25  * Code is still running on QSPI, and only direct read is supported,
26  * write is not supported yet.
27  * It should be replaced with a real flash driver.
28  */
29 
30 #include <string.h>
31 #include <stdint.h>
32 #include "Driver_Flash.h"
33 #include "RTE_Device.h"
34 #include "flash_layout.h"
35 
36 #ifndef ARG_UNUSED
37 #define ARG_UNUSED(arg)  ((void)arg)
38 #endif
39 
40 /* Driver version */
41 #define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
42 
43 #define FLASH_REDIRECT_BASE   FLASH_PS_AREA_OFFSET
44 #define FLASH_REDIRECT_LIMIT  (FLASH_REDIRECT_BASE   \
45                                + FLASH_PS_AREA_SIZE \
46                                + FLASH_ITS_AREA_SIZE \
47                                + FLASH_OTP_NV_COUNTERS_AREA_SIZE)
48 #define FLASH_REDIRECT_DEST   0x38000000
49 
50 #define FLASH0_BASE_S         0x10000000
51 #define FLASH0_BASE_NS        0x00000000
52 #define FLASH0_SIZE           0x00800000 /* 8 MB */
53 #define FLASH0_SECTOR_SIZE    0x00001000 /* 4 kB */
54 #define FLASH0_PAGE_SIZE      0x00001000 /* 4 kB */
55 #define FLASH0_PROGRAM_UNIT   0x1        /* Minimum write size */
56 
57 /**
58  * Data width values for ARM_FLASH_CAPABILITIES::data_width
59  * \ref ARM_FLASH_CAPABILITIES
60  */
61  enum {
62     DATA_WIDTH_8BIT   = 0u,
63     DATA_WIDTH_16BIT,
64     DATA_WIDTH_32BIT,
65     DATA_WIDTH_ENUM_SIZE
66 };
67 
68 static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = {
69     sizeof(uint8_t),
70     sizeof(uint16_t),
71     sizeof(uint32_t),
72 };
73 
74 /*
75  * ARM FLASH device structure
76  */
77 struct arm_flash_dev_t {
78     const uint32_t memory_base;   /*!< FLASH memory base address */
79     ARM_FLASH_INFO *data;         /*!< FLASH data */
80 };
81 
82 /* Flash Status */
83 static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
84 
85 /* Driver Version */
86 static const ARM_DRIVER_VERSION DriverVersion = {
87     ARM_FLASH_API_VERSION,
88     ARM_FLASH_DRV_VERSION
89 };
90 
91 /* Driver Capabilities */
92 static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
93     0, /* event_ready */
94     0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
95     1  /* erase_chip */
96 };
97 
is_range_valid(struct arm_flash_dev_t * flash_dev,uint32_t offset)98 static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev,
99                               uint32_t offset)
100 {
101     uint32_t flash_limit = 0;
102     int32_t rc = 0;
103 
104     flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size)
105                    - 1;
106 
107     if (offset > flash_limit) {
108         rc = -1;
109     }
110     return rc;
111 }
112 
is_write_aligned(struct arm_flash_dev_t * flash_dev,uint32_t param)113 static int32_t is_write_aligned(struct arm_flash_dev_t *flash_dev,
114                                 uint32_t param)
115 {
116     int32_t rc = 0;
117 
118     if ((param % flash_dev->data->program_unit) != 0) {
119         rc = -1;
120     }
121     return rc;
122 }
123 
is_sector_aligned(struct arm_flash_dev_t * flash_dev,uint32_t offset)124 static int32_t is_sector_aligned(struct arm_flash_dev_t *flash_dev,
125                                  uint32_t offset)
126 {
127     int32_t rc = 0;
128 
129     if ((offset % flash_dev->data->sector_size) != 0) {
130         rc = -1;
131     }
132     return rc;
133 }
134 
135 #if (RTE_FLASH0)
136 static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
137     .sector_info  = NULL,                  /* Uniform sector layout */
138     .sector_count = FLASH0_SIZE / FLASH0_SECTOR_SIZE,
139     .sector_size  = FLASH0_SECTOR_SIZE,
140     .page_size    = FLASH0_PAGE_SIZE,
141     .program_unit = FLASH0_PROGRAM_UNIT,
142     .erased_value = 0xFF};
143 
144 static struct arm_flash_dev_t ARM_FLASH0_DEV = {
145 #if (__DOMAIN_NS == 1)
146     .memory_base = FLASH0_BASE_NS,
147 #else
148     .memory_base = FLASH0_BASE_S,
149 #endif /* __DOMAIN_NS == 1 */
150     .data        = &(ARM_FLASH0_DEV_DATA)};
151 
152 struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV;
153 
154 /*
155  * Functions
156  */
157 
ARM_Flash_GetVersion(void)158 static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
159 {
160     return DriverVersion;
161 }
162 
ARM_Flash_GetCapabilities(void)163 static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
164 {
165     return DriverCapabilities;
166 }
167 
ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)168 static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
169 {
170     ARG_UNUSED(cb_event);
171 
172     if (DriverCapabilities.data_width >= DATA_WIDTH_ENUM_SIZE) {
173         return ARM_DRIVER_ERROR;
174     }
175 
176     /* Nothing to be done */
177     return ARM_DRIVER_OK;
178 }
179 
ARM_Flash_Uninitialize(void)180 static int32_t ARM_Flash_Uninitialize(void)
181 {
182     /* Nothing to be done */
183     return ARM_DRIVER_OK;
184 }
185 
ARM_Flash_PowerControl(ARM_POWER_STATE state)186 static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
187 {
188     switch (state) {
189     case ARM_POWER_FULL:
190         /* Nothing to be done */
191         return ARM_DRIVER_OK;
192         break;
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     volatile uint32_t mem_base = FLASH0_DEV->memory_base;
204     uint32_t start_addr = mem_base + addr;
205     int32_t rc = 0;
206 
207     /* Conversion between data items and bytes */
208     cnt *= data_width_byte[DriverCapabilities.data_width];
209 
210     /* Check flash memory boundaries */
211     rc = is_range_valid(FLASH0_DEV, addr + cnt);
212     if (rc != 0) {
213         return ARM_DRIVER_ERROR_PARAMETER;
214     }
215 
216     /* Redirecting PS storage to BRAM */
217     if (addr >= FLASH_REDIRECT_BASE && addr <= FLASH_REDIRECT_LIMIT) {
218         start_addr = FLASH_REDIRECT_DEST + (addr - FLASH_REDIRECT_BASE);
219     }
220 
221     memcpy(data, (void *)start_addr, cnt);
222 
223     /* Conversion between bytes and data items */
224     cnt /= data_width_byte[DriverCapabilities.data_width];
225 
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,
230                                      uint32_t cnt)
231 {
232     volatile uint32_t mem_base = FLASH0_DEV->memory_base;
233     uint32_t start_addr = mem_base + addr;
234     int32_t rc = 0;
235 
236     /* Conversion between data items and bytes */
237     cnt *= data_width_byte[DriverCapabilities.data_width];
238 
239     /* Check flash memory boundaries and alignment with minimal write size */
240     rc  = is_range_valid(FLASH0_DEV, addr + cnt);
241     rc |= is_write_aligned(FLASH0_DEV, addr);
242     rc |= is_write_aligned(FLASH0_DEV, cnt);
243     if (rc != 0) {
244         return ARM_DRIVER_ERROR_PARAMETER;
245     }
246 
247     /* Redirecting PS storage to BRAM */
248     if (addr >= FLASH_REDIRECT_BASE && addr <= FLASH_REDIRECT_LIMIT) {
249         start_addr = FLASH_REDIRECT_DEST + (addr - FLASH_REDIRECT_BASE);
250         /* PS Flash is emulated over BRAM. use memcpy function. */
251         memcpy((void *)start_addr, data, cnt);
252     } else {
253         /* Flash driver for QSPI is not ready */
254         return ARM_DRIVER_ERROR_UNSUPPORTED;
255     }
256 
257     /* Conversion between bytes and data items */
258     cnt /= data_width_byte[DriverCapabilities.data_width];
259 
260     return cnt;
261 }
262 
ARM_Flash_EraseSector(uint32_t addr)263 static int32_t ARM_Flash_EraseSector(uint32_t addr)
264 {
265     uint32_t rc = 0;
266 
267     rc  = is_range_valid(FLASH0_DEV, addr);
268     rc |= is_sector_aligned(FLASH0_DEV, addr);
269     if (rc != 0) {
270         return ARM_DRIVER_ERROR_PARAMETER;
271     }
272 
273     /* Redirecting PS storage to BRAM */
274     if (addr >= FLASH_REDIRECT_BASE && addr <= FLASH_REDIRECT_LIMIT) {
275         /* PS Flash IS emulated over BRAM. use memcpy function. */
276         memset((void *)(FLASH_REDIRECT_DEST
277                               + (addr - FLASH_REDIRECT_BASE)),
278                      FLASH0_DEV->data->erased_value,
279                      FLASH0_DEV->data->sector_size);
280     } else {
281         /* Flash driver for QSPI is not ready */
282         return ARM_DRIVER_ERROR_UNSUPPORTED;
283     }
284     return ARM_DRIVER_OK;
285 }
286 
ARM_Flash_EraseChip(void)287 static int32_t ARM_Flash_EraseChip(void)
288 {
289     uint32_t i;
290     uint32_t addr = FLASH0_DEV->memory_base;
291     int32_t rc = ARM_DRIVER_ERROR_UNSUPPORTED;
292 
293     /* Check driver capability erase_chip bit */
294     if (DriverCapabilities.erase_chip == 1) {
295         for (i = 0; i < FLASH0_DEV->data->sector_count; i++) {
296             /* Redirecting PS storage to BRAM */
297             if (addr >= FLASH_REDIRECT_BASE && addr <= FLASH_REDIRECT_LIMIT) {
298                 memset((void *)(FLASH_REDIRECT_DEST +
299                         (addr - FLASH0_DEV->memory_base - FLASH_REDIRECT_BASE)),
300                         FLASH0_DEV->data->erased_value,
301                         FLASH0_DEV->data->sector_size);
302             }
303             /* else {
304              *     Flash driver for QSPI is not ready, fall through.
305              * }
306              */
307 
308             addr += FLASH0_DEV->data->sector_size;
309             rc = ARM_DRIVER_OK;
310         }
311     }
312     return rc;
313 }
314 
ARM_Flash_GetStatus(void)315 static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
316 {
317     return FlashStatus;
318 }
319 
ARM_Flash_GetInfo(void)320 static ARM_FLASH_INFO *ARM_Flash_GetInfo(void)
321 {
322     return FLASH0_DEV->data;
323 }
324 
325 ARM_DRIVER_FLASH Driver_FLASH0 = {
326     ARM_Flash_GetVersion,
327     ARM_Flash_GetCapabilities,
328     ARM_Flash_Initialize,
329     ARM_Flash_Uninitialize,
330     ARM_Flash_PowerControl,
331     ARM_Flash_ReadData,
332     ARM_Flash_ProgramData,
333     ARM_Flash_EraseSector,
334     ARM_Flash_EraseChip,
335     ARM_Flash_GetStatus,
336     ARM_Flash_GetInfo
337 };
338 #endif /* RTE_FLASH0 */
339