1 /**
2 ******************************************************************************
3 * @file bflb_xip_sflash.c
4 * @version V1.0
5 * @date
6 * @brief This file is the standard driver c file
7 ******************************************************************************
8 * @attention
9 *
10 * <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
11 *
12 * Redistribution and use in source and binary forms, with or without modification,
13 * are permitted provided that the following conditions are met:
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. Neither the name of Bouffalo Lab nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 ******************************************************************************
35 */
36
37 #include "bflb_common.h"
38 #include "bflb_xip_sflash.h"
39
40 /** @addtogroup BL628_Peripheral_Driver
41 * @{
42 */
43
44 /** @addtogroup XIP_SFLASH
45 * @{
46 */
47
48 /** @defgroup XIP_SFLASH_Private_Macros
49 * @{
50 */
51
52 /*@} end of group XIP_SFLASH_Private_Macros */
53
54 /** @defgroup XIP_SFLASH_Private_Types
55 * @{
56 */
57
58 /*@} end of group XIP_SFLASH_Private_Types */
59
60 /** @defgroup XIP_SFLASH_Private_Variables
61 * @{
62 */
63
64 /*@} end of group XIP_SFLASH_Private_Variables */
65
66 /** @defgroup XIP_SFLASH_Global_Variables
67 * @{
68 */
69
70 /*@} end of group XIP_SFLASH_Global_Variables */
71
72 /** @defgroup XIP_SFLASH_Private_Fun_Declaration
73 * @{
74 */
75
76 /*@} end of group XIP_SFLASH_Private_Fun_Declaration */
77
78 /** @defgroup XIP_SFLASH_Private_Functions
79 * @{
80 */
81
82 /****************************************************************************/ /**
83 * @brief Save flash controller state
84 *
85 * @param p_flash_cfg: Flash config pointer
86 * @param offset: CPU XIP flash offset pointer
87 * @param group: CPU group id 0 or 1
88 * @param bank: Flash bank select
89 *
90 * @return BFLB_RET:0 means success and other value means error
91 *
92 *******************************************************************************/
93 __WEAK
bflb_xip_sflash_state_save(spi_flash_cfg_type * p_flash_cfg,uint32_t * offset,uint8_t group,uint8_t bank)94 int ATTR_TCM_SECTION bflb_xip_sflash_state_save(spi_flash_cfg_type *p_flash_cfg, uint32_t *offset,
95 uint8_t group, uint8_t bank)
96 {
97 /* XIP_SFlash_Delay */
98 volatile uint32_t i = 32 * 2;
99
100 while (i--)
101 ;
102
103 #ifdef BFLB_SF_CTRL_SBUS2_ENABLE
104 if (bank == SF_CTRL_FLASH_BANK1) {
105 bflb_sf_ctrl_sbus2_replace(SF_CTRL_PAD2);
106 }
107 #endif
108 bflb_sf_ctrl_set_owner(SF_CTRL_OWNER_SAHB);
109 /* Exit form continous read for accepting command */
110 bflb_sflash_reset_continue_read(p_flash_cfg);
111 /* For disable command that is setting register instaed of send command, we need write enable */
112 bflb_sflash_disable_burst_wrap(p_flash_cfg);
113 #ifdef BFLB_SF_CTRL_32BITS_ADDR_ENABLE
114 /* Enable 32Bits addr mode again in case reset command make it reset */
115 bflb_sflash_set_32bits_addr_mode(p_flash_cfg, 1);
116 #endif
117 if ((p_flash_cfg->io_mode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->io_mode & 0x0f) == SF_CTRL_QIO_MODE) {
118 /* Enable QE again in case reset command make it reset */
119 bflb_sflash_qspi_enable(p_flash_cfg);
120 }
121 /* Deburst again to make sure */
122 bflb_sflash_disable_burst_wrap(p_flash_cfg);
123
124 /* Clear offset setting*/
125 *offset = bflb_sf_ctrl_get_flash_image_offset(group, bank);
126 bflb_sf_ctrl_set_flash_image_offset(0, group, bank);
127
128 return 0;
129 }
130
131 /****************************************************************************/ /**
132 * @brief Restore flash controller state
133 *
134 * @param p_flash_cfg: Flash config pointer
135 * @param offset: CPU XIP flash offset
136 * @param group: CPU group id 0 or 1
137 * @param bank: Flash bank select
138 *
139 * @return BFLB_RET:0 means success and other value means error
140 *
141 *******************************************************************************/
142 __WEAK
bflb_xip_sflash_state_restore(spi_flash_cfg_type * p_flash_cfg,uint32_t offset,uint8_t group,uint8_t bank)143 int ATTR_TCM_SECTION bflb_xip_sflash_state_restore(spi_flash_cfg_type *p_flash_cfg, uint32_t offset,
144 uint8_t group, uint8_t bank)
145 {
146 uint32_t tmp[1];
147 uint8_t io_mode = p_flash_cfg->io_mode & 0xf;
148
149 bflb_sf_ctrl_set_flash_image_offset(offset, group, bank);
150
151 if(((p_flash_cfg->io_mode>>4)&0x01) == 0) {
152 if((p_flash_cfg->io_mode&0x0f)==SF_CTRL_QO_MODE || (p_flash_cfg->io_mode&0x0f)==SF_CTRL_QIO_MODE) {
153 bflb_sflash_set_burst_wrap(p_flash_cfg);
154 }
155 }
156 #ifdef BFLB_SF_CTRL_32BITS_ADDR_ENABLE
157 bflb_sflash_set_32bits_addr_mode(p_flash_cfg, 1);
158 #endif
159 bflb_sflash_read(p_flash_cfg, io_mode, 1, 0x0, (uint8_t *)tmp, sizeof(tmp));
160 bflb_sflash_set_xip_cfg(p_flash_cfg, io_mode, 1, 0, 32, bank);
161 #ifdef BFLB_SF_CTRL_SBUS2_ENABLE
162 if (bank == SF_CTRL_FLASH_BANK1) {
163 bflb_sf_ctrl_sbus2_revoke_replace();
164 }
165 #endif
166
167 return 0;
168 }
169
170 /*@} end of group XIP_SFLASH_Private_Functions */
171
172 /** @defgroup XIP_SFLASH_Public_Functions
173 * @{
174 */
175
176 /****************************************************************************/ /**
177 * @brief Erase flash one region
178 *
179 * @param p_flash_cfg: Flash config pointer
180 * @param start_addr: start address to erase
181 * @param len: data length to erase
182 * @param group: CPU group id 0 or 1
183 * @param bank: Flash bank select
184 *
185 * @return BFLB_RET:0 means success and other value means error
186 *
187 *******************************************************************************/
188 __WEAK
bflb_xip_sflash_erase_need_lock(spi_flash_cfg_type * p_flash_cfg,uint32_t start_addr,int len,uint8_t group,uint8_t bank)189 int ATTR_TCM_SECTION bflb_xip_sflash_erase_need_lock(spi_flash_cfg_type *p_flash_cfg, uint32_t start_addr,
190 int len, uint8_t group, uint8_t bank)
191 {
192 int stat = 0;
193 uint32_t offset = 0;
194 uint8_t aes_enable = 0;
195 uint8_t io_mode = p_flash_cfg->io_mode & 0xf;
196
197 bflb_xip_sflash_opt_enter(&aes_enable);
198 stat = bflb_xip_sflash_state_save(p_flash_cfg, &offset, group, bank);
199
200 if (stat != 0) {
201 bflb_sflash_set_xip_cfg(p_flash_cfg, io_mode, 1, 0, 32, bank);
202 } else {
203 stat = bflb_sflash_erase(p_flash_cfg, start_addr, start_addr + len - 1);
204 bflb_xip_sflash_state_restore(p_flash_cfg, offset, group, bank);
205 }
206
207 bflb_xip_sflash_opt_exit(aes_enable);
208
209 return stat;
210 }
211
212 /****************************************************************************/ /**
213 * @brief Program flash one region
214 *
215 * @param p_flash_cfg: Flash config pointer
216 * @param addr: start address to be programed
217 * @param data: data pointer to be programed
218 * @param len: data length to be programed
219 * @param group: CPU group id 0 or 1
220 * @param bank: Flash bank select
221 *
222 * @return BFLB_RET:0 means success and other value means error
223 *
224 *******************************************************************************/
225 __WEAK
bflb_xip_sflash_write_need_lock(spi_flash_cfg_type * p_flash_cfg,uint32_t addr,uint8_t * data,uint32_t len,uint8_t group,uint8_t bank)226 int ATTR_TCM_SECTION bflb_xip_sflash_write_need_lock(spi_flash_cfg_type *p_flash_cfg, uint32_t addr, uint8_t *data,
227 uint32_t len, uint8_t group, uint8_t bank)
228 {
229 int stat = 0;
230 uint32_t offset = 0;
231 uint8_t aes_enable = 0;
232 uint8_t io_mode = p_flash_cfg->io_mode & 0xf;
233
234 bflb_xip_sflash_opt_enter(&aes_enable);
235 stat = bflb_xip_sflash_state_save(p_flash_cfg, &offset, group, bank);
236
237 if (stat != 0) {
238 bflb_sflash_set_xip_cfg(p_flash_cfg, io_mode, 1, 0, 32, bank);
239 } else {
240 stat = bflb_sflash_program(p_flash_cfg, io_mode, addr, data, len);
241 bflb_xip_sflash_state_restore(p_flash_cfg, offset, group, bank);
242 }
243
244 bflb_xip_sflash_opt_exit(aes_enable);
245
246 return stat;
247 }
248
249 /****************************************************************************/ /**
250 * @brief Read data from flash
251 *
252 * @param p_flash_cfg: Flash config pointer
253 * @param addr: flash read start address
254 * @param data: data pointer to store data read from flash
255 * @param len: data length to read
256 * @param group: CPU group id 0 or 1
257 * @param bank: Flash bank select
258 *
259 * @return BFLB_RET:0 means success and other value means error
260 *
261 *******************************************************************************/
262 __WEAK
bflb_xip_sflash_read_need_lock(spi_flash_cfg_type * p_flash_cfg,uint32_t addr,uint8_t * data,uint32_t len,uint8_t group,uint8_t bank)263 int ATTR_TCM_SECTION bflb_xip_sflash_read_need_lock(spi_flash_cfg_type *p_flash_cfg, uint32_t addr, uint8_t *data,
264 uint32_t len, uint8_t group, uint8_t bank)
265 {
266 int stat = 0;
267 uint32_t offset = 0;
268 uint8_t aes_enable = 0;
269 uint8_t io_mode = p_flash_cfg->io_mode & 0xf;
270
271 bflb_xip_sflash_opt_enter(&aes_enable);
272 stat = bflb_xip_sflash_state_save(p_flash_cfg, &offset, group, bank);
273
274 if (stat != 0) {
275 bflb_sflash_set_xip_cfg(p_flash_cfg, io_mode, 1, 0, 32, bank);
276 } else {
277 stat = bflb_sflash_read(p_flash_cfg, io_mode, 0, addr, data, len);
278 bflb_xip_sflash_state_restore(p_flash_cfg, offset, group, bank);
279 }
280
281 bflb_xip_sflash_opt_exit(aes_enable);
282
283 return stat;
284 }
285
286 /****************************************************************************/ /**
287 * @brief Get Flash Jedec ID
288 *
289 * @param p_flash_cfg: Flash config pointer
290 * @param data: data pointer to store Jedec ID Read from flash
291 * @param group: CPU group id 0 or 1
292 * @param bank: Flash bank select
293 *
294 * @return BFLB_RET:0 means success and other value means error
295 *
296 *******************************************************************************/
297 __WEAK
bflb_xip_sflash_get_jedecid_need_lock(spi_flash_cfg_type * p_flash_cfg,uint8_t * data,uint8_t group,uint8_t bank)298 int ATTR_TCM_SECTION bflb_xip_sflash_get_jedecid_need_lock(spi_flash_cfg_type *p_flash_cfg, uint8_t *data,
299 uint8_t group, uint8_t bank)
300 {
301 int stat = 0;
302 uint32_t offset = 0;
303 uint8_t aes_enable = 0;
304 uint8_t io_mode = p_flash_cfg->io_mode & 0xf;
305
306 bflb_xip_sflash_opt_enter(&aes_enable);
307 stat = bflb_xip_sflash_state_save(p_flash_cfg, &offset, group, bank);
308
309 if (stat != 0) {
310 bflb_sflash_set_xip_cfg(p_flash_cfg, io_mode, 1, 0, 32, bank);
311 } else {
312 bflb_sflash_get_jedecid(p_flash_cfg, data);
313 bflb_xip_sflash_state_restore(p_flash_cfg, offset, group, bank);
314 }
315
316 bflb_xip_sflash_opt_exit(aes_enable);
317
318 return 0;
319 }
320
321 /****************************************************************************/ /**
322 * @brief Get Flash Device ID
323 *
324 * @param p_flash_cfg: Flash config pointer
325 * @param is_32bits_addr: Is flash addr mode in 32-bits
326 * @param data: data pointer to store Device ID Read from flash
327 * @param group: CPU group id 0 or 1
328 * @param bank: Flash bank select
329 *
330 * @return BFLB_RET:0 means success and other value means error
331 *
332 *******************************************************************************/
333 __WEAK
bflb_xip_sflash_get_deviceid_need_lock(spi_flash_cfg_type * p_flash_cfg,uint8_t is_32bits_addr,uint8_t * data,uint8_t group,uint8_t bank)334 int ATTR_TCM_SECTION bflb_xip_sflash_get_deviceid_need_lock(spi_flash_cfg_type *p_flash_cfg, uint8_t is_32bits_addr,
335 uint8_t *data, uint8_t group, uint8_t bank)
336 {
337 int stat = 0;
338 uint32_t offset = 0;
339 uint8_t aes_enable = 0;
340 uint8_t io_mode = p_flash_cfg->io_mode & 0xf;
341
342 bflb_xip_sflash_opt_enter(&aes_enable);
343 stat = bflb_xip_sflash_state_save(p_flash_cfg, &offset, group, bank);
344
345 if (stat != 0) {
346 bflb_sflash_set_xip_cfg(p_flash_cfg, io_mode, 1, 0, 32, bank);
347 } else {
348 bflb_sflash_get_deviceid(data, is_32bits_addr);
349 bflb_xip_sflash_state_restore(p_flash_cfg, offset, group, bank);
350 }
351
352 bflb_xip_sflash_opt_exit(aes_enable);
353
354 return 0;
355 }
356
357 /****************************************************************************/ /**
358 * @brief Get Flash Unique ID
359 *
360 * @param p_flash_cfg: Flash config pointer
361 * @param data: data pointer to store Device ID Read from flash
362 * @param id_len: Unique id len
363 * @param group: CPU group id 0 or 1
364 * @param bank: Flash bank select
365 *
366 * @return BFLB_RET:0 means success and other value means error
367 *
368 *******************************************************************************/
369 __WEAK
bflb_xip_sflash_get_uniqueid_need_lock(spi_flash_cfg_type * p_flash_cfg,uint8_t * data,uint8_t id_len,uint8_t group,uint8_t bank)370 int ATTR_TCM_SECTION bflb_xip_sflash_get_uniqueid_need_lock(spi_flash_cfg_type *p_flash_cfg, uint8_t *data,
371 uint8_t id_len, uint8_t group, uint8_t bank)
372 {
373 int stat = 0;
374 uint32_t offset = 0;
375 uint8_t aes_enable = 0;
376 uint8_t io_mode = p_flash_cfg->io_mode & 0xf;
377
378 bflb_xip_sflash_opt_enter(&aes_enable);
379 stat = bflb_xip_sflash_state_save(p_flash_cfg, &offset, group, bank);
380
381 if (stat != 0) {
382 bflb_sflash_set_xip_cfg(p_flash_cfg, io_mode, 1, 0, 32, bank);
383 } else {
384 bflb_sflash_get_uniqueid(data, id_len);
385 bflb_xip_sflash_state_restore(p_flash_cfg, offset, group, bank);
386 }
387
388 bflb_xip_sflash_opt_exit(aes_enable);
389
390 return 0;
391 }
392
393 /****************************************************************************//**
394 * @brief Clear flash status register need lock
395 *
396 * @param p_flash_cfg: Flash config pointer
397 * @param group: CPU group id 0 or 1
398 * @param bank: Flash bank select
399 *
400 * @return BFLB_RET:0 means success and other value means error
401 *
402 *******************************************************************************/
403 __WEAK
bflb_xip_sflash_clear_status_register_need_lock(spi_flash_cfg_type * p_flash_cfg,uint8_t group,uint8_t bank)404 int ATTR_TCM_SECTION bflb_xip_sflash_clear_status_register_need_lock(spi_flash_cfg_type *p_flash_cfg,
405 uint8_t group, uint8_t bank)
406 {
407 int stat = 0;
408 uint32_t offset = 0;
409 uint8_t aes_enable = 0;
410 uint8_t io_mode = p_flash_cfg->io_mode & 0xf;
411
412 bflb_xip_sflash_opt_enter(&aes_enable);
413 stat = bflb_xip_sflash_state_save(p_flash_cfg, &offset, group, bank);
414
415 if (stat != 0) {
416 bflb_sflash_set_xip_cfg(p_flash_cfg, io_mode, 1, 0, 32, bank);
417 } else {
418 stat = bflb_sflash_clear_status_register(p_flash_cfg);
419 bflb_xip_sflash_state_restore(p_flash_cfg, offset, group, bank);
420 }
421
422 bflb_xip_sflash_opt_exit(aes_enable);
423
424 return 0;
425 }
426
427 /****************************************************************************/ /**
428 * @brief Read data from flash via XIP
429 *
430 * @param addr: flash read start address
431 * @param data: data pointer to store data read from flash
432 * @param len: data length to read
433 * @param group: CPU group id 0 or 1
434 * @param bank: Flash bank select
435 *
436 * @return BFLB_RET:0 means success and other value means error
437 *
438 *******************************************************************************/
439 __WEAK
bflb_xip_sflash_read_via_cache_need_lock(uint32_t addr,uint8_t * data,uint32_t len,uint8_t group,uint8_t bank)440 int ATTR_TCM_SECTION bflb_xip_sflash_read_via_cache_need_lock(uint32_t addr, uint8_t *data, uint32_t len,
441 uint8_t group, uint8_t bank)
442 {
443 uint32_t offset = 0;
444
445 addr = addr & (BFLB_FLASH_XIP_END-BFLB_FLASH_XIP_BASE-1);
446 addr |= BFLB_FLASH_XIP_BASE;
447
448 offset = bflb_sf_ctrl_get_flash_image_offset(group, bank);
449 bflb_sf_ctrl_set_flash_image_offset(0, group, bank);
450 /* Flash read */
451 arch_memcpy_fast(data, (void *)(uintptr_t)(addr - bflb_sf_ctrl_get_flash_image_offset(group, bank)), len);
452 bflb_sf_ctrl_set_flash_image_offset(offset, group, bank);
453
454 return 0;
455 }
456
457 /****************************************************************************/ /**
458 * @brief XIP SFlash option save
459 *
460 * @param aes_enable: AES enable status pointer
461 *
462 * @return None
463 *
464 *******************************************************************************/
465 __WEAK
bflb_xip_sflash_opt_enter(uint8_t * aes_enable)466 void ATTR_TCM_SECTION bflb_xip_sflash_opt_enter(uint8_t *aes_enable)
467 {
468 *aes_enable = bflb_sf_ctrl_is_aes_enable();
469
470 if (*aes_enable) {
471 bflb_sf_ctrl_aes_disable();
472 }
473 }
474
475 /****************************************************************************/ /**
476 * @brief XIP SFlash option restore
477 *
478 * @param aes_enable: AES enable status
479 *
480 * @return None
481 *
482 *******************************************************************************/
483 __WEAK
bflb_xip_sflash_opt_exit(uint8_t aes_enable)484 void ATTR_TCM_SECTION bflb_xip_sflash_opt_exit(uint8_t aes_enable)
485 {
486 if (aes_enable) {
487 bflb_sf_ctrl_aes_enable();
488 }
489 }
490
491 /*@} end of group XIP_SFLASH_Public_Functions */
492
493 /*@} end of group XIP_SFLASH */
494
495 /*@} end of group BL628_Peripheral_Driver */
496