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